4 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Anupam Roy <anupam.r@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 #include <hardware/bluetooth.h>
23 #include <hardware/bt_gatt.h>
33 #include "bt-hal-log.h"
34 #include "bt-hal-msg.h"
35 #include "bt-hal-event-receiver.h"
36 #include "bt-hal-adapter-le.h"
38 #include "bt-hal-gatt-client.h"
39 #include "bt-hal-dbus-common-utils.h"
40 #include "bt-hal-utils.h"
42 /************************************************************************************
44 ************************************************************************************/
45 extern const btgatt_callbacks_t *bt_gatt_callbacks;
46 #define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
48 ERR("%s: BTGATT not initialized", __FUNCTION__);\
49 return BT_STATUS_NOT_READY;\
51 DBG("%s", __FUNCTION__);\
55 int le_scan_type = BT_GATTC_LE_SCAN_TYPE_PASSIVE;
58 static handle_stack_msg event_cb = NULL;
60 #define GATT_SERV_INTERFACE "org.bluez.GattService1"
61 #define MAX_HAL_OBJECT_PATH_LEN 100
64 HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST = 0x01,
65 HAL_GATT_CHARACTERISTIC_PROPERTY_READ = 0x02,
66 HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE = 0x04,
67 HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE = 0x08,
68 HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY = 0x10,
69 HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE = 0x20,
70 HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE = 0x40,
71 HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE = 0x80,
72 HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES = 0x100,
73 HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ = 0x200,
74 HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE = 0x400,
75 HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ = 0x800,
76 HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE = 0x1000,
77 HAL_GATT_CHARACTERISTIC_PROPERTY_EXTENDED_PROPS = 0xffff,
78 } bt_gatt_characteristic_property_t;
82 HAL_GATT_WRITE_TYPE_WRITE_NO_RESPONSE = 1,
83 HAL_GATT_WRITE_TYPE_WRITE ,
84 } hal_gatt_write_type_t;
88 HAL_GATT_PROPERTY_BROADCAST = 0x01, /**< Broadcast property */
89 HAL_GATT_PROPERTY_READ = 0x02, /**< Read property */
90 HAL_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE = 0x04, /**< Write without response property */
91 HAL_GATT_PROPERTY_WRITE = 0x08, /**< Write property */
92 HAL_GATT_PROPERTY_NOTIFY = 0x10, /**< Notify property */
93 HAL_GATT_PROPERTY_INDICATE = 0x20, /**< Indicate property */
94 HAL_GATT_PROPERTY_AUTHENTICATED_SIGNED_WRITES = 0x40, /**< Authenticated signed writes property */
95 HAL_GATT_PROPERTY_EXTENDED_PROPERTIES = 0x80, /**< Extended properties */
96 } hal_gatt_property_e;
101 gboolean auto_connect;
102 } bt_pending_le_conn_info_s;
112 unsigned int permission;
113 GSList *gatt_list_descs;
119 GSList *gatt_list_chars;
120 } hal_gattc_service_t;
123 bt_bdaddr_t bd_addr; /*remote server address*/
124 int inst_id; /*server instance id*/
125 GSList *gatt_list_services;
126 } hal_gattc_server_info_t;
128 /* Linked List of connected GATT server */
129 static GSList *hal_gattc_server_info_list = NULL;
133 bt_bdaddr_t bd_addr; /*remote server address*/
136 } hal_gattc_client_info_t;
138 /* Linked list of connected GATT client connection */
139 static GSList * hal_gattc_client_info_list = NULL;
142 static bt_pending_le_conn_info_s *pending_le_conn_info = NULL;
143 static guint pending_le_conn_timer_id = 0;
144 static int bt_conn_id = 0;
145 static int bt_inst_id = 0;
147 #define BT_GATTC_CL_MAX 32
151 btgatt_srvc_id_t srvc_id;
152 btgatt_gatt_id_t char_id;
153 btgatt_gatt_id_t desc_id;
154 } hal_gatt_resp_data_t;
160 } hal_gatt_client_app;
162 static GSList * hal_gattc_client_app_list = NULL;
164 static int bt_client_if = 0;
167 static bt_status_t __bt_connect_le_device_internal(int client_if, const bt_bdaddr_t *bd_addr,
168 gboolean auto_connect);
169 static bt_status_t _bt_hold_current_advertising();
170 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data);
171 static gboolean __bt_connect_le_timer_cb(gpointer user_data);
172 static void __le_connection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
174 static hal_gattc_server_info_t *__bt_find_gatt_conn_info_from_conn_id(int conn_id);
175 static void _bt_hal_send_search_service_result_event(int conn_id, int is_primary,
176 const char* uuid_str, int inst_id);
177 static void _bt_hal_send_search_service_complete_event(int conn_id, int status);
180 /* To send stack event to hal-av handler */
181 void _bt_hal_register_gatt_client_handler_cb(handle_stack_msg cb)
186 void _bt_hal_unregister_gatt_client_handler_cb(void)
192 int _bt_hal_gatt_client_get_le_scan_type(void)
198 static gboolean __bt_hal_register_client_cb(gpointer user_data)
200 struct hal_ev_gatt_client_registered ev;
201 hal_gatt_client_app *client_info = user_data;
204 /* Prepare to send AV connecting event */
205 memset(&ev, 0, sizeof(ev));
206 ev.status = BT_STATUS_SUCCESS;
207 ev.client_if = client_info->client_if;
208 memcpy(ev.app_uuid, client_info->app_uuid.uu, sizeof(ev.app_uuid));
211 ERR("GATT Callback not registered");
213 DBG("GATT client registered, client_if: [%d]", client_info->client_if);
214 event_cb(HAL_EV_GATT_CLIENT_REGISTERED, (void *)&ev, sizeof(ev));
221 static int __hal_generate_client_id()
223 return ++bt_client_if;
226 static hal_gatt_client_app *__hal_gattc_add_client_app(bt_uuid_t *app_uuid)
229 hal_gatt_client_app *info = NULL;
230 hal_gatt_client_app *gattc_app = NULL;
232 //check if client app is already registered
233 for (l = hal_gattc_client_app_list; l != NULL; l = g_slist_next(l)) {
234 info = (hal_gatt_client_app*)l->data;
238 if (memcmp(&info->app_uuid, app_uuid, sizeof(bt_uuid_t)) == 0) {
239 DBG("gatt client app already registered");
244 DBG("adding the gatt client app");
247 gattc_app = g_malloc0(sizeof(hal_gatt_client_app));
248 if (gattc_app == NULL) {
249 DBG("Failed to allocate memory");
253 gattc_app->client_if = __hal_generate_client_id();
254 memcpy(&gattc_app->app_uuid, app_uuid, sizeof(bt_uuid_t));
256 hal_gattc_client_app_list = g_slist_append(hal_gattc_client_app_list, gattc_app);
261 static bt_status_t __hal_gattc_register_client_app(bt_uuid_t *app_uuid)
263 hal_gatt_client_app *gattc_app = NULL;
264 hal_gatt_client_app *client_app_info = NULL;
267 /* add gatt client in list */
268 gattc_app = __hal_gattc_add_client_app(app_uuid);
269 if (gattc_app == NULL) {
270 ERR("Failed to register gatt client app");
271 return BT_STATUS_FAIL;
275 client_app_info = g_malloc0(sizeof(hal_gatt_client_app));
276 if (NULL == client_app_info) {
277 ERR("Failed to allocate memory");
278 return BT_STATUS_FAIL;
281 client_app_info->client_if = gattc_app->client_if;
282 memcpy(&client_app_info->app_uuid, app_uuid, sizeof(bt_uuid_t));
283 g_idle_add(__bt_hal_register_client_cb, (gpointer)client_app_info);
285 DBG("registered client client_if [%d]", client_app_info->client_if);
287 return BT_STATUS_SUCCESS;
290 /** Registers a GATT client application with the stack */
291 bt_status_t btif_gattc_register_client(bt_uuid_t *uuid)
296 return __hal_gattc_register_client_app(uuid);
299 bt_status_t __hal_gattc_unregister_client(int client_if)
302 hal_gatt_client_app *info = NULL;
304 DBG("registered client count: [%d]", g_slist_length(hal_gattc_client_app_list));
306 /* remove the gatt client app */
307 for (l = hal_gattc_client_app_list; l != NULL; ) {
308 info = (hal_gatt_client_app*)l->data;
314 if (info->client_if == client_if) {
315 DBG("gatt client app found");
316 hal_gattc_client_app_list = g_slist_remove(hal_gattc_client_app_list, info);
321 DBG("registered client count: [%d]", g_slist_length(hal_gattc_client_app_list));
322 return BT_STATUS_SUCCESS;
325 /** Unregister a client application from the stack */
326 bt_status_t btif_gattc_unregister_client(int client_if)
331 return __hal_gattc_unregister_client(client_if);
334 /** Start or stop LE device scanning */
335 bt_status_t scan(int client_if, bool start)
342 ret = _bt_hal_adapter_le_start_scan();
344 ret = _bt_hal_adapter_le_stop_scan();
349 /** Create a connection to a remote LE or dual-mode device */
350 bt_status_t btif_gattc_client_connect(int client_if, const bt_bdaddr_t *bd_addr,
353 int ret = BT_STATUS_SUCCESS;
359 return BT_STATUS_PARM_INVALID;
361 ret = _bt_hold_current_advertising();
362 if (ret == BT_STATUS_SUCCESS) {
363 DBG("Current advertising is held");
364 pending_le_conn_info = g_malloc0(sizeof(bt_pending_le_conn_info_s));
365 pending_le_conn_info->client_if = client_if;
366 memcpy(pending_le_conn_info->bd_addr.address, bd_addr->address,
367 BT_HAL_ADDRESS_LENGTH_MAX);
368 pending_le_conn_info->auto_connect = is_direct;
370 pending_le_conn_timer_id =
371 g_timeout_add(1000, __bt_connect_le_timer_cb, NULL);
373 return BT_STATUS_SUCCESS;
375 ERR("advertising is not stopped");
378 return __bt_connect_le_device_internal(client_if, bd_addr, is_direct);
382 static void __le_disconnection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
385 GError *g_error = NULL;
386 GVariant *reply = NULL;
387 hal_gattc_client_info_t *gatt_conn_info = user_data;
388 int result = BT_STATUS_SUCCESS;
389 struct hal_ev_gatt_client_connected ev;
393 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
394 g_object_unref(proxy);
396 ERR("Connect LE Dbus Call Error");
398 ERR("Error: %s\n", g_error->message);
399 g_clear_error(&g_error);
401 result = BT_STATUS_FAIL;
403 g_variant_unref(reply);
405 if (NULL == gatt_conn_info) {
406 ERR("server_data is NULL");
411 if (result == BT_STATUS_FAIL) {
412 memset(&ev, 0, sizeof(ev));
413 ev.conn_id = gatt_conn_info->conn_id;
415 ev.client_if = gatt_conn_info->client_if;
416 memcpy(ev.bdaddr, gatt_conn_info->bd_addr.address,
417 BT_HAL_ADDRESS_LENGTH_MAX);
420 ERR("gatt client callback not registered");
422 DBG("sending gatt client disconnected event");
423 event_cb(HAL_EV_GATT_CLIENT_DISCONNECTED, (void *)&ev, sizeof(ev));
429 g_free(gatt_conn_info);
434 bt_status_t _hal_gattc_disconnect(int client_if, const bt_bdaddr_t *bd_addr,
437 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
439 GDBusProxy *device_proxy;
440 GDBusConnection *conn;
441 int ret = BT_STATUS_SUCCESS;
442 hal_gattc_client_info_t *gattc_data;
444 if (NULL == bd_addr) {
445 ERR("bd_addr is NULL");
446 return BT_STATUS_PARM_INVALID;
449 conn = _bt_hal_get_system_gconn();
451 ERR("_bt_gdbus_get_system_gconn returned NULL");
452 return BT_STATUS_FAIL;
455 _bt_hal_convert_addr_type_to_string(device_address,
456 (unsigned char *)bd_addr->address);
457 device_path = _bt_hal_get_device_object_path(device_address);
458 if (device_path == NULL) {
459 DBG("device_path NULL");
460 ret = BT_STATUS_FAIL;
464 ERR("device_path:%s", device_path);
466 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
467 NULL, BT_HAL_BLUEZ_NAME,
468 device_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
470 if (NULL == device_proxy) {
471 ERR("device_proxy returned NULL");
472 return BT_STATUS_FAIL;
475 gattc_data = g_malloc0(sizeof(hal_gattc_client_info_t));
476 if (NULL == gattc_data) {
477 ERR("Unable to allocate memory");
478 ret = BT_STATUS_FAIL;
482 memcpy(gattc_data->bd_addr.address, bd_addr->address,
483 BT_HAL_ADDRESS_LENGTH_MAX);
484 gattc_data->client_if = client_if;
485 gattc_data->conn_id = conn_id;
487 DBG("DisconnectLE [%s]", device_address);
489 g_dbus_proxy_call(device_proxy, "DisconnectLE",
491 G_DBUS_CALL_FLAGS_NONE,
492 BT_HAL_MAX_DBUS_TIMEOUT,
494 (GAsyncReadyCallback)__le_disconnection_req_cb, gattc_data);
498 g_object_unref(device_proxy);
505 /** Disconnect a remote device or cancel a pending connection */
506 bt_status_t btif_gattc_client_disconnect(int client_if, const bt_bdaddr_t *bd_addr,
513 return _hal_gattc_disconnect(client_if, bd_addr, conn_id);
516 /** Clear the attribute cache for a given device */
517 bt_status_t refresh(int client_if, const bt_bdaddr_t *bd_addr)
520 return BT_STATUS_UNSUPPORTED;
523 static hal_gattc_service_t* _gattc_find_service_from_uuid(hal_gattc_server_info_t *conn_info, bt_uuid_t *svc_uuid)
528 hal_gattc_service_t *info = NULL;
530 for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
531 info = (hal_gattc_service_t*)l->data;
535 if (!memcmp(&info->svc_uuid, svc_uuid, sizeof(bt_uuid_t))) {
536 INFO("Found GATT service uuid");
544 static hal_gattc_char_t* _gattc_find_char_from_uuid(hal_gattc_service_t *gattc_svc, bt_uuid_t *char_uuid)
549 hal_gattc_char_t *info = NULL;
551 for (l = gattc_svc->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
552 info = (hal_gattc_char_t*)l->data;
556 if (!memcmp(&info->chr_uuid, char_uuid, sizeof(bt_uuid_t))) {
557 INFO("Found GATT char uuid");
564 static hal_gattc_desc_t* _gattc_find_desc_from_uuid(hal_gattc_char_t *gattc_char, bt_uuid_t *desc_uuid)
569 hal_gattc_desc_t *info = NULL;
571 for (l = gattc_char->gatt_list_descs; l != NULL; l = g_slist_next(l)) {
572 info = (hal_gattc_desc_t*)l->data;
576 if (!memcmp(&info->desc_uuid, desc_uuid, sizeof(bt_uuid_t))) {
577 INFO("Found GATT descriptor uuid");
585 static hal_gattc_service_t* _hal_gatt_client_add_service(hal_gattc_server_info_t *conn_info,
586 const char *uuid_str, char *object_path)
589 hal_gattc_service_t *gattc_service = NULL;
591 gattc_service = g_malloc0(sizeof(hal_gattc_service_t));
592 gattc_service->svc_path = g_strdup(object_path);
593 _bt_hal_convert_uuid_string_to_type(gattc_service->svc_uuid.uu, uuid_str);
595 DBG("service count[%d]", g_slist_length(conn_info->gatt_list_services));
597 conn_info->gatt_list_services = g_slist_append(conn_info->gatt_list_services, gattc_service);
599 DBG("svc path {%s] svc uuid [%s]", object_path, uuid_str);
601 return gattc_service;
604 static void _hal_gattc_add_characteristic(hal_gattc_service_t *gatt_svc, char *char_handle)
607 hal_gattc_char_t *gattc_char = NULL;
609 gattc_char = g_malloc0(sizeof(hal_gattc_char_t));
610 gattc_char->chr_path = g_strdup(char_handle);
612 DBG("svc path: [%s]", gatt_svc->svc_path);
613 DBG("char path: [%s]", gattc_char->chr_path);
615 gatt_svc->gatt_list_chars = g_slist_append(gatt_svc->gatt_list_chars, gattc_char);
618 static void _gattc_create_new_service(hal_gattc_server_info_t *conn_info, gboolean is_primary,
619 const char* uuid_str, char *object_path, GPtrArray *gp_char_array)
621 hal_gattc_service_t* gatt_svc = NULL;
623 gchar *gp_char_path = NULL;
627 /* add the service */
628 gatt_svc = _hal_gatt_client_add_service(conn_info, uuid_str, object_path);
629 if (gatt_svc == NULL) {
630 ERR("Failed to add service");
634 /* add the characteristic */
635 for (i = 0; i < gp_char_array->len; i++) {
636 gp_char_path = g_ptr_array_index(gp_char_array, i);
637 _hal_gattc_add_characteristic(gatt_svc, gp_char_path);
640 g_ptr_array_free(gp_char_array, TRUE);
643 static void _hal_gattc_add_descriptor(hal_gattc_char_t *gattc_char, char *desc_path)
645 hal_gattc_desc_t *gattc_desc = NULL;
647 gattc_desc = g_malloc0(sizeof(hal_gattc_desc_t));
648 gattc_desc->desc_path = g_strdup(desc_path);
650 gattc_char->gatt_list_descs = g_slist_append(gattc_char->gatt_list_descs, gattc_desc);
652 DBG("char path: [%s]", gattc_char->chr_path);
653 DBG("desc path: [%s]", gattc_desc->desc_path);
656 static void _hal_gattc_update_char_property(hal_gattc_char_t *gattc_char, const char* char_uuid_str,
657 GPtrArray *gp_desc_array, unsigned int char_permission)
659 gchar *gp_desc_path = NULL;
664 if (char_uuid_str == NULL) {
665 DBG("char_uuid_str is NULL");
669 //update the char uuid
670 DBG("char UUID: [%s] ", char_uuid_str);
671 DBG("char path: [%s]", gattc_char->chr_path);
673 _bt_hal_convert_uuid_string_to_type(gattc_char->chr_uuid.uu, char_uuid_str);
675 //update char permission
676 gattc_char->permission = char_permission;
679 for (i = 0; i < gp_desc_array->len; i++) {
680 gp_desc_path = g_ptr_array_index(gp_desc_array, i);
681 _hal_gattc_add_descriptor(gattc_char, gp_desc_path);
685 static void _hal_gattc_update_desc_property(hal_gattc_desc_t *gattc_desc, const char* desc_uuid_str)
689 if (desc_uuid_str == NULL) {
690 DBG("char_uuid_str is NULL");
694 //update the descriptor uuid
695 DBG("desc UUID: [%s] ", desc_uuid_str);
696 DBG("desc path: [%s]", gattc_desc->desc_path);
698 _bt_hal_convert_uuid_string_to_type(gattc_desc->desc_uuid.uu, desc_uuid_str);
701 static void browse_service_char(int conn_id)
703 hal_gattc_server_info_t *conn_info = NULL;
707 hal_gattc_service_t *svc_info = NULL;
708 hal_gattc_char_t *char_info = NULL;
709 hal_gattc_desc_t *desc_info = NULL;
713 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
714 if (conn_info == NULL) {
715 DBG("conn_info is NULL");
719 DBG("service count[%d]", g_slist_length(conn_info->gatt_list_services));
721 for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
722 svc_info = (hal_gattc_service_t*)l->data;
723 if (svc_info == NULL)
726 DBG("svc path [%s]", svc_info->svc_path);
728 /* find characteristic object path */
729 for (k = svc_info->gatt_list_chars; k != NULL; k = g_slist_next(k)) {
730 char_info = (hal_gattc_char_t *)k->data;
731 if (char_info == NULL)
734 DBG("char path[%s]", char_info->chr_path);
737 for (m = char_info->gatt_list_descs; m != NULL; m = g_slist_next(m)) {
738 desc_info = (hal_gattc_desc_t *)m->data;
739 if (desc_info == NULL)
742 DBG("desc path[%s]", desc_info->desc_path);
751 * Enumerate all GATT services on a connected device.
752 * Optionally, the results can be filtered for a given UUID.
754 static bt_status_t _gattc_client_search_service(int conn_id)
758 GVariant *result = NULL;
760 GVariantIter *svc_iter;
761 GVariantIter *interface_iter;
762 char *object_path = NULL;
763 char *interface_str = NULL;
764 const gchar *key = NULL;
765 GVariant *value = NULL;
766 GPtrArray *gp_array = NULL;
767 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
768 char temp_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
769 int ret = BT_STATUS_FAIL;
771 const gchar *uuid_str = NULL;
773 hal_gattc_server_info_t *conn_info = NULL;
774 gboolean is_primary = FALSE;
777 char *char_handle = NULL;
778 GVariantIter *char_iter = NULL;
779 GPtrArray *gp_char_array = NULL;
783 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
784 if (NULL == conn_info) {
785 DBG("Failed to get the conn_info");
786 return BT_STATUS_FAIL;
789 _bt_hal_convert_addr_type_to_string(device_address,
790 (unsigned char *)conn_info->bd_addr.address);
792 result = _bt_hal_get_managed_objects();
796 gp_array = g_ptr_array_new();
797 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
799 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
801 if (object_path == NULL)
804 _bt_hal_convert_device_path_to_address(object_path, temp_address);
806 if (g_strcmp0(temp_address, device_address) != 0)
809 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
810 &interface_str, &svc_iter)) {
811 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
814 DBG("[%d] Object Path : %s", idx++, object_path);
815 /* for characteristic */
816 gp_char_array = g_ptr_array_new();
817 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
818 if (g_strcmp0(key, "Primary") == 0) {
819 is_primary = g_variant_get_boolean(value);
822 g_ptr_array_add(gp_array, (gpointer)object_path);
825 } else if (g_strcmp0(key, "UUID") == 0) {
826 uuid_str = g_variant_get_string(value, &len);
827 DBG(" UUID: [%s]", uuid_str);
828 } else if (g_strcmp0(key, "Characteristics") == 0) {
829 g_variant_get(value, "ao", &char_iter);
830 if (char_iter != NULL) {
831 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
832 DBG("char handle : %s", char_handle);
833 g_ptr_array_add(gp_char_array, (gpointer)char_handle);
840 DBG("send search service result event");
841 _bt_hal_send_search_service_result_event(conn_id, is_primary,
842 uuid_str, conn_info->inst_id);
844 _gattc_create_new_service(conn_info, is_primary, uuid_str, object_path, gp_char_array);
849 if (gp_array->len == 0 || svc_count == 0) {
850 ERR("gp_array is NULL");
851 ret = BT_STATUS_FAIL;
853 ret = BT_STATUS_SUCCESS;
856 browse_service_char(conn_id);
857 /* send search service complete event */
858 _bt_hal_send_search_service_complete_event(conn_id, ret);
860 g_ptr_array_free(gp_array, TRUE);
861 g_variant_iter_free(iter);
862 g_variant_unref(result);
867 bt_status_t btif_gattc_client_search_service(int conn_id, bt_uuid_t *filter_uuid)
869 if (NULL == filter_uuid) {
870 DBG("Browse all the services");
871 return _gattc_client_search_service(conn_id);
873 DBG("TODO implement it");
874 return BT_STATUS_UNSUPPORTED;
878 * Enumerate included services for a given service.
879 * Set start_incl_srvc_id to NULL to get the first included service.
881 bt_status_t get_included_service(int conn_id, btgatt_srvc_id_t *srvc_id,
882 btgatt_srvc_id_t *start_incl_srvc_id)
885 return BT_STATUS_UNSUPPORTED;
888 static void _bt_hal_send_client_char_search_result_event(int conn_id, int status,
889 btgatt_srvc_id_t *svc_id, bt_uuid_t *char_uuid, int char_prop)
891 struct hal_ev_gatt_client_char_search_result ev;
894 ERR("gatt client callback not registered");
898 DBG("sending gatt client search char result event conn_id[%d] status[%d]", conn_id, status);
900 memset(&ev, 0, sizeof(ev));
901 ev.conn_id = conn_id;
902 ev.inst_id = svc_id->id.inst_id;
903 ev.is_primary = svc_id->is_primary;
905 memcpy(ev.svc_uuid, svc_id->id.uuid.uu, sizeof(ev.svc_uuid));
907 if (status == BT_STATUS_SUCCESS) {
908 DBG("building char uuid");
909 memcpy(ev.char_uuid, char_uuid->uu, sizeof(ev.char_uuid));
910 ev.char_prop = char_prop;
913 DBG("sending the char search event");
915 event_cb(HAL_EV_GATT_CLIENT_CHARAC_SEARCH_RESULT, (void *)&ev, sizeof(ev));
918 static int _hal_get_permission_flag(char *permission)
922 if (NULL == permission) {
923 ERR("gatt permission is NULL");
927 if (!g_strcmp0(permission, "broadcast"))
928 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
929 else if (!g_strcmp0(permission, "read"))
930 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_READ;
931 else if (!g_strcmp0(permission, "write-without-response"))
932 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
933 else if (!g_strcmp0(permission, "write"))
934 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE;
935 else if (!g_strcmp0(permission, "notify"))
936 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
937 else if (!g_strcmp0(permission, "indicate"))
938 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
939 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
940 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
941 else if (!g_strcmp0(permission, "reliable-write"))
942 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
943 else if (!g_strcmp0(permission, "writable-auxiliaries"))
944 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
945 else if (!g_strcmp0(permission, "encrypt-read"))
946 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
947 else if (!g_strcmp0(permission, "encrypt-write"))
948 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
949 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
950 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
951 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
952 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
958 static bt_status_t _hal_gattc_get_characteristic_info(hal_gattc_char_t *gattc_char)
960 GDBusProxy *properties_proxy = NULL;
961 GError *error = NULL;
962 GVariant *value = NULL;
963 GVariant *result = NULL;
964 GDBusConnection *g_conn;
966 char *char_desc_handle = NULL;
968 GVariantIter *property_iter;
969 GVariantIter *char_desc_iter;
970 char* char_handle = NULL;
971 const gchar *char_uuid_str = NULL;
972 GPtrArray *gp_desc_array = NULL;
973 GVariantIter *char_perm_iter;
975 unsigned int char_permission = 0 ;
979 if (gattc_char->chr_path == NULL) {
980 DBG("char path is NULL");
981 return BT_STATUS_FAIL;
983 char_handle = gattc_char->chr_path;
985 DBG("char path:[%s]", gattc_char->chr_path);
987 g_conn = _bt_hal_get_system_gconn();
988 if (NULL == g_conn) {
989 ERR("_bt_gdbus_get_system_gconn returned NULL");
990 return BT_STATUS_FAIL;
993 properties_proxy = g_dbus_proxy_new_sync(g_conn,
994 G_DBUS_PROXY_FLAGS_NONE, NULL,
997 BT_HAL_PROPERTIES_INTERFACE,
1000 if (properties_proxy == NULL) {
1001 ERR("properties_proxy returned NULL");
1002 return BT_STATUS_FAIL;
1005 result = g_dbus_proxy_call_sync(properties_proxy,
1007 g_variant_new("(s)", BT_HAL_GATT_CHAR_INTERFACE),
1008 G_DBUS_CALL_FLAGS_NONE,
1013 if (error != NULL) {
1014 ERR("Fail to get properties (Error: %s)", error->message);
1015 g_clear_error(&error);
1017 ERR("Fail to get properties");
1018 g_object_unref(properties_proxy);
1019 return BT_STATUS_FAIL;
1022 gp_desc_array = g_ptr_array_new();
1024 g_variant_get(result, "(a{sv})", &property_iter);
1026 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1027 if (!g_strcmp0(key, "UUID")) {
1028 char_uuid_str = g_variant_dup_string(value, &len);
1029 DBG("char UUID [%s]", char_uuid_str);
1030 } else if (!g_strcmp0(key, "Flags")) {
1031 g_variant_get(value, "as", &char_perm_iter);
1032 char_permission = 0x00;
1034 while (g_variant_iter_loop(char_perm_iter, "s", &permission)) {
1035 DBG("char permission: [%s]", permission);
1036 char_permission |= _hal_get_permission_flag(permission);
1038 } else if (!g_strcmp0(key, "Descriptors")) {
1039 g_variant_get(value, "ao", &char_desc_iter);
1040 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle)) {
1041 DBG("char descriptor handle : %s", char_desc_handle);
1043 g_ptr_array_add(gp_desc_array, (gpointer)char_desc_handle);
1048 _hal_gattc_update_char_property(gattc_char, char_uuid_str, gp_desc_array, char_permission);
1050 g_variant_iter_free(property_iter);
1051 g_variant_unref(result);
1052 g_object_unref(properties_proxy);
1053 g_ptr_array_free(gp_desc_array, TRUE);
1055 return BT_STATUS_SUCCESS;
1058 static bt_status_t _gattc_get_all_characteristic(int conn_id,
1059 btgatt_srvc_id_t *srvc_id)
1061 hal_gattc_server_info_t * conn_info = NULL;
1062 hal_gattc_service_t *gattc_service = NULL;
1064 hal_gattc_char_t *gattc_char = NULL;
1065 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1066 int status = BT_STATUS_FAIL;
1069 DBG("conn_id[%d]", conn_id);
1071 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1072 if (NULL == conn_info) {
1073 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1074 return BT_STATUS_FAIL;
1078 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1079 if (NULL == gattc_service) {
1080 DBG("Failed to get the gatt service");
1081 return BT_STATUS_FAIL;
1084 DBG("service path [%s]", gattc_service->svc_path);
1086 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1087 DBG("service uuid [%s]", svc_uuid_str);
1089 /* find characteristic object path */
1090 for (l = gattc_service->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
1091 gattc_char = (hal_gattc_char_t *)l->data;
1092 status = _hal_gattc_get_characteristic_info(gattc_char);
1095 if (BT_STATUS_SUCCESS == status) {
1096 DBG("Sending the success charateristics event");
1097 _bt_hal_send_client_char_search_result_event(conn_id, status, srvc_id,
1098 &gattc_char->chr_uuid, gattc_char->permission);
1102 DBG("sending final event");
1104 status = BT_STATUS_FAIL;
1105 _bt_hal_send_client_char_search_result_event(conn_id, status, srvc_id, NULL, 0);
1107 browse_service_char(conn_id);
1108 /* retrive uuid for characteristic and object path for descriptor */
1110 return BT_STATUS_SUCCESS;
1114 * Enumerate characteristics for a given service.
1115 * Set start_char_id to NULL to get the first characteristic.
1117 bt_status_t btif_gattc_get_characteristic(int conn_id,
1118 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *start_char_id)
1121 CHECK_BTGATT_INIT();
1123 if (start_char_id == NULL) {
1124 DBG("Get all the characteristics");
1125 return _gattc_get_all_characteristic(conn_id, srvc_id);
1128 DBG("TBD Get specific characteristics");
1129 return BT_STATUS_UNSUPPORTED;
1133 static bt_status_t _hal_gattc_get_descriptor_info(hal_gattc_desc_t *gattc_desc)
1135 GDBusProxy *properties_proxy = NULL;
1136 GError *error = NULL;
1137 GVariant *value = NULL;
1138 GVariant *result = NULL;
1139 GDBusConnection *g_conn;
1142 GVariantIter *property_iter;
1143 char* desc_handle = NULL;
1144 const gchar *desc_uuid_str = NULL;
1148 if (gattc_desc->desc_path == NULL) {
1149 DBG("desc path is NULL");
1150 return BT_STATUS_FAIL;
1152 desc_handle = gattc_desc->desc_path;
1154 DBG("desc path:[%s]", gattc_desc->desc_path);
1156 g_conn = _bt_hal_get_system_gconn();
1157 if (NULL == g_conn) {
1158 ERR("_bt_gdbus_get_system_gconn returned NULL");
1159 return BT_STATUS_FAIL;
1162 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1163 G_DBUS_PROXY_FLAGS_NONE, NULL,
1166 BT_HAL_PROPERTIES_INTERFACE,
1169 if (properties_proxy == NULL) {
1170 ERR("properties_proxy returned NULL");
1171 return BT_STATUS_FAIL;
1174 result = g_dbus_proxy_call_sync(properties_proxy,
1176 g_variant_new("(s)", BT_HAL_GATT_DESC_INTERFACE),
1177 G_DBUS_CALL_FLAGS_NONE,
1182 if (error != NULL) {
1183 ERR("Fail to get properties (Error: %s)", error->message);
1184 g_clear_error(&error);
1186 ERR("Fail to get properties");
1187 g_object_unref(properties_proxy);
1188 return BT_STATUS_FAIL;
1191 g_variant_get(result, "(a{sv})", &property_iter);
1193 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1194 if (!g_strcmp0(key, "UUID")) {
1195 desc_uuid_str = g_variant_dup_string(value, &len);
1196 DBG("desc UUID [%s]", desc_uuid_str);
1200 _hal_gattc_update_desc_property(gattc_desc, desc_uuid_str);
1202 g_variant_iter_free(property_iter);
1203 g_variant_unref(result);
1204 g_object_unref(properties_proxy);
1206 return BT_STATUS_SUCCESS;
1209 static void _bt_hal_send_client_desc_search_result_event(int conn_id, int status,
1210 btgatt_srvc_id_t *svc_id, btgatt_gatt_id_t *char_id, bt_uuid_t *desc_uuid)
1212 struct hal_ev_gatt_client_desc_search_result ev;
1215 ERR("gatt client callback not registered");
1219 DBG("sending gatt client search desc result event conn_id[%d] status[%d]", conn_id, status);
1221 memset(&ev, 0, sizeof(ev));
1222 ev.conn_id = conn_id;
1223 ev.inst_id = svc_id->id.inst_id;
1224 ev.is_primary = svc_id->is_primary;
1227 memcpy(ev.svc_uuid, svc_id->id.uuid.uu, sizeof(ev.svc_uuid));
1228 memcpy(ev.char_uuid, char_id->uuid.uu, sizeof(ev.char_uuid));
1230 if (status == BT_STATUS_SUCCESS) {
1231 DBG("building desc uuid");
1232 memcpy(ev.desc_uuid, desc_uuid->uu, sizeof(ev.desc_uuid));
1235 DBG("sending the desc search event");
1237 event_cb(HAL_EV_GATT_CLIENT_DESC_SEARCH_RESULT, (void *)&ev, sizeof(ev));
1240 static bt_status_t _hal_gattc_get_all_descriptor(int conn_id,
1241 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id)
1243 hal_gattc_server_info_t * conn_info = NULL;
1244 hal_gattc_service_t *gattc_service = NULL;
1246 hal_gattc_char_t *gattc_char = NULL;
1247 hal_gattc_desc_t *gattc_desc = NULL;
1248 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1249 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1250 int status = BT_STATUS_FAIL;
1254 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1255 if (NULL == conn_info) {
1256 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1257 return BT_STATUS_FAIL;
1261 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1262 if (NULL == gattc_service) {
1263 DBG("Failed to get the gatt service");
1264 return BT_STATUS_FAIL;
1267 DBG("service path [%s]", gattc_service->svc_path);
1268 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1269 DBG("service uuid [%s]", svc_uuid_str);
1271 /* find characteristics */
1272 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1273 if (NULL == gattc_char) {
1274 DBG("Failed to get the gatt char");
1275 return BT_STATUS_FAIL;
1278 DBG("char path [%s]", gattc_char->chr_path);
1279 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1280 DBG("char uuid [%s]", char_uuid_str);
1282 /* get descriptor uuid */
1283 for (l = gattc_char->gatt_list_descs; l != NULL; l = g_slist_next(l)) {
1284 gattc_desc = (hal_gattc_desc_t *)l->data;
1285 status = _hal_gattc_get_descriptor_info(gattc_desc);
1288 if (BT_STATUS_SUCCESS == status) {
1289 DBG("Sending the success descriptor event");
1290 _bt_hal_send_client_desc_search_result_event(conn_id, status, srvc_id,
1291 char_id, &gattc_desc->desc_uuid);
1295 DBG("sending final event");
1297 status = BT_STATUS_FAIL;
1298 _bt_hal_send_client_desc_search_result_event(conn_id, status, srvc_id, char_id, NULL);
1300 browse_service_char(conn_id);
1301 /* retrive uuid for characteristic and object path for descriptor */
1303 return BT_STATUS_SUCCESS;
1307 * Enumerate descriptors for a given characteristic.
1308 * Set start_descr_id to NULL to get the first descriptor.
1310 bt_status_t btif_gattc_get_descriptor(int conn_id,
1311 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1312 btgatt_gatt_id_t *start_descr_id)
1315 CHECK_BTGATT_INIT();
1317 if (start_descr_id == NULL) {
1318 DBG("Get all the descriptors");
1319 return _hal_gattc_get_all_descriptor(conn_id, srvc_id, char_id);
1321 DBG("TBD Get specific descriptor");
1322 return BT_STATUS_UNSUPPORTED;
1326 static void __hal_send_char_read_event(hal_gatt_resp_data_t *resp_data, int result, uint8_t *value, int len)
1328 struct hal_ev_gatt_client_read_data ev;
1331 ERR("gatt client callback not registered");
1335 DBG("sending gatt client charac read conn_id[%d] status[%d]", resp_data->conn_id, result);
1337 memset(&ev, 0, sizeof(ev));
1338 ev.conn_id = resp_data->conn_id;
1339 ev.inst_id = resp_data->srvc_id.id.inst_id;
1340 ev.is_primary = resp_data->srvc_id.is_primary;
1343 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1344 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1348 DBG("building the char read value [%d]", len);
1349 memcpy(ev.value, value, len);
1352 DBG("sending the gatt client read charac event");
1354 event_cb(HAL_EV_GATT_CLIENT_READ_CHARAC, (void *)&ev, sizeof(ev));
1357 static void __hal_internal_read_char_cb(GObject *source_object,
1358 GAsyncResult *res, gpointer user_data)
1360 GError *error = NULL;
1361 GDBusConnection *system_gconn = NULL;
1364 GByteArray *gp_byte_array = NULL;
1366 hal_gatt_resp_data_t *resp_data = user_data;
1367 int result = BT_STATUS_SUCCESS;
1372 system_gconn = _bt_hal_get_system_gconn();
1373 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1376 ERR("Read Characteristic dbus failed Error:", error->message);
1379 result = BT_STATUS_FAIL;
1380 __hal_send_char_read_event(resp_data, result, NULL, 0);
1381 g_clear_error(&error);
1386 gp_byte_array = g_byte_array_new();
1387 g_variant_get(value, "(ay)", &iter);
1389 while (g_variant_iter_loop(iter, "y", &g_byte))
1390 g_byte_array_append(gp_byte_array, &g_byte, 1);
1394 for (i = 0; i < gp_byte_array->len; i++)
1395 DBG("%02x", gp_byte_array->data[i]);
1398 __hal_send_char_read_event(resp_data, result, gp_byte_array->data, gp_byte_array->len);
1402 g_byte_array_free(gp_byte_array, TRUE);
1403 g_variant_iter_free(iter);
1404 g_variant_unref(value);
1410 static bt_status_t _hal_read_characteristic_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1411 btgatt_gatt_id_t *char_id, int auth_req)
1413 GDBusConnection *g_conn;
1414 hal_gatt_resp_data_t *resp_data;
1415 hal_gattc_service_t *gattc_service = NULL;
1416 GVariantBuilder *builder = NULL;
1418 hal_gattc_server_info_t * conn_info = NULL;
1419 hal_gattc_char_t *gattc_char = NULL;
1420 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1421 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1422 char* char_handle = NULL;
1426 /* get the connection info */
1427 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1428 if (NULL == conn_info) {
1429 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1430 return BT_STATUS_FAIL;
1434 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1435 if (NULL == gattc_service) {
1436 DBG("Failed to get the gatt service");
1437 return BT_STATUS_FAIL;
1440 DBG("service path [%s]", gattc_service->svc_path);
1441 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1442 DBG("service uuid [%s]", svc_uuid_str);
1445 /* find characteristic */
1446 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1447 if (NULL == gattc_char) {
1448 DBG("Failed to get the gatt char");
1449 return BT_STATUS_FAIL;
1452 DBG("char path [%s]", gattc_char->chr_path);
1453 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1454 DBG("char uuid [%s]", char_uuid_str);
1456 g_conn = _bt_hal_get_system_gconn();
1457 if (NULL == g_conn) {
1458 ERR("_bt_gdbus_get_system_gconn returned NULL");
1459 return BT_STATUS_FAIL;
1462 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1463 if (NULL == resp_data) {
1464 ERR("failed to get the memory");
1465 return BT_STATUS_FAIL;
1468 resp_data->conn_id = conn_id;
1469 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1470 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1472 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1475 g_variant_builder_add(builder, "{sv}", "offset",
1476 g_variant_new("q", offset));
1478 char_handle = gattc_char->chr_path;
1480 DBG("calling char read value");
1482 g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, char_handle, BT_HAL_GATT_CHAR_INTERFACE,
1483 "ReadValue", g_variant_new("(a{sv})", builder),
1484 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1485 (GAsyncReadyCallback)__hal_internal_read_char_cb,
1486 (gpointer)resp_data);
1487 g_variant_builder_unref(builder);
1489 return BT_STATUS_SUCCESS;
1492 /** Read a characteristic on a remote device */
1493 bt_status_t btif_read_characteristic(int conn_id,
1494 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1497 CHECK_BTGATT_INIT();
1500 return _hal_read_characteristic_value(conn_id, srvc_id, char_id, auth_req);
1503 static void __hal_send_char_write_event(hal_gatt_resp_data_t *resp_data, int result)
1505 struct hal_ev_gatt_client_write_result ev;
1508 ERR("gatt client callback not registered");
1512 DBG("sending gatt client charac write conn_id[%d] status[%d]", resp_data->conn_id, result);
1514 memset(&ev, 0, sizeof(ev));
1515 ev.conn_id = resp_data->conn_id;
1516 ev.inst_id = resp_data->srvc_id.id.inst_id;
1517 ev.is_primary = resp_data->srvc_id.is_primary;
1520 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1521 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1523 DBG("sending the gatt client write charac event");
1525 event_cb(HAL_EV_GATT_CLIENT_WRITE_CHARAC, (void *)&ev, sizeof(ev));
1528 static void __hal_bluetooth_internal_write_cb(GObject *source_object,
1529 GAsyncResult *res, gpointer user_data)
1531 GError *error = NULL;
1532 GDBusConnection *system_gconn = NULL;
1534 hal_gatt_resp_data_t *resp_data = user_data;
1535 int result = BT_STATUS_SUCCESS;
1539 system_gconn = _bt_hal_get_system_gconn();
1540 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1543 ERR("write Characteristic dbus failed Error:", error->message);
1545 result = BT_STATUS_FAIL;
1547 __hal_send_char_write_event(resp_data, result);
1548 g_clear_error(&error);
1553 //send write value event
1554 __hal_send_char_write_event(resp_data, result);
1557 g_variant_unref(value);
1562 static bt_status_t __hal_get_write_prop(hal_gatt_write_type_t type, hal_gatt_property_e *prop)
1565 case HAL_GATT_WRITE_TYPE_WRITE:
1566 *prop = HAL_GATT_PROPERTY_WRITE;
1568 case HAL_GATT_WRITE_TYPE_WRITE_NO_RESPONSE:
1569 *prop = HAL_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE;
1572 ERR("Unknow write type : %d", type);
1573 return BT_STATUS_FAIL;
1576 return BT_STATUS_SUCCESS;
1579 static bt_status_t _hal_write_characteristic_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1580 btgatt_gatt_id_t *char_id, int write_type, int length, int auth_req, char* value)
1582 GVariant *val, *options;
1583 GVariantBuilder *builder1;
1584 GVariantBuilder *builder2;
1585 GDBusConnection *g_conn;
1588 hal_gatt_resp_data_t *resp_data;
1589 hal_gattc_service_t *gattc_service = NULL;
1590 hal_gattc_server_info_t * conn_info = NULL;
1591 hal_gattc_char_t *gattc_char = NULL;
1592 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1593 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1594 char* char_handle = NULL;
1595 hal_gatt_property_e write_prop = HAL_GATT_PROPERTY_WRITE;
1596 int ret = BT_STATUS_SUCCESS;
1600 ret = __hal_get_write_prop(write_type, &write_prop);
1601 if (BT_STATUS_FAIL == ret) {
1602 DBG("received invalid write type:[%d] ", write_type);
1603 return BT_STATUS_FAIL;
1606 /* get the connection info */
1607 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1608 if (NULL == conn_info) {
1609 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1610 return BT_STATUS_FAIL;
1614 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1615 if (NULL == gattc_service) {
1616 DBG("Failed to get the gatt service");
1617 return BT_STATUS_FAIL;
1620 DBG("service path [%s]", gattc_service->svc_path);
1621 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1622 DBG("service uuid [%s]", svc_uuid_str);
1624 /* find characteristic */
1625 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1626 if (NULL == gattc_char) {
1627 DBG("Failed to get the gatt char");
1628 return BT_STATUS_FAIL;
1631 DBG("char path [%s]", gattc_char->chr_path);
1632 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1633 DBG("char uuid [%s]", char_uuid_str);
1635 g_conn = _bt_hal_get_system_gconn();
1636 if (NULL == g_conn) {
1637 ERR("_bt_gdbus_get_system_gconn returned NULL");
1638 return BT_STATUS_FAIL;
1641 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1642 if (NULL == resp_data) {
1643 ERR("failed to get the memory");
1644 return BT_STATUS_FAIL;
1647 resp_data->conn_id = conn_id;
1648 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1649 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1651 char_handle = gattc_char->chr_path;
1653 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1655 for (i = 0; i < length; i++)
1656 g_variant_builder_add(builder1, "y", value[i]);
1658 val = g_variant_new("ay", builder1);
1660 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1662 g_variant_builder_add(builder2, "{sv}", "offset",
1663 g_variant_new_uint16(offset));
1665 options = g_variant_new("a{sv}", builder2);
1667 g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, char_handle, BT_HAL_GATT_CHAR_INTERFACE,
1669 g_variant_new("(y@ay@a{sv})", write_prop, val, options),
1671 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1672 (GAsyncReadyCallback)__hal_bluetooth_internal_write_cb,
1673 (gpointer)resp_data);
1675 g_variant_builder_unref(builder1);
1676 g_variant_builder_unref(builder2);
1678 return BT_STATUS_SUCCESS;
1681 /** Write a remote characteristic */
1682 bt_status_t btif_write_characteristic(int conn_id,
1683 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1684 int write_type, int len, int auth_req,
1687 CHECK_BTGATT_INIT();
1691 DBG("svc isntance id:[%d]", srvc_id->id.inst_id);
1692 return _hal_write_characteristic_value(conn_id, srvc_id, char_id, write_type,
1693 len, auth_req, p_value);
1696 static void __hal_send_desc_read_event(hal_gatt_resp_data_t *resp_data, int result, uint8_t *value, int len)
1698 struct hal_ev_gatt_client_read_data ev;
1701 ERR("gatt client callback not registered");
1705 DBG("sending gatt client desc read conn_id[%d] status[%d]", resp_data->conn_id, result);
1707 memset(&ev, 0, sizeof(ev));
1708 ev.conn_id = resp_data->conn_id;
1709 ev.inst_id = resp_data->srvc_id.id.inst_id;
1710 ev.is_primary = resp_data->srvc_id.is_primary;
1713 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1714 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1715 memcpy(ev.desc_uuid, resp_data->desc_id.uuid.uu, sizeof(ev.char_uuid));
1719 DBG("building the desc read value [%d]", len);
1720 memcpy(ev.value, value, len);
1723 DBG("sending the gatt client read descriptor event");
1725 event_cb(HAL_EV_GATT_CLIENT_READ_DESC, (void *)&ev, sizeof(ev));
1728 static void __hal_internal_read_desc_cb(GObject *source_object,
1729 GAsyncResult *res, gpointer user_data)
1731 GError *error = NULL;
1732 GDBusConnection *system_gconn = NULL;
1735 GByteArray *gp_byte_array = NULL;
1737 hal_gatt_resp_data_t *resp_data = user_data;
1738 int result = BT_STATUS_SUCCESS;
1743 system_gconn = _bt_hal_get_system_gconn();
1744 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1747 ERR("Read descriptor dbus failed Error:", error->message);
1750 result = BT_STATUS_FAIL;
1751 __hal_send_desc_read_event(resp_data, result, NULL, 0);
1752 g_clear_error(&error);
1757 gp_byte_array = g_byte_array_new();
1758 g_variant_get(value, "(ay)", &iter);
1760 while (g_variant_iter_loop(iter, "y", &g_byte))
1761 g_byte_array_append(gp_byte_array, &g_byte, 1);
1765 for (i = 0; i < gp_byte_array->len; i++)
1766 DBG("%02x", gp_byte_array->data[i]);
1769 __hal_send_desc_read_event(resp_data, result, gp_byte_array->data, gp_byte_array->len);
1773 g_byte_array_free(gp_byte_array, TRUE);
1774 g_variant_iter_free(iter);
1775 g_variant_unref(value);
1780 static bt_status_t _hal_read_descriptor_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1781 btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *desc_id, int auth_req)
1783 GDBusConnection *g_conn;
1784 hal_gatt_resp_data_t *resp_data;
1785 hal_gattc_service_t *gattc_service = NULL;
1786 GVariantBuilder *builder = NULL;
1788 hal_gattc_server_info_t * conn_info = NULL;
1789 hal_gattc_char_t *gattc_char = NULL;
1790 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1791 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1792 char desc_uuid_str[BT_HAL_UUID_STRING_LEN];
1793 char* desc_handle = NULL;
1795 hal_gattc_desc_t *gattc_desc = NULL;
1799 /* get the connection info */
1800 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1801 if (NULL == conn_info) {
1802 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1803 return BT_STATUS_FAIL;
1807 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1808 if (NULL == gattc_service) {
1809 DBG("Failed to get the gatt service");
1810 return BT_STATUS_FAIL;
1813 DBG("service path [%s]", gattc_service->svc_path);
1814 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1815 DBG("service uuid [%s]", svc_uuid_str);
1817 /* find characteristic */
1818 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1819 if (NULL == gattc_char) {
1820 DBG("Failed to get the gatt char");
1821 return BT_STATUS_FAIL;
1824 DBG("char path [%s]", gattc_char->chr_path);
1825 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1826 DBG("char uuid [%s]", char_uuid_str);
1828 /* find descriptor */
1829 gattc_desc = _gattc_find_desc_from_uuid(gattc_char, &desc_id->uuid);
1830 if (NULL == gattc_desc) {
1831 DBG("Failed to get the gatt desc");
1832 return BT_STATUS_FAIL;
1835 DBG("desc path [%s]", gattc_desc->desc_path);
1836 _bt_hal_convert_uuid_type_to_string(desc_uuid_str, gattc_desc->desc_uuid.uu);
1837 DBG("desc uuid [%s]", desc_uuid_str);
1839 g_conn = _bt_hal_get_system_gconn();
1840 if (NULL == g_conn) {
1841 ERR("_bt_gdbus_get_system_gconn returned NULL");
1842 return BT_STATUS_FAIL;
1845 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1846 if (NULL == resp_data) {
1847 ERR("failed to get the memory");
1848 return BT_STATUS_FAIL;
1851 resp_data->conn_id = conn_id;
1852 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1853 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1854 memcpy(&resp_data->desc_id, desc_id, sizeof(btgatt_gatt_id_t));
1856 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1859 g_variant_builder_add(builder, "{sv}", "offset",
1860 g_variant_new("q", offset));
1862 desc_handle = gattc_desc->desc_path;
1864 DBG("calling desc read value");
1866 g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, desc_handle, BT_HAL_GATT_DESC_INTERFACE,
1867 "ReadValue", g_variant_new("(a{sv})", builder),
1868 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1869 (GAsyncReadyCallback)__hal_internal_read_desc_cb,
1870 (gpointer)resp_data);
1871 g_variant_builder_unref(builder);
1873 return BT_STATUS_SUCCESS;
1876 /** Read the descriptor for a given characteristic */
1877 bt_status_t btif_read_descriptor(int conn_id,
1878 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1879 btgatt_gatt_id_t *descr_id, int auth_req)
1881 CHECK_BTGATT_INIT();
1883 return _hal_read_descriptor_value(conn_id, srvc_id, char_id, descr_id, auth_req);
1886 static void __hal_send_desc_write_event(hal_gatt_resp_data_t *resp_data, int result)
1888 struct hal_ev_gatt_client_write_result ev;
1891 ERR("gatt client callback not registered");
1895 DBG("sending gatt client charac write conn_id[%d] status[%d]", resp_data->conn_id, result);
1897 memset(&ev, 0, sizeof(ev));
1898 ev.conn_id = resp_data->conn_id;
1899 ev.inst_id = resp_data->srvc_id.id.inst_id;
1900 ev.is_primary = resp_data->srvc_id.is_primary;
1903 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1904 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1905 memcpy(ev.desc_uuid, resp_data->desc_id.uuid.uu, sizeof(ev.desc_uuid));
1907 DBG("sending the gatt client write charac event");
1909 event_cb(HAL_EV_GATT_CLIENT_WRITE_DESC, (void *)&ev, sizeof(ev));
1912 static void __hal_bluetooth_internal_desc_write_cb(GObject *source_object,
1913 GAsyncResult *res, gpointer user_data)
1915 GError *error = NULL;
1916 GDBusConnection *system_gconn = NULL;
1918 hal_gatt_resp_data_t *resp_data = user_data;
1919 int result = BT_STATUS_SUCCESS;
1923 system_gconn = _bt_hal_get_system_gconn();
1924 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1927 ERR("write descriptor dbus failed Error:", error->message);
1930 result = BT_STATUS_FAIL;
1931 __hal_send_desc_write_event(resp_data, result);
1932 g_clear_error(&error);
1937 //send write value event
1938 __hal_send_desc_write_event(resp_data, result);
1941 g_variant_unref(value);
1946 static bt_status_t _hal_write_descriptor_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1947 btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *descr_id,
1948 int write_type, int length, int auth_req, char* value)
1950 GVariant *val, *options;
1951 GVariantBuilder *builder1;
1952 GVariantBuilder *builder2;
1953 GDBusConnection *g_conn;
1956 hal_gatt_resp_data_t *resp_data;
1957 hal_gattc_service_t *gattc_service = NULL;
1958 hal_gattc_server_info_t * conn_info = NULL;
1959 hal_gattc_char_t *gattc_char = NULL;
1960 hal_gattc_desc_t *gattc_desc = NULL;
1961 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1962 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1963 char desc_uuid_str[BT_HAL_UUID_STRING_LEN];
1964 char* desc_handle = NULL;
1965 hal_gatt_property_e write_prop = HAL_GATT_PROPERTY_WRITE;
1966 int ret = BT_STATUS_SUCCESS;
1970 ret = __hal_get_write_prop(write_type, &write_prop);
1971 if (BT_STATUS_FAIL == ret) {
1972 DBG("received invalid write type:[%d] ", write_type);
1973 return BT_STATUS_FAIL;
1976 /* get the connection info */
1977 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1978 if (NULL == conn_info) {
1979 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1980 return BT_STATUS_FAIL;
1984 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1985 if (NULL == gattc_service) {
1986 DBG("Failed to get the gatt service");
1987 return BT_STATUS_FAIL;
1990 DBG("service path [%s]", gattc_service->svc_path);
1991 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1992 DBG("service uuid [%s]", svc_uuid_str);
1994 /* find characteristic */
1995 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1996 if (NULL == gattc_char) {
1997 DBG("Failed to get the gatt char");
1998 return BT_STATUS_FAIL;
2001 DBG("char path [%s]", gattc_char->chr_path);
2002 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2003 DBG("char uuid [%s]", char_uuid_str);
2005 /* find descriptor */
2006 gattc_desc = _gattc_find_desc_from_uuid(gattc_char, &descr_id->uuid);
2007 if (NULL == gattc_desc) {
2008 DBG("Failed to get the gatt char");
2009 return BT_STATUS_FAIL;
2012 DBG("desc path [%s]", gattc_desc->desc_path);
2013 _bt_hal_convert_uuid_type_to_string(desc_uuid_str, gattc_desc->desc_uuid.uu);
2014 DBG("char uuid [%s]", desc_uuid_str);
2016 g_conn = _bt_hal_get_system_gconn();
2017 if (NULL == g_conn) {
2018 ERR("_bt_gdbus_get_system_gconn returned NULL");
2019 return BT_STATUS_FAIL;
2022 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
2023 if (NULL == resp_data) {
2024 ERR("failed to get the memory");
2025 return BT_STATUS_FAIL;
2028 resp_data->conn_id = conn_id;
2029 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2030 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2031 memcpy(&resp_data->desc_id, descr_id, sizeof(btgatt_gatt_id_t));
2033 desc_handle = gattc_desc->desc_path;
2035 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2037 for (i = 0; i < length; i++)
2038 g_variant_builder_add(builder1, "y", value[i]);
2040 val = g_variant_new("ay", builder1);
2042 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2044 g_variant_builder_add(builder2, "{sv}", "offset",
2045 g_variant_new_uint16(offset));
2047 options = g_variant_new("a{sv}", builder2);
2049 g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, desc_handle, BT_HAL_GATT_DESC_INTERFACE,
2051 g_variant_new("(@ay@a{sv})", val, options),
2053 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2054 (GAsyncReadyCallback)__hal_bluetooth_internal_desc_write_cb,
2055 (gpointer)resp_data);
2057 g_variant_builder_unref(builder1);
2058 g_variant_builder_unref(builder2);
2060 return BT_STATUS_SUCCESS;
2063 /** Write a remote descriptor for a given characteristic */
2064 bt_status_t btif_write_descriptor(int conn_id,
2065 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
2066 btgatt_gatt_id_t *descr_id, int write_type, int len,
2067 int auth_req, char* p_value)
2069 CHECK_BTGATT_INIT();
2071 return _hal_write_descriptor_value(conn_id, srvc_id, char_id, descr_id, write_type,
2072 len, auth_req, p_value);
2075 /** Execute a prepared write operation */
2076 bt_status_t execute_write(int conn_id, int execute)
2078 CHECK_BTGATT_INIT();
2079 return BT_STATUS_UNSUPPORTED;
2083 * Register to receive notifications or indications for a given
2086 bt_status_t register_for_notification(int client_if,
2087 const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2088 btgatt_gatt_id_t *char_id)
2090 CHECK_BTGATT_INIT();
2091 return BT_STATUS_UNSUPPORTED;
2094 /** Deregister a previous request for notifications/indications */
2095 bt_status_t deregister_for_notification(int client_if,
2096 const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2097 btgatt_gatt_id_t *char_id)
2099 CHECK_BTGATT_INIT();
2100 return BT_STATUS_UNSUPPORTED;
2103 /** Request RSSI for a given remote device */
2104 bt_status_t read_remote_rssi(int client_if, const bt_bdaddr_t *bd_addr)
2106 CHECK_BTGATT_INIT();
2107 return BT_STATUS_UNSUPPORTED;
2110 /** OTA firmware download */
2111 bt_status_t ota_fw_update(int client_if, int conn_id, const bt_bdaddr_t *bd_addr, char* path)
2113 CHECK_BTGATT_INIT();
2114 return BT_STATUS_UNSUPPORTED;
2117 /** Determine the type of the remote device (LE, BR/EDR, Dual-mode) */
2118 int get_device_type(const bt_bdaddr_t *bd_addr)
2120 CHECK_BTGATT_INIT();
2121 return BT_STATUS_UNSUPPORTED;
2124 static bt_status_t __hal_update_conn_parameter(bt_bdaddr_t *bd_addr,
2125 int min_int, int max_int, int latency, int timeout)
2127 gchar *device_path = NULL;
2128 GError *error = NULL;
2129 GDBusProxy *device_proxy = NULL;
2130 GDBusConnection *conn;
2132 int ret = BT_STATUS_SUCCESS;
2133 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
2135 INFO("Min interval: %d, Max interval: %d, Latency: %d, Supervision timeout: %d",
2136 min_int, max_int, latency, timeout);
2138 conn = _bt_hal_get_system_gconn();
2141 return BT_STATUS_FAIL;
2144 _bt_hal_convert_addr_type_to_string(device_address,
2145 (unsigned char *)bd_addr->address);
2146 device_path = _bt_hal_get_device_object_path(device_address);
2148 if (device_path == NULL) {
2149 ERR("device_path NULL : [%s]", device_address);
2150 return BT_STATUS_FAIL;
2153 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2154 NULL, BT_HAL_BLUEZ_NAME,
2155 device_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
2157 g_free(device_path);
2158 if (NULL == device_proxy) {
2159 ERR("device_proxy returned NULL");
2160 return BT_STATUS_FAIL;
2163 INFO("### LeConnUpdate");
2164 reply = g_dbus_proxy_call_sync(device_proxy, "LeConnUpdate",
2165 g_variant_new("(uuuu)", min_int, max_int, latency, timeout),
2166 G_DBUS_CALL_FLAGS_NONE,
2171 g_object_unref(device_proxy);
2172 if (reply == NULL) {
2174 ERR("Error %s[%s]", error->message, device_address);
2175 if (g_strrstr(error->message, "In Progress"))
2176 ret = BT_STATUS_SUCCESS;
2178 ret = BT_STATUS_FAIL;
2179 g_error_free(error);
2183 g_variant_unref(reply);
2185 INFO("LE Connection parameter Updated");
2189 /** Request a connection parameter update */
2190 bt_status_t btif_gattc_conn_parameter_update(bt_bdaddr_t *bd, int min_int, int max_int, int latency, int timeout)
2192 CHECK_BTGATT_INIT();
2196 return __hal_update_conn_parameter(bd, min_int, max_int, latency, timeout);
2199 /** Test mode interface */
2200 bt_status_t test_command(int command, btgatt_test_params_t* params)
2202 CHECK_BTGATT_INIT();
2203 return BT_STATUS_UNSUPPORTED;
2206 /** MTU Exchange request from client */
2207 bt_status_t configure_mtu(int conn_id, int mtu)
2209 CHECK_BTGATT_INIT();
2210 return BT_STATUS_UNSUPPORTED;
2213 /** Setup scan filter params */
2214 bt_status_t scan_filter_param_setup(int client_if, int action, int filt_index, int feat_seln,
2215 int list_logic_type, int filt_logic_type, int rssi_high_thres,
2216 int rssi_low_thres, int dely_mode, int found_timeout,
2217 int lost_timeout, int found_timeout_cnt)
2219 CHECK_BTGATT_INIT();
2220 return BT_STATUS_UNSUPPORTED;
2223 /** Configure a scan filter condition */
2224 bt_status_t scan_filter_add_remove(int client_if, int action, int filt_type,
2225 int filt_index, int company_id,
2226 int company_id_mask, const bt_uuid_t *p_uuid,
2227 const bt_uuid_t *p_uuid_mask, const bt_bdaddr_t *bd_addr,
2228 char addr_type, int data_len, char* p_data, int mask_len,
2231 CHECK_BTGATT_INIT();
2232 return BT_STATUS_UNSUPPORTED;
2235 /** Clear all scan filter conditions for specific filter index*/
2236 bt_status_t scan_filter_clear(int client_if, int filt_index)
2238 CHECK_BTGATT_INIT();
2239 return BT_STATUS_UNSUPPORTED;
2242 /** Enable / disable scan filter feature*/
2243 bt_status_t scan_filter_enable(int client_if, bool enable)
2245 CHECK_BTGATT_INIT();
2246 return BT_STATUS_UNSUPPORTED;
2249 /** Sets the LE scan interval and window in units of N*0.625 msec */
2251 bt_status_t set_scan_parameters(int scan_type, int scan_interval, int scan_window)
2255 CHECK_BTGATT_INIT();
2257 le_scan_type = scan_type;
2258 ret = _bt_hal_adapter_le_set_scan_parameters(
2259 scan_type, scan_interval, scan_window);
2263 bt_status_t set_scan_parameters(int scan_interval, int scan_window)
2265 CHECK_BTGATT_INIT();
2266 return BT_STATUS_UNSUPPORTED;
2270 /* Configure the batchscan storage */
2271 bt_status_t batchscan_cfg_storage(int client_if, int batch_scan_full_max,
2272 int batch_scan_trunc_max, int batch_scan_notify_threshold)
2274 CHECK_BTGATT_INIT();
2275 return BT_STATUS_UNSUPPORTED;
2278 /* Enable batchscan */
2279 bt_status_t batchscan_enb_batch_scan(int client_if, int scan_mode,
2280 int scan_interval, int scan_window, int addr_type, int discard_rule)
2282 CHECK_BTGATT_INIT();
2283 return BT_STATUS_UNSUPPORTED;
2286 /* Disable batchscan */
2287 bt_status_t batchscan_dis_batch_scan(int client_if)
2289 CHECK_BTGATT_INIT();
2290 return BT_STATUS_UNSUPPORTED;
2293 /* Read out batchscan reports */
2294 bt_status_t batchscan_read_reports(int client_if, int scan_mode)
2296 CHECK_BTGATT_INIT();
2297 return BT_STATUS_UNSUPPORTED;
2300 const btgatt_client_interface_t btgatt_client_interface = {
2301 btif_gattc_register_client,
2302 btif_gattc_unregister_client,
2304 btif_gattc_client_connect,
2305 btif_gattc_client_disconnect,
2307 btif_gattc_client_search_service,
2308 get_included_service,
2309 btif_gattc_get_characteristic,
2310 btif_gattc_get_descriptor,
2311 btif_read_characteristic,
2312 btif_write_characteristic,
2313 btif_read_descriptor,
2314 btif_write_descriptor,
2316 register_for_notification,
2317 deregister_for_notification,
2321 btif_gattc_conn_parameter_update,
2324 scan_filter_param_setup,
2325 scan_filter_add_remove,
2328 set_scan_parameters,
2329 batchscan_cfg_storage,
2330 batchscan_enb_batch_scan,
2331 batchscan_dis_batch_scan,
2332 batchscan_read_reports
2335 static hal_gattc_server_info_t *__bt_find_gatt_conn_info(bt_bdaddr_t *serv_addr)
2340 hal_gattc_server_info_t *info = NULL;
2342 for (l = hal_gattc_server_info_list; l != NULL; l = g_slist_next(l)) {
2343 info = (hal_gattc_server_info_t*)l->data;
2347 if (!memcmp(&info->bd_addr, serv_addr, sizeof(bt_bdaddr_t))) {
2348 INFO("GATT connection found addr");
2355 static hal_gattc_client_info_t *__bt_find_gatt_client_info(bt_bdaddr_t *serv_addr)
2360 hal_gattc_client_info_t *info = NULL;
2362 for (l = hal_gattc_client_info_list; l != NULL; l = g_slist_next(l)) {
2363 info = (hal_gattc_client_info_t*)l->data;
2367 if (!memcmp(&info->bd_addr, serv_addr, sizeof(bt_bdaddr_t))) {
2368 INFO("GATT client info found addr");
2375 static hal_gattc_client_info_t *__bt_find_gatt_client_info_from_conn_id(int conn_id)
2380 hal_gattc_client_info_t *info = NULL;
2382 for (l = hal_gattc_client_info_list; l != NULL; l = g_slist_next(l)) {
2383 info = (hal_gattc_client_info_t*)l->data;
2387 if (info->conn_id == conn_id) {
2388 INFO("GATT client info found for conn_id [%d]", conn_id);
2395 static hal_gattc_server_info_t *__bt_find_gatt_conn_info_from_conn_id(int conn_id)
2400 hal_gattc_server_info_t *info = NULL;
2401 hal_gattc_client_info_t *gattc_client = NULL;
2403 gattc_client = __bt_find_gatt_client_info_from_conn_id(conn_id);
2404 if (gattc_client == NULL) {
2405 INFO("GATT client conn info not found");
2409 for (l = hal_gattc_server_info_list; l != NULL; l = g_slist_next(l)) {
2410 info = (hal_gattc_server_info_t*)l->data;
2414 if ((info->inst_id == gattc_client->inst_id) &&
2415 !memcmp(&info->bd_addr, &gattc_client->bd_addr, sizeof(bt_bdaddr_t))) {
2416 INFO("GATT connection found for conn_id [%d]", conn_id);
2423 static bt_status_t __bt_connect_le_device_internal(int client_if, const bt_bdaddr_t *bd_addr,
2424 gboolean auto_connect)
2426 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
2427 gchar *device_path = NULL;
2428 GDBusProxy *device_proxy = NULL;
2429 GDBusConnection *conn;
2430 int ret = BT_STATUS_SUCCESS;
2431 hal_gattc_client_info_t *gattc_data;
2435 if (NULL == bd_addr) {
2436 ERR("bd_addr is NULL");
2437 return BT_STATUS_PARM_INVALID;
2440 conn = _bt_hal_get_system_gconn();
2442 ERR("_bt_gdbus_get_system_gconn returned NULL");
2443 return BT_STATUS_FAIL;
2446 _bt_hal_convert_addr_type_to_string(device_address,
2447 (unsigned char *)bd_addr->address);
2448 device_path = _bt_hal_get_device_object_path(device_address);
2449 if (device_path == NULL) {
2450 ERR("device_path NULL : [%s]", device_address);
2451 ret = BT_STATUS_FAIL;
2454 ERR("device_path:%s", device_path);
2456 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2457 NULL, BT_HAL_BLUEZ_NAME,
2458 device_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
2459 g_free(device_path);
2460 if (NULL == device_proxy) {
2461 ERR("device_proxy returned NULL");
2462 return BT_STATUS_FAIL;
2465 gattc_data = g_malloc0(sizeof(hal_gattc_client_info_t));
2466 if (gattc_data == NULL) {
2467 ERR("Unable to allocate memory");
2468 ret = BT_STATUS_NOMEM;
2471 memcpy(gattc_data->bd_addr.address, bd_addr->address,
2472 BT_HAL_ADDRESS_LENGTH_MAX);
2474 DBG("Connect LE [%s]", device_address);
2476 gattc_data->client_if = client_if;
2478 g_dbus_proxy_call(device_proxy, "ConnectLE",
2479 g_variant_new("(b)", auto_connect),
2480 G_DBUS_CALL_FLAGS_NONE,
2481 BT_HAL_MAX_DBUS_TIMEOUT,
2483 (GAsyncReadyCallback)__le_connection_req_cb, gattc_data);
2489 g_object_unref(device_proxy);
2496 static bt_status_t _bt_hold_current_advertising()
2498 int ret = BT_STATUS_FAIL;
2499 gboolean is_advertising = FALSE;
2502 is_advertising = _bt_hal_is_advertising_in_slot(0);
2503 if (is_advertising) {
2504 DBG("+ Stop current advertising");
2506 ret = _bt_hal_enable_advertising(0, FALSE, FALSE);
2507 g_timeout_add(2000, __bt_hold_current_advertising_timeout_cb, NULL);
2513 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
2515 DBG("+ start current advertising");
2517 _bt_hal_enable_advertising(0, TRUE, FALSE);
2522 static gboolean __bt_connect_le_timer_cb(gpointer user_data)
2524 DBG("Try to initiate pending LE connection");
2526 pending_le_conn_timer_id = 0;
2528 __bt_connect_le_device_internal(pending_le_conn_info->client_if,
2529 &pending_le_conn_info->bd_addr,
2530 pending_le_conn_info->auto_connect);
2532 g_free(pending_le_conn_info);
2533 pending_le_conn_info = NULL;
2538 static int __hal_generate_conn_id()
2540 return ++bt_conn_id;
2543 static int __hal_generate_server_instance_id()
2545 return ++bt_inst_id;
2548 static void __le_connection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
2551 GError *g_error = NULL;
2552 GVariant *reply = NULL;
2553 hal_gattc_client_info_t *gattc_data = user_data;
2554 int result = BT_STATUS_SUCCESS;
2555 struct hal_ev_gatt_client_connected ev;
2556 hal_gattc_server_info_t *gatt_conn_info = NULL;
2560 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
2561 g_object_unref(proxy);
2562 if (reply == NULL) {
2563 ERR("Connect LE Dbus Call Error");
2565 ERR("Error: %s\n", g_error->message);
2566 g_clear_error(&g_error);
2568 result = BT_STATUS_FAIL;
2570 g_variant_unref(reply);
2572 if (NULL == gattc_data) {
2573 ERR("server_data is NULL");
2578 if (result == BT_STATUS_FAIL) {
2579 memset(&ev, 0, sizeof(ev));
2582 ev.client_if = gattc_data->client_if;
2583 memcpy(ev.bdaddr, gattc_data->bd_addr.address,
2584 BT_HAL_ADDRESS_LENGTH_MAX);
2587 ERR("gatt client callback not registered");
2589 DBG("sending gatt client connected event");
2590 event_cb(HAL_EV_GATT_CLIENT_CONNECTED, (void *)&ev, sizeof(ev));
2596 DBG("adding the server conn info in list");
2597 gattc_data->conn_id = __hal_generate_conn_id() ;
2598 gattc_data->inst_id = __hal_generate_server_instance_id();
2600 hal_gattc_client_info_list = g_slist_append(hal_gattc_client_info_list, gattc_data);
2602 /*add gatt server connection info*/
2603 gatt_conn_info = g_malloc0(sizeof(hal_gattc_server_info_t));
2604 if (gatt_conn_info == NULL) {
2605 ERR("Failed to allocate memory");
2609 memcpy(gatt_conn_info->bd_addr.address, gattc_data->bd_addr.address, BT_HAL_ADDRESS_LENGTH_MAX);
2610 gatt_conn_info->inst_id = gattc_data->inst_id;
2611 hal_gattc_server_info_list = g_slist_append(hal_gattc_server_info_list, gatt_conn_info);
2617 /*remove conn_info*/
2622 void __hal_gattc_free_svc_info(hal_gattc_service_t *svc_info)
2624 g_free(svc_info->svc_path);
2628 void __hal_gattc_free_char_info(hal_gattc_char_t *char_info)
2630 g_free(char_info->chr_path);
2634 void __hal_gattc_free_desc_info(hal_gattc_desc_t *desc_info)
2636 g_free(desc_info->desc_path);
2640 void __hal_clean_gattc_server_info(hal_gattc_server_info_t *conn_info)
2645 hal_gattc_service_t *svc_info = NULL;
2646 hal_gattc_char_t *char_info = NULL;
2647 hal_gattc_desc_t *desc_info = NULL;
2651 for (l = conn_info->gatt_list_services; l != NULL;) {
2652 svc_info = (hal_gattc_service_t*)l->data;
2653 if (svc_info == NULL)
2655 l = g_slist_next(l);
2657 for (m = svc_info->gatt_list_chars; m != NULL; ) {
2658 char_info = (hal_gattc_char_t*)m->data;
2659 if (char_info == NULL)
2661 m = g_slist_next(m);
2663 for (k = char_info->gatt_list_descs; k != NULL; ) {
2664 desc_info = (hal_gattc_desc_t*)k->data;
2665 if (desc_info == NULL)
2667 k = g_slist_next(k);
2669 /*remove desc element*/
2670 char_info->gatt_list_descs = g_slist_remove(char_info->gatt_list_descs, desc_info);
2671 __hal_gattc_free_desc_info(desc_info);
2674 /*remove desc list*/
2675 g_slist_free(char_info->gatt_list_descs);
2676 char_info->gatt_list_descs = NULL;
2678 /*remove char element*/
2679 svc_info->gatt_list_chars = g_slist_remove(svc_info->gatt_list_chars, char_info);
2680 __hal_gattc_free_char_info(char_info);
2683 /*remove char list*/
2684 g_slist_free(svc_info->gatt_list_chars);
2685 svc_info->gatt_list_chars = NULL;
2687 /*remove svc element*/
2688 conn_info->gatt_list_services = g_slist_remove(conn_info->gatt_list_services, svc_info);
2689 __hal_gattc_free_svc_info(svc_info);
2692 /*remove svc list */
2693 g_slist_free(conn_info->gatt_list_services);
2694 conn_info->gatt_list_services = NULL;
2696 /*remove conn info*/
2700 void _bt_hal_handle_gattc_connected_event(char* address, gboolean gatt_connected)
2702 int result = BT_STATUS_SUCCESS;
2703 struct hal_ev_gatt_client_connected ev;
2704 hal_gattc_server_info_t *conn_info = NULL;
2705 bt_bdaddr_t bd_addr;
2707 hal_gattc_client_info_t *gattc_client = NULL;
2711 DBG("+ connected device address [%s]", address);
2713 event = gatt_connected ? HAL_EV_GATT_CLIENT_CONNECTED :
2714 HAL_EV_GATT_CLIENT_DISCONNECTED;
2716 _bt_hal_convert_addr_string_to_type(bd_addr.address, address);
2717 /* find the gatt client info */
2718 gattc_client = __bt_find_gatt_client_info(&bd_addr);
2719 if (NULL == gattc_client) {
2720 ERR("Fail to get gatt client info");
2725 memset(&ev, 0, sizeof(ev));
2726 ev.conn_id = gattc_client->conn_id;
2728 ev.client_if = gattc_client->client_if;
2729 memcpy(ev.bdaddr, gattc_client->bd_addr.address,
2730 BT_HAL_ADDRESS_LENGTH_MAX);
2733 ERR("gatt client callback not registered");
2735 DBG("sending gatt client connected status event");
2736 event_cb(event, (void *)&ev, sizeof(ev));
2739 if (!gatt_connected) {
2740 inst_id = gattc_client->inst_id;
2742 /* remove the gatt client info from the client list also*/
2743 hal_gattc_client_info_list = g_slist_remove(hal_gattc_client_info_list, gattc_client);
2744 g_free(gattc_client);
2746 //find the connected server info
2747 conn_info = __bt_find_gatt_conn_info(&bd_addr);
2748 if (NULL == conn_info) {
2749 ERR("Fail to get gatt server info");
2753 if (inst_id != conn_info->inst_id) {
2754 ERR("server instance is different");
2758 //remove gatt conn info from the server list
2759 DBG("remove the server conn_info from list after gatt disconnection");
2760 hal_gattc_server_info_list = g_slist_remove(hal_gattc_server_info_list, conn_info);
2761 __hal_clean_gattc_server_info(conn_info);
2767 static void _bt_hal_send_search_service_result_event(int conn_id, int is_primary,
2768 const char* uuid_str, int inst_id)
2770 struct hal_ev_gatt_client_search_result ev;
2773 ERR("gatt client callback not registered");
2777 DBG("sending gatt client search service result event conn_id[%d]", conn_id);
2779 memset(&ev, 0, sizeof(ev));
2780 ev.conn_id = conn_id;
2781 ev.inst_id = inst_id;
2782 ev.is_primary = is_primary;
2783 _bt_hal_convert_uuid_string_to_type(ev.uuid, uuid_str);
2785 event_cb(HAL_EV_GATT_CLIENT_SEARCH_RESULT, (void *)&ev, sizeof(ev));
2788 static void _bt_hal_send_search_service_complete_event(int conn_id, int status)
2790 struct hal_ev_gatt_client_search_complete ev;
2793 ERR("gatt client callback not registered");
2797 DBG("sending gatt client search service complete event conn_id[%d]", conn_id);
2800 memset(&ev, 0, sizeof(ev));
2801 ev.conn_id = conn_id;
2804 event_cb(HAL_EV_GATT_CLIENT_SEARCH_COMPLETE, (void *)&ev, sizeof(ev));