diff options
| author | jacqueline <me@jacqueline.id.au> | 2025-07-25 13:33:07 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2025-07-25 13:33:07 +1000 |
| commit | c8e79a926620e48830778714cfe4b2ea2453fcaf (patch) | |
| tree | 8c756e08e01b8e147cf72bec128026f46bd854c5 /lib/bt/host/bluedroid/stack | |
| parent | 237136f3e93cb6b5be24670d7520adb17cc0fa36 (diff) | |
| download | tangara-fw-c8e79a926620e48830778714cfe4b2ea2453fcaf.tar.gz | |
Update forked idf components
Diffstat (limited to 'lib/bt/host/bluedroid/stack')
75 files changed, 8643 insertions, 678 deletions
diff --git a/lib/bt/host/bluedroid/stack/avct/avct_lcb.c b/lib/bt/host/bluedroid/stack/avct/avct_lcb.c index 61f6c9a5..84a0f021 100644 --- a/lib/bt/host/bluedroid/stack/avct/avct_lcb.c +++ b/lib/bt/host/bluedroid/stack/avct/avct_lcb.c @@ -430,10 +430,10 @@ BOOLEAN avct_lcb_last_ccb(tAVCT_LCB *p_lcb, tAVCT_CCB *p_ccb_last) tAVCT_CCB *p_ccb = &avct_cb.ccb[0]; int i; - AVCT_TRACE_WARNING("avct_lcb_last_ccb"); + AVCT_TRACE_DEBUG("avct_lcb_last_ccb"); for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { - AVCT_TRACE_WARNING("%x: aloc:%d, lcb:%p/%p, ccb:%p/%p", - i, p_ccb->allocated, p_ccb->p_lcb, p_lcb, p_ccb, p_ccb_last); + AVCT_TRACE_DEBUG("%x: aloc:%d, lcb:%p/%p, ccb:%p/%p", + i, p_ccb->allocated, p_ccb->p_lcb, p_lcb, p_ccb, p_ccb_last); if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb != p_ccb_last)) { return FALSE; } diff --git a/lib/bt/host/bluedroid/stack/avdt/avdt_api.c b/lib/bt/host/bluedroid/stack/avdt/avdt_api.c index f37db816..9fb84fb9 100644 --- a/lib/bt/host/bluedroid/stack/avdt/avdt_api.c +++ b/lib/bt/host/bluedroid/stack/avdt/avdt_api.c @@ -266,6 +266,37 @@ UINT16 AVDT_CreateStream(UINT8 *p_handle, tAVDT_CS *p_cs) /******************************************************************************* ** +** Function AVDT_UpdateCodecInfo +** +** Description Update codec capability for a stream endpoint. +** +** +** Returns AVDT_SUCCESS if successful, otherwise error. +** +*******************************************************************************/ +UINT16 AVDT_UpdateCodecInfo(UINT8 handle, UINT8 num_codec, UINT8 *codec_info, UINT16 codec_info_len) +{ + UINT16 result = AVDT_SUCCESS; + tAVDT_SCB *p_scb; + + /* look up scb */ + if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) { + result = AVDT_BAD_HANDLE; + } + else if (num_codec != 1 || codec_info == NULL || codec_info_len != AVDT_CODEC_SIZE) { + /* currently, only allow one codec info */ + result = AVDT_BAD_PARAMS; + } + else { + /* update codec info */ + p_scb->cs.cfg.num_codec = num_codec; + memcpy(p_scb->cs.cfg.codec_info, codec_info, codec_info_len); + } + return result; +} + +/******************************************************************************* +** ** Function AVDT_RemoveStream ** ** Description Remove a stream endpoint. This function is called when diff --git a/lib/bt/host/bluedroid/stack/avrc/avrc_bld_ct.c b/lib/bt/host/bluedroid/stack/avrc/avrc_bld_ct.c index 18106870..279313d4 100644 --- a/lib/bt/host/bluedroid/stack/avrc/avrc_bld_ct.c +++ b/lib/bt/host/bluedroid/stack/avrc/avrc_bld_ct.c @@ -50,7 +50,7 @@ static tAVRC_STS avrc_bld_next_cmd (tAVRC_NEXT_CMD *p_cmd, BT_HDR *p_pkt) p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; p_data = p_start + 2; /* pdu + rsvd */ - /* add fixed lenth 1 - pdu_id (1) */ + /* add fixed length 1 - pdu_id (1) */ UINT16_TO_BE_STREAM(p_data, 1); UINT8_TO_BE_STREAM(p_data, p_cmd->target_pdu); p_pkt->len = (p_data - p_start); @@ -81,7 +81,7 @@ static tAVRC_STS avrc_bld_set_abs_volume_cmd (tAVRC_SET_VOLUME_CMD *p_cmd, BT_HD /* get the existing length, if any, and also the num attributes */ p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; p_data = p_start + 2; /* pdu + rsvd */ - /* add fixed lenth 1 - volume (1) */ + /* add fixed length 1 - volume (1) */ UINT16_TO_BE_STREAM(p_data, 1); UINT8_TO_BE_STREAM(p_data, (AVRC_MAX_VOLUME & p_cmd->volume)); p_pkt->len = (p_data - p_start); @@ -163,7 +163,7 @@ static BT_HDR *avrc_bld_init_cmd_buffer(tAVRC_COMMAND *p_cmd) /* reserved 0, packet_type 0 */ UINT8_TO_BE_STREAM(p_data, 0); /* continue to the next "case to add length */ - /* add fixed lenth - 0 */ + /* add fixed length - 0 */ UINT16_TO_BE_STREAM(p_data, 0); break; } @@ -237,6 +237,20 @@ static tAVRC_STS avrc_bld_get_element_attr_cmd (tAVRC_GET_ELEM_ATTRS_CMD *p_cmd, return AVRC_STS_NO_ERROR; } +static tAVRC_STS avrc_bld_get_play_status_cmd(tAVRC_CMD *p_cmd, BT_HDR *p_pkt) +{ + UINT8 *p_data, *p_start; + + AVRC_TRACE_API("avrc_bld_get_play_status"); + /* get the existing length */ + p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; + p_data = p_start + 2; /* pdu + rsvd */ + /* add parameter length 0 */ + UINT16_TO_BE_STREAM(p_data, 0); + p_pkt->len = (p_data - p_start); + return AVRC_STS_NO_ERROR; +} + static tAVRC_STS avrc_bld_get_caps_cmd(tAVRC_GET_CAPS_CMD *p_cmd, BT_HDR *p_pkt) { UINT8 *p_data, *p_start; @@ -309,6 +323,10 @@ tAVRC_STS AVRC_BldCommand( tAVRC_COMMAND *p_cmd, BT_HDR **pp_pkt) status = avrc_bld_get_element_attr_cmd(&p_cmd->get_elem_attrs, p_pkt); break; + case AVRC_PDU_GET_PLAY_STATUS: /* 0x30 */ + status = avrc_bld_get_play_status_cmd(&p_cmd->get_play_status, p_pkt); + break; + case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */ status = avrc_bld_register_change_notfn(p_cmd->reg_notif.event_id, p_cmd->reg_notif.param, p_pkt); break; diff --git a/lib/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c b/lib/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c index f185e7b5..72f26513 100644 --- a/lib/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c +++ b/lib/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c @@ -113,6 +113,19 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p } } break; + case AVRC_PDU_GET_PLAY_STATUS: + if (p_msg->hdr.ctype == AVRC_RSP_IMPL_STBL) { + BE_STREAM_TO_UINT32(p_result->get_play_status.song_len, p); + BE_STREAM_TO_UINT32(p_result->get_play_status.song_pos, p); + BE_STREAM_TO_UINT8(p_result->get_play_status.play_status, p); + } + else { + /* got error response */ + p_result->get_play_status.song_len = 0; + p_result->get_play_status.song_pos = 0; + p_result->get_play_status.play_status = AVRC_PLAYSTATE_ERROR; + } + break; default: status = AVRC_STS_BAD_CMD; break; diff --git a/lib/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c b/lib/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c index c30bf94a..fe04ca8f 100644 --- a/lib/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c +++ b/lib/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c @@ -71,7 +71,7 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_ p++; /* skip the reserved byte */ BE_STREAM_TO_UINT16 (len, p); if ((len + 4) != (p_msg->vendor_len)) { - status = AVRC_STS_INTERNAL_ERR; + status = AVRC_STS_NOT_FOUND; } if (status != AVRC_STS_NO_ERROR) { diff --git a/lib/bt/host/bluedroid/stack/avrc/avrc_sdp.c b/lib/bt/host/bluedroid/stack/avrc/avrc_sdp.c index fa98082e..0b624b3f 100644 --- a/lib/bt/host/bluedroid/stack/avrc/avrc_sdp.c +++ b/lib/bt/host/bluedroid/stack/avrc/avrc_sdp.c @@ -29,8 +29,8 @@ #if (defined(AVRC_INCLUDED) && AVRC_INCLUDED == TRUE) -#ifndef SDP_AVRCP_1_5 -#define SDP_AVRCP_1_5 TRUE +#ifndef SDP_AVRCP_1_6 +#define SDP_AVRCP_1_6 TRUE #endif #ifndef SDP_AVCTP_1_4 @@ -52,7 +52,7 @@ const tSDP_PROTOCOL_ELEM avrc_proto_list [] = { #if SDP_AVCTP_1_4 == TRUE {UUID_PROTOCOL_AVCTP, 1, {AVCT_REV_1_4, 0} } #else -#if (SDP_AVRCP_1_4 == TRUE || SDP_AVRCP_1_5 == TRUE) +#if SDP_AVRCP_1_6 == TRUE {UUID_PROTOCOL_AVCTP, 1, {AVCT_REV_1_3, 0} } #else #if AVRC_METADATA_INCLUDED == TRUE @@ -64,7 +64,7 @@ const tSDP_PROTOCOL_ELEM avrc_proto_list [] = { #endif }; -#if SDP_AVRCP_1_5 == TRUE +#if SDP_AVRCP_1_6 == TRUE const tSDP_PROTO_LIST_ELEM avrc_add_proto_list [] = { { AVRC_NUM_PROTO_ELEMS, @@ -251,7 +251,7 @@ UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name, char *p_provide /* add service class id list */ class_list[0] = service_uuid; -#if (SDP_AVCTP_1_4 == TRUE || SDP_AVRCP_1_5 == TRUE) +#if (SDP_AVCTP_1_4 == TRUE || SDP_AVRCP_1_6 == TRUE) if ( service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL ) { class_list[1] = UUID_SERVCLASS_AV_REM_CTRL_CONTROL; count = 2; @@ -263,7 +263,7 @@ UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name, char *p_provide result &= SDP_AddProtocolList(sdp_handle, AVRC_NUM_PROTO_ELEMS, (tSDP_PROTOCOL_ELEM *)avrc_proto_list); /* add profile descriptor list */ -#if SDP_AVRCP_1_5 == TRUE +#if SDP_AVRCP_1_6 == TRUE if (browsing_en) { add_additional_protocol_list = TRUE; } else if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET && @@ -277,7 +277,7 @@ UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name, char *p_provide result &= SDP_AddAdditionProtoLists( sdp_handle, 1, (tSDP_PROTO_LIST_ELEM *)avrc_add_proto_list); } - result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, AVRC_REV_1_5); + result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, AVRC_REV_1_6); #else #if AVRC_METADATA_INCLUDED == TRUE result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, AVRC_REV_1_3); @@ -292,6 +292,13 @@ UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name, char *p_provide } else if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET && media_player_virtual_filesystem_supported) { supported_feature |= AVRC_SUPF_TG_BROWSE; } +#if AVRC_CA_INCLUDED + if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL || service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) { + supported_feature |= AVRC_SUPF_CT_COVER_ART_GIP; + supported_feature |= AVRC_SUPF_CT_COVER_ART_GI; + supported_feature |= AVRC_SUPF_CT_COVER_ART_GLT; + } +#endif /* add supported feature */ p = temp; UINT16_TO_BE_STREAM(p, supported_feature); @@ -383,7 +390,7 @@ bt_status_t AVRC_Init(void) ** ** Function AVRC_Deinit ** -** Description This function is called at stack shotdown to free the +** Description This function is called at stack shutdown to free the ** control block (if using dynamic memory), and deinitializes the ** control block and tracing level. ** diff --git a/lib/bt/host/bluedroid/stack/btm/btm_acl.c b/lib/bt/host/bluedroid/stack/btm/btm_acl.c index 4b7e7eed..90506785 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_acl.c @@ -335,7 +335,7 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, UINT8 bdn[BTM_MAX_REM_BD_NAME_L #if (CLASSIC_BT_INCLUDED == TRUE) const UINT8 req_pend = (p_dev_rec->sm4 & BTM_SM4_REQ_PEND); #endif ///CLASSIC_BT_INCLUDED == TRUE - /* Store the Peer Security Capabilites (in SM4 and rmt_sec_caps) */ + /* Store the Peer Security Capabilities (in SM4 and rmt_sec_caps) */ #if (SMP_INCLUDED == TRUE) btm_sec_set_peer_sec_caps(p, p_dev_rec); #endif ///SMP_INCLUDED == TRUE @@ -350,7 +350,7 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, UINT8 bdn[BTM_MAX_REM_BD_NAME_L return; } } else { - /* If remote features indicated secure connection (SC) mode, check the remote feautres again*/ + /* If remote features indicated secure connection (SC) mode, check the remote features again*/ /* this is to prevent from BIAS attack where attacker can downgrade SC mode*/ btm_read_remote_features (p->hci_handle); } @@ -474,7 +474,7 @@ void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport) BTM_TRACE_DEBUG("Bonded\n"); } } else { - BTM_TRACE_DEBUG("Bletooth link down\n"); + BTM_TRACE_DEBUG("Bluetooth link down\n"); p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED); } @@ -531,10 +531,11 @@ void btm_acl_device_down (void) *******************************************************************************/ void btm_acl_update_busy_level (tBTM_BLI_EVENT event) { - tBTM_BL_UPDATE_DATA evt; - UINT8 busy_level; - BTM_TRACE_DEBUG ("btm_acl_update_busy_level\n"); + UINT8 busy_level_flags = 0; BOOLEAN old_inquiry_state = btm_cb.is_inquiry; + + BTM_TRACE_DEBUG ("btm_acl_update_busy_level\n"); + switch (event) { case BTM_BLI_ACL_UP_EVT: BTM_TRACE_DEBUG ("BTM_BLI_ACL_UP_EVT\n"); @@ -545,30 +546,31 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event) case BTM_BLI_PAGE_EVT: BTM_TRACE_DEBUG ("BTM_BLI_PAGE_EVT\n"); btm_cb.is_paging = TRUE; - evt.busy_level_flags = BTM_BL_PAGING_STARTED; + busy_level_flags = BTM_BL_PAGING_STARTED; break; case BTM_BLI_PAGE_DONE_EVT: BTM_TRACE_DEBUG ("BTM_BLI_PAGE_DONE_EVT\n"); btm_cb.is_paging = FALSE; - evt.busy_level_flags = BTM_BL_PAGING_COMPLETE; + busy_level_flags = BTM_BL_PAGING_COMPLETE; break; case BTM_BLI_INQ_EVT: BTM_TRACE_DEBUG ("BTM_BLI_INQ_EVT\n"); btm_cb.is_inquiry = TRUE; - evt.busy_level_flags = BTM_BL_INQUIRY_STARTED; + busy_level_flags = BTM_BL_INQUIRY_STARTED; break; case BTM_BLI_INQ_CANCEL_EVT: BTM_TRACE_DEBUG ("BTM_BLI_INQ_CANCEL_EVT\n"); btm_cb.is_inquiry = FALSE; - evt.busy_level_flags = BTM_BL_INQUIRY_CANCELLED; + busy_level_flags = BTM_BL_INQUIRY_CANCELLED; break; case BTM_BLI_INQ_DONE_EVT: BTM_TRACE_DEBUG ("BTM_BLI_INQ_DONE_EVT\n"); btm_cb.is_inquiry = FALSE; - evt.busy_level_flags = BTM_BL_INQUIRY_COMPLETE; + busy_level_flags = BTM_BL_INQUIRY_COMPLETE; break; } + UINT8 busy_level; if (btm_cb.is_paging || btm_cb.is_inquiry) { busy_level = 10; } else { @@ -576,8 +578,11 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event) } if ((busy_level != btm_cb.busy_level) || (old_inquiry_state != btm_cb.is_inquiry)) { - evt.event = BTM_BL_UPDATE_EVT; - evt.busy_level = busy_level; + tBTM_BL_UPDATE_DATA evt = { + .event = BTM_BL_UPDATE_EVT, + .busy_level = busy_level, + .busy_level_flags = busy_level_flags, + }; btm_cb.busy_level = busy_level; if (btm_cb.p_bl_changed_cb && (btm_cb.bl_evt_mask & BTM_BL_UPDATE_MASK)) { (*btm_cb.p_bl_changed_cb)((tBTM_BL_EVENT_DATA *)&evt); @@ -1016,7 +1021,7 @@ void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read_pages) const UINT8 req_pend = (p_dev_rec->sm4 & BTM_SM4_REQ_PEND); #if (SMP_INCLUDED == TRUE) - /* Store the Peer Security Capabilites (in SM4 and rmt_sec_caps) */ + /* Store the Peer Security Capabilities (in SM4 and rmt_sec_caps) */ btm_sec_set_peer_sec_caps(p_acl_cb, p_dev_rec); #endif ///SMP_INCLUDED == TRUE BTM_TRACE_API("%s: pend:%d\n", __FUNCTION__, req_pend); @@ -1455,7 +1460,7 @@ void btm_process_clk_off_comp_evt (UINT16 hci_handle, UINT16 clock_offset) ** ** Function btm_acl_role_changed ** -** Description This function is called whan a link's master/slave role change +** Description This function is called when a link's master/slave role change ** event or command status event (with error) is received. ** It updates the link control block, and calls ** the registered callback with status and role (if registered). @@ -2060,6 +2065,7 @@ tBTM_STATUS BTM_ReadLinkQuality (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) return (BTM_UNKNOWN_ADDR); } +#if (BLE_HOST_READ_TX_POWER_EN == TRUE) /******************************************************************************* ** ** Function BTM_ReadTxPower @@ -2116,6 +2122,7 @@ tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_C /* If here, no BD Addr found */ return (BTM_UNKNOWN_ADDR); } +#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) tBTM_STATUS BTM_SetAclPktTypes(BD_ADDR remote_bda, UINT16 pkt_types, tBTM_CMPL_CB *p_cb) { @@ -2182,6 +2189,55 @@ void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types) } #if (BLE_INCLUDED == TRUE) + +/******************************************************************************* +** +** Function BTM_ReadChannelMap +** +** Description This function is called to read the current channel map +** for the given connection. The results are returned via +** the callback (tBTM_BLE_CH_MAP_RESULTS). +** +** Returns BTM_CMD_STARTED if successfully initiated or error code +** +*******************************************************************************/ +tBTM_STATUS BTM_ReadChannelMap(BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) +{ + tACL_CONN *p; + tBTM_BLE_CH_MAP_RESULTS result; + + BTM_TRACE_DEBUG("BTM_ReadChannelMap: RemBdAddr: %02x%02x%02x%02x%02x%02x\n", + remote_bda[0], remote_bda[1], remote_bda[2], + remote_bda[3], remote_bda[4], remote_bda[5]); + + memset(result.channel_map, 0, sizeof(result.channel_map)); // Clear channel map data + /* If someone already waiting for the channel map, do not allow another */ + if (btm_cb.devcb.p_ble_ch_map_cmpl_cb) { + result.status = BTM_BUSY; + (*p_cb)(&result); + return BTM_BUSY; + } + p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_LE); + if (p != NULL) { + btm_cb.devcb.p_ble_ch_map_cmpl_cb = p_cb; + + if (!btsnd_hcic_ble_read_chnl_map(p->hci_handle)) { + btm_cb.devcb.p_ble_ch_map_cmpl_cb = NULL; + result.status = BTM_NO_RESOURCES; + (*p_cb)(&result); + return BTM_NO_RESOURCES; + } else { + return BTM_CMD_STARTED; + } + } + + /* If here, no BD Addr found */ + result.status = BTM_UNKNOWN_ADDR; + (*p_cb)(&result); + return BTM_UNKNOWN_ADDR; +} + +#if (BLE_HOST_READ_TX_POWER_EN == TRUE) tBTM_STATUS BTM_BleReadAdvTxPower(tBTM_CMPL_CB *p_cb) { BOOLEAN ret; @@ -2208,6 +2264,7 @@ tBTM_STATUS BTM_BleReadAdvTxPower(tBTM_CMPL_CB *p_cb) return BTM_CMD_STARTED; } } +#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) void BTM_BleGetWhiteListSize(uint16_t *length) { @@ -2218,8 +2275,21 @@ void BTM_BleGetWhiteListSize(uint16_t *length) *length = p_cb->white_list_avail_size; return; } + +#if (BLE_50_EXTEND_SYNC_EN == TRUE) +void BTM_BleGetPeriodicAdvListSize(uint8_t *size) +{ + tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; + if (p_cb->periodic_adv_list_size == 0) { + BTM_TRACE_WARNING("%s Periodic Adv list is full.", __func__); + } + *size = p_cb->periodic_adv_list_size; +} +#endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE) + #endif ///BLE_INCLUDED == TRUE +#if (BLE_HOST_READ_TX_POWER_EN == TRUE) /******************************************************************************* ** ** Function btm_read_tx_power_complete @@ -2273,6 +2343,63 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble) (*p_cb)(&results); } } +#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) + +/******************************************************************************* +** +** Function btm_read_channel_map_complete +** +** Description This function is called when the command complete message +** is received from the HCI for the read channel map request. +** It processes the received channel map data and invokes the +** registered callback function with the results. +** +** Returns void +** +*******************************************************************************/ +void btm_read_channel_map_complete(UINT8 *p) +{ + tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_ble_ch_map_cmpl_cb; + tBTM_BLE_CH_MAP_RESULTS results; + UINT16 handle; + tACL_CONN *p_acl_cb = NULL; + + BTM_TRACE_DEBUG("btm_read_channel_map_complete\n"); + + /* Reset the callback pointer to prevent duplicate calls */ + btm_cb.devcb.p_ble_ch_map_cmpl_cb = NULL; + + if (p_cb) { + /* Extract HCI status from the response */ + STREAM_TO_UINT8(results.hci_status, p); + + if (results.hci_status == HCI_SUCCESS) { + results.status = BTM_SUCCESS; + + /* Extract the connection handle and channel map */ + STREAM_TO_UINT16(handle, p); + STREAM_TO_ARRAY(results.channel_map, p, 5); + + BTM_TRACE_DEBUG("BTM Channel Map Complete: handle 0x%04x, hci status 0x%02x", handle, results.hci_status); + BTM_TRACE_DEBUG("Channel Map: %02x %02x %02x %02x %02x", + results.channel_map[0], results.channel_map[1], results.channel_map[2], + results.channel_map[3], results.channel_map[4]); + + /* Retrieve the remote BD address using the connection handle */ + p_acl_cb = btm_handle_to_acl(handle); + if (p_acl_cb) { + memcpy(results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN); + } + } else { + results.status = BTM_ERR_PROCESSING; + BTM_TRACE_ERROR("BTM Channel Map Read Failed: hci status 0x%02x", results.hci_status); + } + + /* Invoke the registered callback with the results */ + (*p_cb)(&results); + } +} + /******************************************************************************* ** @@ -2705,7 +2832,7 @@ void btm_acl_connected(BD_ADDR bda, UINT16 handle, UINT8 link_type, UINT8 enc_mo l2c_link_hci_conn_comp(status, handle, bda); } #if BTM_SCO_INCLUDED == TRUE - else { + else if (link_type == HCI_LINK_TYPE_SCO) { memset(&esco_data, 0, sizeof(tBTM_ESCO_DATA)); esco_data.link_type = HCI_LINK_TYPE_SCO; memcpy (esco_data.bd_addr, bda, BD_ADDR_LEN); @@ -2721,9 +2848,10 @@ void btm_acl_connected(BD_ADDR bda, UINT16 handle, UINT8 link_type, UINT8 enc_mo ** Description Handle ACL disconnection complete event ** *******************************************************************************/ -void btm_acl_disconnected(UINT16 handle, UINT8 reason) +BOOLEAN btm_acl_disconnected(UINT16 handle, UINT8 reason) { - + BOOLEAN status = FALSE; + BOOLEAN dis_status; /* Report BR/EDR ACL disconnection result to upper layer */ tACL_CONN *conn = btm_handle_to_acl(handle); if (conn) { @@ -2731,6 +2859,7 @@ void btm_acl_disconnected(UINT16 handle, UINT8 reason) if (conn->transport == BT_TRANSPORT_BR_EDR) #endif { + status = TRUE; tBTM_ACL_LINK_STAT_EVENT_DATA evt_data = { .event = BTM_ACL_DISCONN_CMPL_EVT, .link_act.disconn_cmpl.reason = reason, @@ -2742,16 +2871,29 @@ void btm_acl_disconnected(UINT16 handle, UINT8 reason) } #if BTM_SCO_INCLUDED == TRUE + dis_status = l2c_link_hci_disc_comp (handle, reason); /* If L2CAP doesn't know about it, send it to SCO */ - if (!l2c_link_hci_disc_comp (handle, reason)) { - btm_sco_removed (handle, reason); + if (!dis_status) { + dis_status = btm_sco_removed (handle, reason); + } else { + status = TRUE; } #else - l2c_link_hci_disc_comp(handle, reason); + dis_status = l2c_link_hci_disc_comp(handle, reason); #endif /* BTM_SCO_INCLUDED */ + if (dis_status) { + // find tL2C_LCB + status = TRUE; + } #if (SMP_INCLUDED == TRUE) /* Notify security manager */ - btm_sec_disconnected(handle, reason); + if (btm_sec_disconnected(handle, reason)) { + // find tBTM_SEC_DEV_REC + status = TRUE; + } + #endif /* SMP_INCLUDED == TRUE */ + + return status; } diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble.c b/lib/bt/host/bluedroid/stack/btm/btm_ble.c index 334001fe..8f676a65 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_ble.c @@ -217,7 +217,7 @@ void BTM_BleLoadLocalKeys(UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key) break; default: - BTM_TRACE_ERROR("unknow local key type: %d", key_type); + BTM_TRACE_ERROR("unknown local key type: %d", key_type); break; } } @@ -553,6 +553,7 @@ void BTM_BleSecureConnectionCreateOobData(void) #endif } +#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) /****************************************************************************** ** ** Function BTM_BleSetConnScanParams @@ -582,15 +583,17 @@ void BTM_BleSetConnScanParams (UINT32 scan_interval, UINT32 scan_window) p_ble_cb->scan_win = scan_window; new_param = TRUE; } - +#if (tGATT_BG_CONN_DEV == TRUE) if (new_param && p_ble_cb->conn_state == BLE_BG_CONN) { btm_ble_suspend_bg_conn(); } +#endif // #if (tGATT_BG_CONN_DEV == TRUE) } else { BTM_TRACE_ERROR("Illegal Connection Scan Parameters"); } #endif } +#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) /******************************************************** ** @@ -694,7 +697,7 @@ void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR BTM_TRACE_DEBUG ("btm_find_dev_type - unknown device, BR/EDR assumed"); } } - } else { /* there is a security device record exisitng */ + } else { /* there is a security device record existing */ /* new inquiry result, overwrite device type in security device record */ if (p_inq_info) { p_dev_rec->device_type = p_inq_info->results.device_type; @@ -707,7 +710,7 @@ void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR } else if (memcmp(p_dev_rec->ble.pseudo_addr, remote_bda, BD_ADDR_LEN) == 0) { *p_dev_type = BT_DEVICE_TYPE_BLE; *p_addr_type = p_dev_rec->ble.ble_addr_type; - } else { /* matching static adddress only */ + } else { /* matching static address only */ *p_dev_type = BT_DEVICE_TYPE_BREDR; *p_addr_type = BLE_ADDR_PUBLIC; } @@ -766,6 +769,7 @@ BOOLEAN BTM_ReadConnectedTransportAddress(BD_ADDR remote_bda, tBT_TRANSPORT tran } #if (BLE_INCLUDED == TRUE) +#if (BLE_42_DTM_TEST_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleReceiverTest @@ -805,7 +809,8 @@ void BTM_BleTransmitterTest(UINT8 tx_freq, UINT8 test_data_len, BTM_TRACE_ERROR("%s: Unable to Trigger LE transmitter test", __FUNCTION__); } } - +#endif // #if (BLE_42_DTM_TEST_EN == TRUE) +#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE)) /******************************************************************************* ** ** Function BTM_BleTestEnd @@ -837,9 +842,9 @@ void btm_ble_test_command_complete(UINT8 *p) (*p_cb)(p); } } +#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE)) - -#if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_DTM_TEST_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleEnhancedReceiverTest @@ -882,7 +887,7 @@ void BTM_BleEnhancedTransmitterTest(UINT8 tx_freq, UINT8 test_data_len, BTM_TRACE_ERROR("%s: Unable to Trigger LE enhanced transmitter test", __FUNCTION__); } } -#endif // BLE_50_FEATURE_SUPPORT +#endif // #if (BLE_50_DTM_TEST_EN == TRUE) /******************************************************************************* ** @@ -1061,7 +1066,7 @@ tBTM_SEC_ACTION btm_ble_determine_security_act(BOOLEAN is_originator, BD_ADDR bd ** LE link for LE COC. ** ** Parameter bdaddr: remote device address. -** psm : PSM of the LE COC sevice. +** psm : PSM of the LE COC service. ** is_originator: TRUE if outgoing connection. ** p_callback : Pointer to the callback function. ** p_ref_data : Pointer to be returned along with the callback. @@ -1078,7 +1083,7 @@ BOOLEAN btm_ble_start_sec_check(BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_originat /* If there is no application registered with this PSM do not allow connection */ if (!p_serv_rec) { - BTM_TRACE_WARNING ("%s PSM: %d no application registerd", __func__, psm); + BTM_TRACE_WARNING ("%s PSM: %d no application registered", __func__, psm); (*p_callback) (bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_MODE_UNSUPPORTED); return FALSE; } @@ -1151,7 +1156,7 @@ void btm_ble_rand_enc_complete (UINT8 *p, UINT16 op_code, tBTM_RAND_ENC_CB *p_en /* If there was a callback address for vcs complete, call it */ if (p_enc_cplt_cback && p) { - /* Pass paramters to the callback function */ + /* Pass parameters to the callback function */ STREAM_TO_UINT8(params.status, p); /* command status */ if (params.status == HCI_SUCCESS) { @@ -1208,7 +1213,7 @@ void btm_ble_increment_sign_ctr(BD_ADDR bd_addr, BOOLEAN is_local ) ** Function btm_ble_get_enc_key_type ** ** Description This function is to get the BLE key type that has been exchanged -** in betweem local device and peer device. +** in between local device and peer device. ** ** Returns p_key_type: output parameter to carry the key type value. ** @@ -1235,7 +1240,7 @@ BOOLEAN btm_ble_get_enc_key_type(BD_ADDR bd_addr, UINT8 *p_key_types) ** ** Description This function is called to read the local DIV ** -** Returns TRUE - if a valid DIV is availavle +** Returns TRUE - if a valid DIV is available *******************************************************************************/ BOOLEAN btm_get_local_div (BD_ADDR bd_addr, UINT16 *p_div) { @@ -1487,7 +1492,7 @@ void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req, tBTM_BLE BTM_TRACE_DEBUG ("dev_rec sec_flags=0x%x", p_dev_rec->sec_flags); - /* currently encrpted */ + /* currently encrypted */ if (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED) { if (p_dev_rec->sec_flags & BTM_SEC_LE_AUTHENTICATED) { cur_sec_level = BTM_LE_SEC_AUTHENTICATED; @@ -1691,7 +1696,7 @@ tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk) ** ** Function btm_ble_link_encrypted ** -** Description This function is called when LE link encrption status is changed. +** Description This function is called when LE link encryption status is changed. ** ** Returns void ** @@ -1949,7 +1954,7 @@ static void btm_ble_resolve_random_addr_on_conn_cmpl(void *p_rec, void *p_data) ** Function btm_ble_connected ** ** Description This function is when a LE connection to the peer device is -** establsihed +** established ** ** Returns void ** @@ -2060,7 +2065,7 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced) peer_addr_type = bda_type; match = btm_identity_addr_to_random_pseudo (bda, &bda_type, FALSE); - /* possiblly receive connection complete with resolvable random on + /* possibly receive connection complete with resolvable random on slave role while the device has been paired */ /* It will cause that scanner doesn't send scan request to advertiser @@ -2143,6 +2148,16 @@ void btm_ble_create_ll_conn_complete (UINT8 status) if (status != HCI_SUCCESS) { btm_ble_set_conn_st(BLE_CONN_IDLE); btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, NULL, status); + if(l2cb.is_ble_connecting) { + /* see L2CA_CancelBleConnectReq() */ + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(l2cb.ble_connecting_bda, BT_TRANSPORT_LE); + /* Do not remove lcb if an LE link is already up as a peripheral */ + if (p_lcb != NULL && + !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_LE_ACL_IS_CONNECTED(l2cb.ble_connecting_bda))) { + p_lcb->disc_reason = L2CAP_CONN_CANCEL; + l2cu_release_lcb (p_lcb); + } + } } } @@ -2279,17 +2294,16 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) } - } else { - if (event == SMP_SC_LOC_OOB_DATA_UP_EVT) { - tBTM_LE_EVT_DATA evt_data; - memcpy(&evt_data.local_oob_data, &p_data->loc_oob_data, sizeof(tSMP_LOC_OOB_DATA)); - if (btm_cb.api.p_le_callback) { - (*btm_cb.api.p_le_callback)(event, bd_addr, &evt_data); - } - } else { - BTM_TRACE_ERROR("btm_proc_smp_cback received for unknown device"); + } + + if (event == SMP_SC_LOC_OOB_DATA_UP_EVT) { + tBTM_LE_EVT_DATA evt_data; + memcpy(&evt_data.local_oob_data, &p_data->loc_oob_data, sizeof(tSMP_LOC_OOB_DATA)); + if (btm_cb.api.p_le_callback) { + (*btm_cb.api.p_le_callback)(event, bd_addr, &evt_data); } } + return 0; } #endif ///SMP_INCLUDED == TRUE @@ -2300,7 +2314,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) ** Function BTM_BleDataSignature ** ** Description This function is called to sign the data using AES128 CMAC -** algorith. +** algorithm. ** ** Parameter bd_addr: target device the data to be signed for. ** p_text: singing data @@ -2308,7 +2322,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) ** signature: output parameter where data signature is going to ** be stored. ** -** Returns TRUE if signing sucessul, otherwise FALSE. +** Returns TRUE if signing successful, otherwise FALSE. ** *******************************************************************************/ #if (SMP_INCLUDED == TRUE) @@ -2491,7 +2505,7 @@ BOOLEAN BTM_BleSecurityProcedureIsRunning(BD_ADDR bd_addr) ** Function BTM_BleGetSupportedKeySize ** ** Description This function gets the maximum encryption key size in bytes -** the local device can suport. +** the local device can support. ** record. ** ** Returns the key size or 0 if the size can't be retrieved. @@ -2932,7 +2946,7 @@ uint8_t btm_ble_scan_active_count(void) } #if (SMP_INCLUDED == TRUE) -uint8_t btm_ble_sec_dev_active_count(void) +uint8_t btm_ble_sec_dev_record_count(void) { tBTM_SEC_DEV_REC *p_dev_rec = NULL; list_node_t *p_node = NULL; @@ -2948,6 +2962,12 @@ uint8_t btm_ble_sec_dev_active_count(void) return count; } + +void btm_ble_clear_sec_dev_record(void) +{ + /* only used when connection is closed */ + if(btm_cb.p_sec_dev_rec_list) list_clear(btm_cb.p_sec_dev_rec_list); +} #endif #if (BLE_PRIVACY_SPT == TRUE) diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 04ad4804..76fe63c0 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -21,6 +21,7 @@ extern BOOLEAN BTM_GetLocalResolvablePrivateAddr(BD_ADDR bda); extern void BTM_UpdateAddrInfor(uint8_t addr_type, BD_ADDR bda); extern void BTM_BleSetStaticAddr(BD_ADDR rand_addr); extern uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK *cb); +#if (BLE_50_EXTEND_ADV_EN == TRUE) static tBTM_STATUS btm_ble_ext_adv_params_validate(tBTM_BLE_GAP_EXT_ADV_PARAMS *params); static tBTM_STATUS btm_ble_ext_adv_set_data_validate(UINT8 instance, UINT16 len, UINT8 *data); @@ -35,6 +36,8 @@ typedef struct { } tBTM_EXT_ADV_RECORD; tBTM_EXT_ADV_RECORD adv_record[MAX_BLE_ADV_INSTANCE] = {0}; +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) + extern void btm_ble_inter_set(bool extble_inter); #if !UC_BT_STACK_NO_LOG @@ -193,11 +196,12 @@ void btm_ble_extendadvcb_init(void) { memset(&extend_adv_cb, 0, sizeof(tBTM_BLE_EXTENDED_CB)); } - +#if (BLE_50_EXTEND_ADV_EN == TRUE) void btm_ble_advrecod_init(void) { memset(&adv_record[0], 0, sizeof(tBTM_EXT_ADV_RECORD)*MAX_BLE_ADV_INSTANCE); } +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) void BTM_BleGapRegisterCallback(tBTM_BLE_5_HCI_CBACK cb) { @@ -249,10 +253,10 @@ tBTM_STATUS BTM_BleSetPreferDefaultPhy(UINT8 tx_phy_mask, UINT8 rx_phy_mask) if ((err = btsnd_hcic_ble_set_prefered_default_phy(all_phys, tx_phy_mask, rx_phy_mask)) != HCI_SUCCESS) { BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)", __func__, btm_ble_hci_status_to_str(err), err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } - cb_params.set_perf_def_phy.status = err; + cb_params.set_perf_def_phy.status = status; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_PREFERED_DEFAULT_PHY_COMPLETE_EVT, &cb_params); @@ -286,6 +290,7 @@ tBTM_STATUS BTM_BleSetPreferPhy(BD_ADDR bd_addr, UINT8 all_phys, UINT8 tx_phy_ma return BTM_SUCCESS; } +#if (BLE_50_EXTEND_ADV_EN == TRUE) tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr) { tBTM_STATUS status = BTM_SUCCESS; @@ -330,7 +335,7 @@ tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr) if((err = btsnd_hcic_ble_set_extend_rand_address(instance, rand_addr)) != HCI_SUCCESS) { BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)", __func__, btm_ble_hci_status_to_str(err), err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } else { // set random address success, update address info if(extend_adv_cb.inst[instance].configured && extend_adv_cb.inst[instance].connetable) { @@ -340,8 +345,8 @@ tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr) } end: - cb_params.status = status; - + cb_params.set_ext_rand_addr.status = status; + cb_params.set_ext_rand_addr.instance = instance; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, &cb_params); return status; @@ -403,7 +408,7 @@ tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PAR params->primary_phy, params->max_skip, params->secondary_phy, params->sid, params->scan_req_notif)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; goto end; } @@ -414,13 +419,14 @@ end: // update RPA address if((err = btsnd_hcic_ble_set_extend_rand_address(instance, rand_addr)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } else { // set addr success, update address info BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr); } } - cb_params.status = status; + cb_params.set_params.status = status; + cb_params.set_params.instance = instance; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params); return status; @@ -451,27 +457,36 @@ tBTM_STATUS BTM_BleConfigExtendedAdvDataRaw(BOOLEAN is_scan_rsp, UINT8 instance, } else if (rem_len <= BTM_BLE_EXT_ADV_DATA_LEN_MAX) { operation = BTM_BLE_ADV_DATA_OP_LAST_FRAG; } else { - operation = BTM_BLE_ADV_DATA_OP_INTERMEDIATE_FRAG; - } + operation = BTM_BLE_ADV_DATA_OP_INTERMEDIATE_FRAG; + } } if (!is_scan_rsp) { if ((err = btsnd_hcic_ble_set_ext_adv_data(instance, operation, 0, send_data_len, &data[data_offset])) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EA SetAdvData: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; + break; } } else { if ((err = btsnd_hcic_ble_set_ext_adv_scan_rsp_data(instance, operation, 0, send_data_len, &data[data_offset])) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EA SetScanRspData: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; + break; } } rem_len -= send_data_len; - data_offset += send_data_len; + data_offset += send_data_len; } while (rem_len); end: - cb_params.status = status; + if (is_scan_rsp) { + cb_params.scan_rsp_data_set.status = status; + cb_params.scan_rsp_data_set.instance = instance; + } else { + cb_params.adv_data_set.status = status; + cb_params.adv_data_set.instance = instance; + } + BTM_ExtBleCallbackTrigger(is_scan_rsp ? BTM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT, &cb_params); return status; @@ -514,7 +529,7 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_ if ((err = btsnd_hcic_ble_ext_adv_enable(enable, num, instance, duration, max_events)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EA En=%d: cmd err=0x%x", enable, err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } osi_free(instance); @@ -525,7 +540,7 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_ if ((err = btsnd_hcic_ble_ext_adv_enable(enable, num, NULL, NULL, NULL)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EA En=%d: cmd err=0x%x", enable, err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } goto end; } @@ -574,7 +589,12 @@ end: } } - cb_params.status = status; + cb_params.adv_start.status = status; + cb_params.adv_start.instance_num = num; + for (uint8_t i = 0; i < num; i++) { + cb_params.adv_start.instance[i] = ext_adv[i].instance; + } + BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT, &cb_params); return status; @@ -593,6 +613,7 @@ tBTM_STATUS BTM_BleStartExtAdvRestart(uint8_t con_handle) } if((index >= MAX_BLE_ADV_INSTANCE) || (!adv_record[index].invalid)) { + BTM_TRACE_WARNING("%s failed to find extend adv, adv_handle %u con_handle %u", __func__, index, con_handle); return BTM_WRONG_MODE; } @@ -618,7 +639,7 @@ tBTM_STATUS BTM_BleExtAdvSetRemove(UINT8 instance) if ((err = btsnd_hcic_ble_remove_adv_set(instance)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EAS Rm: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } else { extend_adv_cb.inst[instance].configured = false; extend_adv_cb.inst[instance].legacy_pdu = false; @@ -629,7 +650,9 @@ tBTM_STATUS BTM_BleExtAdvSetRemove(UINT8 instance) end: - cb_params.status = status; + cb_params.adv_start.status = status; + cb_params.adv_start.instance_num = 1; + cb_params.adv_start.instance[0] = instance; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT, &cb_params); @@ -644,7 +667,7 @@ tBTM_STATUS BTM_BleExtAdvSetClear(void) if ((err = btsnd_hcic_ble_clear_adv_set()) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EAS Clr: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } else { for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++) { extend_adv_cb.inst[i].configured = false; @@ -655,13 +678,15 @@ tBTM_STATUS BTM_BleExtAdvSetClear(void) } } - cb_params.status = status; + cb_params.adv_start.status = status; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT, &cb_params); return status; } +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) +#if (BLE_50_PERIODIC_ADV_EN == TRUE) tBTM_STATUS BTM_BlePeriodicAdvSetParams(UINT8 instance, tBTM_BLE_Periodic_Adv_Params *params) { tBTM_STATUS status = BTM_SUCCESS; @@ -688,12 +713,13 @@ tBTM_STATUS BTM_BlePeriodicAdvSetParams(UINT8 instance, tBTM_BLE_Periodic_Adv_Pa if ((err= btsnd_hcic_ble_set_periodic_adv_params(instance, params->interval_min, params->interval_max, params->properties)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA SetParams: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } end: - cb_params.status = status; + cb_params.per_adv_set_params.status = status; + cb_params.per_adv_set_params.instance = instance; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params); @@ -740,14 +766,18 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data if ((err = btsnd_hcic_ble_set_periodic_adv_data(instance, operation, send_data_len, &data[data_offset])) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA SetData: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; + break; } + rem_len -= send_data_len; - data_offset += send_data_len; + data_offset += send_data_len; } while(rem_len); end: - cb_params.status = status; + cb_params.per_adv_data_set.status = status; + cb_params.per_adv_data_set.instance = instance; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, &cb_params); return status; @@ -767,19 +797,26 @@ tBTM_STATUS BTM_BlePeriodicAdvEnable(UINT8 instance, UINT8 enable) if ((err = btsnd_hcic_ble_periodic_adv_enable(enable, instance)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA En=%d: cmd err=0x%x", enable, err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } end: - - cb_params.status = status; + if (enable) { + cb_params.per_adv_start.status = status; + cb_params.per_adv_start.instance = instance; + } else { + cb_params.per_adv_stop.status = status; + cb_params.per_adv_stop.instance = instance; + } BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT, &cb_params); return status; } +#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params) { //tHCI_STATUS err = HCI_SUCCESS; @@ -794,10 +831,10 @@ tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params) if ((params->sync_timeout < 0x0a || params->sync_timeout > 0x4000) || (params->filter_policy > 0x01) - #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH) +#if (BLE_FEAT_CREATE_SYNC_ENH == TRUE) || (params->reports_disabled > 0x01) || (params->filter_duplicates > 0x01) - #endif +#endif // (BLE_FEAT_CREATE_SYNC_ENH == TRUE) /*If the Periodic Advertiser List is not used, the Advertising_SID, Advertiser Address_Type, and Advertiser Address parameters specify the periodic advertising device to listen to; otherwise they @@ -814,17 +851,17 @@ tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params) SET_BIT(option, 0); } - #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH) +#if (BLE_FEAT_CREATE_SYNC_ENH == TRUE) if (params->reports_disabled) { SET_BIT(option, 1); } if (params->filter_duplicates) { SET_BIT(option, 2); } - #endif +#endif // (BLE_FEAT_CREATE_SYNC_ENH == TRUE) if (!btsnd_hcic_ble_periodic_adv_create_sync(option, params->sid, params->addr_type, - params->addr, params->sync_timeout, 0)) { + params->addr, params->sync_timeout, params->sync_cte_type)) { BTM_TRACE_ERROR("LE PA CreateSync cmd failed"); status = BTM_ILLEGAL_VALUE; } @@ -837,6 +874,8 @@ end: return status; } +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) + void btm_set_phy_callback(UINT8 status) { tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; @@ -845,6 +884,8 @@ void btm_set_phy_callback(UINT8 status) BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT, &cb_params); } + +#if (BLE_50_EXTEND_SYNC_EN == TRUE) void btm_create_sync_callback(UINT8 status) { tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; @@ -852,6 +893,7 @@ void btm_create_sync_callback(UINT8 status) BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT, &cb_params); } +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) void btm_read_phy_callback(uint8_t hci_status, uint16_t conn_handle, uint8_t tx_phy, uint8_t rx_phy) { @@ -872,6 +914,7 @@ void btm_read_phy_callback(uint8_t hci_status, uint16_t conn_handle, uint8_t tx_ BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_PHY_COMPLETE_EVT, &cb_params); } +#if (BLE_50_EXTEND_SYNC_EN == TRUE) tBTM_STATUS BTM_BlePeriodicAdvSyncCancel(void) { tHCI_STATUS err = HCI_SUCCESS; @@ -880,7 +923,7 @@ tBTM_STATUS BTM_BlePeriodicAdvSyncCancel(void) if ((err = btsnd_hcic_ble_periodic_adv_create_sync_cancel()) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA SyncCancel, cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } cb_params.status = status; @@ -898,7 +941,7 @@ tBTM_STATUS BTM_BlePeriodicAdvSyncTerm(UINT16 sync_handle) if (( err = btsnd_hcic_ble_periodic_adv_term_sync(sync_handle)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA SyncTerm: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } cb_params.status = status; @@ -922,7 +965,7 @@ tBTM_STATUS BTM_BlePeriodicAdvAddDevToList(tBLE_ADDR_TYPE addr_type, BD_ADDR add if ((err = btsnd_hcic_ble_add_dev_to_periodic_adv_list(addr_type, addr, sid)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA AddDevToList: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } end: @@ -946,7 +989,7 @@ tBTM_STATUS BTM_BlePeriodicAdvRemoveDevFromList(tBLE_ADDR_TYPE addr_type, BD_ADD if ((err = btsnd_hcic_ble_rm_dev_from_periodic_adv_list(addr_type, addr, sid)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA RmDevFromList: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } end: @@ -964,7 +1007,7 @@ tBTM_STATUS BTM_BlePeriodicAdvClearDev(void) if ((err = btsnd_hcic_ble_clear_periodic_adv_list()) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA ClrDev: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } cb_params.status = status; @@ -972,7 +1015,9 @@ tBTM_STATUS BTM_BlePeriodicAdvClearDev(void) return status; } +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) +#if (BLE_50_EXTEND_SCAN_EN == TRUE) tBTM_STATUS BTM_BleSetExtendedScanParams(tBTM_BLE_EXT_SCAN_PARAMS *params) { UINT8 phy_mask = 0; @@ -1016,7 +1061,7 @@ tBTM_STATUS BTM_BleSetExtendedScanParams(tBTM_BLE_EXT_SCAN_PARAMS *params) if ((err = btsnd_hcic_ble_set_ext_scan_params(params->own_addr_type, params->filter_policy, phy_mask, phy_count, hci_params)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE ES SetParams: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } end: @@ -1042,7 +1087,7 @@ tBTM_STATUS BTM_BleExtendedScan(BOOLEAN enable, UINT16 duration, UINT16 period) if ((err = btsnd_hcic_ble_ext_scan_enable(enable, extend_adv_cb.scan_duplicate, duration, period)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE ES En=%d: cmd err=0x%x", enable, err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } end: @@ -1053,22 +1098,28 @@ end: return status; } +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) void BTM_BleSetPreferExtenedConnParams (BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *params) { tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bd_addr); + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; if (p_dev_rec) { if (params) { memcpy(&p_dev_rec->ext_conn_params, params, sizeof(tBTM_EXT_CONN_PARAMS)); } else { - BTM_TRACE_ERROR("Invalid Extand connection parameters"); + BTM_TRACE_ERROR("Invalid Extended connection parameters"); + status = BTM_ILLEGAL_VALUE; } } else { - BTM_TRACE_ERROR("Unknown Device, setting rejected"); + BTM_TRACE_ERROR("Unknown Device, setting rejected"); + status = BTM_UNKNOWN_ADDR; } - return; + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PREFER_EXT_CONN_PARAMS_SET_COMPLETE_EVT, &cb_params); } void btm_ble_extended_init(void) @@ -1081,6 +1132,7 @@ void btm_ble_extended_cleanup(void) } +#if (BLE_50_EXTEND_ADV_EN == TRUE) static tBTM_STATUS btm_ble_ext_adv_params_validate(tBTM_BLE_GAP_EXT_ADV_PARAMS *params) { if (!params) { @@ -1157,6 +1209,7 @@ static tBTM_STATUS btm_ble_ext_adv_set_data_validate(UINT8 instance, UINT16 len, return BTM_SUCCESS; } +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) void btm_ble_update_phy_evt(tBTM_BLE_UPDATE_PHY *params) { @@ -1184,11 +1237,14 @@ void btm_ble_update_phy_evt(tBTM_BLE_UPDATE_PHY *params) return; } +#if (BLE_50_EXTEND_SCAN_EN == TRUE) void btm_ble_scan_timeout_evt(void) { BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SCAN_TIMEOUT_EVT, NULL); } +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params) { tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; @@ -1199,7 +1255,7 @@ void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params) } // adv terminated due to connection, save the adv handle and connection handle - if(params->completed_event == 0x00) { + if(params->status == 0x00) { adv_record[params->adv_handle].ter_con_handle = params->conn_handle; } else { adv_record[params->adv_handle].ter_con_handle = INVALID_VALUE; @@ -1214,7 +1270,9 @@ void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params) return; } +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) +#if (BLE_50_EXTEND_SCAN_EN == TRUE) void btm_ble_ext_adv_report_evt(tBTM_BLE_EXT_ADV_REPORT *params) { tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; @@ -1232,7 +1290,9 @@ void btm_ble_ext_adv_report_evt(tBTM_BLE_EXT_ADV_REPORT *params) return; } +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) void btm_ble_scan_req_received_evt(tBTM_BLE_SCAN_REQ_RECEIVED *params) { tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; @@ -1249,7 +1309,7 @@ void btm_ble_scan_req_received_evt(tBTM_BLE_SCAN_REQ_RECEIVED *params) return; } - +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) void btm_ble_channel_select_algorithm_evt(tBTM_BLE_CHANNEL_SEL_ALG *params) { tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; @@ -1267,6 +1327,7 @@ void btm_ble_channel_select_algorithm_evt(tBTM_BLE_CHANNEL_SEL_ALG *params) return; } +#if (BLE_50_EXTEND_SYNC_EN == TRUE) void btm_ble_periodic_adv_report_evt(tBTM_PERIOD_ADV_REPORT *params) { tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; @@ -1320,7 +1381,9 @@ void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *par return; } +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) uint8_t btm_ble_ext_adv_active_count(void) { uint8_t count = 0; @@ -1333,6 +1396,7 @@ uint8_t btm_ble_ext_adv_active_count(void) return count; } +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) @@ -1378,7 +1442,7 @@ void BTM_BlePeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable) if ((err = btsnd_hcic_ble_set_periodic_adv_recv_enable(sync_handle, enable)) != HCI_SUCCESS) { BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } cb_params.status = status; @@ -1437,7 +1501,7 @@ void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 sk tHCI_STATUS err = HCI_SUCCESS; if ((err = btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(mode, skip, sync_timeout, cte_type)) != HCI_SUCCESS) { BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } cb_params.set_past_params.status = status; @@ -1476,3 +1540,192 @@ void btm_ble_periodic_adv_sync_trans_recv_evt(tBTM_BLE_PERIOD_ADV_SYNC_TRANS_REC BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT, &cb_params); } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +void BTM_BleEnhReadTransPowerLevel(uint16_t conn_handle, uint8_t phy) +{ + btsnd_hcic_ble_enh_read_trans_power_level(conn_handle, phy); +} + +void BTM_BleReadRemoteTransPwrLevel(uint16_t conn_handle, uint8_t phy) +{ + btsnd_hcic_ble_read_remote_trans_power_level(conn_handle, phy); +} + +void BTM_BleSetPathLossRptParams(uint16_t conn_handle, uint8_t high_threshold, uint8_t high_hysteresis, + uint8_t low_threshold, uint8_t low_hysteresis, uint16_t min_time_spent) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_path_loss_rpt_params(conn_handle, high_threshold, high_hysteresis, low_threshold, low_hysteresis, min_time_spent)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); + status = BTM_HCI_ERROR | err; + } + + cb_params.path_loss_rpting_params.status = status; + cb_params.path_loss_rpting_params.conn_handle = conn_handle; + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PATH_LOSS_REPORTING_PARAMS_EVT, &cb_params); +} + +void BTM_BleSetPathLossRptEnable(uint16_t conn_handle, uint8_t enable) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_path_loss_rpt_enable(conn_handle, enable)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); + status = BTM_HCI_ERROR | err; + } + + cb_params.path_loss_rpting_enable.status = status; + cb_params.path_loss_rpting_enable.conn_handle = conn_handle; + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PATH_LOSS_REPORTING_ENABLE_EVT, &cb_params); +} + +void BTM_BleSetTransPwrRptEnable(uint16_t conn_handle, uint8_t local_enable, uint8_t remote_enable) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_trans_pwr_rpt_enable(conn_handle, local_enable, remote_enable)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); + status = BTM_HCI_ERROR | err; + } + + cb_params.trans_pwr_rpting_enable.status = status; + cb_params.trans_pwr_rpting_enable.conn_handle = conn_handle; + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_TRANS_POWER_REPORTING_ENABLE_EVT, &cb_params); +} + +void btm_enh_read_trans_pwr_level_cmpl_evt(uint8_t *p) +{ + uint8_t hci_status; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + STREAM_TO_UINT8(hci_status, p); + STREAM_TO_UINT16(cb_params.enh_trans_pwr_level_cmpl.conn_handle, p); + STREAM_TO_UINT8(cb_params.enh_trans_pwr_level_cmpl.phy, p); + STREAM_TO_UINT8(cb_params.enh_trans_pwr_level_cmpl.cur_tx_pwr_level, p); + STREAM_TO_UINT8(cb_params.enh_trans_pwr_level_cmpl.max_tx_pwr_level, p); + + if(hci_status != HCI_SUCCESS) { + hci_status = BTM_HCI_ERROR | hci_status; + BTM_TRACE_ERROR("%s error status %d", __func__, hci_status); + } + cb_params.enh_trans_pwr_level_cmpl.status = hci_status; + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_ENH_READ_TRANS_POWER_LEVEL_EVT, &cb_params); +} + +void btm_read_remote_trans_pwr_level_cmpl(UINT8 status) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if (status != HCI_SUCCESS) { + status = (status | BTM_HCI_ERROR); + } + + cb_params.remote_pwr_level_cmpl.status = status; + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_READ_REMOTE_TRANS_POWER_LEVEL_EVT, &cb_params); +} + +void btm_ble_path_loss_threshold_evt(tBTM_BLE_PATH_LOSS_THRESHOLD_EVT *params) +{ + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + // If the user has register the callback function, should callback it to the application. + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PATH_LOSS_THRESHOLD_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)params); +} + +void btm_ble_transmit_power_report_evt(tBTM_BLE_TRANS_POWER_REPORT_EVT *params) +{ + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + if (params->status != HCI_SUCCESS) { + params->status = (params->status | BTM_HCI_ERROR); + } + + // If the user has register the callback function, should callback it to the application. + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_TRANMIT_POWER_REPORTING_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)params); +} + +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + +#if (BLE_FEAT_CONN_SUBRATING == TRUE) +void BTM_BleSetDefaultSubrate(UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, UINT16 continuation_number, UINT16 supervision_timeout) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_default_subrate(subrate_min, subrate_max, max_latency, continuation_number, supervision_timeout)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); + status = BTM_HCI_ERROR | err; + } + + cb_params.status = status; + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_DEFAULT_SUBRATE_EVT, &cb_params); +} + +void BTM_BleSubrateRequest(UINT16 conn_handle, UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, UINT16 continuation_number, UINT16 supervision_timeout) +{ + btsnd_hcic_ble_subrate_request(conn_handle, subrate_min, subrate_max, max_latency, continuation_number, supervision_timeout); +} + +void btm_subrate_req_cmd_status(UINT8 status) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if (status != HCI_SUCCESS) { + status = (status | BTM_HCI_ERROR); + } + cb_params.status = status; + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SUBRATE_REQUEST_EVT, &cb_params); +} + +void btm_ble_subrate_change_evt(tBTM_BLE_SUBRATE_CHANGE_EVT *params) +{ + if (params->status != HCI_SUCCESS) { + params->status = (params->status | BTM_HCI_ERROR); + } + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SUBRATE_CHANGE_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)params); +} +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) +tBTM_STATUS BTM_BleSetHostFeature(uint16_t bit_num, uint8_t bit_val) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + BTM_TRACE_DEBUG("BTM_BleSetHostFeature bit_num %d bit_value %d\n", bit_num, bit_val); + + if ((err = btsnd_hcic_ble_set_host_feature(bit_num, bit_val)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("set host feature, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_HOST_FEATURE_EVT, &cb_params); + + return status; +} +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_addr.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_addr.c index d7ed2095..60548a76 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_ble_addr.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_addr.c @@ -384,6 +384,10 @@ static BOOLEAN btm_ble_match_random_bda(tBTM_SEC_DEV_REC *p_dev_rec) void btm_ble_resolve_random_addr(BD_ADDR random_bda, tBTM_BLE_RESOLVE_CBACK *p_cback, void *p) { #if (SMP_INCLUDED == TRUE) + if (btm_cb.addr_res_en == FALSE) { + return; + } + tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; list_node_t *p_node = NULL; tBTM_SEC_DEV_REC *p_dev_rec = NULL; @@ -458,6 +462,10 @@ tBTM_SEC_DEV_REC *btm_find_dev_by_identity_addr(BD_ADDR bd_addr, UINT8 addr_type BOOLEAN btm_identity_addr_to_random_pseudo(BD_ADDR bd_addr, UINT8 *p_addr_type, BOOLEAN refresh) { #if BLE_PRIVACY_SPT == TRUE + if (btm_cb.addr_res_en == FALSE) { + return TRUE; + } + tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_identity_addr(bd_addr, *p_addr_type); BTM_TRACE_EVENT ("%s", __func__); @@ -491,6 +499,10 @@ BOOLEAN btm_identity_addr_to_random_pseudo(BD_ADDR bd_addr, UINT8 *p_addr_type, BOOLEAN btm_random_pseudo_to_identity_addr(BD_ADDR random_pseudo, UINT8 *p_static_addr_type) { #if BLE_PRIVACY_SPT == TRUE + if (btm_cb.addr_res_en == FALSE) { + return TRUE; + } + tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (random_pseudo); if (p_dev_rec != NULL) { diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c index c0ae0aaa..9da09143 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c @@ -22,6 +22,7 @@ #include "common/bt_target.h" #if (BLE_INCLUDED == TRUE) +#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE #include "stack/bt_types.h" #include "stack/hcimsgs.h" #include "stack/btu.h" @@ -445,11 +446,11 @@ BOOLEAN btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR *p_bd_addr, UINT8 filte ** ** Function btm_ble_update_pf_local_name ** -** Description this function update(add,delete or clear) the adv lcoal name filtering condition. +** Description this function update(add,delete or clear) the adv local name filtering condition. ** ** -** Returns BTM_SUCCESS if sucessful, -** BTM_ILLEGAL_VALUE if paramter is not valid. +** Returns BTM_SUCCESS if successful, +** BTM_ILLEGAL_VALUE if parameter is not valid. ** *******************************************************************************/ tBTM_STATUS btm_ble_update_pf_local_name(tBTM_BLE_SCAN_COND_OP action, @@ -506,8 +507,8 @@ tBTM_STATUS btm_ble_update_pf_local_name(tBTM_BLE_SCAN_COND_OP action, ** Description this function update(add/remove) service data change filter. ** ** -** Returns BTM_SUCCESS if sucessful, -** BTM_ILLEGAL_VALUE if paramter is not valid. +** Returns BTM_SUCCESS if successful, +** BTM_ILLEGAL_VALUE if parameter is not valid. ** *******************************************************************************/ tBTM_STATUS btm_ble_update_srvc_data_change(tBTM_BLE_SCAN_COND_OP action, @@ -534,8 +535,8 @@ tBTM_STATUS btm_ble_update_srvc_data_change(tBTM_BLE_SCAN_COND_OP action, ** data filtering condition. ** ** -** Returns BTM_SUCCESS if sucessful, -** BTM_ILLEGAL_VALUE if paramter is not valid. +** Returns BTM_SUCCESS if successful, +** BTM_ILLEGAL_VALUE if parameter is not valid. ** *******************************************************************************/ tBTM_STATUS btm_ble_update_pf_manu_data(tBTM_BLE_SCAN_COND_OP action, @@ -708,8 +709,8 @@ UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action, ** Description this function update(add,delete or clear) the address filter of adv. ** ** -** Returns BTM_SUCCESS if sucessful, -** BTM_ILLEGAL_VALUE if paramter is not valid. +** Returns BTM_SUCCESS if successful, +** BTM_ILLEGAL_VALUE if parameter is not valid. ** *******************************************************************************/ tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action, @@ -757,8 +758,8 @@ tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action, ** Description this function update(add,delete or clear) service UUID filter. ** ** -** Returns BTM_SUCCESS if sucessful, -** BTM_ILLEGAL_VALUE if paramter is not valid. +** Returns BTM_SUCCESS if successful, +** BTM_ILLEGAL_VALUE if parameter is not valid. ** *******************************************************************************/ tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action, @@ -872,7 +873,7 @@ tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action, memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); } } else { - BTM_TRACE_ERROR("UUID filter udpating failed"); + BTM_TRACE_ERROR("UUID filter updating failed"); } return st; @@ -886,8 +887,8 @@ tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action, ** Description clear all adv payload filter by de-select all the adv pf feature bits ** ** -** Returns BTM_SUCCESS if sucessful, -** BTM_ILLEGAL_VALUE if paramter is not valid. +** Returns BTM_SUCCESS if successful, +** BTM_ILLEGAL_VALUE if parameter is not valid. ** *******************************************************************************/ tBTM_STATUS btm_ble_clear_scan_pf_filter(tBTM_BLE_SCAN_COND_OP action, @@ -1303,4 +1304,5 @@ void btm_ble_adv_filter_cleanup(void) #endif } +#endif // #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE #endif diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c index 5b0fcd8f..b4b58643 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c @@ -29,15 +29,22 @@ #include "stack/hcimsgs.h" #if (BLE_INCLUDED == TRUE) +#if (BLE_HOST_BATCH_SCAN_EN == TRUE) #if BTM_DYNAMIC_MEMORY == FALSE tBTM_BLE_BATCH_SCAN_CB ble_batchscan_cb; +#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) tBTM_BLE_ADV_TRACK_CB ble_advtrack_cb; +#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #else tBTM_BLE_BATCH_SCAN_CB *ble_batchscan_cb_ptr; +#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) tBTM_BLE_ADV_TRACK_CB *ble_advtrack_cb_ptr; +#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #define ble_batchscan_cb (*ble_batchscan_cb_ptr) +#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #define ble_advtrack_cb (*ble_advtrack_cb_ptr) +#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #endif /* length of each batch scan command */ @@ -66,10 +73,11 @@ void btm_ble_batchscan_cleanup(void); *******************************************************************************/ void btm_ble_batchscan_filter_track_adv_vse_cback(UINT8 len, UINT8 *p) { +#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) tBTM_BLE_TRACK_ADV_DATA adv_data; - - UINT8 sub_event = 0; tBTM_BLE_VSC_CB cmn_ble_vsc_cb; +#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) + UINT8 sub_event = 0; STREAM_TO_UINT8(sub_event, p); BTM_TRACE_EVENT("btm_ble_batchscan_filter_track_adv_vse_cback called with event:%x", sub_event); @@ -78,7 +86,7 @@ void btm_ble_batchscan_filter_track_adv_vse_cback(UINT8 len, UINT8 *p) ble_batchscan_cb.p_thres_cback(ble_batchscan_cb.ref_value); return; } - +#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) if (HCI_VSE_SUBCODE_BLE_TRACKING_SUB_EVT == sub_event && NULL != ble_advtrack_cb.p_track_cback) { if (len < 10) { return; @@ -125,6 +133,7 @@ void btm_ble_batchscan_filter_track_adv_vse_cback(UINT8 len, UINT8 *p) ble_advtrack_cb.p_track_cback(&adv_data); return; } +#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) } /******************************************************************************* @@ -598,6 +607,7 @@ tBTM_STATUS btm_ble_enable_disable_batchscan(BOOLEAN should_enable) return status; } +#if (BLE_HOST_SETUP_STORAGE_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleSetStorageConfig @@ -676,7 +686,7 @@ tBTM_STATUS BTM_BleSetStorageConfig(UINT8 batch_scan_full_max, UINT8 batch_scan_ return status; } - +#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) /******************************************************************************* ** @@ -796,6 +806,7 @@ tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value) return status; } +#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleReadScanReports @@ -854,8 +865,9 @@ tBTM_STATUS BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, } return status; } +#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) - +#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleTrackAdvertiser @@ -888,6 +900,7 @@ tBTM_STATUS BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK *p_track_cback, ble_advtrack_cb.ref_value = ref_value; return BTM_CMD_STARTED; } +#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) /******************************************************************************* ** @@ -904,7 +917,9 @@ void btm_ble_batchscan_init(void) { #if BTM_DYNAMIC_MEMORY == TRUE ble_batchscan_cb_ptr = (tBTM_BLE_BATCH_SCAN_CB *)osi_malloc(sizeof(tBTM_BLE_BATCH_SCAN_CB)); +#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) ble_advtrack_cb_ptr = (tBTM_BLE_ADV_TRACK_CB *)osi_malloc(sizeof(tBTM_BLE_ADV_TRACK_CB)); +#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) if (ble_batchscan_cb_ptr == NULL || ble_advtrack_cb_ptr == NULL) { BTM_TRACE_ERROR("%s malloc failed", __func__); return; @@ -912,7 +927,9 @@ void btm_ble_batchscan_init(void) #endif BTM_TRACE_EVENT (" btm_ble_batchscan_init"); memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB)); +#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) memset(&ble_advtrack_cb, 0, sizeof(tBTM_BLE_ADV_TRACK_CB)); +#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) BTM_RegisterForVSEvents(btm_ble_batchscan_filter_track_adv_vse_cback, TRUE); } @@ -940,14 +957,21 @@ void btm_ble_batchscan_cleanup(void) } memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB)); +#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) memset(&ble_advtrack_cb, 0, sizeof(tBTM_BLE_ADV_TRACK_CB)); +#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #if BTM_DYNAMIC_MEMORY == TRUE osi_free(ble_batchscan_cb_ptr); - osi_free(ble_advtrack_cb_ptr); ble_batchscan_cb_ptr = NULL; +#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) + osi_free(ble_advtrack_cb_ptr); ble_advtrack_cb_ptr = NULL; +#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) + #endif } +#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) + #endif diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c index 4cb282b7..bf9b1adb 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c @@ -201,7 +201,12 @@ BOOLEAN btm_add_dev_to_controller (BOOLEAN to_add, BD_ADDR bd_addr, tBLE_ADDR_TY /* Controller do not support resolvable address now, only support public address and static random address */ BOOLEAN started = FALSE; - if(wl_addr_type > BLE_ADDR_RANDOM) { +#if (BLE_50_FEATURE_SUPPORT == TRUE) + if (wl_addr_type > BLE_ADDR_RANDOM && wl_addr_type != BLE_ADDR_ANONYMOUS) +#else + if (wl_addr_type > BLE_ADDR_RANDOM) +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + { BTM_TRACE_ERROR("wl_addr_type is error\n"); return started; } @@ -278,7 +283,12 @@ void btm_enq_wl_dev_operation(BOOLEAN to_add, BD_ADDR bd_addr, tBLE_ADDR_TYPE ad *******************************************************************************/ BOOLEAN btm_update_dev_to_white_list(BOOLEAN to_add, BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type, tBTM_UPDATE_WHITELIST_CBACK *update_wl_cb) { - if(addr_type > BLE_ADDR_RANDOM) { +#if (BLE_50_FEATURE_SUPPORT == TRUE) + if (addr_type > BLE_ADDR_RANDOM && addr_type != BLE_ADDR_ANONYMOUS) +#else + if (addr_type > BLE_ADDR_RANDOM) +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + { BTM_TRACE_ERROR("%s address type is error, unable to add device", __func__); if (update_wl_cb){ update_wl_cb(HCI_ERR_ILLEGAL_PARAMETER_FMT,to_add); @@ -423,6 +433,23 @@ void btm_ble_white_list_init(UINT8 white_list_size) btm_cb.ble_ctr_cb.white_list_avail_size = white_list_size; } +#if (BLE_50_EXTEND_SYNC_EN == TRUE) +/******************************************************************************* +** +** Function btm_ble_periodic_adv_list_init +** +** Description Initialize the periodic advertiser list size. +** +** Parameters periodic_adv_size: The size of the periodic advertiser list to be initialized. +** +*******************************************************************************/ +void btm_ble_periodic_adv_list_init(UINT8 periodic_adv_size) +{ + BTM_TRACE_DEBUG("%s white_list_size = %d", __func__, periodic_adv_size); + btm_cb.ble_ctr_cb.periodic_adv_list_size = periodic_adv_size; +} +#endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE) + /******************************************************************************* ** ** Function btm_ble_add_2_white_list_complete @@ -648,6 +675,7 @@ void btm_ble_initiate_select_conn(BD_ADDR bda) BTM_TRACE_ERROR("btm_ble_initiate_select_conn failed"); } } +#if (tGATT_BG_CONN_DEV == TRUE) /******************************************************************************* ** ** Function btm_ble_suspend_bg_conn @@ -672,6 +700,8 @@ BOOLEAN btm_ble_suspend_bg_conn(void) return FALSE; } +#endif // #if (tGATT_BG_CONN_DEV == TRUE) + /******************************************************************************* ** ** Function btm_suspend_wl_activity @@ -689,10 +719,11 @@ static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state) if (wl_state & BTM_BLE_WL_SCAN) { btm_ble_start_select_conn(FALSE, NULL); } +#if (BLE_42_ADV_EN == TRUE) if (wl_state & BTM_BLE_WL_ADV) { btm_ble_stop_adv(); } - +#endif // #if (BLE_42_ADV_EN == TRUE) } /******************************************************************************* ** @@ -705,9 +736,13 @@ static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state) *******************************************************************************/ void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state) { +#if (tGATT_BG_CONN_DEV == TRUE) btm_ble_resume_bg_conn(); +#endif // #if (tGATT_BG_CONN_DEV == TRUE) if (wl_state & BTM_BLE_WL_ADV) { +#if (BLE_42_ADV_EN == TRUE) btm_ble_start_adv(); +#endif // #if (BLE_42_ADV_EN == TRUE) } } @@ -724,12 +759,13 @@ void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state) static void btm_wl_update_to_controller(void) { /* whitelist will be added in the btm_ble_resume_bg_conn(), we do not - support background connection now, so we nedd to use btm_execute_wl_dev_operation + support background connection now, so we need to use btm_execute_wl_dev_operation to add whitelist directly ,if we support background connection in the future, please delete btm_execute_wl_dev_operation(). */ btm_execute_wl_dev_operation(); } +#if (tGATT_BG_CONN_DEV == TRUE) /******************************************************************************* ** ** Function btm_ble_resume_bg_conn @@ -759,6 +795,8 @@ BOOLEAN btm_ble_resume_bg_conn(void) return ret; } +#endif // #if (tGATT_BG_CONN_DEV == TRUE) + /******************************************************************************* ** ** Function btm_ble_get_conn_st diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c index dd23d3e9..4b68fe80 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c @@ -20,6 +20,7 @@ #include "common/bt_target.h" #if (BLE_INCLUDED == TRUE) +#if (BLE_HOST_ENERGY_INFO_EN == TRUE) #include "stack/bt_types.h" #include "stack/hcimsgs.h" #include "stack/btu.h" @@ -104,5 +105,6 @@ tBTM_STATUS BTM_BleGetEnergyInfo(tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback) return status; } +#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) #endif diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_cte.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_cte.c new file mode 100644 index 00000000..a79932de --- /dev/null +++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_cte.c @@ -0,0 +1,237 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "btm_int.h" +#include "stack/hcimsgs.h" +#include "osi/allocator.h" +#include "device/controller.h" +#include <string.h> +#include "l2c_int.h" + +tBTM_BLE_CTE_CBACK ble_cte_cb; + +extern void btm_ble_inter_set(bool extble_inter); + +void BTM_BleCteRegisterCallback(tBTM_BLE_CTE_CBACK cb) +{ + if (cb) { + ble_cte_cb = cb; + } else { + BTM_TRACE_ERROR("%s, register fail, the cb function is NULL.", __func__); + } +} + +void BTM_CteBleCallbackTrigger(tBTM_BLE_5_GAP_EVENT event, tBTM_BLE_CTE_CB_PARAMS *params) +{ + BTM_TRACE_DEBUG("%s event %x", __func__, event); + + if(params && params->status == BTM_SUCCESS) { + btm_ble_inter_set(true); + } + if (ble_cte_cb) { + ble_cte_cb(event, params); + } +} +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +tBTM_STATUS BTM_BleSetCteTransParams(uint8_t adv_handle, uint8_t cte_len, uint8_t cte_type, uint8_t cte_count, uint8_t switching_pattern_len, uint8_t *antenna_ids) +{ + + + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_connless_cte_trans_params(adv_handle, cte_len, cte_type, cte_count, switching_pattern_len, antenna_ids)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set trans params, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_trans_params_cmpl.status = status; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_TRANS_PARAMS_EVT, &cb_params); + + return status; +} + +tBTM_STATUS BTM_BleCteSetConnectionlessTransEnable(uint8_t adv_handle, uint8_t cte_en) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_connless_cte_enable(adv_handle, cte_en)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set trans enable, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_trans_en_cmpl.status = status; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_TRANS_ENABLE_EVT, &cb_params); + + return status; +} + +tBTM_STATUS BTM_BleCteSetConnectionlessIqSamplingEnable(uint16_t sync_handle, uint8_t sampling_en, uint8_t slot_dur, + uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *ant_ids) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_connless_iq_sampling_enable(sync_handle, sampling_en, slot_dur, max_sampled_ctes, switching_pattern_len, ant_ids)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set trans enable, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_iq_samp_en_cmpl.status = status; + cb_params.cte_iq_samp_en_cmpl.sync_handle = sync_handle; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT, &cb_params); + + return status; +} +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +tBTM_STATUS BTM_BleCteSetConnectionReceiveParams(uint16_t conn_handle, uint8_t sampling_en, uint8_t slot_dur, + uint8_t switching_pattern_len, uint8_t *ant_ids) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_conn_cte_receive_params(conn_handle, sampling_en, slot_dur, switching_pattern_len, ant_ids)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set conn recv params, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_recv_params_cmpl.status = status; + cb_params.cte_recv_params_cmpl.conn_handle = conn_handle; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_CONN_RECV_PARAMS_EVT, &cb_params); + + return status; +} + +tBTM_STATUS BTM_BleCteSetConnectionTransParams(uint16_t conn_handle, uint8_t cte_types, uint8_t switching_pattern_len, uint8_t *ant_ids) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_conn_cte_trans_params(conn_handle, cte_types, switching_pattern_len, ant_ids)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set conn trans params, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_conn_trans_params_cmpl.status = status; + cb_params.cte_conn_trans_params_cmpl.conn_handle = conn_handle; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_CONN_TRANS_PARAMS_EVT, &cb_params); + + return status; +} + +tBTM_STATUS BTM_BleCteSetConnectionRequestEnable(uint16_t conn_handle, uint8_t enable, uint16_t cte_req_int, + uint8_t req_cte_len, uint8_t req_cte_type) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_conn_cte_req_enable(conn_handle, enable, cte_req_int, req_cte_len, req_cte_type)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set conn req en, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_conn_req_en_cmpl.status = status; + cb_params.cte_conn_req_en_cmpl.conn_handle = conn_handle; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_CONN_REQ_ENABLE_EVT, &cb_params); + + return status; +} + +tBTM_STATUS BTM_BleCteSetConnectionRspEnable(uint16_t conn_handle, uint8_t enable) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_conn_cte_rsp_enable(conn_handle, enable)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set conn rsp en, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_conn_rsp_en_cmpl.status = status; + cb_params.cte_conn_rsp_en_cmpl.conn_handle = conn_handle; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_CONN_RSP_ENABLE_EVT, &cb_params); + + return status; +} +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +tBTM_STATUS BTM_BleCteReadAntInfor(void) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + + if ((err = btsnd_hcic_ble_read_antenna_info()) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte read ant information, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + return status; +} + +void btm_ble_cte_read_ant_infor_complete(UINT8 *p) +{ + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.status, p); + STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.supported_switching_sampling_rates, p); + STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.num_ant, p); + STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.max_switching_pattern_len, p); + STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.max_cte_len, p); + + if (cb_params.cte_read_ant_infor_cmpl.status != HCI_SUCCESS) { + cb_params.cte_read_ant_infor_cmpl.status = (BTM_HCI_ERROR | cb_params.cte_read_ant_infor_cmpl.status); + } + + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_READ_ANT_INFOR_EVT, &cb_params); +} + +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +void btm_ble_connless_iq_report_evt(tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT *params) +{ + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT, (tBTM_BLE_CTE_CB_PARAMS *)params); +} +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +void btm_ble_conn_iq_report_evt(tBTM_BLE_CTE_CONN_IQ_REPORT_EVT *params) +{ + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_CONN_IQ_REPORT_EVT, (tBTM_BLE_CTE_CB_PARAMS *)params); +} + +void btm_ble_cte_req_failed_evt(tBTM_BLE_CTE_REQ_FAILED_EVT *params) +{ + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + if (params->status != HCI_SUCCESS) { + params->status = (params->status | BTM_HCI_ERROR); + } + + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_REQUEST_FAILED_EVT, (tBTM_BLE_CTE_CB_PARAMS *)params); +} +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_gap.c index df24fa08..f3886643 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -71,20 +71,28 @@ static tBTM_BLE_CTRL_FEATURES_CBACK *p_ctrl_le_feature_rd_cmpl_cback = NULL; #endif tBTM_CallbackFunc conn_callback_func; +// BLE vendor HCI event callback +#if (BLE_VENDOR_HCI_EN == TRUE) +static tBTM_BLE_VENDOR_HCI_EVT_CBACK *ble_vs_evt_callback = NULL; +#endif // #if (BLE_VENDOR_HCI_EN == TRUE) /******************************************************************************* ** Local functions *******************************************************************************/ static void btm_ble_update_adv_flag(UINT8 flag); static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p); + UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst, tBTM_BLE_ADV_DATA *p_data); + static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb, BD_ADDR_PTR p_peer_addr_ptr, tBLE_ADDR_TYPE *p_peer_addr_type, tBLE_ADDR_TYPE *p_own_addr_type); static void btm_ble_stop_observe(void); static void btm_ble_stop_discover(void); +#if (BLE_42_SCAN_EN == TRUE) static void btm_adv_pkt_handler(void *arg); +#endif // #if (BLE_42_SCAN_EN == TRUE) uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK *cb); #define BTM_BLE_INQ_RESULT 0x01 @@ -246,56 +254,77 @@ const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = { /* check LE combo state supported */ #define BTM_LE_STATES_SUPPORTED(x, y, z) ((x)[(z)] & (y)) +#if (BLE_42_ADV_EN == TRUE) static osi_mutex_t adv_enable_lock; static osi_mutex_t adv_data_lock; static osi_mutex_t adv_param_lock; -static osi_mutex_t scan_enable_lock; -static osi_mutex_t scan_param_lock; osi_sem_t adv_enable_sem; osi_sem_t adv_data_sem; osi_sem_t adv_param_sem; -osi_sem_t scan_enable_sem; -osi_sem_t scan_param_sem; uint8_t adv_enable_status = 0; uint8_t adv_data_status = 0; uint8_t adv_param_status = 0; +#endif // #if (BLE_42_ADV_EN == TRUE) + +#if (BLE_42_SCAN_EN == TRUE) +static osi_mutex_t scan_enable_lock; +static osi_mutex_t scan_param_lock; +osi_sem_t scan_enable_sem; +osi_sem_t scan_param_sem; uint8_t scan_enable_status = 0; uint8_t scan_param_status = 0; +#endif // #if (BLE_42_SCAN_EN == TRUE) void btm_ble_lock_init(void) { +#if (BLE_42_ADV_EN == TRUE) osi_mutex_new(&adv_enable_lock); osi_mutex_new(&adv_data_lock); osi_mutex_new(&adv_param_lock); +#endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_42_SCAN_EN == TRUE) osi_mutex_new(&scan_enable_lock); osi_mutex_new(&scan_param_lock); +#endif // #if (BLE_42_SCAN_EN == TRUE) } void btm_ble_lock_free(void) { +#if (BLE_42_ADV_EN == TRUE) osi_mutex_free(&adv_enable_lock); osi_mutex_free(&adv_data_lock); osi_mutex_free(&adv_param_lock); +#endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_42_SCAN_EN == TRUE) osi_mutex_free(&scan_enable_lock); osi_mutex_free(&scan_param_lock); +#endif // #if (BLE_42_SCAN_EN == TRUE) } void btm_ble_sem_init(void) { +#if (BLE_42_ADV_EN == TRUE) osi_sem_new(&adv_enable_sem, 1, 0); osi_sem_new(&adv_data_sem, 1, 0); osi_sem_new(&adv_param_sem, 1, 0); +#endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_42_SCAN_EN == TRUE) osi_sem_new(&scan_enable_sem, 1, 0); osi_sem_new(&scan_param_sem, 1, 0); +#endif // #if (BLE_42_SCAN_EN == TRUE) } void btm_ble_sem_free(void) { +#if (BLE_42_ADV_EN == TRUE) osi_sem_free(&adv_enable_sem); osi_sem_free(&adv_data_sem); osi_sem_free(&adv_param_sem); +#endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_42_SCAN_EN == TRUE) osi_sem_free(&scan_enable_sem); osi_sem_free(&scan_param_sem); +#endif // #if (BLE_42_SCAN_EN == TRUE) } /******************************************************************************* @@ -326,6 +355,13 @@ void BTM_BleRegiseterPktLengthChangeCallback(tBTM_SET_PKT_DATA_LENGTH_CBACK *ptk conn_callback_func.set_pkt_data_length_cb = ptk_len_chane_cb; } +#if (BLE_VENDOR_HCI_EN == TRUE) +void BTM_BleRegisterVendorHciEventCallback(tBTM_BLE_VENDOR_HCI_EVT_CBACK *vendor_hci_evt_cb) +{ + ble_vs_evt_callback = vendor_hci_evt_cb; +} +#endif // #if (BLE_VENDOR_HCI_EN == TRUE) + /******************************************************************************* ** ** Function BTM_BleUpdateAdvWhitelist @@ -380,14 +416,22 @@ void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy) if (p_cb->afp != adv_policy) { p_cb->afp = adv_policy; +#if (BLE_42_ADV_EN == TRUE) /* if adv active, stop and restart */ btm_ble_stop_adv (); +#endif // #if (BLE_42_ADV_EN == TRUE) if (p_cb->connectable_mode & BTM_BLE_CONNECTABLE) { p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &p_cb->adv_addr_type); } + uint8_t null_addr[BD_ADDR_LEN] = {0}; + if ((p_cb->evt_type == 0x01 || p_cb->evt_type == 0x04) && memcmp(p_addr_ptr, null_addr, BD_ADDR_LEN) == 0) { + /* directed advertising */ + return; + } + btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_SLOW_INT), (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : @@ -400,7 +444,9 @@ void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy) p_cb->afp); if (adv_mode == BTM_BLE_ADV_ENABLE) { +#if (BLE_42_ADV_EN == TRUE) btm_ble_start_adv (); +#endif // #if (BLE_42_ADV_EN == TRUE) } } @@ -506,8 +552,9 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT32 duration, btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, BTM_BLE_DEFAULT_SFP); } - +#if (BLE_42_SCAN_EN == TRUE) status = btm_ble_start_scan(); +#endif // #if (BLE_42_SCAN_EN == TRUE) } if (status == BTM_CMD_STARTED) { @@ -529,6 +576,7 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT32 duration, } +#if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleScan @@ -606,7 +654,9 @@ tBTM_STATUS BTM_BleScan(BOOLEAN start, UINT32 duration, return status; } +#endif // #if (BLE_42_SCAN_EN == TRUE) +#if (BLE_42_ADV_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleBroadcast @@ -665,7 +715,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s } return status; } - +#endif // #if (BLE_42_ADV_EN == TRUE) #if BLE_VND_INCLUDED == TRUE /******************************************************************************* ** @@ -717,11 +767,11 @@ static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_ __func__, status, btm_cb.cmn_ble_vsc_cb.max_irk_list_sz, btm_cb.cmn_ble_vsc_cb.adv_inst_max, btm_cb.cmn_ble_vsc_cb.rpa_offloading, btm_cb.cmn_ble_vsc_cb.energy_support, btm_cb.cmn_ble_vsc_cb.extended_scan_support); - +#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) if (BTM_BleMaxMultiAdvInstanceCount() > 0) { btm_ble_multi_adv_init(); } - +#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) if (btm_cb.cmn_ble_vsc_cb.max_filter > 0) { btm_ble_adv_filter_init(); } @@ -899,9 +949,11 @@ BOOLEAN BTM_BleConfigPrivacy(BOOLEAN privacy_mode, tBTM_SET_LOCAL_PRIVACY_CBACK btm_gen_resolvable_private_addr((void *)btm_gen_resolve_paddr_low); #endif +#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) if (BTM_BleMaxMultiAdvInstanceCount() > 0) { btm_ble_multi_adv_enb_privacy(privacy_mode); } +#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) /* 4.2 controller only allow privacy 1.2 or mixed mode, resolvable private address in controller */ if (controller_get_interface()->supports_ble_privacy()) { @@ -1139,6 +1191,7 @@ void BTM_BleConfigConnParams(uint16_t int_min, uint16_t int_max, uint16_t latenc #endif } +#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleMaxMultiAdvInstanceCount @@ -1153,6 +1206,7 @@ extern UINT8 BTM_BleMaxMultiAdvInstanceCount(void) return btm_cb.cmn_ble_vsc_cb.adv_inst_max < BTM_BLE_MULTI_ADV_MAX ? btm_cb.cmn_ble_vsc_cb.adv_inst_max : BTM_BLE_MULTI_ADV_MAX; } +#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) #if BLE_PRIVACY_SPT == TRUE /******************************************************************************* @@ -1291,7 +1345,9 @@ void BTM_BleClearBgConnDev(void) { btm_ble_start_auto_conn(FALSE); btm_ble_clear_white_list(NULL); +#if (tGATT_BG_CONN_DEV == TRUE) gatt_reset_bgdev_list(); +#endif // #if (tGATT_BG_CONN_DEV == TRUE) } /******************************************************************************* @@ -1314,7 +1370,7 @@ BOOLEAN BTM_BleUpdateBgConnDev(BOOLEAN add_remove, BD_ADDR remote_bda) BTM_TRACE_EVENT("%s() add=%d", __func__, add_remove); return btm_update_dev_to_white_list(add_remove, remote_bda, 0, NULL); } - +#if 0 /******************************************************************************* ** ** Function BTM_BleSetConnectableMode @@ -1342,7 +1398,7 @@ tBTM_STATUS BTM_BleSetConnectableMode(tBTM_BLE_CONN_MODE connectable_mode) p_cb->directed_conn = connectable_mode; return btm_ble_set_connectability( p_cb->connectable_mode); } - +#endif /******************************************************************************* ** ** Function btm_set_conn_mode_adv_init_addr @@ -1435,76 +1491,7 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb, return evt_type; } -/******************************************************************************* -** -** Function BTM_BleSetAdvParams -** -** Description This function is called to set advertising parameters. -** -** Parameters adv_int_min: minimum advertising interval -** adv_int_max: maximum advertising interval -** p_dir_bda: connectable direct initiator's LE device address -** chnl_map: advertising channel map. -** -** Returns void -** -*******************************************************************************/ -tBTM_STATUS BTM_BleSetAdvParams(UINT16 adv_int_min, UINT16 adv_int_max, - tBLE_BD_ADDR *p_dir_bda, - tBTM_BLE_ADV_CHNL_MAP chnl_map) -{ - tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; - tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; - tBTM_STATUS status = BTM_SUCCESS; - BD_ADDR p_addr_ptr = {0}; - tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC; - tBLE_ADDR_TYPE own_addr_type = p_addr_cb->own_addr_type; - UINT8 adv_mode = p_cb->adv_mode; - - BTM_TRACE_EVENT ("BTM_BleSetAdvParams"); - - if (!controller_get_interface()->supports_ble()) { - return BTM_ILLEGAL_VALUE; - } - - if (!BTM_BLE_ISVALID_PARAM(adv_int_min, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX) || - !BTM_BLE_ISVALID_PARAM(adv_int_max, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX)) { - return BTM_ILLEGAL_VALUE; - } - - p_cb->adv_interval_min = adv_int_min; - p_cb->adv_interval_max = adv_int_max; - p_cb->adv_chnl_map = chnl_map; - - if (p_dir_bda) { - memcpy(&p_cb->direct_bda, p_dir_bda, sizeof(tBLE_BD_ADDR)); - } - - BTM_TRACE_EVENT ("update params for an active adv\n"); - - btm_ble_stop_adv(); - - p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, - &own_addr_type); - - /* update adv params */ - btsnd_hcic_ble_write_adv_params (p_cb->adv_interval_min, - p_cb->adv_interval_max, - p_cb->evt_type, - own_addr_type, - init_addr_type, - p_addr_ptr, - p_cb->adv_chnl_map, - p_cb->afp); - - if (adv_mode == BTM_BLE_ADV_ENABLE) { - btm_ble_start_adv(); - } - - return status; -} - - +#if (BLE_42_ADV_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleSetAdvParamsAll @@ -1599,6 +1586,7 @@ tBTM_STATUS BTM_BleStartAdv(void) return status; } +#endif // #if (BLE_42_ADV_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleReadAdvParams @@ -1632,6 +1620,7 @@ void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max, } } +#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) /******************************************************************************* ** ** Function BTM_BleSetScanParams @@ -1690,7 +1679,9 @@ void BTM_BleSetScanParams(tGATT_IF client_if, UINT32 scan_interval, UINT32 scan_ } } +#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) +#if (BLE_42_SCAN_EN == TRUE) tBTM_STATUS BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, UINT32 scan_window, tBLE_SCAN_MODE scan_mode, UINT8 addr_type_own, UINT8 scan_duplicate_filter, tBTM_BLE_SFP scan_filter_policy, tBLE_SCAN_PARAM_SETUP_CBACK scan_setup_status_cback) @@ -1746,8 +1737,9 @@ tBTM_STATUS BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, osi_mutex_unlock(&scan_param_lock); return ret; } +#endif // #if (BLE_42_SCAN_EN == TRUE) - +#if (BLE_42_ADV_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleWriteScanRsp @@ -1822,6 +1814,7 @@ tBTM_STATUS BTM_BleWriteScanRspRaw(UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_le return ret; } +#endif // #if (BLE_42_ADV_EN == TRUE) /******************************************************************************* ** @@ -1888,6 +1881,7 @@ tBTM_STATUS BTM_UpdateBleDuplicateExceptionalList(uint8_t subcode, uint32_t type return status; } +#if (BLE_42_ADV_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleWriteAdvData @@ -1940,38 +1934,6 @@ tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p /******************************************************************************* ** -** Function BTM_BleWriteLongAdvData -** -** Description This function is called to write long advertising data. -** -** Parameters: adv_data: long advertising data -** adv_data_len: the length of long advertising data -** -** Returns void -** -*******************************************************************************/ -tBTM_STATUS BTM_BleWriteLongAdvData(uint8_t *adv_data, uint8_t adv_data_len) -{ - tBTM_STATUS status = BTM_NO_RESOURCES; - if (!controller_get_interface()->supports_ble()) { - return BTM_ILLEGAL_VALUE; - } - if(!adv_data || adv_data_len <= 0 || adv_data_len > BTM_BLE_LONG_ADV_MAX_LEN) { - return BTM_ILLEGAL_VALUE; - } - uint8_t long_adv[BTM_BLE_LONG_ADV_MAX_LEN + 1] = {0}; - long_adv[0] = adv_data_len; - memcpy(&long_adv[1], adv_data, adv_data_len); - status = BTM_VendorSpecificCommand(HCI_VENDOR_BLE_LONG_ADV_DATA, BTM_BLE_LONG_ADV_MAX_LEN + 1, long_adv, NULL); - if(status == BTM_CMD_STARTED) { - status = BTM_SUCCESS; - } - - return status; -} - -/******************************************************************************* -** ** Function BTM_BleWriteAdvDataRaw ** ** Description This function is called to write raw advertising data. @@ -1995,7 +1957,7 @@ tBTM_STATUS BTM_BleWriteAdvDataRaw(UINT8 *p_raw_adv, UINT32 raw_adv_len) return ret; } - +#endif // #if (BLE_42_ADV_EN == TRUE) /******************************************************************************* ** @@ -2082,6 +2044,7 @@ BOOLEAN BTM_BleGetCurrentAddress(BD_ADDR addr, uint8_t *addr_type) return TRUE; } +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) /******************************************************************************* ** ** Function BTM_CheckAdvData @@ -2095,7 +2058,7 @@ BOOLEAN BTM_BleGetCurrentAddress(BD_ADDR addr, uint8_t *addr_type) ** Returns pointer of ADV data ** *******************************************************************************/ -UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length) +UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT16 adv_data_len, UINT8 type, UINT8 *p_length) { UINT8 *p = p_adv; UINT8 length; @@ -2104,7 +2067,7 @@ UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length) STREAM_TO_UINT8(length, p); - while ( length && (p - p_adv < BTM_BLE_CACHE_ADV_DATA_MAX)) { + while ( length && (p - p_adv < adv_data_len)) { STREAM_TO_UINT8(adv_type, p); if ( adv_type == type ) { @@ -2117,7 +2080,7 @@ UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length) /* Break loop if advertising data is in an incorrect format, as it may lead to memory overflow */ - if (p >= p_adv + BTM_BLE_CACHE_ADV_DATA_MAX) { + if (p >= p_adv + adv_data_len) { break; } @@ -2127,7 +2090,7 @@ UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length) *p_length = 0; return NULL; } - +#endif // #if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) /******************************************************************************* ** ** Function BTM__BLEReadDiscoverability @@ -2165,16 +2128,20 @@ UINT16 BTM_BleReadConnectability(void) void BTM_Recovery_Pre_State(void) { +#if ((BLE_42_ADV_EN == TRUE) || (BLE_42_SCAN_EN == TRUE)) tBTM_BLE_INQ_CB *ble_inq_cb = &btm_cb.ble_ctr_cb.inq_var; - +#endif // #if ((BLE_42_ADV_EN == TRUE) || (BLE_42_SCAN_EN == TRUE)) +#if (BLE_42_ADV_EN == TRUE) if (ble_inq_cb->state & BTM_BLE_ADVERTISING) { btm_ble_stop_adv(); btm_ble_start_adv(); } +#endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_42_SCAN_EN == TRUE) if (ble_inq_cb->state & BTM_BLE_SCANNING) { btm_ble_start_scan(); } - +#endif // #if (BLE_42_SCAN_EN == TRUE) return; } @@ -2205,6 +2172,26 @@ BOOLEAN BTM_GetCurrentConnParams(BD_ADDR bda, uint16_t *interval, uint16_t *late /******************************************************************************* ** +** Function btm_ble_map_adv_tx_power +** +** Description return the actual power in dBm based on the mapping in config file +** +** Parameters advertise parameters used for this instance. +** +** Returns tx power in dBm +** +*******************************************************************************/ +static const int btm_ble_tx_power[BTM_BLE_ADV_TX_POWER_MAX + 1] = BTM_BLE_ADV_TX_POWER; +char btm_ble_map_adv_tx_power(int tx_power_index) +{ + if (0 <= tx_power_index && tx_power_index <= BTM_BLE_ADV_TX_POWER_MAX) { + return (char)btm_ble_tx_power[tx_power_index]; + } + return 0; +} + +/******************************************************************************* +** ** Function btm_ble_build_adv_data ** ** Description This function is called build the adv data and rsp data. @@ -2564,6 +2551,7 @@ void btm_ble_set_adv_flag(UINT16 connect_mode, UINT16 disc_mode) btm_ble_update_adv_flag(flag); } } +#if 0 /******************************************************************************* ** ** Function btm_ble_set_discoverability @@ -2615,7 +2603,9 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode) if (evt_type != p_cb->evt_type || p_cb->adv_addr_type != own_addr_type || !p_cb->fast_adv_on) { +#if (BLE_42_ADV_EN == TRUE) btm_ble_stop_adv(); +#endif // #if (BLE_42_ADV_EN == TRUE) /* update adv params */ if (!btsnd_hcic_ble_write_adv_params (adv_int_min, @@ -2635,11 +2625,13 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode) } if (status == BTM_SUCCESS && p_cb->adv_mode != new_mode) { +#if (BLE_42_ADV_EN == TRUE) if (new_mode == BTM_BLE_ADV_ENABLE) { status = btm_ble_start_adv(); } else { status = btm_ble_stop_adv(); } +#endif // #if (BLE_42_ADV_EN == TRUE) } if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) { @@ -2662,7 +2654,7 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode) } return status; } - +#endif /******************************************************************************* ** ** Function btm_ble_set_connectability @@ -2710,7 +2702,9 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode) btm_ble_set_adv_flag (combined_mode, btm_cb.btm_inq_vars.discoverable_mode); if (p_cb->evt_type != evt_type || p_cb->adv_addr_type != p_addr_cb->own_addr_type || !p_cb->fast_adv_on) { +#if (BLE_42_ADV_EN == TRUE) btm_ble_stop_adv(); +#endif // #if (BLE_42_ADV_EN == TRUE) if (!btsnd_hcic_ble_write_adv_params (adv_int_min, adv_int_max, @@ -2730,11 +2724,13 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode) /* update advertising mode */ if (status == BTM_SUCCESS && new_mode != p_cb->adv_mode) { +#if (BLE_42_ADV_EN == TRUE) if (new_mode == BTM_BLE_ADV_ENABLE) { status = btm_ble_start_adv(); } else { status = btm_ble_stop_adv(); } +#endif // #if (BLE_42_ADV_EN == TRUE) } if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) { @@ -2795,7 +2791,9 @@ tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration) /* enable IRK list */ //btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN); #endif +#if (BLE_42_SCAN_EN == TRUE) status = btm_ble_start_scan(); +#endif // #if (BLE_42_SCAN_EN == TRUE) } else if ((p_ble_cb->inq_var.scan_interval != BTM_BLE_LOW_LATENCY_SCAN_INT) || (p_ble_cb->inq_var.scan_window != BTM_BLE_LOW_LATENCY_SCAN_WIN)) { BTM_TRACE_DEBUG("%s, restart LE scan with low latency scan params", __FUNCTION__); @@ -3170,7 +3168,7 @@ UINT8 btm_ble_is_discoverable(BD_ADDR bda, UINT8 evt_type, UINT8 *p) } if (p_le_inq_cb->adv_len != 0) { - if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, + if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, p_le_inq_cb->adv_len, BTM_BLE_AD_TYPE_FLAG, &data_len)) != NULL) { flag = * p_flag; @@ -3386,7 +3384,7 @@ BOOLEAN btm_ble_update_inq_result(BD_ADDR bda, tINQ_DB_ENT *p_i, UINT8 addr_type p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */ if (p_le_inq_cb->adv_len != 0) { - if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, BTM_BLE_AD_TYPE_FLAG, &len)) != NULL) { + if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, p_le_inq_cb->adv_len, BTM_BLE_AD_TYPE_FLAG, &len)) != NULL) { p_cur->flag = * p_flag; } } @@ -3396,11 +3394,11 @@ BOOLEAN btm_ble_update_inq_result(BD_ADDR bda, tINQ_DB_ENT *p_i, UINT8 addr_type * then try to convert the appearance value to a class of device value Bluedroid can use. * Otherwise fall back to trying to infer if it is a HID device based on the service class. */ - p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, BTM_BLE_AD_TYPE_APPEARANCE, &len); + p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, p_le_inq_cb->adv_len, BTM_BLE_AD_TYPE_APPEARANCE, &len); if (p_uuid16 && len == 2) { btm_ble_appearance_to_cod((UINT16)p_uuid16[0] | (p_uuid16[1] << 8), p_cur->dev_class); } else { - if ((p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, + if ((p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, p_le_inq_cb->adv_len, BTM_BLE_AD_TYPE_16SRV_CMPL, &len)) != NULL) { UINT8 i; for (i = 0; i + 2 <= len; i = i + 2) { @@ -3487,10 +3485,10 @@ void btm_send_sel_conn_callback(BD_ADDR remote_bda, UINT8 evt_type, UINT8 *p_dat /* get the device name if exist in ADV data */ if (data_len != 0) { - p_dev_name = BTM_CheckAdvData(p_data, BTM_BLE_AD_TYPE_NAME_CMPL, &len); + p_dev_name = BTM_CheckAdvData(p_data, data_len, BTM_BLE_AD_TYPE_NAME_CMPL, &len); if (p_dev_name == NULL) { - p_dev_name = BTM_CheckAdvData(p_data, BTM_BLE_AD_TYPE_NAME_SHORT, &len); + p_dev_name = BTM_CheckAdvData(p_data, data_len, BTM_BLE_AD_TYPE_NAME_SHORT, &len); } if (p_dev_name) { @@ -3504,6 +3502,7 @@ void btm_send_sel_conn_callback(BD_ADDR remote_bda, UINT8 evt_type, UINT8 *p_dat } } +#if (BLE_42_SCAN_EN == TRUE) static void btm_adv_pkt_handler(void *arg) { UINT8 hci_evt_code, hci_evt_len; @@ -3546,6 +3545,7 @@ static void btm_adv_pkt_handler(void *arg) UNUSED(hci_evt_code); UNUSED(hci_evt_len); } +#endif // #if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* ** @@ -3832,6 +3832,7 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt void btm_ble_process_adv_discard_evt(UINT8 *p) { +#if (BLE_42_SCAN_EN == TRUE) #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) uint32_t num_dis = 0; STREAM_TO_UINT32 (num_dis, p); @@ -3840,6 +3841,7 @@ void btm_ble_process_adv_discard_evt(UINT8 *p) (p_obs_discard_cb)(num_dis); } #endif +#endif // #if (BLE_42_SCAN_EN == TRUE) } void btm_ble_process_direct_adv_pkt(UINT8 *p) @@ -3847,6 +3849,7 @@ void btm_ble_process_direct_adv_pkt(UINT8 *p) // TODO } +#if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* ** ** Function btm_ble_start_scan @@ -3884,6 +3887,7 @@ tBTM_STATUS btm_ble_start_scan(void) osi_mutex_unlock(&scan_enable_lock); return status; } +#endif // #if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* ** @@ -3933,8 +3937,10 @@ void btm_ble_stop_inquiry(void) } else if ((p_ble_cb->inq_var.scan_interval != BTM_BLE_LOW_LATENCY_SCAN_INT) || (p_ble_cb->inq_var.scan_window != BTM_BLE_LOW_LATENCY_SCAN_WIN)) { BTM_TRACE_DEBUG("%s: setting default params for ongoing observe", __FUNCTION__); +#if (BLE_42_SCAN_EN == TRUE) btm_ble_stop_scan(); btm_ble_start_scan(); +#endif // #if (BLE_42_SCAN_EN == TRUE) } /* If we have a callback registered for inquiry complete, call it */ @@ -3985,6 +3991,7 @@ static void btm_ble_stop_observe(void) *******************************************************************************/ static void btm_ble_stop_discover(void) { +#if (BLE_42_SCAN_EN == TRUE) tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb; tBTM_CMPL_CB *p_scan_cb = p_ble_cb->p_scan_cmpl_cb; btu_stop_timer (&p_ble_cb->scan_timer_ent); @@ -3997,18 +4004,21 @@ static void btm_ble_stop_discover(void) if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) { /* Clear the inquiry callback if set */ - btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE; btm_cb.ble_ctr_cb.inq_var.state &= ~BTM_BLE_SCANNING; /* stop discovery now */ if(btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE)) { osi_sem_take(&scan_enable_sem, OSI_SEM_MAX_TIMEOUT); } + /* reset status */ + btm_ble_clear_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT); + btm_ble_clear_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT); } if (p_scan_cb) { (p_scan_cb)((tBTM_INQUIRY_CMPL *) &btm_cb.btm_inq_vars.inq_cmpl_info); } osi_mutex_unlock(&scan_enable_lock); +#endif // #if (BLE_42_SCAN_EN == TRUE) } /******************************************************************************* @@ -4021,6 +4031,7 @@ static void btm_ble_stop_discover(void) ** *******************************************************************************/ typedef BOOLEAN (BTM_TOPOLOGY_FUNC_PTR)(tBTM_BLE_STATE_MASK); +#if (BLE_42_ADV_EN == TRUE) static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UINT8 adv_evt) { BOOLEAN rt = FALSE; @@ -4053,7 +4064,6 @@ static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UI return rt; } - /******************************************************************************* ** ** Function btm_ble_start_adv @@ -4165,14 +4175,19 @@ tBTM_STATUS btm_ble_stop_adv(void) } return rt; } +#endif // #if (BLE_42_ADV_EN == TRUE) tBTM_STATUS btm_ble_set_random_addr(BD_ADDR random_bda) { tBTM_STATUS rt = BTM_SUCCESS; - +#if (BLE_42_ADV_EN == TRUE) osi_mutex_lock(&adv_enable_lock, OSI_MUTEX_MAX_TIMEOUT); +#endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_42_SCAN_EN == TRUE) osi_mutex_lock(&scan_enable_lock, OSI_MUTEX_MAX_TIMEOUT); +#endif // #if (BLE_42_SCAN_EN == TRUE) +#if (BLE_42_ADV_EN == TRUE) if (btm_cb.ble_ctr_cb.inq_var.adv_mode == BTM_BLE_ADV_ENABLE) { if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE)) { osi_sem_take(&adv_enable_sem, OSI_SEM_MAX_TIMEOUT); @@ -4181,7 +4196,9 @@ tBTM_STATUS btm_ble_set_random_addr(BD_ADDR random_bda) rt = BTM_BAD_VALUE_RET; } } +#endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_42_SCAN_EN == TRUE) if (BTM_BLE_IS_DISCO_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) { if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_SCAN_DUPLICATE_DISABLE)) { osi_sem_take(&scan_enable_sem, OSI_SEM_MAX_TIMEOUT); @@ -4190,11 +4207,13 @@ tBTM_STATUS btm_ble_set_random_addr(BD_ADDR random_bda) rt = BTM_BAD_VALUE_RET; } } +#endif // #if (BLE_42_SCAN_EN == TRUE) if (rt == BTM_SUCCESS) { btsnd_hcic_ble_set_random_addr(random_bda); } +#if (BLE_42_ADV_EN == TRUE) if (btm_cb.ble_ctr_cb.inq_var.adv_mode == BTM_BLE_ADV_ENABLE) { if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE)) { osi_sem_take(&adv_enable_sem, OSI_SEM_MAX_TIMEOUT); @@ -4203,7 +4222,9 @@ tBTM_STATUS btm_ble_set_random_addr(BD_ADDR random_bda) rt = BTM_BAD_VALUE_RET; } } +#endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_42_SCAN_EN == TRUE) if (BTM_BLE_IS_DISCO_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) { if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, btm_cb.ble_ctr_cb.inq_var.scan_duplicate_filter)) { osi_sem_take(&scan_enable_sem, OSI_SEM_MAX_TIMEOUT); @@ -4212,9 +4233,14 @@ tBTM_STATUS btm_ble_set_random_addr(BD_ADDR random_bda) rt = BTM_BAD_VALUE_RET; } } +#endif // #if (BLE_42_SCAN_EN == TRUE) +#if (BLE_42_ADV_EN == TRUE) osi_mutex_unlock(&adv_enable_lock); +#endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_42_SCAN_EN == TRUE) osi_mutex_unlock(&scan_enable_lock); +#endif // #if (BLE_42_SCAN_EN == TRUE) return rt; } @@ -4231,6 +4257,7 @@ tBTM_STATUS btm_ble_set_random_addr(BD_ADDR random_bda) *******************************************************************************/ static void btm_ble_start_slow_adv (void) { +#if (BLE_42_ADV_EN == TRUE) tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) { @@ -4249,9 +4276,9 @@ static void btm_ble_start_slow_adv (void) p_cb->evt_type, own_addr_type, init_addr_type, p_addr_ptr, p_cb->adv_chnl_map, p_cb->afp); - btm_ble_start_adv(); } +#endif // #if (BLE_42_ADV_EN == TRUE) } /******************************************************************************* ** @@ -4291,9 +4318,11 @@ void btm_ble_timeout(TIMER_LIST_ENT *p_tle) btm_gen_resolvable_private_addr((void *)btm_gen_resolve_paddr_low); #endif } else { +#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) if (BTM_BleMaxMultiAdvInstanceCount() > 0) { btm_ble_multi_adv_configure_rpa((tBTM_BLE_MULTI_ADV_INST *)p_tle->param); } +#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) } } break; @@ -4515,12 +4544,36 @@ BOOLEAN btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, UINT8 st now in order */ if (btm_ble_get_conn_st() == BLE_CONN_IDLE && status != HCI_ERR_HOST_REJECT_RESOURCES && !btm_send_pending_direct_conn()) { +#if (tGATT_BG_CONN_DEV == TRUE) bg_con = btm_ble_resume_bg_conn(); +#endif // #if (tGATT_BG_CONN_DEV == TRUE) } return bg_con; } +#if (BLE_VENDOR_HCI_EN == TRUE) +static void btm_ble_vs_evt_callback(UINT8 len, UINT8 *p) +{ + UINT8 sub_event; + + if (!len || !p) { + return; + } + + STREAM_TO_UINT8(sub_event, p); + len--; + + if (sub_event < HCI_VSE_LE_SUBEVT_BASE) { + return; + } + + if (ble_vs_evt_callback) { + ble_vs_evt_callback(sub_event, len, p); + } +} +#endif // #if (BLE_VENDOR_HCI_EN == TRUE) + /******************************************************************************* ** ** Function btm_ble_init @@ -4566,17 +4619,22 @@ void btm_ble_init (void) p_cb->scan_int = p_cb->scan_win = BTM_BLE_SCAN_PARAM_UNDEF; p_cb->inq_var.evt_type = BTM_BLE_NON_CONNECT_EVT; - +#if (BLE_42_SCAN_EN == TRUE) p_cb->adv_rpt_queue = pkt_queue_create(); assert(p_cb->adv_rpt_queue != NULL); p_cb->adv_rpt_ready = osi_event_create(btm_adv_pkt_handler, NULL); assert(p_cb->adv_rpt_ready != NULL); osi_event_bind(p_cb->adv_rpt_ready, btu_get_current_thread(), 0); - +#endif // #if (BLE_42_SCAN_EN == TRUE) #if BLE_VND_INCLUDED == FALSE +#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE btm_ble_adv_filter_init(); +#endif // #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE #endif +#if (BLE_VENDOR_HCI_EN == TRUE) + BTM_RegisterForVSEvents(btm_ble_vs_evt_callback, TRUE); +#endif // #if (BLE_VENDOR_HCI_EN == TRUE) } /******************************************************************************* @@ -4595,19 +4653,25 @@ void btm_ble_free (void) BTM_TRACE_DEBUG("%s", __func__); fixed_queue_free(p_cb->conn_pending_q, osi_free_func); - +#if (BLE_42_SCAN_EN == TRUE) pkt_queue_destroy(p_cb->adv_rpt_queue, NULL); p_cb->adv_rpt_queue = NULL; osi_event_delete(p_cb->adv_rpt_ready); p_cb->adv_rpt_ready = NULL; - +#endif // #if (BLE_42_SCAN_EN == TRUE) #if BTM_DYNAMIC_MEMORY == TRUE osi_free(cmn_ble_gap_vsc_cb_ptr); cmn_ble_gap_vsc_cb_ptr = NULL; #endif } +static bool enable_topology_check_flag = true; +void esp_qa_enable_topology_check(bool enable) +{ + // This is a workaround: If the topology check is disabled, the 'Supported States' will not be checked. + enable_topology_check_flag = enable; +} /******************************************************************************* ** ** Function btm_ble_topology_check @@ -4620,6 +4684,7 @@ void btm_ble_free (void) *******************************************************************************/ BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request_state_mask) { + if(!enable_topology_check_flag) return TRUE; BOOLEAN rt = FALSE; UINT8 state_offset = 0; @@ -4696,6 +4761,7 @@ BOOLEAN BTM_Ble_Authorization(BD_ADDR bd_addr, BOOLEAN authorize) return FALSE; } +#if (BLE_VENDOR_HCI_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleClearAdv @@ -4717,6 +4783,30 @@ BOOLEAN BTM_BleClearAdv(tBTM_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback) p_cb->inq_var.p_clear_adv_cb = p_clear_adv_cback; return TRUE; } + +BOOLEAN BTM_BleSetCsaSupport(UINT8 csa_select, tBTM_SET_CSA_SUPPORT_CMPL_CBACK *p_callback) +{ + if (btsnd_hcic_ble_set_csa_support(csa_select) != TRUE) { + BTM_TRACE_ERROR("LE SetCsaSupport csa_select=%d: error", csa_select); + return FALSE; + } + + btm_cb.ble_ctr_cb.set_csa_support_cmpl_cb = p_callback; + return TRUE; +} + +BOOLEAN BTM_BleSetVendorEventMask(UINT32 evt_mask, tBTM_SET_VENDOR_EVT_MASK_CBACK *p_callback) +{ + if (btsnd_hcic_ble_set_vendor_evt_mask(evt_mask) != TRUE) { + BTM_TRACE_ERROR("LE SetVendorEventMask evt_mask=%x: error", evt_mask); + return FALSE; + } + + btm_cb.ble_ctr_cb.set_vendor_evt_mask_cmpl_cb = p_callback; + return TRUE; +} +#endif // #if (BLE_VENDOR_HCI_EN == TRUE) + BOOLEAN BTM_BleSetRpaTimeout(uint16_t rpa_timeout,tBTM_SET_RPA_TIMEOUT_CMPL_CBACK *p_set_rpa_timeout_cback) { if ((btsnd_hcic_ble_set_rand_priv_addr_timeout(rpa_timeout)) != TRUE) { @@ -4752,6 +4842,7 @@ BOOLEAN BTM_BleSetPrivacyMode(UINT8 addr_type, BD_ADDR bd_addr, UINT8 privacy_mo return TRUE; } +#if (BLE_42_SCAN_EN == TRUE) bool btm_ble_adv_pkt_ready(void) { tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; @@ -4770,4 +4861,6 @@ bool btm_ble_adv_pkt_post(pkt_linked_item_t *pkt) pkt_queue_enqueue(p_cb->adv_rpt_queue, pkt); return true; } +#endif // #if (BLE_42_SCAN_EN == TRUE) + #endif /* BLE_INCLUDED */ diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_iso.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_iso.c new file mode 100644 index 00000000..c66f10b9 --- /dev/null +++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_iso.c @@ -0,0 +1,525 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "btm_int.h" +#include "stack/hcimsgs.h" +#include "osi/allocator.h" +#include "device/controller.h" +#include <string.h> +#include "l2c_int.h" + +tBTM_BLE_ISO_CBACK ble_iso_cb; + +extern void btm_ble_inter_set(bool extble_inter); + +void BTM_BleIsoRegisterCallback(tBTM_BLE_ISO_CBACK cb) +{ + if (cb) { + ble_iso_cb = cb; + } else { + BTM_TRACE_ERROR("%s, register fail, the cb function is NULL.", __func__); + } +} + +void BTM_IsoBleCallbackTrigger(tBTM_BLE_5_GAP_EVENT event, tBTM_BLE_ISO_CB_PARAMS *params) +{ + if(params && params->status == BTM_SUCCESS) { + btm_ble_inter_set(true); + } + if (ble_iso_cb) { + ble_iso_cb(event, params); + } +} + +void btm_ble_iso_read_iso_tx_sync_complete(UINT8 *p) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + STREAM_TO_UINT8(cb_params.btm_read_tx_sync.status, p); + STREAM_TO_UINT16(cb_params.btm_read_tx_sync.conn_hdl, p); + STREAM_TO_UINT16(cb_params.btm_read_tx_sync.pkt_seq_num, p); + STREAM_TO_UINT32(cb_params.btm_read_tx_sync.tx_time_stamp, p); + STREAM_TO_UINT24(cb_params.btm_read_tx_sync.time_offset, p); + + if (cb_params.btm_read_tx_sync.status != HCI_SUCCESS) { + cb_params.btm_read_tx_sync.status = (BTM_HCI_ERROR | cb_params.btm_read_tx_sync.status); + } + cb_params.btm_read_tx_sync.conn_hdl = (cb_params.btm_read_tx_sync.conn_hdl & 0xEFF); + cb_params.btm_read_tx_sync.time_offset = (cb_params.btm_read_tx_sync.time_offset & 0xFFFFFF); + BTM_TRACE_DEBUG("read tx sync cmpl, status 0x%x conn_hdl 0x%x pkt_seq_num %d tx_time_stamp %ld time_offset %ld\n", + cb_params.btm_read_tx_sync.status, cb_params.btm_read_tx_sync.conn_hdl, cb_params.btm_read_tx_sync.pkt_seq_num, + cb_params.btm_read_tx_sync.tx_time_stamp, cb_params.btm_read_tx_sync.time_offset); + + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_READ_TX_SYNC_EVT, &cb_params); +} + +void btm_ble_iso_read_iso_link_quality_complete(UINT8 *p) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + STREAM_TO_UINT8(cb_params.btm_read_link_quality.status, p); + STREAM_TO_UINT16(cb_params.btm_read_link_quality.conn_hdl, p); + STREAM_TO_UINT32(cb_params.btm_read_link_quality.tx_unacked_pkts, p); + STREAM_TO_UINT32(cb_params.btm_read_link_quality.tx_flushed_pkts, p); + STREAM_TO_UINT32(cb_params.btm_read_link_quality.tx_last_subevt_pkts, p); + STREAM_TO_UINT32(cb_params.btm_read_link_quality.retransmitted_pkts, p); + STREAM_TO_UINT32(cb_params.btm_read_link_quality.crc_error_pkts, p); + STREAM_TO_UINT32(cb_params.btm_read_link_quality.rx_unreceived_pkts, p); + STREAM_TO_UINT32(cb_params.btm_read_link_quality.duplicate_pkts, p); + + if (cb_params.btm_read_link_quality.status != HCI_SUCCESS) { + cb_params.btm_read_link_quality.status = (BTM_HCI_ERROR | cb_params.btm_read_link_quality.status); + } + + BTM_TRACE_DEBUG("read link quality cmpl, status 0x%x conn_hdl 0x%x tx_unacked_pkts %d tx_flushed_pkts %ld tx_last_subevt_pkts %ld retransmitted_pkts %d\ + crc_error_pkts %d rx_unreceived_pkts %d duplicate_pkts %d\n", + cb_params.btm_read_link_quality.status, cb_params.btm_read_link_quality.conn_hdl, cb_params.btm_read_link_quality.tx_unacked_pkts, + cb_params.btm_read_link_quality.tx_flushed_pkts, cb_params.btm_read_link_quality.tx_last_subevt_pkts, cb_params.btm_read_link_quality.retransmitted_pkts, + cb_params.btm_read_link_quality.crc_error_pkts, cb_params.btm_read_link_quality.rx_unreceived_pkts, cb_params.btm_read_link_quality.duplicate_pkts); + + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_READ_LINK_QUALITY_EVT, &cb_params); +} + +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +void btm_ble_iso_set_cig_params_complete(UINT8 *p) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + + STREAM_TO_UINT8(cb_params.btm_set_cig_params.status, p); + STREAM_TO_UINT8(cb_params.btm_set_cig_params.cig_id, p); + STREAM_TO_UINT8(cb_params.btm_set_cig_params.cis_count, p); + for (uint8_t i = 0; i < cb_params.btm_set_cig_params.cis_count; i++) + { + STREAM_TO_UINT16(cb_params.btm_set_cig_params.conn_hdl[i], p); + BTM_TRACE_DEBUG("i = %d, conn_hdl = %d", i, cb_params.btm_set_cig_params.conn_hdl[i]); + } + + if (cb_params.btm_set_cig_params.status != HCI_SUCCESS) { + cb_params.btm_set_cig_params.status = (BTM_HCI_ERROR | cb_params.btm_set_cig_params.status); + } + + BTM_TRACE_DEBUG("set cig params, status 0x%x cig_id %d cis_count %d\n", + cb_params.btm_set_cig_params.status, cb_params.btm_set_cig_params.cig_id, cb_params.btm_set_cig_params.cis_count); + + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_SET_CIG_PARAMS_EVT, &cb_params); +} +#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_EN == TRUE) +void btm_ble_cis_disconnected_evt(tBTM_BLE_CIS_DISCON_CMPL *params) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + cb_params.btm_cis_disconnectd_evt.cis_handle = params->cis_handle; + cb_params.btm_cis_disconnectd_evt.reason = params->reason; + + BTM_TRACE_DEBUG("btm cis disconnect, cis_handle %d reason 0x%x\n", params->cis_handle, params->reason); + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_CIS_DISCONNECTED_EVT, &cb_params); +} + +void btm_ble_cis_established_evt(tBTM_BLE_CIS_ESTABLISHED_CMPL *params) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + if (params->status != HCI_SUCCESS) { + params->status = (params->status | BTM_HCI_ERROR); + } + + memcpy(&cb_params.btm_cis_established_evt, params, sizeof(tBTM_BLE_CIS_ESTABLISHED_CMPL)); + + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_CIS_ESTABLISHED_EVT, &cb_params); +} +#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +void btm_ble_cis_request_evt(tBTM_BLE_CIS_REQUEST_CMPL *params) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + memcpy(&cb_params.btm_cis_request_evt, params, sizeof(tBTM_BLE_CIS_REQUEST_CMPL)); + + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_CIS_REQUEST_EVT, &cb_params); +} +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) + +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +void btm_ble_big_create_cmpl_evt(tBTM_BLE_BIG_CREATE_CMPL *params) +{ + BTM_TRACE_DEBUG("%s", __func__); + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + if (params->status != HCI_SUCCESS) { + params->status = (params->status | BTM_HCI_ERROR); + } + + cb_params.btm_big_cmpl.status = params->status; + cb_params.btm_big_cmpl.big_handle = params->big_handle; + cb_params.btm_big_cmpl.big_sync_delay = params->big_sync_delay; + cb_params.btm_big_cmpl.transport_latency = params->transport_latency; + cb_params.btm_big_cmpl.phy = params->phy; + cb_params.btm_big_cmpl.nse = params->nse; + cb_params.btm_big_cmpl.bn = params->bn; + cb_params.btm_big_cmpl.pto = params->pto; + cb_params.btm_big_cmpl.irc = params->irc; + cb_params.btm_big_cmpl.max_pdu = params->max_pdu; + cb_params.btm_big_cmpl.iso_interval = params->iso_interval; + cb_params.btm_big_cmpl.num_bis = params->num_bis; + // for (uint8_t i = 0; i < params->num_bis; i++) + // { + // cb_params.btm_big_cmpl.bis_handle[i] = params->bis_handle[i]; + // } + memcpy(&cb_params.btm_big_cmpl.bis_handle[0], ¶ms->bis_handle[0], params->num_bis * 2); + + //memcpy(&cb_params.btm_big_cmpl, params, sizeof(tBTM_BLE_BIG_CREATE_CMPL)); + + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_CREATE_COMPLETE_EVT, &cb_params); +} + +void btm_ble_big_terminate_cmpl_evt(tBTM_BLE_BIG_TERMINATE_CMPL *params) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + memcpy(&cb_params.btm_big_term, params, sizeof(tBTM_BLE_BIG_TERMINATE_CMPL)); + + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_TERMINATE_COMPLETE_EVT, &cb_params); +} +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) + +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +void btm_ble_big_sync_estab_evt(tBTM_BLE_BIG_SYNC_ESTAB_CMPL *params) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + if (params->status != HCI_SUCCESS) { + params->status = (params->status | BTM_HCI_ERROR); + } + + memcpy(&cb_params.btm_big_sync_estab, params, sizeof(tBTM_BLE_BIG_SYNC_ESTAB_CMPL)); + + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT, &cb_params); +} + +void btm_ble_big_sync_terminate_complete(UINT8 hci_status, UINT8 big_handle) +{ + BTM_TRACE_DEBUG("%s hci_status 0x%x big_handle %d\n", __func__, hci_status, big_handle); + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + + if (hci_status != HCI_SUCCESS) { + hci_status = (hci_status | BTM_HCI_ERROR); + } + + cb_params.status = hci_status; + cb_params.btm_big_sync_ter.big_hdl = big_handle; + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_SYNC_TERMINATE_COMPLETE_EVT, &cb_params); +} + +void btm_ble_big_sync_lost_evt(tBTM_BLE_BIG_SYNC_LOST_EVT *params) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + memcpy(&cb_params.btm_big_sync_lost, params, sizeof(tBTM_BLE_BIG_SYNC_LOST_EVT)); + + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_SYNC_LOST_EVT, &cb_params); +} + +void btm_ble_biginfo_adv_report_evt(tBTM_BLE_BIGINFO_ADV_REPORT_EVT *params) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + memcpy(&cb_params.btm_biginfo_report, params, sizeof(tBTM_BLE_BIGINFO_ADV_REPORT_EVT)); + + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIGINFO_ADV_REPORT_EVT, &cb_params); +} +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) + +void btm_ble_iso_data_path_update_complete(UINT16 opcode, UINT8 hci_status, UINT16 conn_handle) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + BTM_TRACE_DEBUG("data path update cmpl, opcode 0x%x status 0x%x conn_hdl %d\n", opcode, hci_status, conn_handle); + if (hci_status != HCI_SUCCESS) { + hci_status = (BTM_HCI_ERROR | hci_status); + } + cb_params.status = hci_status; + cb_params.btm_data_path_update.op_type = ((opcode == HCI_BLE_ISO_SET_DATA_PATH) ? BTM_BLE_ISO_DATA_PATH_SETUP : BTM_BLE_ISO_DATA_PATH_REMOVE); + cb_params.btm_data_path_update.conn_hdl = conn_handle; + + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_DATA_PATH_UPFATE_EVT, &cb_params); +} + +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +tBTM_STATUS BTM_BleBigCreate(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, + uint32_t sdu_interval, uint16_t max_sdu, uint16_t max_transport_latency, + uint8_t rtn, uint8_t phy, uint8_t packing, uint8_t framing, + uint8_t encryption, uint8_t *broadcast_code) +{ + BTM_TRACE_API("big_handle %d adv_handle %d num_bis %d sdu_interval %d max_sdu %d max_transport_latency %d \ + rtn %d phy %d packing %d framing %d encryption %d broadcast_code %d", big_handle, adv_handle, num_bis, sdu_interval, max_sdu, max_transport_latency,\ + rtn, phy, packing, framing, encryption, broadcast_code); + + btsnd_hcic_ble_big_create(big_handle, adv_handle, num_bis, sdu_interval, max_sdu, max_transport_latency, + rtn, phy, packing, framing, encryption, broadcast_code); + + + return BTM_SUCCESS; +} + +tBTM_STATUS BTM_BleBigCreateTest(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, + uint32_t sdu_interval, uint16_t iso_interval, uint8_t nse, + uint16_t max_sdu, uint16_t max_pdu, uint8_t phy, + uint8_t packing, uint8_t framing, uint8_t bn, uint8_t irc, + uint8_t pto, uint8_t encryption, uint8_t *broadcast_code) +{ + btsnd_hcic_ble_big_create_test(big_handle, adv_handle, num_bis, sdu_interval, iso_interval, nse, + max_sdu, max_pdu, phy, packing, framing, bn, irc, pto, encryption, + broadcast_code); + return BTM_SUCCESS; +} + +tBTM_STATUS BTM_BleBigTerminate(UINT8 big_handle, UINT8 reason) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_big_terminate(big_handle, reason)) != TRUE) { + BTM_TRACE_ERROR("LE PA SyncCancel, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + if (status != BTM_SUCCESS) { + cb_params.status = status; + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_TERMINATE_COMPLETE_EVT, &cb_params); + } + + return status; +} +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) + +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +tBTM_STATUS BTM_BleBigSyncCreate(uint8_t big_handle, uint16_t sync_handle, + uint8_t encryption, uint8_t *bc_code, + uint8_t mse, uint16_t big_sync_timeout, + uint8_t num_bis, uint8_t *bis) +{ + btsnd_hcic_ble_big_sync_create(big_handle, sync_handle, encryption, bc_code, + mse, big_sync_timeout, num_bis, bis); + return BTM_SUCCESS; +} + +tBTM_STATUS BTM_BleBigSyncTerminate(uint8_t big_handle) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + + if ((err = btsnd_hcic_ble_big_sync_terminate(big_handle)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("LE big sync terminate, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + return status; +} +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) + +tBTM_STATUS BTM_BleIsoSetDataPath(uint16_t conn_handle, uint8_t data_path_dir, uint8_t data_path_id, uint8_t coding_fmt, + uint16_t company_id, uint16_t vs_codec_id, uint32_t controller_delay, uint8_t codec_len, + uint8_t *codec_cfg) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + + if (codec_len && (codec_cfg == NULL)) { + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + status = BTM_ILLEGAL_VALUE; + cb_params.btm_data_path_update.op_type = BTM_BLE_ISO_DATA_PATH_SETUP; + cb_params.status = status; + cb_params.btm_data_path_update.conn_hdl = conn_handle; + BTM_TRACE_ERROR("codec_cfg is NULL, set data path error"); + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_DATA_PATH_UPFATE_EVT, &cb_params); + return status; + } + + BTM_TRACE_DEBUG("BTM_BleIsoSetDataPath conn_handle %d data_path_dir %d\n", conn_handle, data_path_dir); + + if ((err = btsnd_hcic_ble_iso_set_data_path(conn_handle, data_path_dir, data_path_id, coding_fmt, company_id, vs_codec_id, + controller_delay, codec_len, codec_cfg)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("iso data path update, cmd err=0x%x", err); + return BTM_HCI_ERROR | err; + } + + return status; +} + +tBTM_STATUS BTM_BleIsoRemoveDataPath(uint16_t conn_handle, uint8_t data_path_dir) +{ + tHCI_STATUS err = HCI_SUCCESS; + + BTM_TRACE_DEBUG("BTM_BleIsoRemoveDataPath conn_handle %d data_path_dir %d\n", conn_handle, data_path_dir); + + if ((err = btsnd_hcic_ble_iso_remove_data_path(conn_handle, data_path_dir)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("iso data path remove, cmd err=0x%x", err); + return BTM_HCI_ERROR | err; + } + + return BTM_SUCCESS; +} + +tBTM_STATUS BTM_BleIsoReadTxSync(uint16_t iso_hdl) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + + BTM_TRACE_DEBUG("BTM_BleIsoReadTxSync iso_hdl %d\n", iso_hdl); + + if ((err = btsnd_hcic_ble_iso_read_tx_sync(iso_hdl)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("iso read tx sync, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + return status; +} + +tBTM_STATUS BTM_BleIsoReadLinkQuality(uint16_t iso_hdl) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + + BTM_TRACE_DEBUG("BTM_BleIsoReadLinkQuality iso_hdl %d\n", iso_hdl); + + if ((err = btsnd_hcic_ble_iso_read_iso_link_quality(iso_hdl)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("iso read link quality, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + return status; +} + +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +tBTM_STATUS BTM_BleSetCigParams(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t worse_case_SCA, uint8_t packing, + uint8_t framing, uint16_t mtl_c_to_p, uint16_t mtl_p_to_c, uint8_t cis_cnt, uint8_t *cis_params) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + + if ((err = btsnd_hcic_ble_iso_set_cig_params(cig_id, sdu_int_c_to_p, sdu_int_p_to_c, worse_case_SCA, packing, + framing, mtl_c_to_p, mtl_p_to_c, cis_cnt, (struct ble_hci_le_cis_params *)cis_params)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("iso set cig params, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + return status; +} + +tBTM_STATUS BTM_BleSetCigParamsTest(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t ft_c_to_p, uint8_t ft_p_to_c, uint16_t iso_interval, + uint8_t worse_case_SCA, uint8_t packing, uint8_t framing, uint8_t cis_cnt, uint8_t *cis_params) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + + if ((err = btsnd_hcic_ble_iso_set_cig_params_test(cig_id, sdu_int_c_to_p, sdu_int_p_to_c,ft_c_to_p, ft_p_to_c, iso_interval, + worse_case_SCA, packing, framing, cis_cnt, (struct ble_hci_le_cis_params_test *)cis_params)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("iso set cig params test, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + return status; +} + +void btm_ble_create_cis_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params) +{ + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_CREATE_CIS_EVT, cb_params); +} + +tBTM_STATUS BTM_BleCreateCis(uint8_t cis_count, uint8_t *cis_hdls) +{ + btsnd_hcic_ble_iso_create_cis(cis_count, (struct ble_hci_cis_hdls *)cis_hdls); + + return BTM_SUCCESS; +} + +tBTM_STATUS BTM_BleRemoveCig(uint8_t cig_id) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_iso_remove_cig(cig_id)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("iso remove cig, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.btm_remove_cig.status = status; + cb_params.btm_remove_cig.cig_id = cig_id; + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_REMOVE_CIG_EVT, &cb_params); + + return status; +} +#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +void btm_ble_accept_cis_req_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params) +{ + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_ACCEPT_CIS_REQ_EVT, cb_params); +} + +tBTM_STATUS BTM_BleAcceptCisReq(uint16_t cis_handle) +{ + btsnd_hcic_ble_iso_accept_cis_req(cis_handle); + return BTM_SUCCESS; +} + +tBTM_STATUS BTM_BleRejectCisReq(uint16_t cis_handle, uint8_t reason) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_iso_reject_cis_req(cis_handle, reason)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("iso reject cis req, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.btm_reject_cis_req.status = status; + cb_params.btm_reject_cis_req.cis_handle = cis_handle; + BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_REJECT_CIS_REQ_EVT, &cb_params); + return status; +} +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_EN == TRUE) +tBTM_STATUS BTM_BleDisconCis(uint16_t cis_handle, uint8_t reason) +{ + btsnd_hcic_disconnect(cis_handle, reason); + + return BTM_SUCCESS; +} +#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c index bc300b02..31d60546 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c @@ -22,6 +22,8 @@ #include "device/controller.h" #if (BLE_INCLUDED == TRUE) + +#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) #include "stack/bt_types.h" #include "stack/hcimsgs.h" #include "stack/btu.h" @@ -218,25 +220,7 @@ tBTM_STATUS btm_ble_enable_multi_adv (BOOLEAN enable, UINT8 inst_id, UINT8 cb_ev } return rt; } -/******************************************************************************* -** -** Function btm_ble_map_adv_tx_power -** -** Description return the actual power in dBm based on the mapping in config file -** -** Parameters advertise parameters used for this instance. -** -** Returns tx power in dBm -** -*******************************************************************************/ -static const int btm_ble_tx_power[BTM_BLE_ADV_TX_POWER_MAX + 1] = BTM_BLE_ADV_TX_POWER; -char btm_ble_map_adv_tx_power(int tx_power_index) -{ - if (0 <= tx_power_index && tx_power_index <= BTM_BLE_ADV_TX_POWER_MAX) { - return (char)btm_ble_tx_power[tx_power_index]; - } - return 0; -} + /******************************************************************************* ** ** Function btm_ble_multi_adv_set_params @@ -882,4 +866,5 @@ void *btm_ble_multi_adv_get_ref(UINT8 inst_id) return NULL; } +#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) #endif diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_privacy.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_privacy.c index be4b9d15..28e06658 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_ble_privacy.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_privacy.c @@ -330,7 +330,7 @@ void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len) BTM_TRACE_DEBUG("%s status = %d", __func__, status); if (!btm_ble_deq_resolving_pending(pseudo_bda)) { - BTM_TRACE_ERROR("%s no pending resolving list operation", __func__); + BTM_TRACE_DEBUG("%s no pending resolving list operation", __func__); return; } @@ -683,20 +683,22 @@ BOOLEAN btm_ble_suspend_resolving_list_activity(void) p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE; +#if (BLE_42_ADV_EN == TRUE) if (p_ble_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE) { btm_ble_stop_adv(); p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV; } +#endif // #if (BLE_42_ADV_EN == TRUE) if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) { btm_ble_stop_scan(); p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN; } - +#if (tGATT_BG_CONN_DEV == TRUE) if (btm_ble_suspend_bg_conn()) { p_ble_cb->suspended_rl_state |= BTM_BLE_RL_INIT; } - +#endif // #if (tGATT_BG_CONN_DEV == TRUE) return TRUE; } @@ -714,19 +716,21 @@ BOOLEAN btm_ble_suspend_resolving_list_activity(void) void btm_ble_resume_resolving_list_activity(void) { tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb; - +#if (BLE_42_ADV_EN == TRUE) if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_ADV) { btm_ble_start_adv(); } - +#endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_42_SCAN_EN == TRUE) if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_SCAN) { btm_ble_start_scan(); } - +#endif // #if (BLE_42_SCAN_EN == TRUE) +#if (tGATT_BG_CONN_DEV == TRUE) if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT) { btm_ble_resume_bg_conn(); } - +#endif // #if (tGATT_BG_CONN_DEV == TRUE) p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE; } @@ -1147,6 +1151,9 @@ void btm_ble_add_default_entry_to_resolving_list(void) BD_ADDR peer_addr = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; BT_OCTET16 peer_irk = {0x0}; + // Remove the existing entry in resolving list When resetting the device identity + btsnd_hcic_ble_rm_device_resolving_list(BLE_ADDR_PUBLIC, peer_addr); + btsnd_hcic_ble_add_device_resolving_list (BLE_ADDR_PUBLIC, peer_addr, peer_irk, btm_cb.devcb.id_keys.irk); } #endif diff --git a/lib/bt/host/bluedroid/stack/btm/btm_dev.c b/lib/bt/host/bluedroid/stack/btm/btm_dev.c index f9e3ed2b..f705a8dc 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_dev.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_dev.c @@ -179,20 +179,33 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, *******************************************************************************/ BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr, tBT_TRANSPORT transport) { - tBTM_SEC_DEV_REC *p_dev_rec; if (BTM_IsAclConnectionUp(bd_addr, transport)) { BTM_TRACE_WARNING("%s FAILED: Cannot Delete when connection is active\n", __func__); return FALSE; } + if ((p_dev_rec = btm_find_dev(bd_addr)) != NULL) { +#if (CLASSIC_BT_INCLUDED == TRUE) /* Tell controller to get rid of the link key, if it has one stored */ BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL); +#endif // (CLASSIC_BT_INCLUDED == TRUE) - btm_sec_free_dev(p_dev_rec, transport); + btm_sec_free_dev(p_dev_rec, transport); } +#if (BLE_SMP_ID_RESET_ENABLE == TRUE) + /* + * There are tracking risks associated with using a fixed or static IRK. + * A best-practices approach, when all pairing and bonding records are deleted, + * assign a new randomly-generated IRK. + */ + if (list_is_empty(btm_cb.p_sec_dev_rec_list)) { + btm_ble_reset_id(); + } +#endif + return TRUE; } @@ -640,7 +653,7 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) tBTM_SEC_DEV_REC *p_dev_rec = NULL; tBTM_SEC_DEV_REC *p_oldest = NULL; list_node_t *p_node = NULL; - UINT32 ot = 0xFFFFFFFF; + UINT32 old_ts = 0xFFFFFFFF; /* First look for the non-paired devices for the oldest entry */ for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { @@ -650,13 +663,13 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) continue; /* Device is paired so skip it */ } - if (p_dev_rec->timestamp < ot) { + if (p_dev_rec->timestamp < old_ts) { p_oldest = p_dev_rec; - ot = p_dev_rec->timestamp; + old_ts = p_dev_rec->timestamp; } } - if (ot != 0xFFFFFFFF) { + if (old_ts != 0xFFFFFFFF) { return (p_oldest); } @@ -666,9 +679,9 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) continue; } - if (p_dev_rec->timestamp < ot) { + if (p_dev_rec->timestamp < old_ts) { p_oldest = p_dev_rec; - ot = p_dev_rec->timestamp; + old_ts = p_dev_rec->timestamp; } } return (p_oldest); diff --git a/lib/bt/host/bluedroid/stack/btm/btm_devctl.c b/lib/bt/host/bluedroid/stack/btm/btm_devctl.c index bab88739..2250c78b 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -82,7 +82,9 @@ void btm_dev_init (void) /* Initialize nonzero defaults */ #if (BTM_MAX_LOC_BD_NAME_LEN > 0) memset(btm_cb.cfg.ble_bd_name, 0, sizeof(tBTM_LOC_BD_NAME)); +#if (CLASSIC_BT_INCLUDED == TRUE) memset(btm_cb.cfg.bredr_bd_name, 0, sizeof(tBTM_LOC_BD_NAME)); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #endif btm_cb.devcb.reset_timer.param = (TIMER_PARAM_TYPE)TT_DEV_RESET; @@ -169,8 +171,12 @@ static void reset_complete(void) btm_cb.ble_ctr_cb.conn_state = BLE_CONN_IDLE; btm_cb.ble_ctr_cb.bg_conn_type = BTM_BLE_CONN_NONE; btm_cb.ble_ctr_cb.p_select_cback = NULL; +#if (tGATT_BG_CONN_DEV == TRUE) gatt_reset_bgdev_list(); +#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) btm_ble_multi_adv_init(); +#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) #endif btm_pm_reset(); @@ -193,6 +199,9 @@ static void reset_complete(void) if (controller->supports_ble()) { btm_ble_white_list_init(controller->get_ble_white_list_size()); + #if (BLE_50_EXTEND_SYNC_EN == TRUE) + btm_ble_periodic_adv_list_init(controller->get_ble_periodic_adv_list_size()); + #endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE) l2c_link_processs_ble_num_bufs(controller->get_acl_buffer_count_ble()); } #endif @@ -471,7 +480,7 @@ tBTM_STATUS BTM_SetLocalDeviceName (char *p_name, tBT_DEVICE_TYPE name_type) btm_cb.cfg.ble_bd_name[BTM_MAX_LOC_BD_NAME_LEN] = '\0'; } } - +#if (CLASSIC_BT_INCLUDED == TRUE) if (name_type & BT_DEVICE_TYPE_BREDR) { p = (UINT8 *)btm_cb.cfg.bredr_bd_name; if (p != (UINT8 *)p_name) { @@ -479,6 +488,7 @@ tBTM_STATUS BTM_SetLocalDeviceName (char *p_name, tBT_DEVICE_TYPE name_type) btm_cb.cfg.bredr_bd_name[BTM_MAX_LOC_BD_NAME_LEN] = '\0'; } } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #else p = (UINT8 *)p_name; #endif @@ -519,21 +529,22 @@ tBTM_STATUS BTM_ReadLocalDeviceName (char **p_name, tBT_DEVICE_TYPE name_type) */ #if BTM_MAX_LOC_BD_NAME_LEN > 0 +#if (CLASSIC_BT_INCLUDED == TRUE) if ((name_type == BT_DEVICE_TYPE_DUMO) && (BCM_STRNCMP_S(btm_cb.cfg.bredr_bd_name, btm_cb.cfg.ble_bd_name, BTM_MAX_LOC_BD_NAME_LEN) != 0)) { *p_name = NULL; BTM_TRACE_ERROR("Error, BLE and BREDR have different names, return NULL\n"); return (BTM_NO_RESOURCES); } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) if (name_type & BT_DEVICE_TYPE_BLE) { *p_name = btm_cb.cfg.ble_bd_name; } - +#if (CLASSIC_BT_INCLUDED == TRUE) if (name_type & BT_DEVICE_TYPE_BREDR) { *p_name = btm_cb.cfg.bredr_bd_name; } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) return (BTM_SUCCESS); #else *p_name = NULL; @@ -752,9 +763,6 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len, #if (BLE_INCLUDED == TRUE) tBTM_BLE_CB *ble_cb = &btm_cb.ble_ctr_cb; switch(opcode) { - case HCI_VENDOR_BLE_LONG_ADV_DATA: - BTM_TRACE_EVENT("Set long adv data complete\n"); - break; case HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST: { uint8_t subcode, status; uint32_t length; STREAM_TO_UINT8(status, p); @@ -773,6 +781,22 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len, } break; } + case HCI_VENDOR_BLE_SET_CSA_SUPPORT: { + uint8_t status; + STREAM_TO_UINT8(status, p); + if (ble_cb && ble_cb->set_csa_support_cmpl_cb) { + ble_cb->set_csa_support_cmpl_cb(status); + } + break; + } + case HCI_VENDOR_BLE_SET_EVT_MASK: { + uint8_t status; + STREAM_TO_UINT8(status, p); + if (ble_cb && ble_cb->set_vendor_evt_mask_cmpl_cb) { + ble_cb->set_vendor_evt_mask_cmpl_cb(status); + } + break; + } default: break; } @@ -863,7 +887,7 @@ void btm_vendor_specific_evt (UINT8 *p, UINT8 evt_len) STREAM_TO_UINT8(sub_event, p_evt); /* Check in subevent if authentication is through Legacy Authentication. */ - if (sub_event == ESP_VS_REM_LEGACY_AUTH_CMP) { + if (sub_event == HCI_VENDOR_LEGACY_REM_AUTH_EVT_SUBCODE) { UINT16 hci_handle; STREAM_TO_UINT16(hci_handle, p_evt); btm_sec_handle_remote_legacy_auth_cmp(hci_handle); @@ -1066,6 +1090,7 @@ tBTM_STATUS BTM_WriteVoiceSettings(UINT16 settings) return (BTM_NO_RESOURCES); } +#if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) /******************************************************************************* ** ** Function BTM_EnableTestMode @@ -1122,7 +1147,9 @@ tBTM_STATUS BTM_EnableTestMode(void) return (BTM_NO_RESOURCES); } } +#endif // #if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function BTM_DeleteStoredLinkKey @@ -1197,6 +1224,7 @@ void btm_delete_stored_link_key_complete (UINT8 *p) } } +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btm_report_device_status diff --git a/lib/bt/host/bluedroid/stack/btm/btm_inq.c b/lib/bt/host/bluedroid/stack/btm/btm_inq.c index b8da2327..528c7a06 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_inq.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_inq.c @@ -163,7 +163,7 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter UINT8 scan_mode = 0; UINT16 service_class; UINT8 *p_cod; - UINT8 major, minor; + UINT8 major, minor, reserved_2; DEV_CLASS cod; LAP temp_lap[2]; BOOLEAN is_limited; @@ -255,13 +255,14 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter if (is_limited ^ cod_limited) { BTM_COD_MINOR_CLASS(minor, p_cod ); BTM_COD_MAJOR_CLASS(major, p_cod ); + BTM_COD_RESERVED_2(reserved_2, p_cod); if (is_limited) { service_class |= BTM_COD_SERVICE_LMTD_DISCOVER; } else { service_class &= ~BTM_COD_SERVICE_LMTD_DISCOVER; } - FIELDS_TO_COD(cod, minor, major, service_class); + FIELDS_TO_COD(cod, reserved_2, minor, major, service_class); (void) BTM_SetDeviceClass (cod); } @@ -515,7 +516,7 @@ tBTM_STATUS BTM_SetPeriodicInquiryMode (tBTM_INQ_PARMS *p_inqparms, UINT16 max_d /* Before beginning the inquiry the current filter must be cleared, so initiate the command */ if ((status = btm_set_inq_event_filter (p_inqparms->filter_cond_type, &p_inqparms->filter_cond)) != BTM_CMD_STARTED) { - /* If set filter command is not succesful reset the state */ + /* If set filter command is not successful reset the state */ p_inq->p_inq_results_cb = NULL; p_inq->state = BTM_INQ_INACTIVE_STATE; @@ -688,7 +689,7 @@ UINT16 BTM_ReadConnectability (UINT16 *p_window, UINT16 *p_interval) ** Description This function returns a bit mask of the current inquiry state ** ** Returns BTM_INQUIRY_INACTIVE if inactive (0) -** BTM_LIMITED_INQUIRY_ACTIVE if a limted inquiry is active +** BTM_LIMITED_INQUIRY_ACTIVE if a limited inquiry is active ** BTM_GENERAL_INQUIRY_ACTIVE if a general inquiry is active ** BTM_PERIODIC_INQUIRY_ACTIVE if a periodic inquiry is active ** @@ -783,7 +784,7 @@ tBTM_STATUS BTM_CancelInquiry(void) ** Description This function is called to start an inquiry. ** ** Parameters: p_inqparms - pointer to the inquiry information -** mode - GENERAL or LIMITED inquiry, BR/LE bit mask seperately +** mode - GENERAL or LIMITED inquiry, BR/LE bit mask separately ** duration - length in 1.28 sec intervals (If '0', the inquiry is CANCELLED) ** max_resps - maximum amount of devices to search for before ending the inquiry ** filter_cond_type - BTM_CLR_INQUIRY_FILTER, BTM_FILTER_COND_DEVICE_CLASS, or @@ -1858,7 +1859,7 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode) #if BLE_INCLUDED == TRUE /* new device response */ && ( p_i == NULL || - /* exisiting device with BR/EDR info */ + /* existing device with BR/EDR info */ (p_i && (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0) ) #endif diff --git a/lib/bt/host/bluedroid/stack/btm/btm_main.c b/lib/bt/host/bluedroid/stack/btm/btm_main.c index 8e49aa3e..67882af0 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_main.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_main.c @@ -39,7 +39,9 @@ tBTM_CB *btm_cb_ptr; #if (BLE_50_FEATURE_SUPPORT == TRUE) extern void btm_ble_extendadvcb_init(void); +#if (BLE_50_EXTEND_ADV_EN == TRUE) extern void btm_ble_advrecod_init(void); +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) #endif @@ -84,11 +86,14 @@ void btm_init (void) #if BLE_INCLUDED == TRUE btm_ble_lock_init(); btm_ble_sem_init(); + btm_cb.addr_res_en = TRUE; #endif btm_sec_dev_init(); #if (BLE_50_FEATURE_SUPPORT == TRUE) btm_ble_extendadvcb_init(); +#if (BLE_50_EXTEND_ADV_EN == TRUE) btm_ble_advrecod_init(); +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) #endif } @@ -109,6 +114,9 @@ void btm_free(void) fixed_queue_free(btm_cb.sec_pending_q, osi_free_func); btm_acl_free(); btm_sec_dev_free(); +#if BTM_SCO_INCLUDED == TRUE + btm_sco_free(); +#endif #if BTM_DYNAMIC_MEMORY FREE_AND_RESET(btm_cb_ptr); #endif @@ -118,7 +126,8 @@ void btm_free(void) #endif } -uint8_t btm_acl_active_count(void) +#if (BLE_INCLUDED == TRUE) +uint8_t btm_ble_acl_active_count(void) { list_node_t *p_node = NULL; tACL_CONN *p_acl_conn = NULL; @@ -126,10 +135,23 @@ uint8_t btm_acl_active_count(void) for (p_node = list_begin(btm_cb.p_acl_db_list); p_node; p_node = list_next(p_node)) { p_acl_conn = list_node(p_node); - if (p_acl_conn && p_acl_conn->in_use) { + if (p_acl_conn && p_acl_conn->in_use && p_acl_conn->transport == BT_TRANSPORT_LE) { count++; } } return count; } + +// Address resolution status +uint8_t btm_get_ble_addr_resolve_disable_status(void) +{ + // Returns false if address resolution is enabled, true if disabled + return (btm_cb.addr_res_en) ? 0 : 1; +} + +void btm_ble_addr_resolve_enable(bool enable) +{ + btm_cb.addr_res_en = enable; +} +#endif /*BLE_INCLUDED*/ diff --git a/lib/bt/host/bluedroid/stack/btm/btm_pm.c b/lib/bt/host/bluedroid/stack/btm/btm_pm.c index 4c52348e..1c46a744 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_pm.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_pm.c @@ -543,7 +543,7 @@ static tBTM_PM_MODE btm_pm_get_set_mode(UINT8 pm_id, tBTM_PM_MCB *p_cb, tBTM_PM_ ** Function btm_pm_snd_md_req ** Description get the resulting mode and send the resuest to host controller ** Returns tBTM_STATUS -**, BOOLEAN *p_chg_ind +** *******************************************************************************/ static tBTM_STATUS btm_pm_snd_md_req(UINT8 pm_id, UINT16 link_hdl, tBTM_PM_PWR_MD *p_mode) { @@ -565,6 +565,8 @@ static tBTM_STATUS btm_pm_snd_md_req(UINT8 pm_id, UINT16 link_hdl, tBTM_PM_PWR_M /* already in the resulting mode */ if ( (mode == BTM_PM_MD_ACTIVE) || ((md_res.max >= p_cb->interval) && (md_res.min <= p_cb->interval)) ) { + // Clear request change indication because already in result mode + p_cb->chg_ind = FALSE; return BTM_CMD_STORED; } /* Otherwise, needs to wake, then sleep */ @@ -689,7 +691,7 @@ static void btm_pm_check_stored(void) ** Description This function is called when an HCI command status event occurs ** for power manager related commands. ** -** Input Parms status - status of the event (HCI_SUCCESS if no errors) +** Input Params status - status of the event (HCI_SUCCESS if no errors) ** ** Returns none. ** @@ -717,7 +719,7 @@ void btm_pm_proc_cmd_status(UINT8 status) #if BTM_PM_DEBUG == TRUE BTM_TRACE_DEBUG( "btm_pm_proc_cmd_status new state:0x%x", p_cb->state); #endif // BTM_PM_DEBUG - } else { /* the command was not successfull. Stay in the same state */ + } else { /* the command was not successful. Stay in the same state */ pm_status = BTM_PM_STS_ERROR; } @@ -743,7 +745,7 @@ void btm_pm_proc_cmd_status(UINT8 status) ** ** Description This function is called when an HCI mode change event occurs. ** -** Input Parms hci_status - status of the event (HCI_SUCCESS if no errors) +** Input Params hci_status - status of the event (HCI_SUCCESS if no errors) ** hci_handle - connection handle associated with the change ** mode - HCI_MODE_ACTIVE, HCI_MODE_HOLD, HCI_MODE_SNIFF, or HCI_MODE_PARK ** interval - number of baseband slots (meaning depends on mode) diff --git a/lib/bt/host/bluedroid/stack/btm/btm_sco.c b/lib/bt/host/bluedroid/stack/btm/btm_sco.c index 53a9768a..69640280 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_sco.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_sco.c @@ -117,14 +117,28 @@ void btm_sco_init (void) } #endif /* Initialize nonzero defaults */ - btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON; - btm_cb.sco_cb.def_esco_parms = btm_esco_defaults; /* Initialize with defaults */ btm_cb.sco_cb.desired_sco_mode = BTM_DEFAULT_SCO_MODE; } /******************************************************************************* ** +** Function btm_sco_free +** +** Description Free sco specific fixed_queue from btm control block +** +*******************************************************************************/ +void btm_sco_free(void) +{ +#if (BTM_SCO_HCI_INCLUDED == TRUE) + for (int i = 0; i < BTM_MAX_SCO_LINKS; i++) { + fixed_queue_free(btm_cb.sco_cb.sco_db[i].xmit_data_q, osi_free_func); + } +#endif +} + +/******************************************************************************* +** ** Function btm_esco_conn_rsp ** ** Description This function is called upon receipt of an (e)SCO connection @@ -233,7 +247,7 @@ void btm_sco_process_num_bufs (UINT16 num_lm_sco_bufs) ** pointer is used, PCM parameter maintained in ** the control block will be used; otherwise update ** control block value. -** err_data_rpt: Lisbon feature to enable the erronous data report +** err_data_rpt: Lisbon feature to enable the erroneous data report ** or not. ** ** Returns BTM_SUCCESS if the successful. @@ -598,12 +612,12 @@ static tBTM_STATUS btm_send_connect_request(UINT16 acl_handle, ** If so, we cannot use SCO-only packet types (HFP 1.7) */ if (BTM_BothEndsSupportSecureConnections(p_acl->remote_addr)) { - temp_pkt_types &= ~(BTM_SCO_PKT_TYPE_MASK); + temp_pkt_types &= ~(BTM_SCO_LINK_ONLY_MASK); BTM_TRACE_DEBUG("%s: SCO Conn: pkt_types after removing SCO (0x%04x)", __FUNCTION__, temp_pkt_types); /* Return error if no packet types left */ - if (temp_pkt_types == 0) { + if (temp_pkt_types == BTM_SCO_EXCEPTION_PKTS_MASK) { BTM_TRACE_ERROR("%s: SCO Conn (BR/EDR SC): No packet types available",__FUNCTION__); return (BTM_WRONG_MODE); } @@ -947,7 +961,7 @@ void btm_sco_conn_req (BD_ADDR bda, DEV_CLASS dev_class, UINT8 link_type) for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) { /* * If the sco state is in the SCO_ST_CONNECTING state, we still need - * to return accept sco to avoid race conditon for sco creation + * to return accept sco to avoid race condition for sco creation */ int rem_bd_matches = p->rem_bd_known && !memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN); @@ -1032,7 +1046,6 @@ void btm_sco_connected (UINT8 hci_status, BD_ADDR bda, UINT16 hci_handle, tBTM_CHG_ESCO_PARAMS parms; #endif - btm_cb.sco_cb.sco_disc_reason = hci_status; BTM_TRACE_API("%s, handle %x", __FUNCTION__, hci_handle); #if (BTM_MAX_SCO_LINKS>0) for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) { @@ -1203,21 +1216,16 @@ void btm_remove_sco_links (BD_ADDR bda) ** Returns void ** *******************************************************************************/ -void btm_sco_removed (UINT16 hci_handle, UINT8 reason) +BOOLEAN btm_sco_removed (UINT16 hci_handle, UINT8 reason) { #if (BTM_MAX_SCO_LINKS>0) tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; UINT16 xx; -#endif - - btm_cb.sco_cb.sco_disc_reason = reason; -#if (BTM_MAX_SCO_LINKS>0) p = &btm_cb.sco_cb.sco_db[0]; for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) { if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) && (p->hci_handle == hci_handle)) { btm_sco_flush_sco_data(xx); - p->state = SCO_ST_UNUSED; #if BTM_SCO_HCI_INCLUDED == TRUE btm_cb.sco_cb.xmit_window_size += p->sent_not_acked; @@ -1232,10 +1240,11 @@ void btm_sco_removed (UINT16 hci_handle, UINT8 reason) p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */ (*p->p_disc_cb)(xx); - return; + return TRUE; } } #endif + return FALSE; } @@ -1361,24 +1370,6 @@ UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx) /******************************************************************************* ** -** Function BTM_ReadScoDiscReason -** -** Description This function is returns the reason why an (e)SCO connection -** has been removed. It contains the value until read, or until -** another (e)SCO connection has disconnected. -** -** Returns HCI reason or BTM_INVALID_SCO_DISC_REASON if not set. -** -*******************************************************************************/ -UINT16 BTM_ReadScoDiscReason (void) -{ - UINT16 res = btm_cb.sco_cb.sco_disc_reason; - btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON; - return (res); -} - -/******************************************************************************* -** ** Function BTM_ReadDeviceScoPacketTypes ** ** Description This function is read the SCO packet types that @@ -1878,10 +1869,6 @@ UINT8 *BTM_ReadScoBdAddr(UINT16 sco_inx) { return ((UINT8 *) NULL); } -UINT16 BTM_ReadScoDiscReason (void) -{ - return (BTM_INVALID_SCO_DISC_REASON); -} tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms) { return (BTM_MODE_UNSUPPORTED); diff --git a/lib/bt/host/bluedroid/stack/btm/btm_sec.c b/lib/bt/host/bluedroid/stack/btm/btm_sec.c index ca5f99e1..3ed5d4b1 100644 --- a/lib/bt/host/bluedroid/stack/btm/btm_sec.c +++ b/lib/bt/host/bluedroid/stack/btm/btm_sec.c @@ -1001,12 +1001,12 @@ tBTM_STATUS btm_sec_bond_by_transport (BD_ADDR bd_addr, tBT_TRANSPORT transport, return (BTM_SUCCESS); } +#if (CLASSIC_BT_INCLUDED == TRUE) /* Tell controller to get rid of the link key if it has one stored */ if ((BTM_DeleteStoredLinkKey (bd_addr, NULL)) != BTM_SUCCESS) { return (BTM_NO_RESOURCES); } -#if (CLASSIC_BT_INCLUDED == TRUE) /* Save the PIN code if we got a valid one */ if (p_pin && (pin_len <= PIN_CODE_LEN) && (pin_len != 0)) { btm_cb.pin_code_len = pin_len; @@ -1720,7 +1720,7 @@ void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr, BT_OCTET16 c, BT_O btsnd_hcic_rem_oob_reply (bd_addr, c, r); } } - +#if 0 /******************************************************************************* ** ** Function BTM_BuildOobData @@ -1745,8 +1745,10 @@ UINT16 BTM_BuildOobData(UINT8 *p_data, UINT16 max_len, BT_OCTET16 c, UINT8 *p = p_data; UINT16 len = 0; #if BTM_MAX_LOC_BD_NAME_LEN > 0 +#if (CLASSIC_BT_INCLUDED == TRUE) UINT16 name_size; UINT8 name_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #endif if (p_data && max_len >= BTM_OOB_MANDATORY_SIZE) { @@ -1789,6 +1791,7 @@ UINT16 BTM_BuildOobData(UINT8 *p_data, UINT16 max_len, BT_OCTET16 c, max_len -= delta; } #if BTM_MAX_LOC_BD_NAME_LEN > 0 +#if (CLASSIC_BT_INCLUDED == TRUE) name_size = name_len; if (name_size > strlen(btm_cb.cfg.bredr_bd_name)) { name_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE; @@ -1802,6 +1805,7 @@ UINT16 BTM_BuildOobData(UINT8 *p_data, UINT16 max_len, BT_OCTET16 c, len += delta; max_len -= delta; } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #endif /* update len */ p = p_data; @@ -1871,6 +1875,7 @@ UINT8 *BTM_ReadOobData(UINT8 *p_data, UINT8 eir_tag, UINT8 *p_len) return p_ret; } +#endif #endif ///BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE #if (CLASSIC_BT_INCLUDED == TRUE) @@ -4589,10 +4594,10 @@ tBTM_STATUS btm_sec_disconnect (UINT16 handle, UINT8 reason) ** Description This function is when a connection to the peer device is ** dropped ** -** Returns void +** Returns tBTM_SEC_DEV_REC is not NULL ** *******************************************************************************/ -void btm_sec_disconnected (UINT16 handle, UINT8 reason) +BOOLEAN btm_sec_disconnected (UINT16 handle, UINT8 reason) { tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle); UINT8 old_pairing_flags = btm_cb.pairing_flags; @@ -4608,7 +4613,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason) #endif if (!p_dev_rec) { - return; + return FALSE; } p_dev_rec->enc_init_by_we = FALSE; transport = (handle == p_dev_rec->hci_handle) ? BT_TRANSPORT_BR_EDR : BT_TRANSPORT_LE; @@ -4649,7 +4654,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason) if (p_dev_rec->sec_state == BTM_SEC_STATE_DISCONNECTING_BOTH) { p_dev_rec->sec_state = (transport == BT_TRANSPORT_LE) ? BTM_SEC_STATE_DISCONNECTING : BTM_SEC_STATE_DISCONNECTING_BLE; - return; + return TRUE; } #endif p_dev_rec->sec_state = BTM_SEC_STATE_IDLE; @@ -4685,6 +4690,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason) p_dev_rec->sec_bd_name, result); } } + return TRUE; } /******************************************************************************* diff --git a/lib/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/lib/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 0f8888fb..de25c6fa 100644 --- a/lib/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/lib/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -212,11 +212,14 @@ typedef struct { #define BTM_BLE_MAX_BG_CONN_DEV_NUM 10 typedef struct { + UINT16 scan_interval; + UINT16 scan_window; UINT16 min_conn_int; UINT16 max_conn_int; UINT16 slave_latency; UINT16 supervision_tout; - + UINT16 min_ce_len; + UINT16 max_ce_len; } tBTM_LE_CONN_PRAMS; @@ -339,10 +342,10 @@ typedef struct { tBTM_INQ_RESULTS_CB *p_scan_results_cb; tBTM_CMPL_CB *p_scan_cmpl_cb; TIMER_LIST_ENT scan_timer_ent; - +#if (BLE_42_SCAN_EN == TRUE) struct pkt_queue *adv_rpt_queue; struct osi_event *adv_rpt_ready; - +#endif // #if (BLE_42_SCAN_EN == TRUE) /* background connection procedure cb value */ tBTM_BLE_CONN_TYPE bg_conn_type; UINT32 scan_int; @@ -350,6 +353,10 @@ typedef struct { tBTM_BLE_SEL_CBACK *p_select_cback; /* white list information */ UINT8 white_list_avail_size; +#if (BLE_50_EXTEND_SYNC_EN == TRUE) + /* periodic list information */ + UINT8 periodic_adv_list_size; +#endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE) tBTM_UPDATE_WHITELIST_CBACK *update_wl_cb; tBTM_BLE_WL_STATE wl_state; @@ -377,6 +384,8 @@ typedef struct { tBTM_BLE_STATE_MASK cur_states; /* bit mask of tBTM_BLE_STATE */ UINT8 link_count[2]; /* total link count master and slave*/ tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK *update_exceptional_list_cmp_cb; + tBTM_SET_CSA_SUPPORT_CMPL_CBACK *set_csa_support_cmpl_cb; + tBTM_SET_VENDOR_EVT_MASK_CBACK *set_vendor_evt_mask_cmpl_cb; } tBTM_BLE_CB; #ifdef __cplusplus @@ -384,12 +393,14 @@ extern "C" { #endif void btm_ble_timeout(TIMER_LIST_ENT *p_tle); +#if (BLE_42_SCAN_EN == TRUE) void btm_ble_process_adv_pkt (UINT8 *p); void btm_ble_process_adv_discard_evt(UINT8 *p); void btm_ble_process_direct_adv_pkt (UINT8 *p); bool btm_ble_adv_pkt_ready(void); bool btm_ble_adv_pkt_post(pkt_linked_item_t *pkt); void btm_ble_proc_scan_rsp_rpt (UINT8 *p); +#endif // #if (BLE_42_SCAN_EN == TRUE) tBTM_STATUS btm_ble_read_remote_name(BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur, tBTM_CMPL_CB *p_cb); BOOLEAN btm_ble_cancel_remote_name(BD_ADDR remote_bda); @@ -405,7 +416,11 @@ void btm_ble_init (void); void btm_ble_free (void); void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role, tBLE_ADDR_TYPE addr_type, BOOLEAN addr_matched); void btm_ble_read_remote_features_complete(UINT8 *p); + +#if (BLE_42_ADV_EN == TRUE) void btm_ble_write_adv_enable_complete(UINT8 *p); +#endif // #if (BLE_42_ADV_EN == TRUE) + void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced); void btm_read_ble_local_supported_states_complete(UINT8 *p, UINT16 evt_len); tBTM_BLE_CONN_ST btm_ble_get_conn_st(void); @@ -455,9 +470,12 @@ void btm_ble_remove_from_white_list_complete(UINT8 *p, UINT16 evt_len); void btm_ble_clear_white_list_complete(UINT8 *p, UINT16 evt_len); void btm_ble_white_list_init(UINT8 white_list_size); +#if (tGATT_BG_CONN_DEV == TRUE) /* background connection function */ BOOLEAN btm_ble_suspend_bg_conn(void); BOOLEAN btm_ble_resume_bg_conn(void); +#endif // #if (tGATT_BG_CONN_DEV == TRUE) + void btm_ble_initiate_select_conn(BD_ADDR bda); BOOLEAN btm_ble_start_auto_conn(BOOLEAN start); BOOLEAN btm_ble_start_select_conn(BOOLEAN start, tBTM_BLE_SEL_CBACK *p_select_cback); @@ -500,12 +518,14 @@ void btm_ble_add_default_entry_to_resolving_list(void); void btm_ble_set_privacy_mode_complete(UINT8 *p, UINT16 evt_len); #endif +#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst); void btm_ble_multi_adv_init(void); void *btm_ble_multi_adv_get_ref(UINT8 inst_id); void btm_ble_multi_adv_cleanup(void); void btm_ble_multi_adv_reenable(UINT8 inst_id); void btm_ble_multi_adv_enb_privacy(BOOLEAN enable); +#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) char btm_ble_map_adv_tx_power(int tx_power_index); void btm_ble_batchscan_init(void); void btm_ble_batchscan_cleanup(void); @@ -536,12 +556,57 @@ void btm_ble_channel_select_algorithm_evt(tBTM_BLE_CHANNEL_SEL_ALG *params); void btm_ble_periodic_adv_report_evt(tBTM_PERIOD_ADV_REPORT *params); void btm_ble_periodic_adv_sync_lost_evt(tBTM_BLE_PERIOD_ADV_SYNC_LOST *params); void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *params); +#if (BLE_50_EXTEND_SYNC_EN == TRUE) +void btm_ble_periodic_adv_list_init(UINT8 periodic_adv_size); +#endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) void btm_ble_periodic_adv_sync_trans_recv_evt(tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV *params); #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_EN == TRUE) +void btm_ble_cis_established_evt(tBTM_BLE_CIS_ESTABLISHED_CMPL *params); +void btm_ble_cis_disconnected_evt(tBTM_BLE_CIS_DISCON_CMPL *params); +#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) +void btm_ble_iso_read_iso_tx_sync_complete(UINT8 *p); +void btm_ble_iso_read_iso_link_quality_complete(UINT8 *p); +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +void btm_ble_cis_request_evt(tBTM_BLE_CIS_REQUEST_CMPL *params); +void btm_ble_accept_cis_req_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params); +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +void btm_ble_create_cis_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params); +void btm_ble_iso_set_cig_params_complete(UINT8 *p); +#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +void btm_ble_big_create_cmpl_evt(tBTM_BLE_BIG_CREATE_CMPL *param); +void btm_ble_big_terminate_cmpl_evt(tBTM_BLE_BIG_TERMINATE_CMPL *params); +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +void btm_ble_big_sync_estab_evt(tBTM_BLE_BIG_SYNC_ESTAB_CMPL *params); +void btm_ble_big_sync_lost_evt(tBTM_BLE_BIG_SYNC_LOST_EVT *params); +void btm_ble_biginfo_adv_report_evt(tBTM_BLE_BIGINFO_ADV_REPORT_EVT *params); +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +void btm_ble_iso_data_path_update_complete(UINT16 opcode, UINT8 hci_status, UINT16 conn_handle); +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +void btm_ble_cte_read_ant_infor_complete(UINT8 *p); +void btm_ble_connless_iq_report_evt(tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT *params); +void btm_ble_conn_iq_report_evt(tBTM_BLE_CTE_CONN_IQ_REPORT_EVT *params); +void btm_ble_cte_req_failed_evt(tBTM_BLE_CTE_REQ_FAILED_EVT *params); +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +void btm_ble_path_loss_threshold_evt(tBTM_BLE_PATH_LOSS_THRESHOLD_EVT *params); +void btm_ble_transmit_power_report_evt(tBTM_BLE_TRANS_POWER_REPORT_EVT *params); +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +#if (BLE_FEAT_CONN_SUBRATING == TRUE) +void btm_ble_subrate_change_evt(tBTM_BLE_SUBRATE_CHANGE_EVT *params); +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + /* #ifdef __cplusplus } diff --git a/lib/bt/host/bluedroid/stack/btm/include/btm_int.h b/lib/bt/host/bluedroid/stack/btm/include/btm_int.h index 3d01a5c2..d5b69c68 100644 --- a/lib/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/lib/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -43,13 +43,12 @@ typedef struct tBTM_SEC_DEV_REC tBTM_SEC_DEV_REC; #include "stack/smp_api.h" #endif -#define ESP_VS_REM_LEGACY_AUTH_CMP 0x03 - #if BTM_MAX_LOC_BD_NAME_LEN > 0 typedef char tBTM_LOC_BD_NAME[BTM_MAX_LOC_BD_NAME_LEN + 1]; #endif #define BTM_ACL_IS_CONNECTED(bda) (btm_bda_to_acl (bda, BT_TRANSPORT_BR_EDR) != NULL) +#define BTM_LE_ACL_IS_CONNECTED(bda) (btm_bda_to_acl (bda, BT_TRANSPORT_LE) != NULL) /* Definitions for Server Channel Number (SCN) management */ @@ -192,6 +191,10 @@ tBTM_CMPL_CB *p_rln_cmpl_cb; /* Callback function to be called when TIMER_LIST_ENT rssi_timer; tBTM_CMPL_CB *p_rssi_cmpl_cb; /* Callback function to be called when */ /* read rssi function completes */ + +tBTM_CMPL_CB *p_ble_ch_map_cmpl_cb; /* Callback function to be called when */ +/* read channel map function completes */ + TIMER_LIST_ENT lnk_quality_timer; tBTM_CMPL_CB *p_lnk_qual_cmpl_cb;/* Callback function to be called when */ /* read link quality function completes */ @@ -207,8 +210,10 @@ tBTM_ROLE_SWITCH_CMPL switch_role_ref_data; tBTM_CMPL_CB *p_switch_role_cb; /* Callback function to be called when */ /* requested switch role is completed */ +#if (BLE_HOST_READ_TX_POWER_EN == TRUE) TIMER_LIST_ENT tx_power_timer; tBTM_CMPL_CB *p_tx_power_cmpl_cb;/* Callback function to be called */ +#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) #if CLASSIC_BT_INCLUDED == TRUE TIMER_LIST_ENT afh_channels_timer; @@ -469,7 +474,6 @@ typedef struct { tSCO_CONN sco_db[BTM_MAX_SCO_LINKS]; tBTM_ESCO_PARAMS def_esco_parms; BD_ADDR xfer_addr; - UINT16 sco_disc_reason; BOOLEAN esco_supported; /* TRUE if 1.2 cntlr AND supports eSCO links */ tBTM_SCO_TYPE desired_sco_mode; tBTM_SCO_TYPE xfer_sco_type; @@ -724,14 +728,18 @@ struct tBTM_SEC_DEV_REC{ */ typedef struct { #if BTM_MAX_LOC_BD_NAME_LEN > 0 +#if (CLASSIC_BT_INCLUDED == TRUE) tBTM_LOC_BD_NAME bredr_bd_name; /* local BREDR device name */ +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) tBTM_LOC_BD_NAME ble_bd_name; /* local BLE device name */ #endif +#if (CLASSIC_BT_INCLUDED == TRUE) BOOLEAN pin_type; /* TRUE if PIN type is fixed */ UINT8 pin_code_len; /* Bonding information */ PIN_CODE pin_code; /* PIN CODE if pin type is fixed */ - BOOLEAN connectable; /* If TRUE page scan should be enabled */ - UINT8 def_inq_scan_mode; /* ??? limited/general/none */ + // BOOLEAN connectable; /* If TRUE page scan should be enabled */ + // UINT8 def_inq_scan_mode; /* ??? limited/general/none */ +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } tBTM_CFG; enum { @@ -885,6 +893,7 @@ typedef struct { UINT16 ediv; /* received ediv value from LTK request */ UINT8 key_size; tBTM_BLE_VSC_CB cmn_ble_vsc_cb; + BOOLEAN addr_res_en; /* internal use for test: address resolution enable/disable */ #endif /* Packet types supported by the local device */ @@ -951,7 +960,7 @@ typedef struct { #endif // SMP_INCLUDED == TRUE || BT_CLASSIC_ENABLED == TRUE list_t *p_sec_dev_rec_list; tBTM_SEC_SERV_REC *p_out_serv; - tBTM_MKEY_CALLBACK *mkey_cback; + // tBTM_MKEY_CALLBACK *mkey_cback; BD_ADDR connecting_bda; DEV_CLASS connecting_dc; @@ -1063,6 +1072,7 @@ void btm_cont_rswitch (tACL_CONN *p, tACL_CONN *btm_handle_to_acl (UINT16 hci_handle); void btm_read_link_policy_complete (UINT8 *p); void btm_read_rssi_complete (UINT8 *p); +void btm_read_channel_map_complete (UINT8 *p); void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble); void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types); void btm_read_link_quality_complete (UINT8 *p); @@ -1113,17 +1123,29 @@ void btm_read_phy_callback(uint8_t hci_status, uint16_t conn_handle, uint8_t tx_ #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) void btm_ble_periodic_adv_sync_trans_complete(UINT16 op_code, UINT8 hci_status, UINT16 conn_handle); #endif +void btm_ble_big_sync_terminate_complete(UINT8 hci_status, UINT8 big_handle); + +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +void btm_enh_read_trans_pwr_level_cmpl_evt(uint8_t *p); +void btm_read_remote_trans_pwr_level_cmpl(UINT8 status); +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + +#if (BLE_FEAT_CONN_SUBRATING == TRUE) +void btm_subrate_req_cmd_status(UINT8 status); +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + /* Internal functions provided by btm_sco.c ******************************************** */ void btm_sco_init (void); +void btm_sco_free(void); void btm_sco_connected (UINT8 hci_status, BD_ADDR bda, UINT16 hci_handle, tBTM_ESCO_DATA *p_esco_data); void btm_esco_proc_conn_chg (UINT8 status, UINT16 handle, UINT8 tx_interval, UINT8 retrans_window, UINT16 rx_pkt_len, UINT16 tx_pkt_len); void btm_sco_conn_req (BD_ADDR bda, DEV_CLASS dev_class, UINT8 link_type); -void btm_sco_removed (UINT16 hci_handle, UINT8 reason); +BOOLEAN btm_sco_removed (UINT16 hci_handle, UINT8 reason); void btm_sco_acl_removed (BD_ADDR bda); void btm_route_sco_data (BT_HDR *p_msg); BOOLEAN btm_is_sco_active (UINT16 handle); @@ -1203,7 +1225,7 @@ void btm_sec_auth_complete (UINT16 handle, UINT8 status); void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable); void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode); tBTM_STATUS btm_sec_disconnect (UINT16 handle, UINT8 reason); -void btm_sec_disconnected (UINT16 handle, UINT8 reason); +BOOLEAN btm_sec_disconnected (UINT16 handle, UINT8 reason); void btm_sec_rmt_name_request_complete (UINT8 *bd_addr, UINT8 *bd_name, UINT8 status); void btm_sec_rmt_host_support_feat_evt (UINT8 *p); void btm_io_capabilities_req (UINT8 *p); diff --git a/lib/bt/host/bluedroid/stack/btu/btu_hcif.c b/lib/bt/host/bluedroid/stack/btu/btu_hcif.c index 30e76125..eb2995b9 100644 --- a/lib/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/lib/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -55,6 +55,7 @@ extern void btm_ble_test_command_complete(UINT8 *p); /********************************************************************************/ /* L O C A L F U N C T I O N P R O T O T Y P E S */ /********************************************************************************/ +#if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_inquiry_comp_evt (UINT8 *p); static void btu_hcif_inquiry_result_evt (UINT8 *p); static void btu_hcif_inquiry_rssi_result_evt (UINT8 *p); @@ -62,30 +63,46 @@ static void btu_hcif_extended_inquiry_result_evt (UINT8 *p); static void btu_hcif_connection_comp_evt (UINT8 *p); static void btu_hcif_connection_request_evt (UINT8 *p); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_disconnection_comp_evt (UINT8 *p); #if (SMP_INCLUDED == TRUE) static void btu_hcif_authentication_comp_evt (UINT8 *p); #endif ///SMP_INCLUDED == TRUE +#if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_rmt_name_request_comp_evt (UINT8 *p, UINT16 evt_len); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (SMP_INCLUDED == TRUE) static void btu_hcif_encryption_change_evt (UINT8 *p); #endif ///SMP_INCLUDED == TRUE +#if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_read_rmt_features_comp_evt (UINT8 *p); static void btu_hcif_read_rmt_ext_features_comp_evt (UINT8 *p); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p); +#if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_qos_setup_comp_evt (UINT8 *p); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_command_complete_evt (BT_HDR *response, void *context); static void btu_hcif_command_status_evt (uint8_t status, BT_HDR *command, void *context); static void btu_hcif_hardware_error_evt (UINT8 *p); +#if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_flush_occured_evt (void); static void btu_hcif_role_change_evt (UINT8 *p); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_num_compl_data_pkts_evt (UINT8 *p); + +#if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_mode_change_evt (UINT8 *p); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) + #if (SMP_INCLUDED == TRUE) +#if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_pin_code_request_evt (UINT8 *p); static void btu_hcif_link_key_request_evt (UINT8 *p); static void btu_hcif_link_key_notification_evt (UINT8 *p); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #endif ///SMP_INCLUDED == TRUE +#if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_loopback_command_evt (void); static void btu_hcif_data_buf_overflow_evt (void); static void btu_hcif_max_slots_changed_evt (void); @@ -98,6 +115,8 @@ static void btu_hcif_esco_connection_comp_evt(UINT8 *p); static void btu_hcif_esco_connection_chg_evt(UINT8 *p); static void btu_hcif_host_support_evt (UINT8 *p); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) + /* Simple Pairing Events */ #if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_io_cap_request_evt (UINT8 *p); @@ -111,12 +130,14 @@ static void btu_hcif_keypress_notif_evt (UINT8 *p); #if BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE static void btu_hcif_rem_oob_request_evt (UINT8 *p); #endif +#if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_link_supv_to_changed_evt (UINT8 *p); #if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE static void btu_hcif_enhanced_flush_complete_evt (void); #endif static void btu_hcif_ssr_evt (UINT8 *p, UINT16 evt_len); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if BLE_INCLUDED == TRUE static void btu_ble_ll_conn_complete_evt (UINT8 *p, UINT16 evt_len); @@ -136,29 +157,91 @@ static void btu_ble_proc_enhanced_conn_cmpl (UINT8 *p, UINT16 evt_len); //#endif #if (BLE_50_FEATURE_SUPPORT == TRUE) static void btu_ble_phy_update_complete_evt(UINT8 *p); +#if (BLE_50_EXTEND_SCAN_EN == TRUE) static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len); +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p); static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len); static void btu_ble_periodic_adv_sync_lost_evt(UINT8 *p); +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) +#if (BLE_50_EXTEND_SCAN_EN == TRUE) static void btu_ble_scan_timeout_evt(UINT8 *p); +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) static void btu_ble_adv_set_terminate_evt(UINT8 *p); static void btu_ble_scan_req_received_evt(UINT8 *p); +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) +static void btu_ble_channel_select_alg_evt(UINT8 *p); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p); #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +void btu_ble_create_big_cmd_status(UINT8 status); +static void btu_ble_big_create_complete_evt(UINT8 *p); +void btu_ble_big_terminate_cmd_status(UINT8 status); +static void btu_ble_big_terminate_complete_evt(UINT8 *p); +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) + +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +static void btu_ble_create_big_sync_cmd_status(UINT8 status); +static void btu_ble_big_sync_establish_evt(UINT8 *p); +static void btu_ble_big_sync_lost_evt(UINT8 *p); +static void btu_ble_biginfo_adv_report_evt(UINT8 *p); +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +static void btu_ble_create_cis_cmd_status(UINT8 status); +#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +static void btu_ble_accept_cis_req_cmd_status(UINT8 status); +static void btu_ble_cis_request_evt(UINT8 *p); +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_EN == TRUE) +static void btu_ble_cis_established_evt(UINT8 *p); +static void btu_ble_cis_disconnected(UINT16 handle, UINT8 reason); +#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) + +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + + +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +static void btu_ble_cte_connless_iq_report_evt(UINT8 *p); +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +static void btu_ble_cte_conn_iq_report_evt(UINT8 *p); +static void btu_ble_cte_req_failed_evt(UINT8 *p); +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +static void btu_ble_path_loss_threshold_evt(UINT8 *p); +static void btu_ble_transmit_power_report_evt(UINT8 *p); +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + +#if (BLE_FEAT_CONN_SUBRATING == TRUE) +static void btu_ble_subrate_change_evt(UINT8 *p); +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + +#if (BLE_42_ADV_EN == TRUE) extern osi_sem_t adv_enable_sem; extern osi_sem_t adv_data_sem; extern osi_sem_t adv_param_sem; -extern osi_sem_t scan_enable_sem; -extern osi_sem_t scan_param_sem; extern uint8_t adv_enable_status; extern uint8_t adv_data_status; extern uint8_t adv_param_status; +#endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_42_SCAN_EN == TRUE) +extern osi_sem_t scan_enable_sem; +extern osi_sem_t scan_param_sem; extern uint8_t scan_enable_status; extern uint8_t scan_param_status; - +#endif // #if (BLE_42_SCAN_EN == TRUE) #endif /******************************************************************************* @@ -182,6 +265,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) STREAM_TO_UINT8 (hci_evt_len, p); switch (hci_evt_code) { +#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_INQUIRY_COMP_EVT: btu_hcif_inquiry_comp_evt (p); break; @@ -200,6 +284,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) case HCI_CONNECTION_REQUEST_EVT: btu_hcif_connection_request_evt (p); break; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) case HCI_DISCONNECTION_COMP_EVT: btu_hcif_disconnection_comp_evt (p); break; @@ -208,9 +293,11 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) btu_hcif_authentication_comp_evt (p); #endif ///SMP_INCLUDED == TRUE break; +#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_RMT_NAME_REQUEST_COMP_EVT: btu_hcif_rmt_name_request_comp_evt (p, hci_evt_len); break; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) case HCI_ENCRYPTION_CHANGE_EVT: #if (SMP_INCLUDED == TRUE) btu_hcif_encryption_change_evt (p); @@ -223,18 +310,22 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) #endif ///SMP_INCLUDED == TRUE break; #endif +#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_READ_RMT_FEATURES_COMP_EVT: btu_hcif_read_rmt_features_comp_evt (p); break; case HCI_READ_RMT_EXT_FEATURES_COMP_EVT: btu_hcif_read_rmt_ext_features_comp_evt (p); break; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) case HCI_READ_RMT_VERSION_COMP_EVT: btu_hcif_read_rmt_version_comp_evt (p); break; +#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_QOS_SETUP_COMP_EVT: btu_hcif_qos_setup_comp_evt (p); break; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) case HCI_COMMAND_COMPLETE_EVT: //HCI_TRACE_ERROR("%s should not have received a command complete event. " // "Someone didn't go through the hci transmit_command function.", __func__); @@ -246,19 +337,24 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) case HCI_HARDWARE_ERROR_EVT: btu_hcif_hardware_error_evt (p); break; +#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_FLUSH_OCCURED_EVT: btu_hcif_flush_occured_evt (); break; case HCI_ROLE_CHANGE_EVT: btu_hcif_role_change_evt (p); break; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) case HCI_NUM_COMPL_DATA_PKTS_EVT: btu_hcif_num_compl_data_pkts_evt (p); break; + #if (CLASSIC_BT_INCLUDED == TRUE) case HCI_MODE_CHANGE_EVT: btu_hcif_mode_change_evt (p); break; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (SMP_INCLUDED == TRUE) +#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_PIN_CODE_REQUEST_EVT: btu_hcif_pin_code_request_evt (p); break; @@ -268,7 +364,9 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) case HCI_LINK_KEY_NOTIFICATION_EVT: btu_hcif_link_key_notification_evt (p); break; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #endif ///SMP_INCLUDED == TRUE +#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_LOOPBACK_COMMAND_EVT: btu_hcif_loopback_command_evt (); break; @@ -305,7 +403,6 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) case HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT: btu_hcif_host_support_evt (p); break; -#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_IO_CAPABILITY_REQUEST_EVT: btu_hcif_io_cap_request_evt (p); break; @@ -334,7 +431,6 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) case HCI_KEYPRESS_NOTIFY_EVT: btu_hcif_keypress_notif_evt (p); break; -#endif /* (CLASSIC_BT_INCLUDED == TRUE) */ case HCI_LINK_SUPER_TOUT_CHANGED_EVT: btu_hcif_link_supv_to_changed_evt (p); break; @@ -343,6 +439,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) btu_hcif_enhanced_flush_complete_evt (); break; #endif +#endif /* (CLASSIC_BT_INCLUDED == TRUE) */ #if (BLE_INCLUDED == TRUE) case HCI_BLE_EVENT: @@ -388,10 +485,13 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) case HCI_BLE_PHY_UPDATE_COMPLETE_EVT: btu_ble_phy_update_complete_evt(p); break; +#if (BLE_50_EXTEND_SCAN_EN == TRUE) case HCI_BLE_EXT_ADV_REPORT_EVT: //HCI_TRACE_ERROR("%s, HCI_BLE_EXT_ADV_REPORT_EVT.", __func__); btu_ble_ext_adv_report_evt(p, hci_evt_len); break; +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) case HCI_BLE_PERIOD_ADV_SYNC_ESTAB_EVT: btu_ble_periodic_adv_sync_establish_evt(p); break; @@ -401,16 +501,22 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) case HCI_BLE_PERIOD_ADV_SYNC_LOST_EVT: btu_ble_periodic_adv_sync_lost_evt(p); break; +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) +#if (BLE_50_EXTEND_SCAN_EN == TRUE) case HCI_BLE_SCAN_TIMEOUT_EVT: btu_ble_scan_timeout_evt(p); break; +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) case HCI_BLE_ADV_SET_TERMINATED_EVT: btu_ble_adv_set_terminate_evt(p); break; case HCI_BLE_SCAN_REQ_RECEIVED_EVT: btu_ble_scan_req_received_evt(p); break; +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) case HCI_BLE_CHANNEL_SELECT_ALG: + btu_ble_channel_select_alg_evt(p); break; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) @@ -418,6 +524,68 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) btu_ble_periodic_adv_sync_trans_recv(p); break; #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_EN == TRUE) + case HCI_BLE_CIS_ESTABLISHED_V1_EVT: + case HCI_BLE_CIS_ESTABLISHED_V2_EVT: + btu_ble_cis_established_evt(p); + break; +#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) + case HCI_BLE_CIS_REQUEST_EVT: + btu_ble_cis_request_evt(p); + break; +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) + case HCI_BLE_BIG_CREATE_COMPLETE_EVT: + btu_ble_big_create_complete_evt(p); + break; + case HCI_BLE_BIG_TERMINATE_COMPLETE_EVT: + btu_ble_big_terminate_complete_evt(p); + break; +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) + case HCI_BLE_BIG_SYNC_ESTABLISHED_EVT: + btu_ble_big_sync_establish_evt(p); + break; + case HCI_BLE_BIG_SYNC_LOST_EVT: + btu_ble_big_sync_lost_evt(p); + break; + case HCI_BLE_BIGINFO_ADV_REPORT_EVT: + btu_ble_biginfo_adv_report_evt(p); + break; +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +#endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + case HCI_BLE_CONNLESS_IQ_REPORT_EVT: + btu_ble_cte_connless_iq_report_evt(p); + break; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + case HCI_BLE_CONN_IQ_REPORT_EVT: + btu_ble_cte_conn_iq_report_evt(p); + break; + case HCI_BLE_CTE_REQUEST_FAILED_EVT: + btu_ble_cte_req_failed_evt(p); + break; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +#endif // #if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + case HCI_BLE_PATH_LOSS_THRESHOLD_EVT: + btu_ble_path_loss_threshold_evt(p); + break; + case HCI_BLE_TRANS_POWER_REPORTING_EVT: + btu_ble_transmit_power_report_evt(p); + break; +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +#if (BLE_FEAT_CONN_SUBRATING == TRUE) + case HCI_BLE_SUBRATE_CHANGE_EVT: + btu_ble_subrate_change_evt(p); + break; +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) } break; #endif /* BLE_INCLUDED */ @@ -559,7 +727,7 @@ void btu_hcif_send_host_rdy_for_data(void) btsnd_hcic_host_num_xmitted_pkts (num_ents, handles, num_pkts); } } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btu_hcif_inquiry_comp_evt @@ -687,7 +855,7 @@ static void btu_hcif_connection_request_evt (UINT8 *p) } #endif /* BTM_SCO_INCLUDED */ } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -702,6 +870,7 @@ static void btu_hcif_disconnection_comp_evt (UINT8 *p) { UINT16 handle; UINT8 reason; + BOOLEAN dev_find = FALSE; ++p; STREAM_TO_UINT16 (handle, p); @@ -709,9 +878,18 @@ static void btu_hcif_disconnection_comp_evt (UINT8 *p) handle = HCID_GET_HANDLE (handle); - btm_acl_disconnected(handle, reason); + dev_find = btm_acl_disconnected(handle, reason); + +#if (BLE_FEAT_ISO_CIG_EN == TRUE) + // Not find device. it is iso handle + if (!dev_find) { + btu_ble_cis_disconnected(handle, reason); + } +#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) - HCI_TRACE_WARNING("hcif disc complete: hdl 0x%x, rsn 0x%x", handle, reason); + HCI_TRACE_WARNING("hcif disc complete: hdl 0x%x, rsn 0x%x dev_find %d", handle, reason, dev_find); + + UNUSED(dev_find); } /******************************************************************************* @@ -736,6 +914,7 @@ static void btu_hcif_authentication_comp_evt (UINT8 *p) } #endif ///SMP_INCLUDED == TRUE +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btu_hcif_rmt_name_request_comp_evt @@ -760,7 +939,7 @@ static void btu_hcif_rmt_name_request_comp_evt (UINT8 *p, UINT16 evt_len) btm_sec_rmt_name_request_complete (bd_addr, p, status); #endif ///SMP_INCLUDED == TRUE } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -786,7 +965,7 @@ static void btu_hcif_encryption_change_evt (UINT8 *p) btm_sec_encrypt_change (handle, status, encr_enable); } #endif ///SMP_INCLUDED == TRUE - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btu_hcif_read_rmt_features_comp_evt @@ -825,6 +1004,7 @@ static void btu_hcif_read_rmt_ext_features_comp_evt (UINT8 *p) btm_read_remote_ext_features_failed(status, handle); } } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -840,7 +1020,7 @@ static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p) btm_read_remote_version_complete (p); } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btu_hcif_qos_setup_comp_evt @@ -934,6 +1114,7 @@ static void btu_hcif_esco_connection_chg_evt (UINT8 *p) rx_pkt_len, tx_pkt_len); #endif } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -949,6 +1130,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l { uint8_t status; switch (opcode) { +#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_INQUIRY_CANCEL: /* Tell inquiry processing that we are done */ btm_process_cancel_complete(HCI_SUCCESS, BTM_BR_INQUIRY_MASK); @@ -961,37 +1143,39 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_delete_stored_link_key_complete (p); break; - case HCI_READ_LOCAL_NAME: - btm_read_local_name_complete (p, evt_len); - break; - case HCI_GET_LINK_QUALITY: btm_read_link_quality_complete (p); break; - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) + case HCI_READ_LOCAL_NAME: + btm_read_local_name_complete (p, evt_len); + break; case HCI_READ_RSSI: btm_read_rssi_complete (p); break; - + case HCI_BLE_READ_CHNL_MAP: + btm_read_channel_map_complete (p); + break; case HCI_READ_TRANSMIT_POWER_LEVEL: +#if (BLE_HOST_READ_TX_POWER_EN == TRUE) btm_read_tx_power_complete(p, FALSE); +#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) break; - +#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_CREATE_CONNECTION_CANCEL: btm_create_conn_cancel_complete(p); break; - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) case HCI_READ_LOCAL_OOB_DATA: #if BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE btm_read_local_oob_complete(p); #endif break; - +#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_READ_INQ_TX_POWER_LEVEL: btm_read_linq_tx_power_complete (p); break; -#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_SET_AFH_CHANNELS: btm_set_afh_channels_complete(p); break; @@ -1055,22 +1239,26 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l break; case HCI_BLE_READ_ADV_CHNL_TX_POWER: +#if (BLE_HOST_READ_TX_POWER_EN == TRUE) btm_read_tx_power_complete(p, TRUE); +#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) break; - +#if (BLE_42_ADV_EN == TRUE) case HCI_BLE_WRITE_ADV_ENABLE: btm_ble_write_adv_enable_complete(p); break; - +#endif // #if (BLE_42_ADV_EN == TRUE) case HCI_BLE_CREATE_LL_CONN: btm_ble_create_ll_conn_complete(*p); break; case HCI_BLE_TRANSMITTER_TEST: case HCI_BLE_RECEIVER_TEST: +#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE)) case HCI_BLE_TEST_END: btm_ble_test_command_complete(p); break; +#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE)) case HCI_BLE_CREATE_CONN_CANCEL: btm_ble_create_conn_cancel_complete(p); break; @@ -1105,6 +1293,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l break; #endif // #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) case HCI_BLE_SET_EXT_ADV_PARAM: case HCI_BLE_SET_EXT_ADV_DATA: case HCI_BLE_SET_EXT_SCAN_RSP_DATA: @@ -1113,6 +1302,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l HCI_TRACE_EVENT("%s opcode 0x%x status 0x%x", __func__, opcode, status); break; } +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) case HCI_BLE_READ_PHY: { uint16_t conn_handle; uint8_t tx_phy; @@ -1124,11 +1314,14 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_read_phy_callback(status, conn_handle, tx_phy, rx_phy); break; } +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_DTM_TEST_EN == TRUE) case HCI_BLE_ENH_RX_TEST: case HCI_BLE_ENH_TX_TEST: btm_ble_test_command_complete(p); break; -#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#endif // #if (BLE_50_DTM_TEST_EN == TRUE) + #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) case HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE: case HCI_BLE_SET_DEFAULT_PAST_PARAMS: @@ -1143,6 +1336,59 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l break; } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) + case HCI_BLE_BIG_TERMINATE_SYNC: + UINT16 big_handle; + STREAM_TO_UINT8(status, p); + STREAM_TO_UINT8(big_handle, p); + btm_ble_big_sync_terminate_complete(status, big_handle); + break; +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) + case HCI_BLE_ISO_SET_DATA_PATH: + case HCI_BLE_ISO_REMOVE_DATA_PATH: + UINT16 conn_handle; + STREAM_TO_UINT8(status, p); + STREAM_TO_UINT16(conn_handle, p); + btm_ble_iso_data_path_update_complete(opcode, status, conn_handle); + break; + case HCI_BLE_ISO_READ_TX_SYNC: + btm_ble_iso_read_iso_tx_sync_complete(p); + break; + case HCI_BLE_ISO_READ_ISO_LINK_QUALITY: + btm_ble_iso_read_iso_link_quality_complete(p); + break; + +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) + case HCI_BLE_ISO_SET_CIG_PARAMS: + case HCI_BLE_ISO_SET_CIG_PARAMS_TEST: + btm_ble_iso_set_cig_params_complete(p); + break; + case HCI_BLE_ISO_REMOVE_CIG: + // do nothing + break; +#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) + case HCI_BLE_ISO_ACCEPT_CIS_REQ: + case HCI_BLE_ISO_REJECT_CIS_REQ: + // do nothing + break; +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) + +#endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) + case HCI_BLE_READ_ANT_INFOR: + btm_ble_cte_read_ant_infor_complete(p); + break; +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + case HCI_BLE_ENH_READ_TRANS_POWER_LEVEL: + btm_enh_read_trans_pwr_level_cmpl_evt(p); + break; +#endif //#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + #endif /* (BLE_INCLUDED == TRUE) */ default: { @@ -1192,6 +1438,7 @@ static void btu_hcif_command_complete_evt(BT_HDR *response, void *context) uint8_t *stream = response->data + response->offset + 3; STREAM_TO_UINT16(opcode, stream); switch (opcode) { +#if (BLE_42_ADV_EN == TRUE) case HCI_BLE_WRITE_ADV_DATA: adv_data_status = *stream; osi_sem_give(&adv_data_sem); @@ -1209,6 +1456,8 @@ static void btu_hcif_command_complete_evt(BT_HDR *response, void *context) adv_param_status = *stream; osi_sem_give(&adv_param_sem); break; +#endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_42_SCAN_EN == TRUE) case HCI_BLE_WRITE_SCAN_PARAMS: scan_param_status = *stream; osi_sem_give(&scan_param_sem); @@ -1217,6 +1466,7 @@ static void btu_hcif_command_complete_evt(BT_HDR *response, void *context) scan_enable_status = *stream; osi_sem_give(&scan_enable_sem); break; +#endif // #if (BLE_42_SCAN_EN == TRUE) default: break; } @@ -1265,6 +1515,7 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c #endif switch (opcode) { +#if (CLASSIC_BT_INCLUDED == TRUE) case HCI_EXIT_SNIFF_MODE: case HCI_EXIT_PARK_MODE: #if BTM_SCO_WAKE_PARKED_LINK == TRUE @@ -1284,7 +1535,9 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c case HCI_PARK_MODE: btm_pm_proc_cmd_status(status); break; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) case HCI_BLE_PERIOD_ADV_CREATE_SYNC: { uint8_t btm_status = BTM_SUCCESS; @@ -1295,6 +1548,7 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c btm_create_sync_callback(btm_status); break; } +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) case HCI_BLE_SET_PHY: { uint8_t btm_status = BTM_SUCCESS; @@ -1306,6 +1560,42 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c break; } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) + case HCI_BLE_CREATE_BIG: + case HCI_BLE_CREATE_BIG_TEST: + btu_ble_create_big_cmd_status(status); + break; + case HCI_BLE_TERMINATE_BIG: + btu_ble_big_terminate_cmd_status(status); + break; +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) + case HCI_BLE_BIG_CREATE_SYNC: + btu_ble_create_big_sync_cmd_status(status); + break; +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) + case HCI_BLE_ISO_CREATE_CIS: + btu_ble_create_cis_cmd_status(status); + break; +#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) + case HCI_BLE_ISO_ACCEPT_CIS_REQ: + btu_ble_accept_cis_req_cmd_status(status); + break; +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +#endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + case HCI_BLE_READ_REMOTE_TRANS_POWER_LEVEL: + btm_read_remote_trans_pwr_level_cmpl(status); + break; +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +#if (BLE_FEAT_CONN_SUBRATING == TRUE) + case HCI_BLE_SUBRATE_REQUEST: + btm_subrate_req_cmd_status(status); + break; +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) default: /* If command failed to start, we may need to tell BTM */ if (status != HCI_SUCCESS) { @@ -1379,6 +1669,9 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c break; #if BLE_INCLUDED == TRUE +#if (BLE_50_FEATURE_SUPPORT == TRUE) + case HCI_BLE_EXT_CREATE_CONN: +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) case HCI_BLE_CREATE_LL_CONN: btm_ble_create_ll_conn_complete(status); break; @@ -1498,7 +1791,7 @@ static void btu_hcif_hardware_error_evt (UINT8 *p) } } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btu_hcif_flush_occured_evt @@ -1535,7 +1828,7 @@ static void btu_hcif_role_change_evt (UINT8 *p) l2c_link_role_changed (bda, role, status); btm_acl_role_changed(status, bda, role); } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -1556,7 +1849,7 @@ static void btu_hcif_num_compl_data_pkts_evt (UINT8 *p) btm_sco_process_num_completed_pkts (p); #endif } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btu_hcif_mode_change_evt @@ -1624,7 +1917,7 @@ static void btu_hcif_ssr_evt (UINT8 *p, UINT16 evt_len) HCI_TRACE_WARNING("hcif ssr evt: st 0x%x, hdl 0x%x, tx_lat %d rx_lat %d", status, handle, max_tx_lat, max_rx_lat); } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btu_hcif_pin_code_request_evt @@ -1635,6 +1928,7 @@ static void btu_hcif_ssr_evt (UINT8 *p, UINT16 evt_len) ** *******************************************************************************/ #if (SMP_INCLUDED == TRUE) +#if (CLASSIC_BT_INCLUDED == TRUE) static void btu_hcif_pin_code_request_evt (UINT8 *p) { #if (CLASSIC_BT_INCLUDED == TRUE) @@ -1689,9 +1983,10 @@ static void btu_hcif_link_key_notification_evt (UINT8 *p) btm_sec_link_key_notification (bda, key, key_type); } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #endif ///SMP_INCLUDED == TRUE - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btu_hcif_loopback_command_evt @@ -1867,7 +2162,7 @@ static void btu_hcif_host_support_evt (UINT8 *p) ** Returns void ** *******************************************************************************/ -#if (CLASSIC_BT_INCLUDED == TRUE) + static void btu_hcif_io_cap_request_evt (UINT8 *p) { btm_io_capabilities_req(p); @@ -1976,6 +2271,7 @@ static void btu_hcif_rem_oob_request_evt (UINT8 *p) } #endif +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btu_hcif_link_supv_to_changed_evt @@ -2014,6 +2310,7 @@ static void btu_hcif_enhanced_flush_complete_evt (void) /* This is empty until an upper layer cares about returning event */ } #endif +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /********************************************** ** End of Simple Pairing Events ***********************************************/ @@ -2133,6 +2430,7 @@ static void btu_ble_phy_update_complete_evt(UINT8 *p) } #if BLE_PRIVACY_SPT == TRUE +#if (BLE_50_EXTEND_SCAN_EN == TRUE) /******************************************************************************* ** ** Function btm_ble_resolve_random_addr_adv_ext @@ -2153,13 +2451,17 @@ static void btm_ble_resolve_random_addr_adv_ext(void *p_rec, void *p) BDADDR_TO_STREAM(pp,bda); } } +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) #endif +#if (BLE_50_EXTEND_SCAN_EN == TRUE) static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len) { tBTM_BLE_EXT_ADV_REPORT ext_adv_report = {0}; UINT8 num_reports = {0}; +#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) UINT8 *pp = p; +#endif //UINT8 legacy_event_type = 0; UINT16 evt_type = 0; uint8_t addr_type; @@ -2233,7 +2535,9 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len) } } +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p) { tBTM_BLE_PERIOD_ADV_SYNC_ESTAB sync_estab = {0}; @@ -2274,7 +2578,7 @@ static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len) STREAM_TO_UINT16(adv_report.sync_handle, p); STREAM_TO_UINT8(adv_report.tx_power, p); STREAM_TO_UINT8(adv_report.rssi, p); - STREAM_TO_UINT8(unused, p); + STREAM_TO_UINT8(adv_report.cte_type, p); STREAM_TO_UINT8(adv_report.data_status, p); STREAM_TO_UINT8(adv_report.data_length, p); @@ -2306,14 +2610,18 @@ static void btu_ble_periodic_adv_sync_lost_evt(UINT8 *p) btm_ble_periodic_adv_sync_lost_evt(&sync_lost); } +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) +#if (BLE_50_EXTEND_SCAN_EN == TRUE) static void btu_ble_scan_timeout_evt(UINT8 *p) { UNUSED(p); btm_ble_scan_timeout_evt(); } +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) static void btu_ble_adv_set_terminate_evt(UINT8 *p) { tBTM_BLE_ADV_TERMINAT adv_term = {0}; @@ -2346,6 +2654,22 @@ static void btu_ble_scan_req_received_evt(UINT8 *p) btm_ble_scan_req_received_evt(&req_received); } +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) + +static void btu_ble_channel_select_alg_evt(UINT8 *p) +{ + tBTM_BLE_CHANNEL_SEL_ALG chan_sel_alg = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT16(chan_sel_alg.conn_handle, p); + STREAM_TO_UINT8(chan_sel_alg.channel_sel_alg, p); + + btm_ble_channel_select_algorithm_evt(&chan_sel_alg); +} #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) @@ -2380,6 +2704,384 @@ static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p) } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +static void btu_ble_create_cis_cmd_status(UINT8 status) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + if (status != HCI_SUCCESS) { + status = (BTM_HCI_ERROR | status); + } + cb_params.status = status; + btm_ble_create_cis_cmd_status(&cb_params); +} +#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +static void btu_ble_accept_cis_req_cmd_status(UINT8 status) +{ + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + if (status != HCI_SUCCESS) { + status = (BTM_HCI_ERROR | status); + } + cb_params.status = status; + + btm_ble_accept_cis_req_cmd_status(&cb_params); +} +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_EN == TRUE) +static void btu_ble_cis_disconnected(UINT16 handle, UINT8 reason) +{ + tBTM_BLE_CIS_DISCON_CMPL cis_disconnected_evt = {0}; + cis_disconnected_evt.cis_handle = handle; + cis_disconnected_evt.reason = reason; + btm_ble_cis_disconnected_evt(&cis_disconnected_evt); +} + +static void btu_ble_cis_established_evt(UINT8 *p) +{ + HCI_TRACE_DEBUG("%s", __func__); + tBTM_BLE_CIS_ESTABLISHED_CMPL cis_estab_evt = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(cis_estab_evt.status, p); + STREAM_TO_UINT16(cis_estab_evt.conn_handle, p); + STREAM_TO_UINT24(cis_estab_evt.cig_sync_delay, p); + STREAM_TO_UINT24(cis_estab_evt.cis_sync_delay, p); + STREAM_TO_UINT24(cis_estab_evt.trans_lat_c_to_p, p); + STREAM_TO_UINT24(cis_estab_evt.trans_lat_p_to_c, p); + STREAM_TO_UINT8(cis_estab_evt.phy_c_to_p, p); + STREAM_TO_UINT8(cis_estab_evt.phy_p_to_c, p); + STREAM_TO_UINT8(cis_estab_evt.nse, p); + STREAM_TO_UINT8(cis_estab_evt.bn_c_to_p, p); + STREAM_TO_UINT8(cis_estab_evt.bn_p_to_c, p); + STREAM_TO_UINT8(cis_estab_evt.ft_c_to_p, p); + STREAM_TO_UINT8(cis_estab_evt.ft_p_to_c, p); + STREAM_TO_UINT16(cis_estab_evt.max_pdu_c_to_p, p); + STREAM_TO_UINT16(cis_estab_evt.max_pdu_p_to_c, p); + STREAM_TO_UINT16(cis_estab_evt.iso_interval, p); +#if (BLE_FEAT_ISO_60_EN == TRUE) + STREAM_TO_UINT24(cis_estab_evt.sub_interval, p); + STREAM_TO_UINT16(cis_estab_evt.max_sdu_c_to_p, p); + STREAM_TO_UINT16(cis_estab_evt.max_sdu_p_to_c, p); + STREAM_TO_UINT24(cis_estab_evt.sdu_int_c_to_p, p); + STREAM_TO_UINT24(cis_estab_evt.sdu_int_p_to_c, p); + STREAM_TO_UINT8(cis_estab_evt.framing, p); +#endif // #if (BLE_FEAT_ISO_60_EN == TRUE) + + btm_ble_cis_established_evt(&cis_estab_evt); +} +#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +static void btu_ble_cis_request_evt(UINT8 *p) +{ + HCI_TRACE_DEBUG("%s", __func__); + tBTM_BLE_CIS_REQUEST_CMPL cis_req_evt = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT16(cis_req_evt.acl_handle, p); + STREAM_TO_UINT16(cis_req_evt.cis_handle, p); + STREAM_TO_UINT8(cis_req_evt.cig_id, p); + STREAM_TO_UINT8(cis_req_evt.cis_id, p); + + + btm_ble_cis_request_evt(&cis_req_evt); +} +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) + +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +void btu_ble_create_big_cmd_status(UINT8 status) +{ + if (status != HCI_SUCCESS) { + tBTM_BLE_BIG_CREATE_CMPL big_cmpl = {0}; + btm_ble_big_create_cmpl_evt(&big_cmpl); + } +} + +static void btu_ble_big_create_complete_evt(UINT8 *p) +{ + HCI_TRACE_DEBUG("%s", __func__); + tBTM_BLE_BIG_CREATE_CMPL big_cmpl = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(big_cmpl.status, p); + STREAM_TO_UINT8(big_cmpl.big_handle, p); + STREAM_TO_UINT24(big_cmpl.big_sync_delay, p); + STREAM_TO_UINT24(big_cmpl.transport_latency, p); + STREAM_TO_UINT8(big_cmpl.phy, p); + STREAM_TO_UINT8(big_cmpl.nse, p); + STREAM_TO_UINT8(big_cmpl.bn, p); + STREAM_TO_UINT8(big_cmpl.pto, p); + STREAM_TO_UINT8(big_cmpl.irc, p); + STREAM_TO_UINT16(big_cmpl.max_pdu, p); + STREAM_TO_UINT16(big_cmpl.iso_interval, p); + STREAM_TO_UINT8(big_cmpl.num_bis, p); + for (uint8_t i = 0; i < big_cmpl.num_bis; i++) + { + STREAM_TO_UINT16(big_cmpl.bis_handle[i], p); + // only 12 bits meaningful + big_cmpl.bis_handle[i] = (big_cmpl.bis_handle[i] & 0x0FFF); + } + + btm_ble_big_create_cmpl_evt(&big_cmpl); +} + +void btu_ble_big_terminate_cmd_status(UINT8 status) +{ + if (status != HCI_SUCCESS) { + tBTM_BLE_BIG_TERMINATE_CMPL big_term = {0}; + big_term.status = (status | BTM_HCI_ERROR); + btm_ble_big_terminate_cmpl_evt(&big_term); + } +} + +static void btu_ble_big_terminate_complete_evt(UINT8 *p) +{ + tBTM_BLE_BIG_TERMINATE_CMPL big_term = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(big_term.big_handle, p); + STREAM_TO_UINT8(big_term.reason, p); + big_term.status = HCI_SUCCESS; + + btm_ble_big_terminate_cmpl_evt(&big_term); +} +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) + +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +void btu_ble_create_big_sync_cmd_status(UINT8 status) +{ + if (status != HCI_SUCCESS) { + tBTM_BLE_BIG_SYNC_ESTAB_CMPL big_estb = {0}; + big_estb.status = status; + btm_ble_big_sync_estab_evt(&big_estb); + } +} + +static void btu_ble_big_sync_establish_evt(UINT8 *p) +{ + tBTM_BLE_BIG_SYNC_ESTAB_CMPL big_estb = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(big_estb.status, p); + STREAM_TO_UINT8(big_estb.big_handle, p); + STREAM_TO_UINT24(big_estb.transport_latency_big, p); + STREAM_TO_UINT8(big_estb.nse, p); + STREAM_TO_UINT8(big_estb.bn, p); + STREAM_TO_UINT8(big_estb.pto, p); + STREAM_TO_UINT8(big_estb.irc, p); + STREAM_TO_UINT16(big_estb.max_pdu, p); + STREAM_TO_UINT16(big_estb.iso_interval, p); + STREAM_TO_UINT8(big_estb.num_bis, p); + for (uint8_t i = 0; i < big_estb.num_bis; i++) + { + STREAM_TO_UINT16(big_estb.bis_handle[i], p); + } + + btm_ble_big_sync_estab_evt(&big_estb); +} + +static void btu_ble_big_sync_lost_evt(UINT8 *p) +{ + tBTM_BLE_BIG_SYNC_LOST_EVT big_sync_lost = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(big_sync_lost.big_handle, p); + STREAM_TO_UINT8(big_sync_lost.reason, p); + + btm_ble_big_sync_lost_evt(&big_sync_lost); +} + +static void btu_ble_biginfo_adv_report_evt(UINT8 *p) +{ + tBTM_BLE_BIGINFO_ADV_REPORT_EVT biginfo_report = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT16(biginfo_report.sync_handle, p); + STREAM_TO_UINT8(biginfo_report.num_bis, p); + STREAM_TO_UINT8(biginfo_report.nse, p); + STREAM_TO_UINT16(biginfo_report.iso_interval, p); + STREAM_TO_UINT8(biginfo_report.bn, p); + STREAM_TO_UINT8(biginfo_report.pto, p); + STREAM_TO_UINT8(biginfo_report.irc, p); + STREAM_TO_UINT16(biginfo_report.max_pdu, p); + STREAM_TO_UINT24(biginfo_report.sdu_interval, p); + STREAM_TO_UINT16(biginfo_report.max_sdu, p); + STREAM_TO_UINT8(biginfo_report.phy, p); + STREAM_TO_UINT8(biginfo_report.framing, p); + STREAM_TO_UINT8(biginfo_report.encryption, p); + + btm_ble_biginfo_adv_report_evt(&biginfo_report); +} +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +static void btu_ble_cte_connless_iq_report_evt(UINT8 *p) +{ + tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT connless_iq_rpt = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT16(connless_iq_rpt.sync_handle, p); + STREAM_TO_UINT8(connless_iq_rpt.channel_idx, p); + STREAM_TO_UINT16(connless_iq_rpt.rssi, p); + STREAM_TO_UINT8(connless_iq_rpt.rssi_ant_id, p); + STREAM_TO_UINT8(connless_iq_rpt.cte_type, p); + STREAM_TO_UINT8(connless_iq_rpt.slot_dur, p); + STREAM_TO_UINT8(connless_iq_rpt.pkt_status, p); + STREAM_TO_UINT16(connless_iq_rpt.periodic_evt_counter, p); + STREAM_TO_UINT8(connless_iq_rpt.sample_count, p); + + for (uint8_t i = 0; i < connless_iq_rpt.sample_count; i++) + { + STREAM_TO_UINT8(connless_iq_rpt.i_sample[i], p); + STREAM_TO_UINT8(connless_iq_rpt.q_sample[i], p); + } + + btm_ble_connless_iq_report_evt(&connless_iq_rpt); +} +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +static void btu_ble_cte_conn_iq_report_evt(UINT8 *p) +{ + tBTM_BLE_CTE_CONN_IQ_REPORT_EVT conn_iq_rpt = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT16(conn_iq_rpt.conn_handle, p); + STREAM_TO_UINT8(conn_iq_rpt.rx_phy, p); + STREAM_TO_UINT8(conn_iq_rpt.data_channel_idx, p); + STREAM_TO_UINT16(conn_iq_rpt.rssi, p); + STREAM_TO_UINT8(conn_iq_rpt.rssi_ant_id, p); + STREAM_TO_UINT8(conn_iq_rpt.cte_type, p); + STREAM_TO_UINT8(conn_iq_rpt.slot_dur, p); + STREAM_TO_UINT8(conn_iq_rpt.pkt_status, p); + STREAM_TO_UINT16(conn_iq_rpt.conn_evt_counter, p); + STREAM_TO_UINT8(conn_iq_rpt.sample_count, p); + + for (uint8_t i = 0; i < conn_iq_rpt.sample_count; i++) + { + STREAM_TO_UINT8(conn_iq_rpt.i_sample[i], p); + STREAM_TO_UINT8(conn_iq_rpt.q_sample[i], p); + } + + btm_ble_conn_iq_report_evt(&conn_iq_rpt); +} + +static void btu_ble_cte_req_failed_evt(UINT8 *p) +{ + tBTM_BLE_CTE_REQ_FAILED_EVT cte_req_failed = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(cte_req_failed.status, p); + STREAM_TO_UINT16(cte_req_failed.conn_handle, p); + + btm_ble_cte_req_failed_evt(&cte_req_failed); +} +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +static void btu_ble_path_loss_threshold_evt(UINT8 *p) +{ + tBTM_BLE_PATH_LOSS_THRESHOLD_EVT path_loss_thres_evt = {0}; + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT16(path_loss_thres_evt.conn_handle, p); + STREAM_TO_UINT8(path_loss_thres_evt.cur_path_loss, p); + STREAM_TO_UINT8(path_loss_thres_evt.zone_entered, p); + + btm_ble_path_loss_threshold_evt(&path_loss_thres_evt); +} + +static void btu_ble_transmit_power_report_evt(UINT8 *p) +{ + tBTM_BLE_TRANS_POWER_REPORT_EVT trans_pwr_report_evt = {0}; + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(trans_pwr_report_evt.status, p); + STREAM_TO_UINT16(trans_pwr_report_evt.conn_handle, p); + STREAM_TO_UINT8(trans_pwr_report_evt.reason, p); + STREAM_TO_UINT8(trans_pwr_report_evt.phy, p); + STREAM_TO_UINT8(trans_pwr_report_evt.tx_power_level, p); + STREAM_TO_UINT8(trans_pwr_report_evt.tx_power_level_flag, p); + STREAM_TO_UINT8(trans_pwr_report_evt.delta, p); + + btm_ble_transmit_power_report_evt(&trans_pwr_report_evt); +} +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + +#if (BLE_FEAT_CONN_SUBRATING == TRUE) +static void btu_ble_subrate_change_evt(UINT8 *p) +{ + tBTM_BLE_SUBRATE_CHANGE_EVT subrate_change_evt = {0}; + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(subrate_change_evt.status, p); + STREAM_TO_UINT16(subrate_change_evt.conn_handle, p); + STREAM_TO_UINT16(subrate_change_evt.subrate_factor, p); + STREAM_TO_UINT16(subrate_change_evt.peripheral_latency, p); + STREAM_TO_UINT16(subrate_change_evt.continuation_number, p); + STREAM_TO_UINT16(subrate_change_evt.supervision_timeout, p); + + btm_ble_subrate_change_evt(&subrate_change_evt); +} +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + /********************************************** ** End of BLE Events Handler ***********************************************/ diff --git a/lib/bt/host/bluedroid/stack/btu/btu_init.c b/lib/bt/host/bluedroid/stack/btu/btu_init.c index 9ede9c2d..a00b3243 100644 --- a/lib/bt/host/bluedroid/stack/btu/btu_init.c +++ b/lib/bt/host/bluedroid/stack/btu/btu_init.c @@ -254,17 +254,6 @@ UINT16 BTU_BleAclPktSize(void) #endif } -#if SCAN_QUEUE_CONGEST_CHECK -bool BTU_check_queue_is_congest(void) -{ - if (osi_thread_queue_wait_size(btu_thread, 0) >= BT_QUEUE_CONGEST_SIZE) { - return true; - } - - return false; -} -#endif - int get_btu_work_queue_size(void) { return osi_thread_queue_wait_size(btu_thread, 0); diff --git a/lib/bt/host/bluedroid/stack/btu/btu_task.c b/lib/bt/host/bluedroid/stack/btu/btu_task.c index 9311a36d..bffa6837 100644 --- a/lib/bt/host/bluedroid/stack/btu/btu_task.c +++ b/lib/bt/host/bluedroid/stack/btu/btu_task.c @@ -229,11 +229,13 @@ bool btu_task_post(uint32_t sig, void *param, uint32_t timeout) break; case SIG_BTU_HCI_ADV_RPT_MSG: #if BLE_INCLUDED == TRUE +#if (BLE_42_SCAN_EN == TRUE) if (param != NULL) { btm_ble_adv_pkt_post(param); } btm_ble_adv_pkt_ready(); status = true; +#endif // #if (BLE_42_SCAN_EN == TRUE) #else osi_free(param); status = false; @@ -451,7 +453,7 @@ void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec) // NOTE: This value is in seconds but stored in a ticks field. p_tle->ticks = timeout_sec; p_tle->in_use = TRUE; - osi_alarm_set(alarm, (period_ms_t)(timeout_sec * 1000)); + osi_alarm_set(alarm, (period_ms_t)((period_ms_t)timeout_sec * 1000)); } diff --git a/lib/bt/host/bluedroid/stack/gatt/gatt_api.c b/lib/bt/host/bluedroid/stack/gatt/gatt_api.c index 8d8056f6..51e46e22 100644 --- a/lib/bt/host/bluedroid/stack/gatt/gatt_api.c +++ b/lib/bt/host/bluedroid/stack/gatt/gatt_api.c @@ -75,7 +75,7 @@ UINT8 GATT_SetTraceLevel (UINT8 new_level) ** ** Function GATTS_AddHandleRange ** -** Description This function add the allocated handles range for the specifed +** Description This function add the allocated handles range for the specified ** application UUID, service UUID and service instance ** ** Parameter p_hndl_range: pointer to allocated handles information @@ -105,7 +105,7 @@ BOOLEAN GATTS_AddHandleRange(tGATTS_HNDL_RANGE *p_hndl_range) ** NV save callback function. There can be one and only one ** NV save callback function. ** -** Parameter p_cb_info : callback informaiton +** Parameter p_cb_info : callback information ** ** Returns TRUE if registered OK, else FALSE ** @@ -151,7 +151,7 @@ static void gatt_update_for_database_change(void) ** num_handles : number of handles needed by the service. ** is_pri : is a primary service or not. ** -** Returns service handle if sucessful, otherwise 0. +** Returns service handle if successful, otherwise 0. ** *******************************************************************************/ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, @@ -170,7 +170,7 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, GATT_TRACE_API ("GATTS_CreateService\n" ); if (p_reg == NULL) { - GATT_TRACE_ERROR ("Inavlid gatt_if=%d\n", gatt_if); + GATT_TRACE_ERROR ("Invalid gatt_if=%d\n", gatt_if); return (0); } @@ -491,7 +491,7 @@ tGATT_STATUS GATTS_StartService (tGATT_IF gatt_if, UINT16 service_handle, return GATT_SERVICE_STARTED; } - /*this is a new application servoce start */ + /*this is a new application service start */ if ((i_sreg = gatt_sr_alloc_rcb(p_list)) == GATT_MAX_SR_PROFILES) { GATT_TRACE_ERROR ("GATTS_StartService: no free server registration block"); return GATT_NO_RESOURCES; @@ -1388,8 +1388,9 @@ void GATT_Deregister (tGATT_IF gatt_if) } } } - +#if (tGATT_BG_CONN_DEV == TRUE) gatt_deregister_bgdev_list(gatt_if); +#endif // #if (tGATT_BG_CONN_DEV == TRUE) /* update the listen mode */ #if (defined(BLE_PERIPHERAL_MODE_SUPPORT) && (BLE_PERIPHERAL_MODE_SUPPORT == TRUE)) GATT_Listen(gatt_if, FALSE, NULL); @@ -1468,9 +1469,12 @@ BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_ if (is_direct) { status = gatt_act_connect (p_reg, bd_addr, bd_addr_type, transport, is_aux); } else { +#if (tGATT_BG_CONN_DEV == TRUE) if (transport == BT_TRANSPORT_LE) { status = gatt_update_auto_connect_dev(gatt_if, TRUE, bd_addr, TRUE); - } else { + } else +#endif // #if (tGATT_BG_CONN_DEV == TRUE) + { GATT_TRACE_ERROR("Unsupported transport for background connection"); } } @@ -1483,7 +1487,7 @@ BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_ ** ** Function GATT_CancelConnect ** -** Description This function terminate the connection initaition to a remote +** Description This function terminate the connection initiation to a remote ** device on GATT channel. ** ** Parameters gatt_if: client interface. If 0 used as unconditionally disconnect, @@ -1527,6 +1531,7 @@ BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct status = gatt_cancel_open(gatt_if, bd_addr); } } else { +#if (tGATT_BG_CONN_DEV == TRUE) if (!gatt_if) { if (gatt_get_num_apps_for_bg_dev(bd_addr)) { while (gatt_find_app_for_bg_dev(bd_addr, &temp_gatt_if)) { @@ -1539,6 +1544,7 @@ BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct } else { status = gatt_remove_bg_dev_for_app(gatt_if, bd_addr); } +#endif // #if (tGATT_BG_CONN_DEV == TRUE) } return status; @@ -1628,7 +1634,7 @@ tGATT_STATUS GATT_SendServiceChangeIndication (BD_ADDR bd_addr) ** ** Function GATT_GetConnectionInfor ** -** Description This function use conn_id to find its associated BD address and applciation +** Description This function use conn_id to find its associated BD address and application ** interface ** ** Parameters conn_id: connection id (input) @@ -1665,7 +1671,7 @@ BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_ ** Function GATT_GetConnIdIfConnected ** ** Description This function find the conn_id if the logical link for BD address -** and applciation interface is connected +** and application interface is connected ** ** Parameters gatt_if: application interface (input) ** bd_addr: peer device address. (input) @@ -1720,7 +1726,9 @@ BOOLEAN GATT_Listen (tGATT_IF gatt_if, BOOLEAN start, BD_ADDR_PTR bd_addr) } if (bd_addr != NULL) { +#if (tGATT_BG_CONN_DEV == TRUE) gatt_update_auto_connect_dev(gatt_if, start, bd_addr, FALSE); +#endif // #if (tGATT_BG_CONN_DEV == TRUE) } else { p_reg->listening = start ? GATT_LISTEN_TO_ALL : GATT_LISTEN_TO_NONE; } diff --git a/lib/bt/host/bluedroid/stack/gatt/gatt_db.c b/lib/bt/host/bluedroid/stack/gatt/gatt_db.c index efae6413..8844ef5d 100644 --- a/lib/bt/host/bluedroid/stack/gatt/gatt_db.c +++ b/lib/bt/host/bluedroid/stack/gatt/gatt_db.c @@ -60,7 +60,7 @@ static BOOLEAN gatts_add_char_desc_value_check (tGATT_ATTR_VAL *attr_val, tGATTS ** Parameter p_db: database pointer. ** len: size of the memory space. ** -** Returns Status of te operation. +** Returns Status of the operation. ** *******************************************************************************/ BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri, @@ -94,7 +94,7 @@ BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN ** Parameter p_db: database pointer. ** len: size of the memory space. ** -** Returns Status of te operation. +** Returns Status of the operation. ** *******************************************************************************/ tBT_UUID *gatts_get_service_uuid (tGATT_SVC_DB *p_db) @@ -497,14 +497,14 @@ UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e ** Function gatts_add_characteristic ** ** Description This function add a characteristics and its descriptor into -** a servce identified by the service database pointer. +** a service identified by the service database pointer. ** ** Parameter p_db: database pointer. ** perm: permission (authentication and key size requirements) ** property: property of the characteristic. ** p_char: characteristic value information. ** -** Returns Status of te operation. +** Returns Status of the operation. ** *******************************************************************************/ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, @@ -1173,40 +1173,40 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, if ((op_code == GATT_SIGN_CMD_WRITE) && !(perm & GATT_WRITE_SIGNED_PERM)) { status = GATT_WRITE_NOT_PERMIT; - GATT_TRACE_DEBUG( "gatts_write_attr_perm_check - sign cmd write not allowed,handle:0x%04x",handle); + GATT_TRACE_DEBUG( "gatts_write_attr_perm_check - sign cmd write not allowed,handle %04x,perm %04x", handle, perm); } if ((op_code == GATT_SIGN_CMD_WRITE) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED)) { status = GATT_INVALID_PDU; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - Error!! sign cmd write sent on a encypted link,handle:0x%04x",handle); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - Error!! sign cmd write sent on a encrypted link,handle %04x,perm %04x", handle, perm); } else if (!(perm & GATT_WRITE_ALLOWED)) { status = GATT_WRITE_NOT_PERMIT; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_WRITE_NOT_PERMIT,handle:0x%04x",handle); + GATT_TRACE_ERROR("gatts_write_attr_perm_check - GATT_WRITE_NOT_PERMIT,handle %04x, perm %04x", handle, perm); } /* require authentication, but not been authenticated */ else if ((perm & GATT_WRITE_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED)) { status = GATT_INSUF_AUTHENTICATION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION,handle:0x%04x",handle); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION,handle %04x, perm %04x", handle, perm); } else if ((perm & GATT_WRITE_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED)) { status = GATT_INSUF_AUTHENTICATION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: MITM required,handle:0x%04x",handle); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: MITM required,handle %04x,perm %04x", handle, perm); } else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) { status = GATT_INSUF_ENCRYPTION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_ENCRYPTION,handle:0x%04x",handle); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_ENCRYPTION,handle:0x%04x, perm:0x%04x", handle, perm); } else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size)) { status = GATT_INSUF_KEY_SIZE; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE,handle:0x%04x",handle); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE,handle %04x,perm %04x", handle, perm); } /* LE Authorization check*/ else if ((perm & GATT_WRITE_AUTHORIZATION) && (!(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED) || !(sec_flag & GATT_SEC_FLAG_AUTHORIZATION))){ status = GATT_INSUF_AUTHORIZATION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHORIZATION,handle:0x%04x",handle); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHORIZATION,handle %04x,perm %04x", handle, perm); } /* LE security mode 2 attribute */ else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (perm & GATT_WRITE_ALLOWED) == 0) { status = GATT_INSUF_AUTHENTICATION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required,handle:0x%04x",handle); - } else { /* writable: must be char value declaration or char descritpors */ + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required,handle %04x,perm %04x", handle, perm); + } else { /* writable: must be char value declaration or char descriptors */ if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) { switch (p_attr->uuid) { case GATT_UUID_CHAR_PRESENT_FORMAT:/* should be readable only */ @@ -1215,13 +1215,19 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, case GATT_UUID_CHAR_VALID_RANGE: status = GATT_WRITE_NOT_PERMIT; break; - + case GATT_UUID_GAP_ICON:/* The Appearance characteristic value shall be 2 octets in length */ case GATT_UUID_CHAR_CLIENT_CONFIG: /* coverity[MISSING_BREAK] */ /* intnended fall through, ignored */ /* fall through */ case GATT_UUID_CHAR_SRVR_CONFIG: max_size = 2; + status = GATT_SUCCESS; + break; + case GATT_UUID_CLIENT_SUP_FEAT: + max_size = 1; + status = GATT_SUCCESS; + break; case GATT_UUID_CHAR_DESCRIPTION: default: /* any other must be character value declaration */ status = GATT_SUCCESS; @@ -1242,17 +1248,17 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, else if ( (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) && (p_attr->uuid == GATT_UUID_CHAR_CLIENT_CONFIG || p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG || - p_attr->uuid == GATT_UUID_CLIENT_SUP_FEAT || + p_attr->uuid == GATT_UUID_CLIENT_SUP_FEAT || p_attr->uuid == GATT_UUID_GAP_ICON ) ) // btla-specific -- { if (op_code == GATT_REQ_PREPARE_WRITE) { /* does not allow write blob */ status = GATT_REQ_NOT_SUPPORTED; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_REQ_NOT_SUPPORTED,handle:0x%04x",handle); + GATT_TRACE_ERROR("gatts_write_attr_perm_check - GATT_REQ_NOT_SUPPORTED,handle %04x,opcode %4x", handle, op_code); } else if (len != max_size) { /* data does not match the required format */ status = GATT_INVALID_ATTR_LEN; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INVALID_ATTR_LEN,handle:0x%04x",handle); + GATT_TRACE_ERROR("gatts_write_attr_perm_check - GATT_INVALID_ATTR_LEN,handle %04x,op_code %04x,len %d,max_size %d", handle, op_code, len, max_size); } else { status = GATT_SUCCESS; } @@ -1554,7 +1560,7 @@ static BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_ uuid.uu.uuid16 = GATT_UUID_SEC_SERVICE; } - /* add service declration record */ + /* add service declaration record */ if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ))) != NULL) { if (copy_extra_byte_in_db (p_db, (void **)&p_attr->p_value, sizeof(tBT_UUID))) { if (p_service->len == LEN_UUID_16) { diff --git a/lib/bt/host/bluedroid/stack/gatt/gatt_main.c b/lib/bt/host/bluedroid/stack/gatt/gatt_main.c index d76aefe9..53d9be74 100644 --- a/lib/bt/host/bluedroid/stack/gatt/gatt_main.c +++ b/lib/bt/host/bluedroid/stack/gatt/gatt_main.c @@ -502,7 +502,7 @@ static void gatt_le_connect_cback (UINT16 chan, BD_ADDR bd_addr, BOOLEAN connect #endif ///GATTS_INCLUDED == TRUE } } else { - GATT_TRACE_ERROR("CCB max out, no rsources"); + GATT_TRACE_ERROR("CCB max out, no resources"); } } } else { @@ -929,18 +929,23 @@ static void gatt_send_conn_cback(tGATT_TCB *p_tcb) { UINT8 i; tGATT_REG *p_reg; +#if (tGATT_BG_CONN_DEV == TRUE) tGATT_BG_CONN_DEV *p_bg_dev = NULL; +#endif // #if (tGATT_BG_CONN_DEV == TRUE) UINT16 conn_id; +#if (tGATT_BG_CONN_DEV == TRUE) p_bg_dev = gatt_find_bg_dev(p_tcb->peer_bda); +#endif // #if (tGATT_BG_CONN_DEV == TRUE) /* notifying all applications for the connection up event */ for (i = 0, p_reg = gatt_cb.cl_rcb ; i < GATT_MAX_APPS; i++, p_reg++) { if (p_reg->in_use) { +#if (tGATT_BG_CONN_DEV == TRUE) if (p_bg_dev && gatt_is_bg_dev_for_app(p_bg_dev, p_reg->gatt_if)) { gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, TRUE, TRUE); } - +#endif // #if (tGATT_BG_CONN_DEV == TRUE) if (p_reg->app_cb.p_conn_cb) { conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if); (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id, @@ -1239,7 +1244,8 @@ uint8_t gatt_tcb_active_count(void) for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) { p_tcb = list_node(p_node); - if (p_tcb && p_tcb->in_use && (p_tcb->ch_state != GATT_CH_CLOSE)) { + if (p_tcb && p_tcb->in_use && (p_tcb->transport == BT_TRANSPORT_LE) && + (p_tcb->ch_state != GATT_CH_CLOSE)) { count++; } } diff --git a/lib/bt/host/bluedroid/stack/gatt/gatt_sr.c b/lib/bt/host/bluedroid/stack/gatt/gatt_sr.c index 79e161c1..5947239c 100644 --- a/lib/bt/host/bluedroid/stack/gatt/gatt_sr.c +++ b/lib/bt/host/bluedroid/stack/gatt/gatt_sr.c @@ -200,7 +200,7 @@ static BOOLEAN process_read_multi_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS status, *p++ = GATT_RSP_READ_MULTI; p_buf->len = 1; - /* Now walk through the buffers puting the data into the response in order */ + /* Now walk through the buffers putting the data into the response in order */ list_t *list = NULL; const list_node_t *node = NULL; if (! fixed_queue_is_empty(p_cmd->multi_rsp_q)) { @@ -321,7 +321,7 @@ static BOOLEAN process_read_multi_var_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS sta *p++ = GATT_RSP_READ_MULTI_VAR; p_buf->len = 1; - /* Now walk through the buffers puting the data into the response in order */ + /* Now walk through the buffers putting the data into the response in order */ list_t *list = NULL; const list_node_t *node = NULL; if (! fixed_queue_is_empty(p_cmd->multi_rsp_q)) { @@ -735,7 +735,7 @@ static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_ handle_len = 4 + p_uuid->len; } - /* get the length byte in the repsonse */ + /* get the length byte in the response */ if (p_msg->offset == 0) { *p ++ = op_code + 1; p_msg->len ++; @@ -788,7 +788,7 @@ static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_ ** buffer. ** ** Returns TRUE: if data filled successfully. -** FALSE: packet full, or format mismatch. +** FALSE: packet full. ** *******************************************************************************/ static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg, UINT16 *p_len, @@ -831,10 +831,9 @@ static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg, gatt_convert_uuid32_to_uuid128(p, ((tGATT_ATTR32 *) p_attr)->uuid); p += LEN_UUID_128; } else { - GATT_TRACE_ERROR("format mismatch"); - status = GATT_NO_RESOURCES; + // UUID format mismatch in sequential attributes + // A new request will be sent with the starting handle of the next attribute break; - /* format mismatch */ } p_msg->len += info_pair_len[p_msg->offset - 1]; len -= info_pair_len[p_msg->offset - 1]; @@ -889,7 +888,7 @@ static tGATT_STATUS gatts_validate_packet_format(UINT8 op_code, UINT16 *p_len, /* parse uuid now */ if (gatt_parse_uuid_from_cmd (p_uuid_filter, uuid_len, &p) == FALSE || p_uuid_filter->len == 0) { - GATT_TRACE_DEBUG("UUID filter does not exsit"); + GATT_TRACE_DEBUG("UUID filter does not exist"); reason = GATT_INVALID_PDU; } else { len -= p_uuid_filter->len; @@ -1042,7 +1041,7 @@ static void gatts_process_find_info(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, ** ** Function gatts_process_mtu_req ** -** Description This function is called to process excahnge MTU request. +** Description This function is called to process exchange MTU request. ** Only used on LE. ** ** Returns void @@ -1055,7 +1054,7 @@ static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data) BT_HDR *p_buf; UINT16 conn_id; - /* BR/EDR conenction, send error response */ + /* BR/EDR connection, send error response */ if (p_tcb->att_lcid != L2CAP_ATT_CID) { gatt_send_error_rsp (p_tcb, GATT_REQ_NOT_SUPPORTED, GATT_REQ_MTU, 0, FALSE); } else if (len < GATT_MTU_REQ_MIN_LEN) { @@ -1081,7 +1080,7 @@ static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data) attp_send_sr_msg (p_tcb, p_buf); /* Notify all registered application with new MTU size. Us a transaction ID */ - /* of 0, as no response is allowed from applcations */ + /* of 0, as no response is allowed from applications */ for (i = 0; i < GATT_MAX_APPS; i ++) { if (gatt_cb.cl_rcb[i].in_use ) { @@ -1448,7 +1447,7 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand } if ((prepare_record->error_code_app == GATT_SUCCESS) - // update prepare write status for excute write request + // update prepare write status for execute write request && (status == GATT_INVALID_OFFSET || status == GATT_INVALID_ATTR_LEN || status == GATT_REQ_NOT_SUPPORTED)) { prepare_record->error_code_app = status; } @@ -1855,7 +1854,7 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code, gatts_process_primary_service_req (p_tcb, op_code, len, p_data); break; - case GATT_REQ_FIND_INFO: /* discover char descrptor */ + case GATT_REQ_FIND_INFO: /* discover char descriptor */ gatts_process_find_info(p_tcb, op_code, len, p_data); break; diff --git a/lib/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c b/lib/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c index 79d09d7a..d5a4b3a5 100644 --- a/lib/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c +++ b/lib/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c @@ -189,7 +189,6 @@ tGATT_STATUS gatts_calculate_datebase_hash(BT_OCTET16 hash) #if SMP_INCLUDED == TRUE BT_OCTET16 key = {0}; aes_cipher_msg_auth_code(key, data_buf, len, 16, hash); - //ESP_LOG_BUFFER_HEX("db hash", hash, BT_OCTET16_LEN); #endif osi_free(data_buf); diff --git a/lib/bt/host/bluedroid/stack/gatt/gatt_utils.c b/lib/bt/host/bluedroid/stack/gatt/gatt_utils.c index 621b2468..0644ab70 100644 --- a/lib/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/lib/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -108,7 +108,7 @@ void gatt_free_pending_ind(tGATT_TCB *p_tcb) ** ** Function gatt_free_pending_enc_queue ** -** Description Free all buffers in pending encyption queue +** Description Free all buffers in pending encryption queue ** ** Returns None ** @@ -222,7 +222,7 @@ void gatt_set_srv_chg(void) ** ** Description Find the app id in on the new service changed list ** -** Returns Pointer to the found new service changed item othwerwise NULL +** Returns Pointer to the found new service changed item otherwise NULL ** *******************************************************************************/ tGATTS_PENDING_NEW_SRV_START *gatt_sr_is_new_srv_chg(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst) @@ -299,7 +299,7 @@ tGATTS_PENDING_NEW_SRV_START *gatt_add_pending_new_srv_start(tGATTS_HNDL_RANGE * ** ** Function gatt_add_srv_chg_clt ** -** Description Add a service chnage client to the service change client queue +** Description Add a service change client to the service change client queue ** ** Returns Pointer to the service change client buffer; Null no buffer available ** @@ -682,7 +682,7 @@ BOOLEAN gatt_remove_a_srv_from_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ ** ** Function gatt_add_an_item_to_list ** -** Description add an service handle range to the list in decending +** Description add an service handle range to the list in descending ** order of the start handle ** ** Returns BOOLEAN TRUE-if add is successful @@ -808,7 +808,7 @@ BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found ** ** Function gatt_is_srv_chg_ind_pending ** -** Description Check whether a service chnaged is in the indication pending queue +** Description Check whether a service changed is in the indication pending queue ** or waiting for an Ack already ** ** Returns BOOLEAN @@ -846,9 +846,9 @@ BOOLEAN gatt_is_srv_chg_ind_pending (tGATT_TCB *p_tcb) ** ** Function gatt_is_bda_in_the_srv_chg_clt_list ** -** Description This function check the specified bda is in the srv chg clinet list or not +** Description This function check the specified bda is in the srv chg client list or not ** -** Returns pointer to the found elemenet otherwise NULL +** Returns pointer to the found element otherwise NULL ** *******************************************************************************/ tGATTS_SRV_CHG *gatt_is_bda_in_the_srv_chg_clt_list (BD_ADDR bda) @@ -1205,7 +1205,7 @@ UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid) if (uuid.len == LEN_UUID_16) { UINT16_TO_STREAM (p, uuid.uu.uuid16); len = LEN_UUID_16; - } else if (uuid.len == LEN_UUID_32) { /* always convert 32 bits into 128 bits as alwats */ + } else if (uuid.len == LEN_UUID_32) { /* always convert 32 bits into 128 bits as always */ gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32); p += LEN_UUID_128; len = LEN_UUID_128; @@ -1465,7 +1465,7 @@ UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list ) UINT8 ii = 0; tGATT_SR_REG *p_sreg = NULL; - /*this is a new application servoce start */ + /*this is a new application service start */ for (ii = 0, p_sreg = gatt_cb.sr_reg; ii < GATT_MAX_SR_PROFILES; ii++, p_sreg++) { if (!p_sreg->in_use) { memset (p_sreg, 0, sizeof(tGATT_SR_REG)); @@ -1616,7 +1616,7 @@ UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl) break; default: - GATT_TRACE_ERROR("inavlid UUID len=%d", p_uuid->len); + GATT_TRACE_ERROR("invalid UUID len=%d", p_uuid->len); SDP_DeleteRecord(sdp_handle); return 0; break; @@ -1633,7 +1633,7 @@ UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl) SDP_AddProtocolList(sdp_handle, 2, proto_elem_list); - /* Make the service browseable */ + /* Make the service browsable */ SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list); return (sdp_handle); @@ -1868,7 +1868,7 @@ UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb) ** ** Function gatt_num_clcb_by_bd_addr ** -** Description The function searches all LCB with macthing bd address +** Description The function searches all LCB with matching bd address ** ** Returns total number of clcb found. ** @@ -1892,7 +1892,7 @@ UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda) ** ** Function gatt_sr_update_cback_cnt ** -** Description The function searches all LCB with macthing bd address +** Description The function searches all LCB with matching bd address ** ** Returns total number of clcb found. ** @@ -1916,7 +1916,7 @@ void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB *p_tcb ) ** ** Function gatt_sr_is_cback_cnt_zero ** -** Description The function searches all LCB with macthing bd address +** Description The function searches all LCB with matching bd address ** ** Returns True if thetotal application callback count is zero ** @@ -2015,7 +2015,7 @@ void gatt_sr_reset_prep_cnt(tGATT_TCB *p_tcb ) ** ** Function gatt_sr_update_cback_cnt ** -** Description Update the teh application callback count +** Description Update the the application callback count ** ** Returns None ** @@ -2045,7 +2045,7 @@ void gatt_sr_update_cback_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc ** ** Function gatt_sr_update_prep_cnt ** -** Description Update the teh prepare write request count +** Description Update the the prepare write request count ** ** Returns None ** @@ -2461,7 +2461,7 @@ void gatt_dbg_display_uuid(tBT_UUID bt_uuid) } - +#if (tGATT_BG_CONN_DEV == TRUE) /******************************************************************************* ** ** Function gatt_is_bg_dev_for_app @@ -2552,7 +2552,7 @@ BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_init for (i = 0; i < GATT_MAX_APPS; i ++) { if (is_initator) { if (p_dev->gatt_if[i] == gatt_if) { - GATT_TRACE_ERROR("device already in iniator white list"); + GATT_TRACE_ERROR("device already in initiator white list"); return TRUE; } else if (p_dev->gatt_if[i] == 0) { p_dev->gatt_if[i] = gatt_if; @@ -2618,9 +2618,9 @@ BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr) ** ** Function gatt_get_num_apps_for_bg_dev ** -** Description Gte the number of applciations for the specified background device +** Description Gte the number of applications for the specified background device ** -** Returns UINT8 total number fo applications +** Returns UINT8 total number for applications ** *******************************************************************************/ UINT8 gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr) @@ -2842,7 +2842,7 @@ BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_ } return ret; } - +#endif // #if (tGATT_BG_CONN_DEV == TRUE) /******************************************************************************* diff --git a/lib/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/lib/bt/host/bluedroid/stack/gatt/include/gatt_int.h index 1161da62..f9d3cd8e 100644 --- a/lib/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/lib/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -130,7 +130,7 @@ typedef union { tGATT_EXEC_FLAG exec_write; /* execute write */ } tGATT_CL_MSG; -/* error response strucutre */ +/* error response structure */ typedef struct { UINT16 handle; UINT8 cmd_code; @@ -480,12 +480,14 @@ typedef struct { UINT32 service_change; } tGATT_SVC_CHG; +#if (tGATT_BG_CONN_DEV == TRUE) typedef struct { tGATT_IF gatt_if[GATT_MAX_APPS]; tGATT_IF listen_gif[GATT_MAX_APPS]; BD_ADDR remote_bda; BOOLEAN in_use; } tGATT_BG_CONN_DEV; +#endif // #if (tGATT_BG_CONN_DEV == TRUE) #define GATT_SVC_CHANGED_CONNECTING 1 /* wait for connection */ #define GATT_SVC_CHANGED_SERVICE 2 /* GATT service discovery */ @@ -553,8 +555,9 @@ typedef struct { tGATT_HDL_CFG hdl_cfg; +#if (tGATT_BG_CONN_DEV == TRUE) tGATT_BG_CONN_DEV bgconn_dev[GATT_MAX_BG_CONN_DEV]; - +#endif // #if (tGATT_BG_CONN_DEV == TRUE) BOOLEAN auto_disc; /* internal use: true for auto discovering after connected */ UINT8 srv_chg_mode; /* internal use: service change mode */ tGATTS_RSP rsp; /* use to read internal service attribute */ @@ -667,6 +670,7 @@ extern BOOLEAN gatt_add_an_item_to_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_L extern BOOLEAN gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIST_ELEM *p_remove); extern tGATTS_SRV_CHG *gatt_add_srv_chg_clt(tGATTS_SRV_CHG *p_srv_chg); +#if (tGATT_BG_CONN_DEV == TRUE) /* for background connection */ extern BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initiator); extern BOOLEAN gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV *p_dev, tGATT_IF gatt_if); @@ -676,6 +680,7 @@ extern BOOLEAN gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF *p_gatt_if); extern tGATT_BG_CONN_DEV *gatt_find_bg_dev(BD_ADDR remote_bda); extern void gatt_deregister_bgdev_list(tGATT_IF gatt_if); extern void gatt_reset_bgdev_list(void); +#endif // #if (tGATT_BG_CONN_DEV == TRUE) /* server function */ extern UINT8 gatt_sr_find_i_rcb_by_handle(UINT16 handle); diff --git a/lib/bt/host/bluedroid/stack/goep/goepc_api.c b/lib/bt/host/bluedroid/stack/goep/goepc_api.c new file mode 100644 index 00000000..06be8f59 --- /dev/null +++ b/lib/bt/host/bluedroid/stack/goep/goepc_api.c @@ -0,0 +1,376 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> + +#include "osi/osi.h" +#include "osi/allocator.h" +#include "common/bt_target.h" + +#include "stack/obex_api.h" +#include "stack/goep_common.h" +#include "stack/goepc_api.h" +#include "goep_int.h" + +#if (GOEPC_INCLUDED == TRUE) + +/******************************************************************************* +** +** Function GOEPC_Init +** +** Description Initialize GOEP Client role, must call before using any +** other GOEPC APIs +** +** Returns GOEP_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 GOEPC_Init(void) +{ +#if (GOEP_DYNAMIC_MEMORY) + if (!goepc_cb_ptr) { + goepc_cb_ptr = (tGOEPC_CB *)osi_malloc(sizeof(tGOEPC_CB)); + if (!goepc_cb_ptr) { + return GOEP_NO_RESOURCES; + } + } +#endif /* #if (GOEP_DYNAMIC_MEMORY) */ + memset(&goepc_cb, 0, sizeof(tGOEPC_CB)); + goepc_cb.trace_level = BT_TRACE_LEVEL_ERROR; + return GOEP_SUCCESS; +} + +/******************************************************************************* +** +** Function GOEPC_Deinit +** +** Description Deinit GOEP Client role, once deinit, can not use any other +** GOEPC APIs until call GOEPC_Init again +** +*******************************************************************************/ +void GOEPC_Deinit(void) +{ +#if (GOEP_DYNAMIC_MEMORY) + if (goepc_cb_ptr) { + osi_free(goepc_cb_ptr); + goepc_cb_ptr = NULL; + } +#endif /* #if (GOEP_DYNAMIC_MEMORY) */ +} + +/******************************************************************************* +** +** Function GOEPC_Open +** +** Description Start the progress to establish a GOEP connection to server +** +** Returns GOEP_SUCCESS if successful, otherwise failed, when the +** connection is established, GOEPC_OPENED_EVT will come +** +*******************************************************************************/ +UINT16 GOEPC_Open(tOBEX_SVR_INFO *svr, tGOEPC_EVT_CBACK callback, UINT16 *out_handle) +{ + UINT16 ret = GOEP_SUCCESS; + tGOEPC_CCB *p_ccb = NULL; + + do { + /* check parameter, allow out_handle to be NULL */ + if (svr == NULL || callback == NULL) { + ret = GOEP_INVALID_PARAM; + break; + } + + p_ccb = goepc_allocate_ccb(); + if (p_ccb == NULL) { + ret = GOEP_NO_RESOURCES; + break; + } + + if (OBEX_CreateConn(svr, goepc_obex_callback, &p_ccb->obex_handle) != OBEX_SUCCESS) { + ret = GOEP_TL_ERROR; + break; + } + + /* success */ + p_ccb->callback = callback; + p_ccb->state = GOEPC_STATE_OPENING; + if (out_handle) { + *out_handle = p_ccb->allocated; + } + } while (0); + + if (ret != GOEP_SUCCESS && p_ccb != NULL) { + goepc_free_ccb(p_ccb); + } + return ret; +} + +/******************************************************************************* +** +** Function GOEPC_Close +** +** Description Close a GOEP connection immediately +** +** Returns GOEP_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 GOEPC_Close(UINT16 handle) +{ + tGOEPC_CCB *p_ccb = NULL; + + UINT16 ccb_idx = handle - 1; + if (ccb_idx >= GOEPC_MAX_CONNECTION || !goepc_cb.ccb[ccb_idx].allocated) { + return GOEP_BAD_HANDLE; + } + + p_ccb = &goepc_cb.ccb[ccb_idx]; + if (p_ccb->obex_handle) { + OBEX_RemoveConn(p_ccb->obex_handle); + } + goepc_free_ccb(p_ccb); + + return GOEP_SUCCESS; +} + +/******************************************************************************* +** +** Function GOEPC_SendRequest +** +** Description Send the prepared request packet to server +** +** Returns GOEP_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 GOEPC_SendRequest(UINT16 handle) +{ + UINT16 ret = GOEP_SUCCESS; + tGOEPC_CCB *p_ccb = NULL; + BOOLEAN final = FALSE; + + do { + UINT16 ccb_idx = handle - 1; + if (ccb_idx >= GOEPC_MAX_CONNECTION || !goepc_cb.ccb[ccb_idx].allocated) { + ret = GOEP_BAD_HANDLE; + break; + } + p_ccb = &goepc_cb.ccb[ccb_idx]; + + if (p_ccb->pkt == NULL) { + ret = GOEP_INVALID_STATE; + break; + } + + final = OBEX_CheckFinalBit(p_ccb->pkt); + /* check whether state machine allow this operation */ + if (!goepc_check_obex_req_allow(p_ccb->state, final)) { + ret = GOEP_INVALID_STATE; + break; + } + + if (p_ccb->congest) { + ret = GOEP_CONGEST; + break; + } + + /* execute srm state machine */ + goepc_srm_sm_execute(p_ccb, TRUE, p_ccb->pkt_srm_en, p_ccb->pkt_srm_wait); + + tGOEPC_DATA data; + data.pkt = p_ccb->pkt; + + p_ccb->last_pkt_opcode = p_ccb->curr_pkt_opcode; + p_ccb->pkt = NULL; + p_ccb->pkt_srm_en = FALSE; + p_ccb->pkt_srm_wait = FALSE; + + /* execute main state machine */ + if (final) { + goepc_sm_execute(p_ccb, GOEPC_SM_EVENT_REQ_FB, &data); + } + else { + goepc_sm_execute(p_ccb, GOEPC_SM_EVENT_REQ, &data); + } + /* since goepc_sm_execute may free ccb, can not access ccb here */ + } while (0); + + return ret; +} + +/******************************************************************************* +** +** Function GOEPC_PrepareRequest +** +** Description Prepare a request packet, packet will be store internally +** +** Returns GOEP_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 GOEPC_PrepareRequest(UINT16 handle, tOBEX_PARSE_INFO *info, UINT16 buff_size) +{ + UINT16 ret = GOEP_SUCCESS; + tGOEPC_CCB *p_ccb = NULL; + BT_HDR *pkt = NULL; + + do { + UINT16 ccb_idx = handle - 1; + if (ccb_idx >= GOEPC_MAX_CONNECTION || !goepc_cb.ccb[ccb_idx].allocated) { + ret = GOEP_BAD_HANDLE; + break; + } + p_ccb = &goepc_cb.ccb[ccb_idx]; + + if (info == NULL || buff_size < OBEX_MIN_PACKET_SIZE) { + ret = GOEP_INVALID_PARAM; + break; + } + + if (p_ccb->pkt != NULL) { + ret = GOEP_INVALID_STATE; + break; + } + + if (!goepc_check_obex_req_param(info)) { + ret = GOEP_INVALID_PARAM; + break; + } + + if (OBEX_BuildRequest(info, buff_size, &pkt) != OBEX_SUCCESS) { + ret = GOEP_NO_RESOURCES; + break; + } + + p_ccb->curr_pkt_opcode = info->opcode; + p_ccb->pkt = pkt; + } while (0); + + return ret; +} + +/******************************************************************************* +** +** Function GOEPC_DropRequest +** +** Description Drop the prepared internal request packet +** +** Returns GOEP_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 GOEPC_DropRequest(UINT16 handle) +{ + UINT16 ccb_idx = handle - 1; + if (ccb_idx >= GOEPC_MAX_CONNECTION || !goepc_cb.ccb[ccb_idx].allocated) { + return GOEP_BAD_HANDLE; + } + + tGOEPC_CCB *p_ccb = &goepc_cb.ccb[ccb_idx]; + if (p_ccb->pkt == NULL) { + return GOEP_INVALID_STATE; + } + + osi_free(p_ccb->pkt); + p_ccb->pkt = NULL; + p_ccb->pkt_srm_en = FALSE; + p_ccb->pkt_srm_wait = FALSE; + return GOEP_SUCCESS; +} + +/******************************************************************************* +** +** Function GOEPC_RequestSetSRM +** +** Description Modify the prepared internal request packet, append SRM header +** or SRMP header +** +** Returns GOEP_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 GOEPC_RequestSetSRM(UINT16 handle, BOOLEAN srm_en, BOOLEAN srm_wait) +{ + UINT16 ret = GOEP_SUCCESS; + tGOEPC_CCB *p_ccb = NULL; + + do { + UINT16 ccb_idx = handle - 1; + if (ccb_idx >= GOEPC_MAX_CONNECTION || !goepc_cb.ccb[ccb_idx].allocated) { + ret = GOEP_BAD_HANDLE; + break; + } + p_ccb = &goepc_cb.ccb[ccb_idx]; + + if (!srm_en && !srm_wait) { + ret = GOEP_INVALID_PARAM; + break; + } + + if (p_ccb->pkt == NULL) { + ret = GOEP_INVALID_STATE; + break; + } + + if (srm_en) { + if (OBEX_AppendHeaderSRM(p_ccb->pkt, OBEX_SRM_ENABLE) == OBEX_SUCCESS) { + p_ccb->pkt_srm_en = TRUE; + } + else { + ret = GOEP_NO_RESOURCES; + break; + } + } + if (srm_wait) { + if (OBEX_AppendHeaderSRMP(p_ccb->pkt, OBEX_SRMP_WAIT) == OBEX_SUCCESS) { + p_ccb->pkt_srm_wait = TRUE; + } + else { + ret = GOEP_NO_RESOURCES; + break; + } + } + } while (0); + + return ret; +} + +/******************************************************************************* +** +** Function GOEPC_RequestAddHeader +** +** Description Modify the prepared internal request packet, append header +** +** Returns GOEP_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 GOEPC_RequestAddHeader(UINT16 handle, UINT8 header_id, const UINT8 *data, UINT16 data_len) +{ + UINT16 ret = GOEP_SUCCESS; + tGOEPC_CCB *p_ccb = NULL; + + do { + UINT16 ccb_idx = handle - 1; + if (ccb_idx >= GOEPC_MAX_CONNECTION || !goepc_cb.ccb[ccb_idx].allocated) { + ret = GOEP_BAD_HANDLE; + break; + } + p_ccb = &goepc_cb.ccb[ccb_idx]; + + if (p_ccb->pkt == NULL) { + ret = GOEP_INVALID_STATE; + break; + } + + if ((data == NULL && data_len != 0) || (data != NULL && data_len == 0)) { + ret = GOEP_INVALID_PARAM; + break; + } + + if (OBEX_AppendHeaderRaw(p_ccb->pkt, header_id, data, data_len) != OBEX_SUCCESS) { + ret = GOEP_NO_RESOURCES; + break; + } + } while (0); + + return ret; +} + +#endif /* #if (GOEPC_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/goep/goepc_main.c b/lib/bt/host/bluedroid/stack/goep/goepc_main.c new file mode 100644 index 00000000..e0859580 --- /dev/null +++ b/lib/bt/host/bluedroid/stack/goep/goepc_main.c @@ -0,0 +1,528 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> + +#include "osi/osi.h" +#include "osi/allocator.h" +#include "common/bt_target.h" + +#include "stack/obex_api.h" +#include "stack/goep_common.h" +#include "stack/goepc_api.h" +#include "goep_int.h" + +#if (GOEPC_INCLUDED == TRUE) + +#if GOEP_DYNAMIC_MEMORY == FALSE +tGOEPC_CB goepc_cb; +#else +tGOEPC_CB *goepc_cb_ptr = NULL; +#endif + +tGOEPC_CCB *goepc_allocate_ccb(void) +{ + tGOEPC_CCB *p_ccb = NULL; + for (int i = 0; i < GOEPC_MAX_CONNECTION; ++i) { + if (!goepc_cb.ccb[i].allocated) { + goepc_cb.ccb[i].allocated = i + 1; + p_ccb = &goepc_cb.ccb[i]; + break; + } + } + return p_ccb; +} + +void goepc_free_ccb(tGOEPC_CCB *p_ccb) +{ + if (p_ccb->pkt != NULL) { + osi_free(p_ccb->pkt); + } + memset(p_ccb, 0, sizeof(tGOEPC_CCB)); +} + +BOOLEAN goepc_check_obex_req_param(tOBEX_PARSE_INFO *info) +{ + BOOLEAN ret = TRUE; + switch (info->opcode) + { + case OBEX_OPCODE_CONNECT: + if (info->max_packet_length < 255 || info->obex_version_number == 0) { + ret = FALSE; + } + break; + case OBEX_OPCODE_DISCONNECT: + case OBEX_OPCODE_PUT: + case OBEX_OPCODE_PUT_FINAL: + case OBEX_OPCODE_GET: + case OBEX_OPCODE_GET_FINAL: + case OBEX_OPCODE_SETPATH: + case OBEX_OPCODE_ACTION: + case OBEX_OPCODE_SESSION: + /* opcode allowed */ + break; + case OBEX_OPCODE_ABORT: + default: + ret = FALSE; + /* opcode not allowed */ + break; + } + + return ret; +} + +static tGOEPC_CCB *find_ccb_by_obex_handle(UINT16 obex_handle) +{ + tGOEPC_CCB *p_ccb = NULL; + for (int i = 0; i < GOEPC_MAX_CONNECTION; ++i) { + if (goepc_cb.ccb[i].allocated && goepc_cb.ccb[i].obex_handle == obex_handle) { + p_ccb = &goepc_cb.ccb[i]; + } + } + return p_ccb; +} + +static void goepc_extra_srm_rsp(UINT8 opcode, BT_HDR *pkt, BOOLEAN *srm_en, BOOLEAN *srm_wait) +{ + tOBEX_PARSE_INFO info; + BOOLEAN srm_found = FALSE; + BOOLEAN srmp_found = FALSE; + if (OBEX_ParseResponse(pkt, opcode, &info) == OBEX_SUCCESS) { + UINT8 *header = NULL; + while((header = OBEX_GetNextHeader(pkt, &info)) != NULL) { + switch (*header) + { + case OBEX_HEADER_ID_SRM: + if (header[1] == OBEX_SRM_ENABLE) { + *srm_en = TRUE; + } + srm_found = TRUE; + break; + case OBEX_HEADER_ID_SRM_PARAM: + switch (header[1]) + { + case OBEX_SRMP_ADD_PKT: + /* goep should not use this */ + break; + case OBEX_SRMP_WAIT: + *srm_wait = TRUE; + break; + case OBEX_SRMP_ADD_PKT_WAIT: + /* goep should not use this */ + break; + default: + break; + } + srmp_found = TRUE; + break; + default: + break; + } + if (srm_found && srmp_found) { + break; + } + } + } +} + +static void goepc_act_congest(tGOEPC_CCB *p_ccb) +{ + p_ccb->congest = TRUE; + p_ccb->callback(p_ccb->allocated, GOEPC_CONGEST_EVT, NULL); +} + +static void goepc_act_uncongest(tGOEPC_CCB *p_ccb) +{ + p_ccb->congest = FALSE; + p_ccb->callback(p_ccb->allocated, GOEPC_UNCONGEST_EVT, NULL); +} + +static void goepc_act_mtu_chg(tGOEPC_CCB *p_ccb, tGOEPC_MTU_CHG *mtu_chg) +{ + tGOEPC_MSG msg; + msg.mtu_changed.peer_mtu = mtu_chg->peer_mtu; + msg.mtu_changed.our_mtu = mtu_chg->our_mtu; + p_ccb->peer_mtu = mtu_chg->peer_mtu; + p_ccb->our_mtu = mtu_chg->our_mtu; + p_ccb->callback(p_ccb->allocated, GOEPC_MTU_CHANGED_EVT, &msg); +} + +void goepc_obex_callback(UINT16 handle, UINT8 event, tOBEX_MSG *msg) +{ + tGOEPC_DATA data; + UINT8 goepc_sm_event = GOEPC_SM_EVENT_DISCONNECT; + BOOLEAN exec_sm = FALSE; + tGOEPC_CCB *p_ccb = find_ccb_by_obex_handle(handle); + if (p_ccb == NULL) { + GOEPC_TRACE_ERROR("goepc_obex_callback can not find a ccb\n"); + /* can not find a ccb in goepc, free resource and remove this connection */ + if (event == OBEX_DATA_EVT && msg->data.pkt) { + osi_free(msg->data.pkt); + } + OBEX_RemoveConn(handle); + return; + } + + switch (event) + { + case OBEX_CONNECT_EVT: + data.connected.peer_mtu = msg->connect.peer_mtu; + data.connected.our_mtu = msg->connect.our_mtu; + goepc_sm_event = GOEPC_SM_EVENT_CONNECT; + exec_sm = TRUE; + break; + case OBEX_MTU_CHANGE_EVT: + data.mtu_chg.peer_mtu = msg->mtu_change.peer_mtu; + data.mtu_chg.our_mtu = msg->mtu_change.our_mtu; + goepc_act_mtu_chg(p_ccb, &data.mtu_chg); + break; + case OBEX_DISCONNECT_EVT: + /* when we received this event, obex connection already disconnect */ + p_ccb->obex_handle = 0; + goepc_sm_event = GOEPC_SM_EVENT_DISCONNECT;; + exec_sm = TRUE; + break; + case OBEX_CONGEST_EVT: + goepc_act_congest(p_ccb); + break; + case OBEX_UNCONGEST_EVT: + goepc_act_uncongest(p_ccb); + break; + case OBEX_DATA_EVT: + data.pkt = msg->data.pkt; + if (OBEX_CheckContinueResponse(data.pkt)) { + /* in OBEX 1.0, final bit of response code will always set, we need to check this */ + goepc_sm_event = GOEPC_SM_EVENT_RSP; + } + else if (OBEX_CheckFinalBit(data.pkt)) { + goepc_sm_event = GOEPC_SM_EVENT_RSP_FB; + } + else { + goepc_sm_event = GOEPC_SM_EVENT_RSP; + } + exec_sm = TRUE; + break; + default: + /* other event, ignore */ + break; + } + + if (exec_sm) { + goepc_sm_execute(p_ccb, goepc_sm_event, &data); + } +} + +static void goepc_sm_act_connect(tGOEPC_CCB *p_ccb, tGOEPC_CONNECTED *connected) +{ + tGOEPC_MSG msg; + msg.opened.peer_mtu = connected->peer_mtu; + msg.opened.our_mtu = connected->our_mtu; + p_ccb->peer_mtu = connected->peer_mtu; + p_ccb->our_mtu = connected->our_mtu; + + /* main state machine transfer to OPENED_IDLE */ + p_ccb->state = GOEPC_STATE_OPENED_IDLE; + p_ccb->callback(p_ccb->allocated, GOEPC_OPENED_EVT, &msg); +} + +static void goepc_sm_act_disconnect(tGOEPC_CCB *p_ccb) +{ + tGOEPC_MSG msg; + if (p_ccb->obex_handle) { + OBEX_RemoveConn(p_ccb->obex_handle); + } + msg.closed.reason = GOEP_TL_ERROR; + p_ccb->callback(p_ccb->allocated, GOEPC_CLOSED_EVT, &msg); + /* free ccb, main state machine end */ + goepc_free_ccb(p_ccb); +} + +static void goepc_sm_act_send_req(tGOEPC_CCB *p_ccb, BT_HDR *pkt) +{ + UINT16 ret = OBEX_SendPacket(p_ccb->obex_handle, pkt); + if (ret == OBEX_SUCCESS) { + /* main state machine transfer to OPENED_REQ */ + p_ccb->state = GOEPC_STATE_OPENED_REQ; + } + else { + /* send failed, something error in transport layer, disconnect */ + goepc_sm_act_disconnect(p_ccb); + } +} + +static void goepc_sm_act_send_req_fb(tGOEPC_CCB *p_ccb, BT_HDR *pkt) +{ + UINT16 ret = OBEX_SendPacket(p_ccb->obex_handle, pkt); + if (ret == OBEX_SUCCESS) { + /* main state machine transfer to OPENED_RSP */ + p_ccb->state = GOEPC_STATE_OPENED_RSP; + } + else { + /* send failed, something error in transport layer, disconnect */ + goepc_sm_act_disconnect(p_ccb); + } +} + +static void goepc_sm_act_rsp(tGOEPC_CCB *p_ccb, BT_HDR *pkt) +{ + /* handle srm state transfer */ + BOOLEAN srm_en = FALSE; + BOOLEAN srm_wait = FALSE; + goepc_extra_srm_rsp(p_ccb->last_pkt_opcode, pkt, &srm_en, &srm_wait); + goepc_srm_sm_execute(p_ccb, FALSE, srm_en, srm_wait); + /* main state machine not change */ + + tGOEPC_MSG msg; + msg.response.opcode = p_ccb->last_pkt_opcode; + msg.response.final = FALSE; + msg.response.srm_en = (p_ccb->srm_state == GOEPC_SRM_STATE_ENABLE_WAIT || p_ccb->srm_state == GOEPC_SRM_STATE_ENABLE); + msg.response.srm_wait = (p_ccb->srm_state == GOEPC_SRM_STATE_ENABLE_WAIT); + msg.response.pkt = pkt; + p_ccb->callback(p_ccb->allocated, GOEPC_RESPONSE_EVT, &msg); +} + +static void goepc_sm_act_rsp_fb(tGOEPC_CCB *p_ccb, BT_HDR *pkt) +{ + tGOEPC_MSG msg; + msg.response.opcode = p_ccb->last_pkt_opcode; + msg.response.final = TRUE; + msg.response.srm_en = FALSE; + msg.response.srm_wait = FALSE; + msg.response.pkt = pkt; + /* operation complete, reset srm state */ + p_ccb->srm_state = GOEPC_SRM_STATE_IDLE; + /* main state machine transfer to OPENED_IDLE */ + p_ccb->state = GOEPC_STATE_OPENED_IDLE; + p_ccb->callback(p_ccb->allocated, GOEPC_RESPONSE_EVT, &msg); +} + + +static void goepc_sm_state_opening(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data) +{ + switch (event) + { + case GOEPC_SM_EVENT_CONNECT: + goepc_sm_act_connect(p_ccb, &p_data->connected); + break; + case GOEPC_SM_EVENT_DISCONNECT: + goepc_sm_act_disconnect(p_ccb); + break; + case GOEPC_SM_EVENT_RSP: + case GOEPC_SM_EVENT_RSP_FB: + GOEPC_TRACE_ERROR("goepc_sm_state_opening received unexpected response from peer\n"); + if (p_data->pkt != NULL) { + osi_free(p_data->pkt); + } + goepc_sm_act_disconnect(p_ccb); + break; + default: + GOEPC_TRACE_ERROR("goepc_sm_state_opening unexpected event: 0x%x\n", event); + break; + } +} + +static void goepc_sm_state_opened_idle(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data) +{ + switch (event) + { + case GOEPC_SM_EVENT_DISCONNECT: + goepc_sm_act_disconnect(p_ccb); + break; + case GOEPC_SM_EVENT_REQ: + goepc_sm_act_send_req(p_ccb, p_data->pkt); + break; + case GOEPC_SM_EVENT_REQ_FB: + goepc_sm_act_send_req_fb(p_ccb, p_data->pkt); + break; + case GOEPC_SM_EVENT_RSP: + case GOEPC_SM_EVENT_RSP_FB: + GOEPC_TRACE_ERROR("goepc_sm_state_opened_idle received unexpected response from peer\n"); + /* peer sent a packet to us when we didn't request */ + if (p_data->pkt != NULL) { + osi_free(p_data->pkt); + } + goepc_sm_act_disconnect(p_ccb); + break; + default: + GOEPC_TRACE_ERROR("goepc_sm_state_opened_idle unexpected event: 0x%x\n", event); + break; + } +} + +static void goepc_sm_state_opened_req(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data) +{ + switch (event) + { + case GOEPC_SM_EVENT_DISCONNECT: + goepc_sm_act_disconnect(p_ccb); + break; + case GOEPC_SM_EVENT_REQ: + goepc_sm_act_send_req(p_ccb, p_data->pkt); + break; + case GOEPC_SM_EVENT_REQ_FB: + goepc_sm_act_send_req_fb(p_ccb, p_data->pkt); + break; + case GOEPC_SM_EVENT_RSP: + goepc_sm_act_rsp(p_ccb, p_data->pkt); + break; + case GOEPC_SM_EVENT_RSP_FB: + goepc_sm_act_rsp_fb(p_ccb, p_data->pkt); + break; + default: + GOEPC_TRACE_ERROR("goepc_sm_state_opened_req unexpected event: 0x%x\n", event); + break; + } +} + +static void goepc_sm_state_opened_rsp(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data) +{ + switch (event) + { + case GOEPC_SM_EVENT_DISCONNECT: + goepc_sm_act_disconnect(p_ccb); + break; + case GOEPC_SM_EVENT_REQ_FB: + goepc_sm_act_send_req_fb(p_ccb, p_data->pkt); + break; + case GOEPC_SM_EVENT_RSP: + goepc_sm_act_rsp(p_ccb, p_data->pkt); + break; + case GOEPC_SM_EVENT_RSP_FB: + goepc_sm_act_rsp_fb(p_ccb, p_data->pkt); + break; + default: + GOEPC_TRACE_ERROR("goepc_sm_state_opened_rsp unexpected event: 0x%x\n", event); + break; + } +} + +BOOLEAN goepc_check_obex_req_allow(UINT8 state, BOOLEAN final) +{ + BOOLEAN ret = FALSE; + if (final) { + switch (state) + { + case GOEPC_STATE_OPENED_IDLE: + case GOEPC_STATE_OPENED_REQ: + case GOEPC_STATE_OPENED_RSP: + ret = TRUE; + break; + default: + break; + } + } + else { + switch (state) + { + case GOEPC_STATE_OPENED_IDLE: + case GOEPC_STATE_OPENED_REQ: + ret = TRUE; + break; + default: + break; + } + } + return ret; +} + +void goepc_sm_execute(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data) +{ + switch (p_ccb->state) + { + case GOEPC_STATE_INIT: + /* do nothing */ + break; + case GOEPC_STATE_OPENING: + goepc_sm_state_opening(p_ccb, event, p_data); + break; + case GOEPC_STATE_OPENED_IDLE: + goepc_sm_state_opened_idle(p_ccb, event, p_data); + break; + case GOEPC_STATE_OPENED_REQ: + goepc_sm_state_opened_req(p_ccb, event, p_data); + break; + case GOEPC_STATE_OPENED_RSP: + goepc_sm_state_opened_rsp(p_ccb, event, p_data); + break; + default: + GOEPC_TRACE_ERROR("goepc_sm_execute unexpected state: 0x%x\n", p_ccb->state); + break; + } +} + +static void goepc_srm_sm_act_req(tGOEPC_CCB *p_ccb, BOOLEAN srm_en, BOOLEAN srm_wait) +{ + switch (p_ccb->srm_state) + { + case GOEPC_SRM_STATE_IDLE: + if (srm_en) { + p_ccb->srm_state = GOEPC_SRM_STATE_REQ; + p_ccb->srm_wait = srm_wait; + } + else { + p_ccb->srm_state = GOEPC_SRM_STATE_DISABLE; + } + break; + case GOEPC_SRM_STATE_ENABLE_WAIT: + if (!srm_wait) { + p_ccb->srm_wait = FALSE; + } + if (!p_ccb->srm_wait && !p_ccb->srm_peer_wait) { + /* no more wait, transfer to ENABLE */ + p_ccb->srm_state = GOEPC_SRM_STATE_ENABLE; + } + break; + default: + break; + } +} + +static void goepc_srm_sm_act_rsp(tGOEPC_CCB *p_ccb, BOOLEAN srm_en, BOOLEAN srm_wait) +{ + switch (p_ccb->srm_state) + { + case GOEPC_SRM_STATE_IDLE: + /* peer can not request to enable srm, ignore */ + break; + case GOEPC_SRM_STATE_REQ: + if (srm_en) { + p_ccb->srm_peer_wait = srm_wait; + if (p_ccb->srm_wait || p_ccb->srm_peer_wait) { + p_ccb->srm_state = GOEPC_SRM_STATE_ENABLE_WAIT; + } + else { + p_ccb->srm_state = GOEPC_SRM_STATE_ENABLE; + } + } + else { + p_ccb->srm_state = GOEPC_SRM_STATE_DISABLE; + } + break; + case GOEPC_SRM_STATE_ENABLE_WAIT: + if (!srm_wait) { + p_ccb->srm_peer_wait = FALSE; + } + if (!p_ccb->srm_wait && !p_ccb->srm_peer_wait) { + /* no more wait, transfer to ENABLE */ + p_ccb->srm_state = GOEPC_SRM_STATE_ENABLE; + } + break; + default: + break; + } +} + +void goepc_srm_sm_execute(tGOEPC_CCB *p_ccb, BOOLEAN is_req, BOOLEAN srm_en, BOOLEAN srm_wait) +{ + if (is_req) { + goepc_srm_sm_act_req(p_ccb, srm_en, srm_wait); + } + else { + goepc_srm_sm_act_rsp(p_ccb, srm_en, srm_wait); + } +} + +#endif /* #if (GOEPC_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/goep/include/goep_int.h b/lib/bt/host/bluedroid/stack/goep/include/goep_int.h new file mode 100644 index 00000000..0c1915f6 --- /dev/null +++ b/lib/bt/host/bluedroid/stack/goep/include/goep_int.h @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "common/bt_target.h" + +#include "stack/obex_api.h" +#include "stack/goep_common.h" +#include "stack/goepc_api.h" + +#if (GOEPC_INCLUDED == TRUE) + +/* GOEPC state machine events */ +enum { + GOEPC_SM_EVENT_CONNECT = 0, + GOEPC_SM_EVENT_DISCONNECT, + GOEPC_SM_EVENT_REQ, + GOEPC_SM_EVENT_REQ_FB, + GOEPC_SM_EVENT_RSP, + GOEPC_SM_EVENT_RSP_FB, +}; + +/* GOEPC state machine states */ +enum { + GOEPC_STATE_INIT = 0, + GOEPC_STATE_OPENING, + GOEPC_STATE_OPENED_IDLE, + GOEPC_STATE_OPENED_REQ, + GOEPC_STATE_OPENED_RSP, +}; + +/* GOEPC srm state machine states */ +enum { + GOEPC_SRM_STATE_IDLE = 0, + GOEPC_SRM_STATE_REQ, + GOEPC_SRM_STATE_ENABLE_WAIT, + GOEPC_SRM_STATE_ENABLE, + GOEPC_SRM_STATE_DISABLE, +}; + +/* GOEPC Connection Control block */ +typedef struct { + tGOEPC_EVT_CBACK *callback; /* GOEP event callback function */ + UINT16 obex_handle; /* OBEX connection handle */ + UINT16 peer_mtu; /* lower layer connection peer MTU */ + UINT16 our_mtu; /* lower layer connection our MTU */ + BOOLEAN congest; /* lower layer connection congestion status */ + + BT_HDR *pkt; /* packet prepared in this GOEP client */ + BOOLEAN pkt_srm_en; /* whether prepared packet had set SRM to enable */ + BOOLEAN pkt_srm_wait; /* whether prepared packet had set SRMP to wait */ + UINT8 curr_pkt_opcode; /* prepared packet opcode */ + + UINT8 last_pkt_opcode; /* last sent packet opcode */ + BOOLEAN srm_wait; /* whether we had set SRMP to wait */ + BOOLEAN srm_peer_wait; /* whether peer had set SRMP to wait */ + UINT8 srm_state; /* SRM state machine */ + UINT8 state; /* main state machine */ + UINT8 allocated; /* 0, not allocated. index+1, otherwise. equal to api handle */ +} tGOEPC_CCB; + +/* GOEPC Control block */ +typedef struct { + tGOEPC_CCB ccb[GOEPC_MAX_CONNECTION]; /* connection control blocks */ + UINT8 trace_level; /* trace level */ +} tGOEPC_CB; + +#if GOEP_DYNAMIC_MEMORY == FALSE +extern tGOEPC_CB goepc_cb; +#else +extern tGOEPC_CB *goepc_cb_ptr; +#define goepc_cb (*goepc_cb_ptr) +#endif + +typedef struct { + UINT16 peer_mtu; + UINT16 our_mtu; +} tGOEPC_CONNECTED; + +typedef struct { + UINT16 peer_mtu; + UINT16 our_mtu; +} tGOEPC_MTU_CHG; + +typedef union { + tGOEPC_CONNECTED connected; + tGOEPC_MTU_CHG mtu_chg; + BT_HDR *pkt; +} tGOEPC_DATA; + +tGOEPC_CCB *goepc_allocate_ccb(void); +void goepc_free_ccb(tGOEPC_CCB *p_ccb); +void goepc_obex_callback(UINT16 handle, UINT8 event, tOBEX_MSG *msg); +BOOLEAN goepc_check_obex_req_allow(UINT8 state, BOOLEAN final); +BOOLEAN goepc_check_obex_req_param(tOBEX_PARSE_INFO *info); +void goepc_sm_execute(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data); +void goepc_srm_sm_execute(tGOEPC_CCB *p_ccb, BOOLEAN is_req, BOOLEAN srm_en, BOOLEAN srm_wait); + +#endif /* #if (GOEPC_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/hcic/hciblecmds.c b/lib/bt/host/bluedroid/stack/hcic/hciblecmds.c index 52a2b2dc..5ad13216 100644 --- a/lib/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/lib/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -349,8 +349,8 @@ BOOLEAN btsnd_hcic_ble_create_ll_conn (UINT16 scan_int, UINT16 scan_win, UINT16_TO_STREAM (pp, conn_latency); UINT16_TO_STREAM (pp, conn_timeout); - UINT16_TO_STREAM (pp, min_ce_len); - UINT16_TO_STREAM (pp, max_ce_len); + UINT16_TO_STREAM (pp, min_ce_len ? min_ce_len : BLE_CE_LEN_MIN); + UINT16_TO_STREAM (pp, max_ce_len ? max_ce_len : BLE_CE_LEN_MIN); btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); return (TRUE); @@ -686,6 +686,7 @@ BOOLEAN btsnd_hcic_ble_ltk_req_neg_reply (UINT16 handle) return (TRUE); } +#if (BLE_42_DTM_TEST_EN == TRUE) BOOLEAN btsnd_hcic_ble_receiver_test(UINT8 rx_freq) { BT_HDR *p; @@ -733,7 +734,9 @@ BOOLEAN btsnd_hcic_ble_transmitter_test(UINT8 tx_freq, UINT8 test_data_len, UINT btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); return (TRUE); } +#endif // // #if (BLE_42_DTM_TEST_EN == TRUE) +#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE)) BOOLEAN btsnd_hcic_ble_test_end(void) { BT_HDR *p; @@ -754,6 +757,7 @@ BOOLEAN btsnd_hcic_ble_test_end(void) btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); return (TRUE); } +#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE)) BOOLEAN btsnd_hcic_ble_read_host_supported (void) { @@ -1084,27 +1088,6 @@ BOOLEAN btsnd_hcic_ble_set_channels (BLE_CHANNELS channels) return (TRUE); } -BOOLEAN btsnd_hcic_ble_clear_adv (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_BLE_CLEAR_ADV)) == NULL) { - return (FALSE); - } - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CLEAR_ADV; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_VENDOR_BLE_CLEAR_ADV); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_CLEAR_ADV); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return TRUE; -} - #define HCIC_BLE_CMD_CREATED(p, pp, size) do{\ if ((p = HCI_GET_CMD_BUF(size)) == NULL) { \ return FALSE; \ @@ -1174,6 +1157,7 @@ BOOLEAN btsnd_hcic_ble_set_phy(UINT16 conn_handle, return TRUE; } +#if (BLE_50_DTM_TEST_EN == TRUE) UINT8 btsnd_hcic_ble_enhand_rx_test(UINT8 rx_channel, UINT8 phy, UINT8 modulation_idx) { @@ -1218,7 +1202,9 @@ UINT8 btsnd_hcic_ble_enhand_tx_test(UINT8 tx_channel, UINT8 len, return TRUE; } +#endif // #if (BLE_50_DTM_TEST_EN == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) UINT8 btsnd_hcic_ble_set_extend_rand_address(UINT8 adv_handle, BD_ADDR rand_addr) { BT_HDR *p; @@ -1432,7 +1418,9 @@ UINT8 btsnd_hcic_ble_clear_adv_set(void) return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) +#if (BLE_50_PERIODIC_ADV_EN == TRUE) UINT8 btsnd_hcic_ble_set_periodic_adv_params(UINT8 adv_handle, UINT16 interval_min, UINT16 interval_max, @@ -1507,7 +1495,9 @@ UINT8 btsnd_hcic_ble_periodic_adv_enable(UINT8 enable, UINT8 adv_handle) return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } +#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE) +#if (BLE_50_EXTEND_SCAN_EN == TRUE) UINT8 btsnd_hcic_ble_set_ext_scan_params(UINT8 own_addr_type, UINT8 filter_policy, UINT8 phy_mask, UINT8 phy_count, tHCI_EXT_SCAN_PARAMS *params) @@ -1555,6 +1545,7 @@ UINT8 btsnd_hcic_ble_ext_scan_enable(UINT8 enable, UINT8 filter_dups, return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn) { @@ -1594,8 +1585,8 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn) UINT16_TO_STREAM(pp, params->conn_interval_max); UINT16_TO_STREAM(pp, params->conn_latency); UINT16_TO_STREAM(pp, params->sup_timeout); - UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN); - UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN); + UINT16_TO_STREAM(pp, params->min_ce_len ? params->min_ce_len : BLE_CE_LEN_MIN); + UINT16_TO_STREAM(pp, params->max_ce_len ? params->max_ce_len : BLE_CE_LEN_MIN); } if (p_conn->init_phy_mask & 0x02) { @@ -1606,8 +1597,8 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn) UINT16_TO_STREAM(pp, params->conn_interval_max); UINT16_TO_STREAM(pp, params->conn_latency); UINT16_TO_STREAM(pp, params->sup_timeout); - UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN); - UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN); + UINT16_TO_STREAM(pp, params->min_ce_len ? params->min_ce_len : BLE_CE_LEN_MIN); + UINT16_TO_STREAM(pp, params->max_ce_len ? params->max_ce_len : BLE_CE_LEN_MIN); } if (p_conn->init_phy_mask & 0x04) { @@ -1618,8 +1609,8 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn) UINT16_TO_STREAM(pp, params->conn_interval_max); UINT16_TO_STREAM(pp, params->conn_latency); UINT16_TO_STREAM(pp, params->sup_timeout); - UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN); - UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN); + UINT16_TO_STREAM(pp, params->min_ce_len ? params->min_ce_len : BLE_CE_LEN_MIN); + UINT16_TO_STREAM(pp, params->max_ce_len ? params->max_ce_len : BLE_CE_LEN_MIN); } btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); @@ -1627,14 +1618,15 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn) } +#if (BLE_50_EXTEND_SYNC_EN == TRUE) BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 option, UINT8 adv_sid, UINT8 adv_addr_type, BD_ADDR adv_addr, - UINT16 sync_timeout, UINT8 unused) + UINT16 sync_timeout, UINT8 sync_cte_type) { BT_HDR *p; UINT8 *pp; - HCI_TRACE_EVENT("%s, option = %d, adv_sid = %d, adv_addr_type = %d, sync_timeout = %d, unused = %d", - __func__, option, adv_sid, adv_addr_type, sync_timeout, unused); + HCI_TRACE_EVENT("%s, option = %d, adv_sid = %d, adv_addr_type = %d, sync_timeout = %d, sync_cte_type = %d", + __func__, option, adv_sid, adv_addr_type, sync_timeout, sync_cte_type); HCI_TRACE_EVENT("addr %02x %02x %02x %02x %02x %02x", adv_addr[0], adv_addr[1], adv_addr[2], adv_addr[3], adv_addr[4], adv_addr[5]); uint16_t skip = 0; @@ -1648,7 +1640,7 @@ BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 option, UINT8 adv_sid, BDADDR_TO_STREAM(pp, adv_addr); UINT16_TO_STREAM(pp, skip); UINT16_TO_STREAM(pp, sync_timeout); - UINT8_TO_STREAM(pp, unused); + UINT8_TO_STREAM(pp, sync_cte_type); btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); return TRUE; @@ -1750,6 +1742,7 @@ UINT8 btsnd_hcic_ble_read_periodic_adv_list_size(void) return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) UINT8 btsnd_hcic_ble_read_trans_power(void) { @@ -1910,7 +1903,7 @@ UINT8 btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(UINT8 mode, UINT } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) -UINT8 btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 privacy_mode) +BOOLEAN btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 privacy_mode) { BT_HDR *p; UINT8 *pp; @@ -1933,4 +1926,885 @@ UINT8 btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 priva btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); return (TRUE); } + +#if (BLE_VENDOR_HCI_EN == TRUE) +BOOLEAN btsnd_hcic_ble_clear_adv (void) +{ + BT_HDR *p; + UINT8 *pp; + + if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_BLE_CLEAR_ADV)) == NULL) { + return (FALSE); + } + + pp = (UINT8 *)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CLEAR_ADV; + p->offset = 0; + + UINT16_TO_STREAM (pp, HCI_VENDOR_BLE_CLEAR_ADV); + UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_CLEAR_ADV); + + btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} + +BOOLEAN btsnd_hcic_ble_set_csa_support (UINT8 csa_select) +{ + BT_HDR *p; + UINT8 *pp; + + if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_BLE_SET_CSA_SUPPORT)) == NULL) { + return (FALSE); + } + + pp = (UINT8 *)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_CSA_SUPPORT; + p->offset = 0; + + UINT16_TO_STREAM (pp, HCI_VENDOR_BLE_SET_CSA_SUPPORT); + UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_SET_CSA_SUPPORT); + UINT8_TO_STREAM (pp, csa_select); + + btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} + +BOOLEAN btsnd_hcic_ble_set_vendor_evt_mask (UINT32 evt_mask) +{ + BT_HDR *p; + UINT8 *pp; + + if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_BLE_SET_VENDOR_EVT_MASK)) == NULL) { + return (FALSE); + } + + pp = (UINT8 *)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_VENDOR_EVT_MASK; + p->offset = 0; + + UINT16_TO_STREAM (pp, HCI_VENDOR_BLE_SET_EVT_MASK); + UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_SET_VENDOR_EVT_MASK); + UINT32_TO_STREAM (pp, evt_mask); + + btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} +#endif // #if (BLE_VENDOR_HCI_EN == TRUE) #endif + +#if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +UINT8 btsnd_hcic_ble_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, + uint32_t sdu_interval, uint16_t max_sdu, uint16_t max_transport_latency, + uint8_t rtn, uint8_t phy, uint8_t packing, uint8_t framing, + uint8_t encryption, uint8_t *broadcast_code) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci big create: big_handle %d, adv_handle %d, num_bis %d sdu_interval %d max_sdu %d max_transport_latency %d \ + rtn %d phy %d packing %d framing %d encryption %d", big_handle, adv_handle, num_bis, sdu_interval, max_sdu,\ + max_transport_latency, rtn, phy, packing, framing, encryption); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_BIG_CREATE_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CREATE_BIG); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BIG_CREATE_PARAMS); + + UINT8_TO_STREAM(pp, big_handle); + UINT8_TO_STREAM(pp, adv_handle); + UINT8_TO_STREAM(pp, num_bis); + UINT24_TO_STREAM(pp, sdu_interval); + UINT16_TO_STREAM(pp, max_sdu); + UINT16_TO_STREAM(pp, max_transport_latency); + UINT8_TO_STREAM(pp, rtn); + UINT8_TO_STREAM(pp, phy); + UINT8_TO_STREAM(pp, packing); + UINT8_TO_STREAM(pp, framing); + UINT8_TO_STREAM(pp, encryption); + ARRAY_TO_STREAM(pp, broadcast_code, 16); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} + +UINT8 btsnd_hcic_ble_big_create_test(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, + uint32_t sdu_interval, uint16_t iso_interval, uint8_t nse, + uint16_t max_sdu, uint16_t max_pdu, uint8_t phy, + uint8_t packing, uint8_t framing, uint8_t bn, uint8_t irc, + uint8_t pto, uint8_t encryption, uint8_t *broadcast_code) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("%s big_handle %d, adv_handle %d, num_bis %d sdu_interval %d max_sdu %d max_pdu %d iso_interval %d \ + nse %d phy %d packing %d framing %d bn %d irc %dencryption %d", __func__, big_handle, adv_handle, num_bis, sdu_interval, max_sdu, max_pdu, \ + iso_interval, nse, phy, packing, framing, bn, irc, encryption); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_BIG_CREATE_TEST_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CREATE_BIG_TEST); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BIG_CREATE_TEST_PARAMS); + + UINT8_TO_STREAM(pp, big_handle); + UINT8_TO_STREAM(pp, adv_handle); + UINT8_TO_STREAM(pp, num_bis); + UINT24_TO_STREAM(pp, sdu_interval); + UINT16_TO_STREAM(pp, iso_interval); + UINT8_TO_STREAM(pp, nse); + UINT16_TO_STREAM(pp, max_sdu); + UINT16_TO_STREAM(pp, max_pdu); + UINT8_TO_STREAM(pp, phy); + UINT8_TO_STREAM(pp, packing); + UINT8_TO_STREAM(pp, framing); + UINT8_TO_STREAM(pp, bn); + UINT8_TO_STREAM(pp, irc); + UINT8_TO_STREAM(pp, pto); + UINT8_TO_STREAM(pp, encryption); + ARRAY_TO_STREAM(pp, broadcast_code, 16); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} + +UINT8 btsnd_hcic_ble_big_terminate(uint8_t big_handle, uint8_t reason) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("%s big_handle %d reason 0x%x", __func__, big_handle, reason); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_BIG_TERMINATE_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_TERMINATE_BIG); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BIG_TERMINATE_PARAMS); + + UINT8_TO_STREAM(pp, big_handle); + UINT8_TO_STREAM(pp, reason); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +UINT8 btsnd_hcic_ble_big_sync_create(uint8_t big_handle, uint16_t sync_handle, + uint8_t encryption, uint8_t *bc_code, + uint8_t mse, uint16_t big_sync_timeout, + uint8_t num_bis, uint8_t *bis) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("big sync create: big_handle %d sync_handle %d encryption %d mse %d big_sync_timeout %d", big_handle, sync_handle, encryption, mse, big_sync_timeout); + + // for (uint8_t i = 0; i < num_bis; i++) + // { + // HCI_TRACE_ERROR("i %d bis %d", bis[i]); + // } + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_BIG_SYNC_CREATE_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_BIG_CREATE_SYNC); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BIG_SYNC_CREATE_PARAMS); + + UINT8_TO_STREAM(pp, big_handle); + UINT16_TO_STREAM(pp, sync_handle); + UINT8_TO_STREAM(pp, encryption); + ARRAY_TO_STREAM(pp, bc_code, 16); + UINT8_TO_STREAM(pp, mse); + UINT16_TO_STREAM(pp, big_sync_timeout); + UINT8_TO_STREAM(pp, num_bis); + ARRAY_TO_STREAM(pp, bis, num_bis); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} + +UINT8 btsnd_hcic_ble_big_sync_terminate(uint8_t big_handle) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("%s big_handle %d", __func__, big_handle); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_BIG_SYNC_TERMINATE_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_BIG_TERMINATE_SYNC); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BIG_SYNC_TERMINATE_PARAMS); + + UINT8_TO_STREAM(pp, big_handle); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +UINT8 btsnd_hcic_ble_iso_set_data_path(uint16_t conn_handle, uint8_t data_path_dir, uint8_t data_path_id, uint8_t coding_fmt, + uint16_t company_id, uint16_t vs_codec_id, uint32_t controller_delay, uint8_t codec_len, + uint8_t *codec_cfg) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set data path: conn_handle %d data_path_dir %d data_path_id %d coding_fmt %d company_id 0x%x vs_codec_id %d controller_delay %ld codec_len %d", + conn_handle, data_path_dir, data_path_id, coding_fmt, company_id, vs_codec_id, controller_delay, codec_len); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_SET_DATA_PATH_PARAMS + codec_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_ISO_SET_DATA_PATH); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_SET_DATA_PATH_PARAMS + codec_len); + + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, data_path_dir); + UINT8_TO_STREAM(pp, data_path_id); + UINT8_TO_STREAM(pp, coding_fmt); + UINT16_TO_STREAM(pp, company_id); + UINT16_TO_STREAM(pp, vs_codec_id); + UINT24_TO_STREAM(pp, controller_delay); + UINT8_TO_STREAM(pp, codec_len); + if (codec_len && codec_cfg) { + ARRAY_TO_STREAM(pp, codec_cfg, codec_len); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_iso_remove_data_path(uint16_t conn_handle, uint8_t data_path_dir) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci remove data path: conn_handle %d data_path_dir %d", conn_handle, data_path_dir); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_REMOVE_DATA_PATH_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_ISO_REMOVE_DATA_PATH); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_REMOVE_DATA_PATH_PARAMS); + + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, data_path_dir); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_iso_read_tx_sync(uint16_t iso_hdl) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci read iso tx sync: iso_hdl %d", iso_hdl); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_READ_TX_SYNC_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_ISO_READ_TX_SYNC); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_READ_TX_SYNC_PARAMS); + // Bit_Number V1 + UINT16_TO_STREAM(pp, iso_hdl); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +UINT8 btsnd_hcic_ble_iso_set_cig_params(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t worse_case_SCA, uint8_t packing, + uint8_t framing, uint16_t mtl_c_to_p, uint16_t mtl_p_to_c, uint8_t cis_cnt, struct ble_hci_le_cis_params *cis_params) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set cig params: cig_id %d sdu_int_c_to_p %d sdu_int_p_to_c %d worse_case_SCA %d packing %d framing %d mtl_c_to_p %d mtl_p_to_c %d cis_cnt %d", + cig_id, sdu_int_c_to_p, sdu_int_p_to_c, worse_case_SCA, packing, framing, mtl_c_to_p, mtl_p_to_c, cis_cnt); + UINT8 cis_param_len = cis_cnt * 9; + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_SET_CIG_PARAMS + cis_param_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_ISO_SET_CIG_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_SET_CIG_PARAMS + cis_param_len); + + UINT8_TO_STREAM(pp, cig_id); + UINT24_TO_STREAM(pp, sdu_int_c_to_p); + UINT24_TO_STREAM(pp, sdu_int_p_to_c); + UINT8_TO_STREAM(pp, worse_case_SCA); + UINT8_TO_STREAM(pp, packing); + UINT8_TO_STREAM(pp, framing); + UINT16_TO_STREAM(pp, mtl_c_to_p); + UINT16_TO_STREAM(pp, mtl_p_to_c); + UINT8_TO_STREAM(pp, cis_cnt); + + for (uint8_t i = 0; i < cis_cnt; i++) + { + UINT8_TO_STREAM(pp, cis_params[i].cis_id); + UINT16_TO_STREAM(pp, cis_params[i].max_sdu_c_to_p); + UINT16_TO_STREAM(pp, cis_params[i].max_sdu_p_to_c); + UINT8_TO_STREAM(pp, cis_params[i].phy_c_to_p); + UINT8_TO_STREAM(pp, cis_params[i].phy_p_to_c); + UINT8_TO_STREAM(pp, cis_params[i].rtn_c_to_p); + UINT8_TO_STREAM(pp, cis_params[i].rtn_p_to_c); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_iso_set_cig_params_test(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t ft_c_to_p, uint8_t ft_p_to_c, + uint16_t iso_interval, uint8_t worse_case_SCA, uint8_t packing, uint8_t framing, uint8_t cis_cnt, + struct ble_hci_le_cis_params_test *cis_params_test) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set cig params test: cig_id %d sdu_int_c_to_p %d sdu_int_p_to_c %d ft_c_to_p %d ft_p_to_c %d iso_interval %d worse_case_SCA %d packing %d framing %d cis_cnt %d", + cig_id, sdu_int_c_to_p, sdu_int_p_to_c, ft_c_to_p, ft_p_to_c, iso_interval, worse_case_SCA, packing, framing, cis_cnt); + UINT8 cis_param_len = cis_cnt * 14; + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_SET_CIG_TEST_PARAMS + cis_param_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_ISO_SET_CIG_PARAMS_TEST); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_SET_CIG_TEST_PARAMS + cis_param_len); + + UINT8_TO_STREAM(pp, cig_id); + UINT24_TO_STREAM(pp, sdu_int_c_to_p); + UINT24_TO_STREAM(pp, sdu_int_p_to_c); + UINT8_TO_STREAM(pp, ft_c_to_p); + UINT8_TO_STREAM(pp, ft_p_to_c); + UINT16_TO_STREAM(pp, iso_interval); + UINT8_TO_STREAM(pp, worse_case_SCA); + UINT8_TO_STREAM(pp, packing); + UINT8_TO_STREAM(pp, framing); + UINT8_TO_STREAM(pp, cis_cnt); + + for (uint8_t i = 0; i < cis_cnt; i++) + { + UINT8_TO_STREAM(pp, cis_params_test[i].cis_id); + UINT8_TO_STREAM(pp, cis_params_test[i].nse); + UINT16_TO_STREAM(pp, cis_params_test[i].max_sdu_c_to_p); + UINT16_TO_STREAM(pp, cis_params_test[i].max_sdu_p_to_c); + UINT16_TO_STREAM(pp, cis_params_test[i].max_pdu_c_to_p); + UINT16_TO_STREAM(pp, cis_params_test[i].max_pdu_p_to_c); + UINT8_TO_STREAM(pp, cis_params_test[i].phy_c_to_p); + UINT8_TO_STREAM(pp, cis_params_test[i].phy_p_to_c); + UINT8_TO_STREAM(pp, cis_params_test[i].bn_c_to_p); + UINT8_TO_STREAM(pp, cis_params_test[i].bn_p_to_c); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_iso_create_cis(uint8_t cis_count, struct ble_hci_cis_hdls *cis_hdls) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci create cis: cig_id ", cis_count); + // for (uint8_t i = 0; i < cis_count; i++) + // { + // HCI_TRACE_ERROR("i %d cis_hdl %d acl_hdl %d", i, cis_hdls[i].cis_hdl, cis_hdls[i].acl_hdl); + // } + + UINT8 cis_param_len = cis_count * 4; + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_CREATE_CIS_PARAMS + cis_param_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_ISO_CREATE_CIS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_CREATE_CIS_PARAMS + cis_param_len); + + UINT8_TO_STREAM(pp, cis_count); + + for (uint8_t i = 0; i < cis_count; i++) + { + UINT16_TO_STREAM(pp, cis_hdls[i].cis_hdl); + UINT16_TO_STREAM(pp, cis_hdls[i].acl_hdl); + } + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + + return TRUE; +} + +UINT8 btsnd_hcic_ble_iso_remove_cig(uint8_t cig_id) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci remove cig: cig_id %d", cig_id); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_REMOVE_CIG_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_ISO_REMOVE_CIG); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_REMOVE_CIG_PARAMS); + + UINT8_TO_STREAM(pp, cig_id); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +UINT8 btsnd_hcic_ble_iso_accept_cis_req(uint16_t cis_handle) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci accept cis req: cis_handle %d", cis_handle); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_ACCEPT_CIS_REQ_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_ISO_ACCEPT_CIS_REQ); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_ACCEPT_CIS_REQ_PARAMS); + + UINT16_TO_STREAM(pp, cis_handle); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + + return TRUE; +} + +UINT8 btsnd_hcic_ble_iso_reject_cis_req(uint16_t cis_handle, uint8_t reason) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci reject cis req: cis_handle %d reason %d", cis_handle, reason); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_REJECT_CIS_REQ_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_ISO_REJECT_CIS_REQ); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_REJECT_CIS_REQ_PARAMS); + + UINT16_TO_STREAM(pp, cis_handle); + UINT8_TO_STREAM(pp, reason); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) + +UINT8 btsnd_hcic_ble_iso_read_iso_link_quality(uint16_t iso_handle) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci read iso link quality: cis_handle %d", iso_handle); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_READ_LINK_QUALITY_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_ISO_READ_ISO_LINK_QUALITY); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_READ_LINK_QUALITY_PARAMS); + + UINT16_TO_STREAM(pp, iso_handle); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +UINT8 btsnd_hcic_ble_set_connless_cte_trans_params(uint8_t adv_hdl, uint8_t cte_len, uint8_t cte_type, + uint8_t cte_cnt, uint8_t switching_pattern_len, uint8_t *antenna_ids) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set connless cte trans: adv_hdl %d cte_len %d cte_type %d cte_cnt %d", adv_hdl, cte_len, cte_type, cte_cnt); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_PARAMS + switching_pattern_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONNLESS_CTE_TRANS_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_PARAMS + switching_pattern_len); + + UINT8_TO_STREAM(pp, adv_hdl); + UINT8_TO_STREAM(pp, cte_len); + UINT8_TO_STREAM(pp, cte_type); + UINT8_TO_STREAM(pp, cte_cnt); + UINT8_TO_STREAM(pp, switching_pattern_len); + for (uint8_t i = 0; i < switching_pattern_len; i++) + { + UINT8_TO_STREAM(pp, antenna_ids[i]); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_set_connless_cte_enable(uint8_t adv_hdl, uint8_t cte_en) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set connect cte enable: adv_hdl %d cte_en %d", adv_hdl, cte_en); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_ENABLE); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONNLESS_CTE_TRANS_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_ENABLE); + + UINT8_TO_STREAM(pp, adv_hdl); + UINT8_TO_STREAM(pp, cte_en); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_set_connless_iq_sampling_enable(uint16_t sync_hdl, uint8_t sampling_en, uint8_t slot_dur, + uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *antenna_ids) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci enable IQ sampling: sync_hdl %d sampling_en %d slot_dur %d", sync_hdl, sampling_en, slot_dur); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONNLESS_IQ_SAMPLING_ENABLE + switching_pattern_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONNLESS_IQ_SAMPLING_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONNLESS_IQ_SAMPLING_ENABLE + switching_pattern_len); + + UINT16_TO_STREAM(pp, sync_hdl); + UINT8_TO_STREAM(pp, sampling_en); + UINT8_TO_STREAM(pp, slot_dur); + UINT8_TO_STREAM(pp, max_sampled_ctes); + UINT8_TO_STREAM(pp, switching_pattern_len); + for (uint8_t i = 0; i < switching_pattern_len; i++) + { + UINT8_TO_STREAM(pp, antenna_ids[i]); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +UINT8 btsnd_hcic_ble_set_conn_cte_receive_params(uint16_t conn_hdl, uint8_t sampling_en, uint8_t slot_dur, + uint8_t switching_pattern_len, uint8_t *antenna_ids) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set connection cte receive params: conn_hdl %d sampling_en %d slot_dur %d", conn_hdl, sampling_en, slot_dur); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONN_CTE_RECEIVE_PARAMS + switching_pattern_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONN_CTE_RECEIVE_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONN_CTE_RECEIVE_PARAMS + switching_pattern_len); + + UINT16_TO_STREAM(pp, conn_hdl); + UINT8_TO_STREAM(pp, sampling_en); + UINT8_TO_STREAM(pp, slot_dur); + UINT8_TO_STREAM(pp, switching_pattern_len); + for (uint8_t i = 0; i < switching_pattern_len; i++) + { + UINT8_TO_STREAM(pp, antenna_ids[i]); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_set_conn_cte_trans_params(uint16_t conn_hdl, uint8_t cte_type, uint8_t switching_pattern_len, uint8_t *antenna_ids) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set connection cte trans params: conn_hdl %d cte_type %d len %d", conn_hdl, cte_type, switching_pattern_len); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONN_CTE_TRANS_PARAMS + switching_pattern_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONN_CTE_TRANS_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONN_CTE_TRANS_PARAMS + switching_pattern_len); + + UINT16_TO_STREAM(pp, conn_hdl); + UINT8_TO_STREAM(pp, cte_type); + UINT8_TO_STREAM(pp, switching_pattern_len); + for (uint8_t i = 0; i < switching_pattern_len; i++) + { + UINT8_TO_STREAM(pp, antenna_ids[i]); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_conn_cte_req_enable(uint16_t conn_hdl, uint8_t enable, uint16_t cte_req_int, uint8_t req_cte_len, uint8_t req_cte_type) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set connect cte request enable: conn_hdl %d enable %d cte_req_int %d req_cte_len %d req_cte_type %d", conn_hdl, enable, cte_req_int, req_cte_len, req_cte_type); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_CONN_CTE_REQ_ENABLE); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONN_CTE_REQ_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CONN_CTE_REQ_ENABLE); + + UINT16_TO_STREAM(pp, conn_hdl); + UINT8_TO_STREAM(pp, enable); + UINT16_TO_STREAM(pp, cte_req_int); + UINT8_TO_STREAM(pp, req_cte_len); + UINT8_TO_STREAM(pp, req_cte_type); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_conn_cte_rsp_enable(uint16_t conn_hdl, uint8_t enable) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set connect cte response enable: conn_hdl %d enable %d", conn_hdl, enable); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_CONN_CTE_RSP_ENABLE); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONN_CTE_RSP_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CONN_CTE_RSP_ENABLE); + + UINT16_TO_STREAM(pp, conn_hdl); + UINT8_TO_STREAM(pp, enable); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +UINT8 btsnd_hcic_ble_read_antenna_info(void) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci read antenna information"); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_READ_ANT_INFO); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_READ_ANT_INFOR); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_ANT_INFO); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +UINT8 btsnd_hcic_ble_enh_read_trans_power_level(uint16_t conn_handle, uint8_t phy) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci enh read trans power level, conn_handle %d phy %d", conn_handle, phy); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ENH_READ_TRANS_PWR_LEVEL); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_ENH_READ_TRANS_POWER_LEVEL); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ENH_READ_TRANS_PWR_LEVEL); + + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, phy); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_read_remote_trans_power_level(uint16_t conn_handle, uint8_t phy) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci read remote trans power level, conn_handle %d phy %d", conn_handle, phy); + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_READ_REMOTE_TRANS_PWR_LEVEL); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_READ_REMOTE_TRANS_POWER_LEVEL); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_REMOTE_TRANS_PWR_LEVEL); + + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, phy); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + + return TRUE; +} + +UINT8 btsnd_hcic_ble_set_path_loss_rpt_params(uint16_t conn_handle, uint8_t high_threshold, uint8_t high_hysteresis, + uint8_t low_threshold, uint8_t low_hysteresis, uint16_t min_time_spent) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set path loss rpt params, conn_handle %d high_threshold %d high_hysteresis %d low_threshold %d low_hysteresis %d min_time_spent %d", + conn_handle, high_threshold, high_hysteresis, low_threshold, + low_hysteresis, min_time_spent); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_PATH_LOSS_REPORTING_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_PATH_LOSS_REPORTING_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PATH_LOSS_REPORTING_PARAMS); + + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, high_threshold); + UINT8_TO_STREAM(pp, high_hysteresis); + UINT8_TO_STREAM(pp, low_threshold); + UINT8_TO_STREAM(pp, low_hysteresis); + UINT16_TO_STREAM(pp, min_time_spent); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_set_path_loss_rpt_enable(uint16_t conn_handle, uint8_t enable) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set path loss rpt en, conn_handle %d enable %d", conn_handle, enable); + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_PATH_LOSS_REPORTING_ENABLE); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_PATH_LOSS_REPORTING_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PATH_LOSS_REPORTING_ENABLE); + + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, enable); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_set_trans_pwr_rpt_enable(uint16_t conn_handle, uint8_t local_enable, uint8_t remote_enable) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set trans power rpt en, conn_handle %d local_enable %d remote_enable %d", conn_handle, local_enable, remote_enable); + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_TRANS_PWR_REPORTING_ENABLE); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_TRANS_POWER_REPORTING_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_TRANS_PWR_REPORTING_ENABLE); + + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, local_enable); + UINT8_TO_STREAM(pp, remote_enable); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + +#if (BLE_FEAT_CONN_SUBRATING == TRUE) +UINT8 btsnd_hcic_ble_set_default_subrate(UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set default subrate, subrate_min %d subrate_max %d max_latency %d continuation_number %d supervision_timeout %d", + subrate_min, subrate_max, max_latency, continuation_number, supervision_timeout); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_DEFAULT_SUBRATE_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_DEFAULT_SUBRATE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_DEFAULT_SUBRATE_PARAMS_LEN); + + UINT16_TO_STREAM(pp, subrate_min); + UINT16_TO_STREAM(pp, subrate_max); + UINT16_TO_STREAM(pp, max_latency); + UINT16_TO_STREAM(pp, continuation_number); + UINT16_TO_STREAM(pp, supervision_timeout); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_subrate_request(UINT16 conn_handle, UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci subrate req, conn_handle %d subrate_min %d subrate_max %d max_latency %d continuation_number %d supervision_timeout %d", + conn_handle, subrate_min, subrate_max, max_latency, continuation_number, supervision_timeout); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SUBRATE_REQ_LENGTH_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SUBRATE_REQUEST); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SUBRATE_REQ_LENGTH_PARAMS_LEN); + + UINT16_TO_STREAM(pp, conn_handle); + UINT16_TO_STREAM(pp, subrate_min); + UINT16_TO_STREAM(pp, subrate_max); + UINT16_TO_STREAM(pp, max_latency); + UINT16_TO_STREAM(pp, continuation_number); + UINT16_TO_STREAM(pp, supervision_timeout); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) +UINT8 btsnd_hcic_ble_set_host_feature(uint16_t bit_num, uint8_t bit_val) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set host feature: bit_num %d bit_val %d", bit_num, bit_val); +#if (BLE_FEAT_ISO_60_EN == TRUE) + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_HOST_FEATURE_PARAMS_V2); +#else + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_HOST_FEATURE_PARAMS); +#endif // #if (BLE_FEAT_ISO_60_EN == TRUE) + pp = (UINT8 *)(p + 1); +#if (BLE_FEAT_ISO_60_EN == TRUE) + UINT16_TO_STREAM(pp, HCI_BLE_SET_HOST_FEATURE_V2); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_HOST_FEATURE_PARAMS_V2); + // Bit_Number V1 + UINT16_TO_STREAM(pp, bit_num); +#else + UINT16_TO_STREAM(pp, HCI_BLE_SET_HOST_FEATURE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_HOST_FEATURE_PARAMS); + // Bit_Number V1 + UINT8_TO_STREAM(pp, bit_num); +#endif // #if (BLE_FEAT_ISO_60_EN == TRUE) + UINT8_TO_STREAM(pp, bit_val); + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/lib/bt/host/bluedroid/stack/include/stack/a2d_sbc.h b/lib/bt/host/bluedroid/stack/include/stack/a2d_sbc.h index 065f264f..088d11ab 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/a2d_sbc.h +++ b/lib/bt/host/bluedroid/stack/include/stack/a2d_sbc.h @@ -30,7 +30,12 @@ /* the length of the SBC Media Payload header. */ #define A2D_SBC_MPL_HDR_LEN 1 -/* the LOSC of SBC media codec capabilitiy */ +/* CIE offset in the info byte sequence */ +#define A2D_SBC_CIE_OFF 3 +/* CIE length in the info byte sequence */ +#define A2D_SBC_CIE_LEN 4 + +/* the LOSC of SBC media codec capability */ #define A2D_SBC_INFO_LEN 6 /* for Codec Specific Information Element */ diff --git a/lib/bt/host/bluedroid/stack/include/stack/acl_hci_link_interface.h b/lib/bt/host/bluedroid/stack/include/stack/acl_hci_link_interface.h index f62c654f..60c0f26a 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/acl_hci_link_interface.h +++ b/lib/bt/host/bluedroid/stack/include/stack/acl_hci_link_interface.h @@ -10,6 +10,6 @@ #include "bt_common.h" void btm_acl_connected(BD_ADDR bda, UINT16 handle, UINT8 link_type, UINT8 enc_mode, UINT8 status); -void btm_acl_disconnected(UINT16 handle, UINT8 reason); +BOOLEAN btm_acl_disconnected(UINT16 handle, UINT8 reason); #endif /* ACL_HCI_LINK_INTERFACE_H */ diff --git a/lib/bt/host/bluedroid/stack/include/stack/avdt_api.h b/lib/bt/host/bluedroid/stack/include/stack/avdt_api.h index 42a1f855..00c16f49 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/avdt_api.h +++ b/lib/bt/host/bluedroid/stack/include/stack/avdt_api.h @@ -519,6 +519,18 @@ extern UINT16 AVDT_CreateStream(UINT8 *p_handle, tAVDT_CS *p_cs); /******************************************************************************* ** +** Function AVDT_UpdateCodecInfo +** +** Description Update codec capability for a stream endpoint. +** +** +** Returns AVDT_SUCCESS if successful, otherwise error. +** +*******************************************************************************/ +extern UINT16 AVDT_UpdateCodecInfo(UINT8 handle, UINT8 num_codec, UINT8 *codec_info, UINT16 codec_info_len); + +/******************************************************************************* +** ** Function AVDT_RemoveStream ** ** Description Remove a stream endpoint. This function is called when diff --git a/lib/bt/host/bluedroid/stack/include/stack/avrc_api.h b/lib/bt/host/bluedroid/stack/include/stack/avrc_api.h index 21f4bee5..2985c65c 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/avrc_api.h +++ b/lib/bt/host/bluedroid/stack/include/stack/avrc_api.h @@ -99,6 +99,9 @@ #define AVRC_SUPF_CT_CAT3 0x0004 /* Category 3 */ #define AVRC_SUPF_CT_CAT4 0x0008 /* Category 4 */ #define AVRC_SUPF_CT_BROWSE 0x0040 /* Browsing */ +#define AVRC_SUPF_CT_COVER_ART_GIP 0x0080 /* Cover Art GetImageProperties */ +#define AVRC_SUPF_CT_COVER_ART_GI 0x0100 /* Cover Art GetImage */ +#define AVRC_SUPF_CT_COVER_ART_GLT 0x0200 /* Cover Art GetLinkedThumbnail */ #define AVRC_SUPF_TG_CAT1 0x0001 /* Category 1 */ #define AVRC_SUPF_TG_CAT2 0x0002 /* Category 2 */ @@ -107,7 +110,8 @@ #define AVRC_SUPF_TG_APP_SETTINGS 0x0010 /* Player Application Settings */ #define AVRC_SUPF_TG_GROUP_NAVI 0x0020 /* Group Navigation */ #define AVRC_SUPF_TG_BROWSE 0x0040 /* Browsing */ -#define AVRC_SUPF_TG_MULTI_PLAYER 0x0080 /* Muliple Media Player */ +#define AVRC_SUPF_TG_MULTI_PLAYER 0x0080 /* Multiple Media Player */ +#define AVRC_SUPF_TG_COVER_ART 0x0100 /* Cover Art */ #define AVRC_META_SUCCESS AVRC_SUCCESS #define AVRC_META_FAIL AVRC_FAIL @@ -561,7 +565,7 @@ extern bt_status_t AVRC_Init(void); ** ** Function AVRC_Deinit ** -** Description This function is called at stack shotdown to free the +** Description This function is called at stack shutdown to free the ** control block (if using dynamic memory), and deinitializes the ** control block and tracing level. ** diff --git a/lib/bt/host/bluedroid/stack/include/stack/avrc_defs.h b/lib/bt/host/bluedroid/stack/include/stack/avrc_defs.h index c90fa6cf..06f73c29 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/avrc_defs.h +++ b/lib/bt/host/bluedroid/stack/include/stack/avrc_defs.h @@ -35,6 +35,7 @@ #define AVRC_REV_1_3 0x0103 #define AVRC_REV_1_4 0x0104 #define AVRC_REV_1_5 0x0105 +#define AVRC_REV_1_6 0x0106 #define AVRC_PACKET_LEN 512 /* Per the spec, you must support 512 byte RC packets */ @@ -185,7 +186,7 @@ #define AVRC_PKT_END 3 #define AVRC_PKT_TYPE_MASK 3 -/* Define the PDUs carried in the vendor dependant data +/* Define the PDUs carried in the vendor dependent data */ #define AVRC_PDU_GET_CAPABILITIES 0x10 #define AVRC_PDU_LIST_PLAYER_APP_ATTR 0x11 @@ -297,7 +298,7 @@ typedef UINT8 tAVRC_BATTERY_STATUS; #define AVRC_MEDIA_ATTR_ID_TRACK_NUM 0x00000004 #define AVRC_MEDIA_ATTR_ID_NUM_TRACKS 0x00000005 #define AVRC_MEDIA_ATTR_ID_GENRE 0x00000006 -#define AVRC_MEDIA_ATTR_ID_PLAYING_TIME 0x00000007 /* in miliseconds */ +#define AVRC_MEDIA_ATTR_ID_PLAYING_TIME 0x00000007 /* in milliseconds */ #define AVRC_MAX_NUM_MEDIA_ATTR_ID 7 /* Define the possible values of play state diff --git a/lib/bt/host/bluedroid/stack/include/stack/bt_types.h b/lib/bt/host/bluedroid/stack/include/stack/bt_types.h index 5d817632..4050b79d 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/bt_types.h +++ b/lib/bt/host/bluedroid/stack/include/stack/bt_types.h @@ -486,6 +486,7 @@ typedef struct { #define BLE_ADDR_RANDOM_ID 0x03 #define BLE_ADDR_TYPE_MAX BLE_ADDR_RANDOM_ID #define BLE_ADDR_UNKNOWN_TYPE 0XFF +#define BLE_ADDR_ANONYMOUS 0xFF typedef UINT8 tBLE_ADDR_TYPE; #define BLE_ADDR_TYPE_MASK (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC) diff --git a/lib/bt/host/bluedroid/stack/include/stack/btm_api.h b/lib/bt/host/bluedroid/stack/include/stack/btm_api.h index 32420f75..3415df5d 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/btm_api.h +++ b/lib/bt/host/bluedroid/stack/include/stack/btm_api.h @@ -75,6 +75,7 @@ enum { BTM_SET_STATIC_RAND_ADDR_FAIL, /* 25 Command failed */ BTM_INVALID_STATIC_RAND_ADDR, /* 26 invalid static rand addr */ BTM_SEC_DEV_REC_REMOVED, /* 27 Device record relate to the bd_addr is removed */ + BTM_HCI_ERROR = 128, /* 128 HCI error code from controller (0x80) */ }; typedef uint8_t tBTM_STATUS; @@ -200,6 +201,8 @@ typedef void (tBTM_SET_LOCAL_PRIVACY_CBACK) (UINT8 status); typedef void (tBTM_SET_RPA_TIMEOUT_CMPL_CBACK) (UINT8 status); typedef void (tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK) (UINT8 status); + +typedef void (tBTM_BLE_VENDOR_HCI_EVT_CBACK) (UINT8 subevt_code, UINT8 param_len, UINT8 *params); /******************************* ** Device Coexist status ********************************/ @@ -456,22 +459,22 @@ typedef enum { #define BTM_COD_SERVICE_INFORMATION 0x8000 /* class of device field macros */ -#define BTM_COD_FORMAT_TYPE(u8, pd) {u8 = pd[2]&0x03;} +#define BTM_COD_RESERVED_2(u8, pd) {u8 = pd[2]&0x03;} #define BTM_COD_MINOR_CLASS(u8, pd) {u8 = pd[2]&0xFC;} #define BTM_COD_MAJOR_CLASS(u8, pd) {u8 = pd[1]&0x1F;} #define BTM_COD_SERVICE_CLASS(u16, pd) {u16 = pd[0]; u16<<=8; u16 += pd[1]&0xE0;} /* to set the fields (assumes that format type is always 0) */ -#define FIELDS_TO_COD(pd, mn, mj, sv) {pd[2] = mn; pd[1] = \ - mj+ ((sv)&BTM_COD_SERVICE_CLASS_LO_B); \ - pd[0] = (sv) >> 8;} +#define FIELDS_TO_COD(pd, rs, mn, mj, sv) {pd[2] = (mn & BTM_COD_MINOR_CLASS_MASK) + (rs & BTM_COD_RESERVED_2_MASK); \ + pd[1] = mj+ ((sv)&BTM_COD_SERVICE_CLASS_LO_B); \ + pd[0] = (sv) >> 8;} /* the COD masks */ -#define BTM_COD_FORMAT_TYPE_MASK 0x03 #define BTM_COD_MINOR_CLASS_MASK 0xFC #define BTM_COD_MAJOR_CLASS_MASK 0x1F #define BTM_COD_SERVICE_CLASS_LO_B 0x00E0 #define BTM_COD_SERVICE_CLASS_MASK 0xFFE0 +#define BTM_COD_RESERVED_2_MASK 0x03 /* BTM service definitions ** Used for storing EIR data to bit mask @@ -808,6 +811,16 @@ typedef struct { BD_ADDR rem_bda; } tBTM_RSSI_RESULTS; +/* Structure returned with read channel map event (in tBTM_CMPL_CB callback function) +** in response to BTM_ReadChannelMap call. +*/ +typedef struct { + tBTM_STATUS status; /* BTM operation status */ + UINT8 hci_status; /* HCI command complete status */ + UINT8 channel_map[5]; /* Channel map (5 bytes) */ + BD_ADDR rem_bda; /* Remote device Bluetooth address */ +} tBTM_BLE_CH_MAP_RESULTS; + /* Structure returned with read current TX power event (in tBTM_CMPL_CB callback function) ** in response to BTM_ReadTxPower call. */ @@ -1027,9 +1040,6 @@ typedef void (tBTM_ACL_DB_CHANGE_CB) (BD_ADDR p_bda, DEV_CLASS p_dc, #define BTM_INVALID_SCO_INDEX 0xFFFF #define BTM_INVALID_HCI_HANDLE 0xFFFF -/* Define an invalid SCO disconnect reason */ -#define BTM_INVALID_SCO_DISC_REASON 0xFFFF - /* Define first active SCO index */ #define BTM_FIRST_ACTIVE_SCO_INDEX BTM_MAX_SCO_LINKS @@ -3024,7 +3034,19 @@ tBTM_STATUS BTM_SwitchRole (BD_ADDR remote_bd_addr, //extern tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb); - +/******************************************************************************* +** +** Function BTM_ReadChannelMap +** +** Description This function is called to read the current channel map +** for the given connection. The results are returned via +** the callback (tBTM_BLE_CH_MAP_RESULTS). +** +** Returns BTM_CMD_STARTED if successfully initiated or error code +** +*******************************************************************************/ +tBTM_STATUS BTM_ReadChannelMap(BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb); +#if (BLE_HOST_READ_TX_POWER_EN == TRUE) /******************************************************************************* ** ** Function BTM_ReadTxPower @@ -3045,10 +3067,13 @@ tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb); tBTM_STATUS BTM_BleReadAdvTxPower(tBTM_CMPL_CB *p_cb); +#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) void BTM_BleGetWhiteListSize(uint16_t *length); - +#if (BLE_50_EXTEND_SYNC_EN == TRUE) +void BTM_BleGetPeriodicAdvListSize(uint8_t *size); +#endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE) /******************************************************************************* ** ** Function BTM_ReadLinkQuality @@ -3262,21 +3287,6 @@ UINT8 *BTM_ReadScoBdAddr (UINT16 sco_inx); /******************************************************************************* ** -** Function BTM_ReadScoDiscReason -** -** Description This function is returns the reason why an (e)SCO connection -** has been removed. It contains the value until read, or until -** another (e)SCO connection has disconnected. -** -** Returns HCI reason or BTM_INVALID_SCO_DISC_REASON if not set. -** -*******************************************************************************/ -//extern -UINT16 BTM_ReadScoDiscReason (void); - - -/******************************************************************************* -** ** Function BTM_SetEScoMode ** ** Description This function sets up the negotiated parameters for SCO or diff --git a/lib/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/lib/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index 1bea9908..7ec384ef 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/lib/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -367,7 +367,6 @@ typedef UINT32 tBTM_BLE_AD_MASK; #define BTM_BLE_AD_TYPE_MANU HCI_EIR_MANUFACTURER_SPECIFIC_TYPE /* 0xff */ typedef UINT8 tBTM_BLE_AD_TYPE; -#define BTM_BLE_LONG_ADV_MAX_LEN 249 /* Security settings used with L2CAP LE COC */ #define BTM_SEC_LE_LINK_ENCRYPTED 0x01 @@ -395,7 +394,9 @@ typedef UINT8 tBTM_BLE_ADV_TX_POWER; /* adv tx power in dBm */ typedef struct { +#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) UINT8 adv_inst_max; /* max adv instance supported in controller */ +#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) UINT8 rpa_offloading; UINT16 tot_scan_results_strg; UINT8 max_irk_list_sz; @@ -499,6 +500,7 @@ typedef struct { tBTM_BLE_ADV_TX_POWER tx_power; } tBTM_BLE_ADV_PARAMS; +#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) typedef struct { UINT8 *p_sub_code; /* dynamic array to store sub code */ UINT8 *p_inst_id; /* dynamic array to store instance id */ @@ -530,6 +532,7 @@ typedef struct { tBTM_BLE_MULTI_ADV_INST *p_adv_inst; /* dynamic array to store adv instance */ tBTM_BLE_MULTI_ADV_OPQ op_q; } tBTM_BLE_MULTI_ADV_CB; +#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) typedef UINT8 tGATT_IF; @@ -810,15 +813,16 @@ typedef struct { typedef struct { UINT8 filter_policy; - #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH) +#if (BLE_FEAT_CREATE_SYNC_ENH == TRUE) UINT8 reports_disabled; UINT8 filter_duplicates; - #endif +#endif // (BLE_FEAT_CREATE_SYNC_ENH == TRUE) UINT8 sid; tBLE_ADDR_TYPE addr_type; BD_ADDR addr; UINT16 skip; UINT16 sync_timeout; + UINT8 sync_cte_type; } tBTM_BLE_Periodic_Sync_Params; typedef struct { @@ -944,6 +948,7 @@ typedef UINT8 tBTM_BLE_CONN_TYPE; #define ADV_INFO_PRESENT 0x00 #define NO_ADV_INFO_PRESENT 0x01 +#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) typedef btgatt_track_adv_info_t tBTM_BLE_TRACK_ADV_DATA; typedef void (tBTM_BLE_TRACK_ADV_CBACK)(tBTM_BLE_TRACK_ADV_DATA *p_track_adv_data); @@ -961,6 +966,7 @@ enum { }; typedef UINT8 tBTM_BLE_TRACK_ADV_ACTION; +#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #define BTM_BLE_MULTI_ADV_INVALID 0 @@ -1007,11 +1013,14 @@ typedef void (tBTM_START_STOP_ADV_CMPL_CBACK) (UINT8 status); typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info); typedef void (tBTM_CLEAR_ADV_CMPL_CBACK) (UINT8 status); typedef void (tBTM_SET_PRIVACY_MODE_CMPL_CBACK) (tBTM_STATUS status); +typedef void (tBTM_SET_CSA_SUPPORT_CMPL_CBACK) (tBTM_STATUS status); +typedef void (tBTM_SET_VENDOR_EVT_MASK_CBACK) (tBTM_STATUS status); #if (BLE_50_FEATURE_SUPPORT == TRUE) #define BTM_BLE_5_GAP_READ_PHY_COMPLETE_EVT 1 #define BTM_BLE_5_GAP_SET_PREFERED_DEFAULT_PHY_COMPLETE_EVT 2 #define BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT 3 +#if (BLE_50_EXTEND_ADV_EN == TRUE) #define BTM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT 4 #define BTM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT 5 #define BTM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT 6 @@ -1020,29 +1029,42 @@ typedef void (tBTM_SET_PRIVACY_MODE_CMPL_CBACK) (tBTM_STATUS status); #define BTM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT 9 #define BTM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT 10 #define BTM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT 11 +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) +#if (BLE_50_PERIODIC_ADV_EN == TRUE) #define BTM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT 12 #define BTM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT 13 #define BTM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT 14 #define BTM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT 15 +#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) #define BTM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT 16 #define BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT 17 #define BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT 18 #define BTM_BLE_5_GAP_PERIODIC_ADV_ADD_DEV_COMPLETE_EVT 19 #define BTM_BLE_5_GAP_PERIODIC_ADV_REMOVE_DEV_COMPLETE_EVT 20 #define BTM_BLE_5_GAP_PERIODIC_ADV_CLEAR_DEV_COMPLETE_EVT 21 +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) +#if (BLE_50_EXTEND_SCAN_EN == TRUE) #define BTM_BLE_5_GAP_SET_EXT_SCAN_PARAMS_COMPLETE_EVT 22 #define BTM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT 23 #define BTM_BLE_5_GAP_EXT_SCAN_STOP_COMPLETE_EVT 24 +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) #define BTM_BLE_5_GAP_PREFER_EXT_CONN_PARAMS_SET_COMPLETE_EVT 25 #define BTM_BLE_5_GAP_PHY_UPDATE_COMPLETE_EVT 26 +#if (BLE_50_EXTEND_SCAN_EN == TRUE) #define BTM_BLE_5_GAP_EXT_ADV_REPORT_EVT 27 #define BTM_BLE_5_GAP_SCAN_TIMEOUT_EVT 28 +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) #define BTM_BLE_5_GAP_ADV_TERMINATED_EVT 29 #define BTM_BLE_5_GAP_SCAN_REQ_RECEIVED_EVT 30 +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) #define BTM_BLE_5_GAP_CHANNEL_SELETE_ALGORITHM_EVT 31 +#if (BLE_50_EXTEND_SYNC_EN == TRUE) #define BTM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT 32 #define BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT 33 #define BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT 34 +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #define BTM_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT 35 #define BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT 36 @@ -1051,9 +1073,76 @@ typedef void (tBTM_SET_PRIVACY_MODE_CMPL_CBACK) (tBTM_STATUS status); #define BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT 39 #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #define BTM_BLE_GAP_SET_PRIVACY_MODE_COMPLETE_EVT 40 -#define BTM_BLE_5_GAP_UNKNOWN_EVT 41 +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +#define BTM_BLE_GAP_ENH_READ_TRANS_POWER_LEVEL_EVT 41 +#define BTM_BLE_GAP_READ_REMOTE_TRANS_POWER_LEVEL_EVT 42 +#define BTM_BLE_GAP_SET_PATH_LOSS_REPORTING_PARAMS_EVT 43 +#define BTM_BLE_GAP_SET_PATH_LOSS_REPORTING_ENABLE_EVT 44 +#define BTM_BLE_GAP_SET_TRANS_POWER_REPORTING_ENABLE_EVT 45 +#define BTM_BLE_GAP_PATH_LOSS_THRESHOLD_EVT 46 +#define BTM_BLE_GAP_TRANMIT_POWER_REPORTING_EVT 47 +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +#if (BLE_FEAT_CONN_SUBRATING == TRUE) +#define BTM_BLE_GAP_SET_DEFAULT_SUBRATE_EVT 48 +#define BTM_BLE_GAP_SUBRATE_REQUEST_EVT 49 +#define BTM_BLE_GAP_SUBRATE_CHANGE_EVT 50 +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BLE_50_FEATURE_SUPPORT == TRUE) +#define BTM_BLE_GAP_SET_HOST_FEATURE_EVT 51 +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#define BTM_BLE_5_GAP_UNKNOWN_EVT 52 typedef UINT8 tBTM_BLE_5_GAP_EVENT; +#if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#define BTM_BLE_ISO_BIG_CREATE_COMPLETE_EVT 1 +#define BTM_BLE_ISO_BIG_TERMINATE_COMPLETE_EVT 2 +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +#define BTM_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT 3 +#define BTM_BLE_ISO_BIG_SYNC_LOST_EVT 4 +#define BTM_BLE_ISO_BIG_SYNC_TERMINATE_COMPLETE_EVT 5 +#define BTM_BLE_ISO_BIGINFO_ADV_REPORT_EVT 6 +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +#define BTM_BLE_ISO_DATA_PATH_UPFATE_EVT 7 +#define BTM_BLE_ISO_READ_TX_SYNC_EVT 9 +#define BTM_BLE_ISO_READ_LINK_QUALITY_EVT 10 +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +#define BTM_BLE_ISO_SET_CIG_PARAMS_EVT 11 +#define BTM_BLE_ISO_CREATE_CIS_EVT 12 +#define BTM_BLE_ISO_REMOVE_CIG_EVT 13 +#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +#define BTM_BLE_ISO_ACCEPT_CIS_REQ_EVT 14 +#define BTM_BLE_ISO_REJECT_CIS_REQ_EVT 15 +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +#define BTM_BLE_ISO_CIS_ESTABLISHED_EVT 16 +#define BTM_BLE_ISO_CIS_REQUEST_EVT 17 +#define BTM_BLE_ISO_CIS_DISCONNECTED_EVT 18 +#define BTM_BLE_ISO_UNKNOWN_EVT 19 +typedef UINT8 tBTM_BLE_ISO_EVENT; +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#define BTM_BLE_CTE_SET_TRANS_PARAMS_EVT 1 +#define BTM_BLE_CTE_SET_TRANS_ENABLE_EVT 2 +#define BTM_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT 3 +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define BTM_BLE_CTE_SET_CONN_RECV_PARAMS_EVT 4 +#define BTM_BLE_CTE_SET_CONN_TRANS_PARAMS_EVT 5 +#define BTM_BLE_CTE_SET_CONN_REQ_ENABLE_EVT 6 +#define BTM_BLE_CTE_SET_CONN_RSP_ENABLE_EVT 7 +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define BTM_BLE_CTE_READ_ANT_INFOR_EVT 8 +#define BTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT 9 +#define BTM_BLE_CTE_CONN_IQ_REPORT_EVT 10 +#define BTM_BLE_CTE_REQUEST_FAILED_EVT 11 +typedef UINT8 tBTM_BLE_CTE_EVENT; +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + #define BTM_BLE_EXT_ADV_DATA_COMPLETE 0x00 #define BTM_BLE_EXT_ADV_DATA_INCOMPLETE 0x01 #define BTM_BLE_EXT_ADV_DATA_TRUNCATED 0x02 @@ -1100,46 +1189,58 @@ typedef struct { typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_SET_PERF_PHY_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_SET_RAND_ADDR_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_SET_PARAMS_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_DATA_SET_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_SCAN_RSP_DATA_SET_CMPL; typedef struct { UINT8 status; + UINT8 instance_num; + UINT8 instance[10]; } tBTM_BLE_EXT_ADV_START_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_STOP_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_PERIOD_ADV_SET_PARAMS_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_PERIOD_ADV_DATA_SET_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_PERIOD_ADV_START_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_PERIOD_ADV_STOP_CMPL; typedef struct { @@ -1230,6 +1331,7 @@ typedef struct { UINT16 sync_handle; UINT8 tx_power; INT8 rssi; + UINT8 cte_type; tBTM_BLE_EXT_ADV_DATA_STATUS data_status; UINT8 data_length; UINT8 *data; @@ -1295,39 +1397,409 @@ typedef struct { } tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV; #endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +typedef struct { + UINT8 status; + UINT16 conn_handle; + UINT8 phy; + INT8 cur_tx_pwr_level; + INT8 max_tx_pwr_level; +} __attribute__((packed)) tBTM_BLE_ENH_TRANS_PWR_LEVEL_CMPL; + +typedef struct { + UINT8 status; +} __attribute__((packed)) tBTM_BLE_REMOTE_TRANS_PWR_LEVEL_CMPL; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_SET_PATH_LOSS_RPTING_PARAMS; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_SET_PATH_LOSS_RPTING_ENABLE; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_SET_TRANS_POWER_RPTING_ENABLE; + +typedef struct { + UINT16 conn_handle; + UINT8 cur_path_loss; + UINT8 zone_entered; +} __attribute__((packed)) tBTM_BLE_PATH_LOSS_THRESHOLD_EVT; + +typedef struct { + UINT8 status; + UINT16 conn_handle; + UINT8 reason; + UINT8 phy; + INT8 tx_power_level; + UINT8 tx_power_level_flag; + INT8 delta; +} __attribute__((packed)) tBTM_BLE_TRANS_POWER_REPORT_EVT; +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + +#if (BLE_FEAT_CONN_SUBRATING == TRUE) +typedef struct { + UINT8 status; + UINT16 conn_handle; + UINT16 subrate_factor; + UINT16 peripheral_latency; + UINT16 continuation_number; + UINT16 supervision_timeout; +} __attribute__((packed)) tBTM_BLE_SUBRATE_CHANGE_EVT; +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + +#if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +typedef struct { + UINT8 status; + UINT8 big_handle; + UINT32 big_sync_delay; + UINT32 transport_latency; + UINT8 phy; + UINT8 nse; + UINT8 bn; + UINT8 pto; + UINT8 irc; + UINT16 max_pdu; + UINT16 iso_interval; + UINT8 num_bis; + UINT16 bis_handle[BLE_ISO_BIS_MAX_COUNT]; +} tBTM_BLE_BIG_CREATE_CMPL; + +typedef struct { + UINT8 status; + UINT8 big_handle; + UINT8 reason; +} tBTM_BLE_BIG_TERMINATE_CMPL; +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) + +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +typedef struct { + UINT8 status; + UINT8 big_handle; + UINT32 transport_latency_big; + UINT8 nse; + UINT8 bn; + UINT8 pto; + UINT8 irc; + UINT16 max_pdu; + UINT16 iso_interval; + uint8_t num_bis; + uint16_t bis_handle[BLE_ISO_BIS_MAX_COUNT]; +} tBTM_BLE_BIG_SYNC_ESTAB_CMPL; + +typedef struct { + UINT8 big_handle; + UINT8 reason; +} tBTM_BLE_BIG_SYNC_LOST_EVT; + +typedef struct { + UINT16 sync_handle; + UINT8 num_bis; + UINT8 nse; + UINT16 iso_interval; + UINT8 bn; + UINT8 pto; + UINT8 irc; + UINT16 max_pdu; + UINT32 sdu_interval; + UINT32 max_sdu; + UINT8 phy; + UINT8 framing; + UINT8 encryption; +} tBTM_BLE_BIGINFO_ADV_REPORT_EVT; + +typedef struct { + UINT8 status; + UINT16 big_hdl; +} tBTM_BLE_BIG_SYNC_TERMINATE_EVT; + +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_EN == TRUE) +typedef struct { + UINT8 status; + UINT16 conn_handle; + UINT32 cig_sync_delay; + UINT32 cis_sync_delay; + UINT32 trans_lat_c_to_p; + UINT32 trans_lat_p_to_c; + UINT8 phy_c_to_p; + UINT8 phy_p_to_c; + UINT8 nse; + UINT8 bn_c_to_p; + UINT8 bn_p_to_c; + UINT8 ft_c_to_p; + UINT8 ft_p_to_c; + UINT16 max_pdu_c_to_p; + UINT16 max_pdu_p_to_c; + UINT16 iso_interval; +#if (BLE_FEAT_ISO_60_EN == TRUE) + UINT32 sub_interval; + UINT16 max_sdu_c_to_p; + UINT16 max_sdu_p_to_c; + UINT32 sdu_int_c_to_p; + UINT32 sdu_int_p_to_c; + UINT8 framing; +#endif // #if (BLE_FEAT_ISO_60_EN == TRUE) +} tBTM_BLE_CIS_ESTABLISHED_CMPL; + +typedef struct { + UINT16 cis_handle; + UINT8 reason; +} tBTM_BLE_CIS_DISCON_CMPL; + +#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +typedef struct { + UINT8 status; + UINT16 cis_handle; +} tBTM_BLE_ISO_REJECT_CIS_REQ_EVT; + + +typedef struct { + UINT16 acl_handle; + UINT16 cis_handle; + UINT8 cig_id; + UINT8 cis_id; +} tBTM_BLE_CIS_REQUEST_CMPL; +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) + +typedef enum { + BTM_BLE_ISO_DATA_PATH_UNKNOWN = 0, + BTM_BLE_ISO_DATA_PATH_SETUP = 1, + BTM_BLE_ISO_DATA_PATH_REMOVE = 2, + BTM_BLE_ISO_DATA_PATH_MAX, +} tBTM_BLE_ISO_DATA_PATH_UPDATE_TYPE; + +typedef struct { + UINT8 status; + tBTM_BLE_ISO_DATA_PATH_UPDATE_TYPE op_type; + UINT16 conn_hdl; +} tBTM_BLE_ISO_DATA_PATH_UPDATE_EVT; + +typedef struct { + UINT8 status; + UINT16 conn_hdl; + UINT16 pkt_seq_num; + UINT32 tx_time_stamp; + UINT32 time_offset; +} tBTM_BLE_ISO_READ_TX_SYNC_EVT; + +typedef struct { + UINT8 status; + UINT16 conn_hdl; + UINT32 tx_unacked_pkts; + UINT32 tx_flushed_pkts; + UINT32 tx_last_subevt_pkts; + UINT32 retransmitted_pkts; + UINT32 crc_error_pkts; + UINT32 rx_unreceived_pkts; + UINT32 duplicate_pkts; +} tBTM_BLE_ISO_READ_LINK_QUALITY_EVT; + +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +typedef struct { + UINT8 status; + UINT8 cig_id; + UINT8 cis_count; + UINT16 conn_hdl[BLE_ISO_CIS_MAX_COUNT]; +} tBTM_BLE_ISO_SET_CIG_PARAMS_EVT; + +typedef struct { + UINT8 status; + UINT8 cig_id; +} tBTM_BLE_ISO_REMOVE_CIG_EVT; + +#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) + +typedef union { + UINT8 status; +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) + tBTM_BLE_BIG_CREATE_CMPL btm_big_cmpl; + tBTM_BLE_BIG_TERMINATE_CMPL btm_big_term; +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) + tBTM_BLE_BIG_SYNC_ESTAB_CMPL btm_big_sync_estab; + tBTM_BLE_BIG_SYNC_LOST_EVT btm_big_sync_lost; + tBTM_BLE_BIGINFO_ADV_REPORT_EVT btm_biginfo_report; + tBTM_BLE_BIG_SYNC_TERMINATE_EVT btm_big_sync_ter; +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) + tBTM_BLE_ISO_DATA_PATH_UPDATE_EVT btm_data_path_update; + tBTM_BLE_ISO_READ_TX_SYNC_EVT btm_read_tx_sync; + tBTM_BLE_ISO_READ_LINK_QUALITY_EVT btm_read_link_quality; +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) + tBTM_BLE_ISO_SET_CIG_PARAMS_EVT btm_set_cig_params; + tBTM_BLE_ISO_REMOVE_CIG_EVT btm_remove_cig; +#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) + tBTM_BLE_ISO_REJECT_CIS_REQ_EVT btm_reject_cis_req; + tBTM_BLE_CIS_REQUEST_CMPL btm_cis_request_evt; +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_EN == TRUE) + tBTM_BLE_CIS_ESTABLISHED_CMPL btm_cis_established_evt; + tBTM_BLE_CIS_DISCON_CMPL btm_cis_disconnectd_evt; +#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) +} tBTM_BLE_ISO_CB_PARAMS; + +typedef void (*tBTM_BLE_ISO_CBACK)(tBTM_BLE_ISO_EVENT event, tBTM_BLE_ISO_CB_PARAMS *params); +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +typedef struct { + UINT8 status; +} __attribute__((packed)) tBTM_BLE_CTE_SET_TRANS_PARAMS_CMPL; + +typedef struct { + UINT8 status; +} __attribute__((packed)) tBTM_BLE_CTE_SET_TRANS_EN_CMPL; + +typedef struct { + UINT8 status; + UINT16 sync_handle; +} __attribute__((packed)) tBTM_BLE_CTE_IQ_SAMP_EN_CMPL; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CTE_CONN_RECV_PARAMS_CMPL; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CTE_CONN_TRANS_PARAMS_CMPL; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CTE_CONN_REQ_ENABLE_CMPL; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CTE_CONN_RSP_ENABLE_CMPL; + +typedef struct { + UINT8 status; + UINT8 supported_switching_sampling_rates; + UINT8 num_ant; + UINT8 max_switching_pattern_len; + UINT8 max_cte_len; +} __attribute__((packed)) tBTM_BLE_CTE_READ_ANT_INFOR_CMPL; + +typedef struct { + UINT16 sync_handle; + UINT8 channel_idx; + INT16 rssi; + UINT8 rssi_ant_id; + UINT8 cte_type; + UINT8 slot_dur; + UINT8 pkt_status; + UINT16 periodic_evt_counter; + UINT8 sample_count; + UINT8 i_sample[0x52]; + UINT8 q_sample[0x52]; +} __attribute__((packed)) tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT; + +typedef struct { + UINT16 conn_handle; + UINT8 rx_phy; + UINT8 data_channel_idx; + INT16 rssi; + UINT8 rssi_ant_id; + UINT8 cte_type; + UINT8 slot_dur; + UINT8 pkt_status; + UINT16 conn_evt_counter; + UINT8 sample_count; + UINT8 i_sample[0x52]; + UINT8 q_sample[0x52]; +} __attribute__((packed)) tBTM_BLE_CTE_CONN_IQ_REPORT_EVT; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CTE_REQ_FAILED_EVT; + +typedef union { + UINT8 status; +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + tBTM_BLE_CTE_SET_TRANS_PARAMS_CMPL cte_trans_params_cmpl; + tBTM_BLE_CTE_SET_TRANS_EN_CMPL cte_trans_en_cmpl; + tBTM_BLE_CTE_IQ_SAMP_EN_CMPL cte_iq_samp_en_cmpl; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + tBTM_BLE_CTE_CONN_RECV_PARAMS_CMPL cte_recv_params_cmpl; + tBTM_BLE_CTE_CONN_TRANS_PARAMS_CMPL cte_conn_trans_params_cmpl; + tBTM_BLE_CTE_CONN_REQ_ENABLE_CMPL cte_conn_req_en_cmpl; + tBTM_BLE_CTE_CONN_RSP_ENABLE_CMPL cte_conn_rsp_en_cmpl; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + tBTM_BLE_CTE_READ_ANT_INFOR_CMPL cte_read_ant_infor_cmpl; +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT cte_connless_iq_rpt; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + tBTM_BLE_CTE_CONN_IQ_REPORT_EVT cte_conn_iq_rpt; + tBTM_BLE_CTE_REQ_FAILED_EVT cte_req_failed; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +} tBTM_BLE_CTE_CB_PARAMS; + +typedef void (*tBTM_BLE_CTE_CBACK)(tBTM_BLE_CTE_EVENT event, tBTM_BLE_CTE_CB_PARAMS *params); +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + typedef union { UINT8 status; tBTM_BLE_READ_PHY_CMPL read_phy; tBTM_BLE_SET_PREF_DEF_PHY_CMPL set_perf_def_phy; tBTM_BLE_SET_PERF_PHY_CMPL set_perf_phy; +#if (BLE_50_EXTEND_ADV_EN == TRUE) tBTM_BLE_EXT_ADV_SET_RAND_ADDR_CMPL set_ext_rand_addr; tBTM_BLE_EXT_ADV_SET_PARAMS_CMPL set_params; tBTM_BLE_EXT_ADV_DATA_SET_CMPL adv_data_set; tBTM_BLE_EXT_ADV_SCAN_RSP_DATA_SET_CMPL scan_rsp_data_set; tBTM_BLE_EXT_ADV_START_CMPL adv_start; tBTM_BLE_EXT_ADV_STOP_CMPL adv_stop; +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) +#if (BLE_50_PERIODIC_ADV_EN == TRUE) tBTM_BLE_PERIOD_ADV_SET_PARAMS_CMPL per_adv_set_params; tBTM_BLE_PERIOD_ADV_DATA_SET_CMPL per_adv_data_set; tBTM_BLE_PERIOD_ADV_START_CMPL per_adv_start; tBTM_BLE_PERIOD_ADV_STOP_CMPL per_adv_stop; +#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) tBTM_BLE_PERIOD_ADV_SYNC_CREATE_CMPL per_adv_sync_create; tBTM_BLE_PERIOD_ADV_SYNC_CANCEL_CMPL per_adv_sync_cancel; tBTM_BLE_PERIOD_ADV_SYNC_TEMINAT_CMPL per_adv_sync_term; tBTM_BLE_PERIOD_ADV_ADD_DEV_CMPL per_adv_add_dev; tBTM_BLE_PERIOD_ADV_REMOVE_DEV_CMPL per_adv_remove_dev; tBTM_BLE_PEROID_ADV_CLEAR_DEV_CMPL per_adv_clear_dev; +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) +#if (BLE_50_EXTEND_SCAN_EN == TRUE) tBTM_BLE_SET_EXT_SCAN_PARAMS_CMPL ext_scan; tBTM_BLE_EXT_SCAN_START_CMPL scan_start; tBTM_BLE_EXT_SCAN_STOP_CMPL scan_stop; +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) tBTM_BLE_PREF_EXT_CONN_SET_PARAMS_CMPL ext_conn_set_params; tBTM_BLE_PHY_UPDATE_CMPL phy_update; +#if (BLE_50_EXTEND_SCAN_EN == TRUE) tBTM_BLE_EXT_ADV_REPORT ext_adv_report; +#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) tBTM_BLE_ADV_TERMINAT adv_term; tBTM_BLE_SCAN_REQ_RECEIVED scan_req; +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) tBTM_BLE_CHANNEL_SEL_ALG channel_sel; +#if (BLE_50_EXTEND_SYNC_EN == TRUE) tBTM_PERIOD_ADV_REPORT period_adv_report; tBTM_BLE_PERIOD_ADV_SYNC_LOST sync_lost; tBTM_BLE_PERIOD_ADV_SYNC_ESTAB sync_estab; +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) tBTM_BLE_PERIOD_ADV_RECV_ENABLE_CMPL per_adv_recv_enable; tBTM_BLE_PERIOD_ADV_SYNC_TRANS_CMPL per_adv_sync_trans; @@ -1335,6 +1807,18 @@ typedef union { tBTM_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS_CMPL set_past_params; tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV past_recv; #endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + tBTM_BLE_ENH_TRANS_PWR_LEVEL_CMPL enh_trans_pwr_level_cmpl; + tBTM_BLE_REMOTE_TRANS_PWR_LEVEL_CMPL remote_pwr_level_cmpl; + tBTM_BLE_SET_PATH_LOSS_RPTING_PARAMS path_loss_rpting_params; + tBTM_BLE_SET_PATH_LOSS_RPTING_ENABLE path_loss_rpting_enable; + tBTM_BLE_SET_TRANS_POWER_RPTING_ENABLE trans_pwr_rpting_enable; + tBTM_BLE_PATH_LOSS_THRESHOLD_EVT path_loss_thres_evt; + tBTM_BLE_TRANS_POWER_REPORT_EVT trans_pwr_report_evt; +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +#if (BLE_FEAT_CONN_SUBRATING == TRUE) + tBTM_BLE_SUBRATE_CHANGE_EVT subrate_change_evt; +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) } tBTM_BLE_5_GAP_CB_PARAMS; typedef struct { @@ -1370,6 +1854,7 @@ extern "C" { *******************************************************************************/ void BTM_BleRegiseterConnParamCallback(tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb); void BTM_BleRegiseterPktLengthChangeCallback(tBTM_SET_PKT_DATA_LENGTH_CBACK *ptk_len_chane_cb); +void BTM_BleRegisterVendorHciEventCallback(tBTM_BLE_VENDOR_HCI_EVT_CBACK *vendor_hci_evt_cb); /******************************************************************************* ** @@ -1413,23 +1898,6 @@ BOOLEAN BTM_SecAddBleKey (BD_ADDR bd_addr, tBTM_LE_KEY_VALUE *p_le_key, /******************************************************************************* ** -** Function BTM_BleSetAdvParams -** -** Description This function is called to set advertising parameters. -** -** Parameters: None. -** -** Returns void -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleSetAdvParams(UINT16 adv_int_min, UINT16 adv_int_max, - tBLE_BD_ADDR *p_dir_bda, tBTM_BLE_ADV_CHNL_MAP chnl_map); - - - -/******************************************************************************* -** ** Function BTM_BleSetAdvParamsAll ** ** Description This function is called to set all of the advertising parameters. @@ -1474,20 +1942,6 @@ tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask, /******************************************************************************* ** -** Function BTM_BleWriteLongAdvData -** -** Description This function is called to write long advertising data. -** -** Parameters: adv_data: long advertising data -** adv_data_len: the length of long advertising data -** -** Returns void -** -*******************************************************************************/ -tBTM_STATUS BTM_BleWriteLongAdvData(uint8_t *adv_data, uint8_t adv_data_len); - -/******************************************************************************* -** ** Function BTM_BleWriteAdvDataRaw ** ** Description This function is called to write raw advertising data. @@ -1539,6 +1993,7 @@ void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max, //extern void BTM_BleObtainVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb); +#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) /******************************************************************************* ** ** Function BTM_BleSetScanParams @@ -1559,7 +2014,7 @@ void BTM_BleSetScanParams(tGATT_IF client_if, UINT32 scan_interval, UINT32 scan_window, tBLE_SCAN_MODE scan_type, tBLE_SCAN_PARAM_SETUP_CBACK scan_setup_status_cback); - +#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) /******************************************************************************* ** @@ -1658,6 +2113,7 @@ tBTM_STATUS BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode, //extern tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value); +#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleReadScanReports @@ -1673,7 +2129,9 @@ tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value); //extern tBTM_STATUS BTM_BleReadScanReports(tBLE_SCAN_MODE scan_mode, tBTM_BLE_REF_VALUE ref_value); +#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) +#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleTrackAdvertiser @@ -1689,6 +2147,7 @@ tBTM_STATUS BTM_BleReadScanReports(tBLE_SCAN_MODE scan_mode, //extern tBTM_STATUS BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK *p_track_cback, tBTM_BLE_REF_VALUE ref_value); +#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) /******************************************************************************* ** @@ -2100,7 +2559,7 @@ void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK *p_vsc_cback); ** *******************************************************************************/ //extern -UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length); +UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT16 adv_data_len, UINT8 type, UINT8 *p_length); /******************************************************************************* ** @@ -2259,6 +2718,7 @@ BOOLEAN BTM_BleLocalPrivacyEnabled(void); //extern void BTM_BleEnableMixedPrivacyMode(BOOLEAN mixed_on); +#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) /******************************************************************************* ** ** Function BTM_BleMaxMultiAdvInstanceCount @@ -2270,6 +2730,7 @@ void BTM_BleEnableMixedPrivacyMode(BOOLEAN mixed_on); *******************************************************************************/ //extern UINT8 BTM_BleMaxMultiAdvInstanceCount(void); +#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) /******************************************************************************* ** @@ -2450,6 +2911,7 @@ BOOLEAN BTM_BleSecurityProcedureIsRunning (BD_ADDR bd_addr); //extern UINT8 BTM_BleGetSupportedKeySize (BD_ADDR bd_addr); +#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) /*******************************************************************************/ /* Multi ADV API */ /******************************************************************************* @@ -2522,6 +2984,8 @@ tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp, //extern tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id); +#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) + /******************************************************************************* ** ** Function BTM_BleAdvFilterParamSetup @@ -2712,6 +3176,33 @@ BOOLEAN BTM_BleSetPrivacyMode(UINT8 addr_type, UINT8 privacy_mode, tBTM_SET_PRIVACY_MODE_CMPL_CBACK *p_callback); +/******************************************************************************* +** +** Function BTM_BleSetCsaSupport +** +** Description This function is called to set the ChSel field of Advertising or Initiating PDUs +** +** Parameters csa_select - Select LE Channel Selection Algorithm. +** p_callback - Callback function to be called when the operation is completed. +** +** Returns TRUE if the operation was successful, otherwise FALSE. +** +*******************************************************************************/ +BOOLEAN BTM_BleSetCsaSupport (UINT8 csa_select, tBTM_SET_CSA_SUPPORT_CMPL_CBACK *p_callback); + +/******************************************************************************* +** +** Function BTM_BleSetVendorEventMask +** +** Description This function is called to set the vendor HCI event mask +** +** Parameters evt_mask - vendor HCI event mask. +** p_callback - Callback function to be called when the operation is completed. +** +** Returns TRUE if the operation was successful, otherwise FALSE. +** +*******************************************************************************/ +BOOLEAN BTM_BleSetVendorEventMask(UINT32 evt_mask, tBTM_SET_VENDOR_EVT_MASK_CBACK *p_callback); /* #ifdef __cplusplus } @@ -2762,12 +3253,13 @@ tBTM_STATUS BTM_BleSetExtendedScanParams(tBTM_BLE_EXT_SCAN_PARAMS *params); tBTM_STATUS BTM_BleExtendedScan(BOOLEAN enable, UINT16 duration, UINT16 period); void BTM_BleSetPreferExtenedConnParams(BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *params); +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_DTM_TEST_EN == TRUE) void BTM_BleEnhancedReceiverTest(UINT8 rx_freq, UINT8 phy, UINT8 modulation_index, tBTM_CMPL_CB *p_cmd_cmpl_cback); void BTM_BleEnhancedTransmitterTest(UINT8 tx_freq, UINT8 test_data_len, UINT8 packet_payload, UINT8 phy, tBTM_CMPL_CB *p_cmd_cmpl_cback); - -#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#endif // #if (BLE_50_DTM_TEST_EN == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) void BTM_BlePeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable); @@ -2779,4 +3271,93 @@ void BTM_BlePeriodicAdvSetInfoTrans(BD_ADDR bd_addr, UINT16 service_data, UINT8 void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ISO_EN == TRUE) +void BTM_BleIsoRegisterCallback(tBTM_BLE_ISO_CBACK cb); +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +tBTM_STATUS BTM_BleBigCreate(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, + uint32_t sdu_interval, uint16_t max_sdu, uint16_t max_transport_latency, + uint8_t rtn, uint8_t phy, uint8_t packing, uint8_t framing, + uint8_t encryption, uint8_t *broadcast_code); + +tBTM_STATUS BTM_BleBigCreateTest(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, + uint32_t sdu_interval, uint16_t iso_interval, uint8_t nse, + uint16_t max_sdu, uint16_t max_pdu, uint8_t phy, + uint8_t packing, uint8_t framing, uint8_t bn, uint8_t irc, + uint8_t pto, uint8_t encryption, uint8_t *broadcast_code); + +tBTM_STATUS BTM_BleBigTerminate(UINT8 big_handle, UINT8 reason); +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +tBTM_STATUS BTM_BleBigSyncCreate(uint8_t big_handle, uint16_t sync_handle, + uint8_t encryption, uint8_t *bc_code, + uint8_t mse, uint16_t big_sync_timeout, + uint8_t num_bis, uint8_t *bis); + +tBTM_STATUS BTM_BleBigSyncTerminate(uint8_t big_handle); +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +tBTM_STATUS BTM_BleIsoSetDataPath(uint16_t conn_handle, uint8_t data_path_dir, uint8_t data_path_id, uint8_t coding_fmt, + uint16_t company_id, uint16_t vs_codec_id, uint32_t controller_delay, uint8_t codec_len, + uint8_t *codec_cfg); +tBTM_STATUS BTM_BleIsoRemoveDataPath(uint16_t conn_handle, uint8_t data_path_dir); + +tBTM_STATUS BTM_BleIsoReadTxSync(uint16_t iso_hdl); +tBTM_STATUS BTM_BleIsoReadLinkQuality(uint16_t iso_hdl); + +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +tBTM_STATUS BTM_BleSetCigParams(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t worse_case_SCA, uint8_t packing, + uint8_t framing, uint16_t mtl_c_to_p, uint16_t mtl_p_to_c, uint8_t cis_cnt, uint8_t *cis_params); +tBTM_STATUS BTM_BleSetCigParamsTest(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t ft_c_to_p, uint8_t ft_p_to_c, uint16_t iso_interval, + uint8_t worse_case_SCA, uint8_t packing, uint8_t framing, uint8_t cis_cnt, uint8_t *cis_params); +tBTM_STATUS BTM_BleCreateCis(uint8_t cis_count, uint8_t *cis_hdls); +tBTM_STATUS BTM_BleRemoveCig(uint8_t cig_id); +#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +tBTM_STATUS BTM_BleAcceptCisReq(uint16_t cis_handle); +tBTM_STATUS BTM_BleRejectCisReq(uint16_t cis_handle, uint8_t reason); +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +#if (BLE_FEAT_ISO_CIG_EN == TRUE) +tBTM_STATUS BTM_BleDisconCis(uint16_t cis_handle, uint8_t reason); +#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) +#endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +void BTM_BleCteRegisterCallback(tBTM_BLE_CTE_CBACK cb); +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +tBTM_STATUS BTM_BleSetCteTransParams(uint8_t adv_handle, uint8_t cte_len, uint8_t cte_type, uint8_t cte_count, uint8_t switching_pattern_len, uint8_t *antenna_ids); +tBTM_STATUS BTM_BleCteSetConnectionlessTransEnable(uint8_t adv_handle, uint8_t cte_en); +tBTM_STATUS BTM_BleCteSetConnectionlessIqSamplingEnable(uint16_t sync_handle, uint8_t sampling_en, uint8_t slot_dur, + uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *ant_ids); +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +tBTM_STATUS BTM_BleCteSetConnectionReceiveParams(uint16_t conn_handle, uint8_t sampling_en, uint8_t slot_dur, + uint8_t switching_pattern_len, uint8_t *ant_ids); +tBTM_STATUS BTM_BleCteSetConnectionTransParams(uint16_t conn_handle, uint8_t cte_types, uint8_t switching_pattern_len, uint8_t *ant_ids); +tBTM_STATUS BTM_BleCteSetConnectionRequestEnable(uint16_t conn_handle, uint8_t enable, uint16_t cte_req_int, + uint8_t req_cte_len, uint8_t req_cte_type); +tBTM_STATUS BTM_BleCteSetConnectionRspEnable(uint16_t conn_handle, uint8_t enable); +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +tBTM_STATUS BTM_BleCteReadAntInfor(void); + +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +void BTM_BleEnhReadTransPowerLevel(uint16_t conn_handle, uint8_t phy); +void BTM_BleReadRemoteTransPwrLevel(uint16_t conn_handle, uint8_t phy); +void BTM_BleSetPathLossRptParams(uint16_t conn_handle, uint8_t high_threshold, uint8_t high_hysteresis, + uint8_t low_threshold, uint8_t low_hysteresis, uint16_t min_time_spent); +void BTM_BleSetPathLossRptEnable(uint16_t conn_handle, uint8_t enable); +void BTM_BleSetTransPwrRptEnable(uint16_t conn_handle, uint8_t local_enable, uint8_t remote_enable); +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + +#if (BLE_FEAT_CONN_SUBRATING == TRUE) +void BTM_BleSetDefaultSubrate(UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout); + +void BTM_BleSubrateRequest(UINT16 conn_handle, UINT16 subrate_min, UINT16 subrate_max, + UINT16 max_latency, UINT16 continuation_number, UINT16 supervision_timeout); +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BLE_50_FEATURE_SUPPORT == TRUE) +tBTM_STATUS BTM_BleSetHostFeature(uint16_t bit_num, uint8_t bit_val); +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #endif diff --git a/lib/bt/host/bluedroid/stack/include/stack/dyn_mem.h b/lib/bt/host/bluedroid/stack/include/stack/dyn_mem.h index fa1ed498..7c208d8c 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/dyn_mem.h +++ b/lib/bt/host/bluedroid/stack/include/stack/dyn_mem.h @@ -45,6 +45,8 @@ #define HCRP_DYNAMIC_MEMORY TRUE #define HFP_DYNAMIC_MEMORY TRUE #define HID_DYNAMIC_MEMORY TRUE +#define OBEX_DYNAMIC_MEMORY TRUE +#define GOEP_DYNAMIC_MEMORY TRUE #define HSP2_DYNAMIC_MEMORY TRUE #define ICP_DYNAMIC_MEMORY TRUE #define OPP_DYNAMIC_MEMORY TRUE @@ -53,6 +55,8 @@ #define SLIP_DYNAMIC_MEMORY TRUE #define LLCP_DYNAMIC_MEMORY TRUE #define BTC_SBC_DEC_DYNAMIC_MEMORY TRUE +#define BTC_GAP_BT_DYNAMIC_MEMORY TRUE +#define L2CAP_DYNAMIC_MEMORY TRUE #else /* #if UC_BT_BLE_DYNAMIC_ENV_MEMORY */ #define BTU_DYNAMIC_MEMORY FALSE @@ -79,6 +83,8 @@ #define HCRP_DYNAMIC_MEMORY FALSE #define HFP_DYNAMIC_MEMORY FALSE #define HID_DYNAMIC_MEMORY FALSE +#define OBEX_DYNAMIC_MEMORY FALSE +#define GOEP_DYNAMIC_MEMORY FALSE #define HSP2_DYNAMIC_MEMORY FALSE #define ICP_DYNAMIC_MEMORY FALSE #define OPP_DYNAMIC_MEMORY FALSE @@ -87,6 +93,8 @@ #define SLIP_DYNAMIC_MEMORY FALSE #define LLCP_DYNAMIC_MEMORY FALSE #define BTC_SBC_DEC_DYNAMIC_MEMORY FALSE +#define BTC_GAP_BT_DYNAMIC_MEMORY FALSE +#define L2CAP_DYNAMIC_MEMORY FALSE #endif /* #if UC_BT_BLE_DYNAMIC_ENV_MEMORY */ @@ -191,6 +199,14 @@ #define HID_DYNAMIC_MEMORY FALSE #endif +#ifndef OBEX_DYNAMIC_MEMORY +#define OBEX_DYNAMIC_MEMORY FALSE +#endif + +#ifndef GOEP_DYNAMIC_MEMORY +#define GOEP_DYNAMIC_MEMORY FALSE +#endif + #ifndef HSP2_DYNAMIC_MEMORY #define HSP2_DYNAMIC_MEMORY FALSE #endif diff --git a/lib/bt/host/bluedroid/stack/include/stack/gatt_api.h b/lib/bt/host/bluedroid/stack/include/stack/gatt_api.h index fed2ea9a..6c63db62 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/gatt_api.h +++ b/lib/bt/host/bluedroid/stack/include/stack/gatt_api.h @@ -139,7 +139,7 @@ typedef UINT16 tGATT_DISCONN_REASON; /* max length of an attribute value */ #ifndef GATT_MAX_ATTR_LEN -#define GATT_MAX_ATTR_LEN 512 +#define GATT_MAX_ATTR_LEN GATT_MAX_MTU_SIZE #endif /* default GATT MTU size over LE link diff --git a/lib/bt/host/bluedroid/stack/include/stack/goep_common.h b/lib/bt/host/bluedroid/stack/include/stack/goep_common.h new file mode 100644 index 00000000..74cb3ca8 --- /dev/null +++ b/lib/bt/host/bluedroid/stack/include/stack/goep_common.h @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "common/bt_target.h" + +/* GOEP Client or Server(not supported yet) API return code */ +#define GOEP_SUCCESS 0x00 /* Operation successful */ +#define GOEP_FAILURE 0x01 /* Operation failed */ +#define GOEP_NO_RESOURCES 0x02 /* Not enough resources */ +#define GOEP_BAD_HANDLE 0x04 /* Bad handle */ +#define GOEP_INVALID_PARAM 0x08 /* Invalid parameter */ +#define GOEP_INVALID_STATE 0x10 /* Operation not allow in current state */ +#define GOEP_CONGEST 0x20 /* Congest */ +#define GOEP_TL_ERROR 0x40 /* Lower transport layer error */ diff --git a/lib/bt/host/bluedroid/stack/include/stack/goepc_api.h b/lib/bt/host/bluedroid/stack/include/stack/goepc_api.h new file mode 100644 index 00000000..f2b93f86 --- /dev/null +++ b/lib/bt/host/bluedroid/stack/include/stack/goepc_api.h @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "common/bt_target.h" + +#include "stack/goep_common.h" +#include "stack/obex_api.h" + +#if (GOEPC_INCLUDED == TRUE) + +enum { + GOEPC_OPENED_EVT, /* connection open */ + GOEPC_CLOSED_EVT, /* disconnect unexpected */ + GOEPC_MTU_CHANGED_EVT, /* lower layer MTU change */ + GOEPC_CONGEST_EVT, /* lower layer connection congest */ + GOEPC_UNCONGEST_EVT, /* lower layer connection uncongest */ + GOEPC_RESPONSE_EVT /* response from server */ +}; + +typedef struct { + UINT16 peer_mtu; /* peer mtu of lower level connection */ + UINT16 our_mtu; /* our mtu of lower level connection */ +} tGOEPC_MSG_OPENED; + +typedef struct { + UINT8 reason; /* connection close reason */ +} tGOEPC_MSG_CLOSED; + +typedef struct { + UINT16 peer_mtu; /* peer mtu of lower level connection */ + UINT16 our_mtu; /* our mtu of lower level connection */ +} tGOEPC_MSG_MTU_CHANGED; + +typedef struct { + UINT8 opcode; /* which opcode that this packet response to */ + BOOLEAN final; /* whether this is a final packet */ + BOOLEAN srm_en; /* whether srm is enable */ + BOOLEAN srm_wait; /* whether srm wait is set, set by peer or by us */ + BT_HDR *pkt; /* pointer to response packet */ +} tGOEPC_MSG_RESPONSE; + +typedef union { + tGOEPC_MSG_OPENED opened; + tGOEPC_MSG_CLOSED closed; + tGOEPC_MSG_MTU_CHANGED mtu_changed; + tGOEPC_MSG_RESPONSE response; +} tGOEPC_MSG; + +typedef void (tGOEPC_EVT_CBACK)(UINT16 handle, UINT8 event, tGOEPC_MSG *msg); + +/******************************************************************************* +* The following APIs are called by bluetooth stack automatically +*******************************************************************************/ + +extern UINT16 GOEPC_Init(void); + +extern void GOEPC_Deinit(void); + +/******************************************************************************* +* The following APIs must be executed in btu task +*******************************************************************************/ + +extern UINT16 GOEPC_Open(tOBEX_SVR_INFO *p_svr, tGOEPC_EVT_CBACK callback, UINT16 *out_handle); + +extern UINT16 GOEPC_Close(UINT16 handle); + +extern UINT16 GOEPC_SendRequest(UINT16 handle); + +extern UINT16 GOEPC_PrepareRequest(UINT16 handle, tOBEX_PARSE_INFO *info, UINT16 buff_size); + +extern UINT16 GOEPC_DropRequest(UINT16 handle); + +extern UINT16 GOEPC_RequestSetSRM(UINT16 handle, BOOLEAN srm_en, BOOLEAN srm_wait); + +extern UINT16 GOEPC_RequestAddHeader(UINT16 handle, UINT8 header_id, const UINT8 *data, UINT16 data_len); + +#endif /* #if (GOEPC_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/include/stack/hcidefs.h b/lib/bt/host/bluedroid/stack/include/stack/hcidefs.h index 21b14881..23f9b3e6 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/lib/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -357,8 +357,12 @@ #define HCI_BLE_READ_PHY (0x0030 | HCI_GRP_BLE_CMDS) #define HCI_BLE_SET_DEFAULT_PHY (0x0031 | HCI_GRP_BLE_CMDS) #define HCI_BLE_SET_PHY (0x0032 | HCI_GRP_BLE_CMDS) +#endif +#if (BLE_50_DTM_TEST_EN == TRUE) #define HCI_BLE_ENH_RX_TEST (0x0033 | HCI_GRP_BLE_CMDS) #define HCI_BLE_ENH_TX_TEST (0x0034 | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_50_DTM_TEST_EN == TRUE) +#if (BLE_50_FEATURE_SUPPORT == TRUE) #define HCI_BLE_SET_ADV_RAND_ADDR (0x0035 | HCI_GRP_BLE_CMDS) #define HCI_BLE_SET_EXT_ADV_PARAM (0x0036 | HCI_GRP_BLE_CMDS) #define HCI_BLE_SET_EXT_ADV_DATA (0x0037 | HCI_GRP_BLE_CMDS) @@ -386,6 +390,20 @@ #define HCI_BLE_WR_RF_PATH_COMPENSATION (0x004D | HCI_GRP_BLE_CMDS) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #define HCI_BLE_SET_PRIVACY_MODE (0x004E | HCI_GRP_BLE_CMDS) +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#define HCI_BLE_SET_CONNLESS_CTE_TRANS_PARAMS (0x0051 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_CONNLESS_CTE_TRANS_ENABLE (0x0052 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_CONNLESS_IQ_SAMPLING_ENABLE (0x0053 | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define HCI_BLE_SET_CONN_CTE_RECEIVE_PARAMS (0x0054 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_CONN_CTE_TRANS_PARAMS (0x0055 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_CONN_CTE_REQ_ENABLE (0x0056 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_CONN_CTE_RSP_ENABLE (0x0057 | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define HCI_BLE_READ_ANT_INFOR (0x0058 | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_CTE_EN == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #define HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE (0x0059 | HCI_GRP_BLE_CMDS) #define HCI_BLE_PERIOD_ADV_SYNC_TRANS (0x005A | HCI_GRP_BLE_CMDS) @@ -393,6 +411,38 @@ #define HCI_BLE_SET_PAST_PARAMS (0x005C | HCI_GRP_BLE_CMDS) #define HCI_BLE_SET_DEFAULT_PAST_PARAMS (0x005D | HCI_GRP_BLE_CMDS) #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define HCI_BLE_READ_BUFFER_SZIE_V2 (0x0060 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_ISO_READ_TX_SYNC (0x0061 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_ISO_SET_CIG_PARAMS (0x0062 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_ISO_SET_CIG_PARAMS_TEST (0x0063 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_ISO_CREATE_CIS (0x0064 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_ISO_REMOVE_CIG (0x0065 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_ISO_ACCEPT_CIS_REQ (0x0066 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_ISO_REJECT_CIS_REQ (0x0067 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CREATE_BIG (0x0068 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CREATE_BIG_TEST (0x0069 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_TERMINATE_BIG (0x006A | HCI_GRP_BLE_CMDS) +#define HCI_BLE_BIG_CREATE_SYNC (0x006B | HCI_GRP_BLE_CMDS) +#define HCI_BLE_BIG_TERMINATE_SYNC (0x006C | HCI_GRP_BLE_CMDS) +#define HCI_BLE_ISO_SET_DATA_PATH (0x006E | HCI_GRP_BLE_CMDS) +#define HCI_BLE_ISO_REMOVE_DATA_PATH (0x006F | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_HOST_FEATURE (0x0074 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_ISO_READ_ISO_LINK_QUALITY (0x0075 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_HOST_FEATURE_V2 (0x0097 | HCI_GRP_BLE_CMDS) + +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +#define HCI_BLE_ENH_READ_TRANS_POWER_LEVEL (0x0076 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_READ_REMOTE_TRANS_POWER_LEVEL (0x0077 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_PATH_LOSS_REPORTING_PARAMS (0x0078 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_PATH_LOSS_REPORTING_ENABLE (0x0079 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_TRANS_POWER_REPORTING_ENABLE (0x007A | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + +#if (BLE_FEAT_CONN_SUBRATING == TRUE) +#define HCI_BLE_SET_DEFAULT_SUBRATE (0x007D | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SUBRATE_REQUEST (0x007E | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + // Vendor OGF define #define HCI_VENDOR_OGF 0x3F @@ -422,11 +472,20 @@ #define HCI_SUBCODE_BLE_ADV_REPORT_FLOW_CONTROL 0x0A #define HCI_SUBCODE_BLE_RD_STATIC_ADDR 0x0B #define HCI_SUBCODE_BLE_CLEAR_ADV 0x0C +#define HCI_SUBCODE_BLE_SET_CSA_SUPPORT 0x12 +#define HCI_SUBCODE_BLE_SET_VENDOR_EVT_MASK 0x16 #define HCI_SUBCODE_BLE_MAX 0x7F //ESP BT subcode define #define HCI_SUBCODE_BT_INIT 0x00 +#define HCI_SUBCODE_BT_WRITE_DM1_ENABLE 0x01 #define HCI_SUBCODE_BT_SET_MIN_ENC_KEY_SIZE 0x02 +#define HCI_SUBCODE_BT_CLK_UPD 0x03 +#define HCI_SUBCODE_BT_SET_AFH 0x07 +#define HCI_SUBCODE_BT_SET_EVT_MASK 0x08 +#define HCI_SUBCODE_BT_SET_AFH_REPORTING_MODE 0x09 +#define HCI_SUBCODE_BT_MASK_RMT_AFH_CH_CLASS 0x0A +#define HCI_SUBCODE_BT_WR_AUTO_RATE_INIT_ENABLE 0x0B #define HCI_SUBCODE_BT_MAX 0x7F #define HCI_ESP_VENDOR_OPCODE_BUILD(ogf, group, subcode) ((ogf << 10) | (group <<7) | (subcode << 0)) @@ -460,16 +519,25 @@ #define HCI_BLE_ENERGY_INFO_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_ENERGY_INFO) /* Extended BLE Scan parameters OCF */ #define HCI_BLE_EXTENDED_SCAN_PARAMS_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_EXTENDED_SCAN_PARAMS) -/* Long BLE Adv data OCF */ -#define HCI_VENDOR_BLE_LONG_ADV_DATA HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_LONG_ADV) /* BLE update duplicate scan exceptional list */ #define HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_DUPLICATE_EXCEPTIONAL_LIST) #define HCI_VENDOR_BLE_SET_ADV_FLOW_CONTROL HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_SET_ADV_FLOW_CONTROL) #define HCI_VENDOR_BLE_ADV_REPORT_FLOW_CONTROL HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_ADV_REPORT_FLOW_CONTROL) /* BLE clear legacy advertising */ #define HCI_VENDOR_BLE_CLEAR_ADV HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_CLEAR_ADV) +/* BLE set CSA support */ +#define HCI_VENDOR_BLE_SET_CSA_SUPPORT HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_SET_CSA_SUPPORT) +/* BLE set vendor event mask */ +#define HCI_VENDOR_BLE_SET_EVT_MASK HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_SET_VENDOR_EVT_MASK) //ESP BT HCI CMD -#define HCI_VENDOR_BT_SET_MIN_ENC_KEY_SIZE HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_SET_MIN_ENC_KEY_SIZE) +#define HCI_VENDOR_BT_WRITE_DM1_ENABLE HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_WRITE_DM1_ENABLE) +#define HCI_VENDOR_BT_SET_MIN_ENC_KEY_SIZE HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_SET_MIN_ENC_KEY_SIZE) +#define HCI_VENDOR_BT_CLK_UPD HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_CLK_UPD) +#define HCI_VENDOR_BT_SET_AFH HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_SET_AFH) +#define HCI_VENDOR_BT_SET_EVT_MASK HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_SET_EVT_MASK) +#define HCI_VENDOR_BT_SET_AFH_REPORTING_MODE HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_SET_AFH_REPORTING_MODE) +#define HCI_VENDOR_BT_MASK_RMT_AFH_CH_CLASS HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_MASK_RMT_AFH_CH_CLASS) +#define HCI_VENDOR_BT_WR_AUTO_RATE_INIT_ENABLE HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_WR_AUTO_RATE_INIT_ENABLE) /* subcode for multi adv feature */ #define BTM_BLE_MULTI_ADV_SET_PARAM 0x01 @@ -820,10 +888,48 @@ #define HCI_BLE_PERIOD_ADV_SYNC_TRANS_RECV_EVT 0x18 #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +#define HCI_BLE_CONNLESS_IQ_REPORT_EVT 0x15 +#define HCI_BLE_CONN_IQ_REPORT_EVT 0x16 +#define HCI_BLE_CTE_REQUEST_FAILED_EVT 0x17 +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + +#if (BLE_FEAT_ISO_EN == TRUE) +#define HCI_BLE_CIS_ESTABLISHED_V1_EVT 0x19 +#define HCI_BLE_CIS_REQUEST_EVT 0x1A +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#define HCI_BLE_BIG_CREATE_COMPLETE_EVT 0x1B +#define HCI_BLE_BIG_TERMINATE_COMPLETE_EVT 0x1C +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +#define HCI_BLE_BIG_SYNC_ESTABLISHED_EVT 0x1D +#define HCI_BLE_BIG_SYNC_LOST_EVT 0x1E +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +#define HCI_BLE_BIGINFO_ADV_REPORT_EVT 0x22 +#define HCI_BLE_CIS_ESTABLISHED_V2_EVT 0x2A +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +#define HCI_BLE_PATH_LOSS_THRESHOLD_EVT 0x20 +#define HCI_BLE_TRANS_POWER_REPORTING_EVT 0x21 +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + +#if (BLE_FEAT_CONN_SUBRATING == TRUE) +#define HCI_BLE_SUBRATE_CHANGE_EVT 0x23 +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + /* Definitions for LE Channel Map */ #define HCI_BLE_CHNL_MAP_SIZE 5 +#define HCI_VENDOR_SPECIFIC_EVT 0xFF /* Vendor specific events */ +#define HCI_VENDOR_LEGACY_REM_AUTH_EVT_SUBCODE 0x03 +#define HCI_VENDOR_AFH_CHG_EVT_SUBCODE 0x05 +#define HCI_VENDOR_CH_CLASSIFICATION_EVT_SUBCODE 0x06 +#define HCI_VENDOR_CH_CLASSIFICATION_REPORTING_MODE_EVT_SUBCODE 0x07 + #define HCI_VENDOR_SPECIFIC_EVT 0xFF /* Vendor specific events */ +#define HCI_VSE_LE_SUBEVT_BASE 0xC0 /* BLE vendor event code base */ +#define HCI_VSE_LE_EVT_MAX 0xFF /* BLE vendor event code max */ #define HCI_NAP_TRACE_EVT 0xFF /* was define 0xFE, 0xFD, change to 0xFF because conflict w/ TCI_EVT and per specification compliant */ @@ -1871,42 +1977,50 @@ typedef struct { #define HCI_PING_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_PING_OFF] & HCI_EXT_FEATURE_PING_MASK) /* -** LE features encoding - page 0 (the only page for now) +** LE features encoding - page 0 */ -/* LE Encryption */ +/* LE Encryption: bit 0 */ #define HCI_LE_FEATURE_LE_ENCRYPTION_MASK 0x01 #define HCI_LE_FEATURE_LE_ENCRYPTION_OFF 0 #define HCI_LE_ENCRYPTION_SUPPORTED(x) ((x)[HCI_LE_FEATURE_LE_ENCRYPTION_OFF] & HCI_LE_FEATURE_LE_ENCRYPTION_MASK) -/* Connection Parameters Request Procedure */ +/* Connection Parameters Request Procedure: bit 1 */ #define HCI_LE_FEATURE_CONN_PARAM_REQ_MASK 0x02 #define HCI_LE_FEATURE_CONN_PARAM_REQ_OFF 0 #define HCI_LE_CONN_PARAM_REQ_SUPPORTED(x) ((x)[HCI_LE_FEATURE_CONN_PARAM_REQ_OFF] & HCI_LE_FEATURE_CONN_PARAM_REQ_MASK) -/* Extended Reject Indication */ +/* Extended Reject Indication: bit 2 */ #define HCI_LE_FEATURE_EXT_REJ_IND_MASK 0x04 #define HCI_LE_FEATURE_EXT_REJ_IND_OFF 0 #define HCI_LE_EXT_REJ_IND_SUPPORTED(x) ((x)[HCI_LE_FEATURE_EXT_REJ_IND_OFF] & HCI_LE_FEATURE_EXT_REJ_IND_MASK) -/* Slave-initiated Features Exchange */ +/* Slave-initiated Features Exchange: bit 3 */ #define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK 0x08 #define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF 0 #define HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(x) ((x)[HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF] & HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK) +/* LE Data Packet Length Extension: bit 5 */ +#define HCI_LE_FEATURE_DATA_LEN_EXT_MASK 0x20 +#define HCI_LE_FEATURE_DATA_LEN_EXT_OFF 0 +#define HCI_LE_DATA_LEN_EXT_SUPPORTED(x) ((x)[HCI_LE_FEATURE_DATA_LEN_EXT_OFF] & HCI_LE_FEATURE_DATA_LEN_EXT_MASK) + /* Enhanced privacy Feature: bit 6 */ #define HCI_LE_FEATURE_ENHANCED_PRIVACY_MASK 0x40 #define HCI_LE_FEATURE_ENHANCED_PRIVACY_OFF 0 #define HCI_LE_ENHANCED_PRIVACY_SUPPORTED(x) ((x)[HCI_LE_FEATURE_ENHANCED_PRIVACY_OFF] & HCI_LE_FEATURE_ENHANCED_PRIVACY_MASK) -/* Extended scanner filter policy : 7 */ +/* Extended scanner filter policy: bit 7 */ #define HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_MASK 0x80 #define HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_OFF 0 #define HCI_LE_EXT_SCAN_FILTER_POLICY_SUPPORTED(x) ((x)[HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_OFF] & HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_MASK) -/* Slave-initiated Features Exchange */ -#define HCI_LE_FEATURE_DATA_LEN_EXT_MASK 0x20 -#define HCI_LE_FEATURE_DATA_LEN_EXT_OFF 0 -#define HCI_LE_DATA_LEN_EXT_SUPPORTED(x) ((x)[HCI_LE_FEATURE_DATA_LEN_EXT_OFF] & HCI_LE_FEATURE_DATA_LEN_EXT_MASK) +/* +** LE features encoding - page 1 +*/ +/* LE Extended Advertising: bit 12 */ +#define HCI_LE_FEATURE_EXT_ADV_MASK 0x10 +#define HCI_LE_FEATURE_EXT_ADV_OFF 1 +#define HCI_LE_EXT_ADV_SUPPORTED(x) ((x)[HCI_LE_FEATURE_EXT_ADV_OFF] & HCI_LE_FEATURE_EXT_ADV_MASK) /* ** Local Supported Commands encoding diff --git a/lib/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/lib/bt/host/bluedroid/stack/include/stack/hcimsgs.h index 951e5b70..4ee07b4d 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/lib/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -759,12 +759,18 @@ void btsnd_hcic_vendor_spec_cmd (BT_HDR *buffer, UINT16 opcode, #define HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL 2 #define HCIC_PARAM_SIZE_BLE_CLEAR_ADV 0 #define HCIC_PARAM_SIZE_SET_PRIVACY_MODE 8 +#define HCIC_PARAM_SIZE_BLE_SET_CSA_SUPPORT 1 +#define HCIC_PARAM_SIZE_BLE_SET_VENDOR_EVT_MASK 4 #if (BLE_50_FEATURE_SUPPORT == TRUE) #define HCIC_PARAM_SIZE_BLE_READ_PHY 2 #define HCIC_PARAM_SIZE_BLE_SET_DEF_PHY 3 #define HCIC_PARAM_SIZE_BLE_SET_PHY 7 +#endif +#if (BLE_50_DTM_TEST_EN == TRUE) #define HCIC_PARAM_SIZE_ENH_RX_TEST 3 #define HCIC_PARAM_SIZE_ENH_TX_TEST 4 +#endif // #if (BLE_50_DTM_TEST_EN == TRUE) +#if (BLE_50_FEATURE_SUPPORT == TRUE) #define HCIC_PARAM_SIZE_EXT_RAND_ADDR 7 #define HCIC_PARAM_SIZE_EXT_ADV_SET_PARAMS 25 #define HCIC_PARAM_SIZE_EXT_ADV_WRITE_DATA 251 @@ -914,7 +920,14 @@ BOOLEAN btsnd_hcic_ble_set_rand_priv_addr_timeout (UINT16 rpa_timout); BOOLEAN btsnd_hcic_ble_clear_adv(void); +BOOLEAN btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 privacy_mode); + +BOOLEAN btsnd_hcic_ble_set_csa_support (UINT8 csa_select); + +BOOLEAN btsnd_hcic_ble_set_vendor_evt_mask (UINT32 evt_mask); + #endif /* BLE_INCLUDED */ + #if (BLE_50_FEATURE_SUPPORT == TRUE) typedef struct { UINT8 scan_type; @@ -957,14 +970,17 @@ UINT8 btsnd_hcic_ble_set_prefered_default_phy(UINT8 all_phys, BOOLEAN btsnd_hcic_ble_set_phy(UINT16 conn_handle, UINT8 all_phys, UINT8 tx_phys, UINT8 rx_phys, UINT16 phy_options); - +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_DTM_TEST_EN == TRUE) UINT8 btsnd_hcic_ble_enhand_rx_test(UINT8 rx_channel, UINT8 phy, UINT8 modulation_idx); UINT8 btsnd_hcic_ble_enhand_tx_test(UINT8 tx_channel, UINT8 len, UINT8 packect, UINT8 phy); +#endif // #if (BLE_50_DTM_TEST_EN == TRUE) +#if (BLE_50_FEATURE_SUPPORT == TRUE) UINT8 btsnd_hcic_ble_set_extend_rand_address(UINT8 adv_handle, BD_ADDR rand_addr); UINT8 btsnd_hcic_ble_set_ext_adv_params(UINT8 adv_handle, UINT16 properties, UINT32 interval_min, @@ -1018,7 +1034,7 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn); BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 filter_policy, UINT8 adv_sid, UINT8 adv_addr_type, BD_ADDR adv_addr, - UINT16 sync_timeout, UINT8 unused); + UINT16 sync_timeout, UINT8 sync_cte_type); UINT8 btsnd_hcic_ble_periodic_adv_create_sync_cancel(void); @@ -1042,8 +1058,6 @@ UINT8 btsnd_hcic_ble_write_rf_path_compensation(UINT16 rf_tx_path, UINT16 rf_rx_ #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) -UINT8 btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 privacy_mode); - #define HCIC_PARAM_SIZE_WRITE_AUTHENT_PAYLOAD_TOUT 4 #define HCI__WRITE_AUTHENT_PAYLOAD_TOUT_HANDLE_OFF 0 @@ -1069,4 +1083,164 @@ BOOLEAN btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UI UINT8 btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ISO_EN == TRUE) +#define HCIC_PARAM_SIZE_ISO_READ_TX_SYNC_PARAMS 2 +#define HCIC_PARAM_SIZE_ISO_SET_CIG_PARAMS 15 +#define HCIC_PARAM_SIZE_ISO_SET_CIG_TEST_PARAMS 15 +#define HCIC_PARAM_SIZE_ISO_CREATE_CIS_PARAMS 1 +#define HCIC_PARAM_SIZE_ISO_REMOVE_CIG_PARAMS 1 +#define HCIC_PARAM_SIZE_ISO_ACCEPT_CIS_REQ_PARAMS 2 +#define HCIC_PARAM_SIZE_ISO_REJECT_CIS_REQ_PARAMS 3 +#define HCIC_PARAM_SIZE_ISO_READ_LINK_QUALITY_PARAMS 2 +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#define HCIC_PARAM_SIZE_BIG_CREATE_PARAMS 31 +#define HCIC_PARAM_SIZE_BIG_CREATE_TEST_PARAMS 36 +#define HCIC_PARAM_SIZE_BIG_TERMINATE_PARAMS 2 +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +#define HCIC_PARAM_SIZE_BIG_SYNC_CREATE_PARAMS 55 +#define HCIC_PARAM_SIZE_BIG_SYNC_TERMINATE_PARAMS 1 +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +#define HCIC_PARAM_SIZE_ISO_SET_DATA_PATH_PARAMS 13 +#define HCIC_PARAM_SIZE_ISO_REMOVE_DATA_PATH_PARAMS 3 + +#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) +struct ble_hci_le_cis_params { + uint8_t cis_id; + uint16_t max_sdu_c_to_p; + uint16_t max_sdu_p_to_c; + uint8_t phy_c_to_p; + uint8_t phy_p_to_c; + uint8_t rtn_c_to_p; + uint8_t rtn_p_to_c; +} __attribute__((packed)); +struct ble_hci_le_cis_params_test { + uint8_t cis_id; + uint8_t nse; + uint16_t max_sdu_c_to_p; + uint16_t max_sdu_p_to_c; + uint16_t max_pdu_c_to_p; + uint16_t max_pdu_p_to_c; + uint8_t phy_c_to_p; + uint8_t phy_p_to_c; + uint8_t bn_c_to_p; + uint8_t bn_p_to_c; +} __attribute__((packed)); + + +struct ble_hci_cis_hdls { + uint16_t cis_hdl; + uint16_t acl_hdl; +}__attribute__((packed)); + +UINT8 btsnd_hcic_ble_iso_set_cig_params(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t worse_case_SCA, uint8_t packing, + uint8_t framing, uint16_t mtl_c_to_p, uint16_t mtl_p_to_c, uint8_t cis_cnt, struct ble_hci_le_cis_params *cis_params); +UINT8 btsnd_hcic_ble_iso_set_cig_params_test(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t ft_c_to_p, uint8_t ft_p_to_c, + uint16_t iso_interval, uint8_t worse_case_SCA, uint8_t packing, uint8_t framing, uint8_t cis_cnt, + struct ble_hci_le_cis_params_test *cis_params_test); +UINT8 btsnd_hcic_ble_iso_create_cis(uint8_t cis_count, struct ble_hci_cis_hdls *cis_hdls); +UINT8 btsnd_hcic_ble_iso_remove_cig(uint8_t cig_id); +#endif // (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) + +#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) +UINT8 btsnd_hcic_ble_iso_accept_cis_req(uint16_t cis_handle); +UINT8 btsnd_hcic_ble_iso_reject_cis_req(uint16_t cis_handle, uint8_t reason); +#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) + +#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +UINT8 btsnd_hcic_ble_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, + uint32_t sdu_interval, uint16_t max_sdu, uint16_t max_transport_latency, + uint8_t rtn, uint8_t phy, uint8_t packing, uint8_t framing, + uint8_t encryption, uint8_t *broadcast_code); + +UINT8 btsnd_hcic_ble_big_create_test(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, + uint32_t sdu_interval, uint16_t iso_interval, uint8_t nse, + uint16_t max_sdu, uint16_t max_pdu, uint8_t phy, + uint8_t packing, uint8_t framing, uint8_t bn, uint8_t irc, + uint8_t pto, uint8_t encryption, uint8_t *broadcast_code); + +UINT8 btsnd_hcic_ble_big_terminate(uint8_t big_handle, uint8_t reason); +#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) + +#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) +UINT8 btsnd_hcic_ble_big_sync_create(uint8_t big_handle, uint16_t sync_handle, + uint8_t encryption, uint8_t *bc_code, + uint8_t mse, uint16_t big_sync_timeout, + uint8_t num_bis, uint8_t *bis); + +UINT8 btsnd_hcic_ble_big_sync_terminate(uint8_t big_handle); +#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) + +UINT8 btsnd_hcic_ble_iso_set_data_path(uint16_t conn_handle, uint8_t data_path_dir, uint8_t data_path_id, uint8_t coding_fmt, + uint16_t company_id, uint16_t vs_codec_id, uint32_t controller_delay, uint8_t codec_len, + uint8_t *codec_cfg); +UINT8 btsnd_hcic_ble_iso_remove_data_path(uint16_t conn_handle, uint8_t data_path_dir); + +UINT8 btsnd_hcic_ble_iso_read_tx_sync(uint16_t iso_hdl); + +UINT8 btsnd_hcic_ble_iso_read_iso_link_quality(uint16_t iso_hdl); + +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#define HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_PARAMS 5 +#define HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_ENABLE 2 +#define HCIC_PARAM_SIZE_SET_CONNLESS_IQ_SAMPLING_ENABLE 6 +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define HCIC_PARAM_SIZE_SET_CONN_CTE_RECEIVE_PARAMS 5 +#define HCIC_PARAM_SIZE_SET_CONN_CTE_TRANS_PARAMS 4 +#define HCIC_PARAM_SIZE_CONN_CTE_REQ_ENABLE 7 +#define HCIC_PARAM_SIZE_CONN_CTE_RSP_ENABLE 3 +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define HCIC_PARAM_SIZE_READ_ANT_INFO 0 +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +UINT8 btsnd_hcic_ble_set_connless_cte_trans_params(uint8_t adv_hdl, uint8_t cte_len, uint8_t cte_type, + uint8_t cte_cnt, uint8_t switching_pattern_len, uint8_t *antenna_ids); +UINT8 btsnd_hcic_ble_set_connless_cte_enable(uint8_t adv_hdl, uint8_t cte_en); +UINT8 btsnd_hcic_ble_set_connless_iq_sampling_enable(uint16_t sync_hdl, uint8_t sampling_en, uint8_t slot_dur, + uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *antenna_ids); +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +UINT8 btsnd_hcic_ble_set_conn_cte_receive_params(uint16_t conn_hdl, uint8_t sampling_en, uint8_t slot_dur, + uint8_t switching_pattern_len, uint8_t *antenna_ids); +UINT8 btsnd_hcic_ble_set_conn_cte_trans_params(uint16_t conn_hdl, uint8_t cte_type, uint8_t switching_pattern_len, uint8_t *antenna_ids); +UINT8 btsnd_hcic_ble_conn_cte_req_enable(uint16_t conn_hdl, uint8_t enable, uint16_t cte_req_int, uint8_t req_cte_len, uint8_t req_cte_type); +UINT8 btsnd_hcic_ble_conn_cte_rsp_enable(uint16_t conn_hdl, uint8_t enable); +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +UINT8 btsnd_hcic_ble_read_antenna_info(void); +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + +#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) +#define HCIC_PARAM_SIZE_ENH_READ_TRANS_PWR_LEVEL 3 +#define HCIC_PARAM_SIZE_READ_REMOTE_TRANS_PWR_LEVEL 3 +#define HCIC_PARAM_SIZE_SET_PATH_LOSS_REPORTING_PARAMS 8 +#define HCIC_PARAM_SIZE_SET_PATH_LOSS_REPORTING_ENABLE 3 +#define HCIC_PARAM_SIZE_SET_TRANS_PWR_REPORTING_ENABLE 4 + +UINT8 btsnd_hcic_ble_enh_read_trans_power_level(uint16_t conn_handle, uint8_t phy); +UINT8 btsnd_hcic_ble_read_remote_trans_power_level(uint16_t conn_handle, uint8_t phy); +UINT8 btsnd_hcic_ble_set_path_loss_rpt_params(uint16_t conn_handle, uint8_t high_threshold, uint8_t high_hysteresis, + uint8_t low_threshold, uint8_t low_hysteresis, uint16_t min_time_spent); +UINT8 btsnd_hcic_ble_set_path_loss_rpt_enable(uint16_t conn_handle, uint8_t enable); +UINT8 btsnd_hcic_ble_set_trans_pwr_rpt_enable(uint16_t conn_handle, uint8_t local_enable, uint8_t remote_enable); +#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) + +#if (BLE_FEAT_CONN_SUBRATING == TRUE) +#define HCIC_PARAM_SIZE_SET_DEFAULT_SUBRATE_PARAMS_LEN 10 +#define HCIC_PARAM_SIZE_SUBRATE_REQ_LENGTH_PARAMS_LEN 12 +UINT8 btsnd_hcic_ble_set_default_subrate(UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout); + +UINT8 btsnd_hcic_ble_subrate_request(UINT16 conn_handle, UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout); +#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) +#define HCIC_PARAM_SIZE_SET_HOST_FEATURE_PARAMS 2 +#define HCIC_PARAM_SIZE_SET_HOST_FEATURE_PARAMS_V2 3 +UINT8 btsnd_hcic_ble_set_host_feature(uint16_t bit_num, uint8_t bit_val); +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + #endif diff --git a/lib/bt/host/bluedroid/stack/include/stack/obex_api.h b/lib/bt/host/bluedroid/stack/include/stack/obex_api.h new file mode 100644 index 00000000..d22cd33c --- /dev/null +++ b/lib/bt/host/bluedroid/stack/include/stack/obex_api.h @@ -0,0 +1,271 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "common/bt_target.h" + +#if (OBEX_INCLUDED == TRUE) + +/* API function return value result codes. */ +#define OBEX_SUCCESS 0 /* Operation successful */ +#define OBEX_FAILURE 1 /* Operation failed */ +#define OBEX_NO_RESOURCES 3 /* Not enough resources */ +#define OBEX_BAD_HANDLE 4 /* Bad handle */ +#define OBEX_INVALID_PARAM 5 /* Invalid parameter */ +#define OBEX_NOT_OPEN 6 /* Connection not open */ +#define OBEX_PACKET_TOO_LARGE 7 /* Packet size large than MTU */ +#define OBEX_ERROR_TL 8 /* Operation failed in transport layer */ + +/* +* OBEX profile definitions +*/ +#define OBEX_OPCODE_CONNECT 0x80 +#define OBEX_OPCODE_DISCONNECT 0x81 +#define OBEX_OPCODE_PUT 0x02 +#define OBEX_OPCODE_PUT_FINAL 0x82 +#define OBEX_OPCODE_GET 0x03 +#define OBEX_OPCODE_GET_FINAL 0x83 +#define OBEX_OPCODE_SETPATH 0x85 +#define OBEX_OPCODE_ACTION 0x06 +#define OBEX_OPCODE_SESSION 0x87 +#define OBEX_OPCODE_ABORT 0xFF + +#define OBEX_RESPONSE_CODE_CONTINUE 0x10 +#define OBEX_RESPONSE_CODE_OK 0x20 +#define OBEX_RESPONSE_CODE_CREATED 0x21 +#define OBEX_RESPONSE_CODE_ACCEPTED 0x22 +#define OBEX_RESPONSE_CODE_NON_AUTHORITATIVE_INFO 0x23 +#define OBEX_RESPONSE_CODE_NO_CONTENT 0x24 +#define OBEX_RESPONSE_CODE_RESET_CONTENT 0x25 +#define OBEX_RESPONSE_CODE_PARTIAL_CONTENT 0x26 +#define OBEX_RESPONSE_CODE_MULTIPLE_CHOICES 0x30 +#define OBEX_RESPONSE_CODE_MOVED_PERMANENTLY 0x31 +#define OBEX_RESPONSE_CODE_MOVED_TEMPORARILY 0x31 +#define OBEX_RESPONSE_CODE_SEE_OHTER 0x33 +#define OBEX_RESPONSE_CODE_NOT_MODIFIED 0x34 +#define OBEX_RESPONSE_CODE_USE_PROXY 0x35 +#define OBEX_RESPONSE_CODE_BAD_REQUEST 0x40 +#define OBEX_RESPONSE_CODE_UNAUTHORIZED 0x41 +#define OBEX_RESPONSE_CODE_PAYMENT_REQUIRED 0x42 +#define OBEX_RESPONSE_CODE_FORBIDDEN 0x43 +#define OBEX_RESPONSE_CODE_NOT_FOUND 0x44 +#define OBEX_RESPONSE_CODE_METHOD_NOT_ALLOWED 0x45 +#define OBEX_RESPONSE_CODE_NOT_ACCEPTABLE 0x46 +#define OBEX_RESPONSE_CODE_PROXY_AUTHENTICATION_REQUIRED 0x47 +#define OBEX_RESPONSE_CODE_REQUEST_TIME_OUT 0x48 +#define OBEX_RESPONSE_CODE_CONFLICT 0x49 +#define OBEX_RESPONSE_CODE_GONE 0x4A +#define OBEX_RESPONSE_CODE_LENGTH_REQUIRED 0x4B +#define OBEX_RESPONSE_CODE_PRECONDITION_FAILED 0x4C +#define OBEX_RESPONSE_CODE_REQUESTED_ENTITY_TOO_LARGE 0x4D +#define OBEX_RESPONSE_CODE_REQUEST_URL_TOO_LARGE 0x4E +#define OBEX_RESPONSE_CODE_UNSUPPORTED_MEDIA_TYPE 0x4F +#define OBEX_RESPONSE_CODE_INTERNAL_SERVER_ERROR 0x50 +#define OBEX_RESPONSE_CODE_NOT_IMPLEMENTED 0x51 +#define OBEX_RESPONSE_CODE_BAD_GATEWAY 0x52 +#define OBEX_RESPONSE_CODE_SERVICE_UNAVAILABLE 0x53 +#define OBEX_RESPONSE_CODE_GATEWAY_TIMEOUT 0x54 +#define OBEX_RESPONSE_CODE_HTTP_VERSION_NOT_SUPPORTED 0x55 +#define OBEX_RESPONSE_CODE_DATABASE_FULL 0x60 +#define OBEX_RESPONSE_CODE_DATABASE_LOCKED 0x61 + +#define OBEX_FINAL_BIT_MASK 0x80 + +#define OBEX_CONNECT_FLAGS 0x01 /* support multiple link */ +#define OBEX_SETPATH_FLAGS 0x03 /* default flags */ + +#define OBEX_PACKET_LENGTH_MAX (0xFFFF-1) +#define OBEX_PACKET_LENGTH_MIN 255 + +#define OBEX_VERSION_NUMBER 0x15 + +/* Header identifiers */ +#define OBEX_HEADER_ID_U2B_MASK 0xC0 /* upper 2 bits of header ID are user to indicate the header encoding */ +#define OBEX_HEADER_ID_U2B_TYPE1 0x00 /* null terminated Unicode text, length prefixed with 2 byte unsigned integer */ +#define OBEX_HEADER_ID_U2B_TYPE2 0x40 /* byte sequence, length prefixed with 2 byte unsigned integer */ +#define OBEX_HEADER_ID_U2B_TYPE3 0x80 /* 1 byte quantity */ +#define OBEX_HEADER_ID_U2B_TYPE4 0xC0 /* 4 byte quantity - transmitted in network byte order (high byte first) */ + +#define OBEX_HEADER_ID_COUNT 0xC0 +#define OBEX_HEADER_ID_NAME 0x01 +#define OBEX_HEADER_ID_TYPE 0x42 +#define OBEX_HEADER_ID_LENGTH 0xC3 +#define OBEX_HEADER_ID_TIME_ISO8601 0x44 +#define OBEX_HEADER_ID_TIME_4BYTE 0xC4 +#define OBEX_HEADER_ID_DESCRIPTION 0x05 +#define OBEX_HEADER_ID_TARGET 0x46 +#define OBEX_HEADER_ID_HTTP 0x47 +#define OBEX_HEADER_ID_BODY 0x48 +#define OBEX_HEADER_ID_END_OF_BODY 0x49 +#define OBEX_HEADER_ID_WHO 0x4A +#define OBEX_HEADER_ID_CONNECTION_ID 0xCB +#define OBEX_HEADER_ID_APP_PARAM 0x4C +#define OBEX_HEADER_ID_AUTH_CHALLENGE 0x4D +#define OBEX_HEADER_ID_AUTH_RESPONSE 0x4E +#define OBEX_HEADER_ID_CREATOR_ID 0xCF +#define OBEX_HEADER_ID_WAN_UUID 0x50 +#define OBEX_HEADER_ID_OBJECT_CLASS 0x51 +#define OBEX_HEADER_ID_SESSION_PARAM 0x52 +#define OBEX_HEADER_ID_SESSION_SEQ_NUM 0x93 +#define OBEX_HEADER_ID_ACTION_ID 0x94 +#define OBEX_HEADER_ID_DESTNAME 0x15 +#define OBEX_HEADER_ID_PERMISSIONS 0xD6 +#define OBEX_HEADER_ID_SRM 0x97 +#define OBEX_HEADER_ID_SRM_PARAM 0x98 +/* Reserved for future use: 0x19 to 0x2F */ +/* User defined: 0x30 to 0x3F */ + +#define OBEX_ACTION_ID_COPY 0x00 +#define OBEX_ACTION_ID_MOVE_RENAME 0x01 +#define OBEX_ACTION_ID_SET_PERMISSIONS 0x02 + +#define OBEX_SRM_DISABLE 0x00 +#define OBEX_SRM_ENABLE 0x01 +#define OBEX_SRM_SUPPORT 0x02 + +#define OBEX_SRMP_ADD_PKT 0x00 +#define OBEX_SRMP_WAIT 0x01 +#define OBEX_SRMP_ADD_PKT_WAIT 0x02 + +#define OBEX_MIN_PACKET_SIZE 3 + +enum { + /* client event */ + OBEX_CONNECT_EVT, /* connection opened */ + OBEX_DISCONNECT_EVT, /* connection disconnected */ + /* server event */ + OBEX_CONN_INCOME_EVT, /* an incoming connection */ + /* client or server event */ + OBEX_MTU_CHANGE_EVT, /* connection mtu changed */ + OBEX_CONGEST_EVT, /* connection congested */ + OBEX_UNCONGEST_EVT, /* connection is not congested */ + OBEX_DATA_EVT /* data received */ +}; + +enum { + OBEX_OVER_L2CAP = 0, + OBEX_OVER_RFCOMM, + OBEX_NUM_TL +}; + +typedef struct +{ + UINT16 psm; /* l2cap psm */ + UINT16 sec_mask; /* security mask */ + UINT16 pref_mtu; /* preferred mtu, limited by L2CAP_MTU_SIZE */ + BD_ADDR addr; /* peer bluetooth device address */ +} tOBEX_OVER_L2CAP_SVR; + +typedef struct +{ + UINT8 scn; /* service channel number */ + UINT16 sec_mask; /* security mask */ + UINT16 pref_mtu; /* preferred mtu, limited by rfcomm mtu */ + BD_ADDR addr; /* peer bluetooth device address */ +} tOBEX_OVER_RFCOMM_SVR; + +typedef struct +{ + UINT8 tl; /* transport type, OBEX_OVER_L2CAP or OBEX_OVER_RFCOMM */ + union + { + tOBEX_OVER_L2CAP_SVR l2cap; + tOBEX_OVER_RFCOMM_SVR rfcomm; + }; +} tOBEX_SVR_INFO; + +typedef struct { + UINT8 opcode; + UINT8 response_code; + /* Connect */ + UINT8 obex_version_number; + UINT16 max_packet_length; + /* Connect or SetPath */ + UINT8 flags; + /* Internal use */ + UINT16 next_header_pos; +} tOBEX_PARSE_INFO; + +typedef union { + struct { + UINT16 peer_mtu; + UINT16 our_mtu; + } connect; + + struct { + UINT16 svr_handle; + UINT16 peer_mtu; + UINT16 our_mtu; + } conn_income; + + struct { + UINT16 peer_mtu; + UINT16 our_mtu; + } mtu_change; + + struct { + BT_HDR *pkt; + } data; +} tOBEX_MSG; + +typedef void (tOBEX_MSG_CBACK)(UINT16 handle, UINT8 event, tOBEX_MSG *msg); + +/******************************************************************************* +* The following APIs are called by bluetooth stack automatically +*******************************************************************************/ + +extern UINT16 OBEX_Init(void); + +extern void OBEX_Deinit(void); + +/******************************************************************************* +* The following APIs must be executed in btu task +*******************************************************************************/ + +extern UINT16 OBEX_CreateConn(tOBEX_SVR_INFO *server, tOBEX_MSG_CBACK callback, UINT16 *out_handle); + +extern UINT16 OBEX_RemoveConn(UINT16 handle); + +extern UINT16 OBEX_SendPacket(UINT16 handle, BT_HDR *pkt); + +extern UINT16 OBEX_RegisterServer(tOBEX_SVR_INFO *server, tOBEX_MSG_CBACK callback, UINT16 *out_svr_handle); + +extern UINT16 OBEX_DeregisterServer(UINT16 svr_handle); + +/******************************************************************************* +* The following APIs are util function, can be executed in btu or btc task +*******************************************************************************/ + +extern UINT16 OBEX_BuildRequest(tOBEX_PARSE_INFO *info, UINT16 buff_size, BT_HDR **out_pkt); + +extern UINT16 OBEX_BuildResponse(tOBEX_PARSE_INFO *info, UINT16 buff_size, BT_HDR **out_pkt); + +extern UINT16 OBEX_AppendHeader(BT_HDR *pkt, const UINT8 *header); + +extern UINT16 OBEX_AppendHeaderRaw(BT_HDR *pkt, UINT8 header_id, const UINT8 *data, UINT16 data_len); + +extern UINT16 OBEX_AppendHeaderSRM(BT_HDR *pkt, UINT8 value); + +extern UINT16 OBEX_AppendHeaderSRMP(BT_HDR *pkt, UINT8 value); + +extern UINT16 OBEX_GetPacketFreeSpace(BT_HDR *pkt); + +extern UINT16 OBEX_GetPacketLength(BT_HDR *pkt); + +extern UINT16 OBEX_ParseRequest(BT_HDR *pkt, tOBEX_PARSE_INFO *info); + +extern UINT16 OBEX_ParseResponse(BT_HDR *pkt, UINT8 opcode, tOBEX_PARSE_INFO *info); + +extern BOOLEAN OBEX_CheckFinalBit(BT_HDR *pkt); + +extern BOOLEAN OBEX_CheckContinueResponse(BT_HDR *pkt); + +extern UINT8 *OBEX_GetNextHeader(BT_HDR *pkt, tOBEX_PARSE_INFO *info); + +extern UINT16 OBEX_GetHeaderLength(UINT8 *header); + +#endif /* #if (OBEX_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/include/stack/sdp_api.h b/lib/bt/host/bluedroid/stack/include/stack/sdp_api.h index 70da3182..7075e8bb 100644 --- a/lib/bt/host/bluedroid/stack/include/stack/sdp_api.h +++ b/lib/bt/host/bluedroid/stack/include/stack/sdp_api.h @@ -365,6 +365,20 @@ extern BOOLEAN SDP_FindProtocolListElemInRec (tSDP_DISC_REC *p_rec, UINT16 layer_uuid, tSDP_PROTOCOL_ELEM *p_elem); +/******************************************************************************* +** +** Function SDP_FindProtocolListElem +** +** Description This function looks at the protocol list for a specific protocol +** list element. +** +** Returns TRUE if found, FALSE if not +** If found, the passed protocol list element is filled in. +** +*******************************************************************************/ +extern BOOLEAN SDP_FindProtocolListElem (tSDP_DISC_ATTR *p_protocol_list, + UINT16 layer_uuid, + tSDP_PROTOCOL_ELEM *p_elem); /******************************************************************************* ** @@ -409,7 +423,7 @@ extern BOOLEAN SDP_FindProfileVersionInRec (tSDP_DISC_REC *p_rec, ** ** Description This function is called to create a record in the database. ** This would be through the SDP database maintenance API. The -** record is created empty, teh application should then call +** record is created empty, the application should then call ** "add_attribute" to add the record's attributes. ** ** Returns Record handle if OK, else 0. diff --git a/lib/bt/host/bluedroid/stack/l2cap/include/l2c_int.h b/lib/bt/host/bluedroid/stack/l2cap/include/l2c_int.h index 045fb10d..88eac86b 100644 --- a/lib/bt/host/bluedroid/stack/l2cap/include/l2c_int.h +++ b/lib/bt/host/bluedroid/stack/l2cap/include/l2c_int.h @@ -65,7 +65,7 @@ #define L2CAP_WAIT_UNPARK_TOUT 2 /* 2 seconds */ #define L2CAP_LINK_INFO_RESP_TOUT 2 /* 2 seconds */ #define L2CAP_UPDATE_CONN_PARAM_TOUT 6 /* 6 seconds */ -#define L2CAP_BLE_LINK_CONNECT_TOUT BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT // configed in menuconfig +#define L2CAP_BLE_LINK_CONNECT_TOUT BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT // configured in menuconfig #define L2CAP_BLE_CONN_PARAM_UPD_TOUT 30 /* 30 seconds */ /* quick timer uses millisecond unit */ @@ -80,10 +80,10 @@ ** the Bluetooth specification. */ typedef enum { - CST_CLOSED, /* Channel is in clodes state */ + CST_CLOSED, /* Channel is in closed state */ CST_ORIG_W4_SEC_COMP, /* Originator waits security clearence */ CST_TERM_W4_SEC_COMP, /* Acceptor waits security clearence */ - CST_W4_L2CAP_CONNECT_RSP, /* Waiting for peer conenct response */ + CST_W4_L2CAP_CONNECT_RSP, /* Waiting for peer connect response */ CST_W4_L2CA_CONNECT_RSP, /* Waiting for upper layer connect rsp */ CST_CONFIG, /* Negotiating configuration */ CST_OPEN, /* Data transfer state */ @@ -208,8 +208,8 @@ typedef struct { UINT32 controller_idle; /* # of times less than 2 packets in controller */ /* when the xmit window was closed */ UINT32 pkts_retransmitted; /* # of packets that were retransmitted */ - UINT32 retrans_touts; /* # of retransmission timouts */ - UINT32 xmit_ack_touts; /* # of xmit ack timouts */ + UINT32 retrans_touts; /* # of retransmission timeouts */ + UINT32 xmit_ack_touts; /* # of xmit ack timeouts */ #define L2CAP_ERTM_STATS_NUM_AVG 10 #define L2CAP_ERTM_STATS_AVG_NUM_SAMPLES 100 @@ -386,7 +386,7 @@ typedef struct t_l2c_linkcb { tL2C_CCB *p_pending_ccb; /* ccb of waiting channel during link disconnect */ TIMER_LIST_ENT info_timer_entry; /* Timer entry for info resp timeout evt */ - TIMER_LIST_ENT upda_con_timer; /* Timer entry for update connection parametr */ + TIMER_LIST_ENT upda_con_timer; /* Timer entry for update connection parameter */ BD_ADDR remote_bd_addr; /* The BD address of the remote */ UINT8 link_role; /* Master or slave */ @@ -599,7 +599,7 @@ extern BOOLEAN l2cu_start_post_bond_timer (UINT16 handle); extern void l2cu_release_lcb (tL2C_LCB *p_lcb); extern tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport); extern tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle); -extern uint8_t l2cu_plcb_active_count(void); +extern uint8_t l2cu_ble_plcb_active_count(void); extern void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding); extern UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb); diff --git a/lib/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/lib/bt/host/bluedroid/stack/l2cap/l2c_ble.c index 956a4b7f..3ce25ab9 100644 --- a/lib/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/lib/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -111,7 +111,7 @@ BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda) p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE); /* Do not remove lcb if an LE link is already up as a peripheral */ if (p_lcb != NULL && - !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_ACL_IS_CONNECTED(rem_bda))) { + !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_LE_ACL_IS_CONNECTED(rem_bda))) { p_lcb->disc_reason = L2CAP_CONN_CANCEL; l2cu_release_lcb (p_lcb); } @@ -242,7 +242,7 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable) return (FALSE); } bool is_disable = (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE); - if(l2cu_plcb_active_count() >1 && !(enable && is_disable)) { + if(l2cu_ble_plcb_active_count() >1 && !(enable && is_disable)) { return FALSE; } @@ -376,6 +376,7 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, p_lcb->waiting_update_conn_latency = p_lcb->current_used_conn_latency = conn_latency; p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM; p_lcb->updating_param_flag = false; + p_lcb->ble_addr_type = type; /* If there are any preferred connection parameters, set them now */ if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) && @@ -476,6 +477,7 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ p_lcb->waiting_update_conn_latency = p_lcb->current_used_conn_latency = conn_latency; p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM; p_lcb->updating_param_flag = false; + p_lcb->ble_addr_type = type; /* Tell BTM Acl management about the link */ p_dev_rec = btm_find_or_alloc_dev (bda); @@ -900,6 +902,12 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) scan_int = (p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int; scan_win = (p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win; + if (p_dev_rec->conn_params.scan_interval && p_dev_rec->conn_params.scan_interval != BTM_BLE_CONN_PARAM_UNDEF) { + scan_int = p_dev_rec->conn_params.scan_interval; + } + if (p_dev_rec->conn_params.scan_window && p_dev_rec->conn_params.scan_window != BTM_BLE_CONN_PARAM_UNDEF) { + scan_win = p_dev_rec->conn_params.scan_window; + } peer_addr_type = p_lcb->ble_addr_type; memcpy(peer_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN); @@ -964,22 +972,24 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) } if (!p_lcb->is_aux) { - if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int */ - scan_win, /* UINT16 scan_win */ - FALSE, /* UINT8 white_list */ - peer_addr_type, /* UINT8 addr_type_peer */ - peer_addr, /* BD_ADDR bda_peer */ - own_addr_type, /* UINT8 addr_type_own */ + if (!btsnd_hcic_ble_create_ll_conn (scan_int, /* UINT16 scan_int */ + scan_win, /* UINT16 scan_win */ + FALSE, /* UINT8 white_list */ + peer_addr_type, /* UINT8 addr_type_peer */ + peer_addr, /* BD_ADDR bda_peer */ + own_addr_type, /* UINT8 addr_type_own */ (UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? - p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), /* UINT16 conn_int_min */ + p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), /* UINT16 conn_int_min */ (UINT16) ((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? - p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), /* UINT16 conn_int_max */ + p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), /* UINT16 conn_int_max */ (UINT16) ((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? - p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), /* UINT16 conn_latency */ + p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), /* UINT16 conn_latency */ (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? - p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), /* conn_timeout */ - BLE_CE_LEN_MIN, /* UINT16 min_len */ - BLE_CE_LEN_MIN)) { /* UINT16 max_len */ + p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), /* UINT16 conn_timeout */ + (UINT16) ((p_dev_rec->conn_params.min_ce_len != BTM_BLE_CONN_PARAM_UNDEF) ? + p_dev_rec->conn_params.min_ce_len : BLE_CE_LEN_MIN), /* UINT16 min_ce_len */ + (UINT16) ((p_dev_rec->conn_params.max_ce_len != BTM_BLE_CONN_PARAM_UNDEF) ? + p_dev_rec->conn_params.max_ce_len : BLE_CE_LEN_MIN) /* UINT16 max_ce_len */)) { l2cu_release_lcb (p_lcb); L2CAP_TRACE_ERROR("initiate direct connection fail, no resources"); return (FALSE); @@ -1063,11 +1073,11 @@ BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb) L2CAP_TRACE_WARNING ("L2CAP - LE - cannot start new connection at conn st: %d", conn_st); btm_ble_enqueue_direct_conn_req(p_lcb); - +#if (tGATT_BG_CONN_DEV == TRUE) if (conn_st == BLE_BG_CONN) { btm_ble_suspend_bg_conn(); } - +#endif // #if (tGATT_BG_CONN_DEV == TRUE) rt = TRUE; } return rt; diff --git a/lib/bt/host/bluedroid/stack/l2cap/l2c_link.c b/lib/bt/host/bluedroid/stack/l2cap/l2c_link.c index c3118fdd..1af7e8b3 100644 --- a/lib/bt/host/bluedroid/stack/l2cap/l2c_link.c +++ b/lib/bt/host/bluedroid/stack/l2cap/l2c_link.c @@ -368,9 +368,11 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) BTM_Recovery_Pre_State(); } #if (BLE_50_FEATURE_SUPPORT == TRUE) + #if (BLE_50_EXTEND_ADV_EN == TRUE) if(btm_ble_inter_get() && reason == HCI_ERR_CONN_FAILED_ESTABLISHMENT) { BTM_BleStartExtAdvRestart(handle); } + #endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #endif ///BLE_INCLUDED == TRUE status = FALSE; @@ -478,24 +480,36 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) if (l2cu_create_conn(p_lcb, BT_TRANSPORT_LE)) { btm_acl_removed (p_lcb->remote_bd_addr, BT_TRANSPORT_LE); lcb_is_free = FALSE; /* still using this lcb */ + } else { + L2CAP_TRACE_ERROR("master retry connect failed"); } } #endif // (GATTC_CONNECT_RETRY_EN == TRUE) #if (BLE_50_FEATURE_SUPPORT == TRUE) + #if (BLE_50_EXTEND_ADV_EN == TRUE) if(btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE) { p_lcb->retry_create_con ++; L2CAP_TRACE_DEBUG("slave restart extend adv, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason); - BTM_BleStartExtAdvRestart(handle); + tBTM_STATUS start_adv_status = BTM_BleStartExtAdvRestart(handle); + if (start_adv_status != BTM_SUCCESS) { + L2CAP_TRACE_ERROR("slave restart extend adv failed (err 0x%x)", start_adv_status); + } } + #endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_42_FEATURE_SUPPORT == TRUE) + #if (BLE_42_ADV_EN == TRUE) if(!btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE) { p_lcb->retry_create_con ++; L2CAP_TRACE_DEBUG("slave resatrt adv, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason); - btm_ble_start_adv(); + tBTM_STATUS start_adv_status = btm_ble_start_adv(); + if (start_adv_status != BTM_SUCCESS) { + L2CAP_TRACE_ERROR("slave resatrt adv failed (err 0x%x)", start_adv_status); + } } + #endif // #if (BLE_42_ADV_EN == TRUE) #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) } @@ -1078,7 +1092,9 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf) p_lcb_cur = list_node(p_node); if (p_lcb_cur == p_lcb) { p_node = list_next(p_node); - p_lcb = list_node(p_node); + if (p_node) { + p_lcb = list_node(p_node); + } break; } } diff --git a/lib/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/lib/bt/host/bluedroid/stack/l2cap/l2c_utils.c index 992d4b68..e4bf8a08 100644 --- a/lib/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/lib/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -336,14 +336,14 @@ tL2C_LCB *l2cu_find_free_lcb (void) return (NULL); } -uint8_t l2cu_plcb_active_count(void) +uint8_t l2cu_ble_plcb_active_count(void) { list_node_t *p_node = NULL; tL2C_LCB *p_lcb = NULL; uint8_t active_count = 0; for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { p_lcb = list_node(p_node); - if (p_lcb && p_lcb->in_use) { + if (p_lcb && p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) { active_count ++; } } @@ -615,7 +615,7 @@ void l2cu_send_peer_connect_rsp (tL2C_CCB *p_ccb, UINT16 result, UINT16 status) ** ** Description Build and send an L2CAP "connection response neg" message ** to the peer. This function is called when there is no peer -** CCB (non-existant PSM or no resources). +** CCB (non-existent PSM or no resources). ** ** Returns void ** @@ -1737,7 +1737,7 @@ void l2cu_release_ccb (tL2C_CCB *p_ccb) ) { l2cu_dequeue_ccb (p_ccb); - /* Delink the CCB from the LCB */ + /* Unlink the CCB from the LCB */ p_ccb->p_lcb = NULL; } @@ -1960,7 +1960,7 @@ tL2C_RCB *l2cu_find_ble_rcb_by_psm (UINT16 psm) ** ** Returns UINT8 - L2CAP_PEER_CFG_OK if passed to upper layer, ** L2CAP_PEER_CFG_UNACCEPTABLE if automatically responded to -** because parameters are unnacceptable from a specification +** because parameters are unacceptable from a specification ** point of view. ** L2CAP_PEER_CFG_DISCONNECT if no compatible channel modes ** between the two devices, and shall be closed. @@ -2558,7 +2558,7 @@ BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_af ** ** Function l2cu_set_non_flushable_pbf ** -** Description set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts +** Description set L2CAP_PKT_START_NON_FLUSHABLE if controller supports ** ** Returns void ** @@ -3328,7 +3328,7 @@ static tL2C_CCB *l2cu_get_next_channel_in_rr(tL2C_LCB *p_lcb) for ( i = 0; (i < L2CAP_NUM_CHNL_PRIORITY) && (!p_serve_ccb); i++ ) { /* scan all channel within serving priority group until finding a channel to serve */ for ( j = 0; (j < p_lcb->rr_serv[p_lcb->rr_pri].num_ccb) && (!p_serve_ccb); j++) { - /* scaning from next serving channel */ + /* scanning from next serving channel */ p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb; if (!p_ccb) { diff --git a/lib/bt/host/bluedroid/stack/obex/include/obex_int.h b/lib/bt/host/bluedroid/stack/obex/include/obex_int.h new file mode 100644 index 00000000..28c4eab4 --- /dev/null +++ b/lib/bt/host/bluedroid/stack/obex/include/obex_int.h @@ -0,0 +1,76 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "common/bt_target.h" + +#include "stack/obex_api.h" +#include "obex_tl.h" +#include "obex_tl_l2cap.h" + +#if (OBEX_INCLUDED == TRUE) + +#if (RFCOMM_INCLUDED == TRUE) +#define OBEX_BT_HDR_MIN_OFFSET OBEX_TL_RFCOMM_BT_HDR_MIN_OFFSET /* should set to max value of all transport layer */ +#define OBEX_BT_HDR_RESERVE_LEN OBEX_TL_RFCOMM_BT_HDR_RESERVE_LEN /* should set to max value of all transport layer */ +#else +#define OBEX_BT_HDR_MIN_OFFSET OBEX_TL_L2CAP_BT_HDR_OFFSET_MIN +#define OBEX_BT_HDR_RESERVE_LEN OBEX_TL_L2CAP_BT_HDR_RESERVE_LEN +#endif + +#define OBEX_ROLE_CLIENT 0x01 +#define OBEX_ROLE_SERVER 0x02 + +/* OBEX connection state */ +#define OBEX_STATE_IDLE 0 /* No connection */ +#define OBEX_STATE_OPENING 1 /* Starting to open a connection */ +#define OBEX_STATE_OPENED 2 /* Connection opened */ + +/* OBEX Connection Control block */ +typedef struct { + tOBEX_MSG_CBACK *callback; /* Connection msg callback function */ + UINT16 tl_hdl; /* Transport layer non-zeros connection handle*/ + UINT16 tl_peer_mtu; /* Transport layer peer mtu */ + UINT16 tl_our_mtu; /* Transport layer our mtu */ + UINT8 tl_cong; /* 1 if transport layer congestion, otherwise 0 */ + UINT8 tl; /* OBEX_OVER_L2CAP or OBEX_OVER_RFCOMM */ + UINT8 allocated; /* 0, not allocated. index+1, otherwise. equal to api handle */ + UINT8 state; /* This OBEX connection state */ + UINT8 role; /* This OBEX connection role */ +} tOBEX_CCB; + +/* OBEX Server Control block */ +typedef struct { + tOBEX_MSG_CBACK *callback; /* Connection msg callback function */ + UINT16 tl_hdl; /* Transport layer non-zeros server handle*/ + UINT8 tl; /* OBEX_OVER_L2CAP or OBEX_OVER_RFCOMM */ + UINT8 allocated; /* 0, not allocated. index+1, otherwise. */ +} tOBEX_SCB; + +/* OBEX Control block */ +typedef struct { + tOBEX_CCB ccb[OBEX_MAX_CONNECTION]; /* connection control blocks */ + tOBEX_SCB scb[OBEX_MAX_SERVER]; /* server control blocks */ + tOBEX_TL_OPS *tl_ops[OBEX_NUM_TL]; /* transport operation function pointer */ + UINT8 trace_level; /* trace level */ +} tOBEX_CB; + +#if OBEX_DYNAMIC_MEMORY == FALSE +extern tOBEX_CB obex_cb; +#else +extern tOBEX_CB *obex_cb_ptr; +#define obex_cb (*obex_cb_ptr) +#endif + +void obex_tl_l2cap_callback(tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg); +void obex_tl_rfcomm_callback(tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg); +tOBEX_CCB *obex_allocate_ccb(void); +tOBEX_SCB *obex_allocate_scb(void); +void obex_free_ccb(tOBEX_CCB *p_ccb); +void obex_free_scb(tOBEX_SCB *p_scb); + +#endif /* #if (OBEX_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/obex/include/obex_tl.h b/lib/bt/host/bluedroid/stack/obex/include/obex_tl.h new file mode 100644 index 00000000..9211b9b0 --- /dev/null +++ b/lib/bt/host/bluedroid/stack/obex/include/obex_tl.h @@ -0,0 +1,97 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "common/bt_target.h" + +#if (OBEX_INCLUDED == TRUE) + +/* Return code of obex_tl_send_data */ +#define OBEX_TL_FAILED FALSE +#define OBEX_TL_SUCCESS TRUE +#define OBEX_TL_CONGESTED 2 + +typedef enum { + OBEX_TL_CONN_OPEN_EVT, + OBEX_TL_CONN_INCOME_EVT, + OBEX_TL_DIS_CONN_EVT, + OBEX_TL_CONGEST_EVT, + OBEX_TL_UNCONGEST_EVT, + OBEX_TL_MTU_CHANGE_EVT, + OBEX_TL_DATA_EVT +} tOBEX_TL_EVT; + +typedef union { + /* general struct, used to retrieve handle */ + struct { + UINT16 hdl; + } any; + + /* struct for OBEX_TL_CONN_OPEN_EVT */ + struct { + UINT16 hdl; + UINT16 peer_mtu; + UINT16 our_mtu; + } conn_open; + + /* struct for OBEX_TL_CONN_INCOME_EVT */ + struct { + UINT16 hdl; + UINT16 peer_mtu; + UINT16 our_mtu; + UINT16 svr_hdl; + } conn_income; + + /* struct for OBEX_TL_MTU_CHANGE_EVT */ + struct { + UINT16 hdl; + UINT16 peer_mtu; + UINT16 our_mtu; + } mtu_chg; + + /* struct for OBEX_TL_DATA_EVT */ + struct { + UINT16 hdl; + BT_HDR *p_buf; + } data; +} tOBEX_TL_MSG; + +typedef struct +{ + UINT16 psm; /* l2cap psm */ + UINT16 sec_mask; /* security mask */ + UINT16 pref_mtu; /* preferred mtu, limited by L2CAP_MTU_SIZE */ + BD_ADDR addr; /* peer bluetooth device address */ +} tOBEX_TL_L2CAP_SVR; + +typedef struct +{ + UINT8 scn; /* service channel number */ + UINT16 sec_mask; /* security mask */ + UINT16 pref_mtu; /* preferred mtu, limited by rfcomm mtu */ + BD_ADDR addr; /* peer bluetooth device address */ +} tOBEX_TL_RFCOMM_SVR; + +typedef union +{ + tOBEX_TL_L2CAP_SVR l2cap; + tOBEX_TL_RFCOMM_SVR rfcomm; +} tOBEX_TL_SVR_INFO; + +typedef void (tOBEX_TL_CBACK)(tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg); + +typedef struct { + void (*init)(tOBEX_TL_CBACK *callback); + void (*deinit)(void); + UINT16 (*connect)(tOBEX_TL_SVR_INFO *server); + void (*disconnect)(UINT16 tl_hdl); + UINT16 (*send)(UINT16 tl_hdl, BT_HDR *p_buf); + UINT16 (*bind)(tOBEX_TL_SVR_INFO *server); + void (*unbind)(UINT16 tl_hdl); +} tOBEX_TL_OPS; + +#endif /* #if (OBEX_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/obex/include/obex_tl_l2cap.h b/lib/bt/host/bluedroid/stack/obex/include/obex_tl_l2cap.h new file mode 100644 index 00000000..32667766 --- /dev/null +++ b/lib/bt/host/bluedroid/stack/obex/include/obex_tl_l2cap.h @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "obex_tl.h" + +#if (OBEX_INCLUDED == TRUE) + +#define OBEX_TL_L2CAP_BT_HDR_MIN_OFFSET 13 /* equal to L2CAP_MIN_OFFSET */ +#define OBEX_TL_L2CAP_BT_HDR_RESERVE_LEN 0 /* not require any additional byte */ + +tOBEX_TL_OPS *obex_tl_l2cap_ops_get(void); + +#endif /* #if (OBEX_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/obex/include/obex_tl_rfcomm.h b/lib/bt/host/bluedroid/stack/obex/include/obex_tl_rfcomm.h new file mode 100644 index 00000000..61b9d295 --- /dev/null +++ b/lib/bt/host/bluedroid/stack/obex/include/obex_tl_rfcomm.h @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "obex_tl.h" + +#if (OBEX_INCLUDED == TRUE && RFCOMM_INCLUDED == TRUE) + +#define OBEX_TL_RFCOMM_BT_HDR_MIN_OFFSET 18 /* RFCOMM_MIN_OFFSET + L2CAP_MIN_OFFSET */ +#define OBEX_TL_RFCOMM_BT_HDR_RESERVE_LEN 1 /* reserve 1 byte for rfcomm fcs */ + +tOBEX_TL_OPS *obex_tl_rfcomm_ops_get(void); + +#endif /* #if (OBEX_INCLUDED == TRUE && RFCOMM_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/obex/obex_api.c b/lib/bt/host/bluedroid/stack/obex/obex_api.c new file mode 100644 index 00000000..99276a93 --- /dev/null +++ b/lib/bt/host/bluedroid/stack/obex/obex_api.c @@ -0,0 +1,776 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> + +#include "osi/osi.h" +#include "osi/allocator.h" +#include "common/bt_target.h" + +#include "stack/obex_api.h" +#include "obex_int.h" +#include "obex_tl.h" +#include "obex_tl_l2cap.h" +#include "obex_tl_rfcomm.h" + +#if (OBEX_INCLUDED == TRUE) + +static inline void obex_server_to_tl_server(tOBEX_SVR_INFO *server, tOBEX_TL_SVR_INFO *tl_server) +{ + if (server->tl == OBEX_OVER_L2CAP) { + tl_server->l2cap.psm = server->l2cap.psm; + tl_server->l2cap.sec_mask = server->l2cap.sec_mask; + tl_server->l2cap.pref_mtu = server->l2cap.pref_mtu; + bdcpy(tl_server->l2cap.addr, server->l2cap.addr); + } + else if (server->tl == OBEX_OVER_RFCOMM) { + tl_server->rfcomm.scn = server->rfcomm.scn; + tl_server->rfcomm.sec_mask = server->rfcomm.sec_mask; + tl_server->rfcomm.pref_mtu = server->rfcomm.pref_mtu; + bdcpy(tl_server->rfcomm.addr, server->rfcomm.addr); + } + else { + OBEX_TRACE_ERROR("Unsupported OBEX transport type\n"); + assert(0); + } +} + +static inline void obex_updata_packet_length(BT_HDR *p_buf, UINT16 len) +{ + UINT8 *p_pkt_len = (UINT8 *)(p_buf + 1) + p_buf->offset + 1; + UINT16_TO_BE_FIELD(p_pkt_len, len); +} + +/******************************************************************************* +** +** Function OBEX_Init +** +** Description Initialize OBEX Profile, must call before using any other +** OBEX APIs +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_Init(void) +{ +#if (OBEX_DYNAMIC_MEMORY) + if (!obex_cb_ptr) { + obex_cb_ptr = (tOBEX_CB *)osi_malloc(sizeof(tOBEX_CB)); + if (!obex_cb_ptr) { + return OBEX_NO_RESOURCES; + } + } +#endif /* #if (OBEX_DYNAMIC_MEMORY) */ + memset(&obex_cb, 0, sizeof(tOBEX_CB)); + obex_cb.tl_ops[OBEX_OVER_L2CAP] = obex_tl_l2cap_ops_get(); + if (obex_cb.tl_ops[OBEX_OVER_L2CAP]->init != NULL) { + obex_cb.tl_ops[OBEX_OVER_L2CAP]->init(obex_tl_l2cap_callback); + } +#if (RFCOMM_INCLUDED == TRUE) + obex_cb.tl_ops[OBEX_OVER_RFCOMM] = obex_tl_rfcomm_ops_get(); + if (obex_cb.tl_ops[OBEX_OVER_RFCOMM]->init != NULL) { + obex_cb.tl_ops[OBEX_OVER_RFCOMM]->init(obex_tl_rfcomm_callback); + } +#endif + obex_cb.trace_level = BT_TRACE_LEVEL_ERROR; + return OBEX_SUCCESS; +} + +/******************************************************************************* +** +** Function OBEX_Deinit +** +** Description Deinit OBEX profile, once deinit, can not use any other +** APIs until call OBEX_Init again +** +*******************************************************************************/ +void OBEX_Deinit(void) +{ + if (obex_cb.tl_ops[OBEX_OVER_L2CAP]->deinit != NULL) { + obex_cb.tl_ops[OBEX_OVER_L2CAP]->deinit(); + } +#if (RFCOMM_INCLUDED == TRUE) + if (obex_cb.tl_ops[OBEX_OVER_RFCOMM]->deinit != NULL) { + obex_cb.tl_ops[OBEX_OVER_RFCOMM]->deinit(); + } +#endif +#if (OBEX_DYNAMIC_MEMORY) + if (obex_cb_ptr) { + osi_free(obex_cb_ptr); + obex_cb_ptr = NULL; + } +#endif /* #if (OBEX_DYNAMIC_MEMORY) */ +} + +/******************************************************************************* +** +** Function OBEX_CreateConn +** +** Description Start the progress of creating an OBEX connection +** +** Returns OBEX_SUCCESS if successful, otherwise failed, when the +** connection is opened, an OBEX_CONNECT_EVT will come +** +*******************************************************************************/ +UINT16 OBEX_CreateConn(tOBEX_SVR_INFO *server, tOBEX_MSG_CBACK callback, UINT16 *out_handle) +{ + UINT16 ret = OBEX_SUCCESS; + tOBEX_CCB *p_ccb = NULL; + + do { + if (server->tl >= OBEX_NUM_TL) { + ret = OBEX_INVALID_PARAM; + break; + } + + p_ccb = obex_allocate_ccb(); + if (p_ccb == NULL) { + ret = OBEX_NO_RESOURCES; + break; + } + + tOBEX_TL_SVR_INFO tl_server = {0}; + obex_server_to_tl_server(server, &tl_server); + p_ccb->tl = server->tl; + p_ccb->tl_hdl = obex_cb.tl_ops[p_ccb->tl]->connect(&tl_server); + if (p_ccb->tl_hdl == 0) { + ret = OBEX_ERROR_TL; + break; + } + + p_ccb->callback = callback; + p_ccb->role = OBEX_ROLE_CLIENT; + p_ccb->state = OBEX_STATE_OPENING; + *out_handle = p_ccb->allocated; + } while (0); + + if (ret != OBEX_SUCCESS && p_ccb != NULL) { + obex_free_ccb(p_ccb); + } + return ret; +} + +/******************************************************************************* +** +** Function OBEX_RemoveConn +** +** Description Remove an OBEX connection +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_RemoveConn(UINT16 handle) +{ + tOBEX_CCB *p_ccb = NULL; + + UINT16 ccb_idx = handle - 1; + if (ccb_idx >= OBEX_MAX_CONNECTION || !obex_cb.ccb[ccb_idx].allocated) { + return OBEX_BAD_HANDLE; + } + + p_ccb = &obex_cb.ccb[ccb_idx]; + obex_cb.tl_ops[p_ccb->tl]->disconnect(p_ccb->tl_hdl); + obex_free_ccb(p_ccb); + + return OBEX_SUCCESS; +} + +/******************************************************************************* +** +** Function OBEX_RegisterServer +** +** Description Register an OBEX server and listen the incoming connection +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_RegisterServer(tOBEX_SVR_INFO *server, tOBEX_MSG_CBACK callback, UINT16 *out_svr_handle) +{ + UINT8 ret = OBEX_SUCCESS; + tOBEX_SCB *p_scb = NULL; + + do { + if (server->tl >= OBEX_NUM_TL) { + ret = OBEX_INVALID_PARAM; + break; + } + + p_scb = obex_allocate_scb(); + if (p_scb == NULL) { + ret = OBEX_NO_RESOURCES; + break; + } + + tOBEX_TL_SVR_INFO tl_server = {0}; + obex_server_to_tl_server(server, &tl_server); + p_scb->tl = server->tl; + p_scb->tl_hdl = obex_cb.tl_ops[p_scb->tl]->bind(&tl_server); + if (p_scb->tl_hdl == 0) { + ret = OBEX_ERROR_TL; + break; + } + p_scb->callback = callback; + + if (out_svr_handle) { + /* To avoid confuse with connection handle, left shift 8 bit */ + *out_svr_handle = p_scb->allocated << 8; + } + } while (0); + + if (ret != OBEX_SUCCESS && p_scb != NULL) { + obex_free_scb(p_scb); + } + return ret; +} + +/******************************************************************************* +** +** Function OBEX_DeregisterServer +** +** Description Deregister an OBEX server, if there are still a connection +** alive, the behavior depend on the implementation of transport +** layer +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_DeregisterServer(UINT16 svr_handle) +{ + tOBEX_SCB *p_scb = NULL; + + UINT16 scb_idx = (svr_handle >> 8) - 1; + if (scb_idx >= OBEX_MAX_SERVER || !obex_cb.scb[scb_idx].allocated) { + return OBEX_BAD_HANDLE; + } + + p_scb = &obex_cb.scb[scb_idx]; + obex_cb.tl_ops[p_scb->tl]->unbind(p_scb->tl_hdl); + obex_free_scb(p_scb); + return OBEX_SUCCESS; +} + +/******************************************************************************* +** +** Function OBEX_SendPacket +** +** Description Send a packet to peer OBEX server or client, once call +** this function, the ownership of pkt is lost, do not free +** or modify the pkt any more +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_SendPacket(UINT16 handle, BT_HDR *pkt) +{ + UINT16 ret = OBEX_SUCCESS; + BOOLEAN free_pkt = true; + tOBEX_CCB *p_ccb = NULL; + do { + if (pkt == NULL) { + ret = OBEX_INVALID_PARAM; + break; + } + + UINT16 ccb_idx = handle - 1; + if (ccb_idx >= OBEX_MAX_CONNECTION || !obex_cb.ccb[ccb_idx].allocated) { + ret = OBEX_BAD_HANDLE; + break; + } + + p_ccb = &obex_cb.ccb[ccb_idx]; + if (p_ccb->state != OBEX_STATE_OPENED) { + ret = OBEX_NOT_OPEN; + break; + } + + if (pkt->len > p_ccb->tl_peer_mtu) { + ret = OBEX_PACKET_TOO_LARGE; + break; + } + + ret = obex_cb.tl_ops[p_ccb->tl]->send(p_ccb->tl_hdl, pkt); + /* packet has pass to lower layer, do not free it */ + free_pkt = false; + if (ret == OBEX_TL_SUCCESS || ret == OBEX_TL_CONGESTED) { + ret = OBEX_SUCCESS; + } + else { + ret = OBEX_ERROR_TL; + } + } while (0); + + if (free_pkt) { + osi_free(pkt); + } + return ret; +} + +/******************************************************************************* +** +** Function OBEX_BuildRequest +** +** Description Build a request packet with opcode and additional info, +** packet can free by osi_free +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_BuildRequest(tOBEX_PARSE_INFO *info, UINT16 buff_size, BT_HDR **out_pkt) +{ + if (buff_size < OBEX_MIN_PACKET_SIZE || info == NULL || out_pkt == NULL) { + return OBEX_INVALID_PARAM; + } + buff_size += sizeof(BT_HDR) + OBEX_BT_HDR_MIN_OFFSET + OBEX_BT_HDR_RESERVE_LEN; + + BT_HDR *p_buf= (BT_HDR *)osi_malloc(buff_size); + if (p_buf == NULL) { + return OBEX_NO_RESOURCES; + } + + UINT16 pkt_len = OBEX_MIN_PACKET_SIZE; + p_buf->offset = OBEX_BT_HDR_MIN_OFFSET; + /* use layer_specific to store the max data length allowed */ + p_buf->layer_specific = buff_size - sizeof(BT_HDR) - OBEX_BT_HDR_MIN_OFFSET - OBEX_BT_HDR_RESERVE_LEN; + UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; + /* byte 0: opcode */ + *p_data++ = info->opcode; + /* byte 1, 2: packet length, skip, we will update at last */ + UINT8 *p_pkt_len = p_data; + p_data += 2; + + switch (info->opcode) + { + case OBEX_OPCODE_CONNECT: + /* byte 3: OBEX version number */ + *p_data++ = info->obex_version_number; + /* byte 4: flags */ + *p_data++ = info->flags; + /* byte 5, 6: maximum OBEX packet length, recommend to set as our mtu*/ + UINT16_TO_BE_FIELD(p_data, info->max_packet_length); + pkt_len += 4; + break; + case OBEX_OPCODE_SETPATH: + /* byte 3: flags */ + *p_data++ = info->flags; + /* byte 4: constants, reserved, must be zero */ + *p_data++ = 0; + pkt_len += 2; + break; + default: + break; + } + + UINT16_TO_BE_FIELD(p_pkt_len, pkt_len); + p_buf->len = pkt_len; + *out_pkt = p_buf; + return OBEX_SUCCESS; +} + +/******************************************************************************* +** +** Function OBEX_BuildResponse +** +** Description Build a response packet with opcode and response and additional +** info, packet can by free by osi_free +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_BuildResponse(tOBEX_PARSE_INFO *info, UINT16 buff_size, BT_HDR **out_pkt) +{ + if (buff_size < OBEX_MIN_PACKET_SIZE || info == NULL || out_pkt == NULL) { + return OBEX_INVALID_PARAM; + } + buff_size += sizeof(BT_HDR) + OBEX_BT_HDR_MIN_OFFSET + OBEX_BT_HDR_RESERVE_LEN; + + BT_HDR *p_buf= (BT_HDR *)osi_malloc(buff_size); + if (p_buf == NULL) { + return OBEX_NO_RESOURCES; + } + + UINT16 pkt_len = OBEX_MIN_PACKET_SIZE; + p_buf->offset = OBEX_BT_HDR_MIN_OFFSET; + /* use layer_specific to store the max data length allowed */ + p_buf->layer_specific = buff_size - sizeof(BT_HDR) - OBEX_BT_HDR_MIN_OFFSET - OBEX_BT_HDR_RESERVE_LEN; + UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; + /* byte 0: response code */ + *p_data++ = info->response_code; + /* byte 1, 2: packet length, skip, we will update at last */ + UINT8 *p_pkt_len = p_data; + p_data += 2; + + /* we need to use opcode to decide the response format */ + switch (info->opcode) + { + case OBEX_OPCODE_CONNECT: + /* byte 3: OBEX version number */ + *p_data++ = info->obex_version_number; + /* byte 4: flags */ + *p_data++ = info->flags; + /* byte 5, 6: maximum OBEX packet length, recommend to set as our mtu */ + UINT16_TO_BE_FIELD(p_data, info->max_packet_length); + pkt_len += 4; + break; + default: + break; + } + + UINT16_TO_BE_FIELD(p_pkt_len, pkt_len); + p_buf->len = pkt_len; + *out_pkt = p_buf; + return OBEX_SUCCESS; +} + +/******************************************************************************* +** +** Function OBEX_AppendHeader +** +** Description Append a header to specific packet, packet can be request +** or response, the format of header must be valid +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_AppendHeader(BT_HDR *pkt, const UINT8 *header) +{ + if (pkt == NULL || header == NULL) { + return OBEX_INVALID_PARAM; + } + + UINT16 header_len = 0; + UINT8 header_id = *header; + switch (header_id & OBEX_HEADER_ID_U2B_MASK) + { + case OBEX_HEADER_ID_U2B_TYPE1: + case OBEX_HEADER_ID_U2B_TYPE2: + header_len = (header[1] << 8) + header[2]; + break; + case OBEX_HEADER_ID_U2B_TYPE3: + header_len = 2; + break; + case OBEX_HEADER_ID_U2B_TYPE4: + header_len = 5; + break; + default: + break; + } + if (header_len == 0) { + return OBEX_INVALID_PARAM; + } + + if (pkt->layer_specific - pkt->len < header_len) { + /* the packet can not hold this header */ + return OBEX_NO_RESOURCES; + } + UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset; + UINT8 *p_start = p_data + pkt->len; + memcpy(p_start, header, header_len); + pkt->len += header_len; + /* point to packet len */ + p_data++; + UINT16_TO_BE_FIELD(p_data, pkt->len); + return OBEX_SUCCESS; +} + +/******************************************************************************* +** +** Function OBEX_AppendHeaderRaw +** +** Description Append a header to specific packet, packet can be request +** or response, data not include 2 byte length prefixed +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_AppendHeaderRaw(BT_HDR *pkt, UINT8 header_id, const UINT8 *data, UINT16 data_len) +{ + if (pkt == NULL) { + return OBEX_INVALID_PARAM; + } + + if ((data == NULL && data_len != 0) || (data != NULL && data_len == 0)) { + return OBEX_INVALID_PARAM; + } + + UINT16 header_len = 0; + BOOLEAN store_header_len = FALSE; + switch (header_id & OBEX_HEADER_ID_U2B_MASK) + { + case OBEX_HEADER_ID_U2B_TYPE1: + case OBEX_HEADER_ID_U2B_TYPE2: + /* header id + 2 byte length prefixed + data */ + header_len = data_len + 3; + store_header_len = TRUE; + break; + case OBEX_HEADER_ID_U2B_TYPE3: + header_len = 2; + if (data_len != 1) { + return OBEX_INVALID_PARAM; + } + break; + case OBEX_HEADER_ID_U2B_TYPE4: + header_len = 5; + if (data_len != 4) { + return OBEX_INVALID_PARAM; + } + break; + default: + break; + } + if (header_len == 0) { + return OBEX_INVALID_PARAM; + } + + if (pkt->layer_specific - pkt->len < header_len) { + /* the packet can not hold this header */ + return OBEX_NO_RESOURCES; + } + UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset; + UINT8 *p_start = p_data + pkt->len; + /* store header id */ + *p_start++ = header_id; + if (store_header_len) { + /* store header length */ + UINT16_TO_BE_FIELD(p_start, header_len); + p_start+= 2; + } + if (data != NULL) { + /* store data */ + memcpy(p_start, data, data_len); + } + pkt->len += header_len; + /* point to packet len */ + p_data++; + UINT16_TO_BE_FIELD(p_data, pkt->len); + return OBEX_SUCCESS; +} + +/******************************************************************************* +** +** Function OBEX_AppendHeaderSRM +** +** Description Append a Single Response Mode header +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_AppendHeaderSRM(BT_HDR *pkt, UINT8 value) +{ + return OBEX_AppendHeaderRaw(pkt, OBEX_HEADER_ID_SRM, &value, 1); +} + +/******************************************************************************* +** +** Function OBEX_AppendHeaderSRMP +** +** Description Append a Single Response Mode Parameters header +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_AppendHeaderSRMP(BT_HDR *pkt, UINT8 value) +{ + return OBEX_AppendHeaderRaw(pkt, OBEX_HEADER_ID_SRM_PARAM, &value, 1); +} + +/******************************************************************************* +** +** Function OBEX_GetPacketFreeSpace +** +** Description Get the current free space of a packet, use this to check +** if a packet can hold a header +** +** Returns Current free space of a packet, in bytes +** +*******************************************************************************/ +UINT16 OBEX_GetPacketFreeSpace(BT_HDR *pkt) +{ + if (pkt == NULL) { + return 0; + } + return pkt->layer_specific - pkt->len; +} + +/******************************************************************************* +** +** Function OBEX_GetPacketLength +** +** Description Get the current packet length +** +** Returns Current packet length, in bytes +** +*******************************************************************************/ +UINT16 OBEX_GetPacketLength(BT_HDR *pkt) +{ + if (pkt == NULL) { + return 0; + } + return pkt->len; +} + +/******************************************************************************* +** +** Function OBEX_ParseRequest +** +** Description Parse a request packet +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_ParseRequest(BT_HDR *pkt, tOBEX_PARSE_INFO *info) +{ + if (pkt == NULL || info == NULL) { + return OBEX_INVALID_PARAM; + } + + UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset; + info->opcode = *p_data; + switch (info->opcode) + { + case OBEX_OPCODE_CONNECT: + info->obex_version_number = p_data[3]; + info->flags = p_data[4]; + info->max_packet_length = (p_data[5] << 8) + p_data[6]; + info->next_header_pos = 7; + break; + case OBEX_OPCODE_SETPATH: + info->flags = p_data[3]; + info->next_header_pos = 5; + break; + default: + info->next_header_pos = 3; + break; + } + return OBEX_SUCCESS; +} + +/******************************************************************************* +** +** Function OBEX_ParseResponse +** +** Description Parse a request response packet +** +** Returns OBEX_SUCCESS if successful, otherwise failed +** +*******************************************************************************/ +UINT16 OBEX_ParseResponse(BT_HDR *pkt, UINT8 opcode, tOBEX_PARSE_INFO *info) +{ + if (pkt == NULL || info == NULL) { + return OBEX_INVALID_PARAM; + } + + UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset; + info->opcode = opcode; + info->response_code = *p_data; + switch (opcode) + { + case OBEX_OPCODE_CONNECT: + info->obex_version_number = p_data[3]; + info->flags = p_data[4]; + info->max_packet_length = (p_data[5] << 8) + p_data[6]; + info->next_header_pos = 7; + break; + default: + info->next_header_pos = 3; + break; + } + return OBEX_SUCCESS; +} + +/******************************************************************************* +** +** Function OBEX_CheckFinalBit +** +** Description Check whether a packet had set the final bit +** +** Returns TRUE if final bit set, otherwise, false +** +*******************************************************************************/ +BOOLEAN OBEX_CheckFinalBit(BT_HDR *pkt) +{ + if (pkt == NULL) { + return FALSE; + } + UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset; + return (*p_data) & OBEX_FINAL_BIT_MASK; +} + +/******************************************************************************* +** +** Function OBEX_CheckContinueResponse +** +** Description Check whether a packet is continue response +** +** Returns TRUE if continue response, otherwise, false +** +*******************************************************************************/ +BOOLEAN OBEX_CheckContinueResponse(BT_HDR *pkt) +{ + if (pkt == NULL) { + return FALSE; + } + UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset; + return (*p_data == 0x90) || (*p_data == 0x10); +} + +/******************************************************************************* +** +** Function OBEX_GetHeaderLength +** +** Description Get header length +** +** Returns header length +** +*******************************************************************************/ +UINT16 OBEX_GetHeaderLength(UINT8 *header) +{ + UINT16 header_len = 0; + UINT8 header_id = *header; + switch (header_id & OBEX_HEADER_ID_U2B_MASK) + { + case OBEX_HEADER_ID_U2B_TYPE1: + case OBEX_HEADER_ID_U2B_TYPE2: + header_len = (header[1] << 8) + header[2]; + break; + case OBEX_HEADER_ID_U2B_TYPE3: + header_len = 2; + break; + case OBEX_HEADER_ID_U2B_TYPE4: + header_len = 5; + break; + default: + /* unreachable */ + break; + } + return header_len; +} + +/******************************************************************************* +** +** Function OBEX_GetNextHeader +** +** Description Get next header pointer from a packet +** +** Returns Pointer to start address of a header, NULL if no more header +** or failed +** +*******************************************************************************/ +UINT8 *OBEX_GetNextHeader(BT_HDR *pkt, tOBEX_PARSE_INFO *info) +{ + if (pkt == NULL || info == NULL) { + return NULL; + } + UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset; + if (info->next_header_pos == 0 || info->next_header_pos >= pkt->len) { + return NULL; + } + UINT8 *header = p_data + info->next_header_pos; + UINT16 header_len = OBEX_GetHeaderLength(header); + info->next_header_pos += header_len; + return header; +} + +#endif /* #if (OBEX_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/obex/obex_main.c b/lib/bt/host/bluedroid/stack/obex/obex_main.c new file mode 100644 index 00000000..7810ff3c --- /dev/null +++ b/lib/bt/host/bluedroid/stack/obex/obex_main.c @@ -0,0 +1,216 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> + +#include "osi/osi.h" +#include "osi/allocator.h" +#include "common/bt_target.h" + +#include "stack/obex_api.h" +#include "obex_int.h" +#include "obex_tl.h" + +#if (OBEX_INCLUDED == TRUE) + +#if OBEX_DYNAMIC_MEMORY == FALSE +tOBEX_CB obex_cb; +#else +tOBEX_CB *obex_cb_ptr = NULL; +#endif + +static tOBEX_CCB *obex_find_ccb_by_tl_hdl(UINT8 tl, UINT16 tl_hdl) +{ + tOBEX_CCB *p_ccb = NULL; + for (int i = 0; i < OBEX_MAX_CONNECTION; ++i) { + if (obex_cb.ccb[i].allocated && obex_cb.ccb[i].tl == tl && obex_cb.ccb[i].tl_hdl == tl_hdl) { + p_ccb = &obex_cb.ccb[i]; + break; + } + } + return p_ccb; +} + +static tOBEX_SCB *obex_find_scb_by_tl_hdl(UINT8 tl, UINT16 tl_hdl) +{ + tOBEX_SCB *p_scb = NULL; + for (int i = 0; i < OBEX_MAX_SERVER; ++i) { + if (obex_cb.scb[i].allocated && obex_cb.scb[i].tl == tl && obex_cb.scb[i].tl_hdl == tl_hdl) { + p_scb = &obex_cb.scb[i]; + break; + } + } + return p_scb; +} + +tOBEX_CCB *obex_allocate_ccb(void) +{ + tOBEX_CCB *p_ccb = NULL; + for (int i = 0; i < OBEX_MAX_CONNECTION; ++i) { + if (!obex_cb.ccb[i].allocated) { + obex_cb.ccb[i].allocated = i + 1; + p_ccb = &obex_cb.ccb[i]; + break; + } + } + return p_ccb; +} + +void obex_free_ccb(tOBEX_CCB *p_ccb) +{ + assert(p_ccb->allocated != 0); + memset(p_ccb, 0, sizeof(tOBEX_CCB)); +} + +tOBEX_SCB *obex_allocate_scb(void) +{ + tOBEX_SCB *p_scb = NULL; + for (int i = 0; i < OBEX_MAX_SERVER; ++i) { + if (!obex_cb.scb[i].allocated) { + obex_cb.scb[i].allocated = i + 1; + p_scb = &obex_cb.scb[i]; + break; + } + } + return p_scb; +} + +void obex_free_scb(tOBEX_SCB *p_scb) +{ + assert(p_scb->allocated != 0); + memset(p_scb, 0, sizeof(tOBEX_SCB)); +} + +/* check whether connection mtu is valid, if not, disconnect it */ +static bool check_conn_mtu_valid(tOBEX_CCB *p_ccb, BOOLEAN call_cb) +{ + if (p_ccb->tl_our_mtu < 255 || p_ccb->tl_peer_mtu < 255) { + if (call_cb && p_ccb->callback) { + p_ccb->callback(p_ccb->allocated, OBEX_DISCONNECT_EVT, NULL); + } + OBEX_TRACE_ERROR("Check OBEX transport layer MTU failed, disconnect"); + obex_cb.tl_ops[p_ccb->tl]->disconnect(p_ccb->tl_hdl); + obex_free_ccb(p_ccb); + return false; + } + return true; +} + +void obex_tl_evt_handler(UINT8 tl, tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg) +{ + UINT16 tl_hdl = msg->any.hdl; + tOBEX_CCB *p_ccb = obex_find_ccb_by_tl_hdl(tl, tl_hdl); + tOBEX_SCB *p_scb = NULL; + tOBEX_MSG cb_msg = {0}; + + switch (evt) + { + case OBEX_TL_CONN_OPEN_EVT: + assert(p_ccb != NULL); + p_ccb->tl_peer_mtu = msg->conn_open.peer_mtu; + p_ccb->tl_our_mtu = msg->conn_open.our_mtu; + if (!check_conn_mtu_valid(p_ccb, TRUE)) { + break; + } + p_ccb->state = OBEX_STATE_OPENED; + if (p_ccb->callback) { + cb_msg.connect.peer_mtu = msg->conn_open.peer_mtu; + cb_msg.connect.our_mtu = msg->conn_open.our_mtu; + p_ccb->callback(p_ccb->allocated, OBEX_CONNECT_EVT, &cb_msg); + } + break; + case OBEX_TL_DIS_CONN_EVT: + if (p_ccb != NULL) { + if (p_ccb->callback) { + p_ccb->callback(p_ccb->allocated, OBEX_DISCONNECT_EVT, NULL); + } + obex_free_ccb(p_ccb); + } + break; + case OBEX_TL_CONGEST_EVT: + assert(p_ccb != NULL); + if (p_ccb->callback) { + p_ccb->callback(p_ccb->allocated, OBEX_CONGEST_EVT, NULL); + } + break; + case OBEX_TL_UNCONGEST_EVT: + assert(p_ccb != NULL); + if (p_ccb->callback) { + p_ccb->callback(p_ccb->allocated, OBEX_UNCONGEST_EVT, NULL); + } + break; + case OBEX_TL_MTU_CHANGE_EVT: + assert(p_ccb != NULL); + p_ccb->tl_peer_mtu = msg->mtu_chg.peer_mtu; + p_ccb->tl_our_mtu = msg->mtu_chg.our_mtu; + if (!check_conn_mtu_valid(p_ccb, TRUE)) { + break; + } + if (p_ccb->callback) { + cb_msg.mtu_change.peer_mtu = msg->mtu_chg.peer_mtu; + cb_msg.mtu_change.our_mtu = msg->mtu_chg.our_mtu; + p_ccb->callback(p_ccb->allocated, OBEX_MTU_CHANGE_EVT, &cb_msg); + } + break; + case OBEX_TL_DATA_EVT: + assert(p_ccb != NULL); + if (p_ccb->callback) { + cb_msg.data.pkt = msg->data.p_buf; + p_ccb->callback(p_ccb->allocated, OBEX_DATA_EVT, &cb_msg); + } + else { + /* No callback, just free the packet */ + osi_free(msg->data.p_buf); + } + break; + case OBEX_TL_CONN_INCOME_EVT: + /* New connection, p_ccb should be NULL */ + assert(p_ccb == NULL); + p_scb = obex_find_scb_by_tl_hdl(tl, msg->conn_income.svr_hdl); + if (p_scb == NULL) { + obex_cb.tl_ops[tl]->disconnect(tl_hdl); + break; + } + + if ((p_ccb = obex_allocate_ccb()) == NULL) { + obex_cb.tl_ops[tl]->disconnect(tl_hdl); + break; + } + + p_ccb->tl = tl; + p_ccb->tl_hdl = tl_hdl; + p_ccb->role = OBEX_ROLE_SERVER; + p_ccb->tl_peer_mtu = msg->conn_income.peer_mtu; + p_ccb->tl_our_mtu = msg->conn_income.our_mtu; + if (!check_conn_mtu_valid(p_ccb, FALSE)) { + break; + } + p_ccb->state = OBEX_STATE_OPENED; + p_ccb->callback = p_scb->callback; + if (p_ccb->callback) { + cb_msg.conn_income.svr_handle = p_scb->allocated << 8; + cb_msg.conn_income.peer_mtu = msg->conn_income.peer_mtu; + cb_msg.conn_income.our_mtu = msg->conn_income.our_mtu; + p_ccb->callback(p_ccb->allocated, OBEX_CONN_INCOME_EVT, &cb_msg); + } + break; + default: + OBEX_TRACE_ERROR("Unknown OBEX transport event: 0x%x\n", evt); + break; + } +} + +void obex_tl_l2cap_callback(tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg) +{ + obex_tl_evt_handler(OBEX_OVER_L2CAP, evt, msg); +} + +void obex_tl_rfcomm_callback(tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg) +{ + obex_tl_evt_handler(OBEX_OVER_RFCOMM, evt, msg); +} + +#endif /* #if (OBEX_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/obex/obex_tl_l2cap.c b/lib/bt/host/bluedroid/stack/obex/obex_tl_l2cap.c new file mode 100644 index 00000000..d509b4cf --- /dev/null +++ b/lib/bt/host/bluedroid/stack/obex/obex_tl_l2cap.c @@ -0,0 +1,811 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> + +#include "osi/osi.h" +#include "osi/allocator.h" +#include "common/bt_target.h" + +#include "stack/l2c_api.h" +#include "stack/l2cdefs.h" +#include "stack/btm_api.h" +#include "btm_int.h" +#include "obex_tl.h" +#include "obex_tl_l2cap.h" + +#if (OBEX_INCLUDED == TRUE) + +#define OBEX_TL_L2CAP_NUM_CONN 4 +#define OBEX_TL_L2CAP_NUM_SERVER 2 + +#define OBEX_TL_L2CAP_STATUS_FLAG_CFG_DONE 0x01 +#define OBEX_TL_L2CAP_STATUS_FLAG_PEER_CFG_DONE 0x02 +#define OBEX_TL_L2CAP_STATUS_FLAG_CONNECTED 0x80 + +/* ERTM Tx window size */ +#define OBEX_TL_L2CAP_FCR_OPT_TX_WINDOW_SIZE 10 + +/* ERTM Maximum transmissions before disconnecting */ +#define OBEX_TL_L2CAP_FCR_OPT_MAX_TX_B4_DISCNT 20 + +/* ERTM Retransmission timeout (2 secs) */ +#define OBEX_TL_L2CAP_FCR_OPT_RETX_TOUT 2000 + +/* ERTM Monitor timeout (12 secs) */ +#define OBEX_TL_L2CAP_FCR_OPT_MONITOR_TOUT 12000 + +/* ERTM ERTM MPS segment size */ +#define OBEX_TL_L2CAP_FCR_OPT_MAX_PDU_SIZE 1010 + +typedef struct { + UINT16 vpsm; /* psm in our side */ + UINT16 lcid; /* local channel id */ + UINT16 peer_mtu; /* MTU that peer device set */ + UINT16 our_mtu; /* MTU that we set to peer device */ + BOOLEAN initiator; /* TRUE if is initiator, otherwise FALSE */ + UINT8 id; /* remote channel id */ + UINT8 status_flag; /* status flag used in config procedure */ + UINT8 allocated; /* 0 if not allocated, otherwise, index + 1, equal to handle */ + BD_ADDR addr; /* peer bluetooth device address */ +} tOBEX_TL_L2CAP_CCB; + +typedef struct { + UINT16 psm; /* psm in our side */ + UINT16 pref_mtu; /* preferred mtu */ + UINT8 allocated; /* 0 if not allocated, otherwise, index + 1, handle of server will left shift 8 bits */ +} tOBEX_TL_L2CAP_SCB; + +typedef struct { + tOBEX_TL_CBACK *callback; /* Upper layer callback */ + tOBEX_TL_L2CAP_CCB ccb[OBEX_TL_L2CAP_NUM_CONN]; + tOBEX_TL_L2CAP_SCB scb[OBEX_TL_L2CAP_NUM_SERVER]; + tL2CAP_APPL_INFO l2cap_reg_info; /* Default L2CAP Registration info */ + UINT8 trace_level; /* trace level */ +} tOBEX_TL_L2CAP_CB; + +#if OBEX_DYNAMIC_MEMORY == FALSE +static tOBEX_TL_L2CAP_CB obex_tl_l2cap_cb; +#else +static tOBEX_TL_L2CAP_CB *obex_tl_l2cap_cb_ptr = NULL; +#define obex_tl_l2cap_cb (*obex_tl_l2cap_cb_ptr) +#endif + +static tL2CAP_ERTM_INFO obex_tl_l2cap_etm_opts = +{ + L2CAP_FCR_ERTM_MODE, + L2CAP_FCR_CHAN_OPT_ERTM | L2CAP_FCR_CHAN_OPT_BASIC, /* Some devices do not support ERTM */ + L2CAP_USER_RX_BUF_SIZE, + L2CAP_USER_TX_BUF_SIZE, + L2CAP_FCR_RX_BUF_SIZE, + L2CAP_FCR_TX_BUF_SIZE +}; + +static tL2CAP_FCR_OPTS obex_tl_l2cap_fcr_opts = +{ + L2CAP_FCR_ERTM_MODE, + OBEX_TL_L2CAP_FCR_OPT_TX_WINDOW_SIZE, /* Tx window size */ + OBEX_TL_L2CAP_FCR_OPT_MAX_TX_B4_DISCNT, /* Maximum transmissions before disconnecting */ + OBEX_TL_L2CAP_FCR_OPT_RETX_TOUT, /* Retransmission timeout (2 secs) */ + OBEX_TL_L2CAP_FCR_OPT_MONITOR_TOUT, /* Monitor timeout (12 secs) */ + OBEX_TL_L2CAP_FCR_OPT_MAX_PDU_SIZE /* MPS segment size */ +}; + +static tOBEX_TL_L2CAP_CCB *allocate_ccb(void) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = NULL; + for(int i = 0; i < OBEX_TL_L2CAP_NUM_CONN; ++i) { + if (obex_tl_l2cap_cb.ccb[i].allocated == 0) { + obex_tl_l2cap_cb.ccb[i].allocated = i + 1; + p_ccb = &obex_tl_l2cap_cb.ccb[i]; + break; + } + } + return p_ccb; +} + +static void free_ccb(tOBEX_TL_L2CAP_CCB *p_ccb) +{ + memset(p_ccb, 0, sizeof(tOBEX_TL_L2CAP_CCB)); +} + +static tOBEX_TL_L2CAP_CCB *find_ccb_by_lcid(UINT16 lcid) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = NULL; + for (int i = 0; i < OBEX_TL_L2CAP_NUM_CONN; ++i) { + if (obex_tl_l2cap_cb.ccb[i].allocated && obex_tl_l2cap_cb.ccb[i].lcid == lcid) { + p_ccb = &obex_tl_l2cap_cb.ccb[i]; + break; + } + } + return p_ccb; +} + +static tOBEX_TL_L2CAP_CCB *find_ccb_by_hdl(UINT16 hdl) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = NULL; + if (hdl > 0 && hdl <= OBEX_TL_L2CAP_NUM_CONN) { + if (obex_tl_l2cap_cb.ccb[hdl-1].allocated == hdl) { + p_ccb = &obex_tl_l2cap_cb.ccb[hdl-1]; + } + } + return p_ccb; +} + +static tOBEX_TL_L2CAP_CCB *find_ccb_by_psm(UINT16 psm) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = NULL; + for(int i = 0; i < OBEX_TL_L2CAP_NUM_CONN; ++i) { + if (obex_tl_l2cap_cb.ccb[i].allocated && obex_tl_l2cap_cb.ccb[i].vpsm == psm) { + p_ccb = &obex_tl_l2cap_cb.ccb[i]; + break; + } + } + return p_ccb; +} + +static tOBEX_TL_L2CAP_SCB *allocate_scb(void) +{ + tOBEX_TL_L2CAP_SCB *p_scb = NULL; + for(int i = 0; i < OBEX_TL_L2CAP_NUM_SERVER; ++i) { + if (obex_tl_l2cap_cb.scb[i].allocated == 0) { + obex_tl_l2cap_cb.scb[i].allocated = i + 1; + p_scb = &obex_tl_l2cap_cb.scb[i]; + break; + } + } + return p_scb; +} + +static tOBEX_TL_L2CAP_SCB *find_scb_by_psm(UINT16 psm) +{ + tOBEX_TL_L2CAP_SCB *p_scb = NULL; + for(int i = 0; i < OBEX_TL_L2CAP_NUM_SERVER; ++i) { + if (obex_tl_l2cap_cb.scb[i].allocated && obex_tl_l2cap_cb.scb[i].psm == psm) { + p_scb = &obex_tl_l2cap_cb.scb[i]; + break; + } + } + return p_scb; +} + +static void free_scb(tOBEX_TL_L2CAP_SCB *p_scb) +{ + memset(p_scb, 0, sizeof(tOBEX_TL_L2CAP_SCB)); +} + +static tOBEX_TL_L2CAP_SCB *find_scb_by_hdl(UINT16 hdl) +{ + tOBEX_TL_L2CAP_SCB *p_scb = NULL; + hdl = hdl >> 8; + if (hdl > 0 && hdl <= OBEX_TL_L2CAP_NUM_SERVER) { + if (obex_tl_l2cap_cb.scb[hdl-1].allocated == hdl) { + p_scb = &obex_tl_l2cap_cb.scb[hdl-1]; + } + } + return p_scb; +} + +/******************************************************************************* + * + * Function obex_tl_l2cap_sec_check_complete_term + * + * Description OBEX over L2CAP security check complete callback function + * (terminated). + * + ******************************************************************************/ +static void l2cap_sec_check_complete_term(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = (tOBEX_TL_L2CAP_CCB *)p_ref_data; + + if (res == BTM_SUCCESS) { + L2CA_ErtmConnectRsp(p_ccb->addr, p_ccb->id, p_ccb->lcid, L2CAP_CONN_OK, 0, &obex_tl_l2cap_etm_opts); + tL2CAP_CFG_INFO cfg = {0}; + cfg.mtu_present = TRUE; + cfg.mtu = p_ccb->our_mtu; + cfg.fcr_present = TRUE; + cfg.fcr = obex_tl_l2cap_fcr_opts; + L2CA_ConfigReq(p_ccb->lcid, &cfg); + } + else{ + L2CA_ErtmConnectRsp(p_ccb->addr, p_ccb->id, p_ccb->lcid, L2CAP_CONN_SECURITY_BLOCK, 0, &obex_tl_l2cap_etm_opts); + tOBEX_TL_MSG msg = {0}; + msg.any.hdl = p_ccb->allocated; + obex_tl_l2cap_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg); + free_ccb(p_ccb); + } +} + +/******************************************************************************* + * + * Function obex_tl_l2cap_sec_check_complete_orig + * + * Description OBEX over L2CAP security check complete callback function + * (originated). + * + ******************************************************************************/ +static void l2cap_sec_check_complete_orig(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = (tOBEX_TL_L2CAP_CCB *)p_ref_data; + + if (res == BTM_SUCCESS) { + tL2CAP_CFG_INFO cfg = {0}; + cfg.mtu_present = TRUE; + cfg.mtu = p_ccb->our_mtu; + cfg.fcr_present = TRUE; + cfg.fcr = obex_tl_l2cap_fcr_opts; + L2CA_ConfigReq(p_ccb->lcid, &cfg); + } else { + L2CA_DisconnectReq(p_ccb->lcid); + tOBEX_TL_MSG msg = {0}; + msg.any.hdl = p_ccb->allocated; + obex_tl_l2cap_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg); + free_ccb(p_ccb); + } +} + +/******************************************************************************* +** +** Function obex_tl_l2cap_connect_ind +** +** Description This is a callback function called by L2CAP when +** L2CA_ConnectInd received. +** +*******************************************************************************/ +void obex_tl_l2cap_connect_ind(BD_ADDR addr, UINT16 lcid, UINT16 psm, UINT8 id) +{ + tOBEX_TL_L2CAP_SCB *p_scb = find_scb_by_psm(psm); + if (p_scb == NULL) { + /* An incoming connection, but no corresponding server found, reject */ + L2CA_ErtmConnectRsp (addr, id, lcid, L2CAP_CONN_NO_PSM, 0, &obex_tl_l2cap_etm_opts); + OBEX_TL_L2CAP_TRACE_WARNING("No corresponding server found, reject incoming connection\n"); + return; + } + + tOBEX_TL_L2CAP_CCB *p_ccb = allocate_ccb(); + if (p_ccb == NULL) { + /* No resource, can not allocate ccb, reject */ + L2CA_ErtmConnectRsp (addr, id, lcid, L2CAP_CONN_NO_RESOURCES, 0, &obex_tl_l2cap_etm_opts); + OBEX_TL_L2CAP_TRACE_WARNING("Can not allocate a ccb for new connection\n"); + return; + } + + bdcpy(p_ccb->addr, addr); + p_ccb->initiator = FALSE; + p_ccb->lcid = lcid; + p_ccb->id = id; + p_ccb->vpsm = psm; + p_ccb->our_mtu = p_scb->pref_mtu; + if (btm_sec_mx_access_request(p_ccb->addr, p_ccb->vpsm, + FALSE, BTM_SEC_PROTO_OBEX, + OBEX_TL_L2CAP_NUM_CONN + p_scb->allocated - 1, + &l2cap_sec_check_complete_term, p_ccb) == BTM_CMD_STARTED) { + L2CA_ErtmConnectRsp(addr, id, lcid, L2CAP_CONN_PENDING, 0, &obex_tl_l2cap_etm_opts); + } +} + +/******************************************************************************* +** +** Function obex_tl_l2cap_connect_cfm +** +** Description This is a callback function called by L2CAP when +** ConnectCfm received. +** +*******************************************************************************/ +void obex_tl_l2cap_connect_cfm(UINT16 lcid, UINT16 result) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_lcid(lcid); + if (p_ccb == NULL) { + OBEX_TL_L2CAP_TRACE_ERROR("l2cap_connect_cfm but no ccb found\n"); + return; + } + + if (result == L2CAP_CONN_OK) { + btm_sec_mx_access_request(p_ccb->addr, p_ccb->vpsm, + TRUE, BTM_SEC_PROTO_OBEX, + p_ccb->allocated - 1, + &l2cap_sec_check_complete_orig, p_ccb); + } else { + OBEX_TL_L2CAP_TRACE_WARNING("l2cap_connect_cfm result != L2CAP_CONN_OK: result: 0x%x\n", result); + tOBEX_TL_MSG msg = {0}; + msg.any.hdl = p_ccb->allocated; + obex_tl_l2cap_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg); + free_ccb(p_ccb); + } +} + + +/******************************************************************************* +** +** Function obex_tl_l2cap_config_ind +** +** Description This is a callback function called by L2CAP when +** L2CA_ConfigInd received. +** +*******************************************************************************/ +void obex_tl_l2cap_config_ind(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_lcid(lcid); + if (p_ccb == NULL) { + OBEX_TL_L2CAP_TRACE_ERROR("l2cap_config_ind but no ccb found\n"); + return; + } + + tOBEX_TL_L2CAP_SCB *p_scb = find_scb_by_psm(p_ccb->vpsm); + if (p_ccb->initiator == FALSE && p_scb == NULL) { + /* not a initiator, but can not find corresponding server */ + OBEX_TL_L2CAP_TRACE_ERROR("l2cap_config_ind, not a initiator, but can not find corresponding server\n"); + return; + } + + /* save peer mtu if present */ + UINT16 peer_mtu = L2CAP_DEFAULT_MTU; + if (p_cfg->mtu_present) { + peer_mtu = p_cfg->mtu; + } + + p_cfg->mtu_present = FALSE; + p_cfg->flush_to_present = FALSE; + p_cfg->qos_present = FALSE; + p_cfg->result = L2CAP_CFG_OK; + L2CA_ConfigRsp(p_ccb->lcid, p_cfg); + + if (p_ccb->status_flag & OBEX_TL_L2CAP_STATUS_FLAG_CONNECTED) { + /* reconfig l2cap channel */ + if (p_ccb->peer_mtu != peer_mtu) { + /* only report to upper if mtu change */ + p_ccb->peer_mtu = peer_mtu; + tOBEX_TL_MSG msg = {0}; + msg.mtu_chg.hdl = p_ccb->allocated; + msg.mtu_chg.peer_mtu = peer_mtu; + msg.mtu_chg.our_mtu = p_ccb->our_mtu; + obex_tl_l2cap_cb.callback(OBEX_TL_MTU_CHANGE_EVT, &msg); + } + return; + } + + p_ccb->peer_mtu = peer_mtu; + p_ccb->status_flag |= OBEX_TL_L2CAP_STATUS_FLAG_PEER_CFG_DONE; + if (p_ccb->status_flag & OBEX_TL_L2CAP_STATUS_FLAG_CFG_DONE) { + p_ccb->status_flag |= OBEX_TL_L2CAP_STATUS_FLAG_CONNECTED; + } + + if ((p_ccb->status_flag & OBEX_TL_L2CAP_STATUS_FLAG_CONNECTED)) { + tOBEX_TL_MSG msg = {0}; + if (p_ccb->initiator) { + msg.conn_open.hdl = p_ccb->allocated; + msg.conn_open.peer_mtu = p_ccb->peer_mtu; + msg.conn_open.our_mtu = p_ccb->our_mtu; + obex_tl_l2cap_cb.callback(OBEX_TL_CONN_OPEN_EVT, &msg); + } + else { + msg.conn_income.hdl = p_ccb->allocated; + msg.conn_income.peer_mtu = p_ccb->peer_mtu; + msg.conn_income.our_mtu = p_ccb->our_mtu; + msg.conn_income.svr_hdl = p_scb->allocated << 8; + obex_tl_l2cap_cb.callback(OBEX_TL_CONN_INCOME_EVT, &msg); + } + } +} + + +/******************************************************************************* +** +** Function obex_tl_l2cap_config_cfm +** +** Description This is a callback function called by L2CAP when +** L2CA_ConfigCnf received. +** +*******************************************************************************/ +void obex_tl_l2cap_config_cfm(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_lcid(lcid); + if (p_ccb == NULL) { + OBEX_TL_L2CAP_TRACE_ERROR("l2cap_config_cfm but no ccb found\n"); + return; + } + + tOBEX_TL_L2CAP_SCB *p_scb = find_scb_by_psm(p_ccb->vpsm); + if (p_ccb->initiator == FALSE && p_scb == NULL) { + /* not a initiator, but can not find corresponding server */ + OBEX_TL_L2CAP_TRACE_ERROR("l2cap_config_cfm, not a initiator, but can not find corresponding server\n"); + return; + } + + if (p_cfg->result != L2CAP_CFG_OK) { + OBEX_TL_L2CAP_TRACE_WARNING("l2cap_config_cfm result != L2CAP_CFG_OK: result: 0x%x\n", p_cfg->result); + L2CA_DisconnectReq(p_ccb->lcid); + tOBEX_TL_MSG msg = {0}; + msg.any.hdl = p_ccb->allocated; + obex_tl_l2cap_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg); + free_ccb(p_ccb); + return; + } + + p_ccb->status_flag |= OBEX_TL_L2CAP_STATUS_FLAG_CFG_DONE; + if (p_ccb->status_flag & OBEX_TL_L2CAP_STATUS_FLAG_PEER_CFG_DONE) { + p_ccb->status_flag |= OBEX_TL_L2CAP_STATUS_FLAG_CONNECTED; + } + + if (p_ccb->status_flag & OBEX_TL_L2CAP_STATUS_FLAG_CONNECTED) { + tOBEX_TL_MSG msg = {0}; + if (p_ccb->initiator) { + msg.conn_open.hdl = p_ccb->allocated; + msg.conn_open.peer_mtu = p_ccb->peer_mtu; + msg.conn_open.our_mtu = p_ccb->our_mtu; + obex_tl_l2cap_cb.callback(OBEX_TL_CONN_OPEN_EVT, &msg); + } + else { + msg.conn_income.hdl = p_ccb->allocated; + msg.conn_income.peer_mtu = p_ccb->peer_mtu; + msg.conn_income.our_mtu = p_ccb->our_mtu; + msg.conn_income.svr_hdl = p_scb->allocated << 8; + obex_tl_l2cap_cb.callback(OBEX_TL_CONN_INCOME_EVT, &msg); + } + } +} + + +/******************************************************************************* +** +** Function obex_tl_l2cap_qos_violation_ind +** +** Description This is a callback function called by L2CAP when +** L2CA_QoSViolationIndInd received. +** +*******************************************************************************/ +void obex_tl_l2cap_qos_violation_ind(BD_ADDR addr) +{ + UNUSED(addr); +} + + +/******************************************************************************* +** +** Function obex_tl_l2cap_disconnect_ind +** +** Description This is a callback function called by L2CAP when +** L2CA_DisconnectInd received. +** +*******************************************************************************/ +void obex_tl_l2cap_disconnect_ind(UINT16 lcid, BOOLEAN is_conf_needed) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_lcid(lcid); + + if (is_conf_needed) { + L2CA_DisconnectRsp(lcid); + } + + if (p_ccb == NULL) { + OBEX_TL_L2CAP_TRACE_ERROR("l2cap_disconnect_ind but no ccb found\n"); + return; + } + + if (p_ccb->initiator && find_scb_by_psm(p_ccb->vpsm) == NULL) { + L2CA_Deregister(p_ccb->vpsm); + } + + tOBEX_TL_MSG msg = {0}; + msg.any.hdl = p_ccb->allocated; + obex_tl_l2cap_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg); + free_ccb(p_ccb); +} + + +/******************************************************************************* +** +** Function obex_tl_l2cap_buf_data_ind +** +** Description This is a callback function called by L2CAP when +** data frame is received. +** +*******************************************************************************/ +void obex_tl_l2cap_buf_data_ind(UINT16 lcid, BT_HDR *p_buf) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_lcid(lcid); + if (p_ccb == NULL) { + OBEX_TL_L2CAP_TRACE_ERROR("l2cap_buf_data_ind but no ccb found\n"); + osi_free(p_buf); + return; + } + + tOBEX_TL_MSG msg = {0}; + msg.data.hdl = p_ccb->allocated; + msg.data.p_buf = p_buf; + obex_tl_l2cap_cb.callback(OBEX_TL_DATA_EVT, &msg); +} + +/******************************************************************************* +** +** Function obex_tl_l2cap_congestion_status_ind +** +** Description This is a callback function called by L2CAP when +** L2CAP channel congestion status changes +** +*******************************************************************************/ +void obex_tl_l2cap_congestion_status_ind(UINT16 lcid, BOOLEAN is_congested) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_lcid(lcid); + + if (p_ccb == NULL) { + OBEX_TL_L2CAP_TRACE_ERROR("l2cap_congestion_status_ind but no ccb found\n"); + return; + } + + tOBEX_TL_MSG msg = {0}; + msg.any.hdl = p_ccb->allocated; + if (is_congested) { + obex_tl_l2cap_cb.callback(OBEX_TL_CONGEST_EVT, &msg); + } + else { + obex_tl_l2cap_cb.callback(OBEX_TL_UNCONGEST_EVT, &msg); + } +} + +/******************************************************************************* +** +** Function obex_tl_l2cap_init +** +** Description Initialize OBEX over L2CAP transport layer, callback +** can not be NULL, must be called once before using any +** other APIs +** +*******************************************************************************/ +void obex_tl_l2cap_init(tOBEX_TL_CBACK callback) +{ + assert(callback != NULL); +#if (OBEX_DYNAMIC_MEMORY) + if (!obex_tl_l2cap_cb_ptr) { + obex_tl_l2cap_cb_ptr = (tOBEX_TL_L2CAP_CB *)osi_malloc(sizeof(tOBEX_TL_L2CAP_CB)); + if (!obex_tl_l2cap_cb_ptr) { + OBEX_TL_L2CAP_TRACE_ERROR("OBEX over L2CAP transport layer initialize failed, no memory\n"); + assert(0); + } + } +#endif /* #if (OBEX_DYNAMIC_MEMORY) */ + memset(&obex_tl_l2cap_cb, 0, sizeof(tOBEX_TL_L2CAP_CB)); + obex_tl_l2cap_cb.callback = callback; + obex_tl_l2cap_cb.trace_level = BT_TRACE_LEVEL_ERROR; + + tL2CAP_APPL_INFO *p_reg_info = &obex_tl_l2cap_cb.l2cap_reg_info; + + p_reg_info->pL2CA_ConnectInd_Cb = NULL; /* obex_tl_l2cap_connect_ind or NULL, depend on server or not */ + p_reg_info->pL2CA_ConnectCfm_Cb = obex_tl_l2cap_connect_cfm; + p_reg_info->pL2CA_ConnectPnd_Cb = NULL; + p_reg_info->pL2CA_ConfigInd_Cb = obex_tl_l2cap_config_ind; + p_reg_info->pL2CA_ConfigCfm_Cb = obex_tl_l2cap_config_cfm; + p_reg_info->pL2CA_DisconnectInd_Cb = obex_tl_l2cap_disconnect_ind; + p_reg_info->pL2CA_DisconnectCfm_Cb = NULL; + p_reg_info->pL2CA_QoSViolationInd_Cb = obex_tl_l2cap_qos_violation_ind; + p_reg_info->pL2CA_DataInd_Cb = obex_tl_l2cap_buf_data_ind; + p_reg_info->pL2CA_CongestionStatus_Cb = obex_tl_l2cap_congestion_status_ind; + p_reg_info->pL2CA_TxComplete_Cb = NULL; +} + +/******************************************************************************* +** +** Function obex_tl_l2cap_init +** +** Description Deinitialize OBEX over L2CAP transport layer +** +*******************************************************************************/ +void obex_tl_l2cap_deinit(void) +{ +#if (OBEX_DYNAMIC_MEMORY) + if (obex_tl_l2cap_cb_ptr) { + osi_free(obex_tl_l2cap_cb_ptr); + obex_tl_l2cap_cb_ptr = NULL; + } +#endif /* #if (OBEX_DYNAMIC_MEMORY) */ +} + +/******************************************************************************* +** +** Function obex_tl_l2cap_connect +** +** Description Start the process of establishing a L2CAP connection +** +** Returns Non-zeros handle, 0 while failed +** +*******************************************************************************/ +UINT16 obex_tl_l2cap_connect(tOBEX_TL_SVR_INFO *server) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = allocate_ccb(); + if (p_ccb == NULL) { + /* can not allocate a ccb */ + return 0; + } + + if (find_scb_by_psm(server->l2cap.psm) == NULL) { + /* if the psm not register by a server, we register it as outgoing only record */ + tL2CAP_APPL_INFO *p_reg_info = &obex_tl_l2cap_cb.l2cap_reg_info; + p_reg_info->pL2CA_ConnectInd_Cb = NULL; + p_ccb->vpsm = L2CA_Register(server->l2cap.psm, p_reg_info); + if (p_ccb->vpsm == 0) { + free_ccb(p_ccb); + return 0; + } + /* set security level */ + BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_OBEX, server->l2cap.sec_mask, p_ccb->vpsm, BTM_SEC_PROTO_OBEX, p_ccb->allocated - 1); + } + else { + p_ccb->vpsm = server->l2cap.psm; + } + + if (server->l2cap.pref_mtu == 0 || server->l2cap.pref_mtu > L2CAP_MTU_SIZE) { + p_ccb->our_mtu = L2CAP_MTU_SIZE; + } + else { + p_ccb->our_mtu = server->l2cap.pref_mtu; + } + p_ccb->initiator = TRUE; + p_ccb->lcid = L2CA_ErtmConnectReq(p_ccb->vpsm, server->l2cap.addr, &obex_tl_l2cap_etm_opts); + if (p_ccb->lcid == 0) { + free_ccb(p_ccb); + return 0; + } + + return p_ccb->allocated; +} + +/******************************************************************************* +** +** Function obex_tl_l2cap_disconnect +** +** Description Disconnect a L2CAP connection +** +*******************************************************************************/ +void obex_tl_l2cap_disconnect(UINT16 hdl) +{ + tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_hdl(hdl); + if (p_ccb != NULL) { + L2CA_DisconnectReq(p_ccb->lcid); + if (p_ccb->initiator && find_scb_by_psm(p_ccb->vpsm) == NULL) { + L2CA_Deregister(p_ccb->vpsm); + } + free_ccb(p_ccb); + } +} + +/******************************************************************************* +** +** Function obex_tl_l2cap_send_data +** +** Description Start the process of establishing a L2CAP connection +** +** Returns OBEX_TL_SUCCESS, if data accepted +** OBEX_TL_CONGESTED, if data accepted and the channel is congested +** OBEX_TL_FAILED, if error +** +*******************************************************************************/ +UINT16 obex_tl_l2cap_send_data(UINT16 hdl, BT_HDR *p_buf) +{ + UINT16 ret = OBEX_TL_FAILED; + tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_hdl(hdl); + if (p_ccb == NULL) { + osi_free(p_buf); + return ret; + } + + /* Can not send data size larger than peer MTU */ + /* Offset should not smaller than L2CAP_MIN_OFFSET */ + if (p_buf->len > p_ccb->peer_mtu || p_buf->offset < L2CAP_MIN_OFFSET) { + osi_free(p_buf); + return ret; + } + + UINT16 status = L2CA_DataWrite(p_ccb->lcid, p_buf); + switch (status) + { + case L2CAP_DW_SUCCESS: + ret = OBEX_TL_SUCCESS; + break; + case L2CAP_DW_CONGESTED: + ret = OBEX_TL_CONGESTED; + break; + default: + ret = OBEX_TL_FAILED; + break; + } + return ret; +} + +/******************************************************************************* +** +** Function obex_tl_l2cap_bind +** +** Description Register a server in L2CAP module +** +** Returns Non-zeros handle, 0 while failed +** +*******************************************************************************/ +UINT16 obex_tl_l2cap_bind(tOBEX_TL_SVR_INFO *server) +{ + tOBEX_TL_L2CAP_SCB *p_scb = find_scb_by_psm(server->l2cap.psm); + + if (p_scb != NULL) { + /* psm already used */ + return 0; + } + + p_scb = allocate_scb(); + if (p_scb == NULL) { + /* can not allocate a new scb */ + return 0; + } + + if (server->l2cap.pref_mtu == 0 || server->l2cap.pref_mtu > L2CAP_MTU_SIZE) { + p_scb->pref_mtu= L2CAP_MTU_SIZE; + } + else { + p_scb->pref_mtu = server->l2cap.pref_mtu; + } + + tL2CAP_APPL_INFO *p_reg_info = &obex_tl_l2cap_cb.l2cap_reg_info; + p_reg_info->pL2CA_ConnectInd_Cb = obex_tl_l2cap_connect_ind; + /* Register a l2cap server, in this case, L2CA_Register always return the same psm as input */ + p_scb->psm = L2CA_Register(server->l2cap.psm, p_reg_info); + if (p_scb->psm == 0) { + free_scb(p_scb); + return 0; + } + /* set security level */ + BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_OBEX, server->l2cap.sec_mask, p_scb->psm, BTM_SEC_PROTO_OBEX, OBEX_TL_L2CAP_NUM_CONN + p_scb->allocated - 1); + BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_OBEX, server->l2cap.sec_mask, p_scb->psm, BTM_SEC_PROTO_OBEX, OBEX_TL_L2CAP_NUM_CONN + p_scb->allocated - 1); + /* left shift 8 bits to avoid confuse with connection handle */ + return p_scb->allocated << 8; +} + +/******************************************************************************* +** +** Function obex_tl_l2cap_unbind +** +** Description Deregister a server in L2CAP module +** +*******************************************************************************/ +void obex_tl_l2cap_unbind(UINT16 tl_hdl) +{ + tOBEX_TL_L2CAP_SCB *p_scb = find_scb_by_hdl(tl_hdl); + if (p_scb) { + tOBEX_TL_L2CAP_CCB *p_ccb = NULL; + while ((p_ccb = find_ccb_by_psm(p_scb->psm)) != NULL) { + L2CA_DisconnectReq(p_ccb->lcid); + tOBEX_TL_MSG msg = {0}; + msg.any.hdl = p_ccb->allocated; + obex_tl_l2cap_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg); + free_ccb(p_ccb); + } + L2CA_Deregister(p_scb->psm); + free_scb(p_scb); + } +} + +static tOBEX_TL_OPS obex_tl_l2cap_ops = { + .init = obex_tl_l2cap_init, + .deinit = obex_tl_l2cap_deinit, + .connect = obex_tl_l2cap_connect, + .disconnect = obex_tl_l2cap_disconnect, + .bind = obex_tl_l2cap_bind, + .unbind = obex_tl_l2cap_unbind, + .send = obex_tl_l2cap_send_data +}; + +/******************************************************************************* +** +** Function obex_tl_l2cap_ops_get +** +** Description Get the operation function structure pointer of OBEX over +** L2CAP transport layer +** +** Returns Pointer to operation function structure +** +*******************************************************************************/ +tOBEX_TL_OPS *obex_tl_l2cap_ops_get(void) +{ + return &obex_tl_l2cap_ops; +} + +#endif /* #if (OBEX_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/obex/obex_tl_rfcomm.c b/lib/bt/host/bluedroid/stack/obex/obex_tl_rfcomm.c new file mode 100644 index 00000000..ce7799c8 --- /dev/null +++ b/lib/bt/host/bluedroid/stack/obex/obex_tl_rfcomm.c @@ -0,0 +1,439 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> + +#include "osi/osi.h" +#include "osi/allocator.h" +#include "common/bt_target.h" + +#include "stack/port_api.h" +#include "stack/btm_api.h" +#include "stack/sdpdefs.h" +#include "obex_tl.h" +#include "obex_tl_rfcomm.h" + +#if (OBEX_INCLUDED == TRUE && RFCOMM_INCLUDED == TRUE) + +#define OBEX_TL_RFCOMM_NUM_CONN 4 +#define OBEX_TL_RFCOMM_NUM_SERVER 2 + +#define OBEX_TL_RFCOMM_EVENT_MARK (PORT_EV_FC | PORT_EV_FCS) + +typedef struct { + UINT16 rfc_handle; /* rfcomm handle */ + UINT16 mtu; /* rfcomm mtu */ + BOOLEAN initiator; /* TRUE if is initiator, otherwise FALSE */ + UINT8 scn; /* service channel number */ + BD_ADDR addr; /* peer bluetooth device address */ + UINT8 allocated; /* 0 if not allocated, otherwise, index + 1, equal to handle */ +} tOBEX_TL_RFCOMM_CCB; + +typedef struct { + UINT16 rfc_handle; /* rfcomm handle */ + UINT8 scn; /* service channel number */ + UINT8 allocated; /* 0 if not allocated, otherwise, index + 1, handle of server will left shift 8 bits */ +} tOBEX_TL_RFCOMM_SCB; + +typedef struct { + tOBEX_TL_CBACK *callback; /* Upper layer callback */ + tOBEX_TL_RFCOMM_CCB ccb[OBEX_TL_RFCOMM_NUM_CONN]; + tOBEX_TL_RFCOMM_SCB scb[OBEX_TL_RFCOMM_NUM_SERVER]; + UINT8 trace_level; /* trace level */ +} tOBEX_TL_RFCOMM_CB; + +#if OBEX_DYNAMIC_MEMORY == FALSE +static tOBEX_TL_RFCOMM_CB obex_tl_rfcomm_cb; +#else +static tOBEX_TL_RFCOMM_CB *obex_tl_rfcomm_cb_ptr = NULL; +#define obex_tl_rfcomm_cb (*obex_tl_rfcomm_cb_ptr) +#endif + +static tOBEX_TL_RFCOMM_CCB *allocate_ccb(void) +{ + tOBEX_TL_RFCOMM_CCB *p_ccb = NULL; + for(int i = 0; i < OBEX_TL_RFCOMM_NUM_CONN; ++i) { + if (obex_tl_rfcomm_cb.ccb[i].allocated == 0) { + obex_tl_rfcomm_cb.ccb[i].allocated = i + 1; + p_ccb = &obex_tl_rfcomm_cb.ccb[i]; + break; + } + } + return p_ccb; +} + +static tOBEX_TL_RFCOMM_SCB *allocate_scb(void) +{ + tOBEX_TL_RFCOMM_SCB *p_scb = NULL; + for(int i = 0; i < OBEX_TL_RFCOMM_NUM_SERVER; ++i) { + if (obex_tl_rfcomm_cb.scb[i].allocated == 0) { + obex_tl_rfcomm_cb.scb[i].allocated = i + 1; + p_scb = &obex_tl_rfcomm_cb.scb[i]; + break; + } + } + return p_scb; +} + +static void free_ccb(tOBEX_TL_RFCOMM_CCB *p_ccb) +{ + memset(p_ccb, 0, sizeof(tOBEX_TL_RFCOMM_CCB)); +} + +static void free_scb(tOBEX_TL_RFCOMM_SCB *p_scb) +{ + memset(p_scb, 0, sizeof(tOBEX_TL_RFCOMM_SCB)); +} + +static tOBEX_TL_RFCOMM_CCB *find_ccb_by_handle(UINT16 handle) +{ + tOBEX_TL_RFCOMM_CCB *p_ccb = NULL; + if (handle > 0 && handle <= OBEX_TL_RFCOMM_NUM_CONN) { + if (obex_tl_rfcomm_cb.ccb[handle-1].allocated == handle) { + p_ccb = &obex_tl_rfcomm_cb.ccb[handle-1]; + } + } + return p_ccb; +} + +static tOBEX_TL_RFCOMM_CCB *find_ccb_by_rfc_handle(UINT16 rfc_handle) +{ + tOBEX_TL_RFCOMM_CCB *p_ccb = NULL; + for(int i = 0; i < OBEX_TL_RFCOMM_NUM_CONN; ++i) { + if (obex_tl_rfcomm_cb.ccb[i].allocated && obex_tl_rfcomm_cb.ccb[i].rfc_handle == rfc_handle) { + p_ccb = &obex_tl_rfcomm_cb.ccb[i]; + break; + } + } + return p_ccb; +} + +static tOBEX_TL_RFCOMM_SCB *find_scb_by_handle(UINT16 handle) +{ + tOBEX_TL_RFCOMM_SCB *p_scb = NULL; + handle = handle >> 8; + if (handle > 0 && handle <= OBEX_TL_RFCOMM_NUM_SERVER) { + if (obex_tl_rfcomm_cb.scb[handle-1].allocated == handle) { + p_scb = &obex_tl_rfcomm_cb.scb[handle-1]; + } + } + return p_scb; +} + +static tOBEX_TL_RFCOMM_SCB *find_scb_by_rfc_handle(UINT16 rfc_handle) +{ + tOBEX_TL_RFCOMM_SCB *p_scb = NULL; + for(int i = 0; i < OBEX_TL_RFCOMM_NUM_SERVER; ++i) { + if (obex_tl_rfcomm_cb.scb[i].allocated && obex_tl_rfcomm_cb.scb[i].rfc_handle == rfc_handle) { + p_scb = &obex_tl_rfcomm_cb.scb[i]; + break; + } + } + return p_scb; +} + +static tOBEX_TL_RFCOMM_SCB *find_scb_by_scn(UINT16 scn) +{ + tOBEX_TL_RFCOMM_SCB *p_scb = NULL; + for(int i = 0; i < OBEX_TL_RFCOMM_NUM_SERVER; ++i) { + if (obex_tl_rfcomm_cb.scb[i].allocated && obex_tl_rfcomm_cb.scb[i].scn == scn) { + p_scb = &obex_tl_rfcomm_cb.scb[i]; + break; + } + } + return p_scb; +} + +static void rfcomm_mgmt_event_handler(tOBEX_TL_RFCOMM_CCB *p_ccb, UINT32 code) +{ + tOBEX_TL_MSG msg = {0}; + msg.any.hdl = p_ccb->allocated; + switch (code) + { + case PORT_SUCCESS: + /* event already handled, do nothing */ + break; + default: + /* other event, disconnect */ + obex_tl_rfcomm_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg); + free_ccb(p_ccb); + break; + } +} + +static void rfcomm_client_mgmt_callback(UINT32 code, UINT16 rfc_handle, void* data) +{ + tOBEX_TL_RFCOMM_CCB *p_ccb = find_ccb_by_rfc_handle(rfc_handle); + if (p_ccb == NULL) { + OBEX_TL_RFCOMM_TRACE_DEBUG("No ccb to handle rfcomm event\n"); + return; + } + /* connection opened, handle event here */ + if (code == PORT_SUCCESS) { + assert(data != NULL); + tPORT_MGMT_CL_CALLBACK_ARG *cl_mgmt_cb_arg = (tPORT_MGMT_CL_CALLBACK_ARG *)data; + p_ccb->mtu = cl_mgmt_cb_arg->peer_mtu; + + tOBEX_TL_MSG msg = {0}; + msg.conn_open.hdl = p_ccb->allocated; + msg.conn_open.peer_mtu = p_ccb->mtu; + msg.conn_open.our_mtu = p_ccb->mtu; + obex_tl_rfcomm_cb.callback(OBEX_TL_CONN_OPEN_EVT, &msg); + } + rfcomm_mgmt_event_handler(p_ccb, code); +} + +static void rfcomm_server_mgmt_callback(UINT32 code, UINT16 rfc_handle, void* data) +{ + tOBEX_TL_RFCOMM_CCB *p_ccb = NULL; + /* incoming connection, handle event here */ + if (code == PORT_SUCCESS) { + assert(data != NULL); + tOBEX_TL_RFCOMM_SCB *p_scb = find_scb_by_rfc_handle(rfc_handle); + tPORT_MGMT_SR_CALLBACK_ARG *sr_mgmt_cb_arg = (tPORT_MGMT_SR_CALLBACK_ARG *)data; + if (p_scb == NULL) { + OBEX_TL_RFCOMM_TRACE_WARNING("No scb to this rfcomm connection\n"); + /* tell rfcomm to reject this connection */ + sr_mgmt_cb_arg->accept = FALSE; + return; + } + + /* try to find p_ccb with this rfc_handle, we expect to get a NULL */ + p_ccb = find_ccb_by_rfc_handle(rfc_handle); + if (p_ccb == NULL) { + p_ccb = allocate_ccb(); + if (p_ccb == NULL) { + OBEX_TL_RFCOMM_TRACE_WARNING("can not allocate a ccb for new connection\n"); + sr_mgmt_cb_arg->accept = FALSE; + return; + } + } + else { + OBEX_TL_RFCOMM_TRACE_WARNING("found duplicate rfcomm connection\n"); + } + + p_ccb->initiator = FALSE; + p_ccb->rfc_handle = rfc_handle; + p_ccb->scn = p_scb->scn; + p_ccb->mtu = sr_mgmt_cb_arg->peer_mtu; + /* get peer bd_addr */ + PORT_CheckConnection(rfc_handle, FALSE, p_ccb->addr, NULL); + + tOBEX_TL_MSG msg = {0}; + msg.conn_income.hdl = p_ccb->allocated; + msg.conn_income.peer_mtu = p_ccb->mtu; + msg.conn_income.our_mtu = p_ccb->mtu; + msg.conn_income.svr_hdl = (p_scb->allocated << 8); + obex_tl_rfcomm_cb.callback(OBEX_TL_CONN_INCOME_EVT, &msg); + } + else { + /* other event, it means server is connected */ + p_ccb = find_ccb_by_rfc_handle(rfc_handle); + if (p_ccb == NULL) { + OBEX_TL_RFCOMM_TRACE_DEBUG("No ccb to handle rfcomm event\n"); + return; + } + } + rfcomm_mgmt_event_handler(p_ccb, code); +} + +static int rfcomm_data_callback(UINT16 rfc_handle, UINT8 *p_buf, UINT16 len, int type) +{ + tOBEX_TL_RFCOMM_CCB *p_ccb = find_ccb_by_rfc_handle(rfc_handle); + if (p_ccb != NULL && type == DATA_CO_CALLBACK_TYPE_INCOMING) { + tOBEX_TL_MSG msg = {0}; + msg.data.hdl = p_ccb->allocated; + msg.data.p_buf = (BT_HDR *)p_buf; + obex_tl_rfcomm_cb.callback(OBEX_TL_DATA_EVT, &msg); + PORT_FlowControl_GiveCredit(rfc_handle, TRUE, 1); + } + else if(p_buf != NULL) { + osi_free(p_buf); + } + return 1; +} + +static void rfcomm_event_callback(UINT32 code, UINT16 rfc_handle) +{ + tOBEX_TL_RFCOMM_CCB *p_ccb = find_ccb_by_rfc_handle(rfc_handle); + if (p_ccb == NULL) { + OBEX_TL_RFCOMM_TRACE_WARNING("No ccb to handle rfcomm event\n"); + return; + } + + if (code & PORT_EV_FC) { + tOBEX_TL_MSG msg = {0}; + msg.any.hdl = p_ccb->allocated; + if (code & PORT_EV_FCS) { + obex_tl_rfcomm_cb.callback(OBEX_TL_UNCONGEST_EVT, &msg); + } + else { + obex_tl_rfcomm_cb.callback(OBEX_TL_CONGEST_EVT, &msg); + } + } +} + +void obex_tl_rfcomm_init(tOBEX_TL_CBACK *callback) +{ + assert(callback != NULL); +#if (OBEX_DYNAMIC_MEMORY) + if (!obex_tl_rfcomm_cb_ptr) { + obex_tl_rfcomm_cb_ptr = (tOBEX_TL_RFCOMM_CB *)osi_malloc(sizeof(tOBEX_TL_RFCOMM_CB)); + if (!obex_tl_rfcomm_cb_ptr) { + OBEX_TL_RFCOMM_TRACE_ERROR("OBEX over RFCOMM transport layer initialize failed, no memory\n"); + assert(0); + } + } +#endif /* #if (OBEX_DYNAMIC_MEMORY) */ + memset(&obex_tl_rfcomm_cb, 0, sizeof(tOBEX_TL_RFCOMM_CB)); + obex_tl_rfcomm_cb.callback = callback; + obex_tl_rfcomm_cb.trace_level = BT_TRACE_LEVEL_ERROR; +} + +void obex_tl_rfcomm_deinit(void) +{ +#if (OBEX_DYNAMIC_MEMORY) + if (obex_tl_rfcomm_cb_ptr) { + osi_free(obex_tl_rfcomm_cb_ptr); + obex_tl_rfcomm_cb_ptr = NULL; + } +#endif /* #if (OBEX_DYNAMIC_MEMORY) */ +} + +UINT16 obex_tl_rfcomm_connect(tOBEX_TL_SVR_INFO *server) +{ + tOBEX_TL_RFCOMM_CCB *p_ccb = allocate_ccb(); + if (p_ccb == NULL) { + return 0; + } + + BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_OBEX, server->rfcomm.sec_mask, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, server->rfcomm.scn); + if (RFCOMM_CreateConnection(UUID_PROTOCOL_OBEX, server->rfcomm.scn, FALSE, server->rfcomm.pref_mtu, + server->rfcomm.addr, &p_ccb->rfc_handle, rfcomm_client_mgmt_callback) != PORT_SUCCESS) { + free_ccb(p_ccb); + return 0; + } + + /* set up data callback, event mask and event callback */ + PORT_SetDataCOCallback(p_ccb->rfc_handle, rfcomm_data_callback); + PORT_SetEventMask(p_ccb->rfc_handle, OBEX_TL_RFCOMM_EVENT_MARK); + PORT_SetEventCallback(p_ccb->rfc_handle, rfcomm_event_callback); + + bdcpy(p_ccb->addr, server->rfcomm.addr); + p_ccb->scn = server->rfcomm.scn; + p_ccb->initiator = TRUE; + + return p_ccb->allocated; +} + +void obex_tl_rfcomm_disconnect(UINT16 handle) +{ + tOBEX_TL_RFCOMM_CCB *p_ccb = find_ccb_by_handle(handle); + if (p_ccb != NULL) { + RFCOMM_RemoveConnection(p_ccb->rfc_handle); + free_ccb(p_ccb); + } +} + +UINT16 obex_tl_rfcomm_send(UINT16 handle, BT_HDR *p_buf) +{ + UINT16 ret = OBEX_TL_FAILED; + tOBEX_TL_RFCOMM_CCB *p_ccb = find_ccb_by_handle(handle); + do { + if (p_ccb == NULL) { + osi_free(p_buf); + break; + } + + /* Can not send data size larger than MTU */ + /* Offset should not smaller than OBEX_TL_RFCOMM_BT_HDR_MIN_OFFSET */ + if (p_buf->len > p_ccb->mtu || p_buf->offset < OBEX_TL_RFCOMM_BT_HDR_MIN_OFFSET) { + osi_free(p_buf); + break; + } + + if (PORT_Write(p_ccb->rfc_handle, p_buf) == PORT_SUCCESS) { + ret = OBEX_TL_SUCCESS; + } + } while (0); + return ret; +} + +UINT16 obex_tl_rfcomm_bind(tOBEX_TL_SVR_INFO *server) +{ + tOBEX_TL_RFCOMM_SCB *p_scb = find_scb_by_scn(server->rfcomm.scn); + if (p_scb != NULL) { + /* scn already used */ + return 0; + } + + p_scb = allocate_scb(); + if (p_scb == NULL) { + OBEX_TL_RFCOMM_TRACE_WARNING("Can not allocate scb, out of number\n"); + return 0; + } + + BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_OBEX, server->rfcomm.sec_mask, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, server->rfcomm.scn); + if (RFCOMM_CreateConnection(UUID_PROTOCOL_OBEX, server->rfcomm.scn, TRUE, server->rfcomm.pref_mtu, + server->rfcomm.addr, &p_scb->rfc_handle, rfcomm_server_mgmt_callback) != PORT_SUCCESS) { + free_scb(p_scb); + return 0; + } + + /* set up data callback, event mask and event callback */ + PORT_SetDataCOCallback(p_scb->rfc_handle, rfcomm_data_callback); + PORT_SetEventMask(p_scb->rfc_handle, OBEX_TL_RFCOMM_EVENT_MARK); + PORT_SetEventCallback(p_scb->rfc_handle, rfcomm_event_callback); + + p_scb->scn = server->rfcomm.scn; + + /* left shift 8 bits as server handle, avoid confuse with connection handle */ + return (p_scb->allocated << 8); +} + +void obex_tl_rfcomm_unbind(UINT16 handle) +{ + tOBEX_TL_RFCOMM_SCB *p_scb = find_scb_by_handle(handle); + if (p_scb) { + tOBEX_TL_RFCOMM_CCB *p_ccb = NULL; + while ((p_ccb = find_ccb_by_rfc_handle(p_scb->rfc_handle)) != NULL) { + RFCOMM_RemoveConnection(p_ccb->rfc_handle); + tOBEX_TL_MSG msg = {0}; + msg.any.hdl = p_ccb->allocated; + obex_tl_rfcomm_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg); + free_ccb(p_ccb); + } + RFCOMM_RemoveServer(p_scb->rfc_handle); + free_scb(p_scb); + } +} + +static tOBEX_TL_OPS obex_tl_rfcomm_ops = { + .init = obex_tl_rfcomm_init, + .deinit = obex_tl_rfcomm_deinit, + .connect = obex_tl_rfcomm_connect, + .disconnect = obex_tl_rfcomm_disconnect, + .bind = obex_tl_rfcomm_bind, + .unbind = obex_tl_rfcomm_unbind, + .send = obex_tl_rfcomm_send +}; + +/******************************************************************************* +** +** Function obex_tl_rfcomm_ops_get +** +** Description Get the operation function structure pointer of OBEX over +** RFCOMM transport layer +** +** Returns Pointer to operation function structure +** +*******************************************************************************/ +tOBEX_TL_OPS *obex_tl_rfcomm_ops_get(void) +{ + return &obex_tl_rfcomm_ops; +} + +#endif /* #if (OBEX_INCLUDED == TRUE && RFCOMM_INCLUDED == TRUE) */ diff --git a/lib/bt/host/bluedroid/stack/sdp/sdp_api.c b/lib/bt/host/bluedroid/stack/sdp/sdp_api.c index 0103e4de..9b477a1c 100644 --- a/lib/bt/host/bluedroid/stack/sdp/sdp_api.c +++ b/lib/bt/host/bluedroid/stack/sdp/sdp_api.c @@ -372,7 +372,7 @@ BOOLEAN SDP_FindServiceUUIDInRec(tSDP_DISC_REC *p_rec, tBT_UUID *p_uuid) if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE) { /* Look through data element sequence until no more UUIDs */ for (p_extra_sattr = p_sattr->attr_value.v.p_sub_attr; p_extra_sattr; p_extra_sattr = p_extra_sattr->p_next_attr) { - /* Increment past this to see if the next attribut is UUID */ + /* Increment past this to see if the next attribute is UUID */ if ((SDP_DISC_ATTR_TYPE(p_extra_sattr->attr_len_type) == UUID_DESC_TYPE) /* only support 16 bits UUID for now */ && (SDP_DISC_ATTR_LEN(p_extra_sattr->attr_len_type) == 2)) { @@ -522,7 +522,7 @@ tSDP_DISC_REC *SDP_FindServiceInDb (tSDP_DISCOVERY_DB *p_db, UINT16 service_uuid if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE) { /* Look through data element sequence until no more UUIDs */ for (p_extra_sattr = p_sattr->attr_value.v.p_sub_attr; p_extra_sattr; p_extra_sattr = p_extra_sattr->p_next_attr) { - /* Increment past this to see if the next attribut is UUID */ + /* Increment past this to see if the next attribute is UUID */ if ((SDP_DISC_ATTR_TYPE(p_extra_sattr->attr_len_type) == UUID_DESC_TYPE) && (SDP_DISC_ATTR_LEN(p_extra_sattr->attr_len_type) == 2) /* for a specific uuid, or any one */ @@ -768,6 +768,28 @@ BOOLEAN SDP_FindProtocolListElemInRec (tSDP_DISC_REC *p_rec, UINT16 layer_uuid, return (FALSE); } +/******************************************************************************* +** +** Function SDP_FindProtocolListElem +** +** Description This function looks at the protocol list for a specific protocol +** list element. +** +** Returns TRUE if found, FALSE if not +** If found, the passed protocol list element is filled in. +** +*******************************************************************************/ +BOOLEAN SDP_FindProtocolListElem (tSDP_DISC_ATTR *p_protocol_list, UINT16 layer_uuid, tSDP_PROTOCOL_ELEM *p_elem) +{ +#if SDP_CLIENT_ENABLED == TRUE + /* don't check the input protocol descriptor list id, this api may be use in additional protocol descriptor list */ + if ((SDP_DISC_ATTR_TYPE(p_protocol_list->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE)) { + return sdp_fill_proto_elem(p_protocol_list, layer_uuid, p_elem); + } +#endif + /* If here, no match found */ + return (FALSE); +} /******************************************************************************* ** diff --git a/lib/bt/host/bluedroid/stack/sdp/sdp_db.c b/lib/bt/host/bluedroid/stack/sdp/sdp_db.c index a9b3daa4..60dd04a6 100644 --- a/lib/bt/host/bluedroid/stack/sdp/sdp_db.c +++ b/lib/bt/host/bluedroid/stack/sdp/sdp_db.c @@ -276,7 +276,7 @@ static int sdp_compose_proto_list( UINT8 *p, UINT16 num_elem, ** ** Description This function is called to create a record in the database. ** This would be through the SDP database maintenance API. The -** record is created empty, teh application should then call +** record is created empty, the application should then call ** "add_attribute" to add the record's attributes. ** ** Returns Record handle if OK, else 0. @@ -293,15 +293,15 @@ UINT32 SDP_CreateRecord (void) /* First, check if there is a free record */ if (p_db->num_records < SDP_MAX_RECORDS) { - p_rec =(tSDP_RECORD *)osi_malloc(sizeof(tSDP_RECORD)); - if (p_rec) { - memset(p_rec, 0, sizeof(tSDP_RECORD)); - /* Save previous rec */ - if (p_db->num_records) { - p_rec_prev = list_back(p_db->p_record_list); - } - /* Append new record */ - list_append(p_db->p_record_list, p_rec); + p_rec = (tSDP_RECORD *)osi_malloc(sizeof(tSDP_RECORD)); + if (p_rec) { + memset(p_rec, 0, sizeof(tSDP_RECORD)); + /* Save previous rec */ + if (p_db->num_records) { + p_rec_prev = list_back(p_db->p_record_list); + } + /* Append new record */ + list_append(p_db->p_record_list, p_rec); /* We will use a handle of the first unreserved handle plus last record ** number + 1 */ @@ -321,10 +321,12 @@ UINT32 SDP_CreateRecord (void) 4, buf); return (p_rec->record_handle); - } else { + } + else { SDP_TRACE_ERROR("SDP_CreateRecord fail, memory allocation failed\n"); - } - } else { + } + } + else { SDP_TRACE_ERROR("SDP_CreateRecord fail, exceed maximum records:%d\n", SDP_MAX_RECORDS); } #endif @@ -354,17 +356,17 @@ BOOLEAN SDP_DeleteRecord (UINT32 handle) if (handle == 0 || sdp_cb.server_db.num_records == 0) { /* Delete all records in the database */ sdp_cb.server_db.num_records = 0; - for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { - list_remove(sdp_cb.server_db.p_record_list, p_node); - } + for (p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { + list_remove(sdp_cb.server_db.p_record_list, p_node); + } /* require new DI record to be created in SDP_SetLocalDiRecord */ sdp_cb.server_db.di_primary_handle = 0; return (TRUE); } else { /* Find the record in the database */ - for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { - p_rec = list_node(p_node); + for (p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { + p_rec = list_node(p_node); if (p_rec->record_handle == handle) { /* Found it. Shift everything up one */ list_remove(sdp_cb.server_db.p_record_list, p_rec); @@ -374,7 +376,7 @@ BOOLEAN SDP_DeleteRecord (UINT32 handle) SDP_TRACE_DEBUG("SDP_DeleteRecord ok, num_records:%d\n", sdp_cb.server_db.num_records); /* if we're deleting the primary DI record, clear the */ /* value in the control block */ - if ( sdp_cb.server_db.di_primary_handle == handle ) { + if (sdp_cb.server_db.di_primary_handle == handle) { sdp_cb.server_db.di_primary_handle = 0; } diff --git a/lib/bt/host/bluedroid/stack/sdp/sdp_discovery.c b/lib/bt/host/bluedroid/stack/sdp/sdp_discovery.c index d63b164d..31ab11f4 100644 --- a/lib/bt/host/bluedroid/stack/sdp/sdp_discovery.c +++ b/lib/bt/host/bluedroid/stack/sdp/sdp_discovery.c @@ -453,7 +453,7 @@ static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) } } - /* Now, ask for the next handle. Re-use the buffer we just got. */ + /* Now, ask for the next handle. Reuse the buffer we just got. */ if (p_ccb->cur_handle < p_ccb->num_handles) { BT_HDR *p_msg = (BT_HDR *) osi_malloc(SDP_DATA_BUF_SIZE); UINT8 *p; @@ -669,6 +669,7 @@ static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) if ((type >> 3) != DATA_ELE_SEQ_DESC_TYPE) { SDP_TRACE_WARNING ("SDP - Wrong type: 0x%02x in attr_rsp\n", type); + sdp_disconnect (p_ccb, SDP_ILLEGAL_PARAMETER); return; } p = sdpu_get_len_from_type (p, type, &seq_len); diff --git a/lib/bt/host/bluedroid/stack/smp/smp_act.c b/lib/bt/host/bluedroid/stack/smp/smp_act.c index 0e7dcd5b..43b2e476 100644 --- a/lib/bt/host/bluedroid/stack/smp/smp_act.c +++ b/lib/bt/host/bluedroid/stack/smp/smp_act.c @@ -1553,7 +1553,7 @@ void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) } /* Disable L2CAP connection parameter updates while bonding since some peripherals are not able to revert to fast connection parameters - during the start of service discovery. Connection paramter updates + during the start of service discovery. Connection parameter updates get enabled again once service discovery completes. */ #if (BT_MULTI_CONNECTION_ENBALE == FALSE) L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE); @@ -1648,6 +1648,8 @@ void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) /* slave calculates and sends local commitment */ smp_calculate_local_commitment(p_cb); smp_send_commitment(p_cb, NULL); + /* Ensure the connection is still active */ + if (smp_get_state() == SMP_STATE_IDLE) return; /* slave has to wait for peer nonce */ smp_set_state(SMP_STATE_WAIT_NONCE); } else { /* i.e. master */ @@ -1658,6 +1660,8 @@ void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) p_cb->selected_association_model); p_cb->flags &= ~SMP_PAIR_FLAG_HAVE_PEER_COMM; smp_send_rand(p_cb, NULL); + /* Ensure the connection is still active */ + if (smp_get_state() == SMP_STATE_IDLE) return; smp_set_state(SMP_STATE_WAIT_NONCE); } } @@ -1672,6 +1676,8 @@ void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) if (p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_COMM) { /* master commitment is already received */ smp_send_commitment(p_cb, NULL); + /* Ensure the connection is still active */ + if (smp_get_state() == SMP_STATE_IDLE) return; smp_set_state(SMP_STATE_WAIT_NONCE); } } @@ -1679,6 +1685,8 @@ void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) case SMP_MODEL_SEC_CONN_OOB: if (p_cb->role == HCI_ROLE_MASTER) { smp_send_rand(p_cb, NULL); + /* Ensure the connection is still active */ + if (smp_get_state() == SMP_STATE_IDLE) return; } smp_set_state(SMP_STATE_WAIT_NONCE); @@ -2002,7 +2010,7 @@ void smp_link_encrypted(BD_ADDR bda, UINT8 encr_enable) SMP_TRACE_DEBUG("%s encr_enable=%d\n", __func__, encr_enable); if (memcmp(&smp_cb.pairing_bda[0], bda, BD_ADDR_LEN) == 0) { - /* encryption completed with STK, remmeber the key size now, could be overwite + /* encryption completed with STK, remember the key size now, could be overwrite * when key exchange happens */ if (p_cb->loc_enc_size != 0 && encr_enable) { /* update the link encryption key size if a SMP pairing just performed */ diff --git a/lib/bt/host/bluedroid/stack/smp/smp_utils.c b/lib/bt/host/bluedroid/stack/smp/smp_utils.c index 2e9fac77..48ba6c0a 100644 --- a/lib/bt/host/bluedroid/stack/smp/smp_utils.c +++ b/lib/bt/host/bluedroid/stack/smp/smp_utils.c @@ -331,8 +331,7 @@ BOOLEAN smp_send_msg_to_L2CAP(BD_ADDR rem_bda, BT_HDR *p_toL2CAP) if ((l2cap_ret = L2CA_SendFixedChnlData (fixed_cid, rem_bda, p_toL2CAP)) == L2CAP_DW_FAILED) { smp_cb.total_tx_unacked -= 1; - SMP_TRACE_ERROR("SMP failed to pass msg:0x%0x to L2CAP", - *((UINT8 *)(p_toL2CAP + 1) + p_toL2CAP->offset)); + SMP_TRACE_ERROR("SMP failed to pass msg to L2CAP"); return FALSE; } else { return TRUE; @@ -1125,7 +1124,7 @@ BOOLEAN smp_pairing_request_response_parameters_are_valid(tSMP_CB *p_cb) SMP_TRACE_DEBUG("%s for cmd code 0x%02x\n", __func__, p_cb->rcvd_cmd_code); if (io_caps >= BTM_IO_CAP_MAX) { - SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with IO Capabilty \ + SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with IO Capability \ value (0x%02x) out of range).\n", p_cb->rcvd_cmd_code, io_caps); return FALSE; |
