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