From be0b4efd09dd02df48198f53da0c079a74e8b68d Mon Sep 17 00:00:00 2001 From: Ayush Garg Date: Thu, 17 Aug 2023 14:28:55 +0530 Subject: [PATCH] BT 5.0: Add APIs to check Extended feature support This patch adds support for the following APIs: 1. bluetooth_is_le_extended_advertising_supported() 2. bluetooth_is_le_extended_scan_supported() 3. bluetooth_le_get_maximum_advertising_data_length() Change-Id: Ic018cde08d33de319894add49eaa8501075e61e1 Signed-off-by: Ayush Garg --- bt-api/bt-adapter-le.c | 75 ++++++++++++++++++++++ bt-oal/bluez_hal/src/bt-hal-adapter-le.c | 48 ++++++++++---- bt-oal/bluez_hal/src/bt-hal-utils.c | 27 ++++++++ bt-oal/common/oal-utils.c | 9 +++ bt-oal/include/oal-event.h | 3 + bt-oal/oal-adapter-mgr.c | 6 ++ .../services/adapter/bt-service-core-adapter-le.c | 35 +++++++++- bt-service/services/bt-request-handler.c | 25 ++++++++ .../services/include/bt-service-core-adapter-le.h | 6 ++ include/bluetooth-api.h | 61 +++++++++++++++++- include/bt-internal-types.h | 3 + 11 files changed, 284 insertions(+), 14 deletions(-) diff --git a/bt-api/bt-adapter-le.c b/bt-api/bt-adapter-le.c index 3675c42..490f2bc 100644 --- a/bt-api/bt-adapter-le.c +++ b/bt-api/bt-adapter-le.c @@ -752,3 +752,78 @@ BT_EXPORT_API int bluetooth_is_le_coded_phy_supported(gboolean *is_supported) BT_INFO("LE CODED PHY Support[%s]", *is_supported ? "TRUE" : "FALSE"); return result; } + +BT_EXPORT_API int bluetooth_is_le_extended_advertising_supported(gboolean *is_supported) +{ + int result; + + BT_CHECK_PARAMETER(is_supported, return); + BT_CHECK_ENABLED_ANY(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_IS_LE_EXTENDED_ADVERTISING_SUPPORTED, + in_param1, in_param2, in_param3, in_param4, &out_param); + + if (result == BLUETOOTH_ERROR_NONE) { + *is_supported = g_array_index(out_param, int, 0); + } else { + BT_ERR("Fail to send request"); + } + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + BT_INFO("LE Extended Advertising Support[%s]", *is_supported ? "TRUE" : "FALSE"); + return result; +} + +BT_EXPORT_API int bluetooth_is_le_extended_scan_supported(gboolean *is_supported) +{ + int result; + + BT_CHECK_PARAMETER(is_supported, return); + BT_CHECK_ENABLED_ANY(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_IS_LE_EXTENDED_SCAN_SUPPORTED, + in_param1, in_param2, in_param3, in_param4, &out_param); + + if (result == BLUETOOTH_ERROR_NONE) { + *is_supported = g_array_index(out_param, int, 0); + } else { + BT_ERR("Fail to send request"); + } + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + BT_INFO("LE Extended Scan Support[%s]", *is_supported ? "TRUE" : "FALSE"); + return result; +} + +BT_EXPORT_API int bluetooth_le_get_maximum_advertising_data_length(gint *data_length) +{ + int result; + + BT_CHECK_PARAMETER(data_length, return); + BT_CHECK_ENABLED_ANY(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_LE_MAX_ADVERTISING_DATA_LEN, + in_param1, in_param2, in_param3, in_param4, &out_param); + + if (result == BLUETOOTH_ERROR_NONE) { + *data_length = g_array_index(out_param, int, 0); + } else { + BT_ERR("Fail to send request"); + } + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + BT_INFO("LE Max Advertising Data Length [%d]", *data_length); + return result; +} diff --git a/bt-oal/bluez_hal/src/bt-hal-adapter-le.c b/bt-oal/bluez_hal/src/bt-hal-adapter-le.c index dc1ea5e..34bf09e 100644 --- a/bt-oal/bluez_hal/src/bt-hal-adapter-le.c +++ b/bt-oal/bluez_hal/src/bt-hal-adapter-le.c @@ -55,6 +55,9 @@ typedef struct { int max_filter; int le_2m_phy; int le_coded_phy; + int le_extended_advertising; + int le_extended_scan; + int max_advertising_len; } bt_adapter_le_feature_info_t; typedef struct { @@ -66,7 +69,7 @@ typedef struct { bt_uuid_t app_uuid; } bt_adapter_le_adv_slot_t; -static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 }; +static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0, 0, 0, 0, 0, 0 }; static bt_adapter_le_adv_slot_t *le_adv_slot = NULL; typedef struct { @@ -299,26 +302,49 @@ gboolean _bt_hal_update_le_feature_support(const char *item, const char *value, } else if (g_strcmp0(item, "2m_phy") == 0) { if (g_strcmp0(value, "true") == 0) { - le_feature_info.le_2m_phy = TRUE; + le_feature_info.le_2m_phy = 0x1; /* Fill LE feature bytes */ - le_features->le_2m_phy_supported = 0x1; + le_features->le_2m_phy_supported = TRUE; } else { - le_feature_info.le_2m_phy = FALSE; + le_feature_info.le_2m_phy = 0x0; /* Fill LE feature bytes */ - le_features->le_2m_phy_supported = 0x0; + le_features->le_2m_phy_supported = FALSE; } - INFO("2M PHY Supported [%s]", le_feature_info.le_2m_phy ? "TRUE" : "FALSE"); + INFO("2M PHY Supported [%s]", le_feature_info.le_2m_phy ? "TRUE" : "FALSE"); } else if (g_strcmp0(item, "coded_phy") == 0) { if (g_strcmp0(value, "true") == 0) { - le_feature_info.le_coded_phy = TRUE; + le_feature_info.le_coded_phy = 0x1; /* Fill LE feature bytes */ - le_features->le_coded_phy_supported = 0x1; + le_features->le_coded_phy_supported = TRUE; } else { - le_feature_info.le_coded_phy = FALSE; + le_feature_info.le_coded_phy = 0x0; /* Fill LE feature bytes */ - le_features->le_coded_phy_supported = 0x0; + le_features->le_coded_phy_supported = FALSE; } - INFO("CODED PHY Supported [%s]", le_feature_info.le_coded_phy ? "TRUE" : "FALSE"); + INFO("CODED PHY Supported [%s]", le_feature_info.le_coded_phy ? "TRUE" : "FALSE"); + } else if (g_strcmp0(item, "ext_advt") == 0) { + if (g_strcmp0(value, "true") == 0) { + le_feature_info.le_extended_advertising = 0x1; + le_features->le_extended_advertising_supported = TRUE; + } else { + le_feature_info.le_extended_advertising = 0x0; + le_features->le_extended_advertising_supported = FALSE; + } + INFO("LE Extended Advertising Supported [%s]", + le_feature_info.le_extended_advertising ? "TRUE" : "FALSE"); + } else if (g_strcmp0(item, "ext_scan") == 0) { + if (g_strcmp0(value, "true") == 0) { + le_feature_info.le_extended_scan = 0x1; + le_features->extended_scan_support = TRUE; + } else { + le_feature_info.le_extended_scan = 0x0; + le_features->extended_scan_support = FALSE; + } + INFO("LE Extended Scan Supported [%s]", le_feature_info.le_extended_scan ? "TRUE" : "FALSE"); + } else if (g_strcmp0(item, "max_advt_len") == 0) { + le_feature_info.max_advertising_len = atoi(value); + le_features->le_maximum_advertising_data_length = atoi(value); + INFO("LE Maximum Advertising Data Length [%d]", le_feature_info.max_advertising_len); } else { DBG("No registered item"); return FALSE; diff --git a/bt-oal/bluez_hal/src/bt-hal-utils.c b/bt-oal/bluez_hal/src/bt-hal-utils.c index 22dc6e2..b45db34 100644 --- a/bt-oal/bluez_hal/src/bt-hal-utils.c +++ b/bt-oal/bluez_hal/src/bt-hal-utils.c @@ -712,6 +712,33 @@ static void local_le_feat2string(char *str, const bt_local_le_features_t *f, int str += ret; buf_len -= ret; + ret = snprintf(str, buf_len, "LE Extended Advertising Support: %s\n", + f->le_extended_advertising_supported ? "TRUE" : "FALSE"); + if (0 > ret) { + ERR("snprintf failed with %d", ret); + return; + } + str += ret; + buf_len -= ret; + + ret = snprintf(str, buf_len, "LE Extended Scan Support: %s\n", + f->extended_scan_support ? "TRUE" : "FALSE"); + if (0 > ret) { + ERR("snprintf failed with %d", ret); + return; + } + str += ret; + buf_len -= ret; + + ret = snprintf(str, buf_len, "Maximum Advertising Data Length: %u\n", + f->le_maximum_advertising_data_length); + if (0 > ret) { + ERR("snprintf failed with %d", ret); + return; + } + str += ret; + buf_len -= ret; + ret = snprintf(str, buf_len, "}"); if (0 > ret) { ERR("snprintf failed with %d", ret); diff --git a/bt-oal/common/oal-utils.c b/bt-oal/common/oal-utils.c index c25e4a1..96c6dc7 100644 --- a/bt-oal/common/oal-utils.c +++ b/bt-oal/common/oal-utils.c @@ -444,6 +444,15 @@ void local_le_feat_2_string(char *str, const bt_local_le_features_t *f) str += sprintf(str, "LE Coded PHY support: %s\n", f->le_coded_phy_supported ? "TRUE" : "FALSE"); + str += sprintf(str, "LE Extended Advertising support: %s\n", + f->le_extended_advertising_supported ? "TRUE" : "FALSE"); + + str += sprintf(str, "LE Extended Scan support: %s\n", + f->extended_scan_support ? "TRUE" : "FALSE"); + + str += sprintf(str, "Max Advertising Data Length: %u\n", + f->le_maximum_advertising_data_length); + sprintf(str, "}"); } diff --git a/bt-oal/include/oal-event.h b/bt-oal/include/oal-event.h index 672d7fd..8add055 100644 --- a/bt-oal/include/oal-event.h +++ b/bt-oal/include/oal-event.h @@ -254,6 +254,9 @@ typedef struct { uint8_t max_adv_filter; uint8_t le_2m_phy_support; uint8_t le_coded_phy_support; + uint8_t le_extended_advertising_support; + uint8_t le_extended_scan_support; + uint16_t le_maximum_advertising_data_length; } event_adapter_le_features_t; typedef struct { diff --git a/bt-oal/oal-adapter-mgr.c b/bt-oal/oal-adapter-mgr.c index 50a29b2..dda21a9 100644 --- a/bt-oal/oal-adapter-mgr.c +++ b/bt-oal/oal-adapter-mgr.c @@ -1067,6 +1067,12 @@ static void cb_adapter_properties(bt_status_t status, le_features->max_adv_filter = ((bt_local_le_features_t *)(properties[i].val))->max_adv_filter_supported; le_features->le_2m_phy_support = ((bt_local_le_features_t *)(properties[i].val))->le_2m_phy_supported; le_features->le_coded_phy_support = ((bt_local_le_features_t *)(properties[i].val))->le_2m_phy_supported; + le_features->le_extended_advertising_support = + ((bt_local_le_features_t *)(properties[i].val))->le_extended_advertising_supported; + le_features->le_extended_scan_support = + ((bt_local_le_features_t *)(properties[i].val))->extended_scan_support; + le_features->le_maximum_advertising_data_length = + ((bt_local_le_features_t *)(properties[i].val))->le_maximum_advertising_data_length; BT_INFO("LE 2M PHY Support (%d)", le_features->le_2m_phy_support); BT_INFO("LE CODED PHY Support (%d)", le_features->le_coded_phy_support); diff --git a/bt-service/services/adapter/bt-service-core-adapter-le.c b/bt-service/services/adapter/bt-service-core-adapter-le.c index b68b9c9..8a22fab 100644 --- a/bt-service/services/adapter/bt-service-core-adapter-le.c +++ b/bt-service/services/adapter/bt-service-core-adapter-le.c @@ -63,10 +63,13 @@ typedef struct { bool vendor_filter; int le_2m_phy; int le_coded_phy; + int le_extended_advertising; + int le_extended_scan; + int max_advertising_len; } bt_adapter_le_feature_info_t; /* Set Default values */ -static bt_adapter_le_feature_info_t le_feature_info = {1, 0, 0, false, 0, 0}; +static bt_adapter_le_feature_info_t le_feature_info = {1, 0, 0, false, 0, 0, 0, 0, 0}; typedef struct { int adv_handle; @@ -1118,8 +1121,17 @@ static void __bt_le_event_handler(int event_type, gpointer event_data) le_feature_info.vendor_filter = false; } + le_feature_info.le_extended_advertising = le_features->le_extended_advertising_support; + le_feature_info.le_extended_scan = le_features->le_extended_scan_support; + le_feature_info.max_advertising_len = le_features->le_maximum_advertising_data_length; + BT_INFO("Adapter LE 2M PHY Support [%s]", le_feature_info.le_2m_phy ? "TRUE" : "FALSE"); BT_INFO("Adapter LE CODED PHY Support [%s]", le_feature_info.le_coded_phy ? "TRUE" : "FALSE"); + BT_INFO("Adapter LE Extended Advertising Support [%s]", + le_feature_info.le_extended_advertising ? "TRUE" : "FALSE"); + BT_INFO("Adapter LE Extended Scan Support [%s]", + le_feature_info.le_extended_scan ? "TRUE" : "FALSE"); + BT_INFO("Adapter Maximum Advertising Data Length [%d]", le_feature_info.max_advertising_len); break; } @@ -2439,6 +2451,27 @@ gboolean _bt_is_scan_filter_supported(void) return FALSE; } +gboolean _bt_is_le_extended_advertising_supported(void) +{ + if (le_feature_info.le_extended_advertising) + return TRUE; + else + return FALSE; +} + +gboolean _bt_is_le_extended_scan_supported(void) +{ + if (le_feature_info.le_extended_scan) + return TRUE; + else + return FALSE; +} + +int _bt_le_get_maximum_advertising_len(void) +{ + return le_feature_info.max_advertising_len; +} + int _bt_set_le_privacy(gboolean set_privacy) { int result = BLUETOOTH_ERROR_NONE; diff --git a/bt-service/services/bt-request-handler.c b/bt-service/services/bt-request-handler.c index 074813b..4b7e868 100644 --- a/bt-service/services/bt-request-handler.c +++ b/bt-service/services/bt-request-handler.c @@ -3407,6 +3407,28 @@ normal: g_array_append_vals(*out_param1, &is_coded_phy_supported, sizeof(gboolean)); break; } + case BT_IS_LE_EXTENDED_ADVERTISING_SUPPORTED: { + gboolean is_extended_advertising_supported = FALSE; + + is_extended_advertising_supported = _bt_is_le_extended_advertising_supported(); + g_array_append_vals(*out_param1, &is_extended_advertising_supported, + sizeof(gboolean)); + break; + } + case BT_IS_LE_EXTENDED_SCAN_SUPPORTED: { + gboolean is_extended_scan_supported = FALSE; + + is_extended_scan_supported = _bt_is_le_extended_scan_supported(); + g_array_append_vals(*out_param1, &is_extended_scan_supported, sizeof(gboolean)); + break; + } + case BT_LE_MAX_ADVERTISING_DATA_LEN: { + gint max_advertising_len = 0; + + max_advertising_len = _bt_le_get_maximum_advertising_len(); + g_array_append_vals(*out_param1, &max_advertising_len, sizeof(gint)); + break; + } case BT_DISCONNECT_DEVICE: { bluetooth_device_address_t address = { {0} }; @@ -5762,6 +5784,9 @@ gboolean __bt_service_check_privilege(int function_name, case BT_IS_ADVERTISING: case BT_IS_LE_2M_PHY_SUPPORTED: case BT_IS_LE_CODED_PHY_SUPPORTED: + case BT_IS_LE_EXTENDED_ADVERTISING_SUPPORTED: + case BT_IS_LE_EXTENDED_SCAN_SUPPORTED: + case BT_LE_MAX_ADVERTISING_DATA_LEN: case BT_REGISTER_SCAN_FILTER: case BT_IS_SCAN_FILTER_SUPPORTED: case BT_GET_ATT_MTU: diff --git a/bt-service/services/include/bt-service-core-adapter-le.h b/bt-service/services/include/bt-service-core-adapter-le.h index a12b1c3..a9f9f38 100644 --- a/bt-service/services/include/bt-service-core-adapter-le.h +++ b/bt-service/services/include/bt-service-core-adapter-le.h @@ -113,6 +113,12 @@ gboolean _bt_is_le_coded_phy_supported(void); gboolean _bt_is_scan_filter_supported(void); +gboolean _bt_is_le_extended_advertising_supported(void); + +gboolean _bt_is_le_extended_scan_supported(void); + +int _bt_le_get_maximum_advertising_len(void); + int _bt_set_le_static_random_address(gboolean is_enable); bool _bt_is_le_static_random_address_enabled(void); diff --git a/include/bluetooth-api.h b/include/bluetooth-api.h index 60fb555..53e232f 100644 --- a/include/bluetooth-api.h +++ b/include/bluetooth-api.h @@ -7906,7 +7906,7 @@ int bluetooth_otp_disconnect_otc(const bluetooth_device_address_t *device_addres * * This function is a synchronous call. * - * @return BLUETOOTH_ERROR_NONE - Succeess \n + * @return BLUETOOTH_ERROR_NONE - Success \n * BLUETOOTH_ERROR_INVALID_PARAM - Invalid parameter (NULL buffer) \n * BLUETOOTH_ERROR_DEVICE_NOT_ENABLED - Adapter is disabled \n * BLUETOOTH_ERROR_INTERNAL - Internal error \n @@ -7925,7 +7925,7 @@ int bluetooth_is_le_2m_phy_supported(gboolean *is_supported); * * This function is a synchronous call. * - * @return BLUETOOTH_ERROR_NONE - Succeess \n + * @return BLUETOOTH_ERROR_NONE - Success \n * BLUETOOTH_ERROR_INVALID_PARAM - Invalid parameter (NULL buffer) \n * BLUETOOTH_ERROR_DEVICE_NOT_ENABLED - Adapter is disabled \n * BLUETOOTH_ERROR_INTERNAL - Internal error \n @@ -7936,6 +7936,63 @@ int bluetooth_is_le_2m_phy_supported(gboolean *is_supported); int bluetooth_is_le_coded_phy_supported(gboolean *is_supported); /** + * @fn int bluetooth_is_le_extended_advertising_supported(gboolean *is_supported) + * @brief Check if Adapter supports LE Extended Advertising feature or not. + * + * This API is used to check whether LE Adapter supports LE Extended Advertising feature, which is introduced + * in BT 5.0 specification. + * + * This function is a synchronous call. + * + * @return BLUETOOTH_ERROR_NONE - Success \n + * BLUETOOTH_ERROR_INVALID_PARAM - Invalid parameter (NULL buffer) \n + * BLUETOOTH_ERROR_DEVICE_NOT_ENABLED - Adapter is disabled \n + * BLUETOOTH_ERROR_INTERNAL - Internal error \n + * @param[out] is_supported. This boolean variable indicates whether LE Extended Advertising is supported or not + * + * @remark None + */ +int bluetooth_is_le_extended_advertising_supported(gboolean *is_supported); + +/** + * @fn int bluetooth_is_le_extended_scan_supported(gboolean *is_supported) + * @brief Check if Adapter supports LE Extended Scan feature or not. + * + * This API is used to check whether LE Adapter supports LE Extended Scan feature, which is introduced + * in BT 5.0 specification. + * + * This function is a synchronous call. + * + * @return BLUETOOTH_ERROR_NONE - Success \n + * BLUETOOTH_ERROR_INVALID_PARAM - Invalid parameter (NULL buffer) \n + * BLUETOOTH_ERROR_DEVICE_NOT_ENABLED - Adapter is disabled \n + * BLUETOOTH_ERROR_INTERNAL - Internal error \n + * @param[out] is_supported. This boolean variable indicates whether LE Extended Scan is supported or not + * + * @remark None + */ +int bluetooth_is_le_extended_scan_supported(gboolean *is_supported); + +/** + * @fn int bluetooth_le_get_maximum_advertising_data_length(gint *data_length) + * @brief gives the maximum advertising data length supported by controller. + * + * This API is used to get the maximum advertising data length supported by controller. This feature is introduced + * in BT 5.0 specification. + * + * This function is a synchronous call. + * + * @return BLUETOOTH_ERROR_NONE - Success \n + * BLUETOOTH_ERROR_INVALID_PARAM - Invalid parameter (NULL buffer) \n + * BLUETOOTH_ERROR_DEVICE_NOT_ENABLED - Adapter is disabled \n + * BLUETOOTH_ERROR_INTERNAL - Internal error \n + * @param[out] data_length. This integer variable indicates the maximum advertising data length supported by the controller + * + * @remark None + */ +int bluetooth_le_get_maximum_advertising_data_length(gint *data_length); + +/** * @fn int bluetooth_l2cap_le_create_socket(int psm) * @brief Register l2cap_le socket with a specific PSM * diff --git a/include/bt-internal-types.h b/include/bt-internal-types.h index 3d07dd4..ebae2df 100644 --- a/include/bt-internal-types.h +++ b/include/bt-internal-types.h @@ -224,6 +224,9 @@ typedef enum { BT_ENABLE_FORCE_HCI_DUMP, BT_SET_PASSKEY_NOTIFICATION, BT_SET_SCAN_TYPE, + BT_IS_LE_EXTENDED_ADVERTISING_SUPPORTED, + BT_IS_LE_EXTENDED_SCAN_SUPPORTED, + BT_LE_MAX_ADVERTISING_DATA_LEN, BT_BOND_DEVICE = BT_FUNC_DEVICE_BASE, BT_BOND_DEVICE_BY_TYPE, BT_CANCEL_BONDING, -- 2.7.4