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