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
152 btgatt_srvc_id_t srvc_id;
153 btgatt_gatt_id_t char_id;
154 btgatt_gatt_id_t desc_id;
155 } 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);
178 static hal_gattc_server_info_t *__bt_find_gatt_conn_info(bt_bdaddr_t *serv_addr);
179 static hal_gattc_client_info_t *__bt_find_gatt_client_info(bt_bdaddr_t *serv_addr);
182 /* To send stack event to hal-av handler */
183 void _bt_hal_register_gatt_client_handler_cb(handle_stack_msg cb)
188 void _bt_hal_unregister_gatt_client_handler_cb(void)
194 int _bt_hal_gatt_client_get_le_scan_type(void)
200 static gboolean __bt_hal_register_client_cb(gpointer user_data)
202 struct hal_ev_gatt_client_registered ev;
203 hal_gatt_client_app *client_info = user_data;
206 /* Prepare to send AV connecting event */
207 memset(&ev, 0, sizeof(ev));
208 ev.status = BT_STATUS_SUCCESS;
209 ev.client_if = client_info->client_if;
210 memcpy(ev.app_uuid, client_info->app_uuid.uu, sizeof(ev.app_uuid));
213 ERR("GATT Callback not registered");
215 DBG("GATT client registered, client_if: [%d]", client_info->client_if);
216 event_cb(HAL_EV_GATT_CLIENT_REGISTERED, (void *)&ev, sizeof(ev));
223 static int __hal_generate_client_id()
225 return ++bt_client_if;
228 static hal_gatt_client_app *__hal_gattc_add_client_app(bt_uuid_t *app_uuid)
231 hal_gatt_client_app *info = NULL;
232 hal_gatt_client_app *gattc_app = NULL;
234 //check if client app is already registered
235 for (l = hal_gattc_client_app_list; l != NULL; l = g_slist_next(l)) {
236 info = (hal_gatt_client_app*)l->data;
240 if (memcmp(&info->app_uuid, app_uuid, sizeof(bt_uuid_t)) == 0) {
241 DBG("gatt client app already registered");
246 DBG("adding the gatt client app");
249 gattc_app = g_malloc0(sizeof(hal_gatt_client_app));
250 if (gattc_app == NULL) {
251 DBG("Failed to allocate memory");
255 gattc_app->client_if = __hal_generate_client_id();
256 memcpy(&gattc_app->app_uuid, app_uuid, sizeof(bt_uuid_t));
258 hal_gattc_client_app_list = g_slist_append(hal_gattc_client_app_list, gattc_app);
263 static bt_status_t __hal_gattc_register_client_app(bt_uuid_t *app_uuid)
265 hal_gatt_client_app *gattc_app = NULL;
266 hal_gatt_client_app *client_app_info = NULL;
269 /* add gatt client in list */
270 gattc_app = __hal_gattc_add_client_app(app_uuid);
271 if (gattc_app == NULL) {
272 ERR("Failed to register gatt client app");
273 return BT_STATUS_FAIL;
277 client_app_info = g_malloc0(sizeof(hal_gatt_client_app));
278 if (NULL == client_app_info) {
279 ERR("Failed to allocate memory");
280 return BT_STATUS_FAIL;
283 client_app_info->client_if = gattc_app->client_if;
284 memcpy(&client_app_info->app_uuid, app_uuid, sizeof(bt_uuid_t));
285 g_idle_add(__bt_hal_register_client_cb, (gpointer)client_app_info);
287 DBG("registered client client_if [%d]", client_app_info->client_if);
289 return BT_STATUS_SUCCESS;
292 /** Registers a GATT client application with the stack */
293 bt_status_t btif_gattc_register_client(bt_uuid_t *uuid)
298 return __hal_gattc_register_client_app(uuid);
301 bt_status_t __hal_gattc_unregister_client(int client_if)
304 hal_gatt_client_app *info = NULL;
306 DBG("registered client count: [%d]", g_slist_length(hal_gattc_client_app_list));
308 /* remove the gatt client app */
309 for (l = hal_gattc_client_app_list; l != NULL; ) {
310 info = (hal_gatt_client_app*)l->data;
316 if (info->client_if == client_if) {
317 DBG("gatt client app found");
318 hal_gattc_client_app_list = g_slist_remove(hal_gattc_client_app_list, info);
323 DBG("registered client count: [%d]", g_slist_length(hal_gattc_client_app_list));
324 return BT_STATUS_SUCCESS;
327 /** Unregister a client application from the stack */
328 bt_status_t btif_gattc_unregister_client(int client_if)
333 return __hal_gattc_unregister_client(client_if);
336 /** Start or stop LE device scanning */
337 bt_status_t scan(int client_if, bool start)
344 ret = _bt_hal_adapter_le_start_scan();
346 ret = _bt_hal_adapter_le_stop_scan();
351 /** Create a connection to a remote LE or dual-mode device */
352 bt_status_t btif_gattc_client_connect(int client_if, const bt_bdaddr_t *bd_addr,
355 int ret = BT_STATUS_SUCCESS;
361 return BT_STATUS_PARM_INVALID;
363 ret = _bt_hold_current_advertising();
364 if (ret == BT_STATUS_SUCCESS) {
365 DBG("Current advertising is held");
366 pending_le_conn_info = g_malloc0(sizeof(bt_pending_le_conn_info_s));
367 pending_le_conn_info->client_if = client_if;
368 memcpy(pending_le_conn_info->bd_addr.address, bd_addr->address,
369 BT_HAL_ADDRESS_LENGTH_MAX);
370 pending_le_conn_info->auto_connect = is_direct;
372 pending_le_conn_timer_id =
373 g_timeout_add(1000, __bt_connect_le_timer_cb, NULL);
375 return BT_STATUS_SUCCESS;
377 ERR("advertising is not stopped");
380 return __bt_connect_le_device_internal(client_if, bd_addr, is_direct);
384 static void __le_disconnection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
387 GError *g_error = NULL;
388 GVariant *reply = NULL;
389 hal_gattc_client_info_t *gatt_conn_info = user_data;
390 int result = BT_STATUS_SUCCESS;
391 struct hal_ev_gatt_client_connected ev;
395 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
396 g_object_unref(proxy);
398 ERR("Connect LE Dbus Call Error");
400 ERR("Error: %s\n", g_error->message);
401 g_clear_error(&g_error);
403 result = BT_STATUS_FAIL;
405 g_variant_unref(reply);
407 if (NULL == gatt_conn_info) {
408 ERR("server_data is NULL");
413 if (result == BT_STATUS_FAIL) {
414 memset(&ev, 0, sizeof(ev));
415 ev.conn_id = gatt_conn_info->conn_id;
417 ev.client_if = gatt_conn_info->client_if;
418 memcpy(ev.bdaddr, gatt_conn_info->bd_addr.address,
419 BT_HAL_ADDRESS_LENGTH_MAX);
422 ERR("gatt client callback not registered");
424 DBG("sending gatt client disconnected event");
425 event_cb(HAL_EV_GATT_CLIENT_DISCONNECTED, (void *)&ev, sizeof(ev));
431 g_free(gatt_conn_info);
436 bt_status_t _hal_gattc_disconnect(int client_if, const bt_bdaddr_t *bd_addr,
439 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
441 GDBusProxy *device_proxy;
442 GDBusConnection *conn;
443 int ret = BT_STATUS_SUCCESS;
444 hal_gattc_client_info_t *gattc_data;
446 if (NULL == bd_addr) {
447 ERR("bd_addr is NULL");
448 return BT_STATUS_PARM_INVALID;
451 conn = _bt_hal_get_system_gconn();
453 ERR("_bt_gdbus_get_system_gconn returned NULL");
454 return BT_STATUS_FAIL;
457 _bt_hal_convert_addr_type_to_string(device_address,
458 (unsigned char *)bd_addr->address);
459 device_path = _bt_hal_get_device_object_path(device_address);
460 if (device_path == NULL) {
461 DBG("device_path NULL");
462 ret = BT_STATUS_FAIL;
466 ERR("device_path:%s", device_path);
468 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
469 NULL, BT_HAL_BLUEZ_NAME,
470 device_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
472 if (NULL == device_proxy) {
473 ERR("device_proxy returned NULL");
474 return BT_STATUS_FAIL;
477 gattc_data = g_malloc0(sizeof(hal_gattc_client_info_t));
478 if (NULL == gattc_data) {
479 ERR("Unable to allocate memory");
480 ret = BT_STATUS_FAIL;
484 memcpy(gattc_data->bd_addr.address, bd_addr->address,
485 BT_HAL_ADDRESS_LENGTH_MAX);
486 gattc_data->client_if = client_if;
487 gattc_data->conn_id = conn_id;
489 DBG("DisconnectLE [%s]", device_address);
491 g_dbus_proxy_call(device_proxy, "DisconnectLE",
493 G_DBUS_CALL_FLAGS_NONE,
494 BT_HAL_MAX_DBUS_TIMEOUT,
496 (GAsyncReadyCallback)__le_disconnection_req_cb, gattc_data);
500 g_object_unref(device_proxy);
507 /** Disconnect a remote device or cancel a pending connection */
508 bt_status_t btif_gattc_client_disconnect(int client_if, const bt_bdaddr_t *bd_addr,
515 return _hal_gattc_disconnect(client_if, bd_addr, conn_id);
518 /** Clear the attribute cache for a given device */
519 bt_status_t refresh(int client_if, const bt_bdaddr_t *bd_addr)
522 return BT_STATUS_UNSUPPORTED;
525 static hal_gattc_service_t* _gattc_find_service_from_uuid(hal_gattc_server_info_t *conn_info, bt_uuid_t *svc_uuid)
530 hal_gattc_service_t *info = NULL;
532 for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
533 info = (hal_gattc_service_t*)l->data;
537 if (!memcmp(&info->svc_uuid, svc_uuid, sizeof(bt_uuid_t))) {
538 INFO("Found GATT service uuid");
546 static hal_gattc_char_t* _gattc_find_char_from_uuid(hal_gattc_service_t *gattc_svc, bt_uuid_t *char_uuid)
551 hal_gattc_char_t *info = NULL;
553 for (l = gattc_svc->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
554 info = (hal_gattc_char_t*)l->data;
558 if (!memcmp(&info->chr_uuid, char_uuid, sizeof(bt_uuid_t))) {
559 INFO("Found GATT char uuid");
566 static hal_gattc_desc_t* _gattc_find_desc_from_uuid(hal_gattc_char_t *gattc_char, bt_uuid_t *desc_uuid)
571 hal_gattc_desc_t *info = NULL;
573 for (l = gattc_char->gatt_list_descs; l != NULL; l = g_slist_next(l)) {
574 info = (hal_gattc_desc_t*)l->data;
578 if (!memcmp(&info->desc_uuid, desc_uuid, sizeof(bt_uuid_t))) {
579 INFO("Found GATT descriptor uuid");
587 static hal_gattc_service_t* _hal_gatt_client_add_service(hal_gattc_server_info_t *conn_info,
588 const char *uuid_str, char *object_path)
591 hal_gattc_service_t *gattc_service = NULL;
593 gattc_service = g_malloc0(sizeof(hal_gattc_service_t));
594 gattc_service->svc_path = g_strdup(object_path);
595 _bt_hal_convert_uuid_string_to_type(gattc_service->svc_uuid.uu, uuid_str);
597 DBG("service count[%d]", g_slist_length(conn_info->gatt_list_services));
599 conn_info->gatt_list_services = g_slist_append(conn_info->gatt_list_services, gattc_service);
601 DBG("svc path {%s] svc uuid [%s]", object_path, uuid_str);
603 return gattc_service;
606 static void _hal_gattc_add_characteristic(hal_gattc_service_t *gatt_svc, char *char_handle)
609 hal_gattc_char_t *gattc_char = NULL;
611 gattc_char = g_malloc0(sizeof(hal_gattc_char_t));
612 gattc_char->chr_path = g_strdup(char_handle);
614 DBG("svc path: [%s]", gatt_svc->svc_path);
615 DBG("char path: [%s]", gattc_char->chr_path);
617 gatt_svc->gatt_list_chars = g_slist_append(gatt_svc->gatt_list_chars, gattc_char);
620 static void _gattc_create_new_service(hal_gattc_server_info_t *conn_info, gboolean is_primary,
621 const char* uuid_str, char *object_path, GPtrArray *gp_char_array)
623 hal_gattc_service_t* gatt_svc = NULL;
625 gchar *gp_char_path = NULL;
629 /* add the service */
630 gatt_svc = _hal_gatt_client_add_service(conn_info, uuid_str, object_path);
631 if (gatt_svc == NULL) {
632 ERR("Failed to add service");
636 /* add the characteristic */
637 for (i = 0; i < gp_char_array->len; i++) {
638 gp_char_path = g_ptr_array_index(gp_char_array, i);
639 _hal_gattc_add_characteristic(gatt_svc, gp_char_path);
642 g_ptr_array_free(gp_char_array, TRUE);
645 static void _hal_gattc_add_descriptor(hal_gattc_char_t *gattc_char, char *desc_path)
647 hal_gattc_desc_t *gattc_desc = NULL;
649 gattc_desc = g_malloc0(sizeof(hal_gattc_desc_t));
650 gattc_desc->desc_path = g_strdup(desc_path);
652 gattc_char->gatt_list_descs = g_slist_append(gattc_char->gatt_list_descs, gattc_desc);
654 DBG("char path: [%s]", gattc_char->chr_path);
655 DBG("desc path: [%s]", gattc_desc->desc_path);
658 static void _hal_gattc_update_char_property(hal_gattc_char_t *gattc_char, const char* char_uuid_str,
659 GPtrArray *gp_desc_array, unsigned int char_permission)
661 gchar *gp_desc_path = NULL;
666 if (char_uuid_str == NULL) {
667 DBG("char_uuid_str is NULL");
671 //update the char uuid
672 DBG("char UUID: [%s] ", char_uuid_str);
673 DBG("char path: [%s]", gattc_char->chr_path);
675 _bt_hal_convert_uuid_string_to_type(gattc_char->chr_uuid.uu, char_uuid_str);
677 //update char permission
678 gattc_char->permission = char_permission;
681 for (i = 0; i < gp_desc_array->len; i++) {
682 gp_desc_path = g_ptr_array_index(gp_desc_array, i);
683 _hal_gattc_add_descriptor(gattc_char, gp_desc_path);
687 static void _hal_gattc_update_desc_property(hal_gattc_desc_t *gattc_desc, const char* desc_uuid_str)
691 if (desc_uuid_str == NULL) {
692 DBG("char_uuid_str is NULL");
696 //update the descriptor uuid
697 DBG("desc UUID: [%s] ", desc_uuid_str);
698 DBG("desc path: [%s]", gattc_desc->desc_path);
700 _bt_hal_convert_uuid_string_to_type(gattc_desc->desc_uuid.uu, desc_uuid_str);
703 static void browse_service_char(int conn_id)
705 hal_gattc_server_info_t *conn_info = NULL;
709 hal_gattc_service_t *svc_info = NULL;
710 hal_gattc_char_t *char_info = NULL;
711 hal_gattc_desc_t *desc_info = NULL;
715 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
716 if (conn_info == NULL) {
717 DBG("conn_info is NULL");
721 DBG("service count[%d]", g_slist_length(conn_info->gatt_list_services));
723 for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
724 svc_info = (hal_gattc_service_t*)l->data;
725 if (svc_info == NULL)
728 DBG("svc path [%s]", svc_info->svc_path);
730 /* find characteristic object path */
731 for (k = svc_info->gatt_list_chars; k != NULL; k = g_slist_next(k)) {
732 char_info = (hal_gattc_char_t *)k->data;
733 if (char_info == NULL)
736 DBG("char path[%s]", char_info->chr_path);
739 for (m = char_info->gatt_list_descs; m != NULL; m = g_slist_next(m)) {
740 desc_info = (hal_gattc_desc_t *)m->data;
741 if (desc_info == NULL)
744 DBG("desc path[%s]", desc_info->desc_path);
753 * Enumerate all GATT services on a connected device.
754 * Optionally, the results can be filtered for a given UUID.
756 static bt_status_t _gattc_client_search_service(int conn_id)
760 GVariant *result = NULL;
762 GVariantIter *svc_iter;
763 GVariantIter *interface_iter;
764 char *object_path = NULL;
765 char *interface_str = NULL;
766 const gchar *key = NULL;
767 GVariant *value = NULL;
768 GPtrArray *gp_array = NULL;
769 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
770 char temp_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
771 int ret = BT_STATUS_FAIL;
773 const gchar *uuid_str = NULL;
775 hal_gattc_server_info_t *conn_info = NULL;
776 gboolean is_primary = FALSE;
779 char *char_handle = NULL;
780 GVariantIter *char_iter = NULL;
781 GPtrArray *gp_char_array = NULL;
785 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
786 if (NULL == conn_info) {
787 DBG("Failed to get the conn_info");
788 return BT_STATUS_FAIL;
791 _bt_hal_convert_addr_type_to_string(device_address,
792 (unsigned char *)conn_info->bd_addr.address);
794 result = _bt_hal_get_managed_objects();
798 gp_array = g_ptr_array_new();
799 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
801 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
803 if (object_path == NULL)
806 _bt_hal_convert_device_path_to_address(object_path, temp_address);
808 if (g_strcmp0(temp_address, device_address) != 0)
811 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
812 &interface_str, &svc_iter)) {
813 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
816 DBG("[%d] Object Path : %s", idx++, object_path);
817 /* for characteristic */
818 gp_char_array = g_ptr_array_new();
819 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
820 if (g_strcmp0(key, "Primary") == 0) {
821 is_primary = g_variant_get_boolean(value);
824 g_ptr_array_add(gp_array, (gpointer)object_path);
827 } else if (g_strcmp0(key, "UUID") == 0) {
828 uuid_str = g_variant_get_string(value, &len);
829 DBG(" UUID: [%s]", uuid_str);
830 } else if (g_strcmp0(key, "Characteristics") == 0) {
831 g_variant_get(value, "ao", &char_iter);
832 if (char_iter != NULL) {
833 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
834 DBG("char handle : %s", char_handle);
835 g_ptr_array_add(gp_char_array, (gpointer)char_handle);
842 DBG("send search service result event");
843 _bt_hal_send_search_service_result_event(conn_id, is_primary,
844 uuid_str, conn_info->inst_id);
846 _gattc_create_new_service(conn_info, is_primary, uuid_str, object_path, gp_char_array);
851 if (gp_array->len == 0 || svc_count == 0) {
852 ERR("gp_array is NULL");
853 ret = BT_STATUS_FAIL;
855 ret = BT_STATUS_SUCCESS;
858 browse_service_char(conn_id);
859 /* send search service complete event */
860 _bt_hal_send_search_service_complete_event(conn_id, ret);
862 g_ptr_array_free(gp_array, TRUE);
863 g_variant_iter_free(iter);
864 g_variant_unref(result);
869 bt_status_t btif_gattc_client_search_service(int conn_id, bt_uuid_t *filter_uuid)
871 if (NULL == filter_uuid) {
872 DBG("Browse all the services");
873 return _gattc_client_search_service(conn_id);
875 DBG("TODO implement it");
876 return BT_STATUS_UNSUPPORTED;
880 * Enumerate included services for a given service.
881 * Set start_incl_srvc_id to NULL to get the first included service.
883 bt_status_t get_included_service(int conn_id, btgatt_srvc_id_t *srvc_id,
884 btgatt_srvc_id_t *start_incl_srvc_id)
887 return BT_STATUS_UNSUPPORTED;
890 static void _bt_hal_send_client_char_search_result_event(int conn_id, int status,
891 btgatt_srvc_id_t *svc_id, bt_uuid_t *char_uuid, int char_prop)
893 struct hal_ev_gatt_client_char_search_result ev;
896 ERR("gatt client callback not registered");
900 DBG("sending gatt client search char result event conn_id[%d] status[%d]", conn_id, status);
902 memset(&ev, 0, sizeof(ev));
903 ev.conn_id = conn_id;
904 ev.inst_id = svc_id->id.inst_id;
905 ev.is_primary = svc_id->is_primary;
907 memcpy(ev.svc_uuid, svc_id->id.uuid.uu, sizeof(ev.svc_uuid));
909 if (status == BT_STATUS_SUCCESS) {
910 DBG("building char uuid");
911 memcpy(ev.char_uuid, char_uuid->uu, sizeof(ev.char_uuid));
912 ev.char_prop = char_prop;
915 DBG("sending the char search event");
917 event_cb(HAL_EV_GATT_CLIENT_CHARAC_SEARCH_RESULT, (void *)&ev, sizeof(ev));
920 static int _hal_get_permission_flag(char *permission)
924 if (NULL == permission) {
925 ERR("gatt permission is NULL");
929 if (!g_strcmp0(permission, "broadcast"))
930 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
931 else if (!g_strcmp0(permission, "read"))
932 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_READ;
933 else if (!g_strcmp0(permission, "write-without-response"))
934 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
935 else if (!g_strcmp0(permission, "write"))
936 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE;
937 else if (!g_strcmp0(permission, "notify"))
938 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
939 else if (!g_strcmp0(permission, "indicate"))
940 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
941 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
942 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
943 else if (!g_strcmp0(permission, "reliable-write"))
944 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
945 else if (!g_strcmp0(permission, "writable-auxiliaries"))
946 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
947 else if (!g_strcmp0(permission, "encrypt-read"))
948 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
949 else if (!g_strcmp0(permission, "encrypt-write"))
950 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
951 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
952 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
953 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
954 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
960 static bt_status_t _hal_gattc_get_characteristic_info(hal_gattc_char_t *gattc_char)
962 GDBusProxy *properties_proxy = NULL;
963 GError *error = NULL;
964 GVariant *value = NULL;
965 GVariant *result = NULL;
966 GDBusConnection *g_conn;
968 char *char_desc_handle = NULL;
970 GVariantIter *property_iter;
971 GVariantIter *char_desc_iter;
972 char* char_handle = NULL;
973 const gchar *char_uuid_str = NULL;
974 GPtrArray *gp_desc_array = NULL;
975 GVariantIter *char_perm_iter;
977 unsigned int char_permission = 0 ;
981 if (gattc_char->chr_path == NULL) {
982 DBG("char path is NULL");
983 return BT_STATUS_FAIL;
985 char_handle = gattc_char->chr_path;
987 DBG("char path:[%s]", gattc_char->chr_path);
989 g_conn = _bt_hal_get_system_gconn();
990 if (NULL == g_conn) {
991 ERR("_bt_gdbus_get_system_gconn returned NULL");
992 return BT_STATUS_FAIL;
995 properties_proxy = g_dbus_proxy_new_sync(g_conn,
996 G_DBUS_PROXY_FLAGS_NONE, NULL,
999 BT_HAL_PROPERTIES_INTERFACE,
1002 if (properties_proxy == NULL) {
1003 ERR("properties_proxy returned NULL");
1004 return BT_STATUS_FAIL;
1007 result = g_dbus_proxy_call_sync(properties_proxy,
1009 g_variant_new("(s)", BT_HAL_GATT_CHAR_INTERFACE),
1010 G_DBUS_CALL_FLAGS_NONE,
1015 if (error != NULL) {
1016 ERR("Fail to get properties (Error: %s)", error->message);
1017 g_clear_error(&error);
1019 ERR("Fail to get properties");
1020 g_object_unref(properties_proxy);
1021 return BT_STATUS_FAIL;
1024 gp_desc_array = g_ptr_array_new();
1026 g_variant_get(result, "(a{sv})", &property_iter);
1028 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1029 if (!g_strcmp0(key, "UUID")) {
1030 char_uuid_str = g_variant_dup_string(value, &len);
1031 DBG("char UUID [%s]", char_uuid_str);
1032 } else if (!g_strcmp0(key, "Flags")) {
1033 g_variant_get(value, "as", &char_perm_iter);
1034 char_permission = 0x00;
1036 while (g_variant_iter_loop(char_perm_iter, "s", &permission)) {
1037 DBG("char permission: [%s]", permission);
1038 char_permission |= _hal_get_permission_flag(permission);
1040 } else if (!g_strcmp0(key, "Descriptors")) {
1041 g_variant_get(value, "ao", &char_desc_iter);
1042 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle)) {
1043 DBG("char descriptor handle : %s", char_desc_handle);
1045 g_ptr_array_add(gp_desc_array, (gpointer)char_desc_handle);
1050 _hal_gattc_update_char_property(gattc_char, char_uuid_str, gp_desc_array, char_permission);
1052 g_variant_iter_free(property_iter);
1053 g_variant_unref(result);
1054 g_object_unref(properties_proxy);
1055 g_ptr_array_free(gp_desc_array, TRUE);
1057 return BT_STATUS_SUCCESS;
1060 static bt_status_t _gattc_get_all_characteristic(int conn_id,
1061 btgatt_srvc_id_t *srvc_id)
1063 hal_gattc_server_info_t * conn_info = NULL;
1064 hal_gattc_service_t *gattc_service = NULL;
1066 hal_gattc_char_t *gattc_char = NULL;
1067 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1068 int status = BT_STATUS_FAIL;
1071 DBG("conn_id[%d]", conn_id);
1073 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1074 if (NULL == conn_info) {
1075 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1076 return BT_STATUS_FAIL;
1080 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1081 if (NULL == gattc_service) {
1082 DBG("Failed to get the gatt service");
1083 return BT_STATUS_FAIL;
1086 DBG("service path [%s]", gattc_service->svc_path);
1088 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1089 DBG("service uuid [%s]", svc_uuid_str);
1091 /* find characteristic object path */
1092 for (l = gattc_service->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
1093 gattc_char = (hal_gattc_char_t *)l->data;
1094 status = _hal_gattc_get_characteristic_info(gattc_char);
1097 if (BT_STATUS_SUCCESS == status) {
1098 DBG("Sending the success charateristics event");
1099 _bt_hal_send_client_char_search_result_event(conn_id, status, srvc_id,
1100 &gattc_char->chr_uuid, gattc_char->permission);
1104 DBG("sending final event");
1106 status = BT_STATUS_FAIL;
1107 _bt_hal_send_client_char_search_result_event(conn_id, status, srvc_id, NULL, 0);
1109 browse_service_char(conn_id);
1110 /* retrive uuid for characteristic and object path for descriptor */
1112 return BT_STATUS_SUCCESS;
1116 * Enumerate characteristics for a given service.
1117 * Set start_char_id to NULL to get the first characteristic.
1119 bt_status_t btif_gattc_get_characteristic(int conn_id,
1120 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *start_char_id)
1123 CHECK_BTGATT_INIT();
1125 if (start_char_id == NULL) {
1126 DBG("Get all the characteristics");
1127 return _gattc_get_all_characteristic(conn_id, srvc_id);
1130 DBG("TBD Get specific characteristics");
1131 return BT_STATUS_UNSUPPORTED;
1135 static bt_status_t _hal_gattc_get_descriptor_info(hal_gattc_desc_t *gattc_desc)
1137 GDBusProxy *properties_proxy = NULL;
1138 GError *error = NULL;
1139 GVariant *value = NULL;
1140 GVariant *result = NULL;
1141 GDBusConnection *g_conn;
1144 GVariantIter *property_iter;
1145 char* desc_handle = NULL;
1146 const gchar *desc_uuid_str = NULL;
1150 if (gattc_desc->desc_path == NULL) {
1151 DBG("desc path is NULL");
1152 return BT_STATUS_FAIL;
1154 desc_handle = gattc_desc->desc_path;
1156 DBG("desc path:[%s]", gattc_desc->desc_path);
1158 g_conn = _bt_hal_get_system_gconn();
1159 if (NULL == g_conn) {
1160 ERR("_bt_gdbus_get_system_gconn returned NULL");
1161 return BT_STATUS_FAIL;
1164 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1165 G_DBUS_PROXY_FLAGS_NONE, NULL,
1168 BT_HAL_PROPERTIES_INTERFACE,
1171 if (properties_proxy == NULL) {
1172 ERR("properties_proxy returned NULL");
1173 return BT_STATUS_FAIL;
1176 result = g_dbus_proxy_call_sync(properties_proxy,
1178 g_variant_new("(s)", BT_HAL_GATT_DESC_INTERFACE),
1179 G_DBUS_CALL_FLAGS_NONE,
1184 if (error != NULL) {
1185 ERR("Fail to get properties (Error: %s)", error->message);
1186 g_clear_error(&error);
1188 ERR("Fail to get properties");
1189 g_object_unref(properties_proxy);
1190 return BT_STATUS_FAIL;
1193 g_variant_get(result, "(a{sv})", &property_iter);
1195 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1196 if (!g_strcmp0(key, "UUID")) {
1197 desc_uuid_str = g_variant_dup_string(value, &len);
1198 DBG("desc UUID [%s]", desc_uuid_str);
1202 _hal_gattc_update_desc_property(gattc_desc, desc_uuid_str);
1204 g_variant_iter_free(property_iter);
1205 g_variant_unref(result);
1206 g_object_unref(properties_proxy);
1208 return BT_STATUS_SUCCESS;
1211 static void _bt_hal_send_client_desc_search_result_event(int conn_id, int status,
1212 btgatt_srvc_id_t *svc_id, btgatt_gatt_id_t *char_id, bt_uuid_t *desc_uuid)
1214 struct hal_ev_gatt_client_desc_search_result ev;
1217 ERR("gatt client callback not registered");
1221 DBG("sending gatt client search desc result event conn_id[%d] status[%d]", conn_id, status);
1223 memset(&ev, 0, sizeof(ev));
1224 ev.conn_id = conn_id;
1225 ev.inst_id = svc_id->id.inst_id;
1226 ev.is_primary = svc_id->is_primary;
1229 memcpy(ev.svc_uuid, svc_id->id.uuid.uu, sizeof(ev.svc_uuid));
1230 memcpy(ev.char_uuid, char_id->uuid.uu, sizeof(ev.char_uuid));
1232 if (status == BT_STATUS_SUCCESS) {
1233 DBG("building desc uuid");
1234 memcpy(ev.desc_uuid, desc_uuid->uu, sizeof(ev.desc_uuid));
1237 DBG("sending the desc search event");
1239 event_cb(HAL_EV_GATT_CLIENT_DESC_SEARCH_RESULT, (void *)&ev, sizeof(ev));
1242 static bt_status_t _hal_gattc_get_all_descriptor(int conn_id,
1243 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id)
1245 hal_gattc_server_info_t * conn_info = NULL;
1246 hal_gattc_service_t *gattc_service = NULL;
1248 hal_gattc_char_t *gattc_char = NULL;
1249 hal_gattc_desc_t *gattc_desc = NULL;
1250 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1251 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1252 int status = BT_STATUS_FAIL;
1256 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1257 if (NULL == conn_info) {
1258 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1259 return BT_STATUS_FAIL;
1263 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1264 if (NULL == gattc_service) {
1265 DBG("Failed to get the gatt service");
1266 return BT_STATUS_FAIL;
1269 DBG("service path [%s]", gattc_service->svc_path);
1270 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1271 DBG("service uuid [%s]", svc_uuid_str);
1273 /* find characteristics */
1274 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1275 if (NULL == gattc_char) {
1276 DBG("Failed to get the gatt char");
1277 return BT_STATUS_FAIL;
1280 DBG("char path [%s]", gattc_char->chr_path);
1281 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1282 DBG("char uuid [%s]", char_uuid_str);
1284 /* get descriptor uuid */
1285 for (l = gattc_char->gatt_list_descs; l != NULL; l = g_slist_next(l)) {
1286 gattc_desc = (hal_gattc_desc_t *)l->data;
1287 status = _hal_gattc_get_descriptor_info(gattc_desc);
1290 if (BT_STATUS_SUCCESS == status) {
1291 DBG("Sending the success descriptor event");
1292 _bt_hal_send_client_desc_search_result_event(conn_id, status, srvc_id,
1293 char_id, &gattc_desc->desc_uuid);
1297 DBG("sending final event");
1299 status = BT_STATUS_FAIL;
1300 _bt_hal_send_client_desc_search_result_event(conn_id, status, srvc_id, char_id, NULL);
1302 browse_service_char(conn_id);
1303 /* retrive uuid for characteristic and object path for descriptor */
1305 return BT_STATUS_SUCCESS;
1309 * Enumerate descriptors for a given characteristic.
1310 * Set start_descr_id to NULL to get the first descriptor.
1312 bt_status_t btif_gattc_get_descriptor(int conn_id,
1313 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1314 btgatt_gatt_id_t *start_descr_id)
1317 CHECK_BTGATT_INIT();
1319 if (start_descr_id == NULL) {
1320 DBG("Get all the descriptors");
1321 return _hal_gattc_get_all_descriptor(conn_id, srvc_id, char_id);
1323 DBG("TBD Get specific descriptor");
1324 return BT_STATUS_UNSUPPORTED;
1328 static void __hal_send_char_read_event(hal_gatt_resp_data_t *resp_data, int result, uint8_t *value, int len)
1330 struct hal_ev_gatt_client_read_data ev;
1333 ERR("gatt client callback not registered");
1337 DBG("sending gatt client charac read conn_id[%d] status[%d]", resp_data->conn_id, result);
1339 memset(&ev, 0, sizeof(ev));
1340 ev.conn_id = resp_data->conn_id;
1341 ev.inst_id = resp_data->srvc_id.id.inst_id;
1342 ev.is_primary = resp_data->srvc_id.is_primary;
1345 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1346 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1350 DBG("building the char read value [%d]", len);
1351 memcpy(ev.value, value, len);
1354 DBG("sending the gatt client read charac event");
1356 event_cb(HAL_EV_GATT_CLIENT_READ_CHARAC, (void *)&ev, sizeof(ev));
1359 static void __hal_internal_read_char_cb(GObject *source_object,
1360 GAsyncResult *res, gpointer user_data)
1362 GError *error = NULL;
1363 GDBusConnection *system_gconn = NULL;
1366 GByteArray *gp_byte_array = NULL;
1368 hal_gatt_resp_data_t *resp_data = user_data;
1369 int result = BT_STATUS_SUCCESS;
1374 system_gconn = _bt_hal_get_system_gconn();
1375 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1378 ERR("Read Characteristic dbus failed Error:[%s]", error->message);
1381 result = BT_STATUS_FAIL;
1382 __hal_send_char_read_event(resp_data, result, NULL, 0);
1383 g_clear_error(&error);
1388 gp_byte_array = g_byte_array_new();
1389 g_variant_get(value, "(ay)", &iter);
1391 while (g_variant_iter_loop(iter, "y", &g_byte))
1392 g_byte_array_append(gp_byte_array, &g_byte, 1);
1396 for (i = 0; i < gp_byte_array->len; i++)
1397 DBG("%02x", gp_byte_array->data[i]);
1400 __hal_send_char_read_event(resp_data, result, gp_byte_array->data, gp_byte_array->len);
1404 g_byte_array_free(gp_byte_array, TRUE);
1405 g_variant_iter_free(iter);
1406 g_variant_unref(value);
1412 static bt_status_t _hal_read_characteristic_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1413 btgatt_gatt_id_t *char_id, int auth_req)
1415 GDBusConnection *g_conn;
1416 hal_gatt_resp_data_t *resp_data;
1417 hal_gattc_service_t *gattc_service = NULL;
1418 GVariantBuilder *builder = NULL;
1420 hal_gattc_server_info_t * conn_info = NULL;
1421 hal_gattc_char_t *gattc_char = NULL;
1422 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1423 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1424 char* char_handle = NULL;
1428 /* get the connection info */
1429 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1430 if (NULL == conn_info) {
1431 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1432 return BT_STATUS_FAIL;
1436 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1437 if (NULL == gattc_service) {
1438 DBG("Failed to get the gatt service");
1439 return BT_STATUS_FAIL;
1442 DBG("service path [%s]", gattc_service->svc_path);
1443 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1444 DBG("service uuid [%s]", svc_uuid_str);
1447 /* find characteristic */
1448 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1449 if (NULL == gattc_char) {
1450 DBG("Failed to get the gatt char");
1451 return BT_STATUS_FAIL;
1454 DBG("char path [%s]", gattc_char->chr_path);
1455 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1456 DBG("char uuid [%s]", char_uuid_str);
1458 g_conn = _bt_hal_get_system_gconn();
1459 if (NULL == g_conn) {
1460 ERR("_bt_gdbus_get_system_gconn returned NULL");
1461 return BT_STATUS_FAIL;
1464 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1465 if (NULL == resp_data) {
1466 ERR("failed to get the memory");
1467 return BT_STATUS_FAIL;
1470 resp_data->conn_id = conn_id;
1471 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1472 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1474 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1477 g_variant_builder_add(builder, "{sv}", "offset",
1478 g_variant_new("q", offset));
1480 char_handle = gattc_char->chr_path;
1482 DBG("calling char read value");
1484 g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, char_handle, BT_HAL_GATT_CHAR_INTERFACE,
1485 "ReadValue", g_variant_new("(a{sv})", builder),
1486 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1487 (GAsyncReadyCallback)__hal_internal_read_char_cb,
1488 (gpointer)resp_data);
1489 g_variant_builder_unref(builder);
1491 return BT_STATUS_SUCCESS;
1494 /** Read a characteristic on a remote device */
1495 bt_status_t btif_read_characteristic(int conn_id,
1496 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1499 CHECK_BTGATT_INIT();
1502 return _hal_read_characteristic_value(conn_id, srvc_id, char_id, auth_req);
1505 static void __hal_send_char_write_event(hal_gatt_resp_data_t *resp_data, int result)
1507 struct hal_ev_gatt_client_write_result ev;
1510 ERR("gatt client callback not registered");
1514 DBG("sending gatt client charac write conn_id[%d] status[%d]", resp_data->conn_id, result);
1516 memset(&ev, 0, sizeof(ev));
1517 ev.conn_id = resp_data->conn_id;
1518 ev.inst_id = resp_data->srvc_id.id.inst_id;
1519 ev.is_primary = resp_data->srvc_id.is_primary;
1522 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1523 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1525 DBG("sending the gatt client write charac event");
1527 event_cb(HAL_EV_GATT_CLIENT_WRITE_CHARAC, (void *)&ev, sizeof(ev));
1530 static void __hal_bluetooth_internal_write_cb(GObject *source_object,
1531 GAsyncResult *res, gpointer user_data)
1533 GError *error = NULL;
1534 GDBusConnection *system_gconn = NULL;
1536 hal_gatt_resp_data_t *resp_data = user_data;
1537 int result = BT_STATUS_SUCCESS;
1541 system_gconn = _bt_hal_get_system_gconn();
1542 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1545 ERR("write Characteristic dbus failed Error:[%s]", error->message);
1547 result = BT_STATUS_FAIL;
1549 __hal_send_char_write_event(resp_data, result);
1550 g_clear_error(&error);
1555 //send write value event
1556 __hal_send_char_write_event(resp_data, result);
1559 g_variant_unref(value);
1564 static bt_status_t __hal_get_write_prop(hal_gatt_write_type_t type, hal_gatt_property_e *prop)
1567 case HAL_GATT_WRITE_TYPE_WRITE:
1568 *prop = HAL_GATT_PROPERTY_WRITE;
1570 case HAL_GATT_WRITE_TYPE_WRITE_NO_RESPONSE:
1571 *prop = HAL_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE;
1574 ERR("Unknow write type : %d", type);
1575 return BT_STATUS_FAIL;
1578 return BT_STATUS_SUCCESS;
1581 static bt_status_t _hal_write_characteristic_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1582 btgatt_gatt_id_t *char_id, int write_type, int length, int auth_req, char* value)
1584 GVariant *val, *options;
1585 GVariantBuilder *builder1;
1586 GVariantBuilder *builder2;
1587 GDBusConnection *g_conn;
1590 hal_gatt_resp_data_t *resp_data;
1591 hal_gattc_service_t *gattc_service = NULL;
1592 hal_gattc_server_info_t * conn_info = NULL;
1593 hal_gattc_char_t *gattc_char = NULL;
1594 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1595 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1596 char* char_handle = NULL;
1597 hal_gatt_property_e write_prop = HAL_GATT_PROPERTY_WRITE;
1598 int ret = BT_STATUS_SUCCESS;
1602 ret = __hal_get_write_prop(write_type, &write_prop);
1603 if (BT_STATUS_FAIL == ret) {
1604 DBG("received invalid write type:[%d] ", write_type);
1605 return BT_STATUS_FAIL;
1608 /* get the connection info */
1609 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1610 if (NULL == conn_info) {
1611 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1612 return BT_STATUS_FAIL;
1616 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1617 if (NULL == gattc_service) {
1618 DBG("Failed to get the gatt service");
1619 return BT_STATUS_FAIL;
1622 DBG("service path [%s]", gattc_service->svc_path);
1623 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1624 DBG("service uuid [%s]", svc_uuid_str);
1626 /* find characteristic */
1627 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1628 if (NULL == gattc_char) {
1629 DBG("Failed to get the gatt char");
1630 return BT_STATUS_FAIL;
1633 DBG("char path [%s]", gattc_char->chr_path);
1634 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1635 DBG("char uuid [%s]", char_uuid_str);
1637 g_conn = _bt_hal_get_system_gconn();
1638 if (NULL == g_conn) {
1639 ERR("_bt_gdbus_get_system_gconn returned NULL");
1640 return BT_STATUS_FAIL;
1643 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1644 if (NULL == resp_data) {
1645 ERR("failed to get the memory");
1646 return BT_STATUS_FAIL;
1649 resp_data->conn_id = conn_id;
1650 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1651 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1653 char_handle = gattc_char->chr_path;
1655 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1657 for (i = 0; i < length; i++)
1658 g_variant_builder_add(builder1, "y", value[i]);
1660 val = g_variant_new("ay", builder1);
1662 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1664 g_variant_builder_add(builder2, "{sv}", "offset",
1665 g_variant_new_uint16(offset));
1667 options = g_variant_new("a{sv}", builder2);
1669 g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, char_handle, BT_HAL_GATT_CHAR_INTERFACE,
1671 g_variant_new("(y@ay@a{sv})", write_prop, val, options),
1673 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1674 (GAsyncReadyCallback)__hal_bluetooth_internal_write_cb,
1675 (gpointer)resp_data);
1677 g_variant_builder_unref(builder1);
1678 g_variant_builder_unref(builder2);
1680 return BT_STATUS_SUCCESS;
1683 /** Write a remote characteristic */
1684 bt_status_t btif_write_characteristic(int conn_id,
1685 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1686 int write_type, int len, int auth_req,
1689 CHECK_BTGATT_INIT();
1693 DBG("svc isntance id:[%d]", srvc_id->id.inst_id);
1694 return _hal_write_characteristic_value(conn_id, srvc_id, char_id, write_type,
1695 len, auth_req, p_value);
1698 static void __hal_send_desc_read_event(hal_gatt_resp_data_t *resp_data, int result, uint8_t *value, int len)
1700 struct hal_ev_gatt_client_read_data ev;
1703 ERR("gatt client callback not registered");
1707 DBG("sending gatt client desc read conn_id[%d] status[%d]", resp_data->conn_id, result);
1709 memset(&ev, 0, sizeof(ev));
1710 ev.conn_id = resp_data->conn_id;
1711 ev.inst_id = resp_data->srvc_id.id.inst_id;
1712 ev.is_primary = resp_data->srvc_id.is_primary;
1715 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1716 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1717 memcpy(ev.desc_uuid, resp_data->desc_id.uuid.uu, sizeof(ev.char_uuid));
1721 DBG("building the desc read value [%d]", len);
1722 memcpy(ev.value, value, len);
1725 DBG("sending the gatt client read descriptor event");
1727 event_cb(HAL_EV_GATT_CLIENT_READ_DESC, (void *)&ev, sizeof(ev));
1730 static void __hal_internal_read_desc_cb(GObject *source_object,
1731 GAsyncResult *res, gpointer user_data)
1733 GError *error = NULL;
1734 GDBusConnection *system_gconn = NULL;
1737 GByteArray *gp_byte_array = NULL;
1739 hal_gatt_resp_data_t *resp_data = user_data;
1740 int result = BT_STATUS_SUCCESS;
1745 system_gconn = _bt_hal_get_system_gconn();
1746 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1749 ERR("Read descriptor dbus failed Error:[%s]", error->message);
1752 result = BT_STATUS_FAIL;
1753 __hal_send_desc_read_event(resp_data, result, NULL, 0);
1754 g_clear_error(&error);
1759 gp_byte_array = g_byte_array_new();
1760 g_variant_get(value, "(ay)", &iter);
1762 while (g_variant_iter_loop(iter, "y", &g_byte))
1763 g_byte_array_append(gp_byte_array, &g_byte, 1);
1767 for (i = 0; i < gp_byte_array->len; i++)
1768 DBG("%02x", gp_byte_array->data[i]);
1771 __hal_send_desc_read_event(resp_data, result, gp_byte_array->data, gp_byte_array->len);
1775 g_byte_array_free(gp_byte_array, TRUE);
1776 g_variant_iter_free(iter);
1777 g_variant_unref(value);
1782 static bt_status_t _hal_read_descriptor_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1783 btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *desc_id, int auth_req)
1785 GDBusConnection *g_conn;
1786 hal_gatt_resp_data_t *resp_data;
1787 hal_gattc_service_t *gattc_service = NULL;
1788 GVariantBuilder *builder = NULL;
1790 hal_gattc_server_info_t * conn_info = NULL;
1791 hal_gattc_char_t *gattc_char = NULL;
1792 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1793 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1794 char desc_uuid_str[BT_HAL_UUID_STRING_LEN];
1795 char* desc_handle = NULL;
1797 hal_gattc_desc_t *gattc_desc = NULL;
1801 /* get the connection info */
1802 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1803 if (NULL == conn_info) {
1804 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1805 return BT_STATUS_FAIL;
1809 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1810 if (NULL == gattc_service) {
1811 DBG("Failed to get the gatt service");
1812 return BT_STATUS_FAIL;
1815 DBG("service path [%s]", gattc_service->svc_path);
1816 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1817 DBG("service uuid [%s]", svc_uuid_str);
1819 /* find characteristic */
1820 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1821 if (NULL == gattc_char) {
1822 DBG("Failed to get the gatt char");
1823 return BT_STATUS_FAIL;
1826 DBG("char path [%s]", gattc_char->chr_path);
1827 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1828 DBG("char uuid [%s]", char_uuid_str);
1830 /* find descriptor */
1831 gattc_desc = _gattc_find_desc_from_uuid(gattc_char, &desc_id->uuid);
1832 if (NULL == gattc_desc) {
1833 DBG("Failed to get the gatt desc");
1834 return BT_STATUS_FAIL;
1837 DBG("desc path [%s]", gattc_desc->desc_path);
1838 _bt_hal_convert_uuid_type_to_string(desc_uuid_str, gattc_desc->desc_uuid.uu);
1839 DBG("desc uuid [%s]", desc_uuid_str);
1841 g_conn = _bt_hal_get_system_gconn();
1842 if (NULL == g_conn) {
1843 ERR("_bt_gdbus_get_system_gconn returned NULL");
1844 return BT_STATUS_FAIL;
1847 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1848 if (NULL == resp_data) {
1849 ERR("failed to get the memory");
1850 return BT_STATUS_FAIL;
1853 resp_data->conn_id = conn_id;
1854 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1855 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1856 memcpy(&resp_data->desc_id, desc_id, sizeof(btgatt_gatt_id_t));
1858 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1861 g_variant_builder_add(builder, "{sv}", "offset",
1862 g_variant_new("q", offset));
1864 desc_handle = gattc_desc->desc_path;
1866 DBG("calling desc read value");
1868 g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, desc_handle, BT_HAL_GATT_DESC_INTERFACE,
1869 "ReadValue", g_variant_new("(a{sv})", builder),
1870 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1871 (GAsyncReadyCallback)__hal_internal_read_desc_cb,
1872 (gpointer)resp_data);
1873 g_variant_builder_unref(builder);
1875 return BT_STATUS_SUCCESS;
1878 /** Read the descriptor for a given characteristic */
1879 bt_status_t btif_read_descriptor(int conn_id,
1880 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1881 btgatt_gatt_id_t *descr_id, int auth_req)
1883 CHECK_BTGATT_INIT();
1885 return _hal_read_descriptor_value(conn_id, srvc_id, char_id, descr_id, auth_req);
1888 static void __hal_send_desc_write_event(hal_gatt_resp_data_t *resp_data, int result)
1890 struct hal_ev_gatt_client_write_result ev;
1893 ERR("gatt client callback not registered");
1897 DBG("sending gatt client charac write conn_id[%d] status[%d]", resp_data->conn_id, result);
1899 memset(&ev, 0, sizeof(ev));
1900 ev.conn_id = resp_data->conn_id;
1901 ev.inst_id = resp_data->srvc_id.id.inst_id;
1902 ev.is_primary = resp_data->srvc_id.is_primary;
1905 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1906 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1907 memcpy(ev.desc_uuid, resp_data->desc_id.uuid.uu, sizeof(ev.desc_uuid));
1909 DBG("sending the gatt client write charac event");
1911 event_cb(HAL_EV_GATT_CLIENT_WRITE_DESC, (void *)&ev, sizeof(ev));
1914 static void __hal_bluetooth_internal_desc_write_cb(GObject *source_object,
1915 GAsyncResult *res, gpointer user_data)
1917 GError *error = NULL;
1918 GDBusConnection *system_gconn = NULL;
1920 hal_gatt_resp_data_t *resp_data = user_data;
1921 int result = BT_STATUS_SUCCESS;
1925 system_gconn = _bt_hal_get_system_gconn();
1926 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1929 ERR("write descriptor dbus failed Error: [%s]", error->message);
1932 result = BT_STATUS_FAIL;
1933 __hal_send_desc_write_event(resp_data, result);
1934 g_clear_error(&error);
1939 //send write value event
1940 __hal_send_desc_write_event(resp_data, result);
1943 g_variant_unref(value);
1948 static bt_status_t _hal_write_descriptor_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1949 btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *descr_id,
1950 int write_type, int length, int auth_req, char* value)
1952 GVariant *val, *options;
1953 GVariantBuilder *builder1;
1954 GVariantBuilder *builder2;
1955 GDBusConnection *g_conn;
1958 hal_gatt_resp_data_t *resp_data;
1959 hal_gattc_service_t *gattc_service = NULL;
1960 hal_gattc_server_info_t * conn_info = NULL;
1961 hal_gattc_char_t *gattc_char = NULL;
1962 hal_gattc_desc_t *gattc_desc = NULL;
1963 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1964 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1965 char desc_uuid_str[BT_HAL_UUID_STRING_LEN];
1966 char* desc_handle = NULL;
1967 hal_gatt_property_e write_prop = HAL_GATT_PROPERTY_WRITE;
1968 int ret = BT_STATUS_SUCCESS;
1972 ret = __hal_get_write_prop(write_type, &write_prop);
1973 if (BT_STATUS_FAIL == ret) {
1974 DBG("received invalid write type:[%d] ", write_type);
1975 return BT_STATUS_FAIL;
1978 /* get the connection info */
1979 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1980 if (NULL == conn_info) {
1981 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1982 return BT_STATUS_FAIL;
1986 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1987 if (NULL == gattc_service) {
1988 DBG("Failed to get the gatt service");
1989 return BT_STATUS_FAIL;
1992 DBG("service path [%s]", gattc_service->svc_path);
1993 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1994 DBG("service uuid [%s]", svc_uuid_str);
1996 /* find characteristic */
1997 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1998 if (NULL == gattc_char) {
1999 DBG("Failed to get the gatt char");
2000 return BT_STATUS_FAIL;
2003 DBG("char path [%s]", gattc_char->chr_path);
2004 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2005 DBG("char uuid [%s]", char_uuid_str);
2007 /* find descriptor */
2008 gattc_desc = _gattc_find_desc_from_uuid(gattc_char, &descr_id->uuid);
2009 if (NULL == gattc_desc) {
2010 DBG("Failed to get the gatt char");
2011 return BT_STATUS_FAIL;
2014 DBG("desc path [%s]", gattc_desc->desc_path);
2015 _bt_hal_convert_uuid_type_to_string(desc_uuid_str, gattc_desc->desc_uuid.uu);
2016 DBG("char uuid [%s]", desc_uuid_str);
2018 g_conn = _bt_hal_get_system_gconn();
2019 if (NULL == g_conn) {
2020 ERR("_bt_gdbus_get_system_gconn returned NULL");
2021 return BT_STATUS_FAIL;
2024 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
2025 if (NULL == resp_data) {
2026 ERR("failed to get the memory");
2027 return BT_STATUS_FAIL;
2030 resp_data->conn_id = conn_id;
2031 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2032 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2033 memcpy(&resp_data->desc_id, descr_id, sizeof(btgatt_gatt_id_t));
2035 desc_handle = gattc_desc->desc_path;
2037 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2039 for (i = 0; i < length; i++)
2040 g_variant_builder_add(builder1, "y", value[i]);
2042 val = g_variant_new("ay", builder1);
2044 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2046 g_variant_builder_add(builder2, "{sv}", "offset",
2047 g_variant_new_uint16(offset));
2049 options = g_variant_new("a{sv}", builder2);
2051 g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, desc_handle, BT_HAL_GATT_DESC_INTERFACE,
2053 g_variant_new("(@ay@a{sv})", val, options),
2055 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2056 (GAsyncReadyCallback)__hal_bluetooth_internal_desc_write_cb,
2057 (gpointer)resp_data);
2059 g_variant_builder_unref(builder1);
2060 g_variant_builder_unref(builder2);
2062 return BT_STATUS_SUCCESS;
2065 /** Write a remote descriptor for a given characteristic */
2066 bt_status_t btif_write_descriptor(int conn_id,
2067 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
2068 btgatt_gatt_id_t *descr_id, int write_type, int len,
2069 int auth_req, char* p_value)
2071 CHECK_BTGATT_INIT();
2073 return _hal_write_descriptor_value(conn_id, srvc_id, char_id, descr_id, write_type,
2074 len, auth_req, p_value);
2077 /** Execute a prepared write operation */
2078 bt_status_t execute_write(int conn_id, int execute)
2080 CHECK_BTGATT_INIT();
2081 return BT_STATUS_UNSUPPORTED;
2084 static gboolean _hal_watch_register_notifi_cb(gpointer user_data)
2086 struct hal_ev_gatt_client_watch_notification ev;
2087 hal_gatt_resp_data_t *resp_data = user_data;
2089 DBG("sending the watch register notification event");
2090 /* send the event */
2091 memset(&ev, 0, sizeof(ev));
2092 ev.client_if = resp_data->conn_id; /* conn_id is saved with client_if */
2094 ev.status = resp_data->result;
2096 ev.is_primary = resp_data->srvc_id.is_primary;
2097 ev.inst_id = resp_data->srvc_id.id.inst_id;
2099 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
2100 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
2103 ERR("GATT Callback not registered");
2105 event_cb(HAL_EV_GATT_CLIENT_WATCH_NOTIFICATION, (void *)&ev, sizeof(ev));
2112 static bt_status_t _hal_register_for_notification(int client_if,
2113 bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2114 btgatt_gatt_id_t *char_id)
2116 int result = BT_STATUS_SUCCESS;
2117 GError *error = NULL;
2118 GDBusConnection *g_conn;
2119 hal_gattc_client_info_t *gattc_client = NULL;
2120 hal_gattc_server_info_t * conn_info = NULL;
2121 hal_gattc_service_t *gattc_service = NULL;
2122 hal_gattc_char_t *gattc_char = NULL;
2123 char* char_handle = NULL;
2124 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
2125 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
2126 hal_gatt_resp_data_t *resp_data;
2130 gattc_client = __bt_find_gatt_client_info(bd_addr);
2131 if (gattc_client == NULL) {
2132 ERR("failed to get the gatt client info");
2133 return BT_STATUS_FAIL;
2136 if (gattc_client->client_if != client_if) {
2137 ERR("could not find the gatt client for client id[%d]", client_if);
2138 return BT_STATUS_FAIL;
2141 /* get the connection info */
2142 conn_info = __bt_find_gatt_conn_info(bd_addr);
2143 if (NULL == conn_info) {
2144 ERR("Failed to get the conn_info");
2145 return BT_STATUS_FAIL;
2148 if (conn_info->inst_id != gattc_client->inst_id) {
2149 ERR("could not fild the conn_info");
2150 return BT_STATUS_FAIL;
2154 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
2155 if (NULL == gattc_service) {
2156 DBG("Failed to get the gatt service");
2157 return BT_STATUS_FAIL;
2160 DBG("service path [%s]", gattc_service->svc_path);
2161 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
2162 DBG("service uuid [%s]", svc_uuid_str);
2165 /* find characteristic */
2166 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
2167 if (NULL == gattc_char) {
2168 DBG("Failed to get the gatt char");
2169 return BT_STATUS_FAIL;
2172 DBG("char path [%s]", gattc_char->chr_path);
2173 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2174 DBG("char uuid [%s]", char_uuid_str);
2176 char_handle = gattc_char->chr_path;
2178 g_conn = _bt_hal_get_system_gconn();
2179 if (g_conn == NULL) {
2181 return BT_STATUS_FAIL;
2184 resp_data = malloc(sizeof(hal_gatt_resp_data_t));
2185 if (NULL == resp_data) {
2186 ERR("failed to get the memory");
2187 return BT_STATUS_FAIL;
2190 DBG("#StartNotify");
2191 g_dbus_connection_call_sync(g_conn,
2194 BT_HAL_GATT_CHAR_INTERFACE,
2198 G_DBUS_CALL_FLAGS_NONE,
2199 BT_HAL_MAX_DBUS_TIMEOUT, NULL, &error);
2202 g_dbus_error_strip_remote_error(error);
2203 ERR("### Watch Failed: %s", error->message);
2204 if (g_strrstr(error->message, "Already notifying"))
2205 result = BT_STATUS_SUCCESS;
2206 else if (g_strrstr(error->message, "In Progress"))
2207 result = BT_STATUS_BUSY;
2208 else if (g_strrstr(error->message, "Operation is not supported"))
2209 result = BT_STATUS_UNSUPPORTED;
2210 /*failed because of either Insufficient Authorization or Write Not Permitted */
2211 else if (g_strrstr(error->message, "Write not permitted") ||
2212 g_strrstr(error->message, "Operation Not Authorized"))
2213 result = BT_STATUS_AUTH_FAILURE;
2214 /* failed because of either Insufficient Authentication,
2215 Insufficient Encryption Key Size, or Insufficient Encryption. */
2216 else if (g_strrstr(error->message, "Not paired"))
2217 result = BT_STATUS_NOT_READY;
2219 result = BT_STATUS_FAIL;
2221 g_clear_error(&error);
2224 resp_data->conn_id = gattc_client->client_if; /* saving client_if instead of conn_id */
2225 resp_data->result = result;
2226 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2227 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2229 g_idle_add(_hal_watch_register_notifi_cb, (gpointer)resp_data);
2233 return BT_STATUS_SUCCESS;
2237 * Register to receive notifications or indications for a given
2240 bt_status_t btif_register_for_notification(int client_if,
2241 const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2242 btgatt_gatt_id_t *char_id)
2244 CHECK_BTGATT_INIT();
2246 return _hal_register_for_notification(client_if, (bt_bdaddr_t *)bd_addr, srvc_id, char_id);
2249 static gboolean _hal_watch_deregister_notifi_cb(gpointer user_data)
2251 struct hal_ev_gatt_client_watch_notification ev;
2252 hal_gatt_resp_data_t *resp_data = user_data;
2254 DBG("sending the watch deregister notification event");
2255 /* send the event */
2256 memset(&ev, 0, sizeof(ev));
2257 ev.client_if = resp_data->conn_id; /* conn_id is saved with client_if */
2259 ev.status = resp_data->result;
2261 ev.is_primary = resp_data->srvc_id.is_primary;
2262 ev.inst_id = resp_data->srvc_id.id.inst_id;
2264 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
2265 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
2268 ERR("GATT Callback not registered");
2270 event_cb(HAL_EV_GATT_CLIENT_WATCH_NOTIFICATION, (void *)&ev, sizeof(ev));
2277 static bt_status_t _hal_deregister_for_notification(int client_if,
2278 bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2279 btgatt_gatt_id_t *char_id)
2281 int result = BT_STATUS_SUCCESS;
2282 GError *error = NULL;
2283 GDBusConnection *g_conn;
2284 hal_gattc_client_info_t *gattc_client = NULL;
2285 hal_gattc_server_info_t * conn_info = NULL;
2286 hal_gattc_service_t *gattc_service = NULL;
2287 hal_gattc_char_t *gattc_char = NULL;
2288 char* char_handle = NULL;
2289 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
2290 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
2291 hal_gatt_resp_data_t *resp_data;
2295 gattc_client = __bt_find_gatt_client_info(bd_addr);
2296 if (gattc_client == NULL) {
2297 ERR("failed to get the gatt client info");
2298 return BT_STATUS_FAIL;
2301 if (gattc_client->client_if != client_if) {
2302 ERR("could not find the gatt client for client id[%d]", client_if);
2303 return BT_STATUS_FAIL;
2306 /* get the connection info */
2307 conn_info = __bt_find_gatt_conn_info(bd_addr);
2308 if (NULL == conn_info) {
2309 ERR("Failed to get the conn_info");
2310 return BT_STATUS_FAIL;
2313 if (conn_info->inst_id != gattc_client->inst_id) {
2314 ERR("could not fild the conn_info");
2315 return BT_STATUS_FAIL;
2319 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
2320 if (NULL == gattc_service) {
2321 DBG("Failed to get the gatt service");
2322 return BT_STATUS_FAIL;
2325 DBG("service path [%s]", gattc_service->svc_path);
2326 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
2327 DBG("service uuid [%s]", svc_uuid_str);
2330 /* find characteristic */
2331 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
2332 if (NULL == gattc_char) {
2333 DBG("Failed to get the gatt char");
2334 return BT_STATUS_FAIL;
2337 DBG("char path [%s]", gattc_char->chr_path);
2338 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2339 DBG("char uuid [%s]", char_uuid_str);
2341 char_handle = gattc_char->chr_path;
2343 g_conn = _bt_hal_get_system_gconn();
2344 if (g_conn == NULL) {
2346 return BT_STATUS_FAIL;
2349 resp_data = malloc(sizeof(hal_gatt_resp_data_t));
2350 if (NULL == resp_data) {
2351 ERR("failed to get the memory");
2352 return BT_STATUS_FAIL;
2355 DBG("#StartNotify");
2356 g_dbus_connection_call_sync(g_conn,
2359 BT_HAL_GATT_CHAR_INTERFACE,
2363 G_DBUS_CALL_FLAGS_NONE,
2364 BT_HAL_MAX_DBUS_TIMEOUT, NULL, &error);
2367 ERR("### Watch Failed: %s", error->message);
2368 g_clear_error(&error);
2369 result = BT_STATUS_FAIL;
2372 resp_data->conn_id = gattc_client->client_if; /* saving client_if instead of conn_id */
2373 resp_data->result = result;
2374 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2375 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2377 g_idle_add(_hal_watch_deregister_notifi_cb, (gpointer)resp_data);
2381 return BT_STATUS_SUCCESS;
2383 /** Deregister a previous request for notifications/indications */
2384 bt_status_t btif_deregister_for_notification(int client_if,
2385 const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2386 btgatt_gatt_id_t *char_id)
2388 CHECK_BTGATT_INIT();
2389 return _hal_deregister_for_notification(client_if, (bt_bdaddr_t *)bd_addr, srvc_id, char_id);
2392 /** Request RSSI for a given remote device */
2393 bt_status_t read_remote_rssi(int client_if, const bt_bdaddr_t *bd_addr)
2395 CHECK_BTGATT_INIT();
2396 return BT_STATUS_UNSUPPORTED;
2399 /** OTA firmware download */
2400 bt_status_t ota_fw_update(int client_if, int conn_id, const bt_bdaddr_t *bd_addr, char* path)
2402 CHECK_BTGATT_INIT();
2403 return BT_STATUS_UNSUPPORTED;
2406 /** Determine the type of the remote device (LE, BR/EDR, Dual-mode) */
2407 int get_device_type(const bt_bdaddr_t *bd_addr)
2409 CHECK_BTGATT_INIT();
2410 return BT_STATUS_UNSUPPORTED;
2413 static bt_status_t __hal_update_conn_parameter(bt_bdaddr_t *bd_addr,
2414 int min_int, int max_int, int latency, int timeout)
2416 gchar *device_path = NULL;
2417 GError *error = NULL;
2418 GDBusProxy *device_proxy = NULL;
2419 GDBusConnection *conn;
2421 int ret = BT_STATUS_SUCCESS;
2422 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
2424 INFO("Min interval: %d, Max interval: %d, Latency: %d, Supervision timeout: %d",
2425 min_int, max_int, latency, timeout);
2427 conn = _bt_hal_get_system_gconn();
2430 return BT_STATUS_FAIL;
2433 _bt_hal_convert_addr_type_to_string(device_address,
2434 (unsigned char *)bd_addr->address);
2435 device_path = _bt_hal_get_device_object_path(device_address);
2437 if (device_path == NULL) {
2438 ERR("device_path NULL : [%s]", device_address);
2439 return BT_STATUS_FAIL;
2442 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2443 NULL, BT_HAL_BLUEZ_NAME,
2444 device_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
2446 g_free(device_path);
2447 if (NULL == device_proxy) {
2448 ERR("device_proxy returned NULL");
2449 return BT_STATUS_FAIL;
2452 INFO("### LeConnUpdate");
2453 reply = g_dbus_proxy_call_sync(device_proxy, "LeConnUpdate",
2454 g_variant_new("(uuuu)", min_int, max_int, latency, timeout),
2455 G_DBUS_CALL_FLAGS_NONE,
2460 g_object_unref(device_proxy);
2461 if (reply == NULL) {
2463 ERR("Error %s[%s]", error->message, device_address);
2464 if (g_strrstr(error->message, "In Progress"))
2465 ret = BT_STATUS_SUCCESS;
2467 ret = BT_STATUS_FAIL;
2468 g_error_free(error);
2472 g_variant_unref(reply);
2474 INFO("LE Connection parameter Updated");
2478 /** Request a connection parameter update */
2479 bt_status_t btif_gattc_conn_parameter_update(bt_bdaddr_t *bd, int min_int, int max_int, int latency, int timeout)
2481 CHECK_BTGATT_INIT();
2485 return __hal_update_conn_parameter(bd, min_int, max_int, latency, timeout);
2488 /** Test mode interface */
2489 bt_status_t test_command(int command, btgatt_test_params_t* params)
2491 CHECK_BTGATT_INIT();
2492 return BT_STATUS_UNSUPPORTED;
2495 /** MTU Exchange request from client */
2496 bt_status_t configure_mtu(int conn_id, int mtu)
2498 CHECK_BTGATT_INIT();
2499 return BT_STATUS_UNSUPPORTED;
2502 /** Setup scan filter params */
2503 bt_status_t scan_filter_param_setup(int client_if, int action, int filt_index, int feat_seln,
2504 int list_logic_type, int filt_logic_type, int rssi_high_thres,
2505 int rssi_low_thres, int dely_mode, int found_timeout,
2506 int lost_timeout, int found_timeout_cnt)
2508 CHECK_BTGATT_INIT();
2509 return BT_STATUS_UNSUPPORTED;
2512 /** Configure a scan filter condition */
2513 bt_status_t scan_filter_add_remove(int client_if, int action, int filt_type,
2514 int filt_index, int company_id,
2515 int company_id_mask, const bt_uuid_t *p_uuid,
2516 const bt_uuid_t *p_uuid_mask, const bt_bdaddr_t *bd_addr,
2517 char addr_type, int data_len, char* p_data, int mask_len,
2520 CHECK_BTGATT_INIT();
2521 return BT_STATUS_UNSUPPORTED;
2524 /** Clear all scan filter conditions for specific filter index*/
2525 bt_status_t scan_filter_clear(int client_if, int filt_index)
2527 CHECK_BTGATT_INIT();
2528 return BT_STATUS_UNSUPPORTED;
2531 /** Enable / disable scan filter feature*/
2532 bt_status_t scan_filter_enable(int client_if, bool enable)
2534 CHECK_BTGATT_INIT();
2535 return BT_STATUS_UNSUPPORTED;
2538 /** Sets the LE scan interval and window in units of N*0.625 msec */
2540 bt_status_t set_scan_parameters(int scan_type, int scan_interval, int scan_window)
2544 CHECK_BTGATT_INIT();
2546 le_scan_type = scan_type;
2547 ret = _bt_hal_adapter_le_set_scan_parameters(
2548 scan_type, scan_interval, scan_window);
2552 bt_status_t set_scan_parameters(int scan_interval, int scan_window)
2554 CHECK_BTGATT_INIT();
2555 return BT_STATUS_UNSUPPORTED;
2559 /* Configure the batchscan storage */
2560 bt_status_t batchscan_cfg_storage(int client_if, int batch_scan_full_max,
2561 int batch_scan_trunc_max, int batch_scan_notify_threshold)
2563 CHECK_BTGATT_INIT();
2564 return BT_STATUS_UNSUPPORTED;
2567 /* Enable batchscan */
2568 bt_status_t batchscan_enb_batch_scan(int client_if, int scan_mode,
2569 int scan_interval, int scan_window, int addr_type, int discard_rule)
2571 CHECK_BTGATT_INIT();
2572 return BT_STATUS_UNSUPPORTED;
2575 /* Disable batchscan */
2576 bt_status_t batchscan_dis_batch_scan(int client_if)
2578 CHECK_BTGATT_INIT();
2579 return BT_STATUS_UNSUPPORTED;
2582 /* Read out batchscan reports */
2583 bt_status_t batchscan_read_reports(int client_if, int scan_mode)
2585 CHECK_BTGATT_INIT();
2586 return BT_STATUS_UNSUPPORTED;
2589 const btgatt_client_interface_t btgatt_client_interface = {
2590 btif_gattc_register_client,
2591 btif_gattc_unregister_client,
2593 btif_gattc_client_connect,
2594 btif_gattc_client_disconnect,
2596 btif_gattc_client_search_service,
2597 get_included_service,
2598 btif_gattc_get_characteristic,
2599 btif_gattc_get_descriptor,
2600 btif_read_characteristic,
2601 btif_write_characteristic,
2602 btif_read_descriptor,
2603 btif_write_descriptor,
2605 btif_register_for_notification,
2606 btif_deregister_for_notification,
2610 btif_gattc_conn_parameter_update,
2613 scan_filter_param_setup,
2614 scan_filter_add_remove,
2617 set_scan_parameters,
2618 batchscan_cfg_storage,
2619 batchscan_enb_batch_scan,
2620 batchscan_dis_batch_scan,
2621 batchscan_read_reports
2624 static hal_gattc_server_info_t *__bt_find_gatt_conn_info(bt_bdaddr_t *serv_addr)
2629 hal_gattc_server_info_t *info = NULL;
2631 for (l = hal_gattc_server_info_list; l != NULL; l = g_slist_next(l)) {
2632 info = (hal_gattc_server_info_t*)l->data;
2636 if (!memcmp(&info->bd_addr, serv_addr, sizeof(bt_bdaddr_t))) {
2637 INFO("GATT connection found addr");
2644 static hal_gattc_client_info_t *__bt_find_gatt_client_info(bt_bdaddr_t *serv_addr)
2649 hal_gattc_client_info_t *info = NULL;
2651 for (l = hal_gattc_client_info_list; l != NULL; l = g_slist_next(l)) {
2652 info = (hal_gattc_client_info_t*)l->data;
2656 if (!memcmp(&info->bd_addr, serv_addr, sizeof(bt_bdaddr_t))) {
2657 INFO("GATT client info found addr");
2664 static hal_gattc_client_info_t *__bt_find_gatt_client_info_from_conn_id(int conn_id)
2669 hal_gattc_client_info_t *info = NULL;
2671 for (l = hal_gattc_client_info_list; l != NULL; l = g_slist_next(l)) {
2672 info = (hal_gattc_client_info_t*)l->data;
2676 if (info->conn_id == conn_id) {
2677 INFO("GATT client info found for conn_id [%d]", conn_id);
2684 static hal_gattc_server_info_t *__bt_find_gatt_conn_info_from_conn_id(int conn_id)
2689 hal_gattc_server_info_t *info = NULL;
2690 hal_gattc_client_info_t *gattc_client = NULL;
2692 gattc_client = __bt_find_gatt_client_info_from_conn_id(conn_id);
2693 if (gattc_client == NULL) {
2694 INFO("GATT client conn info not found");
2698 for (l = hal_gattc_server_info_list; l != NULL; l = g_slist_next(l)) {
2699 info = (hal_gattc_server_info_t*)l->data;
2703 if ((info->inst_id == gattc_client->inst_id) &&
2704 !memcmp(&info->bd_addr, &gattc_client->bd_addr, sizeof(bt_bdaddr_t))) {
2705 INFO("GATT connection found for conn_id [%d]", conn_id);
2712 static bt_status_t __bt_connect_le_device_internal(int client_if, const bt_bdaddr_t *bd_addr,
2713 gboolean auto_connect)
2715 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
2716 gchar *device_path = NULL;
2717 GDBusProxy *device_proxy = NULL;
2718 GDBusConnection *conn;
2719 int ret = BT_STATUS_SUCCESS;
2720 hal_gattc_client_info_t *gattc_data;
2724 if (NULL == bd_addr) {
2725 ERR("bd_addr is NULL");
2726 return BT_STATUS_PARM_INVALID;
2729 conn = _bt_hal_get_system_gconn();
2731 ERR("_bt_gdbus_get_system_gconn returned NULL");
2732 return BT_STATUS_FAIL;
2735 _bt_hal_convert_addr_type_to_string(device_address,
2736 (unsigned char *)bd_addr->address);
2737 device_path = _bt_hal_get_device_object_path(device_address);
2738 if (device_path == NULL) {
2739 ERR("device_path NULL : [%s]", device_address);
2740 ret = BT_STATUS_FAIL;
2743 ERR("device_path:%s", device_path);
2745 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2746 NULL, BT_HAL_BLUEZ_NAME,
2747 device_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
2748 g_free(device_path);
2749 if (NULL == device_proxy) {
2750 ERR("device_proxy returned NULL");
2751 return BT_STATUS_FAIL;
2754 gattc_data = g_malloc0(sizeof(hal_gattc_client_info_t));
2755 if (gattc_data == NULL) {
2756 ERR("Unable to allocate memory");
2757 ret = BT_STATUS_NOMEM;
2760 memcpy(gattc_data->bd_addr.address, bd_addr->address,
2761 BT_HAL_ADDRESS_LENGTH_MAX);
2763 DBG("Connect LE [%s]", device_address);
2765 gattc_data->client_if = client_if;
2767 g_dbus_proxy_call(device_proxy, "ConnectLE",
2768 g_variant_new("(b)", auto_connect),
2769 G_DBUS_CALL_FLAGS_NONE,
2770 BT_HAL_MAX_DBUS_TIMEOUT,
2772 (GAsyncReadyCallback)__le_connection_req_cb, gattc_data);
2778 g_object_unref(device_proxy);
2785 static bt_status_t _bt_hold_current_advertising()
2787 int ret = BT_STATUS_FAIL;
2788 gboolean is_advertising = FALSE;
2791 is_advertising = _bt_hal_is_advertising_in_slot(0);
2792 if (is_advertising) {
2793 DBG("+ Stop current advertising");
2795 ret = _bt_hal_enable_advertising(0, FALSE, FALSE);
2796 g_timeout_add(2000, __bt_hold_current_advertising_timeout_cb, NULL);
2802 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
2804 DBG("+ start current advertising");
2806 _bt_hal_enable_advertising(0, TRUE, FALSE);
2811 static gboolean __bt_connect_le_timer_cb(gpointer user_data)
2813 DBG("Try to initiate pending LE connection");
2815 pending_le_conn_timer_id = 0;
2817 __bt_connect_le_device_internal(pending_le_conn_info->client_if,
2818 &pending_le_conn_info->bd_addr,
2819 pending_le_conn_info->auto_connect);
2821 g_free(pending_le_conn_info);
2822 pending_le_conn_info = NULL;
2827 static int __hal_generate_conn_id()
2829 return ++bt_conn_id;
2832 static int __hal_generate_server_instance_id()
2834 return ++bt_inst_id;
2837 static void __le_connection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
2840 GError *g_error = NULL;
2841 GVariant *reply = NULL;
2842 hal_gattc_client_info_t *gattc_data = user_data;
2843 int result = BT_STATUS_SUCCESS;
2844 struct hal_ev_gatt_client_connected ev;
2845 hal_gattc_server_info_t *gatt_conn_info = NULL;
2849 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
2850 g_object_unref(proxy);
2851 if (reply == NULL) {
2852 ERR("Connect LE Dbus Call Error");
2854 ERR("Error: %s\n", g_error->message);
2855 g_clear_error(&g_error);
2857 result = BT_STATUS_FAIL;
2859 g_variant_unref(reply);
2861 if (NULL == gattc_data) {
2862 ERR("server_data is NULL");
2867 if (result == BT_STATUS_FAIL) {
2868 memset(&ev, 0, sizeof(ev));
2871 ev.client_if = gattc_data->client_if;
2872 memcpy(ev.bdaddr, gattc_data->bd_addr.address,
2873 BT_HAL_ADDRESS_LENGTH_MAX);
2876 ERR("gatt client callback not registered");
2878 DBG("sending gatt client connected event");
2879 event_cb(HAL_EV_GATT_CLIENT_CONNECTED, (void *)&ev, sizeof(ev));
2885 DBG("adding the server conn info in list");
2886 gattc_data->conn_id = __hal_generate_conn_id() ;
2887 gattc_data->inst_id = __hal_generate_server_instance_id();
2889 hal_gattc_client_info_list = g_slist_append(hal_gattc_client_info_list, gattc_data);
2891 /*add gatt server connection info*/
2892 gatt_conn_info = g_malloc0(sizeof(hal_gattc_server_info_t));
2893 if (gatt_conn_info == NULL) {
2894 ERR("Failed to allocate memory");
2898 memcpy(gatt_conn_info->bd_addr.address, gattc_data->bd_addr.address, BT_HAL_ADDRESS_LENGTH_MAX);
2899 gatt_conn_info->inst_id = gattc_data->inst_id;
2900 hal_gattc_server_info_list = g_slist_append(hal_gattc_server_info_list, gatt_conn_info);
2906 /*remove conn_info*/
2911 void __hal_gattc_free_svc_info(hal_gattc_service_t *svc_info)
2913 g_free(svc_info->svc_path);
2917 void __hal_gattc_free_char_info(hal_gattc_char_t *char_info)
2919 g_free(char_info->chr_path);
2923 void __hal_gattc_free_desc_info(hal_gattc_desc_t *desc_info)
2925 g_free(desc_info->desc_path);
2929 void __hal_clean_gattc_server_info(hal_gattc_server_info_t *conn_info)
2934 hal_gattc_service_t *svc_info = NULL;
2935 hal_gattc_char_t *char_info = NULL;
2936 hal_gattc_desc_t *desc_info = NULL;
2940 for (l = conn_info->gatt_list_services; l != NULL;) {
2941 svc_info = (hal_gattc_service_t*)l->data;
2942 if (svc_info == NULL)
2944 l = g_slist_next(l);
2946 for (m = svc_info->gatt_list_chars; m != NULL; ) {
2947 char_info = (hal_gattc_char_t*)m->data;
2948 if (char_info == NULL)
2950 m = g_slist_next(m);
2952 for (k = char_info->gatt_list_descs; k != NULL; ) {
2953 desc_info = (hal_gattc_desc_t*)k->data;
2954 if (desc_info == NULL)
2956 k = g_slist_next(k);
2958 /*remove desc element*/
2959 char_info->gatt_list_descs = g_slist_remove(char_info->gatt_list_descs, desc_info);
2960 __hal_gattc_free_desc_info(desc_info);
2963 /*remove desc list*/
2964 g_slist_free(char_info->gatt_list_descs);
2965 char_info->gatt_list_descs = NULL;
2967 /*remove char element*/
2968 svc_info->gatt_list_chars = g_slist_remove(svc_info->gatt_list_chars, char_info);
2969 __hal_gattc_free_char_info(char_info);
2972 /*remove char list*/
2973 g_slist_free(svc_info->gatt_list_chars);
2974 svc_info->gatt_list_chars = NULL;
2976 /*remove svc element*/
2977 conn_info->gatt_list_services = g_slist_remove(conn_info->gatt_list_services, svc_info);
2978 __hal_gattc_free_svc_info(svc_info);
2981 /*remove svc list */
2982 g_slist_free(conn_info->gatt_list_services);
2983 conn_info->gatt_list_services = NULL;
2985 /*remove conn info*/
2989 void _bt_hal_handle_gattc_connected_event(char* address, gboolean gatt_connected)
2991 int result = BT_STATUS_SUCCESS;
2992 struct hal_ev_gatt_client_connected ev;
2993 hal_gattc_server_info_t *conn_info = NULL;
2994 bt_bdaddr_t bd_addr;
2996 hal_gattc_client_info_t *gattc_client = NULL;
3000 DBG("+ connected device address [%s]", address);
3002 event = gatt_connected ? HAL_EV_GATT_CLIENT_CONNECTED :
3003 HAL_EV_GATT_CLIENT_DISCONNECTED;
3005 _bt_hal_convert_addr_string_to_type(bd_addr.address, address);
3006 /* find the gatt client info */
3007 gattc_client = __bt_find_gatt_client_info(&bd_addr);
3008 if (NULL == gattc_client) {
3009 ERR("Fail to get gatt client info");
3014 memset(&ev, 0, sizeof(ev));
3015 ev.conn_id = gattc_client->conn_id;
3017 ev.client_if = gattc_client->client_if;
3018 memcpy(ev.bdaddr, gattc_client->bd_addr.address,
3019 BT_HAL_ADDRESS_LENGTH_MAX);
3022 ERR("gatt client callback not registered");
3024 DBG("sending gatt client connected status event");
3025 event_cb(event, (void *)&ev, sizeof(ev));
3028 if (!gatt_connected) {
3029 inst_id = gattc_client->inst_id;
3031 /* remove the gatt client info from the client list also*/
3032 hal_gattc_client_info_list = g_slist_remove(hal_gattc_client_info_list, gattc_client);
3033 g_free(gattc_client);
3035 //find the connected server info
3036 conn_info = __bt_find_gatt_conn_info(&bd_addr);
3037 if (NULL == conn_info) {
3038 ERR("Fail to get gatt server info");
3042 if (inst_id != conn_info->inst_id) {
3043 ERR("server instance is different");
3047 //remove gatt conn info from the server list
3048 DBG("remove the server conn_info from list after gatt disconnection");
3049 hal_gattc_server_info_list = g_slist_remove(hal_gattc_server_info_list, conn_info);
3050 __hal_clean_gattc_server_info(conn_info);
3056 static void _bt_hal_send_search_service_result_event(int conn_id, int is_primary,
3057 const char* uuid_str, int inst_id)
3059 struct hal_ev_gatt_client_search_result ev;
3062 ERR("gatt client callback not registered");
3066 DBG("sending gatt client search service result event conn_id[%d]", conn_id);
3068 memset(&ev, 0, sizeof(ev));
3069 ev.conn_id = conn_id;
3070 ev.inst_id = inst_id;
3071 ev.is_primary = is_primary;
3072 _bt_hal_convert_uuid_string_to_type(ev.uuid, uuid_str);
3074 event_cb(HAL_EV_GATT_CLIENT_SEARCH_RESULT, (void *)&ev, sizeof(ev));
3077 static void _bt_hal_send_search_service_complete_event(int conn_id, int status)
3079 struct hal_ev_gatt_client_search_complete ev;
3082 ERR("gatt client callback not registered");
3086 DBG("sending gatt client search service complete event conn_id[%d]", conn_id);
3089 memset(&ev, 0, sizeof(ev));
3090 ev.conn_id = conn_id;
3093 event_cb(HAL_EV_GATT_CLIENT_SEARCH_COMPLETE, (void *)&ev, sizeof(ev));