From 975cd8f8c2ff2cb0c280027c5abcc061db17b44e Mon Sep 17 00:00:00 2001 From: Wootak Jung Date: Mon, 20 Feb 2023 16:21:12 +0900 Subject: [PATCH] Add custom name removing API fix ad type removing function Change-Id: Ic47a8ef39b0cc8d954326cb683d3816543e8b273 Signed-off-by: Wootak Jung --- include/bluetooth_internal.h | 28 ++++++++- src/bluetooth-adapter.c | 113 +++++++++++++++++++++-------------- tests/test/bt_unit_test.c | 14 ++++- 3 files changed, 106 insertions(+), 49 deletions(-) diff --git a/include/bluetooth_internal.h b/include/bluetooth_internal.h index 449ae41..b0f41a9 100644 --- a/include/bluetooth_internal.h +++ b/include/bluetooth_internal.h @@ -5473,7 +5473,7 @@ int bt_adapter_get_hci_address(char **address); /** * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE - * @brief Sets the custom name should be included in advertise or scan response data. + * @brief Adds the custom name should be included in advertise or scan response data. * The maximum advertised or responded data size is 31 bytes. * if you want to include the system wide device name, * please use @a bt_adapter_le_set_advertising_device_name. @@ -5501,6 +5501,32 @@ int bt_adapter_get_hci_address(char **address); int bt_adapter_le_add_advertising_custom_name(bt_advertiser_h advertiser, bt_adapter_le_packet_type_e pkt_type, const char *name, unsigned int name_len); +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Removes the custom name in advertise or scan response data. + * @since_tizen 7.5 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] advertiser The handle of advertiser + * @param[in] pkt_type The packet type + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_QUOTA_EXCEEDED Quota exceeded + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_adapter_le_start_advertising_new() + * @see bt_adapter_le_add_advertising_custom_name() + */ +int bt_adapter_le_remove_advertising_custom_name(bt_advertiser_h advertiser, + bt_adapter_le_packet_type_e pkt_type); + /** * @} */ diff --git a/src/bluetooth-adapter.c b/src/bluetooth-adapter.c index 9aa9478..11ffca2 100644 --- a/src/bluetooth-adapter.c +++ b/src/bluetooth-adapter.c @@ -1802,53 +1802,50 @@ int bt_adapter_le_destroy_advertiser(bt_advertiser_h advertiser) } /* LCOV_EXCL_START */ -static int __bt_remove_ad_data_by_type(char *in_data, unsigned int in_len, - char in_type, char **data, unsigned int *data_len) +static int __bt_remove_ad_data_by_type(char **in_data, unsigned int *in_len, char in_type) { - if (in_data == NULL || data == NULL || data_len == NULL) - return BT_ERROR_OPERATION_FAILED; - int i; - int len = 0; - int type = 0; - char *p; - - for (i = 0; i < in_len; i++) { - len = in_data[i]; - if (len <= 0 || i + 1 >= in_len) { - BT_ERR("Invalid advertising data"); - return BT_ERROR_OPERATION_FAILED; - } - - type = in_data[i + 1]; - if (type == in_type) { - i = i + 2; - len--; - break; - } - - i += len; - len = 0; - } + int ad_len = 0; + int ad_type = 0; + char *data; + unsigned int data_len; - if (i + len > in_len) { - BT_ERR("Invalid advertising data"); + if (*in_data == NULL || in_len == NULL) return BT_ERROR_OPERATION_FAILED; - } else if (len == 0) { - BT_INFO("AD Type 0x%02x data is not set", in_type); - return BT_ERROR_OPERATION_FAILED; - } - p = (char *)malloc(sizeof(char) *(in_len - len)); - if (p == NULL) - return BT_ERROR_OUT_OF_MEMORY; + data = g_memdup2(*in_data, *in_len); + data_len = *in_len; - memcpy(p, in_data, sizeof(char) *i); - memcpy(p + i, in_data + i + len, sizeof(char) *(in_len - len - i)); + for (i = 0; i < data_len; i++) { + ad_len = data[i]; + ad_type = data[i + 1]; - *data = p; - *data_len = in_len - len; + if (ad_type == in_type) { + /* Only current ad data is added */ + if (ad_len + 1 == data_len) { + free(*in_data); + *in_data = NULL; + *in_len = 0; + g_free(data); + BT_DBG("Removed ad_type(0x%02x) data", ad_type); + return BT_ERROR_NONE; + } + + *in_data = realloc(*in_data, sizeof(char) * (data_len - ad_len)); + if (i + ad_len + 1 == data_len) /* ad data is added in last position */ + memcpy(*in_data, data, data_len - ad_len - 1); + else /* ad data is added in first/middle position */ + memcpy(*in_data + i, data + i + ad_len + 1, data_len - i - ad_len - 1); + *in_len = *in_len - ad_len - 1; + BT_DBG("Removed ad_type(0x%02x) data", ad_type); + g_free(data); + return BT_ERROR_NONE; + } else { + i += data[i]; + } + } + BT_ERR("ad_type(0x%02x) data is not set", in_type); return BT_ERROR_NONE; } /* LCOV_EXCL_STOP */ @@ -1932,8 +1929,6 @@ static int bt_adapter_le_remove_advertising_data(bt_advertiser_h advertiser, char **p; unsigned int *len; unsigned int *system_data_len; - char *new_p = NULL; - unsigned int new_len = 0; BT_CHECK_LE_SUPPORT(); BT_CHECK_INIT_STATUS(); @@ -1958,14 +1953,11 @@ static int bt_adapter_le_remove_advertising_data(bt_advertiser_h advertiser, return BT_ERROR_INVALID_PARAMETER; } - ret = __bt_remove_ad_data_by_type(*p, *len, data_type, &new_p, &new_len); + ret = __bt_remove_ad_data_by_type(p, len, data_type); if (ret != BT_ERROR_NONE) return ret; - free(*p); - *p = new_p; - *len = new_len; - + // TODO: need to check system_data_len is required if (data_type == BT_ADAPTER_LE_ADVERTISING_DATA_LOCAL_NAME || data_type == BT_ADAPTER_LE_ADVERTISING_DATA_TX_POWER_LEVEL) *system_data_len -= 1; @@ -2541,6 +2533,35 @@ int bt_adapter_le_add_advertising_custom_name(bt_advertiser_h advertiser, return BT_ERROR_NONE; } +int bt_adapter_le_remove_advertising_custom_name(bt_advertiser_h advertiser, + bt_adapter_le_packet_type_e pkt_type) +{ + bt_advertiser_s *__adv = (bt_advertiser_s *)advertiser; + char **p; + unsigned int *len; + int ret = BT_ERROR_NONE; + + BT_CHECK_LE_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(advertiser); + + // TODO: need to check below logic can be replaced to bt_adapter_le_remove_advertising_data() + + if (pkt_type == BT_ADAPTER_LE_PACKET_ADVERTISING) { + p = &__adv->adv_data; + len = &__adv->adv_data_len; + } else if (pkt_type == BT_ADAPTER_LE_PACKET_SCAN_RESPONSE) { + p = &__adv->scan_rsp_data; + len = &__adv->scan_rsp_data_len; + } else + return BT_ERROR_INVALID_PARAMETER; + + ret = __bt_remove_ad_data_by_type(p, len, + BT_ADAPTER_LE_ADVERTISING_DATA_LOCAL_NAME); + + return ret; +} + int bt_adapter_le_set_advertising_tx_power_level(bt_advertiser_h advertiser, bt_adapter_le_packet_type_e pkt_type, bool include_tx_power) { diff --git a/tests/test/bt_unit_test.c b/tests/test/bt_unit_test.c index a668b33..cccfc5f 100644 --- a/tests/test/bt_unit_test.c +++ b/tests/test/bt_unit_test.c @@ -5250,9 +5250,19 @@ int test_input_callback(void *data) ret = bt_adapter_le_add_advertising_custom_name(advertiser, BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, - "Customname123456789", strlen("Customname123456789")); + "1st custom name", strlen("1st custom name")); if (ret != BT_ERROR_NONE) - TC_PRT("set custom name [0x%04x]", ret); + TC_PRT("add custom name [0x%04x]", ret); + + ret = bt_adapter_le_remove_advertising_custom_name(advertiser, + BT_ADAPTER_LE_PACKET_SCAN_RESPONSE); + if (ret != BT_ERROR_NONE) + TC_PRT("remove custom name [0x%04x]", ret); + + ret = bt_adapter_le_add_advertising_custom_name(advertiser, + BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, "adv custom name", strlen("adv custom name")); + if (ret != BT_ERROR_NONE) + TC_PRT("add custom name [0x%04x]", ret); return 0; default: TC_PRT("No adv data"); -- 2.34.1