diff --git a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/bl_host_assist.c b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/bl_host_assist.c deleted file mode 100644 index d62716d4..00000000 --- a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/bl_host_assist.c +++ /dev/null @@ -1,363 +0,0 @@ -#include "ble_lib_api.h" -#include "bluetooth.h" -#include "conn.h" -#include "hci_core.h" -#include "hci_driver.h" -#include "byteorder.h" -#include "log.h" -#include "errno.h" - -struct blhast_le_adv_data { - u8_t ad[31]; - size_t ad_len; -}; - -static struct bt_le_scan_param blhast_le_scan_param; -static struct bt_le_adv_param blhast_le_adv_param; -static struct blhast_le_adv_data blhast_le_ad; -static struct blhast_le_adv_data blhast_le_sd; -static bt_le_scan_cb_t *blhast_le_scan_cb; - -static void blhast_ble_scan_assist_cb(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb); -static void blhast_ble_adv_assist_cb(const struct bt_le_adv_param *param, const struct bt_data *ad, - size_t ad_len, const struct bt_data *sd, size_t sd_len); - -static struct blhast_cb assist_cb = { - .le_scan_cb = blhast_ble_scan_assist_cb, - .le_adv_cb = blhast_ble_adv_assist_cb, -}; - -extern struct bt_dev bt_dev; - -static void blhast_ble_scan_assist_cb(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb) -{ - memcpy(&blhast_le_scan_param, param, sizeof(struct bt_le_scan_param)); - blhast_le_scan_cb = cb; -} - -static void blhast_ble_get_ad(const struct bt_data *ad, size_t ad_len, uint8_t *output) -{ - int i; - uint8_t data_len = 0; - - for (i = 0; i < ad_len; i++) { - *(output + data_len) = ad[i].type; - data_len++; - - *(output + data_len) = ad[i].data_len; - data_len++; - - memcpy(output + data_len, ad[i].data, ad[i].data_len); - - data_len += ad[i].data_len; - } -} - -static void blhast_ble_construct_ad(struct blhast_le_adv_data *adv_data, struct bt_data *output) -{ - int i; - size_t ad_len = adv_data->ad_len; - u8_t *p_ad = adv_data->ad; - - for (i = 0; i < ad_len; i++) { - memcpy(&output[i], p_ad, 2); //type, data_len - p_ad += 2; - output[i].data = (const u8_t *)p_ad; - p_ad += output[i].data_len; - } -} - -static void blhast_ble_adv_assist_cb(const struct bt_le_adv_param *param, const struct bt_data *ad, - size_t ad_len, const struct bt_data *sd, size_t sd_len) -{ - memcpy(&blhast_le_adv_param, param, sizeof(struct bt_le_adv_param)); - - if (ad) { - blhast_le_ad.ad_len = ad_len; - memset(blhast_le_ad.ad, 0, sizeof(blhast_le_ad.ad)); - blhast_ble_get_ad(ad, ad_len, blhast_le_ad.ad); - } - - if (sd) { - blhast_le_sd.ad_len = sd_len; - memset(blhast_le_sd.ad, 0, sizeof(blhast_le_sd.ad)); - blhast_ble_get_ad(sd, sd_len, blhast_le_sd.ad); - } -} - -static int blhast_common_reset(void) -{ - struct net_buf *rsp; - int err; - - if (!(bt_dev.drv->quirks & BT_QUIRK_NO_RESET)) { - /* Send HCI_RESET */ - err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, &rsp); - if (err) { - return err; - } - bt_hci_reset_complete(rsp); - net_buf_unref(rsp); - } - -#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) - err = bt_set_flow_control(); - if (err) { - return err; - } -#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */ - - return 0; -} - -static int blhast_ble_reset(void) -{ - struct bt_hci_cp_write_le_host_supp *cp_le; - struct net_buf *buf, *rsp; - int err; - - if (!BT_FEAT_LE(bt_dev.features)) { - BT_ERR("Non-LE capable controller detected!"); - return -ENODEV; - } - - if (BT_FEAT_BREDR(bt_dev.features)) { - buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_LE_HOST_SUPP, - sizeof(*cp_le)); - if (!buf) { - return -ENOBUFS; - } - - cp_le = net_buf_add(buf, sizeof(*cp_le)); - - /* Explicitly enable LE for dual-mode controllers */ - cp_le->le = 0x01; - cp_le->simul = 0x00; - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_WRITE_LE_HOST_SUPP, buf, - NULL); - if (err) { - return err; - } - } - - if (IS_ENABLED(CONFIG_BT_CONN) && - IS_ENABLED(CONFIG_BT_DATA_LEN_UPDATE) && - BT_FEAT_LE_DLE(bt_dev.le.features)) { - struct bt_hci_cp_le_write_default_data_len *cp; - struct bt_hci_rp_le_read_max_data_len *rp; - u16_t tx_octets, tx_time; - - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_MAX_DATA_LEN, NULL, - &rsp); - if (err) { - return err; - } - - rp = (void *)rsp->data; - tx_octets = sys_le16_to_cpu(rp->max_tx_octets); - tx_time = sys_le16_to_cpu(rp->max_tx_time); - net_buf_unref(rsp); - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN, - sizeof(*cp)); - if (!buf) { - return -ENOBUFS; - } - - cp = net_buf_add(buf, sizeof(*cp)); - cp->max_tx_octets = sys_cpu_to_le16(tx_octets); - cp->max_tx_time = sys_cpu_to_le16(tx_time); - - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN, - buf, NULL); - if (err) { - return err; - } - } - - return bt_le_set_event_mask(); -} - -#if defined(CONFIG_BT_BREDR) -static int blhast_br_reset(void) -{ - struct net_buf *buf; - struct bt_hci_cp_write_ssp_mode *ssp_cp; - struct bt_hci_cp_write_inquiry_mode *inq_cp; - struct bt_hci_write_local_name *name_cp; - int err; - - /* Set SSP mode */ - buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_SSP_MODE, sizeof(*ssp_cp)); - if (!buf) { - return -ENOBUFS; - } - - ssp_cp = net_buf_add(buf, sizeof(*ssp_cp)); - ssp_cp->mode = 0x01; - err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_SSP_MODE, buf, NULL); - if (err) { - return err; - } - - /* Enable Inquiry results with RSSI or extended Inquiry */ - buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_INQUIRY_MODE, sizeof(*inq_cp)); - if (!buf) { - return -ENOBUFS; - } - - inq_cp = net_buf_add(buf, sizeof(*inq_cp)); - inq_cp->mode = 0x02; - err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_INQUIRY_MODE, buf, NULL); - if (err) { - return err; - } - - /* Set local name */ - buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_LOCAL_NAME, sizeof(*name_cp)); - if (!buf) { - return -ENOBUFS; - } - - name_cp = net_buf_add(buf, sizeof(*name_cp)); - strncpy((char *)name_cp->local_name, CONFIG_BT_DEVICE_NAME, - sizeof(name_cp->local_name)); - - err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_LOCAL_NAME, buf, NULL); - if (err) { - return err; - } - - /* Set page timeout*/ - buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_PAGE_TIMEOUT, sizeof(u16_t)); - if (!buf) { - return -ENOBUFS; - } - - net_buf_add_le16(buf, CONFIG_BT_PAGE_TIMEOUT); - - err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_PAGE_TIMEOUT, buf, NULL); - if (err) { - return err; - } - - /* Enable BR/EDR SC if supported */ - if (BT_FEAT_SC(bt_dev.features)) { - struct bt_hci_cp_write_sc_host_supp *sc_cp; - - buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_SC_HOST_SUPP, - sizeof(*sc_cp)); - if (!buf) { - return -ENOBUFS; - } - - sc_cp = net_buf_add(buf, sizeof(*sc_cp)); - sc_cp->sc_support = 0x01; - - err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_SC_HOST_SUPP, buf, - NULL); - if (err) { - return err; - } - } - - return 0; -} -#endif - -static int blhast_host_hci_reset(void) -{ - int err; - ATOMIC_DEFINE(old_flags, BT_DEV_NUM_FLAGS); - memcpy(old_flags, bt_dev.flags, sizeof(old_flags)); - - err = blhast_common_reset(); - - if (err) { - return err; - } - - err = blhast_ble_reset(); - if (err) { - return err; - } - -#if defined(CONFIG_BT_BREDR) - if (BT_FEAT_BREDR(bt_dev.features)) { - err = blhast_br_reset(); - if (err) { - return err; - } - } -#endif - - err = bt_set_event_mask(); - if (err) { - return err; - } - - memcpy(bt_dev.flags, old_flags, sizeof(old_flags)); - - return 0; -} - -static void blhast_host_state_restore(void) -{ - struct bt_data *ad = NULL; - struct bt_data *sd = NULL; - k_sem_give(&bt_dev.ncmd_sem); - net_buf_unref(bt_dev.sent_cmd); - bt_dev.sent_cmd = NULL; - - blhast_host_hci_reset(); - -#if defined(CONFIG_BT_CONN) - bt_notify_disconnected(); -#endif - - atomic_set_bit(bt_dev.flags, BT_DEV_ASSIST_RUN); - -#if defined(CONFIG_BT_OBSERVER) - if (atomic_test_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) { - BT_WARN("Restore BLE scan\r\n"); - atomic_clear_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN); - atomic_clear_bit(bt_dev.flags, BT_DEV_SCANNING); - bt_le_scan_start((const struct bt_le_scan_param *)&blhast_le_scan_param, blhast_le_scan_cb); - } -#endif - - if (atomic_test_and_clear_bit(bt_dev.flags, BT_DEV_ADVERTISING)) { - BT_WARN("Restore BLE advertising\r\n"); - if (blhast_le_ad.ad_len > 0) { - ad = k_malloc(sizeof(struct bt_data) * blhast_le_ad.ad_len); - blhast_ble_construct_ad(&blhast_le_ad, ad); - } - if (blhast_le_sd.ad_len > 0) { - sd = k_malloc(sizeof(struct bt_data) * blhast_le_sd.ad_len); - blhast_ble_construct_ad(&blhast_le_sd, sd); - } - - bt_le_adv_start((const struct bt_le_adv_param *)&blhast_le_adv_param, ad, - blhast_le_ad.ad_len, sd, blhast_le_sd.ad_len); - - if (ad) - k_free(ad); - if (sd) - k_free(sd); - } - - atomic_clear_bit(bt_dev.flags, BT_DEV_ASSIST_RUN); -} - -void blhast_bt_reset(void) -{ - ble_controller_reset(); - blhast_host_state_restore(); -} - -void blhast_init(void) -{ - memset(&blhast_le_ad, 0, sizeof(struct blhast_le_adv_data)); - memset(&blhast_le_sd, 0, sizeof(struct blhast_le_adv_data)); - bt_register_host_assist_cb(&assist_cb); -} diff --git a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/conn.c b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/conn.c index 86b90b3e..6644abcd 100644 --- a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/conn.c +++ b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/conn.c @@ -35,7 +35,7 @@ #include "att_internal.h" #include "gatt_internal.h" #if defined(BFLB_BLE) -#include "config.h" +#include "ble_config.h" extern struct k_sem g_poll_sem; #endif diff --git a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/gatt.c b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/gatt.c index a9c4d916..e6ed08ae 100644 --- a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/gatt.c +++ b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/gatt.c @@ -30,7 +30,7 @@ #include #include #if defined(BFLB_BLE) -#include "config.h" +#include "ble_config.h" #include #endif diff --git a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/iso.c b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/iso.c deleted file mode 100644 index 7ab175d1..00000000 --- a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/iso.c +++ /dev/null @@ -1,1111 +0,0 @@ -/* Bluetooth ISO */ - -/* - * Copyright (c) 2020 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "hci_core.h" -#include "conn_internal.h" -#include "iso_internal.h" - -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_AUDIO_DEBUG_ISO) -#define LOG_MODULE_NAME bt_iso -#include "log.h" - -#if !defined(BFLB_DYNAMIC_ALLOC_MEM) -NET_BUF_POOL_FIXED_DEFINE(iso_tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT, - CONFIG_BT_ISO_TX_MTU, NULL); -NET_BUF_POOL_FIXED_DEFINE(iso_rx_pool, CONFIG_BT_ISO_RX_BUF_COUNT, - CONFIG_BT_ISO_RX_MTU, NULL); -#if CONFIG_BT_ISO_TX_FRAG_COUNT > 0 -NET_BUF_POOL_FIXED_DEFINE(iso_frag_pool, CONFIG_BT_ISO_TX_FRAG_COUNT, - CONFIG_BT_ISO_TX_MTU, NULL); -#endif - -#else //defined(BFLB_DYNAMIC_ALLOC_MEM) - -struct net_buf_pool iso_tx_pool; -struct net_buf_pool iso_rx_pool; -#if CONFIG_BT_ISO_TX_FRAG_COUNT > 0 -struct net_buf_pool iso_frag_pool; -#endif - -#endif - -/* TODO: Allow more than one server? */ -static struct bt_iso_server *iso_server; -struct bt_conn iso_conns[CONFIG_BT_MAX_ISO_CONN]; - -struct bt_iso_data_path { - /* Data Path direction */ - uint8_t dir; - /* Data Path ID */ - uint8_t pid; - /* Data Path param reference */ - struct bt_iso_chan_path *path; -}; - -struct net_buf *bt_iso_get_rx(uint32_t timeout) -{ - struct net_buf *buf = net_buf_alloc(&iso_rx_pool, timeout); - - if (buf) { - net_buf_reserve(buf, BT_BUF_RESERVE); - bt_buf_set_type(buf, BT_BUF_ISO_IN); - } - - return buf; -} - -void hci_iso(struct net_buf *buf) -{ - struct bt_hci_iso_hdr *hdr; - uint16_t handle, len; - struct bt_conn *conn; - uint8_t flags; - - BT_DBG("buf %p", buf); - - BT_ASSERT(buf->len >= sizeof(*hdr)); - - hdr = net_buf_pull_mem(buf, sizeof(*hdr)); - len = sys_le16_to_cpu(hdr->len); - handle = sys_le16_to_cpu(hdr->handle); - flags = bt_iso_flags(handle); - - iso(buf)->handle = bt_iso_handle(handle); - iso(buf)->index = BT_CONN_ID_INVALID; - - BT_DBG("handle %u len %u flags %u", iso(buf)->handle, len, flags); - - if (buf->len != len) { - BT_ERR("ISO data length mismatch (%u != %u)", buf->len, len); - net_buf_unref(buf); - return; - } - - conn = bt_conn_lookup_handle(iso(buf)->handle); - if (!conn) { - BT_ERR("Unable to find conn for handle %u", iso(buf)->handle); - net_buf_unref(buf); - return; - } - - iso(buf)->index = bt_conn_index(conn); - - bt_conn_recv(conn, buf, flags); - bt_conn_unref(conn); -} - -void hci_le_cis_estabilished(struct net_buf *buf) -{ - struct bt_hci_evt_le_cis_established *evt = (void *)buf->data; - uint16_t handle = sys_le16_to_cpu(evt->conn_handle); - struct bt_conn *conn; - - BT_DBG("status %u handle %u", evt->status, handle); - - /* ISO connection handles are already assigned at this point */ - conn = bt_conn_lookup_handle(handle); - if (!conn) { - BT_ERR("No connection found for handle %u", handle); - return; - } - - __ASSERT(conn->type == BT_CONN_TYPE_ISO, "Invalid connection type"); - - if (!evt->status) { - /* TODO: Add CIG sync delay */ - bt_conn_set_state(conn, BT_CONN_CONNECTED); - bt_conn_unref(conn); - return; - } - - conn->err = evt->status; - bt_iso_disconnected(conn); - bt_conn_unref(conn); -} - -int hci_le_reject_cis(uint16_t handle, uint8_t reason) -{ - struct bt_hci_cp_le_reject_cis *cp; - struct net_buf *buf; - int err; - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_REJECT_CIS, sizeof(*cp)); - if (!buf) { - return -ENOBUFS; - } - - cp = net_buf_add(buf, sizeof(*cp)); - cp->handle = sys_cpu_to_le16(handle); - cp->reason = reason; - - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_REJECT_CIS, buf, NULL); - if (err) { - return err; - } - - return 0; -} - -int hci_le_accept_cis(uint16_t handle) -{ - struct bt_hci_cp_le_accept_cis *cp; - struct net_buf *buf; - int err; - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_ACCEPT_CIS, sizeof(*cp)); - if (!buf) { - return -ENOBUFS; - } - - cp = net_buf_add(buf, sizeof(*cp)); - cp->handle = sys_cpu_to_le16(handle); - - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_ACCEPT_CIS, buf, NULL); - if (err) { - return err; - } - - return 0; -} - -void hci_le_cis_req(struct net_buf *buf) -{ - struct bt_hci_evt_le_cis_req *evt = (void *)buf->data; - uint16_t acl_handle = sys_le16_to_cpu(evt->acl_handle); - uint16_t cis_handle = sys_le16_to_cpu(evt->cis_handle); - struct bt_conn *conn, *iso; - int err; - - BT_DBG("acl_handle %u cis_handle %u cig_id %u cis %u", - acl_handle, cis_handle, evt->cig_id, evt->cis_id); - - /* Lookup existing connection with same handle */ - iso = bt_conn_lookup_handle(cis_handle); - if (iso) { - BT_ERR("Invalid ISO handle %u", cis_handle); - hci_le_reject_cis(cis_handle, BT_HCI_ERR_CONN_LIMIT_EXCEEDED); - bt_conn_unref(iso); - return; - } - - /* Lookup ACL connection to attach */ - conn = bt_conn_lookup_handle(acl_handle); - if (!conn) { - BT_ERR("Invalid ACL handle %u", acl_handle); - hci_le_reject_cis(cis_handle, BT_HCI_ERR_UNKNOWN_CONN_ID); - return; - } - - /* Add ISO connection */ - iso = bt_conn_add_iso(conn); - - bt_conn_unref(conn); - - if (!iso) { - BT_ERR("Could not create and add ISO to conn %u", acl_handle); - hci_le_reject_cis(cis_handle, - BT_HCI_ERR_INSUFFICIENT_RESOURCES); - return; - } - - /* Request application to accept */ - err = bt_iso_accept(iso); - if (err) { - BT_DBG("App rejected ISO %d", err); - bt_iso_cleanup(iso); - hci_le_reject_cis(cis_handle, - BT_HCI_ERR_INSUFFICIENT_RESOURCES); - return; - } - - iso->handle = cis_handle; - iso->role = BT_HCI_ROLE_SLAVE; - bt_conn_set_state(iso, BT_CONN_CONNECT); - - hci_le_accept_cis(cis_handle); -} - -int hci_le_remove_cig(uint8_t cig_id) -{ - struct bt_hci_cp_le_remove_cig *req; - struct net_buf *buf; - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_REMOVE_CIG, sizeof(*req)); - if (!buf) { - return -ENOBUFS; - } - - req = net_buf_add(buf, sizeof(*req)); - - memset(req, 0, sizeof(*req)); - - req->cig_id = cig_id; - - return bt_hci_cmd_send_sync(BT_HCI_OP_LE_REMOVE_CIG, buf, NULL); -} - -void bt_iso_cleanup(struct bt_conn *conn) -{ - int i; - - bt_conn_unref(conn->iso.acl); - conn->iso.acl = NULL; - - /* Check if conn is last of CIG */ - for (i = 0; i < CONFIG_BT_MAX_ISO_CONN; i++) { - if (conn == &iso_conns[i]) { - continue; - } - - if (atomic_get(&iso_conns[i].ref) && - iso_conns[i].iso.cig_id == conn->iso.cig_id) { - break; - } - } - - if (i == CONFIG_BT_MAX_ISO_CONN) { - hci_le_remove_cig(conn->iso.cig_id); - } - - bt_conn_unref(conn); -} - -struct bt_conn *iso_new(void) -{ - return iso_conn_new(iso_conns, ARRAY_SIZE(iso_conns)); -} - -struct bt_conn *bt_conn_add_iso(struct bt_conn *acl) -{ - struct bt_conn *conn = iso_new(); - - if (!conn) { - return NULL; - } - - conn->iso.acl = bt_conn_ref(acl); - conn->type = BT_CONN_TYPE_ISO; - sys_slist_init(&conn->channels); - - return conn; -} - -#if defined(CONFIG_NET_BUF_LOG) -struct net_buf *bt_iso_create_pdu_timeout_debug(struct net_buf_pool *pool, - size_t reserve, - k_timeout_t timeout, - const char *func, int line) -#else -struct net_buf *bt_iso_create_pdu_timeout(struct net_buf_pool *pool, - size_t reserve, uint32_t timeout) -#endif -{ - if (!pool) { - pool = &iso_tx_pool; - } - - reserve += sizeof(struct bt_hci_iso_data_hdr); - -#if defined(CONFIG_NET_BUF_LOG) - return bt_conn_create_pdu_timeout_debug(pool, reserve, timeout, func, - line); -#else - return bt_conn_create_pdu_timeout(pool, reserve, timeout); -#endif -} - -#if defined(CONFIG_NET_BUF_LOG) -struct net_buf *bt_iso_create_frag_timeout_debug(size_t reserve, - k_timeout_t timeout, - const char *func, int line) -#else -struct net_buf *bt_iso_create_frag_timeout(size_t reserve, uint32_t timeout) -#endif -{ - struct net_buf_pool *pool = NULL; - -#if CONFIG_BT_L2CAP_TX_FRAG_COUNT > 0 - pool = &iso_frag_pool; -#endif - -#if defined(CONFIG_NET_BUF_LOG) - return bt_conn_create_pdu_timeout_debug(pool, reserve, timeout, func, - line); -#else - return bt_conn_create_pdu_timeout(pool, reserve, timeout); -#endif -} - -static struct net_buf *hci_le_set_cig_params(struct bt_iso_create_param *param) -{ - struct bt_hci_cis_params *cis; - struct bt_hci_cp_le_set_cig_params *req; - struct net_buf *buf; - struct net_buf *rsp; - int i, err; - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_CIG_PARAMS, - sizeof(*req) + sizeof(*cis) * param->num_conns); - if (!buf) { - return NULL; - } - - req = net_buf_add(buf, sizeof(*req)); - - memset(req, 0, sizeof(*req)); - - req->cig_id = param->conns[0]->iso.cig_id; - sys_put_le24(param->chans[0]->qos->interval, req->m_interval); - sys_put_le24(param->chans[0]->qos->interval, req->s_interval); - req->sca = param->chans[0]->qos->sca; - req->packing = param->chans[0]->qos->packing; - req->framing = param->chans[0]->qos->framing; - req->m_latency = sys_cpu_to_le16(param->chans[0]->qos->latency); - req->s_latency = sys_cpu_to_le16(param->chans[0]->qos->latency); - req->num_cis = param->num_conns; - - /* Program the cis parameters */ - for (i = 0; i < param->num_conns; i++) { - cis = net_buf_add(buf, sizeof(*cis)); - - memset(cis, 0, sizeof(*cis)); - - cis->cis_id = param->conns[i]->iso.cis_id; - - switch (param->chans[i]->qos->dir) { - case BT_ISO_CHAN_QOS_IN: - cis->m_sdu = param->chans[i]->qos->sdu; - break; - case BT_ISO_CHAN_QOS_OUT: - cis->s_sdu = param->chans[i]->qos->sdu; - break; - case BT_ISO_CHAN_QOS_INOUT: - cis->m_sdu = param->chans[i]->qos->sdu; - cis->s_sdu = param->chans[i]->qos->sdu; - break; - } - - cis->m_phy = param->chans[i]->qos->phy; - cis->s_phy = param->chans[i]->qos->phy; - cis->m_rtn = param->chans[i]->qos->rtn; - cis->s_rtn = param->chans[i]->qos->rtn; - } - - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CIG_PARAMS, buf, &rsp); - if (err) { - return NULL; - } - - return rsp; -} - -int bt_conn_bind_iso(struct bt_iso_create_param *param) -{ - struct bt_conn *conn; - struct net_buf *rsp; - struct bt_hci_rp_le_set_cig_params *cig_rsp; - int i, err; - - /* Check if controller is ISO capable */ - if (!BT_FEAT_LE_CIS_MASTER(bt_dev.le.features)) { - return -ENOTSUP; - } - - if (!param->num_conns || param->num_conns > CONFIG_BT_MAX_ISO_CONN) { - return -EINVAL; - } - - /* Assign ISO connections to each LE connection */ - for (i = 0; i < param->num_conns; i++) { - conn = param->conns[i]; - - if (conn->type != BT_CONN_TYPE_LE) { - err = -EINVAL; - goto failed; - } - - conn = bt_conn_add_iso(conn); - if (!conn) { - err = -ENOMEM; - goto failed; - } - - conn->iso.cig_id = param->id; - conn->iso.cis_id = bt_conn_index(conn); - - param->conns[i] = conn; - } - - rsp = hci_le_set_cig_params(param); - if (!rsp) { - err = -EIO; - goto failed; - } - - cig_rsp = (void *)rsp->data; - - if (rsp->len < sizeof(cig_rsp) || - cig_rsp->num_handles != param->num_conns) { - BT_WARN("Unexpected response to hci_le_set_cig_params"); - err = -EIO; - net_buf_unref(rsp); - goto failed; - } - - for (i = 0; i < cig_rsp->num_handles; i++) { - /* Assign the connection handle */ - param->conns[i]->handle = cig_rsp->handle[i]; - } - - net_buf_unref(rsp); - - return 0; - -failed: - for (i = 0; i < param->num_conns; i++) { - conn = param->conns[i]; - - if (conn->type == BT_CONN_TYPE_ISO) { - bt_iso_cleanup(conn); - } - } - - return err; -} - -static int hci_le_create_cis(struct bt_conn **conn, uint8_t num_conns) -{ - struct bt_hci_cis *cis; - struct bt_hci_cp_le_create_cis *req; - struct net_buf *buf; - int i; - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_CREATE_CIS, - sizeof(*req) + sizeof(*cis) * num_conns); - if (!buf) { - return -ENOBUFS; - } - - req = net_buf_add(buf, sizeof(*req)); - - memset(req, 0, sizeof(*req)); - - req->num_cis = num_conns; - - /* Program the cis parameters */ - for (i = 0; i < num_conns; i++) { - cis = net_buf_add(buf, sizeof(*cis)); - - memset(cis, 0, sizeof(*cis)); - - cis->cis_handle = sys_cpu_to_le16(conn[i]->handle); - cis->acl_handle = sys_cpu_to_le16(conn[i]->iso.acl->handle); - } - - return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_CIS, buf, NULL); -} - -int bt_conn_connect_iso(struct bt_conn **conns, uint8_t num_conns) -{ - int i, err; - - /* Check if controller is ISO capable */ - if (!BT_FEAT_LE_CIS_MASTER(bt_dev.le.features)) { - return -ENOTSUP; - } - - if (num_conns > CONFIG_BT_MAX_ISO_CONN) { - return -EINVAL; - } - - for (i = 0; i < num_conns; i++) { - if (conns[i]->type != BT_CONN_TYPE_ISO) { - return -EINVAL; - } - } - - err = hci_le_create_cis(conns, num_conns); - if (err) { - return err; - } - - /* Set connection state */ - for (i = 0; i < num_conns; i++) { - bt_conn_set_state(conns[i], BT_CONN_CONNECT); - } - - return 0; -} - -static int hci_le_setup_iso_data_path(struct bt_conn *conn, - struct bt_iso_data_path *path) -{ - struct bt_hci_cp_le_setup_iso_path *cp; - struct bt_hci_rp_le_setup_iso_path *rp; - struct net_buf *buf, *rsp; - uint8_t *cc; - int err; - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_SETUP_ISO_PATH, sizeof(*cp)); - if (!buf) { - return -ENOBUFS; - } - - cp = net_buf_add(buf, sizeof(*cp)); - cp->handle = sys_cpu_to_le16(conn->handle); - cp->path_dir = path->dir; - cp->path_id = path->pid; - cp->codec_id.coding_format = path->path->format; - cp->codec_id.company_id = sys_cpu_to_le16(path->path->cid); - cp->codec_id.vs_codec_id = sys_cpu_to_le16(path->path->vid); - sys_put_le24(path->path->delay, cp->controller_delay); - cp->codec_config_len = path->path->cc_len; - cc = net_buf_add(buf, cp->codec_config_len); - memcpy(cc, path->path->cc, cp->codec_config_len); - - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SETUP_ISO_PATH, buf, &rsp); - if (err) { - return err; - } - - rp = (void *)rsp->data; - if (rp->status || (rp->handle != conn->handle)) { - err = -EIO; - } - - net_buf_unref(rsp); - - return err; -} - -static int hci_le_remove_iso_data_path(struct bt_conn *conn, uint8_t dir) -{ - struct bt_hci_cp_le_remove_iso_path *cp; - struct bt_hci_rp_le_remove_iso_path *rp; - struct net_buf *buf, *rsp; - int err; - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_REMOVE_ISO_PATH, sizeof(*cp)); - if (!buf) { - return -ENOBUFS; - } - - cp = net_buf_add(buf, sizeof(*cp)); - cp->handle = conn->handle; - cp->path_dir = dir; - - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_REMOVE_ISO_PATH, buf, &rsp); - if (err) { - return err; - } - - rp = (void *)rsp->data; - if (rp->status || (rp->handle != conn->handle)) { - err = -EIO; - } - - net_buf_unref(rsp); - - return err; -} - -static void bt_iso_chan_add(struct bt_conn *conn, struct bt_iso_chan *chan) -{ - /* Attach channel to the connection */ - sys_slist_append(&conn->channels, &chan->node); - chan->conn = conn; - - BT_DBG("conn %p chan %p", conn, chan); -} - -int bt_iso_accept(struct bt_conn *conn) -{ - struct bt_iso_chan *chan; - int err; - - __ASSERT_NO_MSG(conn->type == BT_CONN_TYPE_ISO); - - BT_DBG("%p", conn); - - if (!iso_server) { - return -ENOMEM; - } - - err = iso_server->accept(conn, &chan); - if (err < 0) { - BT_ERR("err %d", err); - return err; - } - - bt_iso_chan_add(conn, chan); - bt_iso_chan_set_state(chan, BT_ISO_BOUND); - - return 0; -} - -static int bt_iso_setup_data_path(struct bt_conn *conn) -{ - int err; - struct bt_iso_chan *chan; - struct bt_iso_chan_path path = {}; - struct bt_iso_data_path out_path = { - .dir = BT_HCI_DATAPATH_DIR_CTLR_TO_HOST - }; - struct bt_iso_data_path in_path = { - .dir = BT_HCI_DATAPATH_DIR_HOST_TO_CTLR - }; - - chan = SYS_SLIST_PEEK_HEAD_CONTAINER(&conn->channels, chan, node); - if (!chan) { - return -EINVAL; - } - - in_path.path = chan->path ? chan->path : &path; - out_path.path = chan->path ? chan->path : &path; - - switch (chan->qos->dir) { - case BT_ISO_CHAN_QOS_IN: - in_path.pid = in_path.path->pid; - out_path.pid = BT_ISO_DATA_PATH_DISABLED; - break; - case BT_ISO_CHAN_QOS_OUT: - in_path.pid = BT_ISO_DATA_PATH_DISABLED; - out_path.pid = out_path.path->pid; - break; - case BT_ISO_CHAN_QOS_INOUT: - in_path.pid = in_path.path->pid; - out_path.pid = out_path.path->pid; - break; - default: - return -EINVAL; - } - - err = hci_le_setup_iso_data_path(conn, &in_path); - if (err) { - return err; - } - - return hci_le_setup_iso_data_path(conn, &out_path); -} - -void bt_iso_connected(struct bt_conn *conn) -{ - struct bt_iso_chan *chan; - - __ASSERT_NO_MSG(conn->type == BT_CONN_TYPE_ISO); - - BT_DBG("%p", conn); - - if (bt_iso_setup_data_path(conn)) { - BT_ERR("Unable to setup data path"); - bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - return; - } - - SYS_SLIST_FOR_EACH_CONTAINER(&conn->channels, chan, node) - { - if (chan->ops->connected) { - chan->ops->connected(chan); - } - - bt_iso_chan_set_state(chan, BT_ISO_CONNECTED); - } -} - -static void bt_iso_remove_data_path(struct bt_conn *conn) -{ - BT_DBG("%p", conn); - - /* Remove both directions */ - hci_le_remove_iso_data_path(conn, BT_HCI_DATAPATH_DIR_CTLR_TO_HOST); - hci_le_remove_iso_data_path(conn, BT_HCI_DATAPATH_DIR_HOST_TO_CTLR); -} - -void bt_iso_disconnected(struct bt_conn *conn) -{ - struct bt_iso_chan *chan, *next; - - __ASSERT_NO_MSG(conn->type == BT_CONN_TYPE_ISO); - - BT_DBG("%p", conn); - - if (sys_slist_is_empty(&conn->channels)) { - return; - } - - bt_iso_remove_data_path(conn); - - SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&conn->channels, chan, next, node) - { - if (chan->ops->disconnected) { - chan->ops->disconnected(chan); - } - - if (chan->conn) { - bt_conn_unref(chan->conn); - chan->conn = NULL; - } - - bt_iso_chan_set_state(chan, BT_ISO_DISCONNECTED); - } -} - -int bt_iso_server_register(struct bt_iso_server *server) -{ - __ASSERT_NO_MSG(server); - - /* Check if controller is ISO capable */ - if (!BT_FEAT_LE_CIS_SLAVE(bt_dev.le.features)) { - return -ENOTSUP; - } - - if (iso_server) { - return -EADDRINUSE; - } - - if (!server->accept) { - return -EINVAL; - } - - if (server->sec_level > BT_SECURITY_L3) { - return -EINVAL; - } else if (server->sec_level < BT_SECURITY_L1) { - /* Level 0 is only applicable for BR/EDR */ - server->sec_level = BT_SECURITY_L1; - } - - BT_DBG("%p", server); - - iso_server = server; - - return 0; -} - -#if defined(CONFIG_BT_AUDIO_DEBUG_ISO) -const char *bt_iso_chan_state_str(uint8_t state) -{ - switch (state) { - case BT_ISO_DISCONNECTED: - return "disconnected"; - case BT_ISO_BOUND: - return "bound"; - case BT_ISO_CONNECT: - return "connect"; - case BT_ISO_CONNECTED: - return "connected"; - case BT_ISO_DISCONNECT: - return "disconnect"; - default: - return "unknown"; - } -} - -void bt_iso_chan_set_state_debug(struct bt_iso_chan *chan, uint8_t state, - const char *func, int line) -{ - BT_DBG("chan %p conn %p %s -> %s", chan, chan->conn, - bt_iso_chan_state_str(chan->state), - bt_iso_chan_state_str(state)); - - /* check transitions validness */ - switch (state) { - case BT_ISO_DISCONNECTED: - /* regardless of old state always allows this state */ - break; - case BT_ISO_BOUND: - if (chan->state != BT_ISO_DISCONNECTED) { - BT_WARN("%s()%d: invalid transition", func, line); - } - break; - case BT_ISO_CONNECT: - if (chan->state != BT_ISO_BOUND) { - BT_WARN("%s()%d: invalid transition", func, line); - } - break; - case BT_ISO_CONNECTED: - if (chan->state != BT_ISO_BOUND && - chan->state != BT_ISO_CONNECT) { - BT_WARN("%s()%d: invalid transition", func, line); - } - break; - case BT_ISO_DISCONNECT: - if (chan->state != BT_ISO_CONNECTED) { - BT_WARN("%s()%d: invalid transition", func, line); - } - break; - default: - BT_ERR("%s()%d: unknown (%u) state was set", func, line, state); - return; - } - - chan->state = state; -} -#else -void bt_iso_chan_set_state(struct bt_iso_chan *chan, uint8_t state) -{ - chan->state = state; -} -#endif /* CONFIG_BT_AUDIO_DEBUG_ISO */ - -void bt_iso_chan_remove(struct bt_conn *conn, struct bt_iso_chan *chan) -{ - struct bt_iso_chan *c; - sys_snode_t *prev = NULL; - - SYS_SLIST_FOR_EACH_CONTAINER(&conn->channels, c, node) - { - if (c == chan) { - sys_slist_remove(&conn->channels, prev, &chan->node); - return; - } - - prev = &chan->node; - } -} - -int bt_iso_chan_bind(struct bt_conn **conns, uint8_t num_conns, - struct bt_iso_chan **chans) -{ - struct bt_iso_create_param param; - int i, err; - static uint8_t id; - - __ASSERT_NO_MSG(conns); - __ASSERT_NO_MSG(num_conns); - __ASSERT_NO_MSG(chans); - - memset(¶m, 0, sizeof(param)); - - param.id = id++; - param.num_conns = num_conns; - param.conns = conns; - param.chans = chans; - - err = bt_conn_bind_iso(¶m); - if (err) { - return err; - } - - /* Bind respective connection to channel */ - for (i = 0; i < num_conns; i++) { - bt_iso_chan_add(conns[i], chans[i]); - bt_iso_chan_set_state(chans[i], BT_ISO_BOUND); - } - - return 0; -} - -int bt_iso_chan_connect(struct bt_iso_chan **chans, uint8_t num_chans) -{ - struct bt_conn *conns[CONFIG_BT_MAX_ISO_CONN]; - int i, err; - - __ASSERT_NO_MSG(chans); - __ASSERT_NO_MSG(num_chans); - - for (i = 0; i < num_chans; i++) { - if (!chans[i]->conn) { - return -ENOTCONN; - } - - conns[i] = chans[i]->conn; - } - - err = bt_conn_connect_iso(conns, num_chans); - if (err) { - return err; - } - - for (i = 0; i < num_chans; i++) { - bt_iso_chan_set_state(chans[i], BT_ISO_CONNECT); - } - - return 0; -} - -int bt_iso_chan_disconnect(struct bt_iso_chan *chan) -{ - __ASSERT_NO_MSG(chan); - - if (!chan->conn) { - return -ENOTCONN; - } - - if (chan->state == BT_ISO_BOUND) { - bt_iso_chan_set_state(chan, BT_ISO_DISCONNECTED); - bt_iso_chan_remove(chan->conn, chan); - bt_conn_unref(chan->conn); - chan->conn = NULL; - return 0; - } - - return bt_conn_disconnect(chan->conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); -} - -void bt_iso_recv(struct bt_conn *conn, struct net_buf *buf, uint8_t flags) -{ - struct bt_hci_iso_data_hdr *hdr; - struct bt_iso_chan *chan; - uint8_t pb, ts; - uint16_t len; - - pb = bt_iso_flags_pb(flags); - ts = bt_iso_flags_ts(flags); - - BT_DBG("handle %u len %u flags 0x%02x pb 0x%02x ts 0x%02x", - conn->handle, buf->len, flags, pb, ts); - - /* When the PB_Flag does not equal 0b00, the fields Time_Stamp, - * Packet_Sequence_Number, Packet_Status_Flag and ISO_SDU_Length - * are omitted from the HCI ISO Data packet. - */ - switch (pb) { - case BT_ISO_START: - case BT_ISO_SINGLE: - /* The ISO_Data_Load field contains either the first fragment - * of an SDU or a complete SDU. - */ - if (ts) { - struct bt_hci_iso_ts_data_hdr *ts_hdr; - - ts_hdr = net_buf_pull_mem(buf, sizeof(*ts_hdr)); - iso(buf)->ts = sys_le32_to_cpu(ts_hdr->ts); - - hdr = &ts_hdr->data; - } else { - hdr = net_buf_pull_mem(buf, sizeof(*hdr)); - /* TODO: Generate a timestamp? */ - iso(buf)->ts = 0x00000000; - } - - len = sys_le16_to_cpu(hdr->slen); - flags = bt_iso_pkt_flags(len); - len = bt_iso_pkt_len(len); - - /* TODO: Drop the packet if NOP? */ - - BT_DBG("%s, len %u total %u flags 0x%02x timestamp %u", - pb == BT_ISO_START ? "Start" : "Single", buf->len, len, - flags, iso(buf)->ts); - - if (conn->rx) { - BT_ERR("Unexpected ISO %s fragment", - pb == BT_ISO_START ? "Start" : "Single"); - bt_conn_reset_rx_state(conn); - } - - conn->rx = buf; - conn->rx_len = len - buf->len; - if (conn->rx_len) { - /* if conn->rx_len then package is longer than the - * buf->len and cannot fit in a SINGLE package - */ - if (pb == BT_ISO_SINGLE) { - BT_ERR("Unexpected ISO single fragment"); - bt_conn_reset_rx_state(conn); - } - return; - } - break; - - case BT_ISO_CONT: - /* The ISO_Data_Load field contains a continuation fragment of - * an SDU. - */ - if (!conn->rx) { - BT_ERR("Unexpected ISO continuation fragment"); - net_buf_unref(buf); - return; - } - - BT_DBG("Cont, len %u rx_len %u", buf->len, conn->rx_len); - - if (buf->len > net_buf_tailroom(conn->rx)) { - BT_ERR("Not enough buffer space for ISO data"); - bt_conn_reset_rx_state(conn); - net_buf_unref(buf); - return; - } - - net_buf_add_mem(conn->rx, buf->data, buf->len); - conn->rx_len -= buf->len; - net_buf_unref(buf); - return; - - case BT_ISO_END: - /* The ISO_Data_Load field contains the last fragment of an - * SDU. - */ - BT_DBG("End, len %u rx_len %u", buf->len, conn->rx_len); - - if (!conn->rx) { - BT_ERR("Unexpected ISO end fragment"); - net_buf_unref(buf); - return; - } - - if (buf->len > net_buf_tailroom(conn->rx)) { - BT_ERR("Not enough buffer space for ISO data"); - bt_conn_reset_rx_state(conn); - net_buf_unref(buf); - return; - } - - net_buf_add_mem(conn->rx, buf->data, buf->len); - conn->rx_len -= buf->len; - net_buf_unref(buf); - - break; - default: - BT_ERR("Unexpected ISO pb flags (0x%02x)", pb); - bt_conn_reset_rx_state(conn); - net_buf_unref(buf); - return; - } - - SYS_SLIST_FOR_EACH_CONTAINER(&conn->channels, chan, node) - { - if (chan->ops->recv) { - chan->ops->recv(chan, conn->rx); - } - } - - bt_conn_reset_rx_state(conn); -} - -int bt_iso_chan_send(struct bt_iso_chan *chan, struct net_buf *buf) -{ - struct bt_hci_iso_data_hdr *hdr; - static uint16_t sn; - - __ASSERT_NO_MSG(chan); - __ASSERT_NO_MSG(buf); - - BT_DBG("chan %p len %zu", chan, net_buf_frags_len(buf)); - - if (!chan->conn) { - BT_DBG("Not connected"); - return -ENOTCONN; - } - - hdr = net_buf_push(buf, sizeof(*hdr)); - hdr->sn = sys_cpu_to_le16(sn++); - hdr->slen = sys_cpu_to_le16(bt_iso_pkt_len_pack(net_buf_frags_len(buf) - sizeof(*hdr), - BT_ISO_DATA_VALID)); - - return bt_conn_send(chan->conn, buf); -} diff --git a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/l2cap.c b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/l2cap.c index c4018386..98836572 100644 --- a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/l2cap.c +++ b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/l2cap.c @@ -26,7 +26,7 @@ #include "conn_internal.h" #include "l2cap_internal.h" -#include "config.h" +#include "ble_config.h" #define LE_CHAN_RTX(_w) CONTAINER_OF(_w, struct bt_l2cap_le_chan, chan.rtx_work) #define CHAN_RX(_w) CONTAINER_OF(_w, struct bt_l2cap_le_chan, rx_work) diff --git a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/rfcomm.c b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/rfcomm.c index 67bf469a..1ce95ada 100644 --- a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/rfcomm.c +++ b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/host/rfcomm.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include diff --git a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/services/ble_tp_svc.c b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/services/ble_tp_svc.c index 4f27a55b..1e52e13f 100644 --- a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/services/ble_tp_svc.c +++ b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/services/ble_tp_svc.c @@ -14,7 +14,6 @@ NOTES #include #include #include -#include #include "bluetooth.h" #include "conn.h" diff --git a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/services/oad/oad_main.c b/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/services/oad/oad_main.c deleted file mode 100644 index d324eddb..00000000 --- a/source/Core/BSP/Pinecilv2/bl_mcu_sdk/components/ble/ble_stack/services/oad/oad_main.c +++ /dev/null @@ -1,625 +0,0 @@ -#include -#include -#include -#include "oad_service.h" -#include "oad.h" -#include "oad_main.h" -#ifdef CONFIG_BT_SETTINGS -#include "settings.h" -#include "ef_def.h" -#endif -#include "conn_internal.h" -#if !defined(CONFIG_BL_MCU_SDK) -#include "hal_boot2.h" -#include "bl_flash.h" -#include "bl_sys.h" -#include "hosal_ota.h" -#include "bl702_common.h" -#include "hal_sys.h" -#else -#include "partition.h" -#include "hal_flash.h" -#include "errno.h" -#include "bl702_glb.h" -#include "mbedtls/sha256.h" -#endif -#include "log.h" -#include "bl702.h" -#include "softcrc.h" -#if defined(CONFIG_BL_MCU_SDK) -#define BL_SDK_VER "1.00" -#define BOOT2_PARTITION_ADDR (0x4202DC00) -#endif //CONFIG_BL_MCU_SDK - -#define OTA_WRITE_FLASH_SIZE (256 * 16) -#define WBUF_SIZE(CON) (OTA_WRITE_FLASH_SIZE + bt_gatt_get_mtu(CON)) -#define UPGRD_TIMEOUT K_SECONDS(2) - -static app_check_oad_cb app_check_cb = NULL; -struct oad_env_tag oad_env; - -struct wflash_data_t { - u8_t *wdata_buf; - u16_t index; -} __packed; - -static struct wflash_data_t wData; - -#if defined(CONFIG_BL_MCU_SDK) -static int hal_boot2_partition_addr_inactive(const char *name, uint32_t *addr, uint32_t *size); -static int hal_boot2_get_active_entries_byname(u8_t *name, pt_table_entry_config *ptEntry_hal); -static int hal_boot2_update_ptable(pt_table_entry_config *ptEntry_hal); -static int fw_check_hash256(void); -#endif -static bool check_data_valid(struct oad_file_info *file_info) -{ - if (file_info->manu_code != oad_env.file_info.manu_code || file_info->file_ver != oad_env.upgrd_file_ver) - return false; - - return true; -} - -static void oad_notify_image_info(struct bt_conn *conn) -{ - u8_t *buf = (u8_t *)k_malloc(sizeof(u8_t) * 256); - u8_t index = 0; - char *build_date = __DATE__; - char *build_time = __TIME__; - char *build_ver = BL_SDK_VER; - - if (buf) { - memset(buf, 0, 256); - } else { - BT_WARN("Buffer allocation failed\r\n"); - return; - } - buf[index++] = OAD_CMD_IMAG_INFO; - if (strlen(build_date) + index <= 256) { - buf[index] = strlen(build_date); - memcpy(&buf[++index], build_date, strlen(build_date)); - index += strlen(build_date); - } else { - BT_WARN("No enough space\r\n"); - } - if (strlen(build_time) + index <= 256) { - buf[index] = strlen(build_time); - memcpy(&buf[++index], build_time, strlen(build_time)); - index += strlen(build_time); - } else { - BT_WARN("No enough space\r\n"); - } - - if (strlen(build_ver) + index <= 256) { - buf[index] = strlen(build_ver); - memcpy(&buf[++index], build_ver, strlen(build_ver)); - index += strlen(build_ver); - } else { - BT_WARN("No enough space\r\n"); - } - BT_WARN("Info:%s,%s,%s\r\n", build_date, build_time, build_ver); - BT_WARN("Send:%s\r\n", bt_hex(buf, index)); - bt_oad_notify(conn, buf, index); - k_free(buf); -} - -static void oad_notify_block_req(struct bt_conn *conn) -{ - struct net_buf_simple *buf = NET_BUF_SIMPLE(sizeof(struct oad_block_req_t) + OAD_OPCODE_SIZE); - struct oad_block_req_t *block_req; - - net_buf_simple_init(buf, 0); - *(buf->data) = OAD_CMD_IMAG_BLOCK_REQ; - block_req = (struct oad_block_req_t *)(buf->data + 1); - buf->len = sizeof(struct oad_block_req_t) + OAD_OPCODE_SIZE; - - block_req->file_info.file_ver = oad_env.upgrd_file_ver; - block_req->file_info.manu_code = oad_env.file_info.manu_code; - block_req->file_offset = oad_env.upgrd_offset; - - bt_oad_notify(conn, buf->data, buf->len); -} - -static void oad_notify_upgrd_end(struct bt_conn *conn, u8_t status) -{ - struct net_buf_simple *buf = NET_BUF_SIMPLE(sizeof(struct oad_upgrd_end_t) + OAD_OPCODE_SIZE); - struct oad_upgrd_end_t *upgrd_end; - - if (status == OAD_SUCC) { - BT_WARN("Submit upgrade work\r\n"); -#if !defined(CONFIG_BL_MCU_SDK) - if (!hosal_ota_finish(1, 0)) -#else - if (!fw_check_hash256()) -#endif - k_delayed_work_submit(&oad_env.upgrd_work, UPGRD_TIMEOUT); - else { - BT_WARN("Hash256 check failed"); - status = OAD_CHECK_HASH256_FAIL; - } - } - - net_buf_simple_init(buf, 0); - *(buf->data) = OAD_CMD_IMAG_UPGRD_END; - upgrd_end = (struct oad_upgrd_end_t *)(buf->data + 1); - buf->len = sizeof(struct oad_upgrd_end_t) + OAD_OPCODE_SIZE; - upgrd_end->file_info.file_ver = oad_env.upgrd_file_ver; - upgrd_end->file_info.manu_code = oad_env.file_info.manu_code; - upgrd_end->status = status; - - bt_oad_notify(conn, buf->data, buf->len); -} - -static void oad_notity_image_identity(struct bt_conn *conn) -{ - struct net_buf_simple *buf = NET_BUF_SIMPLE(sizeof(struct oad_image_identity_t)); - struct oad_image_identity_t *identity; - - net_buf_simple_init(buf, 0); - *(buf->data) = OAD_CMD_IMAG_IDENTITY; - identity = (void *)(buf->data + 1); - buf->len = sizeof(struct oad_image_identity_t) + OAD_OPCODE_SIZE; - - identity->file_info.file_ver = oad_env.file_info.file_ver; - identity->file_info.manu_code = oad_env.file_info.manu_code; - identity->file_size = oad_env.cur_file_size; - identity->crc32 = 0; - - bt_oad_notify(conn, buf->data, buf->len); -} - -void ota_finish(struct k_work *work) -{ - BT_WARN("oad_upgrade\r\n"); - oad_env.file_info.file_ver = oad_env.upgrd_file_ver; - -#if defined(CONFIG_BT_SETTINGS) - struct oad_ef_info ef_info; - memset(&ef_info, 0, sizeof(struct oad_ef_info)); - bt_settings_set_bin(NV_IMG_info, (uint8_t *)&ef_info, sizeof(struct oad_ef_info)); -#endif - -#if defined(CONFIG_BL_MCU_SDK) - GLB_SW_System_Reset(); -#else - hal_reboot(); -#endif -} - -static u8_t oad_write_flash(uint32_t filesize, uint32_t offset, u8_t *data, u16_t len) -{ -#if defined(CONFIG_BL_MCU_SDK) - uint32_t size = 0; - uint32_t wflash_address = 0; - - if (!oad_env.new_img_addr) { - if (hal_boot2_partition_addr_inactive("FW", (uint32_t *)&oad_env.new_img_addr, &size)) { - BT_WARN("New img address is null\r\n"); - return OAD_ABORT; - } - - BT_WARN("Upgrade file size is %d\r\n", oad_env.upgrd_file_size); - if (oad_env.upgrd_file_size <= size) { - BT_WARN("flash erase\r\n"); - flash_erase(oad_env.new_img_addr, oad_env.upgrd_file_size); - } else { - return -1; - } - } - - BT_WARN("upgrd_offset is 0x%x len (%d)\r\n", oad_env.upgrd_offset, len); - - if (oad_env.w_img_end_addr <= oad_env.new_img_addr && !oad_env.w_img_end_addr) { - wflash_address = oad_env.new_img_addr; - } else if (oad_env.w_img_end_addr) { - wflash_address = oad_env.w_img_end_addr; - } else { - BT_WARN("Write flash address invalid\r\n"); - } - - BT_WARN("Start address : 0x%x\r\n", wflash_address); - flash_write(wflash_address, data, len); - oad_env.w_img_end_addr = wflash_address + len; - BT_WARN("End address : 0x%x\r\n", wflash_address + len); -#else - hosal_ota_update(filesize, offset, data, len); -#endif - - return 0; -} - -static u8_t oad_image_data_handler(struct bt_conn *conn, const u8_t *data, u16_t len) -{ - u16_t left_size = 0; - u16_t oDataLen = 0; - static u32_t write_count = 0; - - if (!wData.wdata_buf) { - wData.wdata_buf = (u8_t *)k_malloc(WBUF_SIZE(conn)); - if (!wData.wdata_buf) { - BT_WARN("Buf is NULL\r\n"); - return OAD_ABORT; - }; - memset(wData.wdata_buf, 0, WBUF_SIZE(conn)); - wData.index = 0; - } - - if (wData.wdata_buf) { - left_size = /*WBUF_SIZE(conn)*/ OTA_WRITE_FLASH_SIZE - wData.index; - BT_WARN("left_size (0x%x) wData.index (0x%x) len (%d)\r\n", left_size, wData.index, len); - if (left_size >= len) { - memcpy((wData.wdata_buf + wData.index), data, len); - wData.index += len; - - } else { - oDataLen = len - left_size; - memcpy((wData.wdata_buf + wData.index), data, left_size); - wData.index += left_size; - if (wData.index == OTA_WRITE_FLASH_SIZE) { - if (oad_write_flash(oad_env.upgrd_file_size, oad_env.hosal_offset, wData.wdata_buf, OTA_WRITE_FLASH_SIZE)) { - BT_ERR("Failed to write flash\r\n"); - return OAD_ABORT; - } - } else { - BT_ERR("Unexpect result\r\n"); - return OAD_ABORT; - } - - write_count += 1; - oad_env.hosal_offset = write_count * OTA_WRITE_FLASH_SIZE; -#if defined(CONFIG_BT_SETTINGS) - struct oad_ef_info ef_info; - memcpy(&ef_info.file_info, &oad_env.file_info, sizeof(struct oad_file_info)); - ef_info.file_offset = write_count * OTA_WRITE_FLASH_SIZE; - ef_info.last_wflash_addr = oad_env.w_img_end_addr; - ef_info.upgrd_crc32 = oad_env.upgrd_crc32; - - bt_settings_set_bin(NV_IMG_info, (uint8_t *)&ef_info, sizeof(struct oad_ef_info)); - BT_WARN("ef_info: file ver(%d) manu code(0x%x) file offset(0x%x) last_adder (0x%x)\r\n", ef_info.file_info.file_ver, ef_info.file_info.manu_code, - ef_info.file_offset, ef_info.last_wflash_addr); -#endif - wData.index = 0; - memcpy((wData.wdata_buf + wData.index), (data + left_size), oDataLen); - wData.index += oDataLen; - } - } - - oad_env.upgrd_offset += len; - if (oad_env.upgrd_offset > oad_env.upgrd_file_size) { - return OAD_INVALID_IMAG; - } else if (oad_env.upgrd_offset == oad_env.upgrd_file_size) { - if (wData.index) { - oad_write_flash(oad_env.upgrd_file_size, oad_env.hosal_offset, wData.wdata_buf, wData.index); - } - - if (wData.wdata_buf) { - k_free(wData.wdata_buf); - wData.wdata_buf = NULL; - } - - return OAD_UPGRD_CMPLT; - } else { - return OAD_REQ_MORE_DATA; - } -} - -static void oad_image_info_handler(struct bt_conn *conn, const u8_t *data, u16_t len) -{ - oad_notify_image_info(conn); -} - -static u8_t oad_image_block_resp_handler(struct bt_conn *conn, const u8_t *data, u16_t len) -{ - struct oad_block_rsp_t *block_rsp; - const u8_t *rsp_data; - u8_t status = OAD_SUCC; - - switch (*data) { - case OAD_SUCC: { - block_rsp = (struct oad_block_rsp_t *)data; - if (!check_data_valid(&block_rsp->file_info)) { - status = OAD_INVALID_IMAG; - break; - } - - if (block_rsp->file_offset != oad_env.upgrd_offset) { - status = OAD_MALORMED_CMD; - break; - } - - rsp_data = data + OAD_BLK_RSP_DATA_OFFSET; - status = oad_image_data_handler(conn, rsp_data, block_rsp->data_size); - if (status == OAD_UPGRD_CMPLT) { - oad_notify_upgrd_end(conn, OAD_SUCC); - } else if (status == OAD_REQ_MORE_DATA) { - oad_notify_block_req(conn); - } else { - oad_notify_upgrd_end(conn, status); - } - } break; - case OAD_ABORT: { -#if !defined(CONFIG_BL_MCU_SDK) - bl_flash_erase(oad_env.new_img_addr, oad_env.upgrd_file_size); -#else - flash_erase(oad_env.new_img_addr, oad_env.upgrd_file_size); -#endif - } break; - - default: - status = OAD_MALORMED_CMD; - } - return status; -} - -static void oad_image_identity_handler(struct bt_conn *conn, const u8_t *data, u16_t len) -{ - struct bt_le_conn_param conn_param; - struct oad_image_identity_t *identity = (struct oad_image_identity_t *)(data); - int err = 0; - - BT_WARN("File size=[0x%x] [0x%x] [0x%x] [0x%x]\r\n", identity->file_size, identity->file_info.file_ver, - identity->file_info.manu_code, identity->crc32); -#if defined(CONFIG_BT_SETTINGS) - size_t llen = 0; - struct oad_ef_info ef_info; - - memset(&ef_info, 0, sizeof(struct oad_ef_info)); - bt_settings_get_bin(NV_IMG_info, (uint8_t *)&ef_info, sizeof(struct oad_ef_info), &llen); - BT_WARN("ef_info: file ver(%d) manu code(0x%x) file offset(0x%x) last_adder (0x%x)\r\n", ef_info.file_info.file_ver, ef_info.file_info.manu_code, - ef_info.file_offset, ef_info.last_wflash_addr); -#else - oad_env.new_img_addr = 0; - oad_env.w_img_end_addr = 0; -#endif - - if (identity->file_info.manu_code == oad_env.file_info.manu_code && - (app_check_cb)(oad_env.file_info.file_ver, identity->file_info.file_ver)) { -#if defined(CONFIG_BT_SETTINGS) - if (identity->crc32 && ef_info.upgrd_crc32 == identity->crc32) { - if (ef_info.file_offset && ef_info.file_offset <= identity->file_size) { - oad_env.upgrd_offset = ef_info.file_offset; - } - - oad_env.new_img_addr = ef_info.last_wflash_addr; - - } else -#endif - { - oad_env.upgrd_offset = 0x00; - } - - conn_param.interval_max = 6; - conn_param.interval_min = 6; - conn_param.latency = 0; - conn_param.timeout = 500; //5s - err = bt_conn_le_param_update(conn, &conn_param); - if (err) - BT_WARN("fail to start conn update\r\n"); - else - BT_WARN("start conn update\r\n"); - - oad_env.upgrd_file_ver = identity->file_info.file_ver; - oad_env.upgrd_file_size = identity->file_size; - oad_env.upgrd_crc32 = identity->crc32; - BT_WARN("Send the image block request\r\n"); -#if !defined(CONFIG_BL_MCU_SDK) - hosal_ota_start(oad_env.upgrd_file_size); -#endif - oad_notify_block_req(conn); - } else { - oad_notity_image_identity(conn); - } -} - -static void oad_recv_callback(struct bt_conn *conn, const u8_t *data, u16_t len) -{ - if (len) { - if (*data == OAD_CMD_IMAG_IDENTITY && ((len - 1) == sizeof(struct oad_image_identity_t))) { - oad_image_identity_handler(conn, data + 1, len - 1); - } - if (*data == OAD_CMD_IMAG_BLOCK_RESP) { - oad_image_block_resp_handler(conn, data + 1, len - 1); - } - if (*data == OAD_CMD_IMAG_INFO) { - oad_image_info_handler(conn, data + 1, len - 1); - } - } -} - -static void oad_disc_callback(struct bt_conn *conn, u8_t reason) -{ - if (wData.wdata_buf) { - k_free(wData.wdata_buf); - wData.wdata_buf = NULL; - wData.index = 0; - } -} -#if defined(CONFIG_BL_MCU_SDK) -static struct { - u8_t partition_active_idx; - u8_t pad[3]; - pt_table_stuff_config table; -} boot2_partition_table; - -//#define PARTITION_MAGIC (0x54504642) - -pt_table_id_type active_id = PT_TABLE_ID_INVALID; -pt_table_stuff_config pt_table_stuff[2]; - -static int fw_check_hash256(void) -{ - uint32_t bin_size; - uint32_t hash_addr; - pt_table_entry_config ptEntry; - - if (oad_env.upgrd_file_size <= 32) { - return -1; - } - if (oad_env.w_img_end_addr <= 32) { - return -1; - } - - bin_size = oad_env.upgrd_file_size - 32; - hash_addr = oad_env.w_img_end_addr - 32; - - if (hal_boot2_get_active_entries_byname((uint8_t *)"FW", &ptEntry)) { - BT_WARN("Failed to get active entries by name\r\n"); - return -1; - } - -#define CHECK_IMG_BUF_SIZE 512 - uint8_t sha_check[32] = { 0 }; - uint8_t dst_sha[32] = { 0 }; - uint32_t read_size; - mbedtls_sha256_context sha256_ctx; - int i, offset = 0; - uint8_t r_buf[CHECK_IMG_BUF_SIZE]; - - BT_WARN("[OTA]prepare OTA partition info\r\n"); - mbedtls_sha256_init(&sha256_ctx); - mbedtls_sha256_starts_ret(&sha256_ctx, 0); - - memset(sha_check, 0, 32); - memset(dst_sha, 0, 32); - offset = 0; - while (offset < bin_size) { - (bin_size - offset >= CHECK_IMG_BUF_SIZE) ? (read_size = CHECK_IMG_BUF_SIZE) : (read_size = bin_size - offset); - if (flash_read(oad_env.new_img_addr + offset, r_buf, read_size)) { - BT_WARN("flash read failed \r\n"); - return -1; - } - mbedtls_sha256_update_ret(&sha256_ctx, (const uint8_t *)r_buf, read_size); - offset += read_size; - } - - mbedtls_sha256_finish_ret(&sha256_ctx, sha_check); - - flash_read(hash_addr, dst_sha, 32); - for (i = 0; i < 32; i++) { - BT_WARN("%02X", dst_sha[i]); - } - puts("\r\nHeader SET SHA256 Checksum:"); - for (i = 0; i < 32; i++) { - BT_WARN("%02X", sha_check[i]); - } - - if (memcmp(sha_check, (const void *)dst_sha, 32) != 0) { - BT_WARN("sha256 check error\r\n"); - return -1; - } - ptEntry.len = bin_size; - BT_WARN("[OTA] Update PARTITION, partition len is %lu\r\n", ptEntry.len); - hal_boot2_update_ptable(&ptEntry); - - return 0; -} - -static int oad_hal_boot2_partition_addr(const char *name, uint32_t *addr0, uint32_t *addr1, uint32_t *size0, uint32_t *size1, int *active) -{ - int i; - - if (BFLB_PT_MAGIC_CODE != boot2_partition_table.table.pt_table.magicCode) { - return -EIO; - } - - /*Get Target partition*/ - for (i = 0; i < boot2_partition_table.table.pt_table.entryCnt; i++) { - if (0 == strcmp((char *)&(boot2_partition_table.table.pt_entries[i].name[0]), name)) { - break; - } - } - if (boot2_partition_table.table.pt_table.entryCnt == i) { - return -ENOENT; - } - *addr0 = boot2_partition_table.table.pt_entries[i].start_address[0]; - *addr1 = boot2_partition_table.table.pt_entries[i].start_address[1]; - *size0 = boot2_partition_table.table.pt_entries[i].max_len[0]; - *size1 = boot2_partition_table.table.pt_entries[i].max_len[1]; - *active = boot2_partition_table.table.pt_entries[i].active_index; - - return 0; -} - -static int hal_boot2_partition_addr_inactive(const char *name, uint32_t *addr, uint32_t *size) -{ - uint32_t addr0, addr1; - uint32_t size0, size1; - int active, ret; - - if ((ret = oad_hal_boot2_partition_addr(name, &addr0, &addr1, &size0, &size1, &active))) { - return ret; - } - *addr = active ? addr0 : addr1; - *size = active ? size0 : size1; - - return 0; -} - -static pt_table_error_type oad_PtTable_Get_Active_Entries_By_Name(pt_table_stuff_config *ptStuff, - u8_t *name, - pt_table_entry_config *ptEntry) -{ - uint32_t i = 0; - uint32_t len = strlen((char *)name); - - if (ptStuff == NULL || ptEntry == NULL) { - return PT_ERROR_PARAMETER; - } - for (i = 0; i < ptStuff->pt_table.entryCnt; i++) { - if (strlen((char *)ptStuff->pt_entries[i].name) == len && - memcmp((char *)ptStuff->pt_entries[i].name, (char *)name, len) == 0) { - ARCH_MemCpy_Fast(ptEntry, &ptStuff->pt_entries[i], sizeof(pt_table_entry_config)); - return PT_ERROR_SUCCESS; - } - } - return PT_ERROR_ENTRY_NOT_FOUND; -} - -static int hal_boot2_update_ptable(pt_table_entry_config *ptEntry_hal) -{ - int ret; - //FIXME force covert - pt_table_entry_config *ptEntry = (pt_table_entry_config *)ptEntry_hal; - - ptEntry->active_index = !ptEntry->active_index; - (ptEntry->age)++; - ret = pt_table_update_entry((pt_table_id_type)(!active_id), &pt_table_stuff[!active_id], ptEntry); - return ret; -} - -static int hal_boot2_get_active_entries_byname(uint8_t *name, pt_table_entry_config *ptEntry_hal) -{ - pt_table_entry_config *ptEntry = (pt_table_entry_config *)ptEntry_hal; - if (oad_PtTable_Get_Active_Entries_By_Name(&boot2_partition_table.table, name, ptEntry)) { - return -1; - } - return 0; -} - -static int oad_get_boot2_partition_table(void) -{ - memcpy(&boot2_partition_table.table, &pt_table_stuff[active_id], sizeof(pt_table_stuff_config)); - boot2_partition_table.partition_active_idx = active_id; - BT_WARN("magicCode: 0x%x\r\n", boot2_partition_table.table.pt_table.magicCode); - return 0; -} -#endif -void oad_service_enable(app_check_oad_cb cb) -{ - //todo: get current file info for oad_env.fileinfo - - app_check_cb = cb; - oad_env.file_info.file_ver = LOCAL_FILE_VER; - oad_env.file_info.manu_code = LOCAL_MANU_CODE; - oad_env.new_img_addr = 0; - bt_oad_service_enable(); - bt_oad_register_recv_cb(oad_recv_callback); - bt_oad_register_disc_cb(oad_disc_callback); - -#if defined(CONFIG_BL_MCU_SDK) - flash_init(); - pt_table_set_flash_operation(flash_erase, flash_write, flash_read); - active_id = pt_table_get_active_partition_need_lock(pt_table_stuff); - oad_get_boot2_partition_table(); -#endif - k_delayed_work_init(&oad_env.upgrd_work, ota_finish); -} diff --git a/source/Core/BSP/Pinecilv2/ble.c b/source/Core/BSP/Pinecilv2/ble.c index bdde2653..e64b3f04 100644 --- a/source/Core/BSP/Pinecilv2/ble.c +++ b/source/Core/BSP/Pinecilv2/ble.c @@ -22,7 +22,7 @@ NOTES #include "uuid.h" #include "ble_peripheral_tp_server.h" #include "log.h" - +#include "bl702_glb.h" static void ble_tp_connected(struct bt_conn *conn, u8_t err); static void ble_tp_disconnected(struct bt_conn *conn, u8_t reason); diff --git a/source/Core/BSP/Pinecilv2/ble_peripheral_tp_server.c b/source/Core/BSP/Pinecilv2/ble_peripheral_tp_server.c new file mode 100644 index 00000000..576617d0 --- /dev/null +++ b/source/Core/BSP/Pinecilv2/ble_peripheral_tp_server.c @@ -0,0 +1,352 @@ +/**************************************************************************** +FILE NAME + ble_peripheral_tp_server.c + +DESCRIPTION + test profile demo + +NOTES +*/ +/****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "bluetooth.h" +#include "conn.h" +#include "gatt.h" +#include "hci_core.h" +#include "uuid.h" +#include "ble_peripheral_tp_server.h" +#include "log.h" +#include "hal_clock.h" + +extern bool pds_start; + +static void ble_tp_connected(struct bt_conn *conn, u8_t err); +static void ble_tp_disconnected(struct bt_conn *conn, u8_t reason); +static void ble_param_updated(struct bt_conn *conn, u16_t interval, u16_t latency, u16_t timeout); + +static struct bt_conn *ble_tp_conn; +#if !defined(CONFIG_BT_OAD_SERVER) +static struct bt_gatt_exchange_params exchg_mtu; +#endif +static TaskHandle_t ble_tp_task_h; + +static struct k_sem notify_poll_sem; + +static int tx_mtu_size = 20; +static u8_t created_tp_task = 0; +static u8_t isRegister = 0; + +static struct bt_conn_cb ble_tp_conn_callbacks = { + .connected = ble_tp_connected, + .disconnected = ble_tp_disconnected, + .le_param_updated = ble_param_updated, +}; + +#if !defined(CONFIG_BT_OAD_SERVER) +/************************************************************************* +NAME + ble_tp_tx_mtu_size +*/ +static void ble_tp_tx_mtu_size(struct bt_conn *conn, u8_t err, + struct bt_gatt_exchange_params *params) +{ + if (!err) { + tx_mtu_size = bt_gatt_get_mtu(ble_tp_conn); + BT_WARN("ble tp echange mtu size success, mtu size: %d", tx_mtu_size); + } else { + BT_WARN("ble tp echange mtu size failure, err: %d", err); + } +} +#endif +/************************************************************************* +NAME + ble_tp_connected +*/ +static void ble_tp_connected(struct bt_conn *conn, u8_t err) +{ +#if !defined(CONFIG_BT_OAD_SERVER) + int tx_octets = 0x00fb; + int tx_time = 0x0848; + int ret = -1; +#endif + +#if XTAL_32K_TYPE == EXTERNAL_XTAL_32K + struct bt_le_conn_param param; +#endif + + if (err) { + return; + } + + BT_WARN("Tp connected"); + ble_tp_conn = conn; + pds_start = false; + +#if XTAL_32K_TYPE == EXTERNAL_XTAL_32K + param.interval_min = param.interval_max = 0x320; + param.latency = 0; + param.timeout = 0x05dc; + ret = bt_conn_le_param_update(ble_tp_conn, ¶m); + if (ret) { + BT_WARN("conn update failed (err %d)\r\n", ret); + } else { + BT_WARN("conn update initiated\r\n"); + } +#endif + +#if !defined(CONFIG_BT_OAD_SERVER) + //set data length after connected. + ret = bt_le_set_data_len(ble_tp_conn, tx_octets, tx_time); + + if (!ret) { + BT_WARN("ble tp set data length success"); + } else { + BT_WARN("ble tp set data length failure, err: %d", ret); + } + + //exchange mtu size after connected. + exchg_mtu.func = ble_tp_tx_mtu_size; + ret = bt_gatt_exchange_mtu(ble_tp_conn, &exchg_mtu); + + if (!ret) { + BT_WARN("ble tp exchange mtu size pending"); + } else { + BT_WARN("ble tp exchange mtu size failure, err: %d", ret); + } +#endif +} + +/************************************************************************* +NAME + ble_tp_disconnected +*/ +static void ble_tp_disconnected(struct bt_conn *conn, u8_t reason) +{ + BT_WARN("Tp disconnected"); + + if (created_tp_task) { + BT_WARN("Delete throughput tx task"); + vTaskDelete(ble_tp_task_h); + created_tp_task = 0; + } + + ble_tp_conn = NULL; + extern int ble_start_adv(void); + ble_start_adv(); + pds_start = true; +} + +/************************************************************************* +NAME + ble_param_updated +*/ + +static void ble_param_updated(struct bt_conn *conn, u16_t interval, + u16_t latency, u16_t timeout) +{ + BT_WARN("LE conn param updated: int 0x%04x lat %d to %d \r\n", interval, latency, timeout); +#if XTAL_32K_TYPE == EXTERNAL_XTAL_32K + if (interval > 80) { + pds_start = true; + } else { + pds_start = false; + } +#endif +} + +/************************************************************************* +NAME + ble_tp_recv_rd +*/ +static int ble_tp_recv_rd(struct bt_conn *conn, const struct bt_gatt_attr *attr, + void *buf, u16_t len, u16_t offset) +{ + int size = 9; + char data[9] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; + + memcpy(buf, data, size); + + return size; +} + +/************************************************************************* +NAME + ble_tp_recv_wr(receive data from client) +*/ +static int ble_tp_recv_wr(struct bt_conn *conn, const struct bt_gatt_attr *attr, + const void *buf, u16_t len, u16_t offset, u8_t flags) +{ + BT_WARN("recv data len=%d, offset=%d, flag=%d", len, offset, flags); + BT_WARN("recv data:%s", bt_hex(buf, len)); + + if (flags & BT_GATT_WRITE_FLAG_PREPARE) { + //Don't use prepare write data, execute write will upload data again. + BT_WARN("recv prepare write request"); + return 0; + } + + if (flags & BT_GATT_WRITE_FLAG_CMD) { + //Use write command data. + BT_WARN("recv write command"); + } else { + //Use write request / execute write data. + BT_WARN("recv write request / exce write"); + } + + k_sem_give(¬ify_poll_sem); + return len; +} + +/************************************************************************* +NAME + indicate_rsp /bl_tp_send_indicate +*/ + +static void indicate_rsp(struct bt_conn *conn, const struct bt_gatt_attr *attr, u8_t err) +{ + BT_WARN("receive comfirmation, err:%d", err); +} + +static int bl_tp_send_indicate(struct bt_conn *conn, const struct bt_gatt_attr *attr, + const void *data, u16_t len) +{ + static struct bt_gatt_indicate_params ind_params; + + ind_params.attr = attr; + ind_params.data = data; + ind_params.len = len; + ind_params.func = indicate_rsp; + ind_params.uuid = NULL; + + return bt_gatt_indicate(conn, &ind_params); +} + +/************************************************************************* +NAME + ble_tp_ind_ccc_changed +*/ +static void ble_tp_ind_ccc_changed(const struct bt_gatt_attr *attr, u16_t value) +{ + int err = -1; + char data[9] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; + + if (value == BT_GATT_CCC_INDICATE) { + err = bl_tp_send_indicate(ble_tp_conn, get_attr(BT_CHAR_BLE_TP_IND_ATTR_VAL_INDEX), data, 9); + BT_WARN("ble tp send indatcate: %d", err); + } +} + +/************************************************************************* +NAME + ble_tp_notify(send data to client) +*/ +static void ble_tp_notify_task(void *pvParameters) +{ + int err = -1; + u8_t data[244] = { 0x01 }; + k_sem_give(¬ify_poll_sem); + + while (1) { + k_sem_take(¬ify_poll_sem, K_FOREVER); + //send data to client + err = bt_gatt_notify(ble_tp_conn, get_attr(BT_CHAR_BLE_TP_NOT_ATTR_VAL_INDEX), data, (tx_mtu_size - 3)); + data[0] = data[0] + 1; + BT_WARN("ble tp send notify : %d", err); + } +} + +/************************************************************************* +NAME + ble_tp_not_ccc_changed +*/ +static void ble_tp_notify_ccc_changed(const struct bt_gatt_attr *attr, u16_t value) +{ + BT_WARN("ccc:value=[%d]", value); + + if (value == BT_GATT_CCC_NOTIFY) { + if (xTaskCreate(ble_tp_notify_task, (char *)"bletp", 512, NULL, 15, &ble_tp_task_h) == pdPASS) { + created_tp_task = 1; + BT_WARN("Create throughput tx task success"); + } else { + created_tp_task = 0; + BT_WARN("Create throughput tx taskfail"); + } + } else { + if (created_tp_task) { + BT_WARN("Delete throughput tx task"); + vTaskDelete(ble_tp_task_h); + created_tp_task = 0; + } + } +} + +/************************************************************************* +* DEFINE : attrs +*/ +static struct bt_gatt_attr attrs[] = { + BT_GATT_PRIMARY_SERVICE(BT_UUID_SVC_BLE_TP), + + BT_GATT_CHARACTERISTIC(BT_UUID_CHAR_BLE_TP_RD, + BT_GATT_CHRC_READ, + BT_GATT_PERM_READ, + ble_tp_recv_rd, + NULL, + NULL), + + BT_GATT_CHARACTERISTIC(BT_UUID_CHAR_BLE_TP_WR, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, + BT_GATT_PERM_WRITE | BT_GATT_PERM_PREPARE_WRITE, + NULL, + ble_tp_recv_wr, + NULL), + + BT_GATT_CHARACTERISTIC(BT_UUID_CHAR_BLE_TP_IND, + BT_GATT_CHRC_INDICATE, + 0, + NULL, + NULL, + NULL), + + BT_GATT_CCC(ble_tp_ind_ccc_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), + + BT_GATT_CHARACTERISTIC(BT_UUID_CHAR_BLE_TP_NOT, + BT_GATT_CHRC_NOTIFY, + 0, + NULL, + NULL, + NULL), + + BT_GATT_CCC(ble_tp_notify_ccc_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE) + +}; + +/************************************************************************* +NAME + get_attr +*/ +struct bt_gatt_attr *get_attr(u8_t index) +{ + return &attrs[index]; +} + +static struct bt_gatt_service ble_tp_server = BT_GATT_SERVICE(attrs); + +/************************************************************************* +NAME + ble_tp_init +*/ +void ble_tp_init() +{ + if (!isRegister) { + isRegister = 1; + bt_conn_cb_register(&ble_tp_conn_callbacks); + bt_gatt_service_register(&ble_tp_server); + k_sem_init(¬ify_poll_sem, 0, 1); + } +} diff --git a/source/Core/BSP/Pinecilv2/ble_peripheral_tp_server.h b/source/Core/BSP/Pinecilv2/ble_peripheral_tp_server.h new file mode 100644 index 00000000..235039af --- /dev/null +++ b/source/Core/BSP/Pinecilv2/ble_peripheral_tp_server.h @@ -0,0 +1,38 @@ +/**************************************************************************** +FILE NAME + ble_peripheral_tp_server.h + +DESCRIPTION +NOTES +*/ +/****************************************************************************/ + +#ifndef _BLE_TP_SVC_H_ +#define _BLE_TP_SVC_H_ + +#include "ble_config.h" + +//07af27a5-9c22-11ea-9afe-02fcdc4e7412 +#define BT_UUID_SVC_BLE_TP BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x07af27a5, 0x9c22, 0x11ea, 0x9afe, 0x02fcdc4e7412)) +//07af27a6-9c22-11ea-9afe-02fcdc4e7412 +#define BT_UUID_CHAR_BLE_TP_RD BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x07af27a6, 0x9c22, 0x11ea, 0x9afe, 0x02fcdc4e7412)) +//07af27a7-9c22-11ea-9afe-02fcdc4e7412 +#define BT_UUID_CHAR_BLE_TP_WR BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x07af27a7, 0x9c22, 0x11ea, 0x9afe, 0x02fcdc4e7412)) +//07af27a8-9c22-11ea-9afe-02fcdc4e7412 +#define BT_UUID_CHAR_BLE_TP_IND BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x07af27a8, 0x9c22, 0x11ea, 0x9afe, 0x02fcdc4e7412)) +//07af27a9-9c22-11ea-9afe-02fcdc4e7412 +#define BT_UUID_CHAR_BLE_TP_NOT BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x07af27a9, 0x9c22, 0x11ea, 0x9afe, 0x02fcdc4e7412)) + +//read value handle offset 2 +#define BT_CHAR_BLE_TP_RD_ATTR_VAL_INDEX (2) +//write value handle offset 4 +#define BT_CHAR_BLE_TP_WR_ATTR_VAL_INDEX (4) +//indicate value handle offset 6 +#define BT_CHAR_BLE_TP_IND_ATTR_VAL_INDEX (6) +//notity value handle offset 9 +#define BT_CHAR_BLE_TP_NOT_ATTR_VAL_INDEX (9) + +void ble_tp_init(); +struct bt_gatt_attr *get_attr(u8_t index); + +#endif