diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/CMakeLists.txt b/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/CMakeLists.txt index 6265291dec..905d2f8b8d 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/CMakeLists.txt +++ b/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/CMakeLists.txt @@ -2,5 +2,7 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_LIST_DIR}/../../common/nimble_central_utils) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(coc_blecent) diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/CMakeLists.txt b/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/CMakeLists.txt index 7eff1870a2..18d510d988 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/CMakeLists.txt +++ b/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/CMakeLists.txt @@ -1,2 +1,4 @@ -idf_component_register(SRCS "main.c" "misc.c" "peer.c" - INCLUDE_DIRS ".") +set(srcs "main.c") + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/coc_blecent.h b/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/coc_blecent.h index 5111ad3dd9..0a29abb156 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/coc_blecent.h +++ b/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/coc_blecent.h @@ -8,6 +8,7 @@ #define H_COC_BLECENT_ #include "modlog/modlog.h" +#include "esp_central.h" #ifdef __cplusplus extern "C" { #endif @@ -18,76 +19,6 @@ struct ble_hs_cfg; union ble_store_value; union ble_store_key; -/** Misc. */ -void print_bytes(const uint8_t *bytes, int len); -void print_mbuf(const struct os_mbuf *om); -char *addr_str(const void *addr); -void print_uuid(const ble_uuid_t *uuid); -void print_conn_desc(const struct ble_gap_conn_desc *desc); -void print_adv_fields(const struct ble_hs_adv_fields *fields); -void ext_print_adv_report(const void *param); -void print_mbuf_data(const struct os_mbuf *om); - -/** Peer. */ -struct peer_dsc { - SLIST_ENTRY(peer_dsc) next; - struct ble_gatt_dsc dsc; -}; -SLIST_HEAD(peer_dsc_list, peer_dsc); - -struct peer_chr { - SLIST_ENTRY(peer_chr) next; - struct ble_gatt_chr chr; - - struct peer_dsc_list dscs; -}; -SLIST_HEAD(peer_chr_list, peer_chr); - -struct peer_svc { - SLIST_ENTRY(peer_svc) next; - struct ble_gatt_svc svc; - - struct peer_chr_list chrs; -}; -SLIST_HEAD(peer_svc_list, peer_svc); - -struct peer; -typedef void peer_disc_fn(const struct peer *peer, int status, void *arg); - -struct peer { - SLIST_ENTRY(peer) next; - - uint16_t conn_handle; - - /** List of discovered GATT services. */ - struct peer_svc_list svcs; - - /** Keeps track of where we are in the service discovery process. */ - uint16_t disc_prev_chr_val; - struct peer_svc *cur_svc; - - /** Callback that gets executed when service discovery completes. */ - peer_disc_fn *disc_cb; - void *disc_cb_arg; -}; - -int peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, - void *disc_cb_arg); -const struct peer_dsc * -peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, - const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid); -const struct peer_chr * -peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, - const ble_uuid_t *chr_uuid); -const struct peer_svc * -peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid); -int peer_delete(uint16_t conn_handle); -int peer_add(uint16_t conn_handle); -int peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs); -struct peer * -peer_find(uint16_t conn_handle); - - #ifdef __cplusplus } #endif diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/CMakeLists.txt b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/CMakeLists.txt index 74e6734037..1979f5db49 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/CMakeLists.txt +++ b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/CMakeLists.txt @@ -2,5 +2,7 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_LIST_DIR}/../../common/nimble_peripheral_utils) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(coc_bleprph) diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/CMakeLists.txt b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/CMakeLists.txt index 04e467e105..18d510d988 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/CMakeLists.txt +++ b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/CMakeLists.txt @@ -1,6 +1,4 @@ -set(srcs "main.c" - "misc.c" - "scli.c") +set(srcs "main.c") idf_component_register(SRCS "${srcs}" - INCLUDE_DIRS ".") + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/coc_bleprph.h b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/coc_bleprph.h index 4503e9a1b3..bf4ffe6e28 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/coc_bleprph.h +++ b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/coc_bleprph.h @@ -10,6 +10,7 @@ #include #include "nimble/ble.h" #include "modlog/modlog.h" +#include "esp_peripheral.h" #ifdef __cplusplus extern "C" { #endif @@ -23,14 +24,6 @@ struct ble_gatt_register_ctxt; void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); int gatt_svr_init(void); -/* Console */ -int scli_init(void); -int scli_receive_key(int *key); - -/** Misc. */ -void print_bytes(const uint8_t *bytes, int len); -void print_addr(const void *addr); - #ifdef __cplusplus } #endif diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/CMakeLists.txt b/examples/bluetooth/nimble/ble_spp/spp_client/CMakeLists.txt index 615f271b6c..b0bdddddf7 100644 --- a/examples/bluetooth/nimble/ble_spp/spp_client/CMakeLists.txt +++ b/examples/bluetooth/nimble/ble_spp/spp_client/CMakeLists.txt @@ -2,5 +2,7 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) +set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_LIST_DIR}/../../common/nimble_central_utils) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(spp_client) diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/main/CMakeLists.txt b/examples/bluetooth/nimble/ble_spp/spp_client/main/CMakeLists.txt index 7eff1870a2..18d510d988 100644 --- a/examples/bluetooth/nimble/ble_spp/spp_client/main/CMakeLists.txt +++ b/examples/bluetooth/nimble/ble_spp/spp_client/main/CMakeLists.txt @@ -1,2 +1,4 @@ -idf_component_register(SRCS "main.c" "misc.c" "peer.c" - INCLUDE_DIRS ".") +set(srcs "main.c") + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/main/ble_spp_client.h b/examples/bluetooth/nimble/ble_spp/spp_client/main/ble_spp_client.h index da0f9d8f8d..c94f900558 100644 --- a/examples/bluetooth/nimble/ble_spp/spp_client/main/ble_spp_client.h +++ b/examples/bluetooth/nimble/ble_spp/spp_client/main/ble_spp_client.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -8,6 +8,7 @@ #define H_BLESPPCLIENT_ #include "modlog/modlog.h" +#include "esp_central.h" #ifdef __cplusplus extern "C" { #endif @@ -25,74 +26,6 @@ union ble_store_key; #define GATT_SVR_CHR_UNR_ALERT_STAT_UUID 0x2A45 #define GATT_SVR_CHR_ALERT_NOT_CTRL_PT 0x2A44 -/** Misc. */ -void print_bytes(const uint8_t *bytes, int len); -void print_mbuf(const struct os_mbuf *om); -char *addr_str(const void *addr); -void print_uuid(const ble_uuid_t *uuid); -void print_conn_desc(const struct ble_gap_conn_desc *desc); -void print_adv_fields(const struct ble_hs_adv_fields *fields); - -/** Peer. */ -struct peer_dsc { - SLIST_ENTRY(peer_dsc) next; - struct ble_gatt_dsc dsc; -}; -SLIST_HEAD(peer_dsc_list, peer_dsc); - -struct peer_chr { - SLIST_ENTRY(peer_chr) next; - struct ble_gatt_chr chr; - - struct peer_dsc_list dscs; -}; -SLIST_HEAD(peer_chr_list, peer_chr); - -struct peer_svc { - SLIST_ENTRY(peer_svc) next; - struct ble_gatt_svc svc; - - struct peer_chr_list chrs; -}; -SLIST_HEAD(peer_svc_list, peer_svc); - -struct peer; -typedef void peer_disc_fn(const struct peer *peer, int status, void *arg); - -struct peer { - SLIST_ENTRY(peer) next; - - uint16_t conn_handle; - - /** List of discovered GATT services. */ - struct peer_svc_list svcs; - - /** Keeps track of where we are in the service discovery process. */ - uint16_t disc_prev_chr_val; - struct peer_svc *cur_svc; - - /** Callback that gets executed when service discovery completes. */ - peer_disc_fn *disc_cb; - void *disc_cb_arg; -}; - -int peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, - void *disc_cb_arg); -const struct peer_dsc * -peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, - const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid); -const struct peer_chr * -peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, - const ble_uuid_t *chr_uuid); -const struct peer_svc * -peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid); -int peer_delete(uint16_t conn_handle); -int peer_add(uint16_t conn_handle); -int peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs); -struct peer * -peer_find(uint16_t conn_handle); - - #ifdef __cplusplus } #endif diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/main/misc.c b/examples/bluetooth/nimble/ble_spp/spp_client/main/misc.c deleted file mode 100644 index d94c15b55f..0000000000 --- a/examples/bluetooth/nimble/ble_spp/spp_client/main/misc.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#include -#include -#include -#include "host/ble_hs.h" -#include "host/ble_uuid.h" -#include "ble_spp_client.h" - -/** - * Utility function to log an array of bytes. - */ -void -print_bytes(const uint8_t *bytes, int len) -{ - int i; - - for (i = 0; i < len; i++) { - MODLOG_DFLT(DEBUG, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); - } -} - -void -print_mbuf(const struct os_mbuf *om) -{ - int colon, i; - - colon = 0; - while (om != NULL) { - if (colon) { - MODLOG_DFLT(INFO, ":"); - } else { - colon = 1; - } - for (i = 0; i < om->om_len; i++) { - MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", om->om_data[i]); - } - om = SLIST_NEXT(om, om_next); - } -} - -char * -addr_str(const void *addr) -{ - static char buf[6 * 2 + 5 + 1]; - const uint8_t *u8p; - - u8p = addr; - sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", - u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); - - return buf; -} - -void -print_uuid(const ble_uuid_t *uuid) -{ - char buf[BLE_UUID_STR_LEN]; - - MODLOG_DFLT(DEBUG, "%s", ble_uuid_to_str(uuid, buf)); -} - -/** - * Logs information about a connection to the console. - */ -void -print_conn_desc(const struct ble_gap_conn_desc *desc) -{ - MODLOG_DFLT(DEBUG, "handle=%d our_ota_addr_type=%d our_ota_addr=%s ", - desc->conn_handle, desc->our_ota_addr.type, - addr_str(desc->our_ota_addr.val)); - MODLOG_DFLT(DEBUG, "our_id_addr_type=%d our_id_addr=%s ", - desc->our_id_addr.type, addr_str(desc->our_id_addr.val)); - MODLOG_DFLT(DEBUG, "peer_ota_addr_type=%d peer_ota_addr=%s ", - desc->peer_ota_addr.type, addr_str(desc->peer_ota_addr.val)); - MODLOG_DFLT(DEBUG, "peer_id_addr_type=%d peer_id_addr=%s ", - desc->peer_id_addr.type, addr_str(desc->peer_id_addr.val)); - MODLOG_DFLT(DEBUG, "conn_itvl=%d conn_latency=%d supervision_timeout=%d " - "encrypted=%d authenticated=%d bonded=%d", - desc->conn_itvl, desc->conn_latency, - desc->supervision_timeout, - desc->sec_state.encrypted, - desc->sec_state.authenticated, - desc->sec_state.bonded); -} - - -void -print_adv_fields(const struct ble_hs_adv_fields *fields) -{ - char s[BLE_HS_ADV_MAX_SZ]; - const uint8_t *u8p; - int i; - - if (fields->flags != 0) { - MODLOG_DFLT(DEBUG, " flags=0x%02x\n", fields->flags); - } - - if (fields->uuids16 != NULL) { - MODLOG_DFLT(DEBUG, " uuids16(%scomplete)=", - fields->uuids16_is_complete ? "" : "in"); - for (i = 0; i < fields->num_uuids16; i++) { - print_uuid(&fields->uuids16[i].u); - MODLOG_DFLT(DEBUG, " "); - } - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->uuids32 != NULL) { - MODLOG_DFLT(DEBUG, " uuids32(%scomplete)=", - fields->uuids32_is_complete ? "" : "in"); - for (i = 0; i < fields->num_uuids32; i++) { - print_uuid(&fields->uuids32[i].u); - MODLOG_DFLT(DEBUG, " "); - } - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->uuids128 != NULL) { - MODLOG_DFLT(DEBUG, " uuids128(%scomplete)=", - fields->uuids128_is_complete ? "" : "in"); - for (i = 0; i < fields->num_uuids128; i++) { - print_uuid(&fields->uuids128[i].u); - MODLOG_DFLT(DEBUG, " "); - } - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->name != NULL) { - assert(fields->name_len < sizeof s - 1); - memcpy(s, fields->name, fields->name_len); - s[fields->name_len] = '\0'; - MODLOG_DFLT(DEBUG, " name(%scomplete)=%s\n", - fields->name_is_complete ? "" : "in", s); - } - - if (fields->tx_pwr_lvl_is_present) { - MODLOG_DFLT(DEBUG, " tx_pwr_lvl=%d\n", fields->tx_pwr_lvl); - } - - if (fields->slave_itvl_range != NULL) { - MODLOG_DFLT(DEBUG, " slave_itvl_range="); - print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN); - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->svc_data_uuid16 != NULL) { - MODLOG_DFLT(DEBUG, " svc_data_uuid16="); - print_bytes(fields->svc_data_uuid16, fields->svc_data_uuid16_len); - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->public_tgt_addr != NULL) { - MODLOG_DFLT(DEBUG, " public_tgt_addr="); - u8p = fields->public_tgt_addr; - for (i = 0; i < fields->num_public_tgt_addrs; i++) { - MODLOG_DFLT(DEBUG, "public_tgt_addr=%s ", addr_str(u8p)); - u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN; - } - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->appearance_is_present) { - MODLOG_DFLT(DEBUG, " appearance=0x%04x\n", fields->appearance); - } - - if (fields->adv_itvl_is_present) { - MODLOG_DFLT(DEBUG, " adv_itvl=0x%04x\n", fields->adv_itvl); - } - - if (fields->svc_data_uuid32 != NULL) { - MODLOG_DFLT(DEBUG, " svc_data_uuid32="); - print_bytes(fields->svc_data_uuid32, fields->svc_data_uuid32_len); - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->svc_data_uuid128 != NULL) { - MODLOG_DFLT(DEBUG, " svc_data_uuid128="); - print_bytes(fields->svc_data_uuid128, fields->svc_data_uuid128_len); - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->uri != NULL) { - MODLOG_DFLT(DEBUG, " uri="); - print_bytes(fields->uri, fields->uri_len); - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->mfg_data != NULL) { - MODLOG_DFLT(DEBUG, " mfg_data="); - print_bytes(fields->mfg_data, fields->mfg_data_len); - MODLOG_DFLT(DEBUG, "\n"); - } -} diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/main/peer.c b/examples/bluetooth/nimble/ble_spp/spp_client/main/peer.c deleted file mode 100644 index 93ab5a483c..0000000000 --- a/examples/bluetooth/nimble/ble_spp/spp_client/main/peer.c +++ /dev/null @@ -1,794 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#include -#include -#include "host/ble_hs.h" -#include "ble_spp_client.h" - -static void *peer_svc_mem; -static struct os_mempool peer_svc_pool; - -static void *peer_chr_mem; -static struct os_mempool peer_chr_pool; - -static void *peer_dsc_mem; -static struct os_mempool peer_dsc_pool; - -static void *peer_mem; -static struct os_mempool peer_pool; -static SLIST_HEAD(, peer) peers; - -static struct peer_svc * -peer_svc_find_range(struct peer *peer, uint16_t attr_handle); -static struct peer_svc * -peer_svc_find(struct peer *peer, uint16_t svc_start_handle, - struct peer_svc **out_prev); -int -peer_svc_is_empty(const struct peer_svc *svc); - -uint16_t -chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr); -int -chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr); -static struct peer_chr * -peer_chr_find(const struct peer_svc *svc, uint16_t chr_def_handle, - struct peer_chr **out_prev); -static void -peer_disc_chrs(struct peer *peer); - -static int -peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, - uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, - void *arg); - -struct peer * -peer_find(uint16_t conn_handle) -{ - struct peer *peer; - - SLIST_FOREACH(peer, &peers, next) { - if (peer->conn_handle == conn_handle) { - return peer; - } - } - - return NULL; -} - -static void -peer_disc_complete(struct peer *peer, int rc) -{ - peer->disc_prev_chr_val = 0; - - /* Notify caller that discovery has completed. */ - if (peer->disc_cb != NULL) { - peer->disc_cb(peer, rc, peer->disc_cb_arg); - } -} - -static struct peer_dsc * -peer_dsc_find_prev(const struct peer_chr *chr, uint16_t dsc_handle) -{ - struct peer_dsc *prev; - struct peer_dsc *dsc; - - prev = NULL; - SLIST_FOREACH(dsc, &chr->dscs, next) { - if (dsc->dsc.handle >= dsc_handle) { - break; - } - - prev = dsc; - } - - return prev; -} - -static struct peer_dsc * -peer_dsc_find(const struct peer_chr *chr, uint16_t dsc_handle, - struct peer_dsc **out_prev) -{ - struct peer_dsc *prev; - struct peer_dsc *dsc; - - prev = peer_dsc_find_prev(chr, dsc_handle); - if (prev == NULL) { - dsc = SLIST_FIRST(&chr->dscs); - } else { - dsc = SLIST_NEXT(prev, next); - } - - if (dsc != NULL && dsc->dsc.handle != dsc_handle) { - dsc = NULL; - } - - if (out_prev != NULL) { - *out_prev = prev; - } - return dsc; -} - -static int -peer_dsc_add(struct peer *peer, uint16_t chr_val_handle, - const struct ble_gatt_dsc *gatt_dsc) -{ - struct peer_dsc *prev; - struct peer_dsc *dsc; - struct peer_svc *svc; - struct peer_chr *chr; - - svc = peer_svc_find_range(peer, chr_val_handle); - if (svc == NULL) { - /* Can't find service for discovered descriptor; this shouldn't - * happen. - */ - assert(0); - return BLE_HS_EUNKNOWN; - } - - chr = peer_chr_find(svc, chr_val_handle, NULL); - if (chr == NULL) { - /* Can't find characteristic for discovered descriptor; this shouldn't - * happen. - */ - assert(0); - return BLE_HS_EUNKNOWN; - } - - dsc = peer_dsc_find(chr, gatt_dsc->handle, &prev); - if (dsc != NULL) { - /* Descriptor already discovered. */ - return 0; - } - - dsc = os_memblock_get(&peer_dsc_pool); - if (dsc == NULL) { - /* Out of memory. */ - return BLE_HS_ENOMEM; - } - memset(dsc, 0, sizeof * dsc); - - dsc->dsc = *gatt_dsc; - - if (prev == NULL) { - SLIST_INSERT_HEAD(&chr->dscs, dsc, next); - } else { - SLIST_NEXT(prev, next) = dsc; - } - - return 0; -} - -static void -peer_disc_dscs(struct peer *peer) -{ - struct peer_chr *chr; - struct peer_svc *svc; - int rc; - - /* Search through the list of discovered characteristics for the first - * characteristic that contains undiscovered descriptors. Then, discover - * all descriptors belonging to that characteristic. - */ - SLIST_FOREACH(svc, &peer->svcs, next) { - SLIST_FOREACH(chr, &svc->chrs, next) { - if (!chr_is_empty(svc, chr) && - SLIST_EMPTY(&chr->dscs) && - peer->disc_prev_chr_val <= chr->chr.def_handle) { - - rc = ble_gattc_disc_all_dscs(peer->conn_handle, - chr->chr.val_handle, - chr_end_handle(svc, chr), - peer_dsc_disced, peer); - if (rc != 0) { - peer_disc_complete(peer, rc); - } - - peer->disc_prev_chr_val = chr->chr.val_handle; - return; - } - } - } - - /* All descriptors discovered. */ - peer_disc_complete(peer, 0); -} - -static int -peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, - uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, - void *arg) -{ - struct peer *peer; - int rc; - - peer = arg; - assert(peer->conn_handle == conn_handle); - - switch (error->status) { - case 0: - rc = peer_dsc_add(peer, chr_val_handle, dsc); - break; - - case BLE_HS_EDONE: - /* All descriptors in this characteristic discovered; start discovering - * descriptors in the next characteristic. - */ - if (peer->disc_prev_chr_val > 0) { - peer_disc_dscs(peer); - } - rc = 0; - break; - - default: - /* Error; abort discovery. */ - rc = error->status; - break; - } - - if (rc != 0) { - /* Error; abort discovery. */ - peer_disc_complete(peer, rc); - } - - return rc; -} - -uint16_t -chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr) -{ - const struct peer_chr *next_chr; - - next_chr = SLIST_NEXT(chr, next); - if (next_chr != NULL) { - return next_chr->chr.def_handle - 1; - } else { - return svc->svc.end_handle; - } -} - -int -chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr) -{ - return chr_end_handle(svc, chr) <= chr->chr.val_handle; -} - -static struct peer_chr * -peer_chr_find_prev(const struct peer_svc *svc, uint16_t chr_val_handle) -{ - struct peer_chr *prev; - struct peer_chr *chr; - - prev = NULL; - SLIST_FOREACH(chr, &svc->chrs, next) { - if (chr->chr.val_handle >= chr_val_handle) { - break; - } - - prev = chr; - } - - return prev; -} - -static struct peer_chr * -peer_chr_find(const struct peer_svc *svc, uint16_t chr_val_handle, - struct peer_chr **out_prev) -{ - struct peer_chr *prev; - struct peer_chr *chr; - - prev = peer_chr_find_prev(svc, chr_val_handle); - if (prev == NULL) { - chr = SLIST_FIRST(&svc->chrs); - } else { - chr = SLIST_NEXT(prev, next); - } - - if (chr != NULL && chr->chr.val_handle != chr_val_handle) { - chr = NULL; - } - - if (out_prev != NULL) { - *out_prev = prev; - } - return chr; -} - -static void -peer_chr_delete(struct peer_chr *chr) -{ - struct peer_dsc *dsc; - - while ((dsc = SLIST_FIRST(&chr->dscs)) != NULL) { - SLIST_REMOVE_HEAD(&chr->dscs, next); - os_memblock_put(&peer_dsc_pool, dsc); - } - - os_memblock_put(&peer_chr_pool, chr); -} - -static int -peer_chr_add(struct peer *peer, uint16_t svc_start_handle, - const struct ble_gatt_chr *gatt_chr) -{ - struct peer_chr *prev; - struct peer_chr *chr; - struct peer_svc *svc; - - svc = peer_svc_find(peer, svc_start_handle, NULL); - if (svc == NULL) { - /* Can't find service for discovered characteristic; this shouldn't - * happen. - */ - assert(0); - return BLE_HS_EUNKNOWN; - } - - chr = peer_chr_find(svc, gatt_chr->def_handle, &prev); - if (chr != NULL) { - /* Characteristic already discovered. */ - return 0; - } - - chr = os_memblock_get(&peer_chr_pool); - if (chr == NULL) { - /* Out of memory. */ - return BLE_HS_ENOMEM; - } - memset(chr, 0, sizeof * chr); - - chr->chr = *gatt_chr; - - if (prev == NULL) { - SLIST_INSERT_HEAD(&svc->chrs, chr, next); - } else { - SLIST_NEXT(prev, next) = chr; - } - - return 0; -} - -static int -peer_chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error, - const struct ble_gatt_chr *chr, void *arg) -{ - struct peer *peer; - int rc; - - peer = arg; - assert(peer->conn_handle == conn_handle); - - switch (error->status) { - case 0: - rc = peer_chr_add(peer, peer->cur_svc->svc.start_handle, chr); - break; - - case BLE_HS_EDONE: - /* All characteristics in this service discovered; start discovering - * characteristics in the next service. - */ - if (peer->disc_prev_chr_val > 0) { - peer_disc_chrs(peer); - } - rc = 0; - break; - - default: - rc = error->status; - break; - } - - if (rc != 0) { - /* Error; abort discovery. */ - peer_disc_complete(peer, rc); - } - - return rc; -} - -static void -peer_disc_chrs(struct peer *peer) -{ - struct peer_svc *svc; - int rc; - - /* Search through the list of discovered service for the first service that - * contains undiscovered characteristics. Then, discover all - * characteristics belonging to that service. - */ - SLIST_FOREACH(svc, &peer->svcs, next) { - if (!peer_svc_is_empty(svc) && SLIST_EMPTY(&svc->chrs)) { - peer->cur_svc = svc; - rc = ble_gattc_disc_all_chrs(peer->conn_handle, - svc->svc.start_handle, - svc->svc.end_handle, - peer_chr_disced, peer); - if (rc != 0) { - peer_disc_complete(peer, rc); - } - return; - } - } - - /* All characteristics discovered. */ - peer_disc_dscs(peer); -} - -int -peer_svc_is_empty(const struct peer_svc *svc) -{ - return svc->svc.end_handle <= svc->svc.start_handle; -} - -static struct peer_svc * -peer_svc_find_prev(struct peer *peer, uint16_t svc_start_handle) -{ - struct peer_svc *prev; - struct peer_svc *svc; - - prev = NULL; - SLIST_FOREACH(svc, &peer->svcs, next) { - if (svc->svc.start_handle >= svc_start_handle) { - break; - } - - prev = svc; - } - - return prev; -} - -static struct peer_svc * -peer_svc_find(struct peer *peer, uint16_t svc_start_handle, - struct peer_svc **out_prev) -{ - struct peer_svc *prev; - struct peer_svc *svc; - - prev = peer_svc_find_prev(peer, svc_start_handle); - if (prev == NULL) { - svc = SLIST_FIRST(&peer->svcs); - } else { - svc = SLIST_NEXT(prev, next); - } - - if (svc != NULL && svc->svc.start_handle != svc_start_handle) { - svc = NULL; - } - - if (out_prev != NULL) { - *out_prev = prev; - } - return svc; -} - -static struct peer_svc * -peer_svc_find_range(struct peer *peer, uint16_t attr_handle) -{ - struct peer_svc *svc; - - SLIST_FOREACH(svc, &peer->svcs, next) { - if (svc->svc.start_handle <= attr_handle && - svc->svc.end_handle >= attr_handle) { - - return svc; - } - } - - return NULL; -} - -const struct peer_svc * -peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid) -{ - const struct peer_svc *svc; - - SLIST_FOREACH(svc, &peer->svcs, next) { - if (ble_uuid_cmp(&svc->svc.uuid.u, uuid) == 0) { - return svc; - } - } - - return NULL; -} - -const struct peer_chr * -peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, - const ble_uuid_t *chr_uuid) -{ - const struct peer_svc *svc; - const struct peer_chr *chr; - - svc = peer_svc_find_uuid(peer, svc_uuid); - if (svc == NULL) { - return NULL; - } - - SLIST_FOREACH(chr, &svc->chrs, next) { - if (ble_uuid_cmp(&chr->chr.uuid.u, chr_uuid) == 0) { - return chr; - } - } - - return NULL; -} - -const struct peer_dsc * -peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, - const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid) -{ - const struct peer_chr *chr; - const struct peer_dsc *dsc; - - chr = peer_chr_find_uuid(peer, svc_uuid, chr_uuid); - if (chr == NULL) { - return NULL; - } - - SLIST_FOREACH(dsc, &chr->dscs, next) { - if (ble_uuid_cmp(&dsc->dsc.uuid.u, dsc_uuid) == 0) { - return dsc; - } - } - - return NULL; -} - -static int -peer_svc_add(struct peer *peer, const struct ble_gatt_svc *gatt_svc) -{ - struct peer_svc *prev; - struct peer_svc *svc; - - svc = peer_svc_find(peer, gatt_svc->start_handle, &prev); - if (svc != NULL) { - /* Service already discovered. */ - return 0; - } - - svc = os_memblock_get(&peer_svc_pool); - if (svc == NULL) { - /* Out of memory. */ - return BLE_HS_ENOMEM; - } - memset(svc, 0, sizeof * svc); - - svc->svc = *gatt_svc; - SLIST_INIT(&svc->chrs); - - if (prev == NULL) { - SLIST_INSERT_HEAD(&peer->svcs, svc, next); - } else { - SLIST_INSERT_AFTER(prev, svc, next); - } - - return 0; -} - -static void -peer_svc_delete(struct peer_svc *svc) -{ - struct peer_chr *chr; - - while ((chr = SLIST_FIRST(&svc->chrs)) != NULL) { - SLIST_REMOVE_HEAD(&svc->chrs, next); - peer_chr_delete(chr); - } - - os_memblock_put(&peer_svc_pool, svc); -} - -static int -peer_svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, - const struct ble_gatt_svc *service, void *arg) -{ - struct peer *peer; - int rc; - - peer = arg; - assert(peer->conn_handle == conn_handle); - - switch (error->status) { - case 0: - rc = peer_svc_add(peer, service); - break; - - case BLE_HS_EDONE: - /* All services discovered; start discovering characteristics. */ - if (peer->disc_prev_chr_val > 0) { - peer_disc_chrs(peer); - } - rc = 0; - break; - - default: - rc = error->status; - break; - } - - if (rc != 0) { - /* Error; abort discovery. */ - peer_disc_complete(peer, rc); - } - - return rc; -} - - -int -peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, void *disc_cb_arg) -{ - struct peer_svc *svc; - struct peer *peer; - int rc; - - peer = peer_find(conn_handle); - if (peer == NULL) { - return BLE_HS_ENOTCONN; - } - - /* Undiscover everything first. */ - while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) { - SLIST_REMOVE_HEAD(&peer->svcs, next); - peer_svc_delete(svc); - } - - peer->disc_prev_chr_val = 1; - peer->disc_cb = disc_cb; - peer->disc_cb_arg = disc_cb_arg; - - rc = ble_gattc_disc_all_svcs(conn_handle, peer_svc_disced, peer); - if (rc != 0) { - return rc; - } - - return 0; -} - -int -peer_delete(uint16_t conn_handle) -{ - struct peer_svc *svc; - struct peer *peer; - int rc; - - peer = peer_find(conn_handle); - if (peer == NULL) { - return BLE_HS_ENOTCONN; - } - - SLIST_REMOVE(&peers, peer, peer, next); - - while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) { - SLIST_REMOVE_HEAD(&peer->svcs, next); - peer_svc_delete(svc); - } - - rc = os_memblock_put(&peer_pool, peer); - if (rc != 0) { - return BLE_HS_EOS; - } - - return 0; -} - -int -peer_add(uint16_t conn_handle) -{ - struct peer *peer; - - /* Make sure the connection handle is unique. */ - peer = peer_find(conn_handle); - if (peer != NULL) { - return BLE_HS_EALREADY; - } - - peer = os_memblock_get(&peer_pool); - if (peer == NULL) { - /* Out of memory. */ - return BLE_HS_ENOMEM; - } - - memset(peer, 0, sizeof * peer); - peer->conn_handle = conn_handle; - - SLIST_INSERT_HEAD(&peers, peer, next); - - return 0; -} - -static void -peer_free_mem(void) -{ - free(peer_mem); - peer_mem = NULL; - - free(peer_svc_mem); - peer_svc_mem = NULL; - - free(peer_chr_mem); - peer_chr_mem = NULL; - - free(peer_dsc_mem); - peer_dsc_mem = NULL; -} - -int -peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs) -{ - int rc; - - /* Free memory first in case this function gets called more than once. */ - peer_free_mem(); - - peer_mem = malloc( - OS_MEMPOOL_BYTES(max_peers, sizeof (struct peer))); - if (peer_mem == NULL) { - rc = BLE_HS_ENOMEM; - goto err; - } - - rc = os_mempool_init(&peer_pool, max_peers, - sizeof (struct peer), peer_mem, - "peer_pool"); - if (rc != 0) { - rc = BLE_HS_EOS; - goto err; - } - - peer_svc_mem = malloc( - OS_MEMPOOL_BYTES(max_svcs, sizeof (struct peer_svc))); - if (peer_svc_mem == NULL) { - rc = BLE_HS_ENOMEM; - goto err; - } - - rc = os_mempool_init(&peer_svc_pool, max_svcs, - sizeof (struct peer_svc), peer_svc_mem, - "peer_svc_pool"); - if (rc != 0) { - rc = BLE_HS_EOS; - goto err; - } - - peer_chr_mem = malloc( - OS_MEMPOOL_BYTES(max_chrs, sizeof (struct peer_chr))); - if (peer_chr_mem == NULL) { - rc = BLE_HS_ENOMEM; - goto err; - } - - rc = os_mempool_init(&peer_chr_pool, max_chrs, - sizeof (struct peer_chr), peer_chr_mem, - "peer_chr_pool"); - if (rc != 0) { - rc = BLE_HS_EOS; - goto err; - } - - peer_dsc_mem = malloc( - OS_MEMPOOL_BYTES(max_dscs, sizeof (struct peer_dsc))); - if (peer_dsc_mem == NULL) { - rc = BLE_HS_ENOMEM; - goto err; - } - - rc = os_mempool_init(&peer_dsc_pool, max_dscs, - sizeof (struct peer_dsc), peer_dsc_mem, - "peer_dsc_pool"); - if (rc != 0) { - rc = BLE_HS_EOS; - goto err; - } - - return 0; - -err: - peer_free_mem(); - return rc; -} diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/CMakeLists.txt b/examples/bluetooth/nimble/ble_spp/spp_server/CMakeLists.txt index 99cadaff23..87c71ac07d 100644 --- a/examples/bluetooth/nimble/ble_spp/spp_server/CMakeLists.txt +++ b/examples/bluetooth/nimble/ble_spp/spp_server/CMakeLists.txt @@ -2,5 +2,7 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) +set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_LIST_DIR}/../../common/nimble_peripheral_utils) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(spp_server) diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/main/CMakeLists.txt b/examples/bluetooth/nimble/ble_spp/spp_server/main/CMakeLists.txt index 1d440d5d68..eee6ef2d0a 100644 --- a/examples/bluetooth/nimble/ble_spp/spp_server/main/CMakeLists.txt +++ b/examples/bluetooth/nimble/ble_spp/spp_server/main/CMakeLists.txt @@ -1,6 +1,5 @@ set(srcs "main.c" - "gatt_svr.c" - "misc.c") + "gatt_svr.c") idf_component_register(SRCS "${srcs}" - INCLUDE_DIRS ".") + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/main/ble_spp_server.h b/examples/bluetooth/nimble/ble_spp/spp_server/main/ble_spp_server.h index 2b6d12e394..880ca9efca 100644 --- a/examples/bluetooth/nimble/ble_spp/spp_server/main/ble_spp_server.h +++ b/examples/bluetooth/nimble/ble_spp/spp_server/main/ble_spp_server.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -10,6 +10,7 @@ #include #include "nimble/ble.h" #include "modlog/modlog.h" +#include "esp_peripheral.h" #ifdef __cplusplus extern "C" { #endif @@ -28,14 +29,6 @@ struct ble_gatt_register_ctxt; void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); int new_gatt_svr_init(void); -/* Console */ -int scli_init(void); -int scli_receive_key(int *key); - -/** Misc. */ -void print_bytes(const uint8_t *bytes, int len); -void print_addr(const void *addr); - #ifdef __cplusplus } #endif diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/main/misc.c b/examples/bluetooth/nimble/ble_spp/spp_server/main/misc.c deleted file mode 100644 index 988ffebd1e..0000000000 --- a/examples/bluetooth/nimble/ble_spp/spp_server/main/misc.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#include "ble_spp_server.h" - -/** - * Utility function to log an array of bytes. - */ -void -print_bytes(const uint8_t *bytes, int len) -{ - int i; - - for (i = 0; i < len; i++) { - MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); - } -} - -void -print_addr(const void *addr) -{ - const uint8_t *u8p; - - u8p = addr; - MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x", - u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); -} diff --git a/examples/bluetooth/nimble/blecent/CMakeLists.txt b/examples/bluetooth/nimble/blecent/CMakeLists.txt index f443dbefda..6b337e7c82 100644 --- a/examples/bluetooth/nimble/blecent/CMakeLists.txt +++ b/examples/bluetooth/nimble/blecent/CMakeLists.txt @@ -2,5 +2,7 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) +set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_LIST_DIR}/../common/nimble_central_utils) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(blecent) diff --git a/examples/bluetooth/nimble/blecent/main/CMakeLists.txt b/examples/bluetooth/nimble/blecent/main/CMakeLists.txt index 7eff1870a2..18d510d988 100644 --- a/examples/bluetooth/nimble/blecent/main/CMakeLists.txt +++ b/examples/bluetooth/nimble/blecent/main/CMakeLists.txt @@ -1,2 +1,4 @@ -idf_component_register(SRCS "main.c" "misc.c" "peer.c" - INCLUDE_DIRS ".") +set(srcs "main.c") + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/blecent/main/blecent.h b/examples/bluetooth/nimble/blecent/main/blecent.h index d540908d45..b070af1164 100644 --- a/examples/bluetooth/nimble/blecent/main/blecent.h +++ b/examples/bluetooth/nimble/blecent/main/blecent.h @@ -21,6 +21,7 @@ #define H_BLECENT_ #include "modlog/modlog.h" +#include "esp_central.h" #ifdef __cplusplus extern "C" { #endif @@ -38,75 +39,6 @@ union ble_store_key; #define BLECENT_CHR_UNR_ALERT_STAT_UUID 0x2A45 #define BLECENT_CHR_ALERT_NOT_CTRL_PT 0x2A44 -/** Misc. */ -void print_bytes(const uint8_t *bytes, int len); -void print_mbuf(const struct os_mbuf *om); -char *addr_str(const void *addr); -void print_uuid(const ble_uuid_t *uuid); -void print_conn_desc(const struct ble_gap_conn_desc *desc); -void print_adv_fields(const struct ble_hs_adv_fields *fields); -void ext_print_adv_report(const void *param); - -/** Peer. */ -struct peer_dsc { - SLIST_ENTRY(peer_dsc) next; - struct ble_gatt_dsc dsc; -}; -SLIST_HEAD(peer_dsc_list, peer_dsc); - -struct peer_chr { - SLIST_ENTRY(peer_chr) next; - struct ble_gatt_chr chr; - - struct peer_dsc_list dscs; -}; -SLIST_HEAD(peer_chr_list, peer_chr); - -struct peer_svc { - SLIST_ENTRY(peer_svc) next; - struct ble_gatt_svc svc; - - struct peer_chr_list chrs; -}; -SLIST_HEAD(peer_svc_list, peer_svc); - -struct peer; -typedef void peer_disc_fn(const struct peer *peer, int status, void *arg); - -struct peer { - SLIST_ENTRY(peer) next; - - uint16_t conn_handle; - - /** List of discovered GATT services. */ - struct peer_svc_list svcs; - - /** Keeps track of where we are in the service discovery process. */ - uint16_t disc_prev_chr_val; - struct peer_svc *cur_svc; - - /** Callback that gets executed when service discovery completes. */ - peer_disc_fn *disc_cb; - void *disc_cb_arg; -}; - -int peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, - void *disc_cb_arg); -const struct peer_dsc * -peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, - const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid); -const struct peer_chr * -peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, - const ble_uuid_t *chr_uuid); -const struct peer_svc * -peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid); -int peer_delete(uint16_t conn_handle); -int peer_add(uint16_t conn_handle); -int peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs); -struct peer * -peer_find(uint16_t conn_handle); - - #ifdef __cplusplus } #endif diff --git a/examples/bluetooth/nimble/blecent/main/misc.c b/examples/bluetooth/nimble/blecent/main/misc.c deleted file mode 100644 index 5437fe692f..0000000000 --- a/examples/bluetooth/nimble/blecent/main/misc.c +++ /dev/null @@ -1,232 +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 "host/ble_hs.h" -#include "host/ble_uuid.h" -#include "blecent.h" - -/** - * Utility function to log an array of bytes. - */ -void -print_bytes(const uint8_t *bytes, int len) -{ - int i; - - for (i = 0; i < len; i++) { - MODLOG_DFLT(DEBUG, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); - } -} - -void -print_mbuf(const struct os_mbuf *om) -{ - int colon, i; - - colon = 0; - while (om != NULL) { - if (colon) { - MODLOG_DFLT(INFO, ":"); - } else { - colon = 1; - } - for (i = 0; i < om->om_len; i++) { - MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", om->om_data[i]); - } - om = SLIST_NEXT(om, om_next); - } -} - -char * -addr_str(const void *addr) -{ - static char buf[6 * 2 + 5 + 1]; - const uint8_t *u8p; - - u8p = addr; - sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", - u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); - - return buf; -} - -void -print_uuid(const ble_uuid_t *uuid) -{ - char buf[BLE_UUID_STR_LEN]; - - MODLOG_DFLT(DEBUG, "%s", ble_uuid_to_str(uuid, buf)); -} - -/** - * Logs information about a connection to the console. - */ -void -print_conn_desc(const struct ble_gap_conn_desc *desc) -{ - MODLOG_DFLT(DEBUG, "handle=%d our_ota_addr_type=%d our_ota_addr=%s ", - desc->conn_handle, desc->our_ota_addr.type, - addr_str(desc->our_ota_addr.val)); - MODLOG_DFLT(DEBUG, "our_id_addr_type=%d our_id_addr=%s ", - desc->our_id_addr.type, addr_str(desc->our_id_addr.val)); - MODLOG_DFLT(DEBUG, "peer_ota_addr_type=%d peer_ota_addr=%s ", - desc->peer_ota_addr.type, addr_str(desc->peer_ota_addr.val)); - MODLOG_DFLT(DEBUG, "peer_id_addr_type=%d peer_id_addr=%s ", - desc->peer_id_addr.type, addr_str(desc->peer_id_addr.val)); - MODLOG_DFLT(DEBUG, "conn_itvl=%d conn_latency=%d supervision_timeout=%d " - "encrypted=%d authenticated=%d bonded=%d", - desc->conn_itvl, desc->conn_latency, - desc->supervision_timeout, - desc->sec_state.encrypted, - desc->sec_state.authenticated, - desc->sec_state.bonded); -} - -#if CONFIG_EXAMPLE_EXTENDED_ADV -void -print_addr(const void *addr, const char *name) -{ - const uint8_t *u8p; - u8p = addr; - MODLOG_DFLT(DEBUG, "%s = %02x:%02x:%02x:%02x:%02x:%02x", - name, u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); -} -void -ext_print_adv_report(const void *param) -{ - const struct ble_gap_ext_disc_desc *disc = (struct ble_gap_ext_disc_desc *)param; - MODLOG_DFLT(DEBUG, "props=%d data_status=%d legacy_event_type=%d", disc->props, disc->data_status, disc->legacy_event_type); - print_addr(disc->addr.val, "address"); - MODLOG_DFLT(DEBUG, "rssi=%d tx_power=%d", disc->rssi, disc->tx_power); - MODLOG_DFLT(DEBUG, "sid=%d prim_phy=%d sec_phy=%d", disc->sid, disc->prim_phy, disc->sec_phy); - MODLOG_DFLT(DEBUG, "periodic_adv_itvl=%d length_data=%d", disc->periodic_adv_itvl, disc->length_data); - print_addr(disc->direct_addr.val, "direct address"); -} -#endif - -void -print_adv_fields(const struct ble_hs_adv_fields *fields) -{ - char s[BLE_HS_ADV_MAX_SZ]; - const uint8_t *u8p; - int i; - - if (fields->flags != 0) { - MODLOG_DFLT(DEBUG, " flags=0x%02x\n", fields->flags); - } - - if (fields->uuids16 != NULL) { - MODLOG_DFLT(DEBUG, " uuids16(%scomplete)=", - fields->uuids16_is_complete ? "" : "in"); - for (i = 0; i < fields->num_uuids16; i++) { - print_uuid(&fields->uuids16[i].u); - MODLOG_DFLT(DEBUG, " "); - } - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->uuids32 != NULL) { - MODLOG_DFLT(DEBUG, " uuids32(%scomplete)=", - fields->uuids32_is_complete ? "" : "in"); - for (i = 0; i < fields->num_uuids32; i++) { - print_uuid(&fields->uuids32[i].u); - MODLOG_DFLT(DEBUG, " "); - } - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->uuids128 != NULL) { - MODLOG_DFLT(DEBUG, " uuids128(%scomplete)=", - fields->uuids128_is_complete ? "" : "in"); - for (i = 0; i < fields->num_uuids128; i++) { - print_uuid(&fields->uuids128[i].u); - MODLOG_DFLT(DEBUG, " "); - } - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->name != NULL) { - assert(fields->name_len < sizeof s - 1); - memcpy(s, fields->name, fields->name_len); - s[fields->name_len] = '\0'; - MODLOG_DFLT(DEBUG, " name(%scomplete)=%s\n", - fields->name_is_complete ? "" : "in", s); - } - - if (fields->tx_pwr_lvl_is_present) { - MODLOG_DFLT(DEBUG, " tx_pwr_lvl=%d\n", fields->tx_pwr_lvl); - } - - if (fields->slave_itvl_range != NULL) { - MODLOG_DFLT(DEBUG, " slave_itvl_range="); - print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN); - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->svc_data_uuid16 != NULL) { - MODLOG_DFLT(DEBUG, " svc_data_uuid16="); - print_bytes(fields->svc_data_uuid16, fields->svc_data_uuid16_len); - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->public_tgt_addr != NULL) { - MODLOG_DFLT(DEBUG, " public_tgt_addr="); - u8p = fields->public_tgt_addr; - for (i = 0; i < fields->num_public_tgt_addrs; i++) { - MODLOG_DFLT(DEBUG, "public_tgt_addr=%s ", addr_str(u8p)); - u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN; - } - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->appearance_is_present) { - MODLOG_DFLT(DEBUG, " appearance=0x%04x\n", fields->appearance); - } - - if (fields->adv_itvl_is_present) { - MODLOG_DFLT(DEBUG, " adv_itvl=0x%04x\n", fields->adv_itvl); - } - - if (fields->svc_data_uuid32 != NULL) { - MODLOG_DFLT(DEBUG, " svc_data_uuid32="); - print_bytes(fields->svc_data_uuid32, fields->svc_data_uuid32_len); - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->svc_data_uuid128 != NULL) { - MODLOG_DFLT(DEBUG, " svc_data_uuid128="); - print_bytes(fields->svc_data_uuid128, fields->svc_data_uuid128_len); - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->uri != NULL) { - MODLOG_DFLT(DEBUG, " uri="); - print_bytes(fields->uri, fields->uri_len); - MODLOG_DFLT(DEBUG, "\n"); - } - - if (fields->mfg_data != NULL) { - MODLOG_DFLT(DEBUG, " mfg_data="); - print_bytes(fields->mfg_data, fields->mfg_data_len); - MODLOG_DFLT(DEBUG, "\n"); - } -} diff --git a/examples/bluetooth/nimble/blecent/main/peer.c b/examples/bluetooth/nimble/blecent/main/peer.c deleted file mode 100644 index a01ae061e3..0000000000 --- a/examples/bluetooth/nimble/blecent/main/peer.c +++ /dev/null @@ -1,807 +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 "host/ble_hs.h" -#include "blecent.h" - -static void *peer_svc_mem; -static struct os_mempool peer_svc_pool; - -static void *peer_chr_mem; -static struct os_mempool peer_chr_pool; - -static void *peer_dsc_mem; -static struct os_mempool peer_dsc_pool; - -static void *peer_mem; -static struct os_mempool peer_pool; -static SLIST_HEAD(, peer) peers; - -static struct peer_svc * -peer_svc_find_range(struct peer *peer, uint16_t attr_handle); -static struct peer_svc * -peer_svc_find(struct peer *peer, uint16_t svc_start_handle, - struct peer_svc **out_prev); -int -peer_svc_is_empty(const struct peer_svc *svc); - -uint16_t -chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr); -int -chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr); -static struct peer_chr * -peer_chr_find(const struct peer_svc *svc, uint16_t chr_def_handle, - struct peer_chr **out_prev); -static void -peer_disc_chrs(struct peer *peer); - -static int -peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, - uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, - void *arg); - -struct peer * -peer_find(uint16_t conn_handle) -{ - struct peer *peer; - - SLIST_FOREACH(peer, &peers, next) { - if (peer->conn_handle == conn_handle) { - return peer; - } - } - - return NULL; -} - -static void -peer_disc_complete(struct peer *peer, int rc) -{ - peer->disc_prev_chr_val = 0; - - /* Notify caller that discovery has completed. */ - if (peer->disc_cb != NULL) { - peer->disc_cb(peer, rc, peer->disc_cb_arg); - } -} - -static struct peer_dsc * -peer_dsc_find_prev(const struct peer_chr *chr, uint16_t dsc_handle) -{ - struct peer_dsc *prev; - struct peer_dsc *dsc; - - prev = NULL; - SLIST_FOREACH(dsc, &chr->dscs, next) { - if (dsc->dsc.handle >= dsc_handle) { - break; - } - - prev = dsc; - } - - return prev; -} - -static struct peer_dsc * -peer_dsc_find(const struct peer_chr *chr, uint16_t dsc_handle, - struct peer_dsc **out_prev) -{ - struct peer_dsc *prev; - struct peer_dsc *dsc; - - prev = peer_dsc_find_prev(chr, dsc_handle); - if (prev == NULL) { - dsc = SLIST_FIRST(&chr->dscs); - } else { - dsc = SLIST_NEXT(prev, next); - } - - if (dsc != NULL && dsc->dsc.handle != dsc_handle) { - dsc = NULL; - } - - if (out_prev != NULL) { - *out_prev = prev; - } - return dsc; -} - -static int -peer_dsc_add(struct peer *peer, uint16_t chr_val_handle, - const struct ble_gatt_dsc *gatt_dsc) -{ - struct peer_dsc *prev; - struct peer_dsc *dsc; - struct peer_svc *svc; - struct peer_chr *chr; - - svc = peer_svc_find_range(peer, chr_val_handle); - if (svc == NULL) { - /* Can't find service for discovered descriptor; this shouldn't - * happen. - */ - assert(0); - return BLE_HS_EUNKNOWN; - } - - chr = peer_chr_find(svc, chr_val_handle, NULL); - if (chr == NULL) { - /* Can't find characteristic for discovered descriptor; this shouldn't - * happen. - */ - assert(0); - return BLE_HS_EUNKNOWN; - } - - dsc = peer_dsc_find(chr, gatt_dsc->handle, &prev); - if (dsc != NULL) { - /* Descriptor already discovered. */ - return 0; - } - - dsc = os_memblock_get(&peer_dsc_pool); - if (dsc == NULL) { - /* Out of memory. */ - return BLE_HS_ENOMEM; - } - memset(dsc, 0, sizeof * dsc); - - dsc->dsc = *gatt_dsc; - - if (prev == NULL) { - SLIST_INSERT_HEAD(&chr->dscs, dsc, next); - } else { - SLIST_NEXT(prev, next) = dsc; - } - - return 0; -} - -static void -peer_disc_dscs(struct peer *peer) -{ - struct peer_chr *chr; - struct peer_svc *svc; - int rc; - - /* Search through the list of discovered characteristics for the first - * characteristic that contains undiscovered descriptors. Then, discover - * all descriptors belonging to that characteristic. - */ - SLIST_FOREACH(svc, &peer->svcs, next) { - SLIST_FOREACH(chr, &svc->chrs, next) { - if (!chr_is_empty(svc, chr) && - SLIST_EMPTY(&chr->dscs) && - peer->disc_prev_chr_val <= chr->chr.def_handle) { - - rc = ble_gattc_disc_all_dscs(peer->conn_handle, - chr->chr.val_handle, - chr_end_handle(svc, chr), - peer_dsc_disced, peer); - if (rc != 0) { - peer_disc_complete(peer, rc); - } - - peer->disc_prev_chr_val = chr->chr.val_handle; - return; - } - } - } - - /* All descriptors discovered. */ - peer_disc_complete(peer, 0); -} - -static int -peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, - uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, - void *arg) -{ - struct peer *peer; - int rc; - - peer = arg; - assert(peer->conn_handle == conn_handle); - - switch (error->status) { - case 0: - rc = peer_dsc_add(peer, chr_val_handle, dsc); - break; - - case BLE_HS_EDONE: - /* All descriptors in this characteristic discovered; start discovering - * descriptors in the next characteristic. - */ - if (peer->disc_prev_chr_val > 0) { - peer_disc_dscs(peer); - } - rc = 0; - break; - - default: - /* Error; abort discovery. */ - rc = error->status; - break; - } - - if (rc != 0) { - /* Error; abort discovery. */ - peer_disc_complete(peer, rc); - } - - return rc; -} - -uint16_t -chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr) -{ - const struct peer_chr *next_chr; - - next_chr = SLIST_NEXT(chr, next); - if (next_chr != NULL) { - return next_chr->chr.def_handle - 1; - } else { - return svc->svc.end_handle; - } -} - -int -chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr) -{ - return chr_end_handle(svc, chr) <= chr->chr.val_handle; -} - -static struct peer_chr * -peer_chr_find_prev(const struct peer_svc *svc, uint16_t chr_val_handle) -{ - struct peer_chr *prev; - struct peer_chr *chr; - - prev = NULL; - SLIST_FOREACH(chr, &svc->chrs, next) { - if (chr->chr.val_handle >= chr_val_handle) { - break; - } - - prev = chr; - } - - return prev; -} - -static struct peer_chr * -peer_chr_find(const struct peer_svc *svc, uint16_t chr_val_handle, - struct peer_chr **out_prev) -{ - struct peer_chr *prev; - struct peer_chr *chr; - - prev = peer_chr_find_prev(svc, chr_val_handle); - if (prev == NULL) { - chr = SLIST_FIRST(&svc->chrs); - } else { - chr = SLIST_NEXT(prev, next); - } - - if (chr != NULL && chr->chr.val_handle != chr_val_handle) { - chr = NULL; - } - - if (out_prev != NULL) { - *out_prev = prev; - } - return chr; -} - -static void -peer_chr_delete(struct peer_chr *chr) -{ - struct peer_dsc *dsc; - - while ((dsc = SLIST_FIRST(&chr->dscs)) != NULL) { - SLIST_REMOVE_HEAD(&chr->dscs, next); - os_memblock_put(&peer_dsc_pool, dsc); - } - - os_memblock_put(&peer_chr_pool, chr); -} - -static int -peer_chr_add(struct peer *peer, uint16_t svc_start_handle, - const struct ble_gatt_chr *gatt_chr) -{ - struct peer_chr *prev; - struct peer_chr *chr; - struct peer_svc *svc; - - svc = peer_svc_find(peer, svc_start_handle, NULL); - if (svc == NULL) { - /* Can't find service for discovered characteristic; this shouldn't - * happen. - */ - assert(0); - return BLE_HS_EUNKNOWN; - } - - chr = peer_chr_find(svc, gatt_chr->def_handle, &prev); - if (chr != NULL) { - /* Characteristic already discovered. */ - return 0; - } - - chr = os_memblock_get(&peer_chr_pool); - if (chr == NULL) { - /* Out of memory. */ - return BLE_HS_ENOMEM; - } - memset(chr, 0, sizeof * chr); - - chr->chr = *gatt_chr; - - if (prev == NULL) { - SLIST_INSERT_HEAD(&svc->chrs, chr, next); - } else { - SLIST_NEXT(prev, next) = chr; - } - - return 0; -} - -static int -peer_chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error, - const struct ble_gatt_chr *chr, void *arg) -{ - struct peer *peer; - int rc; - - peer = arg; - assert(peer->conn_handle == conn_handle); - - switch (error->status) { - case 0: - rc = peer_chr_add(peer, peer->cur_svc->svc.start_handle, chr); - break; - - case BLE_HS_EDONE: - /* All characteristics in this service discovered; start discovering - * characteristics in the next service. - */ - if (peer->disc_prev_chr_val > 0) { - peer_disc_chrs(peer); - } - rc = 0; - break; - - default: - rc = error->status; - break; - } - - if (rc != 0) { - /* Error; abort discovery. */ - peer_disc_complete(peer, rc); - } - - return rc; -} - -static void -peer_disc_chrs(struct peer *peer) -{ - struct peer_svc *svc; - int rc; - - /* Search through the list of discovered service for the first service that - * contains undiscovered characteristics. Then, discover all - * characteristics belonging to that service. - */ - SLIST_FOREACH(svc, &peer->svcs, next) { - if (!peer_svc_is_empty(svc) && SLIST_EMPTY(&svc->chrs)) { - peer->cur_svc = svc; - rc = ble_gattc_disc_all_chrs(peer->conn_handle, - svc->svc.start_handle, - svc->svc.end_handle, - peer_chr_disced, peer); - if (rc != 0) { - peer_disc_complete(peer, rc); - } - return; - } - } - - /* All characteristics discovered. */ - peer_disc_dscs(peer); -} - -int -peer_svc_is_empty(const struct peer_svc *svc) -{ - return svc->svc.end_handle <= svc->svc.start_handle; -} - -static struct peer_svc * -peer_svc_find_prev(struct peer *peer, uint16_t svc_start_handle) -{ - struct peer_svc *prev; - struct peer_svc *svc; - - prev = NULL; - SLIST_FOREACH(svc, &peer->svcs, next) { - if (svc->svc.start_handle >= svc_start_handle) { - break; - } - - prev = svc; - } - - return prev; -} - -static struct peer_svc * -peer_svc_find(struct peer *peer, uint16_t svc_start_handle, - struct peer_svc **out_prev) -{ - struct peer_svc *prev; - struct peer_svc *svc; - - prev = peer_svc_find_prev(peer, svc_start_handle); - if (prev == NULL) { - svc = SLIST_FIRST(&peer->svcs); - } else { - svc = SLIST_NEXT(prev, next); - } - - if (svc != NULL && svc->svc.start_handle != svc_start_handle) { - svc = NULL; - } - - if (out_prev != NULL) { - *out_prev = prev; - } - return svc; -} - -static struct peer_svc * -peer_svc_find_range(struct peer *peer, uint16_t attr_handle) -{ - struct peer_svc *svc; - - SLIST_FOREACH(svc, &peer->svcs, next) { - if (svc->svc.start_handle <= attr_handle && - svc->svc.end_handle >= attr_handle) { - - return svc; - } - } - - return NULL; -} - -const struct peer_svc * -peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid) -{ - const struct peer_svc *svc; - - SLIST_FOREACH(svc, &peer->svcs, next) { - if (ble_uuid_cmp(&svc->svc.uuid.u, uuid) == 0) { - return svc; - } - } - - return NULL; -} - -const struct peer_chr * -peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, - const ble_uuid_t *chr_uuid) -{ - const struct peer_svc *svc; - const struct peer_chr *chr; - - svc = peer_svc_find_uuid(peer, svc_uuid); - if (svc == NULL) { - return NULL; - } - - SLIST_FOREACH(chr, &svc->chrs, next) { - if (ble_uuid_cmp(&chr->chr.uuid.u, chr_uuid) == 0) { - return chr; - } - } - - return NULL; -} - -const struct peer_dsc * -peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, - const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid) -{ - const struct peer_chr *chr; - const struct peer_dsc *dsc; - - chr = peer_chr_find_uuid(peer, svc_uuid, chr_uuid); - if (chr == NULL) { - return NULL; - } - - SLIST_FOREACH(dsc, &chr->dscs, next) { - if (ble_uuid_cmp(&dsc->dsc.uuid.u, dsc_uuid) == 0) { - return dsc; - } - } - - return NULL; -} - -static int -peer_svc_add(struct peer *peer, const struct ble_gatt_svc *gatt_svc) -{ - struct peer_svc *prev; - struct peer_svc *svc; - - svc = peer_svc_find(peer, gatt_svc->start_handle, &prev); - if (svc != NULL) { - /* Service already discovered. */ - return 0; - } - - svc = os_memblock_get(&peer_svc_pool); - if (svc == NULL) { - /* Out of memory. */ - return BLE_HS_ENOMEM; - } - memset(svc, 0, sizeof * svc); - - svc->svc = *gatt_svc; - SLIST_INIT(&svc->chrs); - - if (prev == NULL) { - SLIST_INSERT_HEAD(&peer->svcs, svc, next); - } else { - SLIST_INSERT_AFTER(prev, svc, next); - } - - return 0; -} - -static void -peer_svc_delete(struct peer_svc *svc) -{ - struct peer_chr *chr; - - while ((chr = SLIST_FIRST(&svc->chrs)) != NULL) { - SLIST_REMOVE_HEAD(&svc->chrs, next); - peer_chr_delete(chr); - } - - os_memblock_put(&peer_svc_pool, svc); -} - -static int -peer_svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, - const struct ble_gatt_svc *service, void *arg) -{ - struct peer *peer; - int rc; - - peer = arg; - assert(peer->conn_handle == conn_handle); - - switch (error->status) { - case 0: - rc = peer_svc_add(peer, service); - break; - - case BLE_HS_EDONE: - /* All services discovered; start discovering characteristics. */ - if (peer->disc_prev_chr_val > 0) { - peer_disc_chrs(peer); - } - rc = 0; - break; - - default: - rc = error->status; - break; - } - - if (rc != 0) { - /* Error; abort discovery. */ - peer_disc_complete(peer, rc); - } - - return rc; -} - - -int -peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, void *disc_cb_arg) -{ - struct peer_svc *svc; - struct peer *peer; - int rc; - - peer = peer_find(conn_handle); - if (peer == NULL) { - return BLE_HS_ENOTCONN; - } - - /* Undiscover everything first. */ - while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) { - SLIST_REMOVE_HEAD(&peer->svcs, next); - peer_svc_delete(svc); - } - - peer->disc_prev_chr_val = 1; - peer->disc_cb = disc_cb; - peer->disc_cb_arg = disc_cb_arg; - - rc = ble_gattc_disc_all_svcs(conn_handle, peer_svc_disced, peer); - if (rc != 0) { - return rc; - } - - return 0; -} - -int -peer_delete(uint16_t conn_handle) -{ - struct peer_svc *svc; - struct peer *peer; - int rc; - - peer = peer_find(conn_handle); - if (peer == NULL) { - return BLE_HS_ENOTCONN; - } - - SLIST_REMOVE(&peers, peer, peer, next); - - while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) { - SLIST_REMOVE_HEAD(&peer->svcs, next); - peer_svc_delete(svc); - } - - rc = os_memblock_put(&peer_pool, peer); - if (rc != 0) { - return BLE_HS_EOS; - } - - return 0; -} - -int -peer_add(uint16_t conn_handle) -{ - struct peer *peer; - - /* Make sure the connection handle is unique. */ - peer = peer_find(conn_handle); - if (peer != NULL) { - return BLE_HS_EALREADY; - } - - peer = os_memblock_get(&peer_pool); - if (peer == NULL) { - /* Out of memory. */ - return BLE_HS_ENOMEM; - } - - memset(peer, 0, sizeof * peer); - peer->conn_handle = conn_handle; - - SLIST_INSERT_HEAD(&peers, peer, next); - - return 0; -} - -static void -peer_free_mem(void) -{ - free(peer_mem); - peer_mem = NULL; - - free(peer_svc_mem); - peer_svc_mem = NULL; - - free(peer_chr_mem); - peer_chr_mem = NULL; - - free(peer_dsc_mem); - peer_dsc_mem = NULL; -} - -int -peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs) -{ - int rc; - - /* Free memory first in case this function gets called more than once. */ - peer_free_mem(); - - peer_mem = malloc( - OS_MEMPOOL_BYTES(max_peers, sizeof (struct peer))); - if (peer_mem == NULL) { - rc = BLE_HS_ENOMEM; - goto err; - } - - rc = os_mempool_init(&peer_pool, max_peers, - sizeof (struct peer), peer_mem, - "peer_pool"); - if (rc != 0) { - rc = BLE_HS_EOS; - goto err; - } - - peer_svc_mem = malloc( - OS_MEMPOOL_BYTES(max_svcs, sizeof (struct peer_svc))); - if (peer_svc_mem == NULL) { - rc = BLE_HS_ENOMEM; - goto err; - } - - rc = os_mempool_init(&peer_svc_pool, max_svcs, - sizeof (struct peer_svc), peer_svc_mem, - "peer_svc_pool"); - if (rc != 0) { - rc = BLE_HS_EOS; - goto err; - } - - peer_chr_mem = malloc( - OS_MEMPOOL_BYTES(max_chrs, sizeof (struct peer_chr))); - if (peer_chr_mem == NULL) { - rc = BLE_HS_ENOMEM; - goto err; - } - - rc = os_mempool_init(&peer_chr_pool, max_chrs, - sizeof (struct peer_chr), peer_chr_mem, - "peer_chr_pool"); - if (rc != 0) { - rc = BLE_HS_EOS; - goto err; - } - - peer_dsc_mem = malloc( - OS_MEMPOOL_BYTES(max_dscs, sizeof (struct peer_dsc))); - if (peer_dsc_mem == NULL) { - rc = BLE_HS_ENOMEM; - goto err; - } - - rc = os_mempool_init(&peer_dsc_pool, max_dscs, - sizeof (struct peer_dsc), peer_dsc_mem, - "peer_dsc_pool"); - if (rc != 0) { - rc = BLE_HS_EOS; - goto err; - } - - return 0; - -err: - peer_free_mem(); - return rc; -} diff --git a/examples/bluetooth/nimble/bleprph/CMakeLists.txt b/examples/bluetooth/nimble/bleprph/CMakeLists.txt index 0e8a4553f9..1156a75370 100644 --- a/examples/bluetooth/nimble/bleprph/CMakeLists.txt +++ b/examples/bluetooth/nimble/bleprph/CMakeLists.txt @@ -2,5 +2,7 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) +set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_LIST_DIR}/../common/nimble_peripheral_utils) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(bleprph) diff --git a/examples/bluetooth/nimble/bleprph/main/CMakeLists.txt b/examples/bluetooth/nimble/bleprph/main/CMakeLists.txt index 621b69cbd3..4195d94b04 100644 --- a/examples/bluetooth/nimble/bleprph/main/CMakeLists.txt +++ b/examples/bluetooth/nimble/bleprph/main/CMakeLists.txt @@ -1,8 +1,6 @@ set(srcs "main.c" - "gatt_svr.c" - "misc.c" - "scli.c") + "gatt_svr.c") idf_component_register(SRCS "${srcs}" - INCLUDE_DIRS ".") + INCLUDE_DIRS ".") target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/examples/bluetooth/nimble/bleprph/main/bleprph.h b/examples/bluetooth/nimble/bleprph/main/bleprph.h index cf90b9fb6a..f6b89a618f 100644 --- a/examples/bluetooth/nimble/bleprph/main/bleprph.h +++ b/examples/bluetooth/nimble/bleprph/main/bleprph.h @@ -23,6 +23,7 @@ #include #include "nimble/ble.h" #include "modlog/modlog.h" +#include "esp_peripheral.h" #ifdef __cplusplus extern "C" { #endif @@ -41,14 +42,6 @@ struct ble_gatt_register_ctxt; void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); int gatt_svr_init(void); -/* Console */ -int scli_init(void); -int scli_receive_key(int *key); - -/** Misc. */ -void print_bytes(const uint8_t *bytes, int len); -void print_addr(const void *addr); - #ifdef __cplusplus } #endif diff --git a/examples/bluetooth/nimble/bleprph/main/misc.c b/examples/bluetooth/nimble/bleprph/main/misc.c deleted file mode 100644 index 640b7ff8b6..0000000000 --- a/examples/bluetooth/nimble/bleprph/main/misc.c +++ /dev/null @@ -1,43 +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 "bleprph.h" - -/** - * Utility function to log an array of bytes. - */ -void -print_bytes(const uint8_t *bytes, int len) -{ - int i; - - for (i = 0; i < len; i++) { - MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); - } -} - -void -print_addr(const void *addr) -{ - const uint8_t *u8p; - - u8p = addr; - MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x", - u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); -} diff --git a/examples/bluetooth/nimble/bleprph/main/scli.c b/examples/bluetooth/nimble/bleprph/main/scli.c deleted file mode 100644 index 173e0a9166..0000000000 --- a/examples/bluetooth/nimble/bleprph/main/scli.c +++ /dev/null @@ -1,159 +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 "esp_log.h" -#include -#include -#include -#include -#include -#include -#include -#include "bleprph.h" - -#define BLE_RX_TIMEOUT (30000 / portTICK_PERIOD_MS) - -static TaskHandle_t cli_task; -static QueueHandle_t cli_handle; -static int stop; - -static int enter_passkey_handler(int argc, char *argv[]) -{ - int key; - char pkey[8]; - int num; - - if (argc != 2) { - return -1; - } - - sscanf(argv[1], "%s", pkey); - ESP_LOGI("You entered", "%s %s", argv[0], argv[1]); - num = pkey[0]; - - if (isalpha(num)) { - if ((strcasecmp(pkey, "Y") == 0) || (strcasecmp(pkey, "Yes") == 0)) { - key = 1; - xQueueSend(cli_handle, &key, 0); - } else { - key = 0; - xQueueSend(cli_handle, &key, 0); - } - } else { - sscanf(pkey, "%d", &key); - xQueueSend(cli_handle, &key, 0); - } - - return 0; -} - -int scli_receive_key(int *console_key) -{ - return xQueueReceive(cli_handle, console_key, BLE_RX_TIMEOUT); -} - -static esp_console_cmd_t cmds[] = { - { - .command = "key", - .help = "", - .func = enter_passkey_handler, - }, -}; - -static int ble_register_cli(void) -{ - int cmds_num = sizeof(cmds) / sizeof(esp_console_cmd_t); - int i; - for (i = 0; i < cmds_num; i++) { - esp_console_cmd_register(&cmds[i]); - } - return 0; -} - -static void scli_task(void *arg) -{ - int uart_num = (int) arg; - uint8_t linebuf[256]; - int i, cmd_ret; - esp_err_t ret; - QueueHandle_t uart_queue; - uart_event_t event; - - uart_driver_install(uart_num, 256, 0, 8, &uart_queue, 0); - /* Initialize the console */ - esp_console_config_t console_config = { - .max_cmdline_args = 8, - .max_cmdline_length = 256, - }; - - esp_console_init(&console_config); - - while (!stop) { - i = 0; - memset(linebuf, 0, sizeof(linebuf)); - do { - ret = xQueueReceive(uart_queue, (void * )&event, (TickType_t)portMAX_DELAY); - if (ret != pdPASS) { - if (stop == 1) { - break; - } else { - continue; - } - } - if (event.type == UART_DATA) { - while (uart_read_bytes(uart_num, (uint8_t *) &linebuf[i], 1, 0)) { - if (linebuf[i] == '\r') { - uart_write_bytes(uart_num, "\r\n", 2); - } else { - uart_write_bytes(uart_num, (char *) &linebuf[i], 1); - } - i++; - } - } - } while ((i < 255) && linebuf[i - 1] != '\r'); - if (stop) { - break; - } - /* Remove the truncating \r\n */ - linebuf[strlen((char *)linebuf) - 1] = '\0'; - ret = esp_console_run((char *) linebuf, &cmd_ret); - if (ret < 0) { - break; - } - } - vTaskDelete(NULL); -} - -int scli_init(void) -{ - /* Register CLI "key " to accept input from user during pairing */ - ble_register_cli(); - - xTaskCreate(scli_task, "scli_cli", 4096, (void *) 0, 3, &cli_task); - if (cli_task == NULL) { - return ESP_FAIL; - } - cli_handle = xQueueCreate( 1, sizeof(int) ); - if (cli_handle == NULL) { - return ESP_FAIL; - } - return ESP_OK; -} diff --git a/examples/bluetooth/nimble/common/nimble_central_utils/CMakeLists.txt b/examples/bluetooth/nimble/common/nimble_central_utils/CMakeLists.txt new file mode 100644 index 0000000000..f6ec8bde8d --- /dev/null +++ b/examples/bluetooth/nimble/common/nimble_central_utils/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "misc.c" "peer.c" + INCLUDE_DIRS "." + PRIV_REQUIRES bt) diff --git a/examples/bluetooth/nimble/common/nimble_central_utils/esp_central.h b/examples/bluetooth/nimble/common/nimble_central_utils/esp_central.h new file mode 100644 index 0000000000..740275d426 --- /dev/null +++ b/examples/bluetooth/nimble/common/nimble_central_utils/esp_central.h @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef H_ESP_CENTRAL_ +#define H_ESP_CENTRAL_ + +#include "modlog/modlog.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** Misc. */ +void print_bytes(const uint8_t *bytes, int len); +void print_mbuf(const struct os_mbuf *om); +void print_mbuf_data(const struct os_mbuf *om); +char *addr_str(const void *addr); +void print_uuid(const ble_uuid_t *uuid); +void print_conn_desc(const struct ble_gap_conn_desc *desc); +void print_adv_fields(const struct ble_hs_adv_fields *fields); +void ext_print_adv_report(const void *param); + +/** Peer. */ +struct peer_dsc { + SLIST_ENTRY(peer_dsc) next; + struct ble_gatt_dsc dsc; +}; +SLIST_HEAD(peer_dsc_list, peer_dsc); + +struct peer_chr { + SLIST_ENTRY(peer_chr) next; + struct ble_gatt_chr chr; + + struct peer_dsc_list dscs; +}; +SLIST_HEAD(peer_chr_list, peer_chr); + +struct peer_svc { + SLIST_ENTRY(peer_svc) next; + struct ble_gatt_svc svc; + + struct peer_chr_list chrs; +}; +SLIST_HEAD(peer_svc_list, peer_svc); + +struct peer; +typedef void peer_disc_fn(const struct peer *peer, int status, void *arg); + +struct peer { + SLIST_ENTRY(peer) next; + + uint16_t conn_handle; + + /** List of discovered GATT services. */ + struct peer_svc_list svcs; + + /** Keeps track of where we are in the service discovery process. */ + uint16_t disc_prev_chr_val; + struct peer_svc *cur_svc; + + /** Callback that gets executed when service discovery completes. */ + peer_disc_fn *disc_cb; + void *disc_cb_arg; +}; + +int peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, + void *disc_cb_arg); +const struct peer_dsc * +peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, + const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid); +const struct peer_chr * +peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid, + const ble_uuid_t *chr_uuid); +const struct peer_svc * +peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid); +int peer_delete(uint16_t conn_handle); +int peer_add(uint16_t conn_handle); +int peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs); +struct peer * +peer_find(uint16_t conn_handle); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/misc.c b/examples/bluetooth/nimble/common/nimble_central_utils/misc.c similarity index 99% rename from examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/misc.c rename to examples/bluetooth/nimble/common/nimble_central_utils/misc.c index 5a57815e77..41f3dfff46 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/misc.c +++ b/examples/bluetooth/nimble/common/nimble_central_utils/misc.c @@ -9,7 +9,7 @@ #include #include "host/ble_hs.h" #include "host/ble_uuid.h" -#include "coc_blecent.h" +#include "esp_central.h" /** * Utility function to log an array of bytes. diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/peer.c b/examples/bluetooth/nimble/common/nimble_central_utils/peer.c similarity index 99% rename from examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/peer.c rename to examples/bluetooth/nimble/common/nimble_central_utils/peer.c index 5f0112766b..30cb1338af 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/peer.c +++ b/examples/bluetooth/nimble/common/nimble_central_utils/peer.c @@ -7,7 +7,7 @@ #include #include #include "host/ble_hs.h" -#include "coc_blecent.h" +#include "esp_central.h" static void *peer_svc_mem; static struct os_mempool peer_svc_pool; diff --git a/examples/bluetooth/nimble/common/nimble_peripheral_utils/CMakeLists.txt b/examples/bluetooth/nimble/common/nimble_peripheral_utils/CMakeLists.txt new file mode 100644 index 0000000000..963f158e7f --- /dev/null +++ b/examples/bluetooth/nimble/common/nimble_peripheral_utils/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "misc.c" "scli.c" + INCLUDE_DIRS "." + PRIV_REQUIRES bt console driver) diff --git a/examples/bluetooth/nimble/common/nimble_peripheral_utils/esp_peripheral.h b/examples/bluetooth/nimble/common/nimble_peripheral_utils/esp_peripheral.h new file mode 100644 index 0000000000..9a68ee7166 --- /dev/null +++ b/examples/bluetooth/nimble/common/nimble_peripheral_utils/esp_peripheral.h @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef H_ESP_PERIPHERAL_ +#define H_ESP_PERIPHERAL_ + +#include +#include "nimble/ble.h" +#include "modlog/modlog.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* Console */ +int scli_init(void); +int scli_receive_key(int *key); + +/** Misc. */ +void print_bytes(const uint8_t *bytes, int len); +void print_addr(const void *addr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/misc.c b/examples/bluetooth/nimble/common/nimble_peripheral_utils/misc.c similarity index 95% rename from examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/misc.c rename to examples/bluetooth/nimble/common/nimble_peripheral_utils/misc.c index 836e7b0864..543bfe7f6c 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/misc.c +++ b/examples/bluetooth/nimble/common/nimble_peripheral_utils/misc.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ -#include "coc_bleprph.h" +#include "esp_peripheral.h" /** * Utility function to log an array of bytes. diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/scli.c b/examples/bluetooth/nimble/common/nimble_peripheral_utils/scli.c similarity index 99% rename from examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/scli.c rename to examples/bluetooth/nimble/common/nimble_peripheral_utils/scli.c index f20aceaa00..0a5b4565ce 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/scli.c +++ b/examples/bluetooth/nimble/common/nimble_peripheral_utils/scli.c @@ -14,7 +14,7 @@ #include #include #include -#include "coc_bleprph.h" +#include "esp_peripheral.h" #define BLE_RX_TIMEOUT (30000 / portTICK_PERIOD_MS)