From ac44083765bc3b9257a2eb83f34be26e56d6f8ec Mon Sep 17 00:00:00 2001 From: Deokhyun Kim Date: Mon, 13 Jan 2020 20:29:57 +0900 Subject: [PATCH 1/1] Add GATT data batching Change-Id: Ia8219206cf109e0c177fbfa3a2527fd95258641e --- bt-api/bt-device.c | 70 +++++++++++ bt-oal/bluez_hal/src/bt-hal-gatt-client.c | 129 +++++++++++++++++++++ bt-oal/hardware/bt_gatt_client.h | 9 ++ bt-oal/include/oal-gatt.h | 8 ++ bt-oal/oal-gatt.c | 42 +++++++ .../services/bt-request-handler.c | 44 +++++++ .../services/gatt/bt-service-gatt.c | 65 +++++++++++ .../services/include/bt-service-gatt.h | 8 ++ include/bluetooth-api.h | 9 ++ include/bt-internal-types.h | 5 + 10 files changed, 389 insertions(+) diff --git a/bt-api/bt-device.c b/bt-api/bt-device.c index 8b80037..5016d2c 100644 --- a/bt-api/bt-device.c +++ b/bt-api/bt-device.c @@ -446,6 +446,76 @@ BT_EXPORT_API int bluetooth_disconnect_le(const bluetooth_device_address_t *devi return result; } +BT_EXPORT_API int bluetooth_get_gatt_data_batching_available_packets( + int *available_packets) +{ + int result; + int available; + + BT_CHECK_PARAMETER(available_packets, 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_GET_GATT_DATA_BATCHING_AVAILABLE_PACKETS, + in_param1, in_param2, in_param3, in_param4, &out_param); + + if (result == BLUETOOTH_ERROR_NONE) { + available = g_array_index(out_param, guint, 0); + BT_DBG("available_packets: %d", available); + *available_packets = available; + } + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_enable_gatt_data_batching( + const bluetooth_device_address_t *device_address, int packet_threshold, int timeout) +{ + int result; + + BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_ENABLED_ANY(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, device_address, sizeof(bluetooth_device_address_t)); + g_array_append_vals(in_param2, &packet_threshold, sizeof(int)); + g_array_append_vals(in_param3, &timeout, sizeof(int)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_ENABLE_GATT_DATA_BATCHING, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_disable_gatt_data_batching( + const bluetooth_device_address_t *device_address) +{ + int result; + + BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_ENABLED_ANY(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, device_address, sizeof(bluetooth_device_address_t)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_DISABLE_GATT_DATA_BATCHING, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + BT_EXPORT_API int bluetooth_enable_rssi(const bluetooth_device_address_t *remote_address, int link_type, bt_rssi_threshold_t *rssi_threshold) { diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt-client.c b/bt-oal/bluez_hal/src/bt-hal-gatt-client.c index 6a29e5b..b906e45 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt-client.c +++ b/bt-oal/bluez_hal/src/bt-hal-gatt-client.c @@ -3266,6 +3266,132 @@ bt_status_t batchscan_read_reports(int client_if, int scan_mode) return BT_STATUS_UNSUPPORTED; } +bt_status_t btif_gatt_get_data_batching_available_packets(unsigned int *available_packets) +{ + GDBusProxy *proxy; + GError *error = NULL; + GVariant *ret; + guint32 available_pkts; + + CHECK_BTGATT_INIT(); + + if (available_packets == NULL) { + ERR("available_packets is NULL"); + return BT_STATUS_PARM_INVALID; + } + + proxy = _bt_hal_get_adapter_proxy(); + if (proxy == NULL) { + ERR("proxy is NULL"); + return BT_STATUS_FAIL; + } + + ret = g_dbus_proxy_call_sync(proxy, "GetLeBatchingAvailablePkts", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + if (error) { + int result = BT_STATUS_FAIL; + + ERR("SetLeBatchingParam Fail: %s", error->message); + if (g_strrstr(error->message, "Operation is not supported")) + result = BT_STATUS_UNSUPPORTED; + + g_clear_error(&error); + return result; + } + g_variant_get(ret, "(u)", &available_pkts); + g_variant_unref(ret); + + INFO("GATT Batching available packets: %u", available_pkts); + *available_packets = available_pkts; + return BT_STATUS_SUCCESS; +} + +bt_status_t btif_gatt_enable_data_batching(const bt_bdaddr_t *bd_addr, int packet_threshold, int timeout) +{ + char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 }; + GDBusProxy *proxy; + GError *error = NULL; + GVariant *ret; + CHECK_BTGATT_INIT(); + + if (bd_addr == NULL) { + ERR("bd_addr is NULL"); + return BT_STATUS_PARM_INVALID; + } + + proxy = _bt_hal_get_adapter_proxy(); + if (proxy == NULL) { + ERR("proxy is NULL"); + return BT_STATUS_FAIL; + } + + _bt_hal_convert_addr_type_to_string(device_address, + (unsigned char *)bd_addr->address); + ret = g_dbus_proxy_call_sync(proxy, "EnableLeBatching", + g_variant_new("(sii)", device_address, packet_threshold, timeout), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + if (error) { + int result = BT_STATUS_FAIL; + + ERR("SetLeBatchingParam Fail: %s", error->message); + if (g_strrstr(error->message, "Operation is not supported")) + result = BT_STATUS_UNSUPPORTED; + else if (g_strrstr(error->message, "Invalid arguments")) + result = BT_STATUS_PARM_INVALID; + + g_clear_error(&error); + return result; + } + g_variant_unref(ret); + + INFO("GATT Batching is enabled"); + return BT_STATUS_SUCCESS; +} + +bt_status_t btif_gatt_disable_data_batching(const bt_bdaddr_t *bd_addr) +{ + char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 }; + GDBusProxy *proxy; + GError *error = NULL; + GVariant *ret; + CHECK_BTGATT_INIT(); + + if (bd_addr == NULL) { + ERR("bd_addr is NULL"); + return BT_STATUS_PARM_INVALID; + } + + proxy = _bt_hal_get_adapter_proxy(); + if (proxy == NULL) { + ERR("proxy is NULL"); + return BT_STATUS_FAIL; + } + + _bt_hal_convert_addr_type_to_string(device_address, + (unsigned char *)bd_addr->address); + ret = g_dbus_proxy_call_sync(proxy, "DisableLeBatching", + g_variant_new("(s)", device_address), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + if (error) { + int result = BT_STATUS_FAIL; + + ERR("SetLeBatching Fail: %s", error->message); + if (g_strrstr(error->message, "Operation is not supported")) + result = BT_STATUS_UNSUPPORTED; + + g_clear_error(&error); + return result; + } + g_variant_unref(ret); + + INFO("GATT Batching is disabled"); + return BT_STATUS_SUCCESS; +} + const btgatt_client_interface_t btgatt_client_interface = { .register_client = btif_gattc_register_client, .unregister_client = btif_gattc_unregister_client, @@ -3302,6 +3428,9 @@ const btgatt_client_interface_t btgatt_client_interface = { .batchscan_dis_batch_scan = batchscan_dis_batch_scan, .batchscan_read_reports = batchscan_read_reports, .add_connection_info = btif_gattc_add_connection_info, + .get_data_batching_available_packets = btif_gatt_get_data_batching_available_packets, + .enable_data_batching = btif_gatt_enable_data_batching, + .disable_data_batching = btif_gatt_disable_data_batching, }; static hal_gattc_server_info_t *__bt_find_gatt_conn_info(const bt_bdaddr_t *serv_addr) diff --git a/bt-oal/hardware/bt_gatt_client.h b/bt-oal/hardware/bt_gatt_client.h index e879aa7..e9f2983 100644 --- a/bt-oal/hardware/bt_gatt_client.h +++ b/bt-oal/hardware/bt_gatt_client.h @@ -387,6 +387,15 @@ typedef struct { /** Adds a connection info in list */ bt_status_t (*add_connection_info)(const bt_bdaddr_t *bd_addr, int conn_id, int server_inst_id); + + /** Get data batching available packets */ + bt_status_t (*get_data_batching_available_packets)(unsigned int *available_packets); + + /** Enable data batching */ + bt_status_t (*enable_data_batching)(const bt_bdaddr_t *bd_addr, int packet_threshold, int timeout); + + /** Disable data batching */ + bt_status_t (*disable_data_batching)(const bt_bdaddr_t *bd_addr); } btgatt_client_interface_t; __END_DECLS diff --git a/bt-oal/include/oal-gatt.h b/bt-oal/include/oal-gatt.h index d6844c4..ebdf246 100644 --- a/bt-oal/include/oal-gatt.h +++ b/bt-oal/include/oal-gatt.h @@ -525,4 +525,12 @@ oal_status_t gatt_send_response_acquire(int conn_id, int trans_id, oal_status_t gattc_configure_mtu(int conn_id, int mtu); +oal_status_t gatt_get_data_batching_available_packets( + unsigned int *available_packets); + +oal_status_t gatt_enable_data_batching(bt_address_t * address, + int packet_threshold, int timeout); + +oal_status_t gatt_disable_data_batching(bt_address_t * address); + #endif /* OAL_GATT_H_ */ diff --git a/bt-oal/oal-gatt.c b/bt-oal/oal-gatt.c index a5074b7..2ebd7fd 100644 --- a/bt-oal/oal-gatt.c +++ b/bt-oal/oal-gatt.c @@ -2448,6 +2448,48 @@ oal_status_t gattc_configure_mtu(int conn_id, int mtu) BT_ERR("Gatt client configure_mtu error: %s", status2string(ret)); return convert_to_oal_status(ret); } + + return OAL_STATUS_SUCCESS; +} + +oal_status_t gatt_get_data_batching_available_packets( + unsigned int *available_packets) +{ + int ret; + + ret = gatt_api->client->get_data_batching_available_packets(available_packets); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("GATT data batching failed: %s", status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +} + +oal_status_t gatt_enable_data_batching(bt_address_t * address, + int packet_threshold, int timeout) +{ + int ret; + + ret = gatt_api->client->enable_data_batching((bt_bdaddr_t *)address, packet_threshold, timeout); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("GATT data batching failed: %s", status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +} + +oal_status_t gatt_disable_data_batching(bt_address_t * address) +{ + int ret; + + ret = gatt_api->client->disable_data_batching((bt_bdaddr_t *)address); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("GATT data batching failed: %s", status2string(ret)); + return convert_to_oal_status(ret); + } + return OAL_STATUS_SUCCESS; } diff --git a/bt-service-adaptation/services/bt-request-handler.c b/bt-service-adaptation/services/bt-request-handler.c index e8f22ff..d36d751 100644 --- a/bt-service-adaptation/services/bt-request-handler.c +++ b/bt-service-adaptation/services/bt-request-handler.c @@ -2860,6 +2860,46 @@ int __bt_bluez_request(int function_name, } break; } + /* Sync */ + case BT_GET_GATT_DATA_BATCHING_AVAILABLE_PACKETS: { + guint available_packets = 0; + + result = _bt_gatt_get_data_batching_available_packets(&available_packets); + BT_DBG("LE batching available packets %u", available_packets); + if (result == BLUETOOTH_ERROR_NONE) { + g_array_append_vals(*out_param1, &available_packets, + sizeof(guint)); + } + + break; + } + /* Sync */ + case BT_ENABLE_GATT_DATA_BATCHING: { + bluetooth_device_address_t address = { {0} }; + int packet_threshold; + int timeout; + + __bt_service_get_parameters(in_param1, + &address, sizeof(bluetooth_device_address_t)); + __bt_service_get_parameters(in_param2, + &packet_threshold, sizeof(int)); + __bt_service_get_parameters(in_param3, + &timeout, sizeof(int)); + result = _bt_gatt_enable_data_batching(&address, packet_threshold, timeout); + + break; + } + /* Sync */ + case BT_DISABLE_GATT_DATA_BATCHING: { + bluetooth_device_address_t address = { {0} }; + + __bt_service_get_parameters(in_param1, + &address, sizeof(bluetooth_device_address_t)); + result = _bt_gatt_disable_data_batching(&address); + + break; + } + case BT_GATT_GET_PRIMARY_SERVICES: { char *addr; @@ -4174,6 +4214,10 @@ gboolean __bt_service_check_privilege(int function_name, case BT_LE_OOB_READ_LOCAL_DATA: case BT_LE_OOB_ADD_REMOTE_DATA: + case BT_GET_GATT_DATA_BATCHING_AVAILABLE_PACKETS: + case BT_ENABLE_GATT_DATA_BATCHING: + case BT_DISABLE_GATT_DATA_BATCHING: + case BT_LE_IPSP_INIT: case BT_LE_IPSP_DEINIT: case BT_LE_IPSP_CONNECT: diff --git a/bt-service-adaptation/services/gatt/bt-service-gatt.c b/bt-service-adaptation/services/gatt/bt-service-gatt.c index 3067535..737740d 100644 --- a/bt-service-adaptation/services/gatt/bt-service-gatt.c +++ b/bt-service-adaptation/services/gatt/bt-service-gatt.c @@ -5145,5 +5145,70 @@ static void __bt_update_mtu_gatt_device(char *address, int mtu) } } +int _bt_gatt_get_data_batching_available_packets( + guint *available_packets) +{ + int ret = OAL_STATUS_SUCCESS; + + BT_CHECK_PARAMETER(available_packets, return); + + ret = gatt_get_data_batching_available_packets(available_packets); + if (ret != OAL_STATUS_SUCCESS) { + BT_ERR("ret: %d", ret); + if (ret == OAL_STATUS_NOT_SUPPORT) + return BLUETOOTH_ERROR_NOT_SUPPORT; + return BLUETOOTH_ERROR_INTERNAL; + } + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_gatt_enable_data_batching(bluetooth_device_address_t *address, + int packet_threshold, int timeout) +{ + int ret = OAL_STATUS_SUCCESS; + char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 }; + + BT_CHECK_PARAMETER(address, return); + + _bt_convert_addr_type_to_string(remote_address, address->addr); + BT_INFO("Enable GATT data batching. address[%s] packet_threshold[%d] timeout[%d]", + remote_address, packet_threshold, timeout); + + ret = gatt_enable_data_batching((bt_address_t*)(address), packet_threshold, timeout); + + if (ret != OAL_STATUS_SUCCESS) { + BT_ERR("ret: %d", ret); + if (ret == OAL_STATUS_INVALID_PARAM) + return BLUETOOTH_ERROR_INVALID_PARAM; + else if (ret == OAL_STATUS_NOT_SUPPORT) + return BLUETOOTH_ERROR_NOT_SUPPORT; + return BLUETOOTH_ERROR_INTERNAL; + } + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_gatt_disable_data_batching(bluetooth_device_address_t *address) +{ + int ret = OAL_STATUS_SUCCESS; + char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 }; + + BT_CHECK_PARAMETER(address, return); + + _bt_convert_addr_type_to_string(remote_address, address->addr); + BT_INFO("Disable GATT data batching. address[%s]", remote_address); + + ret = gatt_disable_data_batching((bt_address_t*)(address)); + + if (ret != OAL_STATUS_SUCCESS) { + BT_ERR("ret: %d", ret); + if (ret == OAL_STATUS_NOT_SUPPORT) + return BLUETOOTH_ERROR_NOT_SUPPORT; + return BLUETOOTH_ERROR_INTERNAL; + } + + return BLUETOOTH_ERROR_NONE; +} #endif diff --git a/bt-service-adaptation/services/include/bt-service-gatt.h b/bt-service-adaptation/services/include/bt-service-gatt.h index 70a2ce7..48ab767 100644 --- a/bt-service-adaptation/services/include/bt-service-gatt.h +++ b/bt-service-adaptation/services/include/bt-service-gatt.h @@ -117,6 +117,14 @@ void _bt_handle_invocation_context(int function_name, void *data); int _bt_connect_le_device(bluetooth_device_address_t *address, int auto_connect, int client_id); +int _bt_gatt_get_data_batching_available_packets( + guint *available_packets); + +int _bt_gatt_enable_data_batching(bluetooth_device_address_t *address, + int packet_threshold, int timeout); + +int _bt_gatt_disable_data_batching(bluetooth_device_address_t *address); + int _bt_gatt_get_primary_services(char *address); int _bt_gatt_get_all_characteristic(bluetooth_gatt_client_svc_prop_info_t *svc); diff --git a/include/bluetooth-api.h b/include/bluetooth-api.h index 451a005..50ee9a9 100644 --- a/include/bluetooth-api.h +++ b/include/bluetooth-api.h @@ -5690,6 +5690,15 @@ int bluetooth_disconnect_le(const bluetooth_device_address_t *device_address, int bluetooth_disconnect_le(const bluetooth_device_address_t *device_address); #endif +int bluetooth_get_gatt_data_batching_available_packets( + int *available_packets); + +int bluetooth_enable_gatt_data_batching( + const bluetooth_device_address_t *device_address, int packet_threshold, int timeout); + +int bluetooth_disable_gatt_data_batching( + const bluetooth_device_address_t *device_address); + /** * @fn int bluetooth_gatt_discover_characteristic_descriptor(const char *characteristic_handle); * diff --git a/include/bt-internal-types.h b/include/bt-internal-types.h index c9e06a3..f43b0d0 100644 --- a/include/bt-internal-types.h +++ b/include/bt-internal-types.h @@ -354,6 +354,11 @@ typedef enum { BT_GET_ATT_MTU, BT_GET_DEVICE_IDA, BT_SET_LE_STATIC_RANDOM_ADDRESS, + + BT_GET_GATT_DATA_BATCHING_AVAILABLE_PACKETS, + BT_ENABLE_GATT_DATA_BATCHING, + BT_DISABLE_GATT_DATA_BATCHING, + BT_HDP_CONNECT = BT_FUNC_HDP_BASE, BT_HDP_DISCONNECT, BT_HDP_SEND_DATA, -- 2.7.4