Implemented enable and disable Gatt watch notification
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-gatt-client.c
1 /*
2  * BLUETOOOTH HAL
3  *
4  * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Anupam Roy <anupam.r@samsung.com>
7  *
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
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include <hardware/bluetooth.h>
23 #include <hardware/bt_gatt.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <string.h>
28 #include <dlog.h>
29 #include <gio/gio.h>
30 #include <glib.h>
31
32
33 #include "bt-hal-log.h"
34 #include "bt-hal-msg.h"
35 #include "bt-hal-event-receiver.h"
36 #include "bt-hal-adapter-le.h"
37
38 #include "bt-hal-gatt-client.h"
39 #include "bt-hal-dbus-common-utils.h"
40 #include "bt-hal-utils.h"
41
42 /************************************************************************************
43  **  Static variables
44  ************************************************************************************/
45 extern const btgatt_callbacks_t *bt_gatt_callbacks;
46 #define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
47 {\
48         ERR("%s: BTGATT not initialized", __FUNCTION__);\
49         return BT_STATUS_NOT_READY;\
50 } else {\
51         DBG("%s", __FUNCTION__);\
52 }
53
54 #ifdef TIZEN_BT_HAL
55 int le_scan_type = BT_GATTC_LE_SCAN_TYPE_PASSIVE;
56 #endif
57
58 static handle_stack_msg event_cb = NULL;
59
60 #define GATT_SERV_INTERFACE             "org.bluez.GattService1"
61 #define MAX_HAL_OBJECT_PATH_LEN         100
62
63 typedef enum {
64         HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST = 0x01,
65         HAL_GATT_CHARACTERISTIC_PROPERTY_READ = 0x02,
66         HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE = 0x04,
67         HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE = 0x08,
68         HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY = 0x10,
69         HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE = 0x20,
70         HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE = 0x40,
71         HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE = 0x80,
72         HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES = 0x100,
73         HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ = 0x200,
74         HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE = 0x400,
75         HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ = 0x800,
76         HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE = 0x1000,
77         HAL_GATT_CHARACTERISTIC_PROPERTY_EXTENDED_PROPS = 0xffff,
78 } bt_gatt_characteristic_property_t;
79
80
81 typedef enum {
82         HAL_GATT_WRITE_TYPE_WRITE_NO_RESPONSE = 1,
83         HAL_GATT_WRITE_TYPE_WRITE ,
84 } hal_gatt_write_type_t;
85
86
87 typedef enum {
88         HAL_GATT_PROPERTY_BROADCAST = 0x01,  /**< Broadcast property */
89         HAL_GATT_PROPERTY_READ = 0x02,  /**< Read property */
90         HAL_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE = 0x04,  /**< Write without response property */
91         HAL_GATT_PROPERTY_WRITE = 0x08,  /**< Write property */
92         HAL_GATT_PROPERTY_NOTIFY = 0x10,  /**< Notify property */
93         HAL_GATT_PROPERTY_INDICATE = 0x20,  /**< Indicate property */
94         HAL_GATT_PROPERTY_AUTHENTICATED_SIGNED_WRITES = 0x40,  /**< Authenticated signed writes property */
95         HAL_GATT_PROPERTY_EXTENDED_PROPERTIES = 0x80,  /**< Extended properties */
96 } hal_gatt_property_e;
97
98 typedef struct {
99         int client_if;
100         bt_bdaddr_t bd_addr;
101         gboolean auto_connect;
102 } bt_pending_le_conn_info_s;
103
104 typedef struct {
105         char *desc_path;
106         bt_uuid_t desc_uuid;
107 } hal_gattc_desc_t;
108
109 typedef struct {
110         char *chr_path;
111         bt_uuid_t chr_uuid;
112         unsigned int permission;
113         GSList *gatt_list_descs;
114 } hal_gattc_char_t;
115
116 typedef struct {
117         gchar *svc_path;
118         bt_uuid_t svc_uuid;
119         GSList *gatt_list_chars;
120 } hal_gattc_service_t;
121
122 typedef struct {
123         bt_bdaddr_t bd_addr;    /*remote server address*/
124         int inst_id;            /*server instance id*/
125         GSList *gatt_list_services;
126 } hal_gattc_server_info_t;
127
128 /* Linked List of connected GATT server */
129 static GSList *hal_gattc_server_info_list = NULL;
130
131 typedef struct {
132         int client_if;
133         bt_bdaddr_t bd_addr;    /*remote server address*/
134         int conn_id;
135         int inst_id;
136 } hal_gattc_client_info_t;
137
138 /* Linked list of connected GATT client connection */
139 static GSList * hal_gattc_client_info_list = NULL;
140
141
142 static bt_pending_le_conn_info_s *pending_le_conn_info = NULL;
143 static guint pending_le_conn_timer_id = 0;
144 static int bt_conn_id = 0;
145 static int bt_inst_id = 0;
146
147 #define BT_GATTC_CL_MAX 32
148
149 typedef struct {
150         int conn_id;
151         int result;
152         btgatt_srvc_id_t srvc_id;
153         btgatt_gatt_id_t char_id;
154         btgatt_gatt_id_t desc_id;
155 } hal_gatt_resp_data_t;
156
157 typedef struct {
158         int client_if;
159         bt_uuid_t app_uuid;
160 } hal_gatt_client_app;
161
162 static GSList * hal_gattc_client_app_list = NULL;
163
164 static int bt_client_if = 0;
165
166
167 static bt_status_t __bt_connect_le_device_internal(int client_if, const bt_bdaddr_t *bd_addr,
168                 gboolean auto_connect);
169 static bt_status_t _bt_hold_current_advertising();
170 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data);
171 static gboolean __bt_connect_le_timer_cb(gpointer user_data);
172 static void __le_connection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
173                 gpointer user_data);
174 static hal_gattc_server_info_t *__bt_find_gatt_conn_info_from_conn_id(int  conn_id);
175 static void _bt_hal_send_search_service_result_event(int conn_id, int is_primary,
176                                                 const char* uuid_str, int inst_id);
177 static void _bt_hal_send_search_service_complete_event(int conn_id, int status);
178 static hal_gattc_server_info_t *__bt_find_gatt_conn_info(bt_bdaddr_t *serv_addr);
179 static hal_gattc_client_info_t *__bt_find_gatt_client_info(bt_bdaddr_t *serv_addr);
180
181
182 /* To send stack event to hal-av handler */
183 void _bt_hal_register_gatt_client_handler_cb(handle_stack_msg cb)
184 {
185         event_cb = cb;
186 }
187
188 void _bt_hal_unregister_gatt_client_handler_cb(void)
189 {
190         event_cb = NULL;
191 }
192
193 #ifdef TIZEN_BT_HAL
194 int _bt_hal_gatt_client_get_le_scan_type(void)
195 {
196         return le_scan_type;
197 }
198 #endif
199
200 static gboolean __bt_hal_register_client_cb(gpointer user_data)
201 {
202         struct hal_ev_gatt_client_registered ev;
203         hal_gatt_client_app *client_info = user_data;
204
205         DBG("+");
206         /* Prepare to send AV connecting event */
207         memset(&ev, 0, sizeof(ev));
208         ev.status = BT_STATUS_SUCCESS;
209         ev.client_if = client_info->client_if;
210         memcpy(ev.app_uuid, client_info->app_uuid.uu, sizeof(ev.app_uuid));
211
212         if (!event_cb)
213                 ERR("GATT Callback not registered");
214         else {
215                 DBG("GATT client registered, client_if: [%d]", client_info->client_if);
216                 event_cb(HAL_EV_GATT_CLIENT_REGISTERED, (void *)&ev, sizeof(ev));
217         }
218
219         g_free(user_data);
220         return FALSE;
221 }
222
223 static int __hal_generate_client_id()
224 {
225         return ++bt_client_if;
226 }
227
228 static hal_gatt_client_app *__hal_gattc_add_client_app(bt_uuid_t *app_uuid)
229 {
230         GSList *l;
231         hal_gatt_client_app *info = NULL;
232         hal_gatt_client_app *gattc_app = NULL;
233
234         //check if client app is already registered
235         for (l = hal_gattc_client_app_list; l != NULL; l = g_slist_next(l)) {
236                 info = (hal_gatt_client_app*)l->data;
237                 if (info == NULL)
238                         continue;
239
240                 if (memcmp(&info->app_uuid, app_uuid, sizeof(bt_uuid_t)) == 0) {
241                         DBG("gatt client app already registered");
242                         return info;
243                 }
244         }
245
246         DBG("adding the gatt client app");
247
248         //add client app
249         gattc_app = g_malloc0(sizeof(hal_gatt_client_app));
250         if (gattc_app == NULL) {
251                 DBG("Failed to allocate memory");
252                 return NULL;
253         }
254
255         gattc_app->client_if = __hal_generate_client_id();
256         memcpy(&gattc_app->app_uuid, app_uuid, sizeof(bt_uuid_t));
257
258         hal_gattc_client_app_list = g_slist_append(hal_gattc_client_app_list, gattc_app);
259
260         return gattc_app;
261 }
262
263 static bt_status_t __hal_gattc_register_client_app(bt_uuid_t *app_uuid)
264 {
265         hal_gatt_client_app *gattc_app = NULL;
266         hal_gatt_client_app *client_app_info = NULL;
267
268         DBG("+");
269         /* add gatt client in list */
270         gattc_app = __hal_gattc_add_client_app(app_uuid);
271         if (gattc_app == NULL) {
272                 ERR("Failed to register gatt client app");
273                 return BT_STATUS_FAIL;
274         }
275
276         /*send event */
277         client_app_info = g_malloc0(sizeof(hal_gatt_client_app));
278         if (NULL == client_app_info) {
279                 ERR("Failed to allocate memory");
280                 return BT_STATUS_FAIL;
281         }
282
283         client_app_info->client_if = gattc_app->client_if;
284         memcpy(&client_app_info->app_uuid, app_uuid, sizeof(bt_uuid_t));
285         g_idle_add(__bt_hal_register_client_cb, (gpointer)client_app_info);
286
287         DBG("registered client client_if [%d]", client_app_info->client_if);
288
289         return BT_STATUS_SUCCESS;
290 }
291
292 /** Registers a GATT client application with the stack */
293 bt_status_t btif_gattc_register_client(bt_uuid_t *uuid)
294 {
295         CHECK_BTGATT_INIT();
296         DBG("+");
297
298         return __hal_gattc_register_client_app(uuid);
299 }
300
301 bt_status_t __hal_gattc_unregister_client(int client_if)
302 {
303         GSList *l;
304         hal_gatt_client_app *info = NULL;
305
306         DBG("registered client count: [%d]", g_slist_length(hal_gattc_client_app_list));
307
308         /* remove the gatt client app */
309         for (l = hal_gattc_client_app_list; l != NULL; ) {
310                 info = (hal_gatt_client_app*)l->data;
311                 l = g_slist_next(l);
312
313                 if (info == NULL)
314                         continue;
315
316                 if (info->client_if == client_if) {
317                         DBG("gatt client app found");
318                         hal_gattc_client_app_list = g_slist_remove(hal_gattc_client_app_list, info);
319                         g_free(info);
320                 }
321         }
322
323         DBG("registered client count: [%d]", g_slist_length(hal_gattc_client_app_list));
324         return BT_STATUS_SUCCESS;
325 }
326
327 /** Unregister a client application from the stack */
328 bt_status_t btif_gattc_unregister_client(int client_if)
329 {
330         CHECK_BTGATT_INIT();
331         DBG("+");
332
333         return __hal_gattc_unregister_client(client_if);
334 }
335
336 /** Start or stop LE device scanning */
337 bt_status_t scan(int client_if, bool start)
338 {
339         int ret;
340
341         CHECK_BTGATT_INIT();
342
343         if (start)
344                 ret = _bt_hal_adapter_le_start_scan();
345         else
346                 ret = _bt_hal_adapter_le_stop_scan();
347
348         return ret;
349 }
350
351 /** Create a connection to a remote LE or dual-mode device */
352 bt_status_t btif_gattc_client_connect(int client_if, const bt_bdaddr_t *bd_addr,
353                 bool is_direct)
354 {
355         int ret = BT_STATUS_SUCCESS;
356
357         CHECK_BTGATT_INIT();
358         DBG("+");
359
360         if (NULL == bd_addr)
361                 return BT_STATUS_PARM_INVALID;
362
363         ret = _bt_hold_current_advertising();
364         if (ret == BT_STATUS_SUCCESS) {
365                 DBG("Current advertising is held");
366                 pending_le_conn_info = g_malloc0(sizeof(bt_pending_le_conn_info_s));
367                 pending_le_conn_info->client_if = client_if;
368                 memcpy(pending_le_conn_info->bd_addr.address, bd_addr->address,
369                                 BT_HAL_ADDRESS_LENGTH_MAX);
370                 pending_le_conn_info->auto_connect = is_direct;
371
372                 pending_le_conn_timer_id =
373                         g_timeout_add(1000, __bt_connect_le_timer_cb, NULL);
374
375                 return BT_STATUS_SUCCESS;
376         } else {
377                 ERR("advertising is not stopped");
378         }
379
380         return __bt_connect_le_device_internal(client_if, bd_addr, is_direct);
381 }
382
383
384 static void __le_disconnection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
385                 gpointer user_data)
386 {
387         GError *g_error = NULL;
388         GVariant *reply = NULL;
389         hal_gattc_client_info_t *gatt_conn_info  = user_data;
390         int result = BT_STATUS_SUCCESS;
391         struct hal_ev_gatt_client_connected ev;
392
393         DBG("+");
394
395         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
396         g_object_unref(proxy);
397         if (reply == NULL) {
398                 ERR("Connect LE Dbus Call Error");
399                 if (g_error) {
400                         ERR("Error: %s\n", g_error->message);
401                         g_clear_error(&g_error);
402                 }
403                 result = BT_STATUS_FAIL;
404         }
405         g_variant_unref(reply);
406
407         if (NULL == gatt_conn_info) {
408                 ERR("server_data is NULL");
409                 return;
410         }
411
412         /*send fail event*/
413         if (result == BT_STATUS_FAIL) {
414                 memset(&ev, 0, sizeof(ev));
415                 ev.conn_id = gatt_conn_info->conn_id;
416                 ev.status = result;
417                 ev.client_if = gatt_conn_info->client_if;
418                 memcpy(ev.bdaddr, gatt_conn_info->bd_addr.address,
419                                                 BT_HAL_ADDRESS_LENGTH_MAX);
420
421                 if (!event_cb) {
422                         ERR("gatt client callback not registered");
423                 } else {
424                         DBG("sending gatt client disconnected event");
425                         event_cb(HAL_EV_GATT_CLIENT_DISCONNECTED, (void *)&ev, sizeof(ev));
426                 }
427         }
428
429         /*remove conn_info*/
430         if (gatt_conn_info)
431                 g_free(gatt_conn_info);
432
433         DBG("-");
434 }
435
436 bt_status_t _hal_gattc_disconnect(int client_if, const bt_bdaddr_t *bd_addr,
437                         int conn_id)
438 {
439         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
440         gchar *device_path;
441         GDBusProxy *device_proxy;
442         GDBusConnection *conn;
443         int ret = BT_STATUS_SUCCESS;
444         hal_gattc_client_info_t *gattc_data;
445
446         if (NULL == bd_addr) {
447                 ERR("bd_addr is NULL");
448                 return BT_STATUS_PARM_INVALID;
449         }
450
451         conn = _bt_hal_get_system_gconn();
452         if (NULL == conn) {
453                 ERR("_bt_gdbus_get_system_gconn returned NULL");
454                 return BT_STATUS_FAIL;
455         }
456
457         _bt_hal_convert_addr_type_to_string(device_address,
458                         (unsigned char *)bd_addr->address);
459         device_path = _bt_hal_get_device_object_path(device_address);
460         if (device_path == NULL) {
461                 DBG("device_path NULL");
462                 ret =  BT_STATUS_FAIL;
463                 return ret;
464         }
465
466         ERR("device_path:%s", device_path);
467
468         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
469                         NULL, BT_HAL_BLUEZ_NAME,
470                         device_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
471         g_free(device_path);
472         if (NULL == device_proxy) {
473                 ERR("device_proxy returned NULL");
474                 return BT_STATUS_FAIL;
475         }
476
477         gattc_data = g_malloc0(sizeof(hal_gattc_client_info_t));
478         if (NULL == gattc_data) {
479                 ERR("Unable to allocate memory");
480                 ret = BT_STATUS_FAIL;
481                 goto fail;
482         }
483
484         memcpy(gattc_data->bd_addr.address, bd_addr->address,
485                         BT_HAL_ADDRESS_LENGTH_MAX);
486         gattc_data->client_if = client_if;
487         gattc_data->conn_id = conn_id;
488
489         DBG("DisconnectLE [%s]", device_address);
490
491         g_dbus_proxy_call(device_proxy, "DisconnectLE",
492                         NULL,
493                         G_DBUS_CALL_FLAGS_NONE,
494                         BT_HAL_MAX_DBUS_TIMEOUT,
495                         NULL,
496                         (GAsyncReadyCallback)__le_disconnection_req_cb, gattc_data);
497         return ret;
498 fail:
499         if (device_proxy)
500                 g_object_unref(device_proxy);
501
502         g_free(gattc_data);
503
504         return ret;
505 }
506
507 /** Disconnect a remote device or cancel a pending connection */
508 bt_status_t btif_gattc_client_disconnect(int client_if, const bt_bdaddr_t *bd_addr,
509                 int conn_id)
510 {
511         CHECK_BTGATT_INIT();
512
513         DBG("+");
514
515         return _hal_gattc_disconnect(client_if, bd_addr, conn_id);
516 }
517
518 /** Clear the attribute cache for a given device */
519 bt_status_t refresh(int client_if, const bt_bdaddr_t *bd_addr)
520 {
521         CHECK_BTGATT_INIT();
522         return BT_STATUS_UNSUPPORTED;
523 }
524
525 static hal_gattc_service_t* _gattc_find_service_from_uuid(hal_gattc_server_info_t *conn_info, bt_uuid_t *svc_uuid)
526 {
527         DBG("+");
528
529         GSList *l;
530         hal_gattc_service_t *info = NULL;
531
532         for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
533                 info = (hal_gattc_service_t*)l->data;
534                 if (info == NULL)
535                         continue;
536
537                 if (!memcmp(&info->svc_uuid, svc_uuid, sizeof(bt_uuid_t))) {
538                         INFO("Found GATT service uuid");
539                         return info;
540                 }
541         }
542         return NULL;
543 }
544
545
546 static hal_gattc_char_t* _gattc_find_char_from_uuid(hal_gattc_service_t *gattc_svc, bt_uuid_t *char_uuid)
547 {
548         DBG("+");
549
550         GSList *l;
551         hal_gattc_char_t *info = NULL;
552
553         for (l = gattc_svc->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
554                 info = (hal_gattc_char_t*)l->data;
555                 if (info == NULL)
556                         continue;
557
558                 if (!memcmp(&info->chr_uuid, char_uuid, sizeof(bt_uuid_t))) {
559                         INFO("Found GATT char uuid");
560                         return info;
561                 }
562         }
563         return NULL;
564 }
565
566 static hal_gattc_desc_t* _gattc_find_desc_from_uuid(hal_gattc_char_t *gattc_char, bt_uuid_t *desc_uuid)
567 {
568         DBG("+");
569
570         GSList *l;
571         hal_gattc_desc_t *info = NULL;
572
573         for (l = gattc_char->gatt_list_descs; l != NULL; l = g_slist_next(l)) {
574                 info = (hal_gattc_desc_t*)l->data;
575                 if (info == NULL)
576                         continue;
577
578                 if (!memcmp(&info->desc_uuid, desc_uuid, sizeof(bt_uuid_t))) {
579                         INFO("Found GATT descriptor uuid");
580                         return info;
581                 }
582         }
583         return NULL;
584 }
585
586
587 static hal_gattc_service_t* _hal_gatt_client_add_service(hal_gattc_server_info_t *conn_info,
588                 const char *uuid_str, char *object_path)
589 {
590         DBG("+");
591         hal_gattc_service_t *gattc_service = NULL;
592
593         gattc_service = g_malloc0(sizeof(hal_gattc_service_t));
594         gattc_service->svc_path = g_strdup(object_path);
595         _bt_hal_convert_uuid_string_to_type(gattc_service->svc_uuid.uu, uuid_str);
596
597         DBG("service count[%d]", g_slist_length(conn_info->gatt_list_services));
598
599         conn_info->gatt_list_services = g_slist_append(conn_info->gatt_list_services, gattc_service);
600
601         DBG("svc path {%s] svc uuid [%s]", object_path, uuid_str);
602
603         return gattc_service;
604 }
605
606 static void _hal_gattc_add_characteristic(hal_gattc_service_t *gatt_svc, char *char_handle)
607 {
608         DBG("+");
609         hal_gattc_char_t *gattc_char = NULL;
610
611         gattc_char = g_malloc0(sizeof(hal_gattc_char_t));
612         gattc_char->chr_path = g_strdup(char_handle);
613
614         DBG("svc path: [%s]", gatt_svc->svc_path);
615         DBG("char path: [%s]", gattc_char->chr_path);
616
617         gatt_svc->gatt_list_chars = g_slist_append(gatt_svc->gatt_list_chars, gattc_char);
618 }
619
620 static void _gattc_create_new_service(hal_gattc_server_info_t *conn_info, gboolean is_primary,
621                 const char* uuid_str, char *object_path, GPtrArray *gp_char_array)
622 {
623         hal_gattc_service_t* gatt_svc = NULL;
624         int i;
625         gchar *gp_char_path = NULL;
626
627         DBG("+");
628
629         /* add the service */
630         gatt_svc = _hal_gatt_client_add_service(conn_info, uuid_str, object_path);
631         if (gatt_svc == NULL) {
632                 ERR("Failed to add service");
633                 return;
634         }
635
636         /* add the characteristic */
637         for (i = 0; i < gp_char_array->len; i++) {
638                 gp_char_path = g_ptr_array_index(gp_char_array, i);
639                 _hal_gattc_add_characteristic(gatt_svc, gp_char_path);
640         }
641
642         g_ptr_array_free(gp_char_array, TRUE);
643 }
644
645 static void _hal_gattc_add_descriptor(hal_gattc_char_t *gattc_char, char *desc_path)
646 {
647         hal_gattc_desc_t *gattc_desc = NULL;
648
649         gattc_desc = g_malloc0(sizeof(hal_gattc_desc_t));
650         gattc_desc->desc_path = g_strdup(desc_path);
651
652         gattc_char->gatt_list_descs = g_slist_append(gattc_char->gatt_list_descs, gattc_desc);
653
654         DBG("char path: [%s]", gattc_char->chr_path);
655         DBG("desc path: [%s]", gattc_desc->desc_path);
656 }
657
658 static void _hal_gattc_update_char_property(hal_gattc_char_t *gattc_char, const char* char_uuid_str,
659                 GPtrArray *gp_desc_array, unsigned int char_permission)
660 {
661         gchar *gp_desc_path = NULL;
662         int i;
663
664         DBG("+");
665
666         if (char_uuid_str == NULL) {
667                 DBG("char_uuid_str is NULL");
668                 return;
669         }
670
671         //update the char uuid
672         DBG("char UUID: [%s] ", char_uuid_str);
673         DBG("char path: [%s]", gattc_char->chr_path);
674
675         _bt_hal_convert_uuid_string_to_type(gattc_char->chr_uuid.uu, char_uuid_str);
676
677         //update char permission
678         gattc_char->permission = char_permission;
679
680         //add the descriptor
681         for (i = 0; i < gp_desc_array->len; i++) {
682                 gp_desc_path = g_ptr_array_index(gp_desc_array, i);
683                 _hal_gattc_add_descriptor(gattc_char, gp_desc_path);
684         }
685 }
686
687 static void _hal_gattc_update_desc_property(hal_gattc_desc_t *gattc_desc, const char* desc_uuid_str)
688 {
689         DBG("+");
690
691         if (desc_uuid_str == NULL) {
692                 DBG("char_uuid_str is NULL");
693                 return;
694         }
695
696         //update the descriptor uuid
697         DBG("desc UUID: [%s] ", desc_uuid_str);
698         DBG("desc path: [%s]", gattc_desc->desc_path);
699
700         _bt_hal_convert_uuid_string_to_type(gattc_desc->desc_uuid.uu, desc_uuid_str);
701 }
702
703 static void browse_service_char(int conn_id)
704 {
705         hal_gattc_server_info_t *conn_info = NULL;
706         GSList *l;
707         GSList *k;
708         GSList *m;
709         hal_gattc_service_t *svc_info = NULL;
710         hal_gattc_char_t *char_info = NULL;
711         hal_gattc_desc_t *desc_info = NULL;
712
713         DBG("+");
714
715         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
716         if (conn_info == NULL) {
717                 DBG("conn_info is NULL");
718                 return;
719         }
720
721         DBG("service count[%d]", g_slist_length(conn_info->gatt_list_services));
722
723         for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
724                 svc_info = (hal_gattc_service_t*)l->data;
725                 if (svc_info == NULL)
726                         continue;
727
728                 DBG("svc path [%s]", svc_info->svc_path);
729
730                 /* find characteristic object path */
731                 for (k = svc_info->gatt_list_chars; k != NULL; k = g_slist_next(k)) {
732                         char_info = (hal_gattc_char_t *)k->data;
733                         if (char_info == NULL)
734                                 continue;
735
736                         DBG("char path[%s]", char_info->chr_path);
737
738                         /* descriptor */
739                         for (m = char_info->gatt_list_descs; m != NULL; m = g_slist_next(m)) {
740                                 desc_info = (hal_gattc_desc_t *)m->data;
741                                 if (desc_info == NULL)
742                                         continue;
743
744                                 DBG("desc path[%s]", desc_info->desc_path);
745                         }
746                 }
747         }
748 }
749
750
751
752 /**
753  * Enumerate all GATT services on a connected device.
754  * Optionally, the results can be filtered for a given UUID.
755  */
756 static bt_status_t _gattc_client_search_service(int conn_id)
757 {
758         CHECK_BTGATT_INIT();
759
760         GVariant *result = NULL;
761         GVariantIter *iter;
762         GVariantIter *svc_iter;
763         GVariantIter *interface_iter;
764         char *object_path = NULL;
765         char *interface_str = NULL;
766         const gchar *key = NULL;
767         GVariant *value = NULL;
768         GPtrArray *gp_array  = NULL;
769         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
770         char temp_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
771         int ret = BT_STATUS_FAIL;
772         int idx = 0;
773         const gchar *uuid_str = NULL;
774         gsize len = 0;
775         hal_gattc_server_info_t *conn_info = NULL;
776         gboolean is_primary = FALSE;
777         int svc_count = 0;
778
779         char *char_handle = NULL;
780         GVariantIter *char_iter = NULL;
781         GPtrArray *gp_char_array  = NULL;
782
783         DBG("+");
784
785         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
786         if (NULL == conn_info) {
787                 DBG("Failed to get the conn_info");
788                 return BT_STATUS_FAIL;
789         }
790
791         _bt_hal_convert_addr_type_to_string(device_address,
792                         (unsigned char *)conn_info->bd_addr.address);
793
794         result = _bt_hal_get_managed_objects();
795         if (result == NULL)
796                 return ret;
797
798         gp_array = g_ptr_array_new();
799         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
800
801         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
802                                 &interface_iter)) {
803                 if (object_path == NULL)
804                         continue;
805
806                 _bt_hal_convert_device_path_to_address(object_path, temp_address);
807
808                 if (g_strcmp0(temp_address, device_address) != 0)
809                         continue;
810
811                 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
812                                         &interface_str, &svc_iter)) {
813                         if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
814                                 continue;
815
816                         DBG("[%d] Object Path : %s", idx++, object_path);
817                         /* for characteristic */
818                         gp_char_array = g_ptr_array_new();
819                         while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
820                                 if (g_strcmp0(key, "Primary") == 0) {
821                                         is_primary = g_variant_get_boolean(value);
822                                         DBG("primary");
823                                         if (is_primary) {
824                                                 g_ptr_array_add(gp_array, (gpointer)object_path);
825                                                 svc_count++;
826                                         }
827                                 } else if (g_strcmp0(key, "UUID") == 0) {
828                                         uuid_str = g_variant_get_string(value, &len);
829                                         DBG(" UUID: [%s]", uuid_str);
830                                 } else if (g_strcmp0(key, "Characteristics") == 0) {
831                                         g_variant_get(value, "ao", &char_iter);
832                                         if (char_iter != NULL) {
833                                                 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
834                                                         DBG("char handle : %s", char_handle);
835                                                         g_ptr_array_add(gp_char_array, (gpointer)char_handle);
836                                                 }
837                                         }
838                                 }
839                         }
840
841                         if (uuid_str) {
842                                 DBG("send search service result event");
843                                 _bt_hal_send_search_service_result_event(conn_id, is_primary,
844                                                 uuid_str, conn_info->inst_id);
845
846                                 _gattc_create_new_service(conn_info, is_primary, uuid_str, object_path, gp_char_array);
847                         }
848                 }
849         }
850
851         if (gp_array->len == 0 || svc_count == 0) {
852                 ERR("gp_array is NULL");
853                 ret = BT_STATUS_FAIL;
854         } else {
855                 ret = BT_STATUS_SUCCESS;
856         }
857
858         browse_service_char(conn_id);
859         /* send search service complete event */
860         _bt_hal_send_search_service_complete_event(conn_id, ret);
861
862         g_ptr_array_free(gp_array, TRUE);
863         g_variant_iter_free(iter);
864         g_variant_unref(result);
865         DBG("-");
866         return ret;
867 }
868
869 bt_status_t btif_gattc_client_search_service(int conn_id, bt_uuid_t *filter_uuid)
870 {
871         if (NULL == filter_uuid) {
872                 DBG("Browse all the services");
873                 return _gattc_client_search_service(conn_id);
874         } else {
875                 DBG("TODO implement it");
876                 return BT_STATUS_UNSUPPORTED;
877         }
878 }
879 /**
880  * Enumerate included services for a given service.
881  * Set start_incl_srvc_id to NULL to get the first included service.
882  */
883 bt_status_t get_included_service(int conn_id, btgatt_srvc_id_t *srvc_id,
884                 btgatt_srvc_id_t *start_incl_srvc_id)
885 {
886         CHECK_BTGATT_INIT();
887         return BT_STATUS_UNSUPPORTED;
888 }
889
890 static void _bt_hal_send_client_char_search_result_event(int conn_id, int status,
891                 btgatt_srvc_id_t *svc_id, bt_uuid_t *char_uuid, int char_prop)
892 {
893         struct hal_ev_gatt_client_char_search_result  ev;
894
895          if (!event_cb) {
896                 ERR("gatt client callback not registered");
897                 return;
898         }
899
900         DBG("sending gatt client search char result event conn_id[%d] status[%d]", conn_id, status);
901
902         memset(&ev, 0, sizeof(ev));
903         ev.conn_id = conn_id;
904         ev.inst_id = svc_id->id.inst_id;
905         ev.is_primary = svc_id->is_primary;
906         ev.status = status;
907         memcpy(ev.svc_uuid, svc_id->id.uuid.uu, sizeof(ev.svc_uuid));
908
909         if (status == BT_STATUS_SUCCESS) {
910                 DBG("building char uuid");
911                 memcpy(ev.char_uuid, char_uuid->uu, sizeof(ev.char_uuid));
912                 ev.char_prop = char_prop;
913         }
914
915         DBG("sending the char search event");
916
917         event_cb(HAL_EV_GATT_CLIENT_CHARAC_SEARCH_RESULT, (void *)&ev, sizeof(ev));
918 }
919
920 static int _hal_get_permission_flag(char *permission)
921 {
922         int ret = 0;
923
924         if (NULL == permission) {
925                 ERR("gatt permission is NULL");
926                 return ret;
927         }
928
929         if (!g_strcmp0(permission, "broadcast"))
930                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
931         else if (!g_strcmp0(permission, "read"))
932                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_READ;
933         else if (!g_strcmp0(permission, "write-without-response"))
934                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
935         else if (!g_strcmp0(permission, "write"))
936                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE;
937         else if (!g_strcmp0(permission, "notify"))
938                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
939         else if (!g_strcmp0(permission, "indicate"))
940                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
941         else if (!g_strcmp0(permission, "authenticated-signed-writes"))
942                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
943         else if (!g_strcmp0(permission, "reliable-write"))
944                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
945         else if (!g_strcmp0(permission, "writable-auxiliaries"))
946                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
947         else if (!g_strcmp0(permission, "encrypt-read"))
948                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
949         else if (!g_strcmp0(permission, "encrypt-write"))
950                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
951         else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
952                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
953         else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
954                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
955
956         return ret;
957 }
958
959
960 static bt_status_t _hal_gattc_get_characteristic_info(hal_gattc_char_t *gattc_char)
961 {
962         GDBusProxy *properties_proxy = NULL;
963         GError *error = NULL;
964         GVariant *value = NULL;
965         GVariant *result = NULL;
966         GDBusConnection *g_conn;
967         const gchar *key;
968         char *char_desc_handle = NULL;
969         gsize len;
970         GVariantIter *property_iter;
971         GVariantIter *char_desc_iter;
972         char* char_handle = NULL;
973         const gchar *char_uuid_str = NULL;
974         GPtrArray *gp_desc_array  = NULL;
975         GVariantIter *char_perm_iter;
976         gchar* permission;
977         unsigned int char_permission = 0 ;
978
979         DBG("+");
980
981         if (gattc_char->chr_path == NULL) {
982                 DBG("char path is NULL");
983                  return BT_STATUS_FAIL;
984         }
985         char_handle = gattc_char->chr_path;
986
987         DBG("char path:[%s]", gattc_char->chr_path);
988
989         g_conn = _bt_hal_get_system_gconn();
990         if (NULL == g_conn) {
991                  ERR("_bt_gdbus_get_system_gconn returned NULL");
992                 return BT_STATUS_FAIL;
993         }
994
995         properties_proxy = g_dbus_proxy_new_sync(g_conn,
996                         G_DBUS_PROXY_FLAGS_NONE, NULL,
997                         BT_HAL_BLUEZ_NAME,
998                         char_handle,
999                         BT_HAL_PROPERTIES_INTERFACE,
1000                         NULL, &error);
1001
1002         if (properties_proxy == NULL) {
1003                 ERR("properties_proxy returned NULL");
1004                 return BT_STATUS_FAIL;
1005         }
1006
1007         result = g_dbus_proxy_call_sync(properties_proxy,
1008                         "GetAll",
1009                         g_variant_new("(s)", BT_HAL_GATT_CHAR_INTERFACE),
1010                         G_DBUS_CALL_FLAGS_NONE,
1011                         -1,
1012                         NULL,
1013                         &error);
1014         if (!result) {
1015                 if (error != NULL) {
1016                         ERR("Fail to get properties (Error: %s)", error->message);
1017                         g_clear_error(&error);
1018                 } else
1019                         ERR("Fail to get properties");
1020                 g_object_unref(properties_proxy);
1021                 return BT_STATUS_FAIL;
1022         }
1023
1024         gp_desc_array = g_ptr_array_new();
1025
1026         g_variant_get(result, "(a{sv})", &property_iter);
1027
1028         while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1029                 if (!g_strcmp0(key, "UUID")) {
1030                         char_uuid_str = g_variant_dup_string(value, &len);
1031                         DBG("char UUID [%s]", char_uuid_str);
1032                 } else if (!g_strcmp0(key, "Flags")) {
1033                         g_variant_get(value, "as", &char_perm_iter);
1034                                 char_permission = 0x00;
1035
1036                         while (g_variant_iter_loop(char_perm_iter, "s", &permission)) {
1037                                 DBG("char permission: [%s]", permission);
1038                                 char_permission |= _hal_get_permission_flag(permission);
1039                         }
1040                 } else if (!g_strcmp0(key, "Descriptors")) {
1041                         g_variant_get(value, "ao", &char_desc_iter);
1042                         while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle)) {
1043                                 DBG("char descriptor handle : %s", char_desc_handle);
1044
1045                                 g_ptr_array_add(gp_desc_array, (gpointer)char_desc_handle);
1046                         }
1047                 }
1048         }
1049
1050         _hal_gattc_update_char_property(gattc_char, char_uuid_str, gp_desc_array, char_permission);
1051
1052         g_variant_iter_free(property_iter);
1053         g_variant_unref(result);
1054         g_object_unref(properties_proxy);
1055         g_ptr_array_free(gp_desc_array, TRUE);
1056
1057         return BT_STATUS_SUCCESS;
1058 }
1059
1060 static bt_status_t _gattc_get_all_characteristic(int conn_id,
1061                 btgatt_srvc_id_t *srvc_id)
1062 {
1063         hal_gattc_server_info_t * conn_info = NULL;
1064         hal_gattc_service_t *gattc_service = NULL;
1065         GSList *l;
1066         hal_gattc_char_t *gattc_char = NULL;
1067         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1068         int status = BT_STATUS_FAIL;
1069
1070         DBG("+");
1071         DBG("conn_id[%d]", conn_id);
1072
1073         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1074         if (NULL == conn_info) {
1075                 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1076                 return BT_STATUS_FAIL;
1077         }
1078
1079         /* find service */
1080         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1081         if (NULL == gattc_service) {
1082                 DBG("Failed to get the gatt service");
1083                 return BT_STATUS_FAIL;
1084         }
1085
1086         DBG("service path [%s]", gattc_service->svc_path);
1087
1088         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1089         DBG("service uuid [%s]", svc_uuid_str);
1090
1091         /* find characteristic object path */
1092         for (l = gattc_service->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
1093                 gattc_char = (hal_gattc_char_t *)l->data;
1094                 status = _hal_gattc_get_characteristic_info(gattc_char);
1095
1096                 /* send event */
1097                 if (BT_STATUS_SUCCESS == status) {
1098                         DBG("Sending the success charateristics event");
1099                         _bt_hal_send_client_char_search_result_event(conn_id, status, srvc_id,
1100                                         &gattc_char->chr_uuid, gattc_char->permission);
1101                 }
1102         }
1103
1104         DBG("sending final event");
1105
1106         status = BT_STATUS_FAIL;
1107         _bt_hal_send_client_char_search_result_event(conn_id, status, srvc_id, NULL, 0);
1108
1109         browse_service_char(conn_id);
1110         /* retrive uuid for characteristic and object path for descriptor */
1111
1112         return BT_STATUS_SUCCESS;
1113 }
1114
1115 /**
1116  * Enumerate characteristics for a given service.
1117  * Set start_char_id to NULL to get the first characteristic.
1118  */
1119 bt_status_t btif_gattc_get_characteristic(int conn_id,
1120                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *start_char_id)
1121 {
1122         DBG("+");
1123         CHECK_BTGATT_INIT();
1124
1125         if (start_char_id == NULL) {
1126                 DBG("Get all the characteristics");
1127                 return _gattc_get_all_characteristic(conn_id, srvc_id);
1128
1129         } else {
1130                 DBG("TBD Get specific characteristics");
1131                 return BT_STATUS_UNSUPPORTED;
1132         }
1133 }
1134
1135 static bt_status_t _hal_gattc_get_descriptor_info(hal_gattc_desc_t *gattc_desc)
1136 {
1137         GDBusProxy *properties_proxy = NULL;
1138         GError *error = NULL;
1139         GVariant *value = NULL;
1140         GVariant *result = NULL;
1141         GDBusConnection *g_conn;
1142         const gchar *key;
1143         gsize len;
1144         GVariantIter *property_iter;
1145         char* desc_handle = NULL;
1146         const gchar *desc_uuid_str = NULL;
1147
1148         DBG("+");
1149
1150         if (gattc_desc->desc_path == NULL) {
1151                 DBG("desc path is NULL");
1152                 return BT_STATUS_FAIL;
1153         }
1154         desc_handle = gattc_desc->desc_path;
1155
1156         DBG("desc path:[%s]", gattc_desc->desc_path);
1157
1158         g_conn = _bt_hal_get_system_gconn();
1159         if (NULL == g_conn) {
1160                 ERR("_bt_gdbus_get_system_gconn returned NULL");
1161                 return BT_STATUS_FAIL;
1162         }
1163
1164         properties_proxy = g_dbus_proxy_new_sync(g_conn,
1165                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1166                         BT_HAL_BLUEZ_NAME,
1167                         desc_handle,
1168                         BT_HAL_PROPERTIES_INTERFACE,
1169                         NULL, &error);
1170
1171         if (properties_proxy == NULL) {
1172                 ERR("properties_proxy returned NULL");
1173                 return BT_STATUS_FAIL;
1174         }
1175
1176         result = g_dbus_proxy_call_sync(properties_proxy,
1177                         "GetAll",
1178                         g_variant_new("(s)", BT_HAL_GATT_DESC_INTERFACE),
1179                         G_DBUS_CALL_FLAGS_NONE,
1180                         -1,
1181                         NULL,
1182                         &error);
1183         if (!result) {
1184                 if (error != NULL) {
1185                         ERR("Fail to get properties (Error: %s)", error->message);
1186                         g_clear_error(&error);
1187                 } else
1188                         ERR("Fail to get properties");
1189                 g_object_unref(properties_proxy);
1190                 return BT_STATUS_FAIL;
1191         }
1192
1193         g_variant_get(result, "(a{sv})", &property_iter);
1194
1195         while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1196                 if (!g_strcmp0(key, "UUID")) {
1197                         desc_uuid_str = g_variant_dup_string(value, &len);
1198                         DBG("desc UUID [%s]", desc_uuid_str);
1199                 }
1200         }
1201
1202         _hal_gattc_update_desc_property(gattc_desc, desc_uuid_str);
1203
1204         g_variant_iter_free(property_iter);
1205         g_variant_unref(result);
1206         g_object_unref(properties_proxy);
1207
1208         return BT_STATUS_SUCCESS;
1209 }
1210
1211 static void _bt_hal_send_client_desc_search_result_event(int conn_id, int status,
1212                 btgatt_srvc_id_t *svc_id, btgatt_gatt_id_t *char_id, bt_uuid_t *desc_uuid)
1213 {
1214         struct hal_ev_gatt_client_desc_search_result  ev;
1215
1216         if (!event_cb) {
1217                 ERR("gatt client callback not registered");
1218                 return;
1219         }
1220
1221         DBG("sending gatt client search desc result event conn_id[%d] status[%d]", conn_id, status);
1222
1223         memset(&ev, 0, sizeof(ev));
1224         ev.conn_id = conn_id;
1225         ev.inst_id = svc_id->id.inst_id;
1226         ev.is_primary = svc_id->is_primary;
1227         ev.status = status;
1228
1229         memcpy(ev.svc_uuid, svc_id->id.uuid.uu, sizeof(ev.svc_uuid));
1230         memcpy(ev.char_uuid, char_id->uuid.uu, sizeof(ev.char_uuid));
1231
1232         if (status == BT_STATUS_SUCCESS) {
1233                 DBG("building desc uuid");
1234                 memcpy(ev.desc_uuid, desc_uuid->uu, sizeof(ev.desc_uuid));
1235         }
1236
1237         DBG("sending the desc search event");
1238
1239         event_cb(HAL_EV_GATT_CLIENT_DESC_SEARCH_RESULT, (void *)&ev, sizeof(ev));
1240 }
1241
1242 static bt_status_t _hal_gattc_get_all_descriptor(int conn_id,
1243                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id)
1244 {
1245         hal_gattc_server_info_t * conn_info = NULL;
1246         hal_gattc_service_t *gattc_service = NULL;
1247         GSList *l;
1248         hal_gattc_char_t *gattc_char = NULL;
1249         hal_gattc_desc_t *gattc_desc = NULL;
1250         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1251         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1252         int status = BT_STATUS_FAIL;
1253
1254         DBG("+");
1255
1256         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1257         if (NULL == conn_info) {
1258                 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1259                 return BT_STATUS_FAIL;
1260         }
1261
1262         /* find service */
1263         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1264         if (NULL == gattc_service) {
1265                 DBG("Failed to get the gatt service");
1266                 return BT_STATUS_FAIL;
1267         }
1268
1269         DBG("service path [%s]", gattc_service->svc_path);
1270         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1271         DBG("service uuid [%s]", svc_uuid_str);
1272
1273         /* find characteristics */
1274         gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1275         if (NULL == gattc_char) {
1276                 DBG("Failed to get the gatt char");
1277                 return BT_STATUS_FAIL;
1278         }
1279
1280         DBG("char path [%s]", gattc_char->chr_path);
1281         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1282         DBG("char uuid [%s]", char_uuid_str);
1283
1284         /* get descriptor uuid */
1285         for (l = gattc_char->gatt_list_descs; l != NULL; l = g_slist_next(l)) {
1286                 gattc_desc = (hal_gattc_desc_t *)l->data;
1287                 status = _hal_gattc_get_descriptor_info(gattc_desc);
1288
1289                 /* send event */
1290                 if (BT_STATUS_SUCCESS == status) {
1291                         DBG("Sending the success descriptor event");
1292                         _bt_hal_send_client_desc_search_result_event(conn_id, status, srvc_id,
1293                                         char_id, &gattc_desc->desc_uuid);
1294                 }
1295         }
1296
1297         DBG("sending final event");
1298
1299         status = BT_STATUS_FAIL;
1300         _bt_hal_send_client_desc_search_result_event(conn_id, status, srvc_id, char_id, NULL);
1301
1302         browse_service_char(conn_id);
1303         /* retrive uuid for characteristic and object path for descriptor */
1304
1305         return BT_STATUS_SUCCESS;
1306 }
1307
1308 /**
1309  * Enumerate descriptors for a given characteristic.
1310  * Set start_descr_id to NULL to get the first descriptor.
1311  */
1312 bt_status_t btif_gattc_get_descriptor(int conn_id,
1313                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1314                 btgatt_gatt_id_t *start_descr_id)
1315 {
1316         DBG("+");
1317         CHECK_BTGATT_INIT();
1318
1319         if (start_descr_id == NULL) {
1320                 DBG("Get all the descriptors");
1321                 return _hal_gattc_get_all_descriptor(conn_id, srvc_id, char_id);
1322         } else {
1323                 DBG("TBD Get specific descriptor");
1324                 return BT_STATUS_UNSUPPORTED;
1325         }
1326 }
1327
1328 static void __hal_send_char_read_event(hal_gatt_resp_data_t *resp_data, int result, uint8_t *value, int len)
1329 {
1330         struct hal_ev_gatt_client_read_data  ev;
1331
1332         if (!event_cb) {
1333                 ERR("gatt client callback not registered");
1334                 return;
1335         }
1336
1337         DBG("sending gatt client charac read conn_id[%d] status[%d]", resp_data->conn_id, result);
1338
1339         memset(&ev, 0, sizeof(ev));
1340         ev.conn_id = resp_data->conn_id;
1341         ev.inst_id = resp_data->srvc_id.id.inst_id;
1342         ev.is_primary = resp_data->srvc_id.is_primary;
1343         ev.status = result;
1344
1345         memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1346         memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1347
1348         ev.len = len;
1349         if (len > 0) {
1350                 DBG("building the char read value [%d]", len);
1351                 memcpy(ev.value, value, len);
1352         }
1353
1354         DBG("sending the gatt client read charac event");
1355
1356         event_cb(HAL_EV_GATT_CLIENT_READ_CHARAC, (void *)&ev, sizeof(ev));
1357 }
1358
1359 static void __hal_internal_read_char_cb(GObject *source_object,
1360                 GAsyncResult *res, gpointer user_data)
1361 {
1362         GError *error = NULL;
1363         GDBusConnection *system_gconn = NULL;
1364         GVariant *value;
1365         GVariantIter *iter;
1366         GByteArray *gp_byte_array = NULL;
1367         guint8 g_byte;
1368         hal_gatt_resp_data_t *resp_data = user_data;
1369         int result = BT_STATUS_SUCCESS;
1370         int i;
1371
1372         DBG("+");
1373
1374         system_gconn = _bt_hal_get_system_gconn();
1375         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1376
1377         if (error) {
1378                 ERR("Read Characteristic dbus failed Error:[%s]", error->message);
1379
1380                 //send failed event
1381                 result  = BT_STATUS_FAIL;
1382                 __hal_send_char_read_event(resp_data, result, NULL, 0);
1383                 g_clear_error(&error);
1384                 g_free(resp_data);
1385                 return;
1386         }
1387
1388         gp_byte_array = g_byte_array_new();
1389         g_variant_get(value, "(ay)", &iter);
1390
1391         while (g_variant_iter_loop(iter, "y", &g_byte))
1392                 g_byte_array_append(gp_byte_array, &g_byte, 1);
1393
1394         //print the value
1395         DBG("value is");
1396         for (i = 0; i < gp_byte_array->len; i++)
1397                 DBG("%02x", gp_byte_array->data[i]);
1398
1399         //send value  event
1400         __hal_send_char_read_event(resp_data, result, gp_byte_array->data, gp_byte_array->len);
1401
1402         g_free(resp_data);
1403
1404         g_byte_array_free(gp_byte_array, TRUE);
1405         g_variant_iter_free(iter);
1406         g_variant_unref(value);
1407
1408         DBG("-");
1409 }
1410
1411
1412 static bt_status_t _hal_read_characteristic_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1413                 btgatt_gatt_id_t *char_id, int auth_req)
1414 {
1415         GDBusConnection *g_conn;
1416         hal_gatt_resp_data_t *resp_data;
1417         hal_gattc_service_t *gattc_service = NULL;
1418         GVariantBuilder *builder = NULL;
1419         guint16 offset = 0;
1420         hal_gattc_server_info_t * conn_info = NULL;
1421         hal_gattc_char_t *gattc_char = NULL;
1422         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1423         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1424         char* char_handle = NULL;
1425
1426         DBG("+");
1427
1428         /* get the connection info */
1429         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1430         if (NULL == conn_info) {
1431                 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1432                 return BT_STATUS_FAIL;
1433         }
1434
1435         /* find service */
1436         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1437         if (NULL == gattc_service) {
1438                 DBG("Failed to get the gatt service");
1439                 return BT_STATUS_FAIL;
1440         }
1441
1442         DBG("service path [%s]", gattc_service->svc_path);
1443         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1444         DBG("service uuid [%s]", svc_uuid_str);
1445
1446
1447         /* find characteristic */
1448         gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1449         if (NULL == gattc_char) {
1450                 DBG("Failed to get the gatt char");
1451                 return BT_STATUS_FAIL;
1452         }
1453
1454         DBG("char path [%s]", gattc_char->chr_path);
1455         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1456         DBG("char uuid [%s]", char_uuid_str);
1457
1458         g_conn = _bt_hal_get_system_gconn();
1459         if (NULL == g_conn) {
1460                 ERR("_bt_gdbus_get_system_gconn returned NULL");
1461                 return BT_STATUS_FAIL;
1462         }
1463
1464         resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1465         if (NULL == resp_data) {
1466                 ERR("failed to get the memory");
1467                 return BT_STATUS_FAIL;
1468         }
1469
1470         resp_data->conn_id = conn_id;
1471         memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1472         memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1473
1474         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1475
1476         /*offset*/
1477         g_variant_builder_add(builder, "{sv}", "offset",
1478                         g_variant_new("q", offset));
1479
1480         char_handle = gattc_char->chr_path;
1481
1482         DBG("calling char read value");
1483
1484         g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, char_handle, BT_HAL_GATT_CHAR_INTERFACE,
1485                         "ReadValue", g_variant_new("(a{sv})", builder),
1486                         G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1487                         (GAsyncReadyCallback)__hal_internal_read_char_cb,
1488                         (gpointer)resp_data);
1489         g_variant_builder_unref(builder);
1490
1491         return BT_STATUS_SUCCESS;
1492 }
1493
1494 /** Read a characteristic on a remote device */
1495 bt_status_t btif_read_characteristic(int conn_id,
1496                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1497                 int auth_req)
1498 {
1499         CHECK_BTGATT_INIT();
1500         DBG("+");
1501
1502         return _hal_read_characteristic_value(conn_id, srvc_id, char_id, auth_req);
1503 }
1504
1505 static void __hal_send_char_write_event(hal_gatt_resp_data_t *resp_data, int result)
1506 {
1507         struct hal_ev_gatt_client_write_result  ev;
1508
1509          if (!event_cb) {
1510                 ERR("gatt client callback not registered");
1511                 return;
1512         }
1513
1514         DBG("sending gatt client charac write conn_id[%d] status[%d]", resp_data->conn_id, result);
1515
1516         memset(&ev, 0, sizeof(ev));
1517         ev.conn_id = resp_data->conn_id;
1518         ev.inst_id = resp_data->srvc_id.id.inst_id;
1519         ev.is_primary = resp_data->srvc_id.is_primary;
1520         ev.status = result;
1521
1522         memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1523         memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1524
1525         DBG("sending the gatt client write charac event");
1526
1527         event_cb(HAL_EV_GATT_CLIENT_WRITE_CHARAC, (void *)&ev, sizeof(ev));
1528 }
1529
1530 static void __hal_bluetooth_internal_write_cb(GObject *source_object,
1531                 GAsyncResult *res, gpointer user_data)
1532 {
1533         GError *error = NULL;
1534         GDBusConnection *system_gconn = NULL;
1535         GVariant *value;
1536         hal_gatt_resp_data_t *resp_data = user_data;
1537         int result = BT_STATUS_SUCCESS;
1538
1539         DBG("+");
1540
1541         system_gconn = _bt_hal_get_system_gconn();
1542         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1543
1544         if (error) {
1545                 ERR("write Characteristic dbus failed Error:[%s]", error->message);
1546
1547                 result  = BT_STATUS_FAIL;
1548                 //send failed event
1549                 __hal_send_char_write_event(resp_data, result);
1550                 g_clear_error(&error);
1551                 g_free(resp_data);
1552                 return;
1553         }
1554
1555         //send write value  event
1556         __hal_send_char_write_event(resp_data, result);
1557
1558         g_free(resp_data);
1559         g_variant_unref(value);
1560
1561         DBG("-");
1562 }
1563
1564 static bt_status_t __hal_get_write_prop(hal_gatt_write_type_t type, hal_gatt_property_e *prop)
1565 {
1566         switch (type) {
1567         case HAL_GATT_WRITE_TYPE_WRITE:
1568                 *prop = HAL_GATT_PROPERTY_WRITE;
1569                 break;
1570         case HAL_GATT_WRITE_TYPE_WRITE_NO_RESPONSE:
1571                 *prop = HAL_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE;
1572                 break;
1573         default:
1574                 ERR("Unknow write type : %d", type);
1575                 return BT_STATUS_FAIL;
1576         }
1577
1578         return BT_STATUS_SUCCESS;
1579 }
1580
1581 static bt_status_t _hal_write_characteristic_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1582                 btgatt_gatt_id_t *char_id, int write_type, int length, int auth_req, char* value)
1583 {
1584         GVariant *val, *options;
1585         GVariantBuilder *builder1;
1586         GVariantBuilder *builder2;
1587         GDBusConnection *g_conn;
1588         guint16 offset = 0;
1589         int i = 0;
1590         hal_gatt_resp_data_t  *resp_data;
1591         hal_gattc_service_t *gattc_service = NULL;
1592         hal_gattc_server_info_t * conn_info = NULL;
1593         hal_gattc_char_t *gattc_char = NULL;
1594         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1595         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1596         char* char_handle = NULL;
1597         hal_gatt_property_e write_prop = HAL_GATT_PROPERTY_WRITE;
1598         int ret = BT_STATUS_SUCCESS;
1599
1600         DBG("+");
1601
1602         ret = __hal_get_write_prop(write_type, &write_prop);
1603         if (BT_STATUS_FAIL == ret) {
1604                 DBG("received invalid  write type:[%d] ", write_type);
1605                 return BT_STATUS_FAIL;
1606         }
1607
1608         /* get the connection info */
1609         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1610         if (NULL == conn_info) {
1611                 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1612                 return BT_STATUS_FAIL;
1613         }
1614
1615         /* find service */
1616         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1617         if (NULL == gattc_service) {
1618                 DBG("Failed to get the gatt service");
1619                 return BT_STATUS_FAIL;
1620         }
1621
1622         DBG("service path [%s]", gattc_service->svc_path);
1623         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1624         DBG("service uuid [%s]", svc_uuid_str);
1625
1626         /* find characteristic */
1627         gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1628         if (NULL == gattc_char) {
1629                 DBG("Failed to get the gatt char");
1630                 return BT_STATUS_FAIL;
1631         }
1632
1633         DBG("char path [%s]", gattc_char->chr_path);
1634         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1635         DBG("char uuid [%s]", char_uuid_str);
1636
1637         g_conn = _bt_hal_get_system_gconn();
1638         if (NULL == g_conn) {
1639                  ERR("_bt_gdbus_get_system_gconn returned NULL");
1640                 return BT_STATUS_FAIL;
1641         }
1642
1643         resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1644         if (NULL == resp_data) {
1645                 ERR("failed to get the memory");
1646                 return BT_STATUS_FAIL;
1647         }
1648
1649         resp_data->conn_id = conn_id;
1650         memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1651         memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1652
1653         char_handle = gattc_char->chr_path;
1654
1655         builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1656
1657         for (i = 0; i < length; i++)
1658                 g_variant_builder_add(builder1, "y", value[i]);
1659
1660         val = g_variant_new("ay", builder1);
1661
1662         builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1663         /*offset*/
1664         g_variant_builder_add(builder2, "{sv}", "offset",
1665                         g_variant_new_uint16(offset));
1666
1667         options = g_variant_new("a{sv}", builder2);
1668
1669         g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, char_handle, BT_HAL_GATT_CHAR_INTERFACE,
1670                         "WriteValuebyType",
1671                         g_variant_new("(y@ay@a{sv})", write_prop, val, options),
1672                         NULL,
1673                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1674                         (GAsyncReadyCallback)__hal_bluetooth_internal_write_cb,
1675                         (gpointer)resp_data);
1676
1677         g_variant_builder_unref(builder1);
1678         g_variant_builder_unref(builder2);
1679
1680         return BT_STATUS_SUCCESS;
1681 }
1682
1683 /** Write a remote characteristic */
1684 bt_status_t btif_write_characteristic(int conn_id,
1685                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1686                 int write_type, int len, int auth_req,
1687                 char* p_value)
1688 {
1689         CHECK_BTGATT_INIT();
1690
1691         DBG("+");
1692
1693         DBG("svc isntance id:[%d]", srvc_id->id.inst_id);
1694         return _hal_write_characteristic_value(conn_id, srvc_id, char_id, write_type,
1695                                 len, auth_req, p_value);
1696 }
1697
1698 static void __hal_send_desc_read_event(hal_gatt_resp_data_t *resp_data, int result, uint8_t *value, int len)
1699 {
1700         struct hal_ev_gatt_client_read_data  ev;
1701
1702          if (!event_cb) {
1703                 ERR("gatt client callback not registered");
1704                 return;
1705         }
1706
1707         DBG("sending gatt client desc read conn_id[%d] status[%d]", resp_data->conn_id, result);
1708
1709         memset(&ev, 0, sizeof(ev));
1710         ev.conn_id = resp_data->conn_id;
1711         ev.inst_id = resp_data->srvc_id.id.inst_id;
1712         ev.is_primary = resp_data->srvc_id.is_primary;
1713         ev.status = result;
1714
1715         memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1716         memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1717         memcpy(ev.desc_uuid, resp_data->desc_id.uuid.uu, sizeof(ev.char_uuid));
1718
1719         ev.len = len;
1720         if (len > 0) {
1721                 DBG("building the desc read value [%d]", len);
1722                 memcpy(ev.value, value, len);
1723         }
1724
1725         DBG("sending the gatt client read descriptor event");
1726
1727         event_cb(HAL_EV_GATT_CLIENT_READ_DESC, (void *)&ev, sizeof(ev));
1728 }
1729
1730 static void __hal_internal_read_desc_cb(GObject *source_object,
1731                 GAsyncResult *res, gpointer user_data)
1732 {
1733         GError *error = NULL;
1734         GDBusConnection *system_gconn = NULL;
1735         GVariant *value;
1736         GVariantIter *iter;
1737         GByteArray *gp_byte_array = NULL;
1738         guint8 g_byte;
1739         hal_gatt_resp_data_t *resp_data = user_data;
1740         int result = BT_STATUS_SUCCESS;
1741         int i;
1742
1743         DBG("+");
1744
1745         system_gconn = _bt_hal_get_system_gconn();
1746         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1747
1748         if (error) {
1749                 ERR("Read descriptor dbus failed Error:[%s]", error->message);
1750
1751                 //send failed event
1752                 result  = BT_STATUS_FAIL;
1753                 __hal_send_desc_read_event(resp_data, result, NULL, 0);
1754                 g_clear_error(&error);
1755                 g_free(resp_data);
1756                 return;
1757         }
1758
1759         gp_byte_array = g_byte_array_new();
1760         g_variant_get(value, "(ay)", &iter);
1761
1762         while (g_variant_iter_loop(iter, "y", &g_byte))
1763                 g_byte_array_append(gp_byte_array, &g_byte, 1);
1764
1765         //print the value
1766         DBG("value is");
1767         for (i = 0; i < gp_byte_array->len; i++)
1768                 DBG("%02x", gp_byte_array->data[i]);
1769
1770         //send value  event
1771         __hal_send_desc_read_event(resp_data, result, gp_byte_array->data, gp_byte_array->len);
1772
1773         g_free(resp_data);
1774
1775         g_byte_array_free(gp_byte_array, TRUE);
1776         g_variant_iter_free(iter);
1777         g_variant_unref(value);
1778
1779         DBG("-");
1780 }
1781
1782 static bt_status_t _hal_read_descriptor_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1783                 btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *desc_id, int auth_req)
1784 {
1785         GDBusConnection *g_conn;
1786         hal_gatt_resp_data_t *resp_data;
1787         hal_gattc_service_t *gattc_service = NULL;
1788         GVariantBuilder *builder = NULL;
1789         guint16 offset = 0;
1790         hal_gattc_server_info_t * conn_info = NULL;
1791         hal_gattc_char_t *gattc_char = NULL;
1792         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1793         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1794         char desc_uuid_str[BT_HAL_UUID_STRING_LEN];
1795         char* desc_handle = NULL;
1796
1797         hal_gattc_desc_t *gattc_desc = NULL;
1798
1799         DBG("+");
1800
1801         /* get the connection info */
1802         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1803         if (NULL == conn_info) {
1804                 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1805                 return BT_STATUS_FAIL;
1806         }
1807
1808         /* find service */
1809         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1810         if (NULL == gattc_service) {
1811                 DBG("Failed to get the gatt service");
1812                 return BT_STATUS_FAIL;
1813         }
1814
1815         DBG("service path [%s]", gattc_service->svc_path);
1816         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1817         DBG("service uuid [%s]", svc_uuid_str);
1818
1819         /* find characteristic */
1820         gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1821         if (NULL == gattc_char) {
1822                 DBG("Failed to get the gatt char");
1823                 return BT_STATUS_FAIL;
1824         }
1825
1826         DBG("char path [%s]", gattc_char->chr_path);
1827         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1828         DBG("char uuid [%s]", char_uuid_str);
1829
1830         /* find descriptor */
1831         gattc_desc = _gattc_find_desc_from_uuid(gattc_char, &desc_id->uuid);
1832         if (NULL == gattc_desc) {
1833                 DBG("Failed to get the gatt desc");
1834                 return BT_STATUS_FAIL;
1835         }
1836
1837         DBG("desc path [%s]", gattc_desc->desc_path);
1838         _bt_hal_convert_uuid_type_to_string(desc_uuid_str, gattc_desc->desc_uuid.uu);
1839         DBG("desc uuid [%s]", desc_uuid_str);
1840
1841         g_conn = _bt_hal_get_system_gconn();
1842         if (NULL == g_conn) {
1843                  ERR("_bt_gdbus_get_system_gconn returned NULL");
1844                 return BT_STATUS_FAIL;
1845         }
1846
1847         resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1848         if (NULL == resp_data) {
1849                 ERR("failed to get the memory");
1850                 return BT_STATUS_FAIL;
1851         }
1852
1853         resp_data->conn_id = conn_id;
1854         memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1855         memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1856         memcpy(&resp_data->desc_id, desc_id, sizeof(btgatt_gatt_id_t));
1857
1858         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1859
1860         /*offset*/
1861         g_variant_builder_add(builder, "{sv}", "offset",
1862                         g_variant_new("q", offset));
1863
1864         desc_handle = gattc_desc->desc_path;
1865
1866         DBG("calling desc read value");
1867
1868         g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, desc_handle, BT_HAL_GATT_DESC_INTERFACE,
1869                         "ReadValue", g_variant_new("(a{sv})", builder),
1870                         G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1871                         (GAsyncReadyCallback)__hal_internal_read_desc_cb,
1872                         (gpointer)resp_data);
1873         g_variant_builder_unref(builder);
1874
1875         return BT_STATUS_SUCCESS;
1876 }
1877
1878 /** Read the descriptor for a given characteristic */
1879 bt_status_t btif_read_descriptor(int conn_id,
1880                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1881                 btgatt_gatt_id_t *descr_id, int auth_req)
1882 {
1883         CHECK_BTGATT_INIT();
1884
1885         return _hal_read_descriptor_value(conn_id, srvc_id, char_id, descr_id, auth_req);
1886 }
1887
1888 static void __hal_send_desc_write_event(hal_gatt_resp_data_t *resp_data, int result)
1889 {
1890         struct hal_ev_gatt_client_write_result  ev;
1891
1892          if (!event_cb) {
1893                 ERR("gatt client callback not registered");
1894                 return;
1895         }
1896
1897         DBG("sending gatt client charac write conn_id[%d] status[%d]", resp_data->conn_id, result);
1898
1899         memset(&ev, 0, sizeof(ev));
1900         ev.conn_id = resp_data->conn_id;
1901         ev.inst_id = resp_data->srvc_id.id.inst_id;
1902         ev.is_primary = resp_data->srvc_id.is_primary;
1903         ev.status = result;
1904
1905         memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1906         memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1907         memcpy(ev.desc_uuid, resp_data->desc_id.uuid.uu, sizeof(ev.desc_uuid));
1908
1909         DBG("sending the gatt client write charac event");
1910
1911         event_cb(HAL_EV_GATT_CLIENT_WRITE_DESC, (void *)&ev, sizeof(ev));
1912 }
1913
1914 static void __hal_bluetooth_internal_desc_write_cb(GObject *source_object,
1915                 GAsyncResult *res, gpointer user_data)
1916 {
1917         GError *error = NULL;
1918         GDBusConnection *system_gconn = NULL;
1919         GVariant *value;
1920         hal_gatt_resp_data_t *resp_data = user_data;
1921         int result = BT_STATUS_SUCCESS;
1922
1923         DBG("+");
1924
1925         system_gconn = _bt_hal_get_system_gconn();
1926         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1927
1928         if (error) {
1929                 ERR("write descriptor dbus failed Error: [%s]", error->message);
1930
1931                 //send failed event
1932                 result  = BT_STATUS_FAIL;
1933                 __hal_send_desc_write_event(resp_data, result);
1934                 g_clear_error(&error);
1935                 g_free(resp_data);
1936                 return;
1937         }
1938
1939         //send write value  event
1940         __hal_send_desc_write_event(resp_data, result);
1941
1942         g_free(resp_data);
1943         g_variant_unref(value);
1944
1945         DBG("-");
1946 }
1947
1948 static bt_status_t _hal_write_descriptor_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1949                                 btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *descr_id,
1950                                 int write_type, int length, int auth_req, char* value)
1951 {
1952         GVariant *val, *options;
1953         GVariantBuilder *builder1;
1954         GVariantBuilder *builder2;
1955         GDBusConnection *g_conn;
1956         guint16 offset = 0;
1957         int i = 0;
1958         hal_gatt_resp_data_t  *resp_data;
1959         hal_gattc_service_t *gattc_service = NULL;
1960         hal_gattc_server_info_t * conn_info = NULL;
1961         hal_gattc_char_t *gattc_char = NULL;
1962         hal_gattc_desc_t *gattc_desc = NULL;
1963         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1964         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1965         char desc_uuid_str[BT_HAL_UUID_STRING_LEN];
1966         char* desc_handle = NULL;
1967         hal_gatt_property_e write_prop = HAL_GATT_PROPERTY_WRITE;
1968         int ret = BT_STATUS_SUCCESS;
1969
1970         DBG("+");
1971
1972         ret = __hal_get_write_prop(write_type, &write_prop);
1973         if (BT_STATUS_FAIL == ret) {
1974                 DBG("received invalid  write type:[%d] ", write_type);
1975                 return BT_STATUS_FAIL;
1976         }
1977
1978         /* get the connection info */
1979         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1980         if (NULL == conn_info) {
1981                 DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
1982                 return BT_STATUS_FAIL;
1983         }
1984
1985         /* find service */
1986         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1987         if (NULL == gattc_service) {
1988                 DBG("Failed to get the gatt service");
1989                 return BT_STATUS_FAIL;
1990         }
1991
1992         DBG("service path [%s]", gattc_service->svc_path);
1993         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1994         DBG("service uuid [%s]", svc_uuid_str);
1995
1996         /* find characteristic */
1997         gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
1998         if (NULL == gattc_char) {
1999                 DBG("Failed to get the gatt char");
2000                 return BT_STATUS_FAIL;
2001         }
2002
2003         DBG("char path [%s]", gattc_char->chr_path);
2004         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2005         DBG("char uuid [%s]", char_uuid_str);
2006
2007         /* find descriptor */
2008         gattc_desc = _gattc_find_desc_from_uuid(gattc_char, &descr_id->uuid);
2009         if (NULL == gattc_desc) {
2010                 DBG("Failed to get the gatt char");
2011                 return BT_STATUS_FAIL;
2012         }
2013
2014         DBG("desc path [%s]", gattc_desc->desc_path);
2015         _bt_hal_convert_uuid_type_to_string(desc_uuid_str, gattc_desc->desc_uuid.uu);
2016         DBG("char uuid [%s]", desc_uuid_str);
2017
2018         g_conn = _bt_hal_get_system_gconn();
2019         if (NULL == g_conn) {
2020                  ERR("_bt_gdbus_get_system_gconn returned NULL");
2021                 return BT_STATUS_FAIL;
2022         }
2023
2024         resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
2025         if (NULL == resp_data) {
2026                 ERR("failed to get the memory");
2027                 return BT_STATUS_FAIL;
2028         }
2029
2030         resp_data->conn_id = conn_id;
2031         memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2032         memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2033         memcpy(&resp_data->desc_id, descr_id, sizeof(btgatt_gatt_id_t));
2034
2035         desc_handle = gattc_desc->desc_path;
2036
2037         builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2038
2039         for (i = 0; i < length; i++)
2040                 g_variant_builder_add(builder1, "y", value[i]);
2041
2042         val = g_variant_new("ay", builder1);
2043
2044         builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2045         /*offset*/
2046         g_variant_builder_add(builder2, "{sv}", "offset",
2047                         g_variant_new_uint16(offset));
2048
2049         options = g_variant_new("a{sv}", builder2);
2050
2051         g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, desc_handle, BT_HAL_GATT_DESC_INTERFACE,
2052                         "WriteValue",
2053                         g_variant_new("(@ay@a{sv})", val, options),
2054                         NULL,
2055                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2056                         (GAsyncReadyCallback)__hal_bluetooth_internal_desc_write_cb,
2057                         (gpointer)resp_data);
2058
2059         g_variant_builder_unref(builder1);
2060         g_variant_builder_unref(builder2);
2061
2062         return BT_STATUS_SUCCESS;
2063 }
2064
2065 /** Write a remote descriptor for a given characteristic */
2066 bt_status_t btif_write_descriptor(int conn_id,
2067                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
2068                 btgatt_gatt_id_t *descr_id, int write_type, int len,
2069                 int auth_req, char* p_value)
2070 {
2071         CHECK_BTGATT_INIT();
2072
2073         return _hal_write_descriptor_value(conn_id, srvc_id, char_id, descr_id, write_type,
2074                         len, auth_req, p_value);
2075 }
2076
2077 /** Execute a prepared write operation */
2078 bt_status_t execute_write(int conn_id, int execute)
2079 {
2080         CHECK_BTGATT_INIT();
2081         return BT_STATUS_UNSUPPORTED;
2082 }
2083
2084 static gboolean _hal_watch_register_notifi_cb(gpointer user_data)
2085 {
2086         struct hal_ev_gatt_client_watch_notification ev;
2087         hal_gatt_resp_data_t *resp_data = user_data;
2088
2089         DBG("sending the watch register notification event");
2090         /* send the event */
2091         memset(&ev, 0, sizeof(ev));
2092         ev.client_if = resp_data->conn_id; /* conn_id is saved with client_if */
2093         ev.registered = 1;
2094         ev.status = resp_data->result;
2095
2096         ev.is_primary = resp_data->srvc_id.is_primary;
2097         ev.inst_id = resp_data->srvc_id.id.inst_id;
2098
2099         memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
2100         memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
2101
2102         if (!event_cb)
2103                 ERR("GATT Callback not registered");
2104         else
2105                 event_cb(HAL_EV_GATT_CLIENT_WATCH_NOTIFICATION, (void *)&ev, sizeof(ev));
2106
2107         g_free(user_data);
2108
2109         return FALSE;
2110 }
2111
2112 static bt_status_t _hal_register_for_notification(int client_if,
2113                 bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2114                 btgatt_gatt_id_t *char_id)
2115 {
2116         int result = BT_STATUS_SUCCESS;
2117         GError *error = NULL;
2118         GDBusConnection *g_conn;
2119         hal_gattc_client_info_t *gattc_client = NULL;
2120         hal_gattc_server_info_t * conn_info = NULL;
2121         hal_gattc_service_t *gattc_service = NULL;
2122         hal_gattc_char_t *gattc_char = NULL;
2123         char* char_handle = NULL;
2124         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
2125         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
2126         hal_gatt_resp_data_t *resp_data;
2127
2128         DBG("+");
2129
2130         gattc_client = __bt_find_gatt_client_info(bd_addr);
2131         if (gattc_client == NULL) {
2132                 ERR("failed to get the gatt client info");
2133                 return BT_STATUS_FAIL;
2134         }
2135
2136         if (gattc_client->client_if != client_if) {
2137                 ERR("could not find the gatt client for client id[%d]", client_if);
2138                 return BT_STATUS_FAIL;
2139         }
2140
2141          /* get the connection info */
2142         conn_info = __bt_find_gatt_conn_info(bd_addr);
2143         if (NULL == conn_info) {
2144                 ERR("Failed to get the conn_info");
2145                 return BT_STATUS_FAIL;
2146         }
2147
2148         if (conn_info->inst_id != gattc_client->inst_id) {
2149                 ERR("could not fild the conn_info");
2150                 return BT_STATUS_FAIL;
2151         }
2152
2153         /* find service */
2154         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
2155         if (NULL == gattc_service) {
2156                 DBG("Failed to get the gatt service");
2157                 return BT_STATUS_FAIL;
2158         }
2159
2160         DBG("service path [%s]", gattc_service->svc_path);
2161         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
2162         DBG("service uuid [%s]", svc_uuid_str);
2163
2164
2165         /* find characteristic */
2166         gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
2167         if (NULL == gattc_char) {
2168                 DBG("Failed to get the gatt char");
2169                 return BT_STATUS_FAIL;
2170         }
2171
2172         DBG("char path [%s]", gattc_char->chr_path);
2173         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2174         DBG("char uuid [%s]", char_uuid_str);
2175
2176         char_handle = gattc_char->chr_path;
2177
2178         g_conn = _bt_hal_get_system_gconn();
2179         if (g_conn == NULL) {
2180                 ERR("conn NULL");
2181                 return BT_STATUS_FAIL;
2182         }
2183
2184         resp_data = malloc(sizeof(hal_gatt_resp_data_t));
2185         if (NULL == resp_data) {
2186                 ERR("failed to get the memory");
2187                 return BT_STATUS_FAIL;
2188         }
2189
2190         DBG("#StartNotify");
2191         g_dbus_connection_call_sync(g_conn,
2192                         BT_HAL_BLUEZ_NAME,
2193                         char_handle,
2194                         BT_HAL_GATT_CHAR_INTERFACE,
2195                         "StartNotify",
2196                         NULL,
2197                         NULL,
2198                         G_DBUS_CALL_FLAGS_NONE,
2199                         BT_HAL_MAX_DBUS_TIMEOUT, NULL, &error);
2200
2201         if (error) {
2202                 g_dbus_error_strip_remote_error(error);
2203                 ERR("### Watch Failed: %s", error->message);
2204                 if (g_strrstr(error->message, "Already notifying"))
2205                         result = BT_STATUS_SUCCESS;
2206                 else if (g_strrstr(error->message, "In Progress"))
2207                         result = BT_STATUS_BUSY;
2208                 else if (g_strrstr(error->message, "Operation is not supported"))
2209                         result = BT_STATUS_UNSUPPORTED;
2210                 /*failed because of either Insufficient Authorization or Write Not Permitted */
2211                 else if (g_strrstr(error->message, "Write not permitted") ||
2212                                 g_strrstr(error->message, "Operation Not Authorized"))
2213                         result = BT_STATUS_AUTH_FAILURE;
2214                 /* failed because of either Insufficient Authentication,
2215                    Insufficient Encryption Key Size, or Insufficient Encryption. */
2216                 else if (g_strrstr(error->message, "Not paired"))
2217                         result = BT_STATUS_NOT_READY;
2218                 else
2219                         result = BT_STATUS_FAIL;
2220
2221                 g_clear_error(&error);
2222         }
2223
2224         resp_data->conn_id = gattc_client->client_if; /* saving client_if instead of conn_id */
2225         resp_data->result = result;
2226         memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2227         memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2228
2229         g_idle_add(_hal_watch_register_notifi_cb, (gpointer)resp_data);
2230
2231         DBG("-");
2232
2233         return BT_STATUS_SUCCESS;
2234 }
2235
2236 /**
2237  * Register to receive notifications or indications for a given
2238  * characteristic
2239  */
2240 bt_status_t btif_register_for_notification(int client_if,
2241                 const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2242                 btgatt_gatt_id_t *char_id)
2243 {
2244         CHECK_BTGATT_INIT();
2245
2246         return _hal_register_for_notification(client_if, (bt_bdaddr_t *)bd_addr, srvc_id, char_id);
2247 }
2248
2249 static gboolean _hal_watch_deregister_notifi_cb(gpointer user_data)
2250 {
2251         struct hal_ev_gatt_client_watch_notification ev;
2252         hal_gatt_resp_data_t *resp_data = user_data;
2253
2254         DBG("sending the watch deregister notification event");
2255         /* send the event */
2256         memset(&ev, 0, sizeof(ev));
2257         ev.client_if = resp_data->conn_id; /* conn_id is saved with client_if */
2258         ev.registered = 0;
2259         ev.status = resp_data->result;
2260
2261         ev.is_primary = resp_data->srvc_id.is_primary;
2262         ev.inst_id = resp_data->srvc_id.id.inst_id;
2263
2264         memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
2265         memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
2266
2267         if (!event_cb)
2268                 ERR("GATT Callback not registered");
2269         else
2270                 event_cb(HAL_EV_GATT_CLIENT_WATCH_NOTIFICATION, (void *)&ev, sizeof(ev));
2271
2272         g_free(user_data);
2273
2274         return FALSE;
2275 }
2276
2277 static bt_status_t _hal_deregister_for_notification(int client_if,
2278                 bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2279                 btgatt_gatt_id_t *char_id)
2280 {
2281         int result = BT_STATUS_SUCCESS;
2282         GError *error = NULL;
2283         GDBusConnection *g_conn;
2284         hal_gattc_client_info_t *gattc_client = NULL;
2285         hal_gattc_server_info_t * conn_info = NULL;
2286         hal_gattc_service_t *gattc_service = NULL;
2287         hal_gattc_char_t *gattc_char = NULL;
2288         char* char_handle = NULL;
2289         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
2290         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
2291         hal_gatt_resp_data_t *resp_data;
2292
2293         DBG("+");
2294
2295         gattc_client = __bt_find_gatt_client_info(bd_addr);
2296         if (gattc_client == NULL) {
2297                 ERR("failed to get the gatt client info");
2298                 return BT_STATUS_FAIL;
2299         }
2300
2301         if (gattc_client->client_if != client_if) {
2302                 ERR("could not find the gatt client for client id[%d]", client_if);
2303                 return BT_STATUS_FAIL;
2304         }
2305
2306          /* get the connection info */
2307         conn_info = __bt_find_gatt_conn_info(bd_addr);
2308         if (NULL == conn_info) {
2309                 ERR("Failed to get the conn_info");
2310                 return BT_STATUS_FAIL;
2311         }
2312
2313         if (conn_info->inst_id != gattc_client->inst_id) {
2314                 ERR("could not fild the conn_info");
2315                 return BT_STATUS_FAIL;
2316         }
2317
2318         /* find service */
2319         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
2320         if (NULL == gattc_service) {
2321                 DBG("Failed to get the gatt service");
2322                 return BT_STATUS_FAIL;
2323         }
2324
2325         DBG("service path [%s]", gattc_service->svc_path);
2326         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
2327         DBG("service uuid [%s]", svc_uuid_str);
2328
2329
2330         /* find characteristic */
2331         gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid);
2332         if (NULL == gattc_char) {
2333                 DBG("Failed to get the gatt char");
2334                 return BT_STATUS_FAIL;
2335         }
2336
2337         DBG("char path [%s]", gattc_char->chr_path);
2338         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2339         DBG("char uuid [%s]", char_uuid_str);
2340
2341         char_handle = gattc_char->chr_path;
2342
2343         g_conn = _bt_hal_get_system_gconn();
2344         if (g_conn == NULL) {
2345                 ERR("conn NULL");
2346                 return BT_STATUS_FAIL;
2347         }
2348
2349         resp_data = malloc(sizeof(hal_gatt_resp_data_t));
2350         if (NULL == resp_data) {
2351                 ERR("failed to get the memory");
2352                 return BT_STATUS_FAIL;
2353         }
2354
2355         DBG("#StartNotify");
2356         g_dbus_connection_call_sync(g_conn,
2357                         BT_HAL_BLUEZ_NAME,
2358                         char_handle,
2359                         BT_HAL_GATT_CHAR_INTERFACE,
2360                         "StopNotify",
2361                         NULL,
2362                         NULL,
2363                         G_DBUS_CALL_FLAGS_NONE,
2364                         BT_HAL_MAX_DBUS_TIMEOUT, NULL, &error);
2365
2366         if (error) {
2367                 ERR("### Watch Failed: %s", error->message);
2368                 g_clear_error(&error);
2369                 result = BT_STATUS_FAIL;
2370         }
2371
2372         resp_data->conn_id = gattc_client->client_if; /* saving client_if instead of conn_id */
2373         resp_data->result = result;
2374         memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2375         memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2376
2377         g_idle_add(_hal_watch_deregister_notifi_cb, (gpointer)resp_data);
2378
2379         DBG("-");
2380
2381         return BT_STATUS_SUCCESS;
2382 }
2383 /** Deregister a previous request for notifications/indications */
2384 bt_status_t btif_deregister_for_notification(int client_if,
2385                 const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2386                 btgatt_gatt_id_t *char_id)
2387 {
2388         CHECK_BTGATT_INIT();
2389         return _hal_deregister_for_notification(client_if, (bt_bdaddr_t *)bd_addr, srvc_id, char_id);
2390 }
2391
2392 /** Request RSSI for a given remote device */
2393 bt_status_t read_remote_rssi(int client_if, const bt_bdaddr_t *bd_addr)
2394 {
2395         CHECK_BTGATT_INIT();
2396         return BT_STATUS_UNSUPPORTED;
2397 }
2398
2399 /** OTA firmware download */
2400 bt_status_t ota_fw_update(int client_if, int conn_id, const bt_bdaddr_t *bd_addr, char* path)
2401 {
2402         CHECK_BTGATT_INIT();
2403         return BT_STATUS_UNSUPPORTED;
2404 }
2405
2406 /** Determine the type of the remote device (LE, BR/EDR, Dual-mode) */
2407 int get_device_type(const bt_bdaddr_t *bd_addr)
2408 {
2409         CHECK_BTGATT_INIT();
2410         return BT_STATUS_UNSUPPORTED;
2411 }
2412
2413 static bt_status_t __hal_update_conn_parameter(bt_bdaddr_t *bd_addr,
2414                         int min_int, int max_int, int latency, int timeout)
2415 {
2416         gchar *device_path = NULL;
2417         GError *error = NULL;
2418         GDBusProxy *device_proxy = NULL;
2419         GDBusConnection *conn;
2420         GVariant *reply;
2421         int ret = BT_STATUS_SUCCESS;
2422         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
2423
2424         INFO("Min interval: %d, Max interval: %d, Latency: %d, Supervision timeout: %d",
2425                         min_int, max_int, latency, timeout);
2426
2427         conn = _bt_hal_get_system_gconn();
2428         if (conn == NULL) {
2429                 ERR("conn NULL");
2430                 return BT_STATUS_FAIL;
2431         }
2432
2433         _bt_hal_convert_addr_type_to_string(device_address,
2434                                 (unsigned char *)bd_addr->address);
2435         device_path = _bt_hal_get_device_object_path(device_address);
2436
2437         if (device_path == NULL) {
2438                 ERR("device_path NULL : [%s]", device_address);
2439                 return BT_STATUS_FAIL;
2440         }
2441
2442         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2443                         NULL, BT_HAL_BLUEZ_NAME,
2444                         device_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
2445
2446         g_free(device_path);
2447         if (NULL == device_proxy) {
2448                 ERR("device_proxy returned NULL");
2449                 return BT_STATUS_FAIL;
2450         }
2451
2452         INFO("### LeConnUpdate");
2453         reply = g_dbus_proxy_call_sync(device_proxy, "LeConnUpdate",
2454                         g_variant_new("(uuuu)", min_int, max_int, latency, timeout),
2455                         G_DBUS_CALL_FLAGS_NONE,
2456                         -1,
2457                         NULL,
2458                         &error);
2459
2460         g_object_unref(device_proxy);
2461         if (reply == NULL) {
2462                 if (error) {
2463                         ERR("Error %s[%s]", error->message, device_address);
2464                         if (g_strrstr(error->message, "In Progress"))
2465                                 ret = BT_STATUS_SUCCESS;
2466                         else
2467                                 ret = BT_STATUS_FAIL;
2468                         g_error_free(error);
2469                         return ret;
2470                 }
2471         }
2472         g_variant_unref(reply);
2473
2474         INFO("LE Connection parameter Updated");
2475         return ret;
2476 }
2477
2478 /** Request a connection parameter update */
2479 bt_status_t btif_gattc_conn_parameter_update(bt_bdaddr_t *bd, int min_int, int max_int, int latency, int timeout)
2480 {
2481         CHECK_BTGATT_INIT();
2482
2483         DBG("+");
2484
2485         return __hal_update_conn_parameter(bd, min_int, max_int, latency, timeout);
2486 }
2487
2488 /** Test mode interface */
2489 bt_status_t test_command(int command, btgatt_test_params_t* params)
2490 {
2491         CHECK_BTGATT_INIT();
2492         return BT_STATUS_UNSUPPORTED;
2493 }
2494
2495 /** MTU Exchange request from client */
2496 bt_status_t configure_mtu(int conn_id, int mtu)
2497 {
2498         CHECK_BTGATT_INIT();
2499         return BT_STATUS_UNSUPPORTED;
2500 }
2501
2502 /** Setup scan filter params */
2503 bt_status_t scan_filter_param_setup(int client_if, int action, int filt_index, int feat_seln,
2504                 int list_logic_type, int filt_logic_type, int rssi_high_thres,
2505                 int rssi_low_thres, int dely_mode, int found_timeout,
2506                 int lost_timeout, int found_timeout_cnt)
2507 {
2508         CHECK_BTGATT_INIT();
2509         return BT_STATUS_UNSUPPORTED;
2510 }
2511
2512 /** Configure a scan filter condition */
2513 bt_status_t scan_filter_add_remove(int client_if, int action, int filt_type,
2514                 int filt_index, int company_id,
2515                 int company_id_mask, const bt_uuid_t *p_uuid,
2516                 const bt_uuid_t *p_uuid_mask, const bt_bdaddr_t *bd_addr,
2517                 char addr_type, int data_len, char* p_data, int mask_len,
2518                 char* p_mask)
2519 {
2520         CHECK_BTGATT_INIT();
2521         return BT_STATUS_UNSUPPORTED;
2522 }
2523
2524 /** Clear all scan filter conditions for specific filter index*/
2525 bt_status_t scan_filter_clear(int client_if, int filt_index)
2526 {
2527         CHECK_BTGATT_INIT();
2528         return BT_STATUS_UNSUPPORTED;
2529 }
2530
2531 /** Enable / disable scan filter feature*/
2532 bt_status_t scan_filter_enable(int client_if, bool enable)
2533 {
2534         CHECK_BTGATT_INIT();
2535         return BT_STATUS_UNSUPPORTED;
2536 }
2537
2538 /** Sets the LE scan interval and window in units of N*0.625 msec */
2539 #ifdef TIZEN_BT_HAL
2540 bt_status_t set_scan_parameters(int scan_type, int scan_interval, int scan_window)
2541 {
2542         int ret;
2543
2544         CHECK_BTGATT_INIT();
2545
2546         le_scan_type = scan_type;
2547         ret = _bt_hal_adapter_le_set_scan_parameters(
2548                         scan_type, scan_interval, scan_window);
2549         return ret;
2550 }
2551 #else
2552 bt_status_t set_scan_parameters(int scan_interval, int scan_window)
2553 {
2554         CHECK_BTGATT_INIT();
2555         return BT_STATUS_UNSUPPORTED;
2556 }
2557 #endif
2558
2559 /* Configure the batchscan storage */
2560 bt_status_t batchscan_cfg_storage(int client_if, int batch_scan_full_max,
2561                 int batch_scan_trunc_max, int batch_scan_notify_threshold)
2562 {
2563         CHECK_BTGATT_INIT();
2564         return BT_STATUS_UNSUPPORTED;
2565 }
2566
2567 /* Enable batchscan */
2568 bt_status_t batchscan_enb_batch_scan(int client_if, int scan_mode,
2569                 int scan_interval, int scan_window, int addr_type, int discard_rule)
2570 {
2571         CHECK_BTGATT_INIT();
2572         return BT_STATUS_UNSUPPORTED;
2573 }
2574
2575 /* Disable batchscan */
2576 bt_status_t batchscan_dis_batch_scan(int client_if)
2577 {
2578         CHECK_BTGATT_INIT();
2579         return BT_STATUS_UNSUPPORTED;
2580 }
2581
2582 /* Read out batchscan reports */
2583 bt_status_t batchscan_read_reports(int client_if, int scan_mode)
2584 {
2585         CHECK_BTGATT_INIT();
2586         return BT_STATUS_UNSUPPORTED;
2587 }
2588
2589 const btgatt_client_interface_t btgatt_client_interface = {
2590         btif_gattc_register_client,
2591         btif_gattc_unregister_client,
2592         scan,
2593         btif_gattc_client_connect,
2594         btif_gattc_client_disconnect,
2595         refresh,
2596         btif_gattc_client_search_service,
2597         get_included_service,
2598         btif_gattc_get_characteristic,
2599         btif_gattc_get_descriptor,
2600         btif_read_characteristic,
2601         btif_write_characteristic,
2602         btif_read_descriptor,
2603         btif_write_descriptor,
2604         execute_write,
2605         btif_register_for_notification,
2606         btif_deregister_for_notification,
2607         read_remote_rssi,
2608         ota_fw_update,
2609         get_device_type,
2610         btif_gattc_conn_parameter_update,
2611         test_command,
2612         configure_mtu,
2613         scan_filter_param_setup,
2614         scan_filter_add_remove,
2615         scan_filter_clear,
2616         scan_filter_enable,
2617         set_scan_parameters,
2618         batchscan_cfg_storage,
2619         batchscan_enb_batch_scan,
2620         batchscan_dis_batch_scan,
2621         batchscan_read_reports
2622 };
2623
2624 static hal_gattc_server_info_t *__bt_find_gatt_conn_info(bt_bdaddr_t *serv_addr)
2625 {
2626         DBG("+");
2627
2628         GSList *l;
2629         hal_gattc_server_info_t *info = NULL;
2630
2631         for (l = hal_gattc_server_info_list; l != NULL; l = g_slist_next(l)) {
2632                 info = (hal_gattc_server_info_t*)l->data;
2633                 if (info == NULL)
2634                         continue;
2635
2636                 if (!memcmp(&info->bd_addr, serv_addr, sizeof(bt_bdaddr_t))) {
2637                         INFO("GATT connection found addr");
2638                         return info;
2639                 }
2640         }
2641         return NULL;
2642 }
2643
2644 static hal_gattc_client_info_t *__bt_find_gatt_client_info(bt_bdaddr_t *serv_addr)
2645 {
2646         DBG("+");
2647
2648         GSList *l;
2649         hal_gattc_client_info_t *info = NULL;
2650
2651         for (l = hal_gattc_client_info_list; l != NULL; l = g_slist_next(l)) {
2652                 info = (hal_gattc_client_info_t*)l->data;
2653                 if (info == NULL)
2654                         continue;
2655
2656                 if (!memcmp(&info->bd_addr, serv_addr, sizeof(bt_bdaddr_t))) {
2657                         INFO("GATT client info found addr");
2658                         return info;
2659                 }
2660         }
2661         return NULL;
2662 }
2663
2664 static hal_gattc_client_info_t *__bt_find_gatt_client_info_from_conn_id(int conn_id)
2665 {
2666         DBG("+");
2667
2668         GSList *l;
2669         hal_gattc_client_info_t *info = NULL;
2670
2671         for (l = hal_gattc_client_info_list; l != NULL; l = g_slist_next(l)) {
2672                 info = (hal_gattc_client_info_t*)l->data;
2673                 if (info == NULL)
2674                         continue;
2675
2676                 if (info->conn_id == conn_id) {
2677                         INFO("GATT client info found for conn_id [%d]", conn_id);
2678                         return info;
2679                 }
2680         }
2681         return NULL;
2682 }
2683
2684 static hal_gattc_server_info_t *__bt_find_gatt_conn_info_from_conn_id(int  conn_id)
2685 {
2686         DBG("+");
2687
2688         GSList *l;
2689         hal_gattc_server_info_t *info = NULL;
2690         hal_gattc_client_info_t *gattc_client = NULL;
2691
2692         gattc_client = __bt_find_gatt_client_info_from_conn_id(conn_id);
2693         if (gattc_client == NULL) {
2694                 INFO("GATT client conn info not found");
2695                 return NULL;
2696         }
2697
2698         for (l = hal_gattc_server_info_list; l != NULL; l = g_slist_next(l)) {
2699                 info = (hal_gattc_server_info_t*)l->data;
2700                 if (info == NULL)
2701                         continue;
2702
2703                 if ((info->inst_id == gattc_client->inst_id) &&
2704                         !memcmp(&info->bd_addr, &gattc_client->bd_addr, sizeof(bt_bdaddr_t))) {
2705                         INFO("GATT connection found for conn_id [%d]", conn_id);
2706                         return info;
2707                 }
2708         }
2709         return NULL;
2710 }
2711
2712 static bt_status_t __bt_connect_le_device_internal(int client_if, const bt_bdaddr_t *bd_addr,
2713                 gboolean auto_connect)
2714 {
2715         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
2716         gchar *device_path = NULL;
2717         GDBusProxy *device_proxy = NULL;
2718         GDBusConnection *conn;
2719         int ret = BT_STATUS_SUCCESS;
2720         hal_gattc_client_info_t *gattc_data;
2721
2722         DBG("+");
2723
2724         if (NULL == bd_addr) {
2725                 ERR("bd_addr is NULL");
2726                 return BT_STATUS_PARM_INVALID;
2727         }
2728
2729         conn = _bt_hal_get_system_gconn();
2730         if (NULL == conn) {
2731                 ERR("_bt_gdbus_get_system_gconn returned NULL");
2732                 return BT_STATUS_FAIL;
2733         }
2734
2735         _bt_hal_convert_addr_type_to_string(device_address,
2736                         (unsigned char *)bd_addr->address);
2737         device_path = _bt_hal_get_device_object_path(device_address);
2738         if (device_path == NULL) {
2739                 ERR("device_path NULL : [%s]", device_address);
2740                 ret = BT_STATUS_FAIL;
2741                 return ret;
2742         }
2743         ERR("device_path:%s", device_path);
2744
2745         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2746                         NULL, BT_HAL_BLUEZ_NAME,
2747                         device_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
2748         g_free(device_path);
2749         if (NULL == device_proxy) {
2750                 ERR("device_proxy returned NULL");
2751                 return BT_STATUS_FAIL;
2752         }
2753
2754         gattc_data = g_malloc0(sizeof(hal_gattc_client_info_t));
2755         if (gattc_data == NULL) {
2756                 ERR("Unable to allocate memory");
2757                 ret = BT_STATUS_NOMEM;
2758                 goto fail;
2759         }
2760         memcpy(gattc_data->bd_addr.address, bd_addr->address,
2761                                         BT_HAL_ADDRESS_LENGTH_MAX);
2762
2763         DBG("Connect LE [%s]", device_address);
2764
2765         gattc_data->client_if = client_if;
2766
2767         g_dbus_proxy_call(device_proxy, "ConnectLE",
2768                         g_variant_new("(b)", auto_connect),
2769                         G_DBUS_CALL_FLAGS_NONE,
2770                         BT_HAL_MAX_DBUS_TIMEOUT,
2771                         NULL,
2772                         (GAsyncReadyCallback)__le_connection_req_cb, gattc_data);
2773
2774         return ret;
2775
2776 fail:
2777         if (device_proxy)
2778                 g_object_unref(device_proxy);
2779
2780         g_free(gattc_data);
2781
2782         return ret;
2783 }
2784
2785 static bt_status_t _bt_hold_current_advertising()
2786 {
2787         int ret = BT_STATUS_FAIL;
2788         gboolean is_advertising = FALSE;
2789         DBG("+");
2790
2791         is_advertising = _bt_hal_is_advertising_in_slot(0);
2792         if (is_advertising) {
2793                 DBG("+ Stop current advertising");
2794
2795                 ret = _bt_hal_enable_advertising(0, FALSE, FALSE);
2796                 g_timeout_add(2000, __bt_hold_current_advertising_timeout_cb, NULL);
2797         }
2798
2799         return ret;
2800 }
2801
2802 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
2803 {
2804         DBG("+ start current advertising");
2805
2806         _bt_hal_enable_advertising(0, TRUE, FALSE);
2807
2808         return FALSE;
2809 }
2810
2811 static gboolean __bt_connect_le_timer_cb(gpointer user_data)
2812 {
2813         DBG("Try to initiate pending LE connection");
2814
2815         pending_le_conn_timer_id = 0;
2816
2817         __bt_connect_le_device_internal(pending_le_conn_info->client_if,
2818                         &pending_le_conn_info->bd_addr,
2819                         pending_le_conn_info->auto_connect);
2820
2821         g_free(pending_le_conn_info);
2822         pending_le_conn_info = NULL;
2823
2824         return FALSE;
2825 }
2826
2827 static int __hal_generate_conn_id()
2828 {
2829          return ++bt_conn_id;
2830 }
2831
2832 static int __hal_generate_server_instance_id()
2833 {
2834         return ++bt_inst_id;
2835 }
2836
2837 static void __le_connection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
2838                 gpointer user_data)
2839 {
2840         GError *g_error = NULL;
2841         GVariant *reply = NULL;
2842         hal_gattc_client_info_t *gattc_data  = user_data;
2843         int result = BT_STATUS_SUCCESS;
2844         struct hal_ev_gatt_client_connected ev;
2845         hal_gattc_server_info_t *gatt_conn_info = NULL;
2846
2847         DBG("+");
2848
2849         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
2850         g_object_unref(proxy);
2851         if (reply == NULL) {
2852                 ERR("Connect LE Dbus Call Error");
2853                 if (g_error) {
2854                         ERR("Error: %s\n", g_error->message);
2855                         g_clear_error(&g_error);
2856                 }
2857                 result = BT_STATUS_FAIL;
2858         }
2859         g_variant_unref(reply);
2860
2861         if (NULL == gattc_data) {
2862                 ERR("server_data is NULL");
2863                 return;
2864         }
2865
2866         /*send fail event*/
2867         if (result == BT_STATUS_FAIL) {
2868                 memset(&ev, 0, sizeof(ev));
2869                 ev.conn_id = -1;
2870                 ev.status = result;
2871                 ev.client_if = gattc_data->client_if;
2872                 memcpy(ev.bdaddr, gattc_data->bd_addr.address,
2873                                                 BT_HAL_ADDRESS_LENGTH_MAX);
2874
2875                 if (!event_cb) {
2876                         ERR("gatt client callback not registered");
2877                 } else {
2878                         DBG("sending gatt client connected event");
2879                         event_cb(HAL_EV_GATT_CLIENT_CONNECTED, (void *)&ev, sizeof(ev));
2880                 }
2881
2882                 goto fail;
2883         }
2884
2885         DBG("adding the server conn info in list");
2886         gattc_data->conn_id = __hal_generate_conn_id() ;
2887         gattc_data->inst_id = __hal_generate_server_instance_id();
2888
2889         hal_gattc_client_info_list = g_slist_append(hal_gattc_client_info_list, gattc_data);
2890
2891         /*add gatt server connection info*/
2892         gatt_conn_info = g_malloc0(sizeof(hal_gattc_server_info_t));
2893         if (gatt_conn_info == NULL) {
2894                 ERR("Failed to allocate memory");
2895                 goto fail;
2896         }
2897
2898         memcpy(gatt_conn_info->bd_addr.address, gattc_data->bd_addr.address, BT_HAL_ADDRESS_LENGTH_MAX);
2899         gatt_conn_info->inst_id = gattc_data->inst_id;
2900         hal_gattc_server_info_list = g_slist_append(hal_gattc_server_info_list, gatt_conn_info);
2901
2902         DBG("-");
2903         return;
2904
2905 fail:
2906         /*remove conn_info*/
2907         if (gattc_data)
2908                 g_free(gattc_data);
2909 }
2910
2911 void __hal_gattc_free_svc_info(hal_gattc_service_t *svc_info)
2912 {
2913         g_free(svc_info->svc_path);
2914         g_free(svc_info);
2915 }
2916
2917 void __hal_gattc_free_char_info(hal_gattc_char_t *char_info)
2918 {
2919         g_free(char_info->chr_path);
2920         g_free(char_info);
2921 }
2922
2923 void __hal_gattc_free_desc_info(hal_gattc_desc_t *desc_info)
2924 {
2925         g_free(desc_info->desc_path);
2926         g_free(desc_info);
2927 }
2928
2929 void __hal_clean_gattc_server_info(hal_gattc_server_info_t *conn_info)
2930 {
2931         GSList *l;
2932         GSList *m;
2933         GSList *k;
2934         hal_gattc_service_t *svc_info = NULL;
2935         hal_gattc_char_t *char_info = NULL;
2936         hal_gattc_desc_t *desc_info = NULL;
2937
2938         DBG("+");
2939
2940         for (l = conn_info->gatt_list_services; l != NULL;) {
2941                 svc_info = (hal_gattc_service_t*)l->data;
2942                 if (svc_info == NULL)
2943                         continue;
2944                 l = g_slist_next(l);
2945
2946                 for (m = svc_info->gatt_list_chars; m != NULL; ) {
2947                         char_info = (hal_gattc_char_t*)m->data;
2948                         if (char_info == NULL)
2949                                 continue;
2950                         m = g_slist_next(m);
2951
2952                         for (k = char_info->gatt_list_descs; k != NULL; ) {
2953                                 desc_info = (hal_gattc_desc_t*)k->data;
2954                                 if (desc_info == NULL)
2955                                         continue;
2956                                 k = g_slist_next(k);
2957
2958                                 /*remove desc element*/
2959                                 char_info->gatt_list_descs = g_slist_remove(char_info->gatt_list_descs, desc_info);
2960                                 __hal_gattc_free_desc_info(desc_info);
2961                         }
2962
2963                         /*remove desc list*/
2964                         g_slist_free(char_info->gatt_list_descs);
2965                         char_info->gatt_list_descs = NULL;
2966
2967                         /*remove char element*/
2968                         svc_info->gatt_list_chars = g_slist_remove(svc_info->gatt_list_chars, char_info);
2969                         __hal_gattc_free_char_info(char_info);
2970                 }
2971
2972                 /*remove char list*/
2973                 g_slist_free(svc_info->gatt_list_chars);
2974                 svc_info->gatt_list_chars = NULL;
2975
2976                 /*remove svc element*/
2977                 conn_info->gatt_list_services = g_slist_remove(conn_info->gatt_list_services, svc_info);
2978                 __hal_gattc_free_svc_info(svc_info);
2979         }
2980
2981         /*remove svc list */
2982         g_slist_free(conn_info->gatt_list_services);
2983         conn_info->gatt_list_services = NULL;
2984
2985         /*remove conn info*/
2986         g_free(conn_info);
2987 }
2988
2989 void _bt_hal_handle_gattc_connected_event(char* address, gboolean gatt_connected)
2990 {
2991         int result = BT_STATUS_SUCCESS;
2992         struct hal_ev_gatt_client_connected ev;
2993         hal_gattc_server_info_t *conn_info = NULL;
2994         bt_bdaddr_t bd_addr;
2995         int event;
2996         hal_gattc_client_info_t *gattc_client = NULL;
2997         int inst_id = -1;
2998
2999
3000         DBG("+ connected device address [%s]", address);
3001
3002         event = gatt_connected ? HAL_EV_GATT_CLIENT_CONNECTED :
3003                                 HAL_EV_GATT_CLIENT_DISCONNECTED;
3004
3005         _bt_hal_convert_addr_string_to_type(bd_addr.address, address);
3006         /* find the gatt client info */
3007         gattc_client = __bt_find_gatt_client_info(&bd_addr);
3008         if (NULL == gattc_client) {
3009                 ERR("Fail to get gatt client info");
3010                 return;
3011         }
3012
3013         //send event
3014         memset(&ev, 0, sizeof(ev));
3015         ev.conn_id = gattc_client->conn_id;
3016         ev.status = result;
3017         ev.client_if = gattc_client->client_if;
3018         memcpy(ev.bdaddr, gattc_client->bd_addr.address,
3019                                 BT_HAL_ADDRESS_LENGTH_MAX);
3020
3021         if (!event_cb) {
3022                 ERR("gatt client callback not registered");
3023         } else {
3024                 DBG("sending gatt client connected status  event");
3025                 event_cb(event, (void *)&ev, sizeof(ev));
3026         }
3027
3028         if (!gatt_connected) {
3029                 inst_id = gattc_client->inst_id;
3030
3031                 /* remove the gatt client info from the client list also*/
3032                 hal_gattc_client_info_list = g_slist_remove(hal_gattc_client_info_list, gattc_client);
3033                 g_free(gattc_client);
3034
3035                 //find the connected server info
3036                 conn_info = __bt_find_gatt_conn_info(&bd_addr);
3037                 if (NULL == conn_info) {
3038                         ERR("Fail to get gatt server info");
3039                         return;
3040                 }
3041
3042                 if (inst_id != conn_info->inst_id) {
3043                         ERR("server instance is different");
3044                         return;
3045                 }
3046
3047                 //remove gatt conn info from the server list
3048                 DBG("remove the server conn_info from list after gatt disconnection");
3049                 hal_gattc_server_info_list = g_slist_remove(hal_gattc_server_info_list, conn_info);
3050                 __hal_clean_gattc_server_info(conn_info);
3051         }
3052
3053         DBG("-");
3054 }
3055
3056 static void _bt_hal_send_search_service_result_event(int conn_id, int is_primary,
3057                                                 const char* uuid_str, int inst_id)
3058 {
3059         struct hal_ev_gatt_client_search_result ev;
3060
3061          if (!event_cb) {
3062                 ERR("gatt client callback not registered");
3063                 return;
3064         }
3065
3066         DBG("sending gatt client search service result event conn_id[%d]", conn_id);
3067
3068         memset(&ev, 0, sizeof(ev));
3069         ev.conn_id = conn_id;
3070         ev.inst_id = inst_id;
3071         ev.is_primary = is_primary;
3072         _bt_hal_convert_uuid_string_to_type(ev.uuid, uuid_str);
3073
3074         event_cb(HAL_EV_GATT_CLIENT_SEARCH_RESULT, (void *)&ev, sizeof(ev));
3075 }
3076
3077 static void _bt_hal_send_search_service_complete_event(int conn_id, int status)
3078 {
3079         struct hal_ev_gatt_client_search_complete ev;
3080
3081          if (!event_cb) {
3082                 ERR("gatt client callback not registered");
3083                 return;
3084         }
3085
3086         DBG("sending gatt client search service complete event conn_id[%d]", conn_id);
3087
3088
3089         memset(&ev, 0, sizeof(ev));
3090         ev.conn_id = conn_id;
3091         ev.status = status;
3092
3093         event_cb(HAL_EV_GATT_CLIENT_SEARCH_COMPLETE, (void *)&ev, sizeof(ev));
3094 }