From 278763a88385567491023bc760a426c0ef5cdf5b Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Thu, 26 Mar 2026 17:23:39 +0800 Subject: [PATCH] feat(ble/bluedroid): support adv monitor feature (cherry picked from commit 1566a509298dee14114f8579f529e08baf996f17) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/Kconfig.in | 9 ++ .../bt/host/bluedroid/api/esp_gap_ble_api.c | 92 +++++++++++++ .../api/include/api/esp_gap_ble_api.h | 127 ++++++++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 37 +++++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 75 +++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 7 + .../bluedroid/bta/dm/include/bta_dm_int.h | 51 +++++++ .../host/bluedroid/bta/include/bta/bta_api.h | 16 +++ .../btc/profile/std/gap/btc_gap_ble.c | 54 ++++++++ .../btc/profile/std/include/btc_gap_ble.h | 25 +++- .../include/common/bluedroid_user_config.h | 6 + .../common/include/common/bt_target.h | 7 + .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 119 ++++++++++++++++ .../bluedroid/stack/btm/include/btm_ble_int.h | 4 + .../bt/host/bluedroid/stack/btu/btu_hcif.c | 30 +++++ .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 81 +++++++++++ .../stack/include/stack/btm_ble_api.h | 35 ++++- .../bluedroid/stack/include/stack/hcidefs.h | 13 ++ .../bluedroid/stack/include/stack/hcimsgs.h | 14 ++ 19 files changed, 800 insertions(+), 2 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 344a6c49ea..77e0750031 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1433,6 +1433,15 @@ config BT_BLE_FEAT_CHANNEL_SOUNDING help Enable BLE channel sounding +config BT_BLE_FEAT_ADV_MONITOR + bool "Enable BLE Advertising Monitor (LE Monitor Advertisement)" + depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_ADV_MONITOR_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR + default n + help + Enable LE Monitor Advertisement feature (Bluetooth Core 6.0). + Allows the host to add devices to a monitor list and receive reports when + the controller detects advertising from those devices (e.g. RSSI threshold). + menuconfig BT_BLE_42_FEATURES_SUPPORTED bool "Enable BLE 4.2 features(please disable BLE 5.0 if enable BLE 4.2)" depends on BT_BLE_ENABLED diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 7dfe9dd3dd..f22e87a741 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -1691,6 +1691,98 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, } +#if (BLE_FEAT_ADV_MONITOR == TRUE) +esp_err_t esp_ble_gap_add_monitor_adv_list(const esp_ble_gap_add_monitor_adv_params_t *params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (params == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ADD_MONITOR_ADV_LIST; + arg.add_monitor_adv_list.addr_type = params->addr_type; + memcpy(arg.add_monitor_adv_list.addr, params->addr, sizeof(esp_bd_addr_t)); + arg.add_monitor_adv_list.rssi_low = params->rssi_low; + arg.add_monitor_adv_list.rssi_high = params->rssi_high; + arg.add_monitor_adv_list.timeout = params->timeout; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_remove_monitor_adv_list(const esp_ble_gap_remove_monitor_adv_params_t *params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (params == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_RMV_MONITOR_ADV_LIST; + arg.rmv_monitor_adv_list.addr_type = params->addr_type; + memcpy(arg.rmv_monitor_adv_list.addr, params->addr, sizeof(esp_bd_addr_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_clear_monitor_adv_list(void) +{ + btc_msg_t msg = {0}; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CLEAR_MONITOR_ADV_LIST; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_read_monitor_adv_list_size(void) +{ + btc_msg_t msg = {0}; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_READ_MONITOR_ADV_LIST_SIZE; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_enable_monitor_adv(bool enable) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ENABLE_MONITOR_ADV; + arg.enable_monitor_adv.enable = enable ? 1 : 0; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 0159e28abc..6e292d7c4e 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -267,6 +267,12 @@ typedef enum { ESP_GAP_BLE_CS_CONFIG_CMPL_EVT, /*!< When CS has completed the Channel Sounding Configuration procedure, the event comes */ ESP_GAP_BLE_CS_SUBEVENT_RESULT_EVT, /*!< When CS has results to report for a CS subevent during the CS procedure, the event comes */ ESP_GAP_BLE_CS_SUBEVENT_RESULT_CONTINUE_EVT, /*!< When CS has completed a new CS subevent measurement, the event comes */ + ESP_GAP_BLE_MONITOR_ADV_REPORT_EVT, /*!< When LE monitor advertisement report (RSSI threshold etc), the event comes */ + ESP_GAP_BLE_ADD_MONITOR_ADV_COMPLETE_EVT, /*!< When add monitor advertiser complete, the event comes */ + ESP_GAP_BLE_REMOVE_MONITOR_ADV_COMPLETE_EVT, /*!< When remove monitor advertiser complete, the event comes */ + ESP_GAP_BLE_CLEAR_MONITOR_ADV_COMPLETE_EVT, /*!< When clear monitor advertiser list complete, the event comes */ + ESP_GAP_BLE_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT, /*!< When read monitor advertiser list size complete, the event comes */ + ESP_GAP_BLE_ENABLE_MONITOR_ADV_COMPLETE_EVT, /*!< When enable/disable monitor advertising complete, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -1212,6 +1218,27 @@ typedef struct { } esp_ble_gap_past_params_t; #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) +/** + * @brief Parameters for adding a device to the LE Monitor Advertisers list + */ +typedef struct { + esp_ble_addr_type_t addr_type; /*!< Address type of the advertiser */ + esp_bd_addr_t addr; /*!< Device address of the advertiser to monitor */ + int8_t rssi_low; /*!< Low threshold of RSSI (dBm). Report when RSSI goes at or below this value */ + int8_t rssi_high; /*!< High threshold of RSSI (dBm). Report when RSSI goes at or above this value */ + uint8_t timeout; /*!< Monitor timeout: 0 = no timeout; 1–0xFF = timeout in seconds */ +} esp_ble_gap_add_monitor_adv_params_t; + +/** + * @brief Parameters for removing a device from the LE Monitor Advertisers list + */ +typedef struct { + esp_ble_addr_type_t addr_type; /*!< Address type of the advertiser */ + esp_bd_addr_t addr; /*!< Device address of the advertiser to remove from the monitor list */ +} esp_ble_gap_remove_monitor_adv_params_t; +#endif // (BLE_FEAT_ADV_MONITOR == TRUE) + typedef enum { ESP_BLE_NETWORK_PRIVACY_MODE = 0X00, /*!< Network Privacy Mode for peer device (default) */ ESP_BLE_DEVICE_PRIVACY_MODE = 0X01, /*!< Device Privacy Mode for peer device */ @@ -2124,6 +2151,47 @@ typedef union { esp_ble_addr_type_t scan_addr_type; /*!< scanner address type */ esp_bd_addr_t scan_addr; /*!< scanner address */ } scan_req_received; /*!< Event parameter of ESP_GAP_BLE_SCAN_REQ_RECEIVED_EVT */ +#if (BLE_FEAT_ADV_MONITOR == TRUE) + /** + * @brief ESP_GAP_BLE_MONITOR_ADV_REPORT_EVT + */ + struct ble_monitor_adv_report_param { + esp_ble_addr_type_t addr_type; /*!< address type */ + esp_bd_addr_t addr; /*!< advertiser address */ + uint8_t condition; /*!< RSSI threshold condition (e.g. entered/left range) */ + } monitor_adv_report; /*!< Event parameter of ESP_GAP_BLE_MONITOR_ADV_REPORT_EVT */ + /** + * @brief ESP_GAP_BLE_ADD_MONITOR_ADV_COMPLETE_EVT + */ + struct ble_add_monitor_adv_cmpl_param { + esp_bt_status_t status; /*!< Indicate add monitor advertiser operation success status */ + } add_monitor_adv; /*!< Event parameter of ESP_GAP_BLE_ADD_MONITOR_ADV_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_REMOVE_MONITOR_ADV_COMPLETE_EVT + */ + struct ble_remove_monitor_adv_cmpl_param { + esp_bt_status_t status; /*!< Indicate remove monitor advertiser operation success status */ + } remove_monitor_adv; /*!< Event parameter of ESP_GAP_BLE_REMOVE_MONITOR_ADV_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_CLEAR_MONITOR_ADV_COMPLETE_EVT + */ + struct ble_clear_monitor_adv_cmpl_param { + esp_bt_status_t status; /*!< Indicate clear monitor advertiser list operation success status */ + } clear_monitor_adv; /*!< Event parameter of ESP_GAP_BLE_CLEAR_MONITOR_ADV_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT + */ + struct ble_read_monitor_adv_list_size_cmpl_param { + esp_bt_status_t status; /*!< Indicate read monitor advertiser list size operation success status */ + uint8_t list_size; /*!< Monitor advertiser list capacity */ + } read_monitor_adv_list_size; /*!< Event parameter of ESP_GAP_BLE_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_ENABLE_MONITOR_ADV_COMPLETE_EVT + */ + struct ble_enable_monitor_adv_cmpl_param { + esp_bt_status_t status; /*!< Indicate enable/disable monitor advertising operation success status */ + } enable_monitor_adv; /*!< Event parameter of ESP_GAP_BLE_ENABLE_MONITOR_ADV_COMPLETE_EVT */ +#endif /** * @brief ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT */ @@ -3901,6 +3969,65 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, const esp_ble_gap_conn_params_t *phy_1m_conn_params, const esp_ble_gap_conn_params_t *phy_2m_conn_params, const esp_ble_gap_conn_params_t *phy_coded_conn_params); + +#if (BLE_FEAT_ADV_MONITOR == TRUE) +/** +* @brief This function is used to add a single device to the list of Monitored Advertisers in the Controller. +* When the Controller receives advertising that matches the address and meets the RSSI threshold condition, +* it will send an LE Monitor Advertising Report event (ESP_GAP_BLE_MONITOR_ADV_REPORT_EVT). +* +* @param[in] params : Pointer to parameters (addr_type, addr, rssi_low, rssi_high, timeout). Reserved fields allow future extension. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_add_monitor_adv_list(const esp_ble_gap_add_monitor_adv_params_t *params); + +/** +* @brief This function is used to remove one device from the list of Monitored Advertisers in the Controller. +* Removals take effect immediately. +* +* @param[in] params : Pointer to parameters (addr_type, addr). Reserved fields allow future extension. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_remove_monitor_adv_list(const esp_ble_gap_remove_monitor_adv_params_t *params); + +/** +* @brief This function is used to remove all devices from the list of Monitored Advertisers in the Controller. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_clear_monitor_adv_list(void); + +/** +* @brief This function is used to read the capacity of the list of Monitored Advertisers in the Controller. +* The HCI command is sent asynchronously; the list size is reported via command complete if needed. +* +* @return - ESP_OK : success (command sent) +* - other : failed +* +*/ +esp_err_t esp_ble_gap_read_monitor_adv_list_size(void); + +/** +* @brief This function is used to enable or disable the reporting of LE Monitor Advertising Report events. +* When enabled, the Controller will generate ESP_GAP_BLE_MONITOR_ADV_REPORT_EVT when advertising +* from devices in the monitor list meets the configured RSSI threshold condition. +* +* @param[in] enable : true to enable monitor advertising reports, false to disable +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_enable_monitor_adv(bool enable); +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 6fccb65b02..85c2ca8354 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5837,6 +5837,43 @@ void bta_dm_ble_gap_set_periodic_adv_sync_trans_params(tBTA_DM_MSG *p_data) } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) +void bta_dm_ble_gap_add_monitor_adv_list(tBTA_DM_MSG *p_data) +{ + APPL_TRACE_API("%s, addr_type = %d", __func__, p_data->ble_add_monitor_adv_list.addr_type); + BTM_BleAddMonitorAdvList(p_data->ble_add_monitor_adv_list.addr_type, + p_data->ble_add_monitor_adv_list.addr, + p_data->ble_add_monitor_adv_list.rssi_low, + p_data->ble_add_monitor_adv_list.rssi_high, + p_data->ble_add_monitor_adv_list.timeout); +} + +void bta_dm_ble_gap_rmv_monitor_adv_list(tBTA_DM_MSG *p_data) +{ + APPL_TRACE_API("%s, addr_type = %d", __func__, p_data->ble_rmv_monitor_adv_list.addr_type); + BTM_BleRemoveMonitorAdvList(p_data->ble_rmv_monitor_adv_list.addr_type, + p_data->ble_rmv_monitor_adv_list.addr); +} + +void bta_dm_ble_gap_clear_monitor_adv_list(tBTA_DM_MSG *p_data) +{ + APPL_TRACE_API("%s", __func__); + BTM_BleClearMonitorAdvList(); +} + +void bta_dm_ble_gap_read_monitor_adv_list_size(tBTA_DM_MSG *p_data) +{ + APPL_TRACE_API("%s", __func__); + BTM_BleReadMonitorAdvListSize(); +} + +void bta_dm_ble_gap_enable_monitor_adv(tBTA_DM_MSG *p_data) +{ + APPL_TRACE_API("%s, enable = %d", __func__, p_data->ble_enable_monitor_adv.enable); + BTM_BleEnableMonitorAdv(p_data->ble_enable_monitor_adv.enable); +} +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) void bta_dm_ble_big_create(tBTA_DM_MSG *p_data) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 85428083df..94055dcd0e 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -3197,6 +3197,81 @@ void BTA_DmBleGapSetPeriodicAdvSyncTransParams(BD_ADDR peer_addr, tBTA_DM_BLE_PA } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) +void BTA_DmBleGapAddMonitorAdvList(UINT8 addr_type, BD_ADDR addr, INT8 rssi_low, INT8 rssi_high, UINT8 timeout) +{ + tBTA_DM_API_ADD_MONITOR_ADV_LIST *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_ADD_MONITOR_ADV_LIST *) osi_malloc(sizeof(tBTA_DM_API_ADD_MONITOR_ADV_LIST))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_ADD_MONITOR_ADV_LIST)); + p_msg->hdr.event = BTA_DM_API_ADD_MONITOR_ADV_LIST_EVT; + p_msg->addr_type = addr_type; + memcpy(p_msg->addr, addr, sizeof(BD_ADDR)); + p_msg->rssi_low = rssi_low; + p_msg->rssi_high = rssi_high; + p_msg->timeout = timeout; + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleGapRemoveMonitorAdvList(UINT8 addr_type, BD_ADDR addr) +{ + tBTA_DM_API_RMV_MONITOR_ADV_LIST *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_RMV_MONITOR_ADV_LIST *) osi_malloc(sizeof(tBTA_DM_API_RMV_MONITOR_ADV_LIST))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_RMV_MONITOR_ADV_LIST)); + p_msg->hdr.event = BTA_DM_API_RMV_MONITOR_ADV_LIST_EVT; + p_msg->addr_type = addr_type; + memcpy(p_msg->addr, addr, sizeof(BD_ADDR)); + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleGapClearMonitorAdvList(void) +{ + tBTA_DM_API_CLEAR_MONITOR_ADV_LIST *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_CLEAR_MONITOR_ADV_LIST *) osi_malloc(sizeof(tBTA_DM_API_CLEAR_MONITOR_ADV_LIST))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_CLEAR_MONITOR_ADV_LIST)); + p_msg->hdr.event = BTA_DM_API_CLEAR_MONITOR_ADV_LIST_EVT; + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleGapReadMonitorAdvListSize(void) +{ + tBTA_DM_API_READ_MONITOR_ADV_LIST_SIZE *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_READ_MONITOR_ADV_LIST_SIZE *) osi_malloc(sizeof(tBTA_DM_API_READ_MONITOR_ADV_LIST_SIZE))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_READ_MONITOR_ADV_LIST_SIZE)); + p_msg->hdr.event = BTA_DM_API_READ_MONITOR_ADV_LIST_SIZE_EVT; + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleGapEnableMonitorAdv(UINT8 enable) +{ + tBTA_DM_API_ENABLE_MONITOR_ADV *p_msg; + APPL_TRACE_API("%s, enable = %d", __func__, enable); + if ((p_msg = (tBTA_DM_API_ENABLE_MONITOR_ADV *) osi_malloc(sizeof(tBTA_DM_API_ENABLE_MONITOR_ADV))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_ENABLE_MONITOR_ADV)); + p_msg->hdr.event = BTA_DM_API_ENABLE_MONITOR_ADV_EVT; + p_msg->enable = enable; + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) void BTA_DmBleGapIsoBigCreate(tBTA_DM_BLE_BIG_CREATE_PARAMS *p_big_creat_param) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index ae04d84dc9..feb2fd5b8f 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -227,6 +227,13 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_gap_periodic_adv_set_info_trans, /* BTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS_EVT */ bta_dm_ble_gap_set_periodic_adv_sync_trans_params, /* BTA_DM_API_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS_EVT */ #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) + bta_dm_ble_gap_add_monitor_adv_list, /* BTA_DM_API_ADD_MONITOR_ADV_LIST_EVT */ + bta_dm_ble_gap_rmv_monitor_adv_list, /* BTA_DM_API_RMV_MONITOR_ADV_LIST_EVT */ + bta_dm_ble_gap_clear_monitor_adv_list, /* BTA_DM_API_CLEAR_MONITOR_ADV_LIST_EVT */ + bta_dm_ble_gap_read_monitor_adv_list_size, /* BTA_DM_API_READ_MONITOR_ADV_LIST_SIZE_EVT */ + bta_dm_ble_gap_enable_monitor_adv, /* BTA_DM_API_ENABLE_MONITOR_ADV_EVT */ +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) #if BLE_INCLUDED == TRUE #if (BLE_42_DTM_TEST_EN == TRUE) bta_dm_ble_gap_dtm_tx_start, /* BTA_DM_API_DTM_TX_START_EVT */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index a7b7527f2b..4c32608984 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -223,6 +223,13 @@ enum { BTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS_EVT, BTA_DM_API_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS_EVT, #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) + BTA_DM_API_ADD_MONITOR_ADV_LIST_EVT, + BTA_DM_API_RMV_MONITOR_ADV_LIST_EVT, + BTA_DM_API_CLEAR_MONITOR_ADV_LIST_EVT, + BTA_DM_API_READ_MONITOR_ADV_LIST_SIZE_EVT, + BTA_DM_API_ENABLE_MONITOR_ADV_EVT, +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) #if BLE_INCLUDED == TRUE #if (BLE_42_DTM_TEST_EN == TRUE) BTA_DM_API_DTM_TX_START_EVT, @@ -1363,6 +1370,35 @@ typedef struct { BT_HDR hdr; } tBTA_DM_API_PERIODIC_ADV_DEV_CLEAR; +#if (BLE_FEAT_ADV_MONITOR == TRUE) +typedef struct { + BT_HDR hdr; + UINT8 addr_type; + BD_ADDR addr; + INT8 rssi_low; + INT8 rssi_high; + UINT8 timeout; +} tBTA_DM_API_ADD_MONITOR_ADV_LIST; + +typedef struct { + BT_HDR hdr; + UINT8 addr_type; + BD_ADDR addr; +} tBTA_DM_API_RMV_MONITOR_ADV_LIST; + +typedef struct { + BT_HDR hdr; +} tBTA_DM_API_CLEAR_MONITOR_ADV_LIST; + +typedef struct { + BT_HDR hdr; +} tBTA_DM_API_READ_MONITOR_ADV_LIST_SIZE; + +typedef struct { + BT_HDR hdr; + UINT8 enable; +} tBTA_DM_API_ENABLE_MONITOR_ADV; +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) typedef struct { BT_HDR hdr; @@ -1790,6 +1826,13 @@ typedef union { tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS ble_periodic_adv_set_info_trans; tBTA_DM_API_SET_PAST_PARAMS ble_set_past_params; #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) + tBTA_DM_API_ADD_MONITOR_ADV_LIST ble_add_monitor_adv_list; + tBTA_DM_API_RMV_MONITOR_ADV_LIST ble_rmv_monitor_adv_list; + tBTA_DM_API_CLEAR_MONITOR_ADV_LIST ble_clear_monitor_adv_list; + tBTA_DM_API_READ_MONITOR_ADV_LIST_SIZE ble_read_monitor_adv_list_size; + tBTA_DM_API_ENABLE_MONITOR_ADV ble_enable_monitor_adv; +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) #if (BLE_42_DTM_TEST_EN == TRUE) tBTA_DM_API_BLE_DTM_TX_START dtm_tx_start; tBTA_DM_API_BLE_DTM_RX_START dtm_rx_start; @@ -2458,6 +2501,14 @@ extern void bta_dm_ble_gap_periodic_adv_set_info_trans(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_set_periodic_adv_sync_trans_params(tBTA_DM_MSG *p_data); #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) +extern void bta_dm_ble_gap_add_monitor_adv_list(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_rmv_monitor_adv_list(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_clear_monitor_adv_list(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_read_monitor_adv_list_size(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_enable_monitor_adv(tBTA_DM_MSG *p_data); +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) extern void bta_dm_ble_big_create(tBTA_DM_MSG *p_data); diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 2a4057f9db..f8c3707b9c 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1621,6 +1621,14 @@ typedef struct { #if (BLE_50_FEATURE_SUPPORT == TRUE) #define BTA_BLE_GAP_SET_HOST_FEATURE_EVT BTM_BLE_GAP_SET_HOST_FEATURE_EVT #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) +#define BTA_DM_BLE_5_GAP_MONITOR_ADV_REPORT_EVT BTM_BLE_5_GAP_MONITOR_ADV_REPORT_EVT +#define BTA_DM_BLE_5_GAP_ADD_MONITOR_ADV_COMPLETE_EVT BTM_BLE_5_GAP_ADD_MONITOR_ADV_COMPLETE_EVT +#define BTA_DM_BLE_5_GAP_REMOVE_MONITOR_ADV_COMPLETE_EVT BTM_BLE_5_GAP_REMOVE_MONITOR_ADV_COMPLETE_EVT +#define BTA_DM_BLE_5_GAP_CLEAR_MONITOR_ADV_COMPLETE_EVT BTM_BLE_5_GAP_CLEAR_MONITOR_ADV_COMPLETE_EVT +#define BTA_DM_BLE_5_GAP_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT BTM_BLE_5_GAP_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT +#define BTA_DM_BLE_5_GAP_ENABLE_MONITOR_ADV_COMPLETE_EVT BTM_BLE_5_GAP_ENABLE_MONITOR_ADV_COMPLETE_EVT +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) #define BTA_BLE_GAP_SET_PERIODIC_ADV_SUBEVT_DATA_EVT BTM_BLE_GAP_SET_PERIODIC_ADV_SUBEVT_DATA_EVT @@ -3100,6 +3108,14 @@ extern void BTA_DmBleGapPeriodicAdvSetInfoTrans(BD_ADDR peer_addr, UINT16 servic extern void BTA_DmBleGapSetPeriodicAdvSyncTransParams(BD_ADDR peer_addr, tBTA_DM_BLE_PAST_PARAMS *params); #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) +extern void BTA_DmBleGapAddMonitorAdvList(UINT8 addr_type, BD_ADDR addr, INT8 rssi_low, INT8 rssi_high, UINT8 timeout); +extern void BTA_DmBleGapRemoveMonitorAdvList(UINT8 addr_type, BD_ADDR addr); +extern void BTA_DmBleGapClearMonitorAdvList(void); +extern void BTA_DmBleGapReadMonitorAdvListSize(void); +extern void BTA_DmBleGapEnableMonitorAdv(UINT8 enable); +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) extern void BTA_DmBleGapIsoBigCreate(tBTA_DM_BLE_BIG_CREATE_PARAMS *p_big_creat_param); diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index a2de8a07ce..c557e1b52b 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -1126,6 +1126,41 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, msg.act = ESP_GAP_BLE_SCAN_TIMEOUT_EVT; break; #endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) + case BTA_DM_BLE_5_GAP_MONITOR_ADV_REPORT_EVT: { + msg.act = ESP_GAP_BLE_MONITOR_ADV_REPORT_EVT; + param.monitor_adv_report.addr_type = params->monitor_adv_report.addr_type; + memcpy(param.monitor_adv_report.addr, params->monitor_adv_report.address, BD_ADDR_LEN); + param.monitor_adv_report.condition = params->monitor_adv_report.condition; + break; + } + case BTA_DM_BLE_5_GAP_ADD_MONITOR_ADV_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_ADD_MONITOR_ADV_COMPLETE_EVT; + param.add_monitor_adv.status = btc_btm_status_to_esp_status(params->status); + break; + } + case BTA_DM_BLE_5_GAP_REMOVE_MONITOR_ADV_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_REMOVE_MONITOR_ADV_COMPLETE_EVT; + param.remove_monitor_adv.status = btc_btm_status_to_esp_status(params->status); + break; + } + case BTA_DM_BLE_5_GAP_CLEAR_MONITOR_ADV_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_CLEAR_MONITOR_ADV_COMPLETE_EVT; + param.clear_monitor_adv.status = btc_btm_status_to_esp_status(params->status); + break; + } + case BTA_DM_BLE_5_GAP_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT; + param.read_monitor_adv_list_size.status = btc_btm_status_to_esp_status(params->monitor_adv_list_size.status); + param.read_monitor_adv_list_size.list_size = params->monitor_adv_list_size.list_size; + break; + } + case BTA_DM_BLE_5_GAP_ENABLE_MONITOR_ADV_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_ENABLE_MONITOR_ADV_COMPLETE_EVT; + param.enable_monitor_adv.status = btc_btm_status_to_esp_status(params->status); + break; + } +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) #if (BLE_50_EXTEND_ADV_EN == TRUE) case BTA_DM_BLE_5_GAP_ADV_TERMINATED_EVT: { param.adv_terminate.status = params->adv_term.status; @@ -3148,6 +3183,25 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) BTA_DmBleGapSetHostFeature(arg_5->set_host_feature_params.bit_num, arg_5->set_host_feature_params.bit_val); break; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) + case BTC_GAP_BLE_ADD_MONITOR_ADV_LIST: + BTA_DmBleGapAddMonitorAdvList(arg_5->add_monitor_adv_list.addr_type, arg_5->add_monitor_adv_list.addr, + arg_5->add_monitor_adv_list.rssi_low, arg_5->add_monitor_adv_list.rssi_high, + arg_5->add_monitor_adv_list.timeout); + break; + case BTC_GAP_BLE_RMV_MONITOR_ADV_LIST: + BTA_DmBleGapRemoveMonitorAdvList(arg_5->rmv_monitor_adv_list.addr_type, arg_5->rmv_monitor_adv_list.addr); + break; + case BTC_GAP_BLE_CLEAR_MONITOR_ADV_LIST: + BTA_DmBleGapClearMonitorAdvList(); + break; + case BTC_GAP_BLE_READ_MONITOR_ADV_LIST_SIZE: + BTA_DmBleGapReadMonitorAdvListSize(); + break; + case BTC_GAP_BLE_ENABLE_MONITOR_ADV: + BTA_DmBleGapEnableMonitorAdv(arg_5->enable_monitor_adv.enable); + break; +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) case BTC_GAP_BLE_SET_PA_SUBEVT_DATA: BTA_DmBleGapSetPASubevtData(arg_5->per_adv_subevent_data_params.adv_handle, arg_5->per_adv_subevent_data_params.num_subevents_with_data, (uint8_t *)(arg_5->per_adv_subevent_data_params.subevent_params)); diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index a429751293..2e6163eb2f 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -140,6 +140,13 @@ typedef enum { #if (BLE_50_FEATURE_SUPPORT == TRUE) BTC_GAP_ACT_SET_HOST_FEATURE, #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) + BTC_GAP_BLE_ADD_MONITOR_ADV_LIST, + BTC_GAP_BLE_RMV_MONITOR_ADV_LIST, + BTC_GAP_BLE_CLEAR_MONITOR_ADV_LIST, + BTC_GAP_BLE_READ_MONITOR_ADV_LIST_SIZE, + BTC_GAP_BLE_ENABLE_MONITOR_ADV, +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) BTC_GAP_BLE_READ_CHANNEL_MAP, #if (BT_BLE_FEAT_PAWR_EN == TRUE) BTC_GAP_BLE_SET_PA_SUBEVT_DATA, @@ -565,6 +572,22 @@ typedef union { uint16_t bit_num; uint8_t bit_val; } set_host_feature_params; +#if (BLE_FEAT_ADV_MONITOR == TRUE) + struct add_monitor_adv_list_args { + uint8_t addr_type; + esp_bd_addr_t addr; + int8_t rssi_low; + int8_t rssi_high; + uint8_t timeout; + } add_monitor_adv_list; + struct rmv_monitor_adv_list_args { + uint8_t addr_type; + esp_bd_addr_t addr; + } rmv_monitor_adv_list; + struct enable_monitor_adv_args { + uint8_t enable; + } enable_monitor_adv; +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) // BTC_GAP_BLE_SET_PA_SUBEVT_DATA struct per_adv_subevent_data_params_args { diff --git a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h index d6275fd379..f657d792a1 100644 --- a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h +++ b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h @@ -307,6 +307,12 @@ #define UC_BT_BLE_FEAT_CHANNEL_SOUNDING FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_ADV_MONITOR +#define UC_BT_BLE_FEAT_ADV_MONITOR CONFIG_BT_BLE_FEAT_ADV_MONITOR +#else +#define UC_BT_BLE_FEAT_ADV_MONITOR FALSE +#endif + #ifdef CONFIG_BT_BLE_VENDOR_HCI_EN #define UC_BT_BLE_VENDOR_HCI_EN CONFIG_BT_BLE_VENDOR_HCI_EN #else diff --git a/components/bt/host/bluedroid/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index c278c85574..2a61ded9f1 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -394,6 +394,13 @@ #define BT_BLE_FEAT_CHANNEL_SOUNDING FALSE #endif +/* LE Monitor Advertisement (Bluetooth Core 6.0) */ +#if (BLE_50_FEATURE_SUPPORT == TRUE) && (defined UC_BT_BLE_FEAT_ADV_MONITOR) && (UC_BT_BLE_FEAT_ADV_MONITOR == TRUE) +#define BLE_FEAT_ADV_MONITOR TRUE +#else +#define BLE_FEAT_ADV_MONITOR FALSE +#endif + #if (UC_BT_BLE_VENDOR_HCI_EN == TRUE) #define BLE_VENDOR_HCI_EN TRUE #else diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 46f0eadbeb..22bb764988 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -1344,6 +1344,125 @@ void btm_ble_ext_adv_report_evt(tBTM_BLE_EXT_ADV_REPORT *params) } #endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) +void btm_ble_monitor_adv_report_evt(tBTM_BLE_MONITOR_ADV_REPORT *params) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + memcpy(&cb_params.monitor_adv_report, params, sizeof(tBTM_BLE_MONITOR_ADV_REPORT)); + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_MONITOR_ADV_REPORT_EVT, &cb_params); +} + +void btm_ble_read_monitor_adv_list_size_complete(UINT8 *p) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + UINT8 status; + + if (!p) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(status, p); + cb_params.monitor_adv_list_size.status = (status == HCI_SUCCESS) ? BTM_SUCCESS : (BTM_HCI_ERROR | status); + if (status == HCI_SUCCESS) { + STREAM_TO_UINT8(cb_params.monitor_adv_list_size.list_size, p); + } + + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT, &cb_params); +} + +tBTM_STATUS BTM_BleAddMonitorAdvList(UINT8 addr_type, BD_ADDR addr, INT8 rssi_low, INT8 rssi_high, UINT8 timeout) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if (addr_type > BLE_ADDR_TYPE_MAX) { + status = BTM_ILLEGAL_VALUE; + BTM_TRACE_ERROR("%s invalid addr_type %d", __func__, addr_type); + goto end; + } + + if ((err = btsnd_hcic_ble_add_monitor_adv_list(addr_type, addr, rssi_low, rssi_high, timeout)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("LE AddMonitorAdvList: cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + +end: + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_ADD_MONITOR_ADV_COMPLETE_EVT, &cb_params); + return status; +} + +tBTM_STATUS BTM_BleRemoveMonitorAdvList(UINT8 addr_type, BD_ADDR addr) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if (addr_type > BLE_ADDR_TYPE_MAX) { + status = BTM_ILLEGAL_VALUE; + BTM_TRACE_ERROR("%s invalid addr_type %d", __func__, addr_type); + goto end; + } + + if ((err = btsnd_hcic_ble_rmv_monitor_adv_list(addr_type, addr)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("LE RmvMonitorAdvList: cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + +end: + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_REMOVE_MONITOR_ADV_COMPLETE_EVT, &cb_params); + return status; +} + +tBTM_STATUS BTM_BleClearMonitorAdvList(void) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_clear_monitor_adv_list()) != HCI_SUCCESS) { + BTM_TRACE_ERROR("LE ClearMonitorAdvList: cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_CLEAR_MONITOR_ADV_COMPLETE_EVT, &cb_params); + return status; +} + +tBTM_STATUS BTM_BleReadMonitorAdvListSize(void) +{ + if (!btsnd_hcic_ble_read_monitor_adv_list_size()) { + return BTM_NO_RESOURCES; + } + return BTM_CMD_STARTED; +} + +tBTM_STATUS BTM_BleEnableMonitorAdv(UINT8 enable) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_enable_monitor_adv(enable)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("LE EnableMonitorAdv: cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_ENABLE_MONITOR_ADV_COMPLETE_EVT, &cb_params); + return status; +} +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + #if (BLE_50_EXTEND_ADV_EN == TRUE) void btm_ble_scan_req_received_evt(tBTM_BLE_SCAN_REQ_RECEIVED *params) { diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 76b34bcefe..d91f9927f6 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -554,6 +554,10 @@ void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *par 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_ADV_MONITOR == TRUE) +void btm_ble_monitor_adv_report_evt(tBTM_BLE_MONITOR_ADV_REPORT *params); +void btm_ble_read_monitor_adv_list_size_complete(UINT8 *p); +#endif // #if (BLE_FEAT_ADV_MONITOR == 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); diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 9d50f320a9..6b956b90f4 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -171,6 +171,9 @@ 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_FEAT_ADV_MONITOR == TRUE) +static void btu_ble_monitor_adv_report_evt(UINT8 *p); +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) #if (BLE_50_EXTEND_SYNC_EN == TRUE) static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p, bool v2_evt); static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len, bool v2_evt); @@ -551,6 +554,11 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) btu_ble_channel_select_alg_evt(p); break; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) + case HCI_BLE_MONITOR_ADV_REPORT_EVT: + btu_ble_monitor_adv_report_evt(p); + break; +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) case HCI_BLE_PERIOD_ADV_SYNC_TRANS_RECV_EVT: btu_ble_periodic_adv_sync_trans_recv(p); @@ -1454,6 +1462,11 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_ble_cs_read_local_supp_caps_cmpl_evt(p); break; #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) + case HCI_BLE_READ_MONITOR_ADV_LIST_SIZE: + btm_ble_read_monitor_adv_list_size_complete(p); + break; +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) #endif /* (BLE_INCLUDED == TRUE) */ default: { @@ -2623,6 +2636,23 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len) } #endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) +static void btu_ble_monitor_adv_report_evt(UINT8 *p) +{ + tBTM_BLE_MONITOR_ADV_REPORT report = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + /* HCI LE Monitor Adv Report: Addr_Type(1) + Address(6) + Condition(1) */ + STREAM_TO_UINT8(report.addr_type, p); + STREAM_TO_BDADDR(report.address, p); + STREAM_TO_UINT8(report.condition, p); + btm_ble_monitor_adv_report_evt(&report); +} +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + #if (BLE_50_EXTEND_SYNC_EN == TRUE) static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p, bool v2_evt) { diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index fef574fd6a..eafe0b6942 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -2969,6 +2969,87 @@ UINT8 btsnd_hcic_ble_set_host_feature(uint16_t bit_num, uint8_t bit_val) } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) +UINT8 btsnd_hcic_ble_add_monitor_adv_list(UINT8 addr_type, BD_ADDR addr, INT8 rssi_low, INT8 rssi_high, UINT8 timeout) +{ + BT_HDR *p; + UINT8 *pp; + + HCIC_BLE_CMD_CREATED_U8(p, pp, HCIC_PARAM_SIZE_ADD_MONITOR_ADV_LIST); + + UINT16_TO_STREAM(pp, HCI_BLE_ADD_MONITOR_ADV_LIST); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ADD_MONITOR_ADV_LIST); + UINT8_TO_STREAM(pp, addr_type); + BDADDR_TO_STREAM(pp, addr); + UINT8_TO_STREAM(pp, (UINT8)rssi_low); + UINT8_TO_STREAM(pp, (UINT8)rssi_high); + UINT8_TO_STREAM(pp, timeout); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_rmv_monitor_adv_list(UINT8 addr_type, BD_ADDR addr) +{ + BT_HDR *p; + UINT8 *pp; + + HCIC_BLE_CMD_CREATED_U8(p, pp, HCIC_PARAM_SIZE_RMV_MONITOR_ADV_LIST); + + UINT16_TO_STREAM(pp, HCI_BLE_RMV_MONITOR_ADV_LIST); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_RMV_MONITOR_ADV_LIST); + UINT8_TO_STREAM(pp, addr_type); + BDADDR_TO_STREAM(pp, addr); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_clear_monitor_adv_list(void) +{ + BT_HDR *p; + UINT8 *pp; + + HCIC_BLE_CMD_CREATED_U8(p, pp, HCIC_PARAM_SIZE_CLEAR_MONITOR_ADV_LIST); + + UINT16_TO_STREAM(pp, HCI_BLE_CLEAR_MONITOR_ADV_LIST); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CLEAR_MONITOR_ADV_LIST); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +BOOLEAN btsnd_hcic_ble_read_monitor_adv_list_size(void) +{ + BT_HDR *p; + UINT8 *pp; + + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_MONITOR_ADV_LIST_SIZE)) == NULL) { + return FALSE; + } + pp = (UINT8 *)(p + 1); + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_MONITOR_ADV_LIST_SIZE; + p->offset = 0; + + UINT16_TO_STREAM(pp, HCI_BLE_READ_MONITOR_ADV_LIST_SIZE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_MONITOR_ADV_LIST_SIZE); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} + +UINT8 btsnd_hcic_ble_enable_monitor_adv(UINT8 enable) +{ + BT_HDR *p; + UINT8 *pp; + + HCIC_BLE_CMD_CREATED_U8(p, pp, HCIC_PARAM_SIZE_ENABLE_MONITOR_ADV); + + UINT16_TO_STREAM(pp, HCI_BLE_ENABLE_MONITOR_ADV); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ENABLE_MONITOR_ADV); + UINT8_TO_STREAM(pp, enable); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + #if (BT_BLE_FEAT_PAWR_EN == TRUE) UINT8 btsnd_hcic_ble_set_periodic_adv_subevt_data(UINT8 adv_handle, UINT8 num_subevents_with_data, ble_subevent_params *subevent_params) { diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index e331a39bf2..cff6e3264f 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -974,7 +974,15 @@ typedef void (tBTM_SET_VENDOR_EVT_MASK_CBACK) (tBTM_STATUS status); #define BTM_BLE_GAP_CS_SUBEVENT_RESULT_EVT 68 #define BTM_BLE_GAP_CS_SUBEVENT_RESULT_CONTINUE_EVT 69 #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) -#define BTM_BLE_5_GAP_UNKNOWN_EVT 70 +#if (BLE_FEAT_ADV_MONITOR == TRUE) +#define BTM_BLE_5_GAP_MONITOR_ADV_REPORT_EVT 70 +#define BTM_BLE_5_GAP_ADD_MONITOR_ADV_COMPLETE_EVT 71 +#define BTM_BLE_5_GAP_REMOVE_MONITOR_ADV_COMPLETE_EVT 72 +#define BTM_BLE_5_GAP_CLEAR_MONITOR_ADV_COMPLETE_EVT 73 +#define BTM_BLE_5_GAP_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT 74 +#define BTM_BLE_5_GAP_ENABLE_MONITOR_ADV_COMPLETE_EVT 75 +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#define BTM_BLE_5_GAP_UNKNOWN_EVT 76 typedef UINT8 tBTM_BLE_5_GAP_EVENT; #if (BLE_FEAT_ISO_EN == TRUE) @@ -1211,6 +1219,19 @@ typedef struct { UINT8 channel_sel_alg; } tBTM_BLE_CHANNEL_SEL_ALG; +#if (BLE_FEAT_ADV_MONITOR == TRUE) +typedef struct { + UINT8 addr_type; + BD_ADDR address; + UINT8 condition; +} tBTM_BLE_MONITOR_ADV_REPORT; + +typedef struct { + tBTM_STATUS status; + UINT8 list_size; +} tBTM_BLE_MONITOR_ADV_LIST_SIZE; +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + typedef struct { UINT16 sync_handle; UINT8 tx_power; @@ -1917,6 +1938,10 @@ typedef union { tBTM_BLE_CS_SUBEVT_RESULT_CMPL_EVT cs_subevt_result; tBTM_BLE_CS_SUBEVT_RESULT_CONTINUE_EVT cs_subevt_result_continue; #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) + tBTM_BLE_MONITOR_ADV_REPORT monitor_adv_report; + tBTM_BLE_MONITOR_ADV_LIST_SIZE monitor_adv_list_size; +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) } tBTM_BLE_5_GAP_CB_PARAMS; typedef struct { @@ -3087,6 +3112,14 @@ 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); + +#if (BLE_FEAT_ADV_MONITOR == TRUE) +tBTM_STATUS BTM_BleAddMonitorAdvList(UINT8 addr_type, BD_ADDR addr, INT8 rssi_low, INT8 rssi_high, UINT8 timeout); +tBTM_STATUS BTM_BleRemoveMonitorAdvList(UINT8 addr_type, BD_ADDR addr); +tBTM_STATUS BTM_BleClearMonitorAdvList(void); +tBTM_STATUS BTM_BleReadMonitorAdvListSize(void); +tBTM_STATUS BTM_BleEnableMonitorAdv(UINT8 enable); +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_50_DTM_TEST_EN == TRUE) diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 454f440684..5204e625ba 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -429,6 +429,15 @@ #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_ADV_MONITOR == TRUE) +/* LE Monitor Advertisement (Bluetooth Core 6.0) */ +#define HCI_BLE_ADD_MONITOR_ADV_LIST (0x0098 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_RMV_MONITOR_ADV_LIST (0x0099 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CLEAR_MONITOR_ADV_LIST (0x009A | HCI_GRP_BLE_CMDS) +#define HCI_BLE_READ_MONITOR_ADV_LIST_SIZE (0x009B | HCI_GRP_BLE_CMDS) +#define HCI_BLE_ENABLE_MONITOR_ADV (0x009C | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + #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) @@ -960,6 +969,10 @@ #define HCI_BLE_PA_RESPONSE_REPORT_EVT 0x28 #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) +#define HCI_BLE_MONITOR_ADV_REPORT_EVT 0x34 +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + #if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) #define HCI_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT 0x2C #define HCI_BLE_CS_READ_REMOTE_FAE_TAB_CMPL_EVT 0x2D diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index c0e46429ba..dd6fdb5dc3 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -805,6 +805,20 @@ uint8_t btsnd_hcic_ble_get_status(void); void btsnd_hci_ble_set_status(UINT8 hci_status); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_ADV_MONITOR == TRUE) +#define HCIC_PARAM_SIZE_ADD_MONITOR_ADV_LIST 10 +#define HCIC_PARAM_SIZE_RMV_MONITOR_ADV_LIST 7 +#define HCIC_PARAM_SIZE_CLEAR_MONITOR_ADV_LIST 0 +#define HCIC_PARAM_SIZE_READ_MONITOR_ADV_LIST_SIZE 0 +#define HCIC_PARAM_SIZE_ENABLE_MONITOR_ADV 1 + +UINT8 btsnd_hcic_ble_add_monitor_adv_list(UINT8 addr_type, BD_ADDR addr, INT8 rssi_low, INT8 rssi_high, UINT8 timeout); +UINT8 btsnd_hcic_ble_rmv_monitor_adv_list(UINT8 addr_type, BD_ADDR addr); +UINT8 btsnd_hcic_ble_clear_monitor_adv_list(void); +BOOLEAN btsnd_hcic_ble_read_monitor_adv_list_size(void); +UINT8 btsnd_hcic_ble_enable_monitor_adv(UINT8 enable); +#endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + /* ULP HCI command */ BOOLEAN btsnd_hcic_ble_set_evt_mask (BT_EVENT_MASK event_mask);