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