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>
31 #include <gio/gunixfdlist.h>
34 #include "bt-hal-log.h"
35 #include "bt-hal-msg.h"
36 #include "bt-hal-event-receiver.h"
37 #include "bt-hal-adapter-le.h"
39 #include "bt-hal-gatt-client.h"
40 #include "bt-hal-dbus-common-utils.h"
41 #include "bt-hal-utils.h"
43 /************************************************************************************
45 ************************************************************************************/
46 extern const btgatt_callbacks_t *bt_gatt_callbacks;
47 #define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
49 ERR("%s: BTGATT not initialized", __FUNCTION__);\
50 return BT_STATUS_NOT_READY;\
52 DBG("%s", __FUNCTION__);\
56 int le_scan_type = BT_GATTC_LE_SCAN_TYPE_PASSIVE;
59 static handle_stack_msg event_cb = NULL;
61 #define GATT_SERV_INTERFACE "org.bluez.GattService1"
62 #define MAX_HAL_OBJECT_PATH_LEN 100
65 HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST = 0x01,
66 HAL_GATT_CHARACTERISTIC_PROPERTY_READ = 0x02,
67 HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE = 0x04,
68 HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE = 0x08,
69 HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY = 0x10,
70 HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE = 0x20,
71 HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE = 0x40,
72 HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE = 0x80,
73 HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES = 0x100,
74 HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ = 0x200,
75 HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE = 0x400,
76 HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ = 0x800,
77 HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE = 0x1000,
78 HAL_GATT_CHARACTERISTIC_PROPERTY_EXTENDED_PROPS = 0xffff,
79 } bt_gatt_characteristic_property_t;
83 HAL_GATT_WRITE_TYPE_WRITE_NO_RESPONSE = 1,
84 HAL_GATT_WRITE_TYPE_WRITE ,
85 } hal_gatt_write_type_t;
89 HAL_GATT_PROPERTY_BROADCAST = 0x01, /**< Broadcast property */
90 HAL_GATT_PROPERTY_READ = 0x02, /**< Read property */
91 HAL_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE = 0x04, /**< Write without response property */
92 HAL_GATT_PROPERTY_WRITE = 0x08, /**< Write property */
93 HAL_GATT_PROPERTY_NOTIFY = 0x10, /**< Notify property */
94 HAL_GATT_PROPERTY_INDICATE = 0x20, /**< Indicate property */
95 HAL_GATT_PROPERTY_AUTHENTICATED_SIGNED_WRITES = 0x40, /**< Authenticated signed writes property */
96 HAL_GATT_PROPERTY_EXTENDED_PROPERTIES = 0x80, /**< Extended properties */
97 } hal_gatt_property_e;
102 gboolean auto_connect;
103 } bt_pending_le_conn_info_s;
113 unsigned int permission;
114 GSList *gatt_list_descs;
121 GSList *gatt_list_chars;
122 } hal_gattc_service_t;
125 bt_bdaddr_t bd_addr; /*remote server address*/
126 int inst_id; /*server instance id*/
127 GSList *gatt_list_services;
128 } hal_gattc_server_info_t;
130 /* Linked List of connected GATT server */
131 static GSList *hal_gattc_server_info_list = NULL;
135 bt_bdaddr_t bd_addr; /*remote server address*/
138 } hal_gattc_client_info_t;
140 /* Linked list of connected GATT client connection */
141 static GSList * hal_gattc_client_info_list = NULL;
143 static bt_pending_le_conn_info_s *pending_le_conn_info = NULL;
144 static guint pending_le_conn_timer_id = 0;
145 static int bt_conn_id = 0;
146 static int bt_inst_id = 0;
148 #define BT_GATTC_CL_MAX 32
153 btgatt_srvc_id_t srvc_id;
154 btgatt_gatt_id_t char_id;
155 btgatt_gatt_id_t desc_id;
156 } hal_gatt_resp_data_t;
161 } hal_gatt_client_app;
163 static GSList * hal_gattc_client_app_list = NULL;
165 static int bt_client_if = 0;
168 static bt_status_t __bt_connect_le_device_internal(int client_if, const bt_bdaddr_t *bd_addr,
169 gboolean auto_connect);
170 static bt_status_t _bt_hold_current_advertising();
171 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data);
172 static gboolean __bt_connect_le_timer_cb(gpointer user_data);
173 static void __le_connection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
175 static hal_gattc_server_info_t *__bt_find_gatt_conn_info_from_conn_id(int conn_id);
176 static void _bt_hal_send_search_service_result_event(int conn_id, int is_primary,
177 const char* uuid_str, int inst_id);
178 static void _bt_hal_send_search_service_complete_event(int conn_id, int status);
179 static hal_gattc_server_info_t *__bt_find_gatt_conn_info(bt_bdaddr_t *serv_addr);
180 static hal_gattc_client_info_t *__bt_find_gatt_client_info(bt_bdaddr_t *serv_addr);
183 /* To send stack event to hal-av handler */
184 void _bt_hal_register_gatt_client_handler_cb(handle_stack_msg cb)
189 void _bt_hal_unregister_gatt_client_handler_cb(void)
195 int _bt_hal_gatt_client_get_le_scan_type(void)
201 static gboolean __bt_hal_register_client_cb(gpointer user_data)
203 struct hal_ev_gatt_client_registered ev;
204 hal_gatt_client_app *client_info = user_data;
207 /* Prepare to send AV connecting event */
208 memset(&ev, 0, sizeof(ev));
209 ev.status = BT_STATUS_SUCCESS;
210 ev.client_if = client_info->client_if;
211 memcpy(ev.app_uuid, client_info->app_uuid.uu, sizeof(ev.app_uuid));
214 ERR("GATT Callback not registered");
216 DBG("GATT client registered, client_if: [%d]", client_info->client_if);
217 event_cb(HAL_EV_GATT_CLIENT_REGISTERED, (void *)&ev, sizeof(ev));
224 static int __hal_generate_client_id()
226 return ++bt_client_if;
229 static hal_gatt_client_app *__hal_gattc_add_client_app(bt_uuid_t *app_uuid)
232 hal_gatt_client_app *info = NULL;
233 hal_gatt_client_app *gattc_app = NULL;
235 //check if client app is already registered
236 for (l = hal_gattc_client_app_list; l != NULL; l = g_slist_next(l)) {
237 info = (hal_gatt_client_app*)l->data;
241 if (memcmp(&info->app_uuid, app_uuid, sizeof(bt_uuid_t)) == 0) {
242 DBG("gatt client app already registered");
247 DBG("adding the gatt client app");
250 gattc_app = g_malloc0(sizeof(hal_gatt_client_app));
251 gattc_app->client_if = __hal_generate_client_id();
252 memcpy(&gattc_app->app_uuid, app_uuid, sizeof(bt_uuid_t));
254 hal_gattc_client_app_list = g_slist_append(hal_gattc_client_app_list, gattc_app);
259 static bt_status_t __hal_gattc_register_client_app(bt_uuid_t *app_uuid)
261 hal_gatt_client_app *gattc_app = NULL;
262 hal_gatt_client_app *client_app_info = NULL;
265 /* add gatt client in list */
266 gattc_app = __hal_gattc_add_client_app(app_uuid);
267 if (gattc_app == NULL) {
268 ERR("Failed to register gatt client app");
269 return BT_STATUS_FAIL;
273 client_app_info = g_malloc0(sizeof(hal_gatt_client_app));
274 client_app_info->client_if = gattc_app->client_if;
275 memcpy(&client_app_info->app_uuid, app_uuid, sizeof(bt_uuid_t));
276 g_idle_add(__bt_hal_register_client_cb, (gpointer)client_app_info);
278 DBG("registered client client_if [%d]", client_app_info->client_if);
280 return BT_STATUS_SUCCESS;
283 /** Registers a GATT client application with the stack */
284 bt_status_t btif_gattc_register_client(bt_uuid_t *uuid)
289 return __hal_gattc_register_client_app(uuid);
292 bt_status_t __hal_gattc_unregister_client(int client_if)
295 hal_gatt_client_app *info = NULL;
297 DBG("registered client count: [%d]", g_slist_length(hal_gattc_client_app_list));
299 /* remove the gatt client app */
300 for (l = hal_gattc_client_app_list; l != NULL; ) {
301 info = (hal_gatt_client_app*)l->data;
307 if (info->client_if == client_if) {
308 DBG("gatt client app found");
309 hal_gattc_client_app_list = g_slist_remove(hal_gattc_client_app_list, info);
314 DBG("registered client count: [%d]", g_slist_length(hal_gattc_client_app_list));
315 return BT_STATUS_SUCCESS;
318 /** Unregister a client application from the stack */
319 bt_status_t btif_gattc_unregister_client(int client_if)
324 return __hal_gattc_unregister_client(client_if);
327 /** Start or stop LE device scanning */
328 bt_status_t scan(int client_if, bool start)
335 ret = _bt_hal_adapter_le_start_scan();
337 ret = _bt_hal_adapter_le_stop_scan();
342 /** Create a connection to a remote LE or dual-mode device */
343 bt_status_t btif_gattc_client_connect(int client_if, const bt_bdaddr_t *bd_addr,
346 int ret = BT_STATUS_SUCCESS;
352 return BT_STATUS_PARM_INVALID;
354 ret = _bt_hold_current_advertising();
355 if (ret == BT_STATUS_SUCCESS) {
356 DBG("Current advertising is held");
357 pending_le_conn_info = g_malloc0(sizeof(bt_pending_le_conn_info_s));
358 pending_le_conn_info->client_if = client_if;
359 memcpy(pending_le_conn_info->bd_addr.address, bd_addr->address,
360 BT_HAL_ADDRESS_LENGTH_MAX);
361 pending_le_conn_info->auto_connect = is_direct;
363 pending_le_conn_timer_id =
364 g_timeout_add(1000, __bt_connect_le_timer_cb, NULL);
366 return BT_STATUS_SUCCESS;
368 ERR("advertising is not stopped");
371 return __bt_connect_le_device_internal(client_if, bd_addr, is_direct);
375 static void __le_disconnection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
378 GError *g_error = NULL;
379 GVariant *reply = NULL;
380 hal_gattc_client_info_t *gatt_conn_info = user_data;
381 int result = BT_STATUS_SUCCESS;
382 struct hal_ev_gatt_client_connected ev;
386 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
387 g_object_unref(proxy);
389 ERR("Connect LE Dbus Call Error");
391 ERR("Error: %s\n", g_error->message);
392 g_clear_error(&g_error);
394 result = BT_STATUS_FAIL;
396 g_variant_unref(reply);
398 if (NULL == gatt_conn_info) {
399 ERR("server_data is NULL");
404 if (result == BT_STATUS_FAIL) {
405 memset(&ev, 0, sizeof(ev));
406 ev.conn_id = gatt_conn_info->conn_id;
408 ev.client_if = gatt_conn_info->client_if;
409 memcpy(ev.bdaddr, gatt_conn_info->bd_addr.address,
410 BT_HAL_ADDRESS_LENGTH_MAX);
413 ERR("gatt client callback not registered");
415 DBG("sending gatt client disconnected event");
416 event_cb(HAL_EV_GATT_CLIENT_DISCONNECTED, (void *)&ev, sizeof(ev));
422 g_free(gatt_conn_info);
427 bt_status_t _hal_gattc_disconnect(int client_if, const bt_bdaddr_t *bd_addr,
430 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
432 GDBusProxy *device_proxy;
433 GDBusConnection *conn;
434 int ret = BT_STATUS_SUCCESS;
435 hal_gattc_client_info_t *gattc_data;
437 if (NULL == bd_addr) {
438 ERR("bd_addr is NULL");
439 return BT_STATUS_PARM_INVALID;
442 conn = _bt_hal_get_system_gconn();
444 ERR("_bt_gdbus_get_system_gconn returned NULL");
445 return BT_STATUS_FAIL;
448 _bt_hal_convert_addr_type_to_string(device_address,
449 (unsigned char *)bd_addr->address);
450 device_path = _bt_hal_get_device_object_path(device_address);
451 if (device_path == NULL) {
452 DBG("device_path NULL");
453 ret = BT_STATUS_FAIL;
457 ERR("device_path:%s", device_path);
459 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
460 NULL, BT_HAL_BLUEZ_NAME,
461 device_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
463 if (NULL == device_proxy) {
464 ERR("device_proxy returned NULL");
465 return BT_STATUS_FAIL;
468 gattc_data = g_malloc0(sizeof(hal_gattc_client_info_t));
469 memcpy(gattc_data->bd_addr.address, bd_addr->address,
470 BT_HAL_ADDRESS_LENGTH_MAX);
471 gattc_data->client_if = client_if;
472 gattc_data->conn_id = conn_id;
474 DBG("DisconnectLE [%s]", device_address);
476 g_dbus_proxy_call(device_proxy, "DisconnectLE",
478 G_DBUS_CALL_FLAGS_NONE,
479 BT_HAL_MAX_DBUS_TIMEOUT,
481 (GAsyncReadyCallback)__le_disconnection_req_cb, gattc_data);
485 /** Disconnect a remote device or cancel a pending connection */
486 bt_status_t btif_gattc_client_disconnect(int client_if, const bt_bdaddr_t *bd_addr,
493 return _hal_gattc_disconnect(client_if, bd_addr, conn_id);
496 /** Clear the attribute cache for a given device */
497 bt_status_t refresh(int client_if, const bt_bdaddr_t *bd_addr)
500 return BT_STATUS_UNSUPPORTED;
503 static hal_gattc_service_t* _gattc_find_service_from_uuid(hal_gattc_server_info_t *conn_info, bt_uuid_t *svc_uuid)
508 hal_gattc_service_t *info = NULL;
510 for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
511 info = (hal_gattc_service_t*)l->data;
515 if (!memcmp(&info->svc_uuid, svc_uuid, sizeof(bt_uuid_t))) {
516 INFO("Found GATT service uuid");
524 static hal_gattc_char_t* _gattc_find_char_from_uuid(hal_gattc_service_t *gattc_svc, bt_uuid_t *char_uuid,
525 bt_gatt_characteristic_property_t prop)
530 hal_gattc_char_t *info = NULL;
532 for (l = gattc_svc->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
533 info = (hal_gattc_char_t*)l->data;
537 if (!memcmp(&info->chr_uuid, char_uuid, sizeof(bt_uuid_t)) &&
538 (info->permission & prop)) {
539 INFO("Found GATT char uuid");
546 static hal_gattc_char_t* _gattc_find_char_from_uuid_for_notify(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->permission & HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) ||
560 (info->permission & HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE))) {
561 INFO("Found GATT char uuid");
568 static hal_gattc_desc_t* _gattc_find_desc_from_uuid(hal_gattc_char_t *gattc_char, bt_uuid_t *desc_uuid)
573 hal_gattc_desc_t *info = NULL;
575 for (l = gattc_char->gatt_list_descs; l != NULL; l = g_slist_next(l)) {
576 info = (hal_gattc_desc_t*)l->data;
580 if (!memcmp(&info->desc_uuid, desc_uuid, sizeof(bt_uuid_t))) {
581 INFO("Found GATT descriptor uuid");
589 static hal_gattc_service_t* _hal_gatt_client_add_service(hal_gattc_server_info_t *conn_info,
590 const char *uuid_str, char *object_path, int is_primary)
593 hal_gattc_service_t *gattc_service = NULL;
595 gattc_service = g_malloc0(sizeof(hal_gattc_service_t));
596 gattc_service->svc_path = g_strdup(object_path);
597 _bt_hal_convert_uuid_string_to_type(gattc_service->svc_uuid.uu, uuid_str);
598 gattc_service->is_primary = is_primary;
600 DBG("service count[%d]", g_slist_length(conn_info->gatt_list_services));
602 conn_info->gatt_list_services = g_slist_append(conn_info->gatt_list_services, gattc_service);
604 DBG("svc path {%s] svc uuid [%s]", object_path, uuid_str);
606 return gattc_service;
609 static void _hal_gattc_add_characteristic(hal_gattc_service_t *gatt_svc, char *char_handle)
612 hal_gattc_char_t *gattc_char = NULL;
614 gattc_char = g_malloc0(sizeof(hal_gattc_char_t));
615 gattc_char->chr_path = g_strdup(char_handle);
617 DBG("svc path: [%s]", gatt_svc->svc_path);
618 DBG("char path: [%s]", gattc_char->chr_path);
620 gatt_svc->gatt_list_chars = g_slist_append(gatt_svc->gatt_list_chars, gattc_char);
623 static void _gattc_create_new_service(hal_gattc_server_info_t *conn_info, gboolean is_primary,
624 const char* uuid_str, char *object_path, GPtrArray *gp_char_array)
626 hal_gattc_service_t* gatt_svc = NULL;
628 gchar *gp_char_path = NULL;
632 /* add the service */
633 gatt_svc = _hal_gatt_client_add_service(conn_info, uuid_str, object_path, is_primary);
634 if (gatt_svc == NULL) {
635 ERR("Failed to add service");
639 /* add the characteristic */
640 for (i = 0; i < gp_char_array->len; i++) {
641 gp_char_path = g_ptr_array_index(gp_char_array, i);
642 _hal_gattc_add_characteristic(gatt_svc, gp_char_path);
645 g_ptr_array_free(gp_char_array, TRUE);
648 static void _hal_gattc_add_descriptor(hal_gattc_char_t *gattc_char, char *desc_path)
650 hal_gattc_desc_t *gattc_desc = NULL;
652 gattc_desc = g_malloc0(sizeof(hal_gattc_desc_t));
653 gattc_desc->desc_path = g_strdup(desc_path);
655 gattc_char->gatt_list_descs = g_slist_append(gattc_char->gatt_list_descs, gattc_desc);
657 DBG("char path: [%s]", gattc_char->chr_path);
658 DBG("desc path: [%s]", gattc_desc->desc_path);
661 static void _hal_gattc_update_char_property(hal_gattc_char_t *gattc_char, const char* char_uuid_str,
662 GPtrArray *gp_desc_array, unsigned int char_permission)
664 gchar *gp_desc_path = NULL;
669 if (char_uuid_str == NULL) {
670 DBG("char_uuid_str is NULL");
674 //update the char uuid
675 DBG("char UUID: [%s] ", char_uuid_str);
676 DBG("char path: [%s]", gattc_char->chr_path);
678 _bt_hal_convert_uuid_string_to_type(gattc_char->chr_uuid.uu, char_uuid_str);
680 //update char permission
681 gattc_char->permission = char_permission;
684 for (i = 0; i < gp_desc_array->len; i++) {
685 gp_desc_path = g_ptr_array_index(gp_desc_array, i);
686 _hal_gattc_add_descriptor(gattc_char, gp_desc_path);
690 static void _hal_gattc_update_desc_property(hal_gattc_desc_t *gattc_desc, const char* desc_uuid_str)
694 if (desc_uuid_str == NULL) {
695 DBG("char_uuid_str is NULL");
699 //update the descriptor uuid
700 DBG("desc UUID: [%s] ", desc_uuid_str);
701 DBG("desc path: [%s]", gattc_desc->desc_path);
703 _bt_hal_convert_uuid_string_to_type(gattc_desc->desc_uuid.uu, desc_uuid_str);
706 static void browse_service_char(int conn_id)
708 hal_gattc_server_info_t *conn_info = NULL;
712 hal_gattc_service_t *svc_info = NULL;
713 hal_gattc_char_t *char_info = NULL;
714 hal_gattc_desc_t *desc_info = NULL;
718 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
719 if (conn_info == NULL) {
720 DBG("conn_info is NULL");
724 DBG("service count[%d]", g_slist_length(conn_info->gatt_list_services));
726 for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
727 svc_info = (hal_gattc_service_t*)l->data;
728 if (svc_info == NULL)
731 DBG("svc path [%s]", svc_info->svc_path);
733 /* find characteristic object path */
734 for (k = svc_info->gatt_list_chars; k != NULL; k = g_slist_next(k)) {
735 char_info = (hal_gattc_char_t *)k->data;
736 if (char_info == NULL)
739 DBG("char path[%s]", char_info->chr_path);
742 for (m = char_info->gatt_list_descs; m != NULL; m = g_slist_next(m)) {
743 desc_info = (hal_gattc_desc_t *)m->data;
744 if (desc_info == NULL)
747 DBG("desc path[%s]", desc_info->desc_path);
756 * Enumerate all GATT services on a connected device.
757 * Optionally, the results can be filtered for a given UUID.
759 static bt_status_t _gattc_client_search_service(int conn_id)
763 GVariant *result = NULL;
765 GVariantIter *svc_iter;
766 GVariantIter *interface_iter;
767 char *object_path = NULL;
768 char *interface_str = NULL;
769 const gchar *key = NULL;
770 GVariant *value = NULL;
771 GPtrArray *gp_array = NULL;
772 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
773 char temp_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
774 int ret = BT_STATUS_FAIL;
776 const gchar *uuid_str = NULL;
778 hal_gattc_server_info_t *conn_info = NULL;
779 gboolean is_primary = FALSE;
782 char *char_handle = NULL;
783 GVariantIter *char_iter = NULL;
784 GPtrArray *gp_char_array = NULL;
788 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
789 if (NULL == conn_info) {
790 DBG("Failed to get the conn_info");
791 return BT_STATUS_FAIL;
794 _bt_hal_convert_addr_type_to_string(device_address,
795 (unsigned char *)conn_info->bd_addr.address);
797 result = _bt_hal_get_managed_objects();
801 gp_array = g_ptr_array_new();
802 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
804 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
806 if (object_path == NULL)
809 _bt_hal_convert_device_path_to_address(object_path, temp_address);
811 if (g_strcmp0(temp_address, device_address) != 0)
814 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
815 &interface_str, &svc_iter)) {
816 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
819 DBG("[%d] Object Path : %s", idx++, object_path);
820 /* for characteristic */
821 gp_char_array = g_ptr_array_new();
822 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
823 if (g_strcmp0(key, "Primary") == 0) {
824 is_primary = g_variant_get_boolean(value);
827 g_ptr_array_add(gp_array, (gpointer)object_path);
830 } else if (g_strcmp0(key, "UUID") == 0) {
831 uuid_str = g_variant_get_string(value, &len);
832 DBG(" UUID: [%s]", uuid_str);
833 } else if (g_strcmp0(key, "Characteristics") == 0) {
834 g_variant_get(value, "ao", &char_iter);
835 if (char_iter != NULL) {
836 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
837 DBG("char handle : %s", char_handle);
838 g_ptr_array_add(gp_char_array, (gpointer)char_handle);
845 DBG("send search service result event");
846 _bt_hal_send_search_service_result_event(conn_id, is_primary,
847 uuid_str, conn_info->inst_id);
849 _gattc_create_new_service(conn_info, is_primary, uuid_str, object_path, gp_char_array);
854 if (gp_array->len == 0 || svc_count == 0) {
855 ERR("gp_array is NULL");
856 ret = BT_STATUS_FAIL;
858 ret = BT_STATUS_SUCCESS;
861 browse_service_char(conn_id);
862 /* send search service complete event */
863 _bt_hal_send_search_service_complete_event(conn_id, ret);
865 g_ptr_array_free(gp_array, TRUE);
866 g_variant_iter_free(iter);
867 g_variant_unref(result);
872 bt_status_t btif_gattc_client_search_service(int conn_id, bt_uuid_t *filter_uuid)
874 if (NULL == filter_uuid) {
875 DBG("Browse all the services");
876 return _gattc_client_search_service(conn_id);
878 DBG("TODO implement it");
879 return BT_STATUS_UNSUPPORTED;
883 * Enumerate included services for a given service.
884 * Set start_incl_srvc_id to NULL to get the first included service.
886 bt_status_t get_included_service(int conn_id, btgatt_srvc_id_t *srvc_id,
887 btgatt_srvc_id_t *start_incl_srvc_id)
890 return BT_STATUS_UNSUPPORTED;
893 static void _bt_hal_send_client_char_search_result_event(int conn_id, int status,
894 btgatt_srvc_id_t *svc_id, bt_uuid_t *char_uuid, int char_prop)
896 struct hal_ev_gatt_client_char_search_result ev;
899 ERR("gatt client callback not registered");
903 DBG("sending gatt client search char result event conn_id[%d] status[%d]", conn_id, status);
905 memset(&ev, 0, sizeof(ev));
906 ev.conn_id = conn_id;
907 ev.inst_id = svc_id->id.inst_id;
908 ev.is_primary = svc_id->is_primary;
910 memcpy(ev.svc_uuid, svc_id->id.uuid.uu, sizeof(ev.svc_uuid));
912 if (status == BT_STATUS_SUCCESS) {
913 DBG("building char uuid");
914 memcpy(ev.char_uuid, char_uuid->uu, sizeof(ev.char_uuid));
915 ev.char_prop = char_prop;
918 DBG("sending the char search event");
920 event_cb(HAL_EV_GATT_CLIENT_CHARAC_SEARCH_RESULT, (void *)&ev, sizeof(ev));
923 static int _hal_get_permission_flag(char *permission)
927 if (NULL == permission) {
928 ERR("gatt permission is NULL");
932 if (!g_strcmp0(permission, "broadcast"))
933 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
934 else if (!g_strcmp0(permission, "read"))
935 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_READ;
936 else if (!g_strcmp0(permission, "write-without-response"))
937 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
938 else if (!g_strcmp0(permission, "write"))
939 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE;
940 else if (!g_strcmp0(permission, "notify"))
941 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
942 else if (!g_strcmp0(permission, "indicate"))
943 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
944 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
945 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
946 else if (!g_strcmp0(permission, "reliable-write"))
947 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
948 else if (!g_strcmp0(permission, "writable-auxiliaries"))
949 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
950 else if (!g_strcmp0(permission, "encrypt-read"))
951 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
952 else if (!g_strcmp0(permission, "encrypt-write"))
953 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
954 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
955 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
956 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
957 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
963 static bt_status_t _hal_gattc_get_characteristic_info(hal_gattc_char_t *gattc_char)
965 GDBusProxy *properties_proxy = NULL;
966 GError *error = NULL;
967 GVariant *value = NULL;
968 GVariant *result = NULL;
969 GDBusConnection *g_conn;
971 char *char_desc_handle = NULL;
973 GVariantIter *property_iter;
974 GVariantIter *char_desc_iter;
975 char* char_handle = NULL;
976 gchar *char_uuid_str = NULL;
977 GPtrArray *gp_desc_array = NULL;
978 GVariantIter *char_perm_iter;
980 unsigned int char_permission = 0 ;
984 if (gattc_char->chr_path == NULL) {
985 DBG("char path is NULL");
986 return BT_STATUS_FAIL;
988 char_handle = gattc_char->chr_path;
990 DBG("char path:[%s]", gattc_char->chr_path);
992 g_conn = _bt_hal_get_system_gconn();
993 if (NULL == g_conn) {
994 ERR("_bt_gdbus_get_system_gconn returned NULL");
995 return BT_STATUS_FAIL;
998 properties_proxy = g_dbus_proxy_new_sync(g_conn,
999 G_DBUS_PROXY_FLAGS_NONE, NULL,
1002 BT_HAL_PROPERTIES_INTERFACE,
1005 if (properties_proxy == NULL) {
1006 ERR("properties_proxy returned NULL");
1007 return BT_STATUS_FAIL;
1010 result = g_dbus_proxy_call_sync(properties_proxy,
1012 g_variant_new("(s)", BT_HAL_GATT_CHAR_INTERFACE),
1013 G_DBUS_CALL_FLAGS_NONE,
1018 if (error != NULL) {
1019 ERR("Fail to get properties (Error: %s)", error->message);
1020 g_clear_error(&error);
1022 ERR("Fail to get properties");
1023 g_object_unref(properties_proxy);
1024 return BT_STATUS_FAIL;
1027 gp_desc_array = g_ptr_array_new();
1029 g_variant_get(result, "(a{sv})", &property_iter);
1031 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1032 if (!g_strcmp0(key, "UUID")) {
1033 char_uuid_str = g_variant_dup_string(value, &len);
1034 DBG("char UUID [%s]", char_uuid_str);
1035 } else if (!g_strcmp0(key, "Flags")) {
1036 g_variant_get(value, "as", &char_perm_iter);
1037 char_permission = 0x00;
1039 while (g_variant_iter_loop(char_perm_iter, "s", &permission)) {
1040 DBG("char permission: [%s]", permission);
1041 char_permission |= _hal_get_permission_flag(permission);
1043 } else if (!g_strcmp0(key, "Descriptors")) {
1044 g_variant_get(value, "ao", &char_desc_iter);
1045 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle)) {
1046 DBG("char descriptor handle : %s", char_desc_handle);
1048 g_ptr_array_add(gp_desc_array, (gpointer)char_desc_handle);
1053 _hal_gattc_update_char_property(gattc_char, char_uuid_str, gp_desc_array, char_permission);
1055 g_free(char_uuid_str);
1056 g_variant_iter_free(property_iter);
1057 g_variant_unref(result);
1058 g_object_unref(properties_proxy);
1059 g_ptr_array_free(gp_desc_array, TRUE);
1061 return BT_STATUS_SUCCESS;
1064 static bt_status_t _gattc_get_all_characteristic(int conn_id,
1065 btgatt_srvc_id_t *srvc_id)
1067 hal_gattc_server_info_t * conn_info = NULL;
1068 hal_gattc_service_t *gattc_service = NULL;
1070 hal_gattc_char_t *gattc_char = NULL;
1071 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1072 int status = BT_STATUS_FAIL;
1075 DBG("conn_id[%d]", conn_id);
1077 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1078 if (NULL == conn_info) {
1079 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1080 return BT_STATUS_FAIL;
1084 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1085 if (NULL == gattc_service) {
1086 DBG("Failed to get the gatt service");
1087 return BT_STATUS_FAIL;
1090 DBG("service path [%s]", gattc_service->svc_path);
1092 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1093 DBG("service uuid [%s]", svc_uuid_str);
1095 /* find characteristic object path */
1096 for (l = gattc_service->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
1097 gattc_char = (hal_gattc_char_t *)l->data;
1098 status = _hal_gattc_get_characteristic_info(gattc_char);
1101 if (BT_STATUS_SUCCESS == status) {
1102 DBG("Sending the success charateristics event");
1103 _bt_hal_send_client_char_search_result_event(conn_id, status, srvc_id,
1104 &gattc_char->chr_uuid, gattc_char->permission);
1108 DBG("sending final event");
1110 status = BT_STATUS_FAIL;
1111 _bt_hal_send_client_char_search_result_event(conn_id, status, srvc_id, NULL, 0);
1113 browse_service_char(conn_id);
1114 /* retrive uuid for characteristic and object path for descriptor */
1116 return BT_STATUS_SUCCESS;
1120 * Enumerate characteristics for a given service.
1121 * Set start_char_id to NULL to get the first characteristic.
1123 bt_status_t btif_gattc_get_characteristic(int conn_id,
1124 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *start_char_id)
1127 CHECK_BTGATT_INIT();
1129 if (start_char_id == NULL) {
1130 DBG("Get all the characteristics");
1131 return _gattc_get_all_characteristic(conn_id, srvc_id);
1134 DBG("TBD Get specific characteristics");
1135 return BT_STATUS_UNSUPPORTED;
1139 static bt_status_t _hal_gattc_get_descriptor_info(hal_gattc_desc_t *gattc_desc)
1141 GDBusProxy *properties_proxy = NULL;
1142 GError *error = NULL;
1143 GVariant *value = NULL;
1144 GVariant *result = NULL;
1145 GDBusConnection *g_conn;
1148 GVariantIter *property_iter;
1149 char* desc_handle = NULL;
1150 const gchar *desc_uuid_str = NULL;
1154 if (gattc_desc->desc_path == NULL) {
1155 DBG("desc path is NULL");
1156 return BT_STATUS_FAIL;
1158 desc_handle = gattc_desc->desc_path;
1160 DBG("desc path:[%s]", gattc_desc->desc_path);
1162 g_conn = _bt_hal_get_system_gconn();
1163 if (NULL == g_conn) {
1164 ERR("_bt_gdbus_get_system_gconn returned NULL");
1165 return BT_STATUS_FAIL;
1168 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1169 G_DBUS_PROXY_FLAGS_NONE, NULL,
1172 BT_HAL_PROPERTIES_INTERFACE,
1175 if (properties_proxy == NULL) {
1176 ERR("properties_proxy returned NULL");
1177 return BT_STATUS_FAIL;
1180 result = g_dbus_proxy_call_sync(properties_proxy,
1182 g_variant_new("(s)", BT_HAL_GATT_DESC_INTERFACE),
1183 G_DBUS_CALL_FLAGS_NONE,
1188 if (error != NULL) {
1189 ERR("Fail to get properties (Error: %s)", error->message);
1190 g_clear_error(&error);
1192 ERR("Fail to get properties");
1193 g_object_unref(properties_proxy);
1194 return BT_STATUS_FAIL;
1197 g_variant_get(result, "(a{sv})", &property_iter);
1199 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1200 if (!g_strcmp0(key, "UUID")) {
1201 desc_uuid_str = g_variant_get_string(value, &len);
1202 DBG("desc UUID [%s]", desc_uuid_str);
1203 _hal_gattc_update_desc_property(gattc_desc, desc_uuid_str);
1208 g_variant_iter_free(property_iter);
1209 g_variant_unref(result);
1210 g_object_unref(properties_proxy);
1212 return BT_STATUS_SUCCESS;
1215 static void _bt_hal_send_client_desc_search_result_event(int conn_id, int status,
1216 btgatt_srvc_id_t *svc_id, btgatt_gatt_id_t *char_id, bt_uuid_t *desc_uuid)
1218 struct hal_ev_gatt_client_desc_search_result ev;
1221 ERR("gatt client callback not registered");
1225 DBG("sending gatt client search desc result event conn_id[%d] status[%d]", conn_id, status);
1227 memset(&ev, 0, sizeof(ev));
1228 ev.conn_id = conn_id;
1229 ev.inst_id = svc_id->id.inst_id;
1230 ev.is_primary = svc_id->is_primary;
1233 memcpy(ev.svc_uuid, svc_id->id.uuid.uu, sizeof(ev.svc_uuid));
1234 memcpy(ev.char_uuid, char_id->uuid.uu, sizeof(ev.char_uuid));
1236 if (status == BT_STATUS_SUCCESS) {
1237 DBG("building desc uuid");
1238 memcpy(ev.desc_uuid, desc_uuid->uu, sizeof(ev.desc_uuid));
1241 DBG("sending the desc search event");
1243 event_cb(HAL_EV_GATT_CLIENT_DESC_SEARCH_RESULT, (void *)&ev, sizeof(ev));
1246 static bt_status_t _hal_gattc_get_all_descriptor(int conn_id,
1247 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id)
1249 hal_gattc_server_info_t * conn_info = NULL;
1250 hal_gattc_service_t *gattc_service = NULL;
1253 hal_gattc_char_t *gattc_char = NULL;
1254 hal_gattc_desc_t *gattc_desc = NULL;
1255 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1256 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1257 int status = BT_STATUS_FAIL;
1261 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1262 if (NULL == conn_info) {
1263 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1264 return BT_STATUS_FAIL;
1268 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1269 if (NULL == gattc_service) {
1270 DBG("Failed to get the gatt service");
1271 return BT_STATUS_FAIL;
1274 DBG("service path [%s]", gattc_service->svc_path);
1275 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1276 DBG("service uuid [%s]", svc_uuid_str);
1278 /* find characteristics */
1279 /* a service can have two char with same uuid */
1280 for (l = gattc_service->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
1281 gattc_char = (hal_gattc_char_t*)l->data;
1282 if (gattc_char == NULL)
1285 if (!memcmp(&gattc_char->chr_uuid, &char_id->uuid, sizeof(bt_uuid_t))) {
1286 INFO("Found GATT char uuid");
1287 DBG("char path [%s]", gattc_char->chr_path);
1288 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1289 DBG("char uuid [%s]", char_uuid_str);
1291 /* get descriptor uuid */
1292 for (m = gattc_char->gatt_list_descs; m != NULL; m = g_slist_next(m)) {
1293 gattc_desc = (hal_gattc_desc_t *)m->data;
1294 if (gattc_desc == NULL)
1297 status = _hal_gattc_get_descriptor_info(gattc_desc);
1300 if (BT_STATUS_SUCCESS == status) {
1301 DBG("Sending the success descriptor event");
1302 _bt_hal_send_client_desc_search_result_event(conn_id, status, srvc_id,
1303 char_id, &gattc_desc->desc_uuid);
1309 DBG("sending final event");
1311 status = BT_STATUS_FAIL;
1312 _bt_hal_send_client_desc_search_result_event(conn_id, status, srvc_id, char_id, NULL);
1314 browse_service_char(conn_id);
1315 /* retrive uuid for characteristic and object path for descriptor */
1317 return BT_STATUS_SUCCESS;
1321 * Enumerate descriptors for a given characteristic.
1322 * Set start_descr_id to NULL to get the first descriptor.
1324 bt_status_t btif_gattc_get_descriptor(int conn_id,
1325 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1326 btgatt_gatt_id_t *start_descr_id)
1329 CHECK_BTGATT_INIT();
1331 if (start_descr_id == NULL) {
1332 DBG("Get all the descriptors");
1333 return _hal_gattc_get_all_descriptor(conn_id, srvc_id, char_id);
1335 DBG("TBD Get specific descriptor");
1336 return BT_STATUS_UNSUPPORTED;
1340 static void __hal_send_char_read_event(hal_gatt_resp_data_t *resp_data, int result, uint8_t *value, int len)
1342 struct hal_ev_gatt_client_read_data ev;
1345 ERR("gatt client callback not registered");
1349 DBG("sending gatt client charac read conn_id[%d] status[%d]", resp_data->conn_id, result);
1351 memset(&ev, 0, sizeof(ev));
1352 ev.conn_id = resp_data->conn_id;
1353 ev.inst_id = resp_data->srvc_id.id.inst_id;
1354 ev.is_primary = resp_data->srvc_id.is_primary;
1357 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1358 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1362 DBG("building the char read value [%d]", len);
1363 memcpy(ev.value, value, len);
1366 DBG("sending the gatt client read charac event");
1368 event_cb(HAL_EV_GATT_CLIENT_READ_CHARAC, (void *)&ev, sizeof(ev));
1371 static void __hal_internal_read_char_cb(GObject *source_object,
1372 GAsyncResult *res, gpointer user_data)
1374 GError *error = NULL;
1375 GDBusConnection *system_gconn = NULL;
1378 GByteArray *gp_byte_array = NULL;
1380 hal_gatt_resp_data_t *resp_data = user_data;
1381 int result = BT_STATUS_SUCCESS;
1386 system_gconn = _bt_hal_get_system_gconn();
1387 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1390 ERR("Read Characteristic dbus failed Error:[%s]", error->message);
1393 result = BT_STATUS_FAIL;
1394 __hal_send_char_read_event(resp_data, result, NULL, 0);
1395 g_clear_error(&error);
1400 gp_byte_array = g_byte_array_new();
1401 g_variant_get(value, "(ay)", &iter);
1403 while (g_variant_iter_loop(iter, "y", &g_byte))
1404 g_byte_array_append(gp_byte_array, &g_byte, 1);
1408 for (i = 0; i < gp_byte_array->len; i++)
1409 DBG("%02x", gp_byte_array->data[i]);
1412 __hal_send_char_read_event(resp_data, result, gp_byte_array->data, gp_byte_array->len);
1416 g_byte_array_free(gp_byte_array, TRUE);
1417 g_variant_iter_free(iter);
1418 g_variant_unref(value);
1424 static bt_status_t _hal_read_characteristic_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1425 btgatt_gatt_id_t *char_id, int auth_req)
1427 GDBusConnection *g_conn;
1428 hal_gatt_resp_data_t *resp_data;
1429 hal_gattc_service_t *gattc_service = NULL;
1430 GVariantBuilder *builder = NULL;
1432 hal_gattc_server_info_t * conn_info = NULL;
1433 hal_gattc_char_t *gattc_char = NULL;
1434 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1435 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1436 char* char_handle = NULL;
1440 /* get the connection info */
1441 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1442 if (NULL == conn_info) {
1443 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1444 return BT_STATUS_FAIL;
1448 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1449 if (NULL == gattc_service) {
1450 DBG("Failed to get the gatt service");
1451 return BT_STATUS_FAIL;
1454 DBG("service path [%s]", gattc_service->svc_path);
1455 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1456 DBG("service uuid [%s]", svc_uuid_str);
1459 /* find characteristic */
1460 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid,
1461 HAL_GATT_CHARACTERISTIC_PROPERTY_READ);
1462 if (NULL == gattc_char) {
1463 DBG("Failed to get the gatt char");
1464 return BT_STATUS_FAIL;
1467 DBG("char path [%s]", gattc_char->chr_path);
1468 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1469 DBG("char uuid [%s]", char_uuid_str);
1471 g_conn = _bt_hal_get_system_gconn();
1472 if (NULL == g_conn) {
1473 ERR("_bt_gdbus_get_system_gconn returned NULL");
1474 return BT_STATUS_FAIL;
1477 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1478 resp_data->conn_id = conn_id;
1479 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1480 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1482 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1485 g_variant_builder_add(builder, "{sv}", "offset",
1486 g_variant_new("q", offset));
1488 char_handle = gattc_char->chr_path;
1490 DBG("calling char read value");
1492 g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, char_handle, BT_HAL_GATT_CHAR_INTERFACE,
1493 "ReadValue", g_variant_new("(a{sv})", builder),
1494 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1495 (GAsyncReadyCallback)__hal_internal_read_char_cb,
1496 (gpointer)resp_data);
1497 g_variant_builder_unref(builder);
1499 return BT_STATUS_SUCCESS;
1502 /** Read a characteristic on a remote device */
1503 bt_status_t btif_read_characteristic(int conn_id,
1504 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1507 CHECK_BTGATT_INIT();
1510 return _hal_read_characteristic_value(conn_id, srvc_id, char_id, auth_req);
1513 static void __hal_send_char_write_event(hal_gatt_resp_data_t *resp_data, int result)
1515 struct hal_ev_gatt_client_write_result ev;
1518 ERR("gatt client callback not registered");
1522 DBG("sending gatt client charac write conn_id[%d] status[%d]", resp_data->conn_id, result);
1524 memset(&ev, 0, sizeof(ev));
1525 ev.conn_id = resp_data->conn_id;
1526 ev.inst_id = resp_data->srvc_id.id.inst_id;
1527 ev.is_primary = resp_data->srvc_id.is_primary;
1530 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1531 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1533 DBG("sending the gatt client write charac event");
1535 event_cb(HAL_EV_GATT_CLIENT_WRITE_CHARAC, (void *)&ev, sizeof(ev));
1538 static void __hal_bluetooth_internal_write_cb(GObject *source_object,
1539 GAsyncResult *res, gpointer user_data)
1541 GError *error = NULL;
1542 GDBusConnection *system_gconn = NULL;
1544 hal_gatt_resp_data_t *resp_data = user_data;
1545 int result = BT_STATUS_SUCCESS;
1549 system_gconn = _bt_hal_get_system_gconn();
1550 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1553 ERR("write Characteristic dbus failed Error:[%s]", error->message);
1555 result = BT_STATUS_FAIL;
1557 __hal_send_char_write_event(resp_data, result);
1558 g_clear_error(&error);
1563 //send write value event
1564 __hal_send_char_write_event(resp_data, result);
1567 g_variant_unref(value);
1572 static bt_status_t __hal_get_write_prop(hal_gatt_write_type_t type, bt_gatt_characteristic_property_t *prop)
1575 case HAL_GATT_WRITE_TYPE_WRITE:
1576 *prop = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE;
1578 case HAL_GATT_WRITE_TYPE_WRITE_NO_RESPONSE:
1579 *prop = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
1582 ERR("Unknow write type : %d", type);
1583 return BT_STATUS_FAIL;
1586 return BT_STATUS_SUCCESS;
1590 static int __bluetooth_gatt_acquire_write_fd(const char *chr, int *fd, int *mtu)
1592 GDBusConnection *conn;
1593 GVariantBuilder *builder = NULL;
1599 GUnixFDList *fd_list = NULL;
1601 conn = _bt_hal_get_system_gconn();
1603 ERR("_bt_gdbus_get_system_gconn returned NULL");
1604 return BT_STATUS_FAIL;
1607 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1608 //val = g_variant_new("ay", builder1);
1610 g_variant_builder_add(builder, "{sv}", "offset",
1611 g_variant_new("q", offset));
1613 value = g_dbus_connection_call_with_unix_fd_list_sync(conn, BT_HAL_BLUEZ_NAME, chr, BT_HAL_GATT_CHAR_INTERFACE,
1614 "AcquireWrite", g_variant_new("(a{sv})", builder),
1615 G_VARIANT_TYPE("(hq)"), G_DBUS_CALL_FLAGS_NONE, -1,
1616 NULL, &fd_list, NULL, &err);
1618 g_dbus_error_strip_remote_error(err);
1619 ERR("Error: %s", err->message);
1621 g_variant_builder_unref(builder);
1622 return BT_STATUS_FAIL;
1625 g_variant_get(value, "(hq)", &idx, &att_mtu);
1626 *fd = g_unix_fd_list_get(fd_list, idx, NULL);
1628 INFO("FD is %d index is %d mtu is %d", *fd, idx, att_mtu);
1631 g_object_unref(fd_list);
1632 g_variant_unref(value);
1633 g_variant_builder_unref(builder);
1635 return BT_STATUS_SUCCESS;
1638 static int __bluetooth_gatt_acquire_notify_fd(const char *chr, int *fd, int *mtu)
1640 GDBusConnection *conn;
1641 GVariantBuilder *builder = NULL;
1645 gint32 idx, notify_fd;
1647 GUnixFDList *fd_list = NULL;
1649 conn = _bt_hal_get_system_gconn();
1652 ERR("_bt_gdbus_get_system_gconn returned NULL");
1653 return BT_STATUS_FAIL;
1657 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1660 g_variant_builder_add(builder, "{sv}", "offset",
1661 g_variant_new("q", offset));
1663 value = g_dbus_connection_call_with_unix_fd_list_sync(conn, BT_HAL_BLUEZ_NAME, chr, BT_HAL_GATT_CHAR_INTERFACE,
1664 "AcquireNotify", g_variant_new("(a{sv})", builder),
1665 G_VARIANT_TYPE("(hq)"), G_DBUS_CALL_FLAGS_NONE, -1,
1666 NULL, &fd_list, NULL, &err);
1668 g_dbus_error_strip_remote_error(err);
1669 ERR("Error: %s", err->message);
1671 g_variant_builder_unref(builder);
1672 return BT_STATUS_FAIL;
1675 g_variant_get(value, "(hq)", &idx, &att_mtu);
1676 notify_fd = g_unix_fd_list_get(fd_list, idx, NULL);
1679 INFO("Acquired characteristic Notify fd %d, mtu %d", notify_fd, *mtu);
1683 g_object_unref(fd_list);
1684 g_variant_unref(value);
1685 g_variant_builder_unref(builder);
1687 return BT_STATUS_SUCCESS;
1691 static bt_status_t _hal_write_characteristic_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1692 btgatt_gatt_id_t *char_id, int write_type, int length, int auth_req, char* value)
1694 GVariant *val, *options;
1695 GVariantBuilder *builder1;
1696 GVariantBuilder *builder2;
1697 GDBusConnection *g_conn;
1700 hal_gatt_resp_data_t *resp_data;
1701 hal_gattc_service_t *gattc_service = NULL;
1702 hal_gattc_server_info_t * conn_info = NULL;
1703 hal_gattc_char_t *gattc_char = NULL;
1704 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1705 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1706 char* char_handle = NULL;
1707 bt_gatt_characteristic_property_t write_prop = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE;
1708 int ret = BT_STATUS_SUCCESS;
1712 ret = __hal_get_write_prop(write_type, &write_prop);
1713 if (BT_STATUS_FAIL == ret) {
1714 DBG("received invalid write type:[%d] ", write_type);
1715 return BT_STATUS_FAIL;
1718 /* get the connection info */
1719 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1720 if (NULL == conn_info) {
1721 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1722 return BT_STATUS_FAIL;
1726 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1727 if (NULL == gattc_service) {
1728 DBG("Failed to get the gatt service");
1729 return BT_STATUS_FAIL;
1732 DBG("service path [%s]", gattc_service->svc_path);
1733 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1734 DBG("service uuid [%s]", svc_uuid_str);
1736 /* find characteristic */
1737 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid, write_prop);
1738 if (NULL == gattc_char) {
1739 DBG("Failed to get the gatt char");
1740 return BT_STATUS_FAIL;
1743 DBG("char path [%s]", gattc_char->chr_path);
1744 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1745 DBG("char uuid [%s]", char_uuid_str);
1747 g_conn = _bt_hal_get_system_gconn();
1748 if (NULL == g_conn) {
1749 ERR("_bt_gdbus_get_system_gconn returned NULL");
1750 return BT_STATUS_FAIL;
1753 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1754 resp_data->conn_id = conn_id;
1755 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1756 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1758 char_handle = gattc_char->chr_path;
1760 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1762 for (i = 0; i < length; i++)
1763 g_variant_builder_add(builder1, "y", value[i]);
1765 val = g_variant_new("ay", builder1);
1767 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1769 g_variant_builder_add(builder2, "{sv}", "offset",
1770 g_variant_new_uint16(offset));
1772 options = g_variant_new("a{sv}", builder2);
1774 g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, char_handle, BT_HAL_GATT_CHAR_INTERFACE,
1776 g_variant_new("(y@ay@a{sv})", write_prop, val, options),
1778 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1779 (GAsyncReadyCallback)__hal_bluetooth_internal_write_cb,
1780 (gpointer)resp_data);
1782 g_variant_builder_unref(builder1);
1783 g_variant_builder_unref(builder2);
1785 return BT_STATUS_SUCCESS;
1788 bt_status_t btif_get_acquire_write_fd(int conn_id,
1789 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1790 int auth_req, int *fd, int*mtu)
1792 CHECK_BTGATT_INIT();
1796 DBG("svc isntance id:[%d]", srvc_id->id.inst_id);
1799 hal_gattc_service_t *gattc_service = NULL;
1800 hal_gattc_server_info_t * conn_info = NULL;
1801 hal_gattc_char_t *gattc_char = NULL;
1802 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1804 bt_gatt_characteristic_property_t write_prop = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
1805 int ret = BT_STATUS_SUCCESS;
1809 /* get the connection info */
1810 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1811 if (NULL == conn_info) {
1812 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1813 return BT_STATUS_FAIL;
1817 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1818 if (NULL == gattc_service) {
1819 DBG("Failed to get the gatt service");
1820 return BT_STATUS_FAIL;
1823 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid, write_prop);
1824 if (NULL == gattc_char) {
1825 DBG("Failed to get the gatt char");
1826 return BT_STATUS_FAIL;
1829 DBG("char path [%s]", gattc_char->chr_path);
1830 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1831 DBG("char uuid [%s]", char_uuid_str);
1834 ret = __bluetooth_gatt_acquire_write_fd(gattc_char->chr_path, fd, mtu);
1835 if (ret != BT_STATUS_SUCCESS)
1839 ERR("Characterstics FD erite characterstics fd is %d", *fd);
1844 bt_status_t btif_get_acquire_notify_fd(int conn_id,
1845 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, int *fd, int *mtu)
1847 CHECK_BTGATT_INIT();
1851 DBG("svc isntance id:[%d]", srvc_id->id.inst_id);
1854 hal_gattc_service_t *gattc_service = NULL;
1855 hal_gattc_server_info_t * conn_info = NULL;
1856 hal_gattc_char_t *gattc_char = NULL;
1857 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1859 bt_gatt_characteristic_property_t write_prop = HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
1860 int ret = BT_STATUS_SUCCESS;
1864 /* get the connection info */
1865 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1866 if (NULL == conn_info) {
1867 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1868 return BT_STATUS_FAIL;
1872 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1873 if (NULL == gattc_service) {
1874 DBG("Failed to get the gatt service");
1875 return BT_STATUS_FAIL;
1878 gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid, write_prop);
1879 if (NULL == gattc_char) {
1880 DBG("Failed to get the gatt char");
1881 return BT_STATUS_FAIL;
1884 DBG("char path [%s]", gattc_char->chr_path);
1885 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1886 DBG("char uuid [%s]", char_uuid_str);
1889 ret = __bluetooth_gatt_acquire_notify_fd(gattc_char->chr_path, fd, mtu);
1890 if (ret != BT_STATUS_SUCCESS)
1894 ERR("Characterstics FD write characterstics fd is %d", *fd);
1901 /** Write a remote characteristic */
1902 bt_status_t btif_write_characteristic(int conn_id,
1903 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1904 int write_type, int len, int auth_req,
1907 CHECK_BTGATT_INIT();
1911 DBG("svc isntance id:[%d]", srvc_id->id.inst_id);
1912 return _hal_write_characteristic_value(conn_id, srvc_id, char_id, write_type,
1913 len, auth_req, p_value);
1916 static void __hal_send_desc_read_event(hal_gatt_resp_data_t *resp_data, int result, uint8_t *value, int len)
1918 struct hal_ev_gatt_client_read_data ev;
1921 ERR("gatt client callback not registered");
1925 DBG("sending gatt client desc read conn_id[%d] status[%d]", resp_data->conn_id, result);
1927 memset(&ev, 0, sizeof(ev));
1928 ev.conn_id = resp_data->conn_id;
1929 ev.inst_id = resp_data->srvc_id.id.inst_id;
1930 ev.is_primary = resp_data->srvc_id.is_primary;
1933 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1934 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1935 memcpy(ev.desc_uuid, resp_data->desc_id.uuid.uu, sizeof(ev.char_uuid));
1939 DBG("building the desc read value [%d]", len);
1940 memcpy(ev.value, value, len);
1943 DBG("sending the gatt client read descriptor event");
1945 event_cb(HAL_EV_GATT_CLIENT_READ_DESC, (void *)&ev, sizeof(ev));
1948 static void __hal_internal_read_desc_cb(GObject *source_object,
1949 GAsyncResult *res, gpointer user_data)
1951 GError *error = NULL;
1952 GDBusConnection *system_gconn = NULL;
1955 GByteArray *gp_byte_array = NULL;
1957 hal_gatt_resp_data_t *resp_data = user_data;
1958 int result = BT_STATUS_SUCCESS;
1963 system_gconn = _bt_hal_get_system_gconn();
1964 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1967 ERR("Read descriptor dbus failed Error:[%s]", error->message);
1970 result = BT_STATUS_FAIL;
1971 __hal_send_desc_read_event(resp_data, result, NULL, 0);
1972 g_clear_error(&error);
1977 gp_byte_array = g_byte_array_new();
1978 g_variant_get(value, "(ay)", &iter);
1980 while (g_variant_iter_loop(iter, "y", &g_byte))
1981 g_byte_array_append(gp_byte_array, &g_byte, 1);
1985 for (i = 0; i < gp_byte_array->len; i++)
1986 DBG("%02x", gp_byte_array->data[i]);
1989 __hal_send_desc_read_event(resp_data, result, gp_byte_array->data, gp_byte_array->len);
1993 g_byte_array_free(gp_byte_array, TRUE);
1994 g_variant_iter_free(iter);
1995 g_variant_unref(value);
2000 static bt_status_t _hal_read_descriptor_value(int conn_id, btgatt_srvc_id_t *srvc_id,
2001 btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *desc_id, int auth_req)
2003 GDBusConnection *g_conn;
2004 hal_gatt_resp_data_t *resp_data;
2005 hal_gattc_service_t *gattc_service = NULL;
2006 GVariantBuilder *builder = NULL;
2008 hal_gattc_server_info_t * conn_info = NULL;
2009 hal_gattc_char_t *gattc_char = NULL;
2010 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
2011 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
2012 char desc_uuid_str[BT_HAL_UUID_STRING_LEN];
2013 char* desc_handle = NULL;
2016 hal_gattc_desc_t *gattc_desc = NULL;
2020 /* get the connection info */
2021 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
2022 if (NULL == conn_info) {
2023 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
2024 return BT_STATUS_FAIL;
2028 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
2029 if (NULL == gattc_service) {
2030 DBG("Failed to get the gatt service");
2031 return BT_STATUS_FAIL;
2034 DBG("service path [%s]", gattc_service->svc_path);
2035 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
2036 DBG("service uuid [%s]", svc_uuid_str);
2038 /* find characteristic */
2039 /* service can have two char with same uuid */
2040 for (l = gattc_service->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
2041 gattc_char = (hal_gattc_char_t*)l->data;
2042 if (gattc_char == NULL)
2045 if (!memcmp(&gattc_char->chr_uuid, &char_id->uuid, sizeof(bt_uuid_t))) {
2046 INFO("Found GATT char uuid");
2047 DBG("char path [%s]", gattc_char->chr_path);
2048 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2049 DBG("char uuid [%s]", char_uuid_str);
2051 /* find descriptor */
2052 gattc_desc = _gattc_find_desc_from_uuid(gattc_char, &desc_id->uuid);
2054 DBG("desc path [%s]", gattc_desc->desc_path);
2055 _bt_hal_convert_uuid_type_to_string(desc_uuid_str, gattc_desc->desc_uuid.uu);
2056 DBG("desc uuid [%s]", desc_uuid_str);
2062 if (NULL == gattc_desc) {
2063 DBG("Failed to get the gatt desc");
2064 return BT_STATUS_FAIL;
2067 g_conn = _bt_hal_get_system_gconn();
2068 if (NULL == g_conn) {
2069 ERR("_bt_gdbus_get_system_gconn returned NULL");
2070 return BT_STATUS_FAIL;
2073 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
2074 resp_data->conn_id = conn_id;
2075 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2076 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2077 memcpy(&resp_data->desc_id, desc_id, sizeof(btgatt_gatt_id_t));
2079 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2082 g_variant_builder_add(builder, "{sv}", "offset",
2083 g_variant_new("q", offset));
2085 desc_handle = gattc_desc->desc_path;
2087 DBG("calling desc read value");
2089 g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, desc_handle, BT_HAL_GATT_DESC_INTERFACE,
2090 "ReadValue", g_variant_new("(a{sv})", builder),
2091 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2092 (GAsyncReadyCallback)__hal_internal_read_desc_cb,
2093 (gpointer)resp_data);
2094 g_variant_builder_unref(builder);
2096 return BT_STATUS_SUCCESS;
2099 /** Read the descriptor for a given characteristic */
2100 bt_status_t btif_read_descriptor(int conn_id,
2101 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
2102 btgatt_gatt_id_t *descr_id, int auth_req)
2104 CHECK_BTGATT_INIT();
2106 return _hal_read_descriptor_value(conn_id, srvc_id, char_id, descr_id, auth_req);
2109 static void __hal_send_desc_write_event(hal_gatt_resp_data_t *resp_data, int result)
2111 struct hal_ev_gatt_client_write_result ev;
2114 ERR("gatt client callback not registered");
2118 DBG("sending gatt client charac write conn_id[%d] status[%d]", resp_data->conn_id, result);
2120 memset(&ev, 0, sizeof(ev));
2121 ev.conn_id = resp_data->conn_id;
2122 ev.inst_id = resp_data->srvc_id.id.inst_id;
2123 ev.is_primary = resp_data->srvc_id.is_primary;
2126 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
2127 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
2128 memcpy(ev.desc_uuid, resp_data->desc_id.uuid.uu, sizeof(ev.desc_uuid));
2130 DBG("sending the gatt client write charac event");
2132 event_cb(HAL_EV_GATT_CLIENT_WRITE_DESC, (void *)&ev, sizeof(ev));
2135 static void __hal_bluetooth_internal_desc_write_cb(GObject *source_object,
2136 GAsyncResult *res, gpointer user_data)
2138 GError *error = NULL;
2139 GDBusConnection *system_gconn = NULL;
2141 hal_gatt_resp_data_t *resp_data = user_data;
2142 int result = BT_STATUS_SUCCESS;
2146 system_gconn = _bt_hal_get_system_gconn();
2147 value = g_dbus_connection_call_finish(system_gconn, res, &error);
2150 ERR("write descriptor dbus failed Error: [%s]", error->message);
2153 result = BT_STATUS_FAIL;
2154 __hal_send_desc_write_event(resp_data, result);
2155 g_clear_error(&error);
2160 //send write value event
2161 __hal_send_desc_write_event(resp_data, result);
2164 g_variant_unref(value);
2169 static bt_status_t _hal_write_descriptor_value(int conn_id, btgatt_srvc_id_t *srvc_id,
2170 btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *descr_id,
2171 int write_type, int length, int auth_req, char* value)
2173 GVariant *val, *options;
2174 GVariantBuilder *builder1;
2175 GVariantBuilder *builder2;
2176 GDBusConnection *g_conn;
2179 hal_gatt_resp_data_t *resp_data;
2180 hal_gattc_service_t *gattc_service = NULL;
2181 hal_gattc_server_info_t * conn_info = NULL;
2182 hal_gattc_char_t *gattc_char = NULL;
2183 hal_gattc_desc_t *gattc_desc = NULL;
2184 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
2185 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
2186 char desc_uuid_str[BT_HAL_UUID_STRING_LEN];
2187 char* desc_handle = NULL;
2188 bt_gatt_characteristic_property_t write_prop = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE;
2189 int ret = BT_STATUS_SUCCESS;
2194 ret = __hal_get_write_prop(write_type, &write_prop);
2195 if (BT_STATUS_FAIL == ret) {
2196 DBG("received invalid write type:[%d] ", write_type);
2197 return BT_STATUS_FAIL;
2200 /* get the connection info */
2201 conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
2202 if (NULL == conn_info) {
2203 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
2204 return BT_STATUS_FAIL;
2208 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
2209 if (NULL == gattc_service) {
2210 DBG("Failed to get the gatt service");
2211 return BT_STATUS_FAIL;
2214 DBG("service path [%s]", gattc_service->svc_path);
2215 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
2216 DBG("service uuid [%s]", svc_uuid_str);
2218 /* find characteristic */
2219 /* service can have two char with same uuid */
2220 for (l = gattc_service->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
2221 gattc_char = (hal_gattc_char_t*)l->data;
2222 if (gattc_char == NULL)
2225 if (!memcmp(&gattc_char->chr_uuid, &char_id->uuid, sizeof(bt_uuid_t))) {
2226 INFO("Found GATT char uuid");
2227 DBG("char path [%s]", gattc_char->chr_path);
2228 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2229 DBG("char uuid [%s]", char_uuid_str);
2231 /* find descriptor */
2232 gattc_desc = _gattc_find_desc_from_uuid(gattc_char, &descr_id->uuid);
2234 DBG("desc path [%s]", gattc_desc->desc_path);
2235 _bt_hal_convert_uuid_type_to_string(desc_uuid_str, gattc_desc->desc_uuid.uu);
2236 DBG("desc uuid [%s]", desc_uuid_str);
2242 if (NULL == gattc_desc) {
2243 DBG("Failed to get the gatt desc");
2244 return BT_STATUS_FAIL;
2247 g_conn = _bt_hal_get_system_gconn();
2248 if (NULL == g_conn) {
2249 ERR("_bt_gdbus_get_system_gconn returned NULL");
2250 return BT_STATUS_FAIL;
2253 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
2254 resp_data->conn_id = conn_id;
2255 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2256 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2257 memcpy(&resp_data->desc_id, descr_id, sizeof(btgatt_gatt_id_t));
2259 desc_handle = gattc_desc->desc_path;
2261 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2263 for (i = 0; i < length; i++)
2264 g_variant_builder_add(builder1, "y", value[i]);
2266 val = g_variant_new("ay", builder1);
2268 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2270 g_variant_builder_add(builder2, "{sv}", "offset",
2271 g_variant_new_uint16(offset));
2273 options = g_variant_new("a{sv}", builder2);
2275 g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, desc_handle, BT_HAL_GATT_DESC_INTERFACE,
2277 g_variant_new("(@ay@a{sv})", val, options),
2279 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2280 (GAsyncReadyCallback)__hal_bluetooth_internal_desc_write_cb,
2281 (gpointer)resp_data);
2283 g_variant_builder_unref(builder1);
2284 g_variant_builder_unref(builder2);
2286 return BT_STATUS_SUCCESS;
2289 /** Write a remote descriptor for a given characteristic */
2290 bt_status_t btif_write_descriptor(int conn_id,
2291 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
2292 btgatt_gatt_id_t *descr_id, int write_type, int len,
2293 int auth_req, char* p_value)
2295 CHECK_BTGATT_INIT();
2297 return _hal_write_descriptor_value(conn_id, srvc_id, char_id, descr_id, write_type,
2298 len, auth_req, p_value);
2301 /** Execute a prepared write operation */
2302 bt_status_t execute_write(int conn_id, int execute)
2304 CHECK_BTGATT_INIT();
2305 return BT_STATUS_UNSUPPORTED;
2308 static gboolean _hal_watch_register_notifi_cb(gpointer user_data)
2310 struct hal_ev_gatt_client_watch_notification ev;
2311 hal_gatt_resp_data_t *resp_data = user_data;
2313 DBG("sending the watch register notification event");
2314 /* send the event */
2315 memset(&ev, 0, sizeof(ev));
2316 ev.client_if = resp_data->conn_id; /* conn_id is saved with client_if */
2318 ev.status = resp_data->result;
2320 ev.is_primary = resp_data->srvc_id.is_primary;
2321 ev.inst_id = resp_data->srvc_id.id.inst_id;
2323 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
2324 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
2327 ERR("GATT Callback not registered");
2329 event_cb(HAL_EV_GATT_CLIENT_WATCH_NOTIFICATION, (void *)&ev, sizeof(ev));
2336 static bt_status_t _hal_register_for_notification(int client_if,
2337 bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2338 btgatt_gatt_id_t *char_id)
2340 int result = BT_STATUS_SUCCESS;
2341 GError *error = NULL;
2342 GDBusConnection *g_conn;
2343 hal_gattc_client_info_t *gattc_client = NULL;
2344 hal_gattc_server_info_t * conn_info = NULL;
2345 hal_gattc_service_t *gattc_service = NULL;
2346 hal_gattc_char_t *gattc_char = NULL;
2347 char* char_handle = NULL;
2348 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
2349 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
2350 hal_gatt_resp_data_t *resp_data;
2354 gattc_client = __bt_find_gatt_client_info(bd_addr);
2355 if (gattc_client == NULL) {
2356 ERR("failed to get the gatt client info");
2357 return BT_STATUS_FAIL;
2360 if (gattc_client->client_if != client_if) {
2361 ERR("could not find the gatt client for client id[%d]", client_if);
2362 return BT_STATUS_FAIL;
2365 /* get the connection info */
2366 conn_info = __bt_find_gatt_conn_info(bd_addr);
2367 if (NULL == conn_info) {
2368 ERR("Failed to get the conn_info");
2369 return BT_STATUS_FAIL;
2372 if (conn_info->inst_id != gattc_client->inst_id) {
2373 ERR("could not fild the conn_info");
2374 return BT_STATUS_FAIL;
2378 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
2379 if (NULL == gattc_service) {
2380 DBG("Failed to get the gatt service");
2381 return BT_STATUS_FAIL;
2384 DBG("service path [%s]", gattc_service->svc_path);
2385 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
2386 DBG("service uuid [%s]", svc_uuid_str);
2389 /* find characteristic */
2390 gattc_char = _gattc_find_char_from_uuid_for_notify(gattc_service, &char_id->uuid);
2391 if (NULL == gattc_char) {
2392 DBG("Failed to get the gatt char");
2393 return BT_STATUS_FAIL;
2396 DBG("char path [%s]", gattc_char->chr_path);
2397 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2398 DBG("char uuid [%s]", char_uuid_str);
2400 char_handle = gattc_char->chr_path;
2402 g_conn = _bt_hal_get_system_gconn();
2403 if (g_conn == NULL) {
2405 return BT_STATUS_FAIL;
2408 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
2410 DBG("#StartNotify");
2411 g_dbus_connection_call_sync(g_conn,
2414 BT_HAL_GATT_CHAR_INTERFACE,
2418 G_DBUS_CALL_FLAGS_NONE,
2419 BT_HAL_MAX_DBUS_TIMEOUT, NULL, &error);
2422 g_dbus_error_strip_remote_error(error);
2423 ERR("### Watch Failed: %s", error->message);
2424 if (g_strrstr(error->message, "Already notifying"))
2425 result = BT_STATUS_SUCCESS;
2426 else if (g_strrstr(error->message, "In Progress"))
2427 result = BT_STATUS_BUSY;
2428 else if (g_strrstr(error->message, "Operation is not supported"))
2429 result = BT_STATUS_UNSUPPORTED;
2430 /*failed because of either Insufficient Authorization or Write Not Permitted */
2431 else if (g_strrstr(error->message, "Write not permitted") ||
2432 g_strrstr(error->message, "Operation Not Authorized"))
2433 result = BT_STATUS_AUTH_FAILURE;
2434 /* failed because of either Insufficient Authentication,
2435 Insufficient Encryption Key Size, or Insufficient Encryption. */
2436 else if (g_strrstr(error->message, "Not paired"))
2437 result = BT_STATUS_NOT_READY;
2439 result = BT_STATUS_FAIL;
2441 g_clear_error(&error);
2444 resp_data->conn_id = gattc_client->client_if; /* saving client_if instead of conn_id */
2445 resp_data->result = result;
2446 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2447 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2449 g_idle_add(_hal_watch_register_notifi_cb, (gpointer)resp_data);
2453 return BT_STATUS_SUCCESS;
2457 * Register to receive notifications or indications for a given
2460 bt_status_t btif_register_for_notification(int client_if,
2461 const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2462 btgatt_gatt_id_t *char_id)
2464 CHECK_BTGATT_INIT();
2466 return _hal_register_for_notification(client_if, (bt_bdaddr_t *)bd_addr, srvc_id, char_id);
2469 static gboolean _hal_watch_deregister_notifi_cb(gpointer user_data)
2471 struct hal_ev_gatt_client_watch_notification ev;
2472 hal_gatt_resp_data_t *resp_data = user_data;
2474 DBG("sending the watch deregister notification event");
2475 /* send the event */
2476 memset(&ev, 0, sizeof(ev));
2477 ev.client_if = resp_data->conn_id; /* conn_id is saved with client_if */
2479 ev.status = resp_data->result;
2481 ev.is_primary = resp_data->srvc_id.is_primary;
2482 ev.inst_id = resp_data->srvc_id.id.inst_id;
2484 memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
2485 memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
2488 ERR("GATT Callback not registered");
2490 event_cb(HAL_EV_GATT_CLIENT_WATCH_NOTIFICATION, (void *)&ev, sizeof(ev));
2497 static bt_status_t _hal_deregister_for_notification(int client_if,
2498 bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2499 btgatt_gatt_id_t *char_id)
2501 int result = BT_STATUS_SUCCESS;
2502 GError *error = NULL;
2503 GDBusConnection *g_conn;
2504 hal_gattc_client_info_t *gattc_client = NULL;
2505 hal_gattc_server_info_t * conn_info = NULL;
2506 hal_gattc_service_t *gattc_service = NULL;
2507 hal_gattc_char_t *gattc_char = NULL;
2508 char* char_handle = NULL;
2509 char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
2510 char char_uuid_str[BT_HAL_UUID_STRING_LEN];
2511 hal_gatt_resp_data_t *resp_data;
2515 gattc_client = __bt_find_gatt_client_info(bd_addr);
2516 if (gattc_client == NULL) {
2517 ERR("failed to get the gatt client info");
2518 return BT_STATUS_FAIL;
2521 if (gattc_client->client_if != client_if) {
2522 ERR("could not find the gatt client for client id[%d]", client_if);
2523 return BT_STATUS_FAIL;
2526 /* get the connection info */
2527 conn_info = __bt_find_gatt_conn_info(bd_addr);
2528 if (NULL == conn_info) {
2529 ERR("Failed to get the conn_info");
2530 return BT_STATUS_FAIL;
2533 if (conn_info->inst_id != gattc_client->inst_id) {
2534 ERR("could not fild the conn_info");
2535 return BT_STATUS_FAIL;
2539 gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
2540 if (NULL == gattc_service) {
2541 DBG("Failed to get the gatt service");
2542 return BT_STATUS_FAIL;
2545 DBG("service path [%s]", gattc_service->svc_path);
2546 _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
2547 DBG("service uuid [%s]", svc_uuid_str);
2550 /* find characteristic */
2551 gattc_char = _gattc_find_char_from_uuid_for_notify(gattc_service, &char_id->uuid);
2552 if (NULL == gattc_char) {
2553 DBG("Failed to get the gatt char");
2554 return BT_STATUS_FAIL;
2557 DBG("char path [%s]", gattc_char->chr_path);
2558 _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2559 DBG("char uuid [%s]", char_uuid_str);
2561 char_handle = gattc_char->chr_path;
2563 g_conn = _bt_hal_get_system_gconn();
2564 if (g_conn == NULL) {
2566 return BT_STATUS_FAIL;
2569 resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
2571 DBG("#StartNotify");
2572 g_dbus_connection_call_sync(g_conn,
2575 BT_HAL_GATT_CHAR_INTERFACE,
2579 G_DBUS_CALL_FLAGS_NONE,
2580 BT_HAL_MAX_DBUS_TIMEOUT, NULL, &error);
2583 ERR("### Watch Failed: %s", error->message);
2584 g_clear_error(&error);
2585 result = BT_STATUS_FAIL;
2588 resp_data->conn_id = gattc_client->client_if; /* saving client_if instead of conn_id */
2589 resp_data->result = result;
2590 memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2591 memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2593 g_idle_add(_hal_watch_deregister_notifi_cb, (gpointer)resp_data);
2597 return BT_STATUS_SUCCESS;
2599 /** Deregister a previous request for notifications/indications */
2600 bt_status_t btif_deregister_for_notification(int client_if,
2601 const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2602 btgatt_gatt_id_t *char_id)
2604 CHECK_BTGATT_INIT();
2605 return _hal_deregister_for_notification(client_if, (bt_bdaddr_t *)bd_addr, srvc_id, char_id);
2608 /** Request RSSI for a given remote device */
2609 bt_status_t read_remote_rssi(int client_if, const bt_bdaddr_t *bd_addr)
2611 CHECK_BTGATT_INIT();
2612 return BT_STATUS_UNSUPPORTED;
2615 /** OTA firmware download */
2616 bt_status_t ota_fw_update(int client_if, int conn_id, const bt_bdaddr_t *bd_addr, char* path)
2618 CHECK_BTGATT_INIT();
2619 return BT_STATUS_UNSUPPORTED;
2622 /** Determine the type of the remote device (LE, BR/EDR, Dual-mode) */
2623 int get_device_type(const bt_bdaddr_t *bd_addr)
2625 CHECK_BTGATT_INIT();
2626 return BT_STATUS_UNSUPPORTED;
2629 static bt_status_t __hal_update_conn_parameter(bt_bdaddr_t *bd_addr,
2630 int min_int, int max_int, int latency, int timeout)
2632 gchar *device_path = NULL;
2633 GError *error = NULL;
2634 GDBusProxy *device_proxy = NULL;
2635 GDBusConnection *conn;
2637 int ret = BT_STATUS_SUCCESS;
2638 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
2640 INFO("Min interval: %d, Max interval: %d, Latency: %d, Supervision timeout: %d",
2641 min_int, max_int, latency, timeout);
2643 conn = _bt_hal_get_system_gconn();
2646 return BT_STATUS_FAIL;
2649 _bt_hal_convert_addr_type_to_string(device_address,
2650 (unsigned char *)bd_addr->address);
2651 device_path = _bt_hal_get_device_object_path(device_address);
2653 if (device_path == NULL) {
2654 ERR("device_path NULL : [%s]", device_address);
2655 return BT_STATUS_FAIL;
2658 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2659 NULL, BT_HAL_BLUEZ_NAME,
2660 device_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
2662 g_free(device_path);
2663 if (NULL == device_proxy) {
2664 ERR("device_proxy returned NULL");
2665 return BT_STATUS_FAIL;
2668 INFO("### LeConnUpdate");
2669 reply = g_dbus_proxy_call_sync(device_proxy, "LeConnUpdate",
2670 g_variant_new("(uuuu)", min_int, max_int, latency, timeout),
2671 G_DBUS_CALL_FLAGS_NONE,
2676 g_object_unref(device_proxy);
2677 if (reply == NULL) {
2679 ERR("Error %s[%s]", error->message, device_address);
2680 if (g_strrstr(error->message, "In Progress"))
2681 ret = BT_STATUS_SUCCESS;
2683 ret = BT_STATUS_FAIL;
2684 g_error_free(error);
2688 g_variant_unref(reply);
2690 INFO("LE Connection parameter Updated");
2694 /** Request a connection parameter update */
2695 bt_status_t btif_gattc_conn_parameter_update(bt_bdaddr_t *bd, int min_int, int max_int, int latency, int timeout)
2697 CHECK_BTGATT_INIT();
2701 return __hal_update_conn_parameter(bd, min_int, max_int, latency, timeout);
2704 /** Test mode interface */
2705 bt_status_t test_command(int command, btgatt_test_params_t* params)
2707 CHECK_BTGATT_INIT();
2708 return BT_STATUS_UNSUPPORTED;
2711 /** MTU Exchange request from client */
2712 bt_status_t configure_mtu(int conn_id, int mtu)
2714 CHECK_BTGATT_INIT();
2715 return BT_STATUS_UNSUPPORTED;
2718 /** Setup scan filter params */
2719 bt_status_t scan_filter_param_setup(int client_if, int action, int filt_index, int feat_seln,
2720 int list_logic_type, int filt_logic_type, int rssi_high_thres,
2721 int rssi_low_thres, int dely_mode, int found_timeout,
2722 int lost_timeout, int found_timeout_cnt)
2725 GError *error = NULL;
2726 GVariant *ret, *param;
2727 CHECK_BTGATT_INIT();
2729 proxy = _bt_hal_get_adapter_proxy();
2732 return BT_STATUS_FAIL;
2734 param = g_variant_new("(iiiiiiiiiiii)",
2747 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
2748 param, G_DBUS_CALL_FLAGS_NONE,
2752 ERR("scan_filter_param_setup Fail: %s", error->message);
2753 g_clear_error(&error);
2754 return BT_STATUS_FAIL;
2758 g_variant_unref(ret);
2760 return BT_STATUS_SUCCESS;
2763 /** Configure a scan filter condition */
2764 bt_status_t scan_filter_add_remove(int client_if, int action, int filt_type,
2765 int filt_index, int company_id,
2766 int company_id_mask, const bt_uuid_t *p_uuid,
2767 const bt_uuid_t *p_uuid_mask, const bt_bdaddr_t *bd_addr,
2768 char addr_type, int data_len, char* p_data, int mask_len,
2772 GError *error = NULL;
2773 GVariant *ret, *param;
2774 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
2775 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
2776 GArray *arr_uuid = NULL;
2777 GArray *arr_uuid_mask = NULL;
2778 GArray *arr_data = NULL;
2779 GArray *arr_data_mask = NULL;
2780 CHECK_BTGATT_INIT();
2782 proxy = _bt_hal_get_adapter_proxy();
2785 return BT_STATUS_FAIL;
2787 if (filt_type == BT_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
2789 char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
2791 _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
2793 INFO("BT_SCAN_FILTER_FEATURE_DEVICE_ADDRESS being added\nRemote Device Address is [%s]", address);
2795 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
2796 NULL, 0, TRUE, NULL, NULL);
2797 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2798 NULL, 0, TRUE, NULL, NULL);
2799 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
2800 NULL, 0, TRUE, NULL, NULL);
2801 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2802 NULL, 0, TRUE, NULL, NULL);
2804 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
2805 client_if, // client_if
2806 action, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
2807 BT_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
2808 filt_index, // filter_index
2809 company_id, // company_id
2810 company_id_mask, // company_id_mask
2811 arr_uuid_param, // p_uuid
2812 arr_uuid_mask_param, // p_uuid_mask
2814 addr_type, // address_type
2815 arr_data_param, // p_data
2816 arr_data_mask_param); // p_mask
2818 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
2819 param, G_DBUS_CALL_FLAGS_NONE,
2823 ERR("scan_filter_add_remove Fail: %s", error->message);
2824 g_clear_error(&error);
2825 return BT_STATUS_FAIL;
2829 g_variant_unref(ret);
2831 return BT_STATUS_SUCCESS;
2834 if (filt_type == BT_SCAN_FILTER_FEATURE_DEVICE_NAME) {
2836 INFO("BT_SCAN_FILTER_FEATURE_DEVICE_NAME being added\nRemote Device Name is %s", p_data);
2837 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
2838 NULL, 0, TRUE, NULL, NULL);
2839 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2840 NULL, 0, TRUE, NULL, NULL);
2841 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
2842 NULL, 0, TRUE, NULL, NULL);
2843 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2844 NULL, 0, TRUE, NULL, NULL);
2846 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
2847 client_if, // client_if
2848 action, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
2849 BT_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
2850 filt_index, // filter_index
2851 company_id, // company_id
2852 company_id_mask, // company_id_mask
2853 arr_uuid_param, // p_uuid
2854 arr_uuid_mask_param, // p_uuid_mask
2856 addr_type, // address_type
2857 arr_data_param, // p_data
2858 arr_data_mask_param);
2860 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
2861 param, G_DBUS_CALL_FLAGS_NONE,
2865 ERR("scan_filter_add_remove Fail: %s", error->message);
2866 g_clear_error(&error);
2867 return BT_STATUS_FAIL;
2871 g_variant_unref(ret);
2873 return BT_STATUS_SUCCESS;
2876 if (filt_type == BT_SCAN_FILTER_FEATURE_SERVICE_UUID) {
2878 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
2879 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
2881 g_array_append_vals(arr_uuid, p_uuid->uu, data_len * sizeof(guint8));
2882 g_array_append_vals(arr_uuid_mask, p_uuid_mask->uu, mask_len * sizeof(guint8));
2884 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
2885 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
2886 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2887 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
2888 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
2889 NULL, 0, TRUE, NULL, NULL);
2890 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2891 NULL, 0, TRUE, NULL, NULL);
2893 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
2894 client_if, // client_if
2895 action, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
2896 BT_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
2897 filt_index, // filter_index
2898 company_id, // company_id
2899 company_id_mask, // company_id_mask
2900 arr_uuid_param, // p_uuid
2901 arr_uuid_mask_param, // p_uuid_mask
2903 addr_type, // address_type
2904 arr_data_param, // p_data
2905 arr_data_mask_param);
2907 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
2908 param, G_DBUS_CALL_FLAGS_NONE,
2912 ERR("scan_filter_add_remove Fail: %s", error->message);
2913 g_clear_error(&error);
2914 return BT_STATUS_FAIL;
2918 g_variant_unref(ret);
2920 g_array_free(arr_uuid, TRUE);
2921 g_array_free(arr_uuid_mask, TRUE);
2923 return BT_STATUS_SUCCESS;
2926 if (filt_type == BT_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
2928 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
2929 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
2931 g_array_append_vals(arr_uuid, p_uuid->uu, data_len * sizeof(guint8));
2932 g_array_append_vals(arr_uuid_mask, p_uuid_mask->uu, mask_len * sizeof(guint8));
2934 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
2935 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
2936 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2937 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
2938 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
2939 NULL, 0, TRUE, NULL, NULL);
2940 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2941 NULL, 0, TRUE, NULL, NULL);
2943 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
2944 client_if, // client_if
2945 action, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
2946 BT_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
2947 filt_index, // filter_index
2948 company_id, // company_id
2949 company_id_mask, // company_id_mask
2950 arr_uuid_param, // p_uuid
2951 arr_uuid_mask_param, // p_uuid_mask
2953 addr_type, // address_type
2954 arr_data_param, // p_data
2955 arr_data_mask_param);
2957 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
2958 G_DBUS_CALL_FLAGS_NONE,
2962 ERR("scan_filter_add_remove Fail: %s", error->message);
2963 g_clear_error(&error);
2964 return BT_STATUS_FAIL;
2968 g_variant_unref(ret);
2970 g_array_free(arr_uuid, TRUE);
2971 g_array_free(arr_uuid_mask, TRUE);
2973 return BT_STATUS_SUCCESS;
2976 if (filt_type == BT_SCAN_FILTER_FEATURE_SERVICE_DATA) {
2978 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
2979 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
2981 g_array_append_vals(arr_data, p_data, data_len * sizeof(guint8));
2982 g_array_append_vals(arr_data_mask, p_mask, mask_len * sizeof(guint8));
2984 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
2985 NULL, 0, TRUE, NULL, NULL);
2986 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2987 NULL, 0, TRUE, NULL, NULL);
2988 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
2989 arr_data->data, arr_data->len, TRUE, NULL, NULL);
2990 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2991 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
2993 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
2994 client_if, // client_if
2995 action, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
2996 BT_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
2997 filt_index, // filter_index
2998 company_id, // company_id
2999 company_id_mask, // company_id_mask
3000 arr_uuid_param, // p_uuid
3001 arr_uuid_mask_param, // p_uuid_mask
3003 addr_type, // address_type
3004 arr_data_param, // p_data
3005 arr_data_mask_param);
3007 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
3008 G_DBUS_CALL_FLAGS_NONE,
3012 ERR("scan_filter_add_remove Fail: %s", error->message);
3013 g_clear_error(&error);
3014 return BT_STATUS_FAIL;
3018 g_variant_unref(ret);
3020 g_array_free(arr_data, TRUE);
3021 g_array_free(arr_data_mask, TRUE);
3023 return BT_STATUS_SUCCESS;
3026 if (filt_type == BT_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
3028 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
3029 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
3031 g_array_append_vals(arr_data, p_data, data_len * sizeof(guint8));
3032 g_array_append_vals(arr_data_mask, p_mask, mask_len * sizeof(guint8));
3034 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
3035 NULL, 0, TRUE, NULL, NULL);
3036 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
3037 NULL, 0, TRUE, NULL, NULL);
3038 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
3039 arr_data->data, arr_data->len, TRUE, NULL, NULL);
3040 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
3041 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
3043 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
3044 client_if, // client_if
3045 action, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
3046 BT_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
3047 filt_index, // filter_index
3048 company_id, // company_id
3049 company_id_mask, // company_id_mask
3050 arr_uuid_param, // p_uuid
3051 arr_uuid_mask_param, // p_uuid_mask
3053 addr_type, // address_type
3054 arr_data_param, // p_data
3055 arr_data_mask_param);
3057 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
3058 G_DBUS_CALL_FLAGS_NONE,
3062 ERR("scan_filter_add_remove Fail: %s", error->message);
3063 g_clear_error(&error);
3064 return BT_STATUS_FAIL;
3068 g_variant_unref(ret);
3070 g_array_free(arr_data, TRUE);
3071 g_array_free(arr_data_mask, TRUE);
3073 return BT_STATUS_SUCCESS;
3076 return BT_STATUS_UNSUPPORTED;
3079 /** Clear all scan filter conditions for specific filter index*/
3080 bt_status_t scan_filter_clear(int client_if, int filt_index)
3083 GError *error = NULL;
3085 CHECK_BTGATT_INIT();
3087 proxy = _bt_hal_get_adapter_proxy();
3089 return BT_STATUS_FAIL;
3091 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
3092 g_variant_new("(ii)", client_if, filt_index),
3093 G_DBUS_CALL_FLAGS_NONE,
3097 ERR("scan_filter_clear Fail: %s", error->message);
3098 g_clear_error(&error);
3099 return BT_STATUS_FAIL;
3102 g_variant_unref(ret);
3103 return BT_STATUS_SUCCESS;
3106 /** Enable / disable scan filter feature*/
3107 bt_status_t scan_filter_enable(int client_if, bool enable)
3110 GError *error = NULL;
3112 CHECK_BTGATT_INIT();
3114 proxy = _bt_hal_get_adapter_proxy();
3116 return BT_STATUS_FAIL;
3118 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
3119 g_variant_new("(ib)", client_if, enable),
3120 G_DBUS_CALL_FLAGS_NONE,
3124 ERR("scan_filter_enable Fail: %s", error->message);
3125 g_clear_error(&error);
3126 return BT_STATUS_FAIL;
3128 g_variant_unref(ret);
3130 return BT_STATUS_SUCCESS;
3133 /** Sets the LE scan interval and window in units of N*0.625 msec */
3135 bt_status_t set_scan_parameters(int scan_type, int scan_interval, int scan_window)
3139 CHECK_BTGATT_INIT();
3141 le_scan_type = scan_type;
3142 ret = _bt_hal_adapter_le_set_scan_parameters(
3143 scan_type, scan_interval, scan_window);
3147 bt_status_t set_scan_parameters(int scan_interval, int scan_window)
3149 CHECK_BTGATT_INIT();
3150 return BT_STATUS_UNSUPPORTED;
3154 /* Configure the batchscan storage */
3155 bt_status_t batchscan_cfg_storage(int client_if, int batch_scan_full_max,
3156 int batch_scan_trunc_max, int batch_scan_notify_threshold)
3158 CHECK_BTGATT_INIT();
3159 return BT_STATUS_UNSUPPORTED;
3162 /* Enable batchscan */
3163 bt_status_t batchscan_enb_batch_scan(int client_if, int scan_mode,
3164 int scan_interval, int scan_window, int addr_type, int discard_rule)
3166 CHECK_BTGATT_INIT();
3167 return BT_STATUS_UNSUPPORTED;
3170 /* Disable batchscan */
3171 bt_status_t batchscan_dis_batch_scan(int client_if)
3173 CHECK_BTGATT_INIT();
3174 return BT_STATUS_UNSUPPORTED;
3177 /* Read out batchscan reports */
3178 bt_status_t batchscan_read_reports(int client_if, int scan_mode)
3180 CHECK_BTGATT_INIT();
3181 return BT_STATUS_UNSUPPORTED;
3184 const btgatt_client_interface_t btgatt_client_interface = {
3185 .register_client = btif_gattc_register_client,
3186 .unregister_client = btif_gattc_unregister_client,
3188 .connect = btif_gattc_client_connect,
3189 .disconnect = btif_gattc_client_disconnect,
3191 .search_service = btif_gattc_client_search_service,
3192 .get_included_service = get_included_service,
3193 .get_characteristic = btif_gattc_get_characteristic,
3194 .get_descriptor = btif_gattc_get_descriptor,
3195 .read_characteristic = btif_read_characteristic,
3196 .write_characteristic = btif_write_characteristic,
3197 .acquire_write = btif_get_acquire_write_fd,
3198 .acquire_notify = btif_get_acquire_notify_fd,
3199 .read_descriptor = btif_read_descriptor,
3200 .write_descriptor = btif_write_descriptor,
3201 .execute_write = execute_write,
3202 .register_for_notification = btif_register_for_notification,
3203 .deregister_for_notification = btif_deregister_for_notification,
3204 .read_remote_rssi = read_remote_rssi,
3205 .ota_fw_update = ota_fw_update,
3206 .get_device_type = get_device_type,
3207 .conn_parameter_update = btif_gattc_conn_parameter_update,
3208 .test_command = test_command,
3209 .configure_mtu = configure_mtu,
3210 .scan_filter_param_setup = scan_filter_param_setup,
3211 .scan_filter_add_remove = scan_filter_add_remove,
3212 .scan_filter_clear = scan_filter_clear,
3213 .scan_filter_enable = scan_filter_enable,
3214 .set_scan_parameters = set_scan_parameters,
3215 .batchscan_cfg_storage = batchscan_cfg_storage,
3216 .batchscan_enb_batch_scan = batchscan_enb_batch_scan,
3217 .batchscan_dis_batch_scan = batchscan_dis_batch_scan,
3218 .batchscan_read_reports = batchscan_read_reports
3221 static hal_gattc_server_info_t *__bt_find_gatt_conn_info(bt_bdaddr_t *serv_addr)
3226 hal_gattc_server_info_t *info = NULL;
3228 for (l = hal_gattc_server_info_list; l != NULL; l = g_slist_next(l)) {
3229 info = (hal_gattc_server_info_t*)l->data;
3233 if (!memcmp(&info->bd_addr, serv_addr, sizeof(bt_bdaddr_t))) {
3234 INFO("GATT connection found addr");
3241 static hal_gattc_client_info_t *__bt_find_gatt_client_info(bt_bdaddr_t *serv_addr)
3246 hal_gattc_client_info_t *info = NULL;
3248 for (l = hal_gattc_client_info_list; l != NULL; l = g_slist_next(l)) {
3249 info = (hal_gattc_client_info_t*)l->data;
3253 if (!memcmp(&info->bd_addr, serv_addr, sizeof(bt_bdaddr_t))) {
3254 INFO("GATT client info found addr");
3261 static hal_gattc_client_info_t *__bt_find_gatt_client_info_from_conn_id(int conn_id)
3266 hal_gattc_client_info_t *info = NULL;
3268 for (l = hal_gattc_client_info_list; l != NULL; l = g_slist_next(l)) {
3269 info = (hal_gattc_client_info_t*)l->data;
3273 if (info->conn_id == conn_id) {
3274 INFO("GATT client info found for conn_id [%d]", conn_id);
3281 static hal_gattc_server_info_t *__bt_find_gatt_conn_info_from_conn_id(int conn_id)
3286 hal_gattc_server_info_t *info = NULL;
3287 hal_gattc_client_info_t *gattc_client = NULL;
3289 gattc_client = __bt_find_gatt_client_info_from_conn_id(conn_id);
3290 if (gattc_client == NULL) {
3291 INFO("GATT client conn info not found");
3295 for (l = hal_gattc_server_info_list; l != NULL; l = g_slist_next(l)) {
3296 info = (hal_gattc_server_info_t*)l->data;
3300 if ((info->inst_id == gattc_client->inst_id) &&
3301 !memcmp(&info->bd_addr, &gattc_client->bd_addr, sizeof(bt_bdaddr_t))) {
3302 INFO("GATT connection found for conn_id [%d]", conn_id);
3309 static bt_status_t __bt_connect_le_device_internal(int client_if, const bt_bdaddr_t *bd_addr,
3310 gboolean auto_connect)
3312 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
3313 gchar *device_path = NULL;
3314 GDBusProxy *device_proxy = NULL;
3315 GDBusConnection *conn;
3316 int ret = BT_STATUS_SUCCESS;
3317 hal_gattc_client_info_t *gattc_data;
3321 if (NULL == bd_addr) {
3322 ERR("bd_addr is NULL");
3323 return BT_STATUS_PARM_INVALID;
3326 conn = _bt_hal_get_system_gconn();
3328 ERR("_bt_gdbus_get_system_gconn returned NULL");
3329 return BT_STATUS_FAIL;
3332 _bt_hal_convert_addr_type_to_string(device_address,
3333 (unsigned char *)bd_addr->address);
3334 device_path = _bt_hal_get_device_object_path(device_address);
3335 if (device_path == NULL) {
3336 ERR("device_path NULL : [%s]", device_address);
3337 ret = BT_STATUS_FAIL;
3340 ERR("device_path:%s", device_path);
3342 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
3343 NULL, BT_HAL_BLUEZ_NAME,
3344 device_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
3345 g_free(device_path);
3346 if (NULL == device_proxy) {
3347 ERR("device_proxy returned NULL");
3348 return BT_STATUS_FAIL;
3351 gattc_data = g_malloc0(sizeof(hal_gattc_client_info_t));
3352 memcpy(gattc_data->bd_addr.address, bd_addr->address,
3353 BT_HAL_ADDRESS_LENGTH_MAX);
3355 DBG("Connect LE [%s]", device_address);
3357 gattc_data->client_if = client_if;
3359 g_dbus_proxy_call(device_proxy, "ConnectLE",
3360 g_variant_new("(b)", auto_connect),
3361 G_DBUS_CALL_FLAGS_NONE,
3362 BT_HAL_MAX_DBUS_TIMEOUT,
3364 (GAsyncReadyCallback)__le_connection_req_cb, gattc_data);
3369 static bt_status_t _bt_hold_current_advertising()
3371 int ret = BT_STATUS_FAIL;
3372 gboolean is_advertising = FALSE;
3375 is_advertising = _bt_hal_is_advertising_in_slot(0);
3376 if (is_advertising) {
3377 DBG("+ Stop current advertising");
3379 ret = _bt_hal_enable_advertising(0, 0, FALSE, FALSE);
3380 g_timeout_add(2000, __bt_hold_current_advertising_timeout_cb, NULL);
3386 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
3388 DBG("+ start current advertising");
3390 _bt_hal_enable_advertising(0, 0, TRUE, FALSE);
3395 static gboolean __bt_connect_le_timer_cb(gpointer user_data)
3397 DBG("Try to initiate pending LE connection");
3399 pending_le_conn_timer_id = 0;
3401 __bt_connect_le_device_internal(pending_le_conn_info->client_if,
3402 &pending_le_conn_info->bd_addr,
3403 pending_le_conn_info->auto_connect);
3405 g_free(pending_le_conn_info);
3406 pending_le_conn_info = NULL;
3411 static int __hal_generate_conn_id()
3413 return ++bt_conn_id;
3416 static int __hal_generate_server_instance_id()
3418 return ++bt_inst_id;
3421 static void __le_connection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
3424 GError *g_error = NULL;
3425 GVariant *reply = NULL;
3426 hal_gattc_client_info_t *gattc_data = user_data;
3427 int result = BT_STATUS_SUCCESS;
3428 struct hal_ev_gatt_client_connected ev;
3429 hal_gattc_server_info_t *gatt_conn_info = NULL;
3433 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
3434 g_object_unref(proxy);
3435 if (reply == NULL) {
3436 ERR("Connect LE Dbus Call Error");
3438 ERR("Error: %s\n", g_error->message);
3439 g_clear_error(&g_error);
3441 result = BT_STATUS_FAIL;
3443 g_variant_unref(reply);
3445 if (NULL == gattc_data) {
3446 ERR("server_data is NULL");
3451 if (result == BT_STATUS_FAIL) {
3452 memset(&ev, 0, sizeof(ev));
3455 ev.client_if = gattc_data->client_if;
3456 memcpy(ev.bdaddr, gattc_data->bd_addr.address,
3457 BT_HAL_ADDRESS_LENGTH_MAX);
3460 ERR("gatt client callback not registered");
3462 DBG("sending gatt client connected event");
3463 event_cb(HAL_EV_GATT_CLIENT_CONNECTED, (void *)&ev, sizeof(ev));
3469 DBG("adding the server conn info in list");
3470 gattc_data->conn_id = __hal_generate_conn_id() ;
3471 gattc_data->inst_id = __hal_generate_server_instance_id();
3473 hal_gattc_client_info_list = g_slist_append(hal_gattc_client_info_list, gattc_data);
3475 /*add gatt server connection info*/
3476 gatt_conn_info = g_malloc0(sizeof(hal_gattc_server_info_t));
3477 memcpy(gatt_conn_info->bd_addr.address, gattc_data->bd_addr.address, BT_HAL_ADDRESS_LENGTH_MAX);
3478 gatt_conn_info->inst_id = gattc_data->inst_id;
3479 hal_gattc_server_info_list = g_slist_append(hal_gattc_server_info_list, gatt_conn_info);
3485 /*remove conn_info*/
3490 void __hal_gattc_free_svc_info(hal_gattc_service_t *svc_info)
3492 g_free(svc_info->svc_path);
3496 void __hal_gattc_free_char_info(hal_gattc_char_t *char_info)
3498 g_free(char_info->chr_path);
3502 void __hal_gattc_free_desc_info(hal_gattc_desc_t *desc_info)
3504 g_free(desc_info->desc_path);
3508 void __hal_clean_gattc_server_info(hal_gattc_server_info_t *conn_info)
3513 hal_gattc_service_t *svc_info = NULL;
3514 hal_gattc_char_t *char_info = NULL;
3515 hal_gattc_desc_t *desc_info = NULL;
3519 for (l = conn_info->gatt_list_services; l != NULL;) {
3520 svc_info = (hal_gattc_service_t*)l->data;
3521 if (svc_info == NULL)
3523 l = g_slist_next(l);
3525 for (m = svc_info->gatt_list_chars; m != NULL; ) {
3526 char_info = (hal_gattc_char_t*)m->data;
3527 if (char_info == NULL)
3529 m = g_slist_next(m);
3531 for (k = char_info->gatt_list_descs; k != NULL; ) {
3532 desc_info = (hal_gattc_desc_t*)k->data;
3533 if (desc_info == NULL)
3535 k = g_slist_next(k);
3537 /*remove desc element*/
3538 char_info->gatt_list_descs = g_slist_remove(char_info->gatt_list_descs, desc_info);
3539 __hal_gattc_free_desc_info(desc_info);
3542 /*remove desc list*/
3543 g_slist_free(char_info->gatt_list_descs);
3544 char_info->gatt_list_descs = NULL;
3546 /*remove char element*/
3547 svc_info->gatt_list_chars = g_slist_remove(svc_info->gatt_list_chars, char_info);
3548 __hal_gattc_free_char_info(char_info);
3551 /*remove char list*/
3552 g_slist_free(svc_info->gatt_list_chars);
3553 svc_info->gatt_list_chars = NULL;
3555 /*remove svc element*/
3556 conn_info->gatt_list_services = g_slist_remove(conn_info->gatt_list_services, svc_info);
3557 __hal_gattc_free_svc_info(svc_info);
3560 /*remove svc list */
3561 g_slist_free(conn_info->gatt_list_services);
3562 conn_info->gatt_list_services = NULL;
3564 /*remove conn info*/
3568 gboolean _bt_hal_check_gattc_is_existing(const char *address)
3570 bt_bdaddr_t bd_addr;
3571 _bt_hal_convert_addr_string_to_type(bd_addr.address, address);
3572 if (__bt_find_gatt_client_info(&bd_addr) != NULL)
3578 void _bt_hal_handle_gattc_connected_event(char* address, gboolean gatt_connected)
3580 int result = BT_STATUS_SUCCESS;
3581 struct hal_ev_gatt_client_connected ev;
3582 hal_gattc_server_info_t *conn_info = NULL;
3583 bt_bdaddr_t bd_addr;
3585 hal_gattc_client_info_t *gattc_client = NULL;
3589 DBG("+ connected device address [%s]", address);
3591 event = gatt_connected ? HAL_EV_GATT_CLIENT_CONNECTED :
3592 HAL_EV_GATT_CLIENT_DISCONNECTED;
3594 _bt_hal_convert_addr_string_to_type(bd_addr.address, address);
3595 /* find the gatt client info */
3596 gattc_client = __bt_find_gatt_client_info(&bd_addr);
3597 if (NULL == gattc_client) {
3598 ERR("Fail to get gatt client info");
3603 memset(&ev, 0, sizeof(ev));
3604 ev.conn_id = gattc_client->conn_id;
3606 ev.client_if = gattc_client->client_if;
3607 memcpy(ev.bdaddr, gattc_client->bd_addr.address,
3608 BT_HAL_ADDRESS_LENGTH_MAX);
3611 ERR("gatt client callback not registered");
3613 DBG("sending gatt client connected status event");
3614 event_cb(event, (void *)&ev, sizeof(ev));
3617 if (!gatt_connected) {
3618 inst_id = gattc_client->inst_id;
3620 /* remove the gatt client info from the client list also*/
3621 hal_gattc_client_info_list = g_slist_remove(hal_gattc_client_info_list, gattc_client);
3622 g_free(gattc_client);
3624 //find the connected server info
3625 conn_info = __bt_find_gatt_conn_info(&bd_addr);
3626 if (NULL == conn_info) {
3627 ERR("Fail to get gatt server info");
3631 if (inst_id != conn_info->inst_id) {
3632 ERR("server instance is different");
3636 //remove gatt conn info from the server list
3637 DBG("remove the server conn_info from list after gatt disconnection");
3638 hal_gattc_server_info_list = g_slist_remove(hal_gattc_server_info_list, conn_info);
3639 __hal_clean_gattc_server_info(conn_info);
3645 static void _bt_hal_send_search_service_result_event(int conn_id, int is_primary,
3646 const char* uuid_str, int inst_id)
3648 struct hal_ev_gatt_client_search_result ev;
3651 ERR("gatt client callback not registered");
3655 DBG("sending gatt client search service result event conn_id[%d]", conn_id);
3657 memset(&ev, 0, sizeof(ev));
3658 ev.conn_id = conn_id;
3659 ev.inst_id = inst_id;
3660 ev.is_primary = is_primary;
3661 _bt_hal_convert_uuid_string_to_type(ev.uuid, uuid_str);
3663 event_cb(HAL_EV_GATT_CLIENT_SEARCH_RESULT, (void *)&ev, sizeof(ev));
3666 static void _bt_hal_send_search_service_complete_event(int conn_id, int status)
3668 struct hal_ev_gatt_client_search_complete ev;
3671 ERR("gatt client callback not registered");
3675 DBG("sending gatt client search service complete event conn_id[%d]", conn_id);
3678 memset(&ev, 0, sizeof(ev));
3679 ev.conn_id = conn_id;
3682 event_cb(HAL_EV_GATT_CLIENT_SEARCH_COMPLETE, (void *)&ev, sizeof(ev));
3685 static void _bt_hal_send_value_changed_event(hal_gattc_server_info_t *conn_info,
3686 hal_gattc_service_t *svc_info, hal_gattc_char_t *char_info,
3687 char *char_value, int len)
3689 struct hal_ev_gatt_client_notify_changed_value ev;
3690 hal_gattc_client_info_t *gattc_client = NULL;
3693 ERR("gatt client callback not registered");
3697 gattc_client = __bt_find_gatt_client_info(&conn_info->bd_addr);
3698 if (NULL == gattc_client) {
3699 ERR("failed to get the gatt client info");
3704 DBG("sending gatt client connected status event");
3705 memset(&ev, 0, sizeof(ev));
3707 ev.conn_id = gattc_client->conn_id;
3708 ev.inst_id = conn_info->inst_id;
3709 ev.is_primary = svc_info->is_primary;
3710 memcpy(ev.svc_uuid, svc_info->svc_uuid.uu, sizeof(ev.svc_uuid));
3711 memcpy(ev.char_uuid, char_info->chr_uuid.uu, sizeof(ev.char_uuid));
3713 memcpy(ev.bdaddr, conn_info->bd_addr.address, BT_HAL_ADDRESS_LENGTH_MAX);
3715 if (len > 0 && (char_value != NULL)) {
3716 memcpy(ev.value, char_value, len);
3720 event_cb(HAL_EV_GATT_CLIENT_NOTIFY_CHANGED_VALUE, (void *)&ev, sizeof(ev));
3723 void _bt_hal_handle_gattc_value_changed_event(int result, const char *char_handle,
3724 char *char_value, int len)
3726 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
3727 hal_gattc_server_info_t *conn_info = NULL;
3728 bt_bdaddr_t bd_addr;
3731 hal_gattc_service_t *svc_info = NULL;
3732 hal_gattc_char_t *char_info = NULL;
3736 _bt_hal_convert_device_path_to_address(char_handle, device_address);
3737 device_address[BT_HAL_ADDRESS_STRING_SIZE - 1] = '\0';
3738 DBG("device address:[%s]", device_address);
3739 DBG("char handle:[%s]", char_handle);
3741 _bt_hal_convert_addr_string_to_type(bd_addr.address, device_address);
3742 conn_info = __bt_find_gatt_conn_info(&bd_addr);
3744 if (conn_info != NULL) {
3745 //find service for notified char path
3746 for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
3747 svc_info = (hal_gattc_service_t*)l->data;
3748 if (svc_info == NULL)
3751 /* find characteristic object path */
3752 for (k = svc_info->gatt_list_chars; k != NULL; k = g_slist_next(k)) {
3753 char_info = (hal_gattc_char_t *)k->data;
3754 if (char_info == NULL)
3757 if (g_strcmp0(char_info->chr_path, char_handle) == 0) {
3758 DBG("Found char handle[%s]", char_info->chr_path);
3761 _bt_hal_send_value_changed_event(conn_info, svc_info,
3762 char_info, char_value, len);