7f9954c4479e53f8ed774b7a3726c789898a28d3
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-gatt-client.c
1 /*
2  * BLUETOOOTH HAL
3  *
4  * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Anupam Roy <anupam.r@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <hardware/bluetooth.h>
23 #include <hardware/bt_gatt.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <string.h>
28 #include <dlog.h>
29 #include <gio/gio.h>
30 #include <glib.h>
31 #include <gio/gunixfdlist.h>
32
33
34 #include "bt-hal-log.h"
35 #include "bt-hal-msg.h"
36 #include "bt-hal-event-receiver.h"
37 #include "bt-hal-adapter-le.h"
38
39 #include "bt-hal-gatt-client.h"
40 #include "bt-hal-dbus-common-utils.h"
41 #include "bt-hal-utils.h"
42
43 /************************************************************************************
44  **  Static variables
45  ************************************************************************************/
46 extern const btgatt_callbacks_t *bt_gatt_callbacks;
47 #define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
48 {\
49         ERR("%s: BTGATT not initialized", __FUNCTION__);\
50         return BT_STATUS_NOT_READY;\
51 } else {\
52         DBG("%s", __FUNCTION__);\
53 }
54
55 #ifdef TIZEN_BT_HAL
56 int le_scan_type = BT_GATTC_LE_SCAN_TYPE_PASSIVE;
57 #endif
58
59 static handle_stack_msg event_cb = NULL;
60
61 #define GATT_SERV_INTERFACE             "org.bluez.GattService1"
62 #define MAX_HAL_OBJECT_PATH_LEN         100
63
64 typedef enum {
65         HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST = 0x01,
66         HAL_GATT_CHARACTERISTIC_PROPERTY_READ = 0x02,
67         HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE = 0x04,
68         HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE = 0x08,
69         HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY = 0x10,
70         HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE = 0x20,
71         HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE = 0x40,
72         HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE = 0x80,
73         HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES = 0x100,
74         HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ = 0x200,
75         HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE = 0x400,
76         HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ = 0x800,
77         HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE = 0x1000,
78         HAL_GATT_CHARACTERISTIC_PROPERTY_EXTENDED_PROPS = 0xffff,
79 } bt_gatt_characteristic_property_t;
80
81
82 typedef enum {
83         HAL_GATT_WRITE_TYPE_WRITE_NO_RESPONSE = 1,
84         HAL_GATT_WRITE_TYPE_WRITE ,
85 } hal_gatt_write_type_t;
86
87
88 typedef enum {
89         HAL_GATT_PROPERTY_BROADCAST = 0x01,  /**< Broadcast property */
90         HAL_GATT_PROPERTY_READ = 0x02,  /**< Read property */
91         HAL_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE = 0x04,  /**< Write without response property */
92         HAL_GATT_PROPERTY_WRITE = 0x08,  /**< Write property */
93         HAL_GATT_PROPERTY_NOTIFY = 0x10,  /**< Notify property */
94         HAL_GATT_PROPERTY_INDICATE = 0x20,  /**< Indicate property */
95         HAL_GATT_PROPERTY_AUTHENTICATED_SIGNED_WRITES = 0x40,  /**< Authenticated signed writes property */
96         HAL_GATT_PROPERTY_EXTENDED_PROPERTIES = 0x80,  /**< Extended properties */
97 } hal_gatt_property_e;
98
99 typedef struct {
100         int client_if;
101         bt_bdaddr_t bd_addr;
102         gboolean auto_connect;
103 } bt_pending_le_conn_info_s;
104
105 typedef struct {
106         char *desc_path;
107         bt_uuid_t desc_uuid;
108 } hal_gattc_desc_t;
109
110 typedef struct {
111         char *chr_path;
112         bt_uuid_t chr_uuid;
113         unsigned int permission;
114         GSList *gatt_list_descs;
115 } hal_gattc_char_t;
116
117 typedef struct {
118         gchar *svc_path;
119         bt_uuid_t svc_uuid;
120         int is_primary;
121         GSList *gatt_list_chars;
122 } hal_gattc_service_t;
123
124 typedef struct {
125         bt_bdaddr_t bd_addr;    /*remote server address*/
126         int conn_id;
127         int inst_id;            /*server instance id*/
128         gboolean is_gatt_connected;             /*status for GattConnected signal*/
129         GSList *gatt_list_services;
130 } hal_gattc_server_info_t;
131
132 /* Linked List of connected GATT server */
133 static GSList *hal_gattc_server_info_list = NULL;
134
135 typedef struct {
136         int client_if;
137         bt_bdaddr_t bd_addr;    /*remote server address*/
138         int conn_id;
139         int inst_id;
140         gboolean is_gatt_connected;             /*status for GattConnected signal*/
141 } hal_gattc_client_info_t;
142
143 /* Linked list of connected GATT client connection */
144 static GSList * hal_gattc_client_info_list = NULL;
145
146 static bt_pending_le_conn_info_s *pending_le_conn_info = NULL;
147 static guint pending_le_conn_timer_id = 0;
148 int hal_gatt_conn_id = 0;
149 static int bt_inst_id = 0;
150
151 /* Should match the range with bt-service-gatt.c's MAX_APPS_SUPPORTED */
152 /* TODO: Adjust MAX Client after modifying MAX app handle logic */
153 #define BT_GATTC_CL_MAX 11
154
155 static int assigned_if = 0;
156 static gboolean client_if_used[BT_GATTC_CL_MAX];
157
158 typedef struct {
159         int conn_id;
160         int result;
161         btgatt_srvc_id_t srvc_id;
162         btgatt_gatt_id_t char_id;
163         btgatt_gatt_id_t desc_id;
164 } hal_gatt_resp_data_t;
165
166 typedef struct {
167         int client_if;
168         bt_uuid_t app_uuid;
169 } hal_gatt_client_app;
170
171 static GSList * hal_gattc_client_app_list = NULL;
172
173 struct conn_mtu_s {
174         int conn_id;
175         int mtu;
176 };
177
178 static bt_status_t __bt_connect_le_device_internal(int client_if, const bt_bdaddr_t *bd_addr,
179                 gboolean auto_connect);
180 static bt_status_t _bt_hold_current_advertising();
181 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data);
182 static gboolean __bt_connect_le_timer_cb(gpointer user_data);
183 static void __le_connection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
184                 gpointer user_data);
185 static hal_gattc_server_info_t *__bt_find_gatt_conn_info_from_conn_id(int  conn_id);
186 static void _bt_hal_send_search_service_result_event(int conn_id, int is_primary,
187                                                 const char* uuid_str, int inst_id);
188 static void _bt_hal_send_search_service_complete_event(int conn_id, int status);
189 static hal_gattc_server_info_t *__bt_find_gatt_conn_info(const bt_bdaddr_t *serv_addr);
190 static hal_gattc_client_info_t *__bt_find_gatt_client_info(bt_bdaddr_t *serv_addr);
191 static hal_gattc_client_info_t *__bt_find_gatt_client_info_from_conn_id(int conn_id);
192
193 void _bt_hal_gatt_client_init(void)
194 {
195         assigned_if = 0;
196         memset(client_if_used, 0x00, sizeof(client_if_used));
197 }
198
199 static int __bt_hal_gatt_assign_if(void)
200 {
201         int index;
202
203         index = assigned_if + 1;
204
205         if (index >= BT_GATTC_CL_MAX)
206                 index = 1;
207
208         while (client_if_used[index] == TRUE) {
209                 if (index == assigned_if) {
210                         /* No available ID */
211                         ERR("All interface ID is used");
212                         return -1;
213                 }
214
215                 index++;
216
217                 if (index >= BT_GATTC_CL_MAX)
218                         index = 1;
219         }
220
221         assigned_if = index;
222         client_if_used[index] = TRUE;
223
224         return assigned_if;
225 }
226
227 static void __bt_hal_gatt_delete_if(int client_if)
228 {
229         if (client_if >= BT_GATTC_CL_MAX || client_if < 0)
230                 return;
231
232         client_if_used[client_if] = FALSE;
233 }
234
235
236 /* To send stack event to hal-av handler */
237 void _bt_hal_register_gatt_client_handler_cb(handle_stack_msg cb)
238 {
239         event_cb = cb;
240 }
241
242 void _bt_hal_unregister_gatt_client_handler_cb(void)
243 {
244         event_cb = NULL;
245 }
246
247 #ifdef TIZEN_BT_HAL
248 int _bt_hal_gatt_client_get_le_scan_type(void)
249 {
250         return le_scan_type;
251 }
252 #endif
253
254 static gboolean __bt_hal_register_client_cb(gpointer user_data)
255 {
256         struct hal_ev_gatt_client_registered ev;
257         hal_gatt_client_app *client_info = user_data;
258
259         /* Prepare to send AV connecting event */
260         memset(&ev, 0, sizeof(ev));
261         ev.status = BT_STATUS_SUCCESS;
262         ev.client_if = client_info->client_if;
263         memcpy(ev.app_uuid, client_info->app_uuid.uu, sizeof(ev.app_uuid));
264
265         if (!event_cb)
266                 ERR("GATT Callback not registered");
267         else {
268                 DBG("GATT client registered, client_if: [%d]", client_info->client_if);
269                 event_cb(HAL_EV_GATT_CLIENT_REGISTERED, (void *)&ev, sizeof(ev));
270         }
271
272         g_free(user_data);
273         return FALSE;
274 }
275
276 static hal_gatt_client_app *__hal_gattc_add_client_app(bt_uuid_t *app_uuid)
277 {
278         GSList *l;
279         int client_if = 0;
280         hal_gatt_client_app *info = NULL;
281         hal_gatt_client_app *gattc_app = NULL;
282
283         //check if client app is already registered
284         for (l = hal_gattc_client_app_list; l != NULL; l = g_slist_next(l)) {
285                 info = (hal_gatt_client_app*)l->data;
286                 if (info == NULL)
287                         continue;
288
289                 if (memcmp(&info->app_uuid, app_uuid, sizeof(bt_uuid_t)) == 0) {
290                         DBG("gatt client app already registered");
291                         return info;
292                 }
293         }
294
295         client_if = __bt_hal_gatt_assign_if();
296         if (client_if == -1) {
297                 ERR("Fail to allocate the client if");
298                 return NULL;
299         }
300
301         DBG("adding the gatt client app");
302
303         //add client app
304         gattc_app = g_malloc0(sizeof(hal_gatt_client_app));
305         gattc_app->client_if = client_if;
306         memcpy(&gattc_app->app_uuid, app_uuid, sizeof(bt_uuid_t));
307
308         hal_gattc_client_app_list = g_slist_append(hal_gattc_client_app_list, gattc_app);
309
310         return gattc_app;
311 }
312
313 static bt_status_t __hal_gattc_register_client_app(bt_uuid_t *app_uuid)
314 {
315         hal_gatt_client_app *gattc_app = NULL;
316         hal_gatt_client_app *client_app_info = NULL;
317
318         /* add gatt client in list */
319         gattc_app = __hal_gattc_add_client_app(app_uuid);
320         if (gattc_app == NULL) {
321                 ERR("Failed to register gatt client app");
322                 return BT_STATUS_FAIL;
323         }
324
325         /*send event */
326         client_app_info = g_malloc0(sizeof(hal_gatt_client_app));
327         client_app_info->client_if = gattc_app->client_if;
328         memcpy(&client_app_info->app_uuid, app_uuid, sizeof(bt_uuid_t));
329         g_idle_add(__bt_hal_register_client_cb, (gpointer)client_app_info);
330
331         DBG("registered client client_if [%d]", client_app_info->client_if);
332
333         return BT_STATUS_SUCCESS;
334 }
335
336 /** Registers a GATT client application with the stack */
337 bt_status_t btif_gattc_register_client(bt_uuid_t *uuid)
338 {
339         CHECK_BTGATT_INIT();
340
341         return __hal_gattc_register_client_app(uuid);
342 }
343
344 bt_status_t btif_gattc_add_connection_info(const bt_bdaddr_t *bd_addr, int conn_id, int server_inst_id)
345 {
346         hal_gattc_client_info_t *client_info = NULL;
347         hal_gattc_server_info_t *server_info = NULL;
348
349         /* Add client connection info in list */
350         client_info = g_malloc0(sizeof(hal_gattc_client_info_t));
351         client_info->client_if = -1;
352         memcpy(client_info->bd_addr.address, bd_addr->address, BT_HAL_ADDRESS_LENGTH_MAX);
353         client_info->conn_id = conn_id;
354         client_info->inst_id = server_inst_id;
355         hal_gattc_client_info_list = g_slist_append(hal_gattc_client_info_list, client_info);
356         DBG("Added client connection info in list");
357
358         /* Add server connection info in list */
359         server_info = __bt_find_gatt_conn_info(bd_addr);
360         if (server_info == NULL) {
361                 server_info = g_malloc0(sizeof(hal_gattc_server_info_t));
362                 memcpy(server_info->bd_addr.address, bd_addr->address, BT_HAL_ADDRESS_LENGTH_MAX);
363                 server_info->conn_id = conn_id;
364                 server_info->inst_id = server_inst_id;
365                 server_info->is_gatt_connected = TRUE;
366                 hal_gattc_server_info_list = g_slist_append(hal_gattc_server_info_list, server_info);
367                 DBG("Added server connection info in list");
368         }
369
370         return BT_STATUS_SUCCESS;
371 }
372
373 bt_status_t __hal_gattc_unregister_client(int client_if)
374 {
375         GSList *l;
376         hal_gatt_client_app *info = NULL;
377         gboolean is_deleted = FALSE;
378         int client_count;
379
380         client_count =  g_slist_length(hal_gattc_client_app_list);
381
382         /* remove the gatt client app */
383         for (l = hal_gattc_client_app_list; l != NULL; ) {
384                 info = (hal_gatt_client_app*)l->data;
385                 l = g_slist_next(l);
386
387                 if (info == NULL)
388                         continue;
389
390                 if (info->client_if == client_if) {
391                         __bt_hal_gatt_delete_if(client_if);
392                         is_deleted = TRUE;
393                         hal_gattc_client_app_list = g_slist_remove(hal_gattc_client_app_list, info);
394                         g_free(info);
395                 }
396         }
397
398         if (is_deleted)
399                 DBG("Deleted. registered client count: [%d -> %d]", client_count, g_slist_length(hal_gattc_client_app_list));
400         else
401                 ERR("Not deleted. registered client count: [%d]", client_count);
402
403         return BT_STATUS_SUCCESS;
404 }
405
406 /** Unregister a client application from the stack */
407 bt_status_t btif_gattc_unregister_client(int client_if)
408 {
409         CHECK_BTGATT_INIT();
410
411         return __hal_gattc_unregister_client(client_if);
412 }
413
414 /** Start or stop LE device scanning */
415 bt_status_t scan(int client_if, bool start)
416 {
417         int ret;
418
419         CHECK_BTGATT_INIT();
420
421         if (start)
422                 ret = _bt_hal_adapter_le_start_scan();
423         else
424                 ret = _bt_hal_adapter_le_stop_scan();
425
426         return ret;
427 }
428
429 /** Create a connection to a remote LE or dual-mode device */
430 bt_status_t btif_gattc_client_connect(int client_if, const bt_bdaddr_t *bd_addr,
431                 bool is_direct)
432 {
433         int ret = BT_STATUS_SUCCESS;
434
435         CHECK_BTGATT_INIT();
436
437         if (NULL == bd_addr)
438                 return BT_STATUS_PARM_INVALID;
439
440         ret = _bt_hold_current_advertising();
441         if (ret == BT_STATUS_SUCCESS) {
442                 DBG("Current advertising is held");
443                 pending_le_conn_info = g_malloc0(sizeof(bt_pending_le_conn_info_s));
444                 pending_le_conn_info->client_if = client_if;
445                 memcpy(pending_le_conn_info->bd_addr.address, bd_addr->address,
446                                 BT_HAL_ADDRESS_LENGTH_MAX);
447                 pending_le_conn_info->auto_connect = is_direct;
448
449                 pending_le_conn_timer_id =
450                         g_timeout_add(1000, __bt_connect_le_timer_cb, NULL);
451
452                 return BT_STATUS_SUCCESS;
453         } else {
454                 ERR("advertising is not stopped");
455         }
456
457         return __bt_connect_le_device_internal(client_if, bd_addr, is_direct);
458 }
459
460
461 static void __le_disconnection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
462                 gpointer user_data)
463 {
464         GError *g_error = NULL;
465         GVariant *reply = NULL;
466         hal_gattc_client_info_t *gatt_conn_info  = user_data;
467         int result = BT_STATUS_SUCCESS;
468         struct hal_ev_gatt_client_connected ev;
469
470         DBG("+");
471
472         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
473         g_object_unref(proxy);
474         if (reply == NULL) {
475                 ERR("Connect LE Dbus Call Error");
476                 if (g_error) {
477                         ERR("Error: %s\n", g_error->message);
478                         g_clear_error(&g_error);
479                 }
480                 result = BT_STATUS_FAIL;
481         }
482         g_variant_unref(reply);
483
484         if (NULL == gatt_conn_info) {
485                 ERR("server_data is NULL");
486                 return;
487         }
488
489         /*send fail event*/
490         if (result == BT_STATUS_FAIL) {
491                 memset(&ev, 0, sizeof(ev));
492                 ev.conn_id = gatt_conn_info->conn_id;
493                 ev.status = result;
494                 ev.client_if = gatt_conn_info->client_if;
495                 memcpy(ev.bdaddr, gatt_conn_info->bd_addr.address,
496                                                 BT_HAL_ADDRESS_LENGTH_MAX);
497
498                 if (!event_cb) {
499                         ERR("gatt client callback not registered");
500                 } else {
501                         DBG("sending gatt client disconnected event");
502                         event_cb(HAL_EV_GATT_CLIENT_DISCONNECTED, (void *)&ev, sizeof(ev));
503                 }
504         }
505
506         /*remove conn_info*/
507         if (gatt_conn_info)
508                 g_free(gatt_conn_info);
509
510         DBG("-");
511 }
512
513 bt_status_t _hal_gattc_disconnect(int client_if, const bt_bdaddr_t *bd_addr,
514                         int conn_id)
515 {
516         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
517         gchar *device_path;
518         GDBusProxy *device_proxy;
519         GDBusConnection *conn;
520         int ret = BT_STATUS_SUCCESS;
521         hal_gattc_client_info_t *gattc_data;
522
523         if (NULL == bd_addr) {
524                 ERR("bd_addr is NULL");
525                 return BT_STATUS_PARM_INVALID;
526         }
527
528         conn = _bt_hal_get_system_gconn();
529         if (NULL == conn) {
530                 ERR("_bt_gdbus_get_system_gconn returned NULL");
531                 return BT_STATUS_FAIL;
532         }
533
534         _bt_hal_convert_addr_type_to_string(device_address,
535                         (unsigned char *)bd_addr->address);
536         device_path = _bt_hal_get_device_object_path(device_address);
537         if (device_path == NULL) {
538                 DBG("device_path NULL");
539                 ret =  BT_STATUS_FAIL;
540                 return ret;
541         }
542
543         ERR("device_path:%s", device_path);
544
545         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
546                         NULL, BT_HAL_BLUEZ_NAME,
547                         device_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
548         g_free(device_path);
549         if (NULL == device_proxy) {
550                 ERR("device_proxy returned NULL");
551                 return BT_STATUS_FAIL;
552         }
553
554         gattc_data = g_malloc0(sizeof(hal_gattc_client_info_t));
555         memcpy(gattc_data->bd_addr.address, bd_addr->address,
556                         BT_HAL_ADDRESS_LENGTH_MAX);
557         gattc_data->client_if = client_if;
558         gattc_data->conn_id = conn_id;
559
560         DBG("DisconnectLE [%s]", device_address);
561
562         g_dbus_proxy_call(device_proxy, "DisconnectLE",
563                         NULL,
564                         G_DBUS_CALL_FLAGS_NONE,
565                         BT_HAL_MAX_DBUS_TIMEOUT,
566                         NULL,
567                         (GAsyncReadyCallback)__le_disconnection_req_cb, gattc_data);
568         return ret;
569 }
570
571 /** Disconnect a remote device or cancel a pending connection */
572 bt_status_t btif_gattc_client_disconnect(int client_if, const bt_bdaddr_t *bd_addr,
573                 int conn_id)
574 {
575         CHECK_BTGATT_INIT();
576
577         return _hal_gattc_disconnect(client_if, bd_addr, conn_id);
578 }
579
580 /** Clear the attribute cache for a given device */
581 bt_status_t refresh(int client_if, const bt_bdaddr_t *bd_addr)
582 {
583         CHECK_BTGATT_INIT();
584         return BT_STATUS_UNSUPPORTED;
585 }
586
587 static hal_gattc_service_t* _gattc_find_service_from_uuid(hal_gattc_server_info_t *conn_info, bt_uuid_t *svc_uuid)
588 {
589         GSList *l;
590         hal_gattc_service_t *info = NULL;
591
592         for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
593                 info = (hal_gattc_service_t*)l->data;
594                 if (info == NULL)
595                         continue;
596
597                 if (!memcmp(&info->svc_uuid, svc_uuid, sizeof(bt_uuid_t)))
598                         return info;
599         }
600
601         return NULL;
602 }
603
604
605 static hal_gattc_char_t* _gattc_find_char_from_uuid(hal_gattc_service_t *gattc_svc, bt_uuid_t *char_uuid,
606                                 bt_gatt_characteristic_property_t prop)
607 {
608         GSList *l;
609         hal_gattc_char_t *info = NULL;
610
611         for (l = gattc_svc->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
612                 info = (hal_gattc_char_t*)l->data;
613                 if (info == NULL)
614                         continue;
615
616                 if (!memcmp(&info->chr_uuid, char_uuid, sizeof(bt_uuid_t)) &&
617                         (info->permission & prop)) {
618                         return info;
619                 }
620         }
621         return NULL;
622 }
623
624 static hal_gattc_char_t* _gattc_find_char_from_uuid_for_notify(hal_gattc_service_t *gattc_svc, bt_uuid_t *char_uuid)
625 {
626         GSList *l;
627         hal_gattc_char_t *info = NULL;
628
629         for (l = gattc_svc->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
630                 info = (hal_gattc_char_t*)l->data;
631                 if (info == NULL)
632                         continue;
633
634                 if (!memcmp(&info->chr_uuid, char_uuid, sizeof(bt_uuid_t)) &&
635                         ((info->permission & HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) ||
636                                 (info->permission & HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE))) {
637                         return info;
638                 }
639         }
640         return NULL;
641 }
642
643 static hal_gattc_desc_t* _gattc_find_desc_from_uuid(hal_gattc_char_t *gattc_char, bt_uuid_t *desc_uuid)
644 {
645         GSList *l;
646         hal_gattc_desc_t *info = NULL;
647
648         for (l = gattc_char->gatt_list_descs; l != NULL; l = g_slist_next(l)) {
649                 info = (hal_gattc_desc_t*)l->data;
650                 if (info == NULL)
651                         continue;
652
653                 if (!memcmp(&info->desc_uuid, desc_uuid, sizeof(bt_uuid_t)))
654                         return info;
655         }
656         return NULL;
657 }
658
659
660 static hal_gattc_service_t* _hal_gatt_client_add_service(hal_gattc_server_info_t *conn_info,
661                 const char *uuid_str, const char *object_path, int is_primary)
662 {
663         hal_gattc_service_t *gattc_service = NULL;
664
665         gattc_service = g_malloc0(sizeof(hal_gattc_service_t));
666         gattc_service->svc_path = g_strdup(object_path);
667         _bt_hal_convert_uuid_string_to_type(gattc_service->svc_uuid.uu, uuid_str);
668         gattc_service->is_primary = is_primary;
669
670         conn_info->gatt_list_services = g_slist_append(conn_info->gatt_list_services, gattc_service);
671         INFO("Total svc [%d] Added [%s] [%s]", g_slist_length(conn_info->gatt_list_services), object_path + 15, uuid_str);
672
673         return gattc_service;
674 }
675
676 static void _hal_gattc_add_characteristic(hal_gattc_service_t *gatt_svc, char *char_handle)
677 {
678         hal_gattc_char_t *gattc_char = NULL;
679
680         gattc_char = g_malloc0(sizeof(hal_gattc_char_t));
681         gattc_char->chr_path = g_strdup(char_handle);
682
683         DBG("[%s]", gattc_char->chr_path + 15);
684
685         gatt_svc->gatt_list_chars = g_slist_append(gatt_svc->gatt_list_chars, gattc_char);
686 }
687
688 static void _gattc_create_new_service(hal_gattc_server_info_t *conn_info, gboolean is_primary,
689                 const char* uuid_str, const char *object_path, GPtrArray *gp_char_array)
690 {
691         hal_gattc_service_t* gatt_svc = NULL;
692         int i;
693         gchar *gp_char_path = NULL;
694         uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
695
696         _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
697         gatt_svc = _gattc_find_service_from_uuid(conn_info, (bt_uuid_t *)uuid);
698         if (gatt_svc) {
699                 DBG("Aleady added to gatt_list_services");
700                 return;
701         }
702
703         /* add the service */
704         gatt_svc = _hal_gatt_client_add_service(conn_info, uuid_str, object_path, is_primary);
705         if (gatt_svc == NULL) {
706                 ERR("Failed to add service");
707                 return;
708         }
709
710         /* add the characteristic */
711         for (i = 0; i < gp_char_array->len; i++) {
712                 gp_char_path = g_ptr_array_index(gp_char_array, i);
713                 _hal_gattc_add_characteristic(gatt_svc, gp_char_path);
714         }
715
716         g_ptr_array_free(gp_char_array, TRUE);
717 }
718
719 static void _hal_gattc_add_descriptor(hal_gattc_char_t *gattc_char, char *desc_path)
720 {
721         hal_gattc_desc_t *gattc_desc = NULL;
722
723         gattc_desc = g_malloc0(sizeof(hal_gattc_desc_t));
724         gattc_desc->desc_path = g_strdup(desc_path);
725
726         gattc_char->gatt_list_descs = g_slist_append(gattc_char->gatt_list_descs, gattc_desc);
727 }
728
729 static void _hal_gattc_update_char_property(hal_gattc_char_t *gattc_char, const char* char_uuid_str,
730                 GPtrArray *gp_desc_array, unsigned int char_permission)
731 {
732         gchar *gp_desc_path = NULL;
733         int i;
734
735         if (char_uuid_str == NULL) {
736                 DBG("char_uuid_str is NULL");
737                 return;
738         }
739
740         //update the char uuid
741         _bt_hal_convert_uuid_string_to_type(gattc_char->chr_uuid.uu, char_uuid_str);
742
743         //update char permission
744         gattc_char->permission = char_permission;
745
746         //add the descriptor
747         for (i = 0; i < gp_desc_array->len; i++) {
748                 gp_desc_path = g_ptr_array_index(gp_desc_array, i);
749                 _hal_gattc_add_descriptor(gattc_char, gp_desc_path);
750         }
751 }
752
753 static void _hal_gattc_update_desc_property(hal_gattc_desc_t *gattc_desc, const char* desc_uuid_str)
754 {
755         if (desc_uuid_str == NULL) {
756                 DBG("char_uuid_str is NULL");
757                 return;
758         }
759
760         //update the descriptor uuid
761         DBG("%s %s",  gattc_desc->desc_path + 37, desc_uuid_str);
762
763         _bt_hal_convert_uuid_string_to_type(gattc_desc->desc_uuid.uu, desc_uuid_str);
764 }
765
766 static void browse_service_char(int conn_id)
767 {
768         hal_gattc_server_info_t *conn_info = NULL;
769         GSList *l;
770         GSList *k;
771         GSList *m;
772         hal_gattc_service_t *svc_info = NULL;
773         hal_gattc_char_t *char_info = NULL;
774         hal_gattc_desc_t *desc_info = NULL;
775
776         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
777         if (conn_info == NULL) {
778                 ERR("Failed to get the conn_info for conn_id [%d]", conn_id);
779                 return;
780         }
781
782         for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
783                 svc_info = (hal_gattc_service_t*)l->data;
784                 if (svc_info == NULL)
785                         continue;
786
787                 /* find characteristic object path */
788                 for (k = svc_info->gatt_list_chars; k != NULL; k = g_slist_next(k)) {
789                         char_info = (hal_gattc_char_t *)k->data;
790                         if (char_info == NULL)
791                                 continue;
792
793                         /* descriptor */
794                         for (m = char_info->gatt_list_descs; m != NULL; m = g_slist_next(m)) {
795                                 desc_info = (hal_gattc_desc_t *)m->data;
796                                 if (desc_info == NULL)
797                                         continue;
798                         }
799                 }
800         }
801 }
802
803
804
805 /**
806  * Enumerate all GATT services on a connected device.
807  * Optionally, the results can be filtered for a given UUID.
808  */
809 static bt_status_t _gattc_client_search_service(int conn_id)
810 {
811         CHECK_BTGATT_INIT();
812
813         GVariant *result = NULL;
814         GVariantIter *iter;
815         GVariantIter *svc_iter;
816         GVariantIter *interface_iter;
817         char *object_path = NULL;
818         char *interface_str = NULL;
819         const gchar *key = NULL;
820         GVariant *value = NULL;
821         GPtrArray *gp_array  = NULL;
822         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
823         char temp_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
824         int ret = BT_STATUS_FAIL;
825         int idx = 0;
826         const gchar *uuid_str = NULL;
827         gsize len = 0;
828         hal_gattc_server_info_t *conn_info = NULL;
829         gboolean is_primary = FALSE;
830         int svc_count = 0;
831
832         char *char_handle = NULL;
833         GVariantIter *char_iter = NULL;
834         GPtrArray *gp_char_array  = NULL;
835
836         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
837         if (NULL == conn_info) {
838                 ERR("Failed to get the conn_info for conn_id [%d]", conn_id);
839                 return BT_STATUS_FAIL;
840         }
841
842 #if 0
843         // TODO: This logic is not able to handle in case service-added event is coming unexpectedly.
844         /* Check the service info is stored */
845         if (g_slist_length(conn_info->gatt_list_services) > 0) {
846                 GSList *l = NULL;
847                 hal_gattc_service_t *svc_info = NULL;
848                 char svc_uuid_str[BT_HAL_UUID_STRING_LEN] = {0, };
849                 DBG("Send event from service info list");
850                 for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
851                         svc_info = l->data;
852                         if (svc_info == NULL)
853                                 continue;
854                         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, svc_info->svc_uuid.uu);
855                         _bt_hal_send_search_service_result_event(conn_id,
856                                         svc_info->is_primary, svc_uuid_str, conn_info->inst_id);
857                 }
858                 _bt_hal_send_search_service_complete_event(conn_id, BT_STATUS_SUCCESS);
859                 return BT_STATUS_SUCCESS;
860         } else {
861                 DBG("No stored service, request to bluez");
862         }
863 #endif
864
865         _bt_hal_convert_addr_type_to_string(device_address,
866                         (unsigned char *)conn_info->bd_addr.address);
867
868         result = _bt_hal_get_managed_objects();
869         if (result == NULL)
870                 return ret;
871
872         gp_array = g_ptr_array_new();
873         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
874
875         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
876                                 &interface_iter)) {
877                 if (object_path == NULL)
878                         continue;
879
880                 _bt_hal_convert_device_path_to_address(object_path, temp_address);
881
882                 if (g_strcmp0(temp_address, device_address) != 0)
883                         continue;
884
885                 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
886                                         &interface_str, &svc_iter)) {
887                         if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
888                                 continue;
889
890                         DBG("[%d] %s", idx++, object_path + 15);
891                         /* for characteristic */
892                         gp_char_array = g_ptr_array_new();
893                         while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
894                                 if (g_strcmp0(key, "Primary") == 0) {
895                                         is_primary = g_variant_get_boolean(value);
896                                         if (is_primary) {
897                                                 g_ptr_array_add(gp_array, (gpointer)object_path);
898                                                 svc_count++;
899                                         }
900                                 } else if (g_strcmp0(key, "UUID") == 0) {
901                                         uuid_str = g_variant_get_string(value, &len);
902                                 } else if (g_strcmp0(key, "Characteristics") == 0) {
903                                         g_variant_get(value, "ao", &char_iter);
904                                         if (char_iter != NULL) {
905                                                 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
906                                                         g_ptr_array_add(gp_char_array, (gpointer)char_handle);
907                                                 }
908                                         }
909                                 }
910                         }
911
912                         if (uuid_str) {
913                                 _bt_hal_send_search_service_result_event(conn_id, is_primary,
914                                                 uuid_str, conn_info->inst_id);
915
916                                 _gattc_create_new_service(conn_info, is_primary, uuid_str, object_path, gp_char_array);
917                         }
918                 }
919         }
920
921         if (gp_array->len == 0 || svc_count == 0) {
922                 ERR("gp_array is NULL");
923                 ret = BT_STATUS_FAIL;
924         } else {
925                 ret = BT_STATUS_SUCCESS;
926         }
927
928         browse_service_char(conn_id);
929         /* send search service complete event */
930         _bt_hal_send_search_service_complete_event(conn_id, ret);
931
932         g_ptr_array_free(gp_array, TRUE);
933         g_variant_iter_free(iter);
934         g_variant_unref(result);
935         DBG("-");
936         return ret;
937 }
938
939 bt_status_t btif_gattc_client_search_service(int conn_id, bt_uuid_t *filter_uuid)
940 {
941         if (NULL == filter_uuid) {
942                 DBG("Browse all the services");
943                 return _gattc_client_search_service(conn_id);
944         } else {
945                 DBG("TODO implement it");
946                 return BT_STATUS_UNSUPPORTED;
947         }
948 }
949 /**
950  * Enumerate included services for a given service.
951  * Set start_incl_srvc_id to NULL to get the first included service.
952  */
953 bt_status_t get_included_service(int conn_id, btgatt_srvc_id_t *srvc_id,
954                 btgatt_srvc_id_t *start_incl_srvc_id)
955 {
956         CHECK_BTGATT_INIT();
957         return BT_STATUS_UNSUPPORTED;
958 }
959
960 static void _bt_hal_send_client_char_search_result_event(int conn_id, int status,
961                 btgatt_srvc_id_t *svc_id, bt_uuid_t *char_uuid, int char_prop)
962 {
963         struct hal_ev_gatt_client_char_search_result  ev;
964
965          if (!event_cb) {
966                 ERR("gatt client callback not registered");
967                 return;
968         }
969
970         memset(&ev, 0, sizeof(ev));
971         ev.conn_id = conn_id;
972         ev.inst_id = svc_id->id.inst_id;
973         ev.is_primary = svc_id->is_primary;
974         ev.status = status;
975         memcpy(ev.svc_uuid, svc_id->id.uuid.uu, sizeof(ev.svc_uuid));
976
977         if (status == BT_STATUS_SUCCESS) {
978                 /* building char uuid */
979                 memcpy(ev.char_uuid, char_uuid->uu, sizeof(ev.char_uuid));
980                 ev.char_prop = char_prop;
981         }
982
983         DBG("sending the char search event.  conn_id[%d] status[%d]", conn_id, status);
984         event_cb(HAL_EV_GATT_CLIENT_CHARAC_SEARCH_RESULT, (void *)&ev, sizeof(ev));
985 }
986
987 static int _hal_get_permission_flag(char *permission)
988 {
989         int ret = 0;
990
991         if (NULL == permission) {
992                 ERR("gatt permission is NULL");
993                 return ret;
994         }
995
996         if (!g_strcmp0(permission, "broadcast"))
997                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
998         else if (!g_strcmp0(permission, "read"))
999                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_READ;
1000         else if (!g_strcmp0(permission, "write-without-response"))
1001                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
1002         else if (!g_strcmp0(permission, "write"))
1003                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE;
1004         else if (!g_strcmp0(permission, "notify"))
1005                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
1006         else if (!g_strcmp0(permission, "indicate"))
1007                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
1008         else if (!g_strcmp0(permission, "authenticated-signed-writes"))
1009                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
1010         else if (!g_strcmp0(permission, "reliable-write"))
1011                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
1012         else if (!g_strcmp0(permission, "writable-auxiliaries"))
1013                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
1014         else if (!g_strcmp0(permission, "encrypt-read"))
1015                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
1016         else if (!g_strcmp0(permission, "encrypt-write"))
1017                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
1018         else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
1019                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
1020         else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
1021                 ret = HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
1022
1023         return ret;
1024 }
1025
1026 static void __hal_convert_permission_flag_to_str(unsigned int permission)
1027 {
1028         char perm[200] = { 0, };
1029
1030         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST)
1031                 g_strlcat(perm, "broadcast ", sizeof(perm));
1032         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_READ)
1033                 g_strlcat(perm, "read ", sizeof(perm));
1034         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE)
1035                 g_strlcat(perm, "write-without-response ", sizeof(perm));
1036         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE)
1037                 g_strlcat(perm, "write ", sizeof(perm));
1038         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY)
1039                 g_strlcat(perm, "notify ", sizeof(perm));
1040         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE)
1041                 g_strlcat(perm, "indicate ", sizeof(perm));
1042         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE)
1043                 g_strlcat(perm, "authenticated-signed-writes ", sizeof(perm));
1044         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE)
1045                 g_strlcat(perm, "reliable-write ", sizeof(perm));
1046         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES)
1047                 g_strlcat(perm, "writable-auxiliaries ", sizeof(perm));
1048         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ)
1049                 g_strlcat(perm, "encrypt-read ", sizeof(perm));
1050         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE)
1051                 g_strlcat(perm, "encrypt-write ", sizeof(perm));
1052         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ)
1053                 g_strlcat(perm, "encrypt-authenticated-read ", sizeof(perm));
1054         if (permission & HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE)
1055                 g_strlcat(perm, "encrypt-authenticated-write ", sizeof(perm));
1056
1057         DBG("permission [0x%04x] : %s\n", permission, perm);
1058         return;
1059 }
1060
1061 static bt_status_t _hal_gattc_get_characteristic_info(hal_gattc_char_t *gattc_char)
1062 {
1063         GDBusProxy *properties_proxy = NULL;
1064         GError *error = NULL;
1065         GVariant *value = NULL;
1066         GVariant *result = NULL;
1067         GDBusConnection *g_conn;
1068         const gchar *key;
1069         char *char_desc_handle = NULL;
1070         gsize len;
1071         GVariantIter *property_iter;
1072         GVariantIter *char_desc_iter;
1073         char* char_handle = NULL;
1074         gchar *char_uuid_str = NULL;
1075         GPtrArray *gp_desc_array  = NULL;
1076         GVariantIter *char_perm_iter;
1077         gchar* permission;
1078         unsigned int char_permission = 0 ;
1079
1080         if (gattc_char->chr_path == NULL) {
1081                 DBG("char path is NULL");
1082                  return BT_STATUS_FAIL;
1083         }
1084         char_handle = gattc_char->chr_path;
1085
1086         g_conn = _bt_hal_get_system_gconn();
1087         if (NULL == g_conn) {
1088                  ERR("_bt_gdbus_get_system_gconn returned NULL");
1089                 return BT_STATUS_FAIL;
1090         }
1091
1092         properties_proxy = g_dbus_proxy_new_sync(g_conn,
1093                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1094                         BT_HAL_BLUEZ_NAME,
1095                         char_handle,
1096                         BT_HAL_PROPERTIES_INTERFACE,
1097                         NULL, &error);
1098
1099         if (properties_proxy == NULL) {
1100                 ERR("properties_proxy returned NULL");
1101                 return BT_STATUS_FAIL;
1102         }
1103
1104         result = g_dbus_proxy_call_sync(properties_proxy,
1105                         "GetAll",
1106                         g_variant_new("(s)", BT_HAL_GATT_CHAR_INTERFACE),
1107                         G_DBUS_CALL_FLAGS_NONE,
1108                         -1,
1109                         NULL,
1110                         &error);
1111         if (!result) {
1112                 if (error != NULL) {
1113                         ERR("Fail to get properties (Error: %s)", error->message);
1114                         g_clear_error(&error);
1115                 } else
1116                         ERR("Fail to get properties");
1117                 g_object_unref(properties_proxy);
1118                 return BT_STATUS_FAIL;
1119         }
1120
1121         gp_desc_array = g_ptr_array_new();
1122
1123         g_variant_get(result, "(a{sv})", &property_iter);
1124
1125         while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1126                 if (!g_strcmp0(key, "UUID")) {
1127                         char_uuid_str = g_variant_dup_string(value, &len);
1128                         INFO("%s [%s]", char_handle + 37, char_uuid_str);
1129                 } else if (!g_strcmp0(key, "Flags")) {
1130                         g_variant_get(value, "as", &char_perm_iter);
1131                                 char_permission = 0x00;
1132
1133                         while (g_variant_iter_loop(char_perm_iter, "s", &permission)) {
1134                                 char_permission |= _hal_get_permission_flag(permission);
1135                         }
1136                         __hal_convert_permission_flag_to_str(char_permission);
1137                         g_variant_iter_free(char_perm_iter);
1138                 } else if (!g_strcmp0(key, "Descriptors")) {
1139                         g_variant_get(value, "ao", &char_desc_iter);
1140                         while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle)) {
1141                                 g_ptr_array_add(gp_desc_array, (gpointer)char_desc_handle);
1142                         }
1143                         g_variant_iter_free(char_desc_iter);
1144                 }
1145         }
1146
1147         _hal_gattc_update_char_property(gattc_char, char_uuid_str, gp_desc_array, char_permission);
1148
1149         g_free(char_uuid_str);
1150         g_variant_iter_free(property_iter);
1151         g_variant_unref(result);
1152         g_object_unref(properties_proxy);
1153         g_ptr_array_free(gp_desc_array, TRUE);
1154
1155         return BT_STATUS_SUCCESS;
1156 }
1157
1158 static bt_status_t _gattc_get_all_characteristic(int conn_id,
1159                 btgatt_srvc_id_t *srvc_id)
1160 {
1161         hal_gattc_server_info_t * conn_info = NULL;
1162         hal_gattc_service_t *gattc_service = NULL;
1163         GSList *l;
1164         hal_gattc_char_t *gattc_char = NULL;
1165         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1166         int status = BT_STATUS_FAIL;
1167
1168         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1169         if (NULL == conn_info) {
1170                 ERR("Failed to get the conn_info for conn_id [%d]", conn_id);
1171                 return BT_STATUS_FAIL;
1172         }
1173
1174         /* find service */
1175         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1176         if (NULL == gattc_service) {
1177                 ERR("Failed to get the gatt service");
1178                 return BT_STATUS_FAIL;
1179         }
1180
1181         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1182         INFO("%s %s", gattc_service->svc_path + 37, svc_uuid_str);
1183
1184         /* find characteristic object path */
1185         for (l = gattc_service->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
1186                 gattc_char = (hal_gattc_char_t *)l->data;
1187                 status = _hal_gattc_get_characteristic_info(gattc_char);
1188
1189                 /* send event */
1190                 if (BT_STATUS_SUCCESS == status) {
1191                         _bt_hal_send_client_char_search_result_event(conn_id, status, srvc_id,
1192                                         &gattc_char->chr_uuid, gattc_char->permission);
1193                 }
1194         }
1195
1196         status = BT_STATUS_FAIL;
1197         _bt_hal_send_client_char_search_result_event(conn_id, status, srvc_id, NULL, 0);
1198
1199         browse_service_char(conn_id);
1200         /* retrive uuid for characteristic and object path for descriptor */
1201
1202         return BT_STATUS_SUCCESS;
1203 }
1204
1205 /**
1206  * Enumerate characteristics for a given service.
1207  * Set start_char_id to NULL to get the first characteristic.
1208  */
1209 bt_status_t btif_gattc_get_characteristic(int conn_id,
1210                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *start_char_id)
1211 {
1212         CHECK_BTGATT_INIT();
1213
1214         if (start_char_id == NULL) {
1215                 return _gattc_get_all_characteristic(conn_id, srvc_id);
1216
1217         } else {
1218                 DBG("TBD Get specific characteristics");
1219                 return BT_STATUS_UNSUPPORTED;
1220         }
1221 }
1222
1223 static bt_status_t _hal_gattc_get_descriptor_info(hal_gattc_desc_t *gattc_desc)
1224 {
1225         GDBusProxy *properties_proxy = NULL;
1226         GError *error = NULL;
1227         GVariant *value = NULL;
1228         GVariant *result = NULL;
1229         GDBusConnection *g_conn;
1230         const gchar *key;
1231         gsize len;
1232         GVariantIter *property_iter;
1233         char* desc_handle = NULL;
1234         const gchar *desc_uuid_str = NULL;
1235
1236         if (gattc_desc->desc_path == NULL) {
1237                 DBG("desc path is NULL");
1238                 return BT_STATUS_FAIL;
1239         }
1240         desc_handle = gattc_desc->desc_path;
1241
1242         g_conn = _bt_hal_get_system_gconn();
1243         if (NULL == g_conn) {
1244                 ERR("_bt_gdbus_get_system_gconn returned NULL");
1245                 return BT_STATUS_FAIL;
1246         }
1247
1248         properties_proxy = g_dbus_proxy_new_sync(g_conn,
1249                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1250                         BT_HAL_BLUEZ_NAME,
1251                         desc_handle,
1252                         BT_HAL_PROPERTIES_INTERFACE,
1253                         NULL, &error);
1254
1255         if (properties_proxy == NULL) {
1256                 ERR("properties_proxy returned NULL");
1257                 return BT_STATUS_FAIL;
1258         }
1259
1260         result = g_dbus_proxy_call_sync(properties_proxy,
1261                         "GetAll",
1262                         g_variant_new("(s)", BT_HAL_GATT_DESC_INTERFACE),
1263                         G_DBUS_CALL_FLAGS_NONE,
1264                         -1,
1265                         NULL,
1266                         &error);
1267         if (!result) {
1268                 if (error != NULL) {
1269                         ERR("Fail to get properties (Error: %s)", error->message);
1270                         g_clear_error(&error);
1271                 } else
1272                         ERR("Fail to get properties");
1273                 g_object_unref(properties_proxy);
1274                 return BT_STATUS_FAIL;
1275         }
1276
1277         g_variant_get(result, "(a{sv})", &property_iter);
1278
1279         while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1280                 if (!g_strcmp0(key, "UUID")) {
1281                         desc_uuid_str = g_variant_get_string(value, &len);
1282                         _hal_gattc_update_desc_property(gattc_desc, desc_uuid_str);
1283
1284                         g_free((gchar *)key);
1285                         g_variant_unref(value);
1286                         break;
1287                 }
1288         }
1289
1290         g_variant_iter_free(property_iter);
1291         g_variant_unref(result);
1292         g_object_unref(properties_proxy);
1293
1294         return BT_STATUS_SUCCESS;
1295 }
1296
1297 static void _bt_hal_send_client_desc_search_result_event(int conn_id, int status,
1298                 btgatt_srvc_id_t *svc_id, btgatt_gatt_id_t *char_id, bt_uuid_t *desc_uuid)
1299 {
1300         struct hal_ev_gatt_client_desc_search_result  ev;
1301
1302         if (!event_cb) {
1303                 ERR("gatt client callback not registered");
1304                 return;
1305         }
1306
1307         memset(&ev, 0, sizeof(ev));
1308         ev.conn_id = conn_id;
1309         ev.inst_id = svc_id->id.inst_id;
1310         ev.is_primary = svc_id->is_primary;
1311         ev.status = status;
1312
1313         memcpy(ev.svc_uuid, svc_id->id.uuid.uu, sizeof(ev.svc_uuid));
1314         memcpy(ev.char_uuid, char_id->uuid.uu, sizeof(ev.char_uuid));
1315
1316         if (status == BT_STATUS_SUCCESS) {
1317                 /* building desc uuid */
1318                 memcpy(ev.desc_uuid, desc_uuid->uu, sizeof(ev.desc_uuid));
1319         }
1320
1321         DBG("sending the desc search event. conn_id[%d] status[%d]", conn_id, status);
1322
1323         event_cb(HAL_EV_GATT_CLIENT_DESC_SEARCH_RESULT, (void *)&ev, sizeof(ev));
1324 }
1325
1326 static bt_status_t _hal_gattc_get_all_descriptor(int conn_id,
1327                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id)
1328 {
1329         hal_gattc_server_info_t * conn_info = NULL;
1330         hal_gattc_service_t *gattc_service = NULL;
1331         GSList *l;
1332         GSList *m;
1333         hal_gattc_char_t *gattc_char = NULL;
1334         hal_gattc_desc_t *gattc_desc = NULL;
1335         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1336         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1337         int status = BT_STATUS_FAIL;
1338
1339         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1340         if (NULL == conn_info) {
1341                 ERR("Failed to get the conn_info for conn_id [%d]", conn_id);
1342                 return BT_STATUS_FAIL;
1343         }
1344
1345         /* find service */
1346         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1347         if (NULL == gattc_service) {
1348                 ERR("Failed to get the gatt service");
1349                 return BT_STATUS_FAIL;
1350         }
1351
1352         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1353 //      DBG("%s %s", gattc_service->svc_path + 37, svc_uuid_str);
1354
1355         /* find characteristics */
1356         /* a service can have two char with same uuid */
1357         for (l = gattc_service->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
1358                 gattc_char = (hal_gattc_char_t*)l->data;
1359                 if (gattc_char == NULL)
1360                         continue;
1361
1362                 if (!memcmp(&gattc_char->chr_uuid, &char_id->uuid, sizeof(bt_uuid_t))) {
1363                         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1364 //                      DBG("%s %s", gattc_char->chr_path + 37, char_uuid_str);
1365
1366                         /* get descriptor uuid */
1367                         for (m = gattc_char->gatt_list_descs; m != NULL; m = g_slist_next(m)) {
1368                                 gattc_desc = (hal_gattc_desc_t *)m->data;
1369                                 if (gattc_desc == NULL)
1370                                         continue;
1371
1372                                 status = _hal_gattc_get_descriptor_info(gattc_desc);
1373
1374                                 /* send event */
1375                                 if (BT_STATUS_SUCCESS == status) {
1376                                         _bt_hal_send_client_desc_search_result_event(conn_id, status, srvc_id,
1377                                                         char_id, &gattc_desc->desc_uuid);
1378                                 }
1379                         }
1380                 }
1381         }
1382
1383         status = BT_STATUS_FAIL;
1384         _bt_hal_send_client_desc_search_result_event(conn_id, status, srvc_id, char_id, NULL);
1385
1386         browse_service_char(conn_id);
1387         /* retrive uuid for characteristic and object path for descriptor */
1388
1389         return BT_STATUS_SUCCESS;
1390 }
1391
1392 /**
1393  * Enumerate descriptors for a given characteristic.
1394  * Set start_descr_id to NULL to get the first descriptor.
1395  */
1396 bt_status_t btif_gattc_get_descriptor(int conn_id,
1397                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1398                 btgatt_gatt_id_t *start_descr_id)
1399 {
1400         CHECK_BTGATT_INIT();
1401
1402         if (start_descr_id == NULL) {
1403                 return _hal_gattc_get_all_descriptor(conn_id, srvc_id, char_id);
1404         } else {
1405                 DBG("TBD Get specific descriptor");
1406                 return BT_STATUS_UNSUPPORTED;
1407         }
1408 }
1409
1410 static void __hal_send_char_read_event(hal_gatt_resp_data_t *resp_data, int result, uint8_t *value, int len)
1411 {
1412         struct hal_ev_gatt_client_read_data  ev;
1413
1414         if (!event_cb) {
1415                 ERR("gatt client callback not registered");
1416                 return;
1417         }
1418
1419         memset(&ev, 0, sizeof(ev));
1420         ev.conn_id = resp_data->conn_id;
1421         ev.inst_id = resp_data->srvc_id.id.inst_id;
1422         ev.is_primary = resp_data->srvc_id.is_primary;
1423         ev.status = result;
1424
1425         memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1426         memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1427
1428         ev.len = len;
1429         if (len > 0) {
1430                 /* building the char read value */
1431                 memcpy(ev.value, value, len);
1432         }
1433
1434         DBG("sending gatt client charac read event. conn_id[%d] status[%d]", resp_data->conn_id, result);
1435
1436         event_cb(HAL_EV_GATT_CLIENT_READ_CHARAC, (void *)&ev, sizeof(ev));
1437 }
1438
1439 static void __hal_internal_read_char_cb(GObject *source_object,
1440                 GAsyncResult *res, gpointer user_data)
1441 {
1442         GError *error = NULL;
1443         GDBusConnection *system_gconn = NULL;
1444         GVariant *value;
1445         GVariantIter *iter;
1446         GByteArray *gp_byte_array = NULL;
1447         guint8 g_byte;
1448         hal_gatt_resp_data_t *resp_data = user_data;
1449         int result = BT_STATUS_SUCCESS;
1450
1451         system_gconn = _bt_hal_get_system_gconn();
1452         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1453
1454         if (error) {
1455                 ERR("Read Characteristic dbus failed Error:[%s]", error->message);
1456
1457                 //send failed event
1458                 result  = BT_STATUS_FAIL;
1459                 __hal_send_char_read_event(resp_data, result, NULL, 0);
1460                 g_clear_error(&error);
1461                 g_free(resp_data);
1462                 return;
1463         }
1464
1465         gp_byte_array = g_byte_array_new();
1466         g_variant_get(value, "(ay)", &iter);
1467
1468         while (g_variant_iter_loop(iter, "y", &g_byte))
1469                 g_byte_array_append(gp_byte_array, &g_byte, 1);
1470
1471
1472         //send value  event
1473         __hal_send_char_read_event(resp_data, result, gp_byte_array->data, gp_byte_array->len);
1474
1475         g_free(resp_data);
1476
1477         g_byte_array_free(gp_byte_array, TRUE);
1478         g_variant_iter_free(iter);
1479         g_variant_unref(value);
1480
1481 }
1482
1483 static bt_status_t _hal_read_characteristic_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1484                 btgatt_gatt_id_t *char_id, int auth_req)
1485 {
1486         GDBusConnection *g_conn;
1487         hal_gatt_resp_data_t *resp_data;
1488         hal_gattc_service_t *gattc_service = NULL;
1489         GVariantBuilder *builder = NULL;
1490         guint16 offset = 0;
1491         hal_gattc_server_info_t * conn_info = NULL;
1492         hal_gattc_char_t *gattc_char = NULL;
1493         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1494         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1495         char* char_handle = NULL;
1496
1497         /* get the connection info */
1498         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1499         if (NULL == conn_info) {
1500                 ERR("Failed to get the conn_info for conn_id [%d]", conn_id);
1501                 return BT_STATUS_FAIL;
1502         }
1503
1504         /* find service */
1505         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1506         if (NULL == gattc_service) {
1507                 ERR("Failed to get the gatt service");
1508                 return BT_STATUS_FAIL;
1509         }
1510
1511         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1512
1513         /* find characteristic */
1514         gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid,
1515                         HAL_GATT_CHARACTERISTIC_PROPERTY_READ);
1516         if (NULL == gattc_char) {
1517                 ERR("Failed to get the gatt char");
1518                 return BT_STATUS_FAIL;
1519         }
1520
1521         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1522         INFO("%s %s", gattc_char->chr_path + 37, char_uuid_str);
1523
1524         g_conn = _bt_hal_get_system_gconn();
1525         if (NULL == g_conn) {
1526                 ERR("_bt_gdbus_get_system_gconn returned NULL");
1527                 return BT_STATUS_FAIL;
1528         }
1529
1530         resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1531         resp_data->conn_id = conn_id;
1532         memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1533         memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1534
1535         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1536
1537         /*offset*/
1538         g_variant_builder_add(builder, "{sv}", "offset",
1539                         g_variant_new("q", offset));
1540
1541         char_handle = gattc_char->chr_path;
1542
1543         g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, char_handle, BT_HAL_GATT_CHAR_INTERFACE,
1544                         "ReadValue", g_variant_new("(a{sv})", builder),
1545                         G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1546                         (GAsyncReadyCallback)__hal_internal_read_char_cb,
1547                         (gpointer)resp_data);
1548         g_variant_builder_unref(builder);
1549
1550         return BT_STATUS_SUCCESS;
1551 }
1552
1553 /** Read a characteristic on a remote device */
1554 bt_status_t btif_read_characteristic(int conn_id,
1555                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1556                 int auth_req)
1557 {
1558         CHECK_BTGATT_INIT();
1559
1560         return _hal_read_characteristic_value(conn_id, srvc_id, char_id, auth_req);
1561 }
1562
1563 static void __hal_send_char_write_event(hal_gatt_resp_data_t *resp_data, int result)
1564 {
1565         struct hal_ev_gatt_client_write_result  ev;
1566
1567          if (!event_cb) {
1568                 ERR("gatt client callback not registered");
1569                 return;
1570         }
1571
1572         memset(&ev, 0, sizeof(ev));
1573         ev.conn_id = resp_data->conn_id;
1574         ev.inst_id = resp_data->srvc_id.id.inst_id;
1575         ev.is_primary = resp_data->srvc_id.is_primary;
1576         ev.status = result;
1577
1578         memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1579         memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1580
1581         event_cb(HAL_EV_GATT_CLIENT_WRITE_CHARAC, (void *)&ev, sizeof(ev));
1582 }
1583
1584 static void __hal_bluetooth_internal_write_cb(GObject *source_object,
1585                 GAsyncResult *res, gpointer user_data)
1586 {
1587         GError *error = NULL;
1588         GDBusConnection *system_gconn = NULL;
1589         GVariant *value;
1590         hal_gatt_resp_data_t *resp_data = user_data;
1591         int result = BT_STATUS_SUCCESS;
1592
1593         system_gconn = _bt_hal_get_system_gconn();
1594         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1595
1596         if (error) {
1597                 ERR("write Characteristic dbus failed Error:[%s]", error->message);
1598
1599                 result  = BT_STATUS_FAIL;
1600                 //send failed event
1601                 __hal_send_char_write_event(resp_data, result);
1602                 g_clear_error(&error);
1603                 g_free(resp_data);
1604                 return;
1605         }
1606
1607         //send write value  event
1608         __hal_send_char_write_event(resp_data, result);
1609
1610         g_free(resp_data);
1611         g_variant_unref(value);
1612
1613 }
1614
1615 static bt_status_t __hal_get_write_prop(hal_gatt_write_type_t type, bt_gatt_characteristic_property_t *prop)
1616 {
1617         switch (type) {
1618         case HAL_GATT_WRITE_TYPE_WRITE:
1619                 *prop = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE;
1620                 break;
1621         case HAL_GATT_WRITE_TYPE_WRITE_NO_RESPONSE:
1622                 *prop = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
1623                 break;
1624         default:
1625                 ERR("Unknow write type : %d", type);
1626                 return BT_STATUS_FAIL;
1627         }
1628
1629         return BT_STATUS_SUCCESS;
1630 }
1631
1632
1633 static int __bluetooth_gatt_acquire_write_fd(const char *chr, int *fd, int *mtu)
1634 {
1635         GDBusConnection *conn;
1636         GVariantBuilder *builder = NULL;
1637         guint16 offset = 0;
1638         GError *err = NULL;
1639         GVariant *value;
1640         gint32 idx;
1641         guint16 att_mtu;
1642         GUnixFDList *fd_list = NULL;
1643
1644         conn = _bt_hal_get_system_gconn();
1645         if (NULL == conn) {
1646                 ERR("_bt_gdbus_get_system_gconn returned NULL");
1647                 return BT_STATUS_FAIL;
1648         }
1649
1650         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1651         //val = g_variant_new("ay", builder1);
1652
1653         g_variant_builder_add(builder, "{sv}", "offset",
1654         g_variant_new("q", offset));
1655
1656         value = g_dbus_connection_call_with_unix_fd_list_sync(conn, BT_HAL_BLUEZ_NAME, chr, BT_HAL_GATT_CHAR_INTERFACE,
1657                         "AcquireWrite", g_variant_new("(a{sv})", builder),
1658                         G_VARIANT_TYPE("(hq)"), G_DBUS_CALL_FLAGS_NONE, -1,
1659                         NULL, &fd_list, NULL, &err);
1660         if (err != NULL) {
1661                 g_dbus_error_strip_remote_error(err);
1662                 ERR("Error: %s", err->message);
1663                 g_error_free(err);
1664                 g_variant_builder_unref(builder);
1665                 return BT_STATUS_FAIL;
1666         }
1667
1668         g_variant_get(value, "(hq)", &idx, &att_mtu);
1669         *fd = g_unix_fd_list_get(fd_list, idx, NULL);
1670
1671         INFO("Acquired Write fd %d,  index %d, mtu %d", *fd, idx, att_mtu);
1672         *mtu = att_mtu;
1673
1674         g_object_unref(fd_list);
1675         g_variant_unref(value);
1676         g_variant_builder_unref(builder);
1677
1678         return BT_STATUS_SUCCESS;
1679 }
1680
1681 static int __bluetooth_gatt_acquire_notify_fd(const char *chr, int *fd, int *mtu)
1682 {
1683         GDBusConnection *conn;
1684         GVariantBuilder *builder = NULL;
1685         guint16 offset = 0;
1686         GError *err = NULL;
1687         GVariant *value;
1688         gint32 idx, notify_fd;
1689         guint16 att_mtu;
1690         GUnixFDList *fd_list = NULL;
1691
1692         conn = _bt_hal_get_system_gconn();
1693
1694         if (NULL == conn) {
1695                 ERR("_bt_gdbus_get_system_gconn returned NULL");
1696                 return BT_STATUS_FAIL;
1697         }
1698
1699
1700         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1701
1702
1703         g_variant_builder_add(builder, "{sv}", "offset",
1704                 g_variant_new("q", offset));
1705
1706         value = g_dbus_connection_call_with_unix_fd_list_sync(conn, BT_HAL_BLUEZ_NAME, chr, BT_HAL_GATT_CHAR_INTERFACE,
1707                 "AcquireNotify", g_variant_new("(a{sv})", builder),
1708                 G_VARIANT_TYPE("(hq)"), G_DBUS_CALL_FLAGS_NONE, -1,
1709                 NULL, &fd_list, NULL, &err);
1710         if (err != NULL) {
1711                 g_dbus_error_strip_remote_error(err);
1712                 ERR("Error: %s", err->message);
1713                 g_error_free(err);
1714                 g_variant_builder_unref(builder);
1715                 return BT_STATUS_FAIL;
1716         }
1717
1718         g_variant_get(value, "(hq)", &idx, &att_mtu);
1719         notify_fd = g_unix_fd_list_get(fd_list, idx, NULL);
1720         *mtu = att_mtu;
1721
1722         INFO("Acquired Notify fd %d, mtu %d", notify_fd, *mtu);
1723
1724         *fd = notify_fd;
1725
1726         g_object_unref(fd_list);
1727         g_variant_unref(value);
1728         g_variant_builder_unref(builder);
1729
1730         return BT_STATUS_SUCCESS;
1731 }
1732
1733
1734 static bt_status_t _hal_write_characteristic_value(int conn_id, btgatt_srvc_id_t *srvc_id,
1735                 btgatt_gatt_id_t *char_id, int write_type, int length, int auth_req, char* value)
1736 {
1737         GVariant *val, *options;
1738         GVariantBuilder *builder1;
1739         GVariantBuilder *builder2;
1740         GDBusConnection *g_conn;
1741         guint16 offset = 0;
1742         int i = 0;
1743         hal_gatt_resp_data_t  *resp_data;
1744         hal_gattc_service_t *gattc_service = NULL;
1745         hal_gattc_server_info_t * conn_info = NULL;
1746         hal_gattc_char_t *gattc_char = NULL;
1747         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
1748         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1749         char* char_handle = NULL;
1750         bt_gatt_characteristic_property_t write_prop = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE;
1751         int ret = BT_STATUS_SUCCESS;
1752
1753         ret = __hal_get_write_prop(write_type, &write_prop);
1754         if (BT_STATUS_FAIL == ret) {
1755                 DBG("received invalid  write type:[%d] ", write_type);
1756                 return BT_STATUS_FAIL;
1757         }
1758
1759         /* get the connection info */
1760         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1761         if (NULL == conn_info) {
1762                 ERR("Failed to get the conn_info for conn_id [%d]", conn_id);
1763                 return BT_STATUS_FAIL;
1764         }
1765
1766         /* find service */
1767         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1768         if (NULL == gattc_service) {
1769                 ERR("Failed to get the gatt service");
1770                 return BT_STATUS_FAIL;
1771         }
1772
1773         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
1774         DBG("%s %s", gattc_service->svc_path + 37, svc_uuid_str);
1775
1776         /* find characteristic */
1777         gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid, write_prop);
1778         if (NULL == gattc_char) {
1779                 ERR("Failed to get the gatt char");
1780                 return BT_STATUS_FAIL;
1781         }
1782
1783         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1784         DBG("%s %s", gattc_char->chr_path + 37, char_uuid_str);
1785
1786         g_conn = _bt_hal_get_system_gconn();
1787         if (NULL == g_conn) {
1788                  ERR("_bt_gdbus_get_system_gconn returned NULL");
1789                 return BT_STATUS_FAIL;
1790         }
1791
1792         resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
1793         resp_data->conn_id = conn_id;
1794         memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
1795         memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
1796
1797         char_handle = gattc_char->chr_path;
1798
1799         builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1800
1801         for (i = 0; i < length; i++)
1802                 g_variant_builder_add(builder1, "y", value[i]);
1803
1804         val = g_variant_new("ay", builder1);
1805
1806         builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1807         /*offset*/
1808         g_variant_builder_add(builder2, "{sv}", "offset",
1809                         g_variant_new_uint16(offset));
1810
1811         options = g_variant_new("a{sv}", builder2);
1812
1813         g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, char_handle, BT_HAL_GATT_CHAR_INTERFACE,
1814                         "WriteValuebyType",
1815                         g_variant_new("(y@ay@a{sv})", write_prop, val, options),
1816                         NULL,
1817                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1818                         (GAsyncReadyCallback)__hal_bluetooth_internal_write_cb,
1819                         (gpointer)resp_data);
1820
1821         g_variant_builder_unref(builder1);
1822         g_variant_builder_unref(builder2);
1823
1824         return BT_STATUS_SUCCESS;
1825 }
1826
1827 bt_status_t btif_get_acquire_write_fd(int conn_id,
1828                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1829                 int auth_req, int *fd, int*mtu)
1830 {
1831         CHECK_BTGATT_INIT();
1832
1833         hal_gattc_service_t *gattc_service = NULL;
1834         hal_gattc_server_info_t * conn_info = NULL;
1835         hal_gattc_char_t *gattc_char = NULL;
1836         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1837
1838         bt_gatt_characteristic_property_t write_prop = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
1839         int ret = BT_STATUS_SUCCESS;
1840
1841         DBG("svc isntance id:[%d]", srvc_id->id.inst_id);
1842
1843         /* get the connection info */
1844         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1845         if (NULL == conn_info) {
1846                 ERR("Failed to get the conn_info for conn_id [%d]", conn_id);
1847                 return BT_STATUS_FAIL;
1848         }
1849
1850         /* find service */
1851         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1852         if (NULL == gattc_service) {
1853                 ERR("Failed to get the gatt service");
1854                 return BT_STATUS_FAIL;
1855         }
1856
1857         gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid, write_prop);
1858         if (NULL == gattc_char) {
1859                 ERR("Failed to get the gatt char");
1860                 return BT_STATUS_FAIL;
1861         }
1862
1863         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1864         INFO("%s %s", gattc_char->chr_path + 37, char_uuid_str);
1865
1866         ret = __bluetooth_gatt_acquire_write_fd(gattc_char->chr_path, fd, mtu);
1867         if (ret != BT_STATUS_SUCCESS)
1868                 return ret;
1869
1870         return ret;
1871 }
1872
1873 bt_status_t btif_get_acquire_notify_fd(int conn_id,
1874                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, int *fd, int *mtu)
1875 {
1876         CHECK_BTGATT_INIT();
1877
1878         hal_gattc_service_t *gattc_service = NULL;
1879         hal_gattc_server_info_t * conn_info = NULL;
1880         hal_gattc_char_t *gattc_char = NULL;
1881         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
1882
1883         bt_gatt_characteristic_property_t write_prop = HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
1884         int ret = BT_STATUS_SUCCESS;
1885
1886         DBG("svc isntance id [%d]", srvc_id->id.inst_id);
1887
1888         /* get the connection info */
1889         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
1890         if (NULL == conn_info) {
1891                 ERR("Failed to get the conn_info for conn_id [%d]", conn_id);
1892                 return BT_STATUS_FAIL;
1893         }
1894
1895         /* find service */
1896         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
1897         if (NULL == gattc_service) {
1898                 ERR("Failed to get the gatt service");
1899                 return BT_STATUS_FAIL;
1900         }
1901
1902         gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid, write_prop);
1903         if (NULL == gattc_char) {
1904                 ERR("Failed to get the gatt char");
1905                 return BT_STATUS_FAIL;
1906         }
1907
1908         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
1909         INFO("%s %s", gattc_char->chr_path + 37, char_uuid_str);
1910
1911         ret = __bluetooth_gatt_acquire_notify_fd(gattc_char->chr_path, fd, mtu);
1912         if (ret != BT_STATUS_SUCCESS)
1913                 return ret;
1914
1915         return ret;
1916 }
1917
1918
1919 /** Write a remote characteristic */
1920 bt_status_t btif_write_characteristic(int conn_id,
1921                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
1922                 int write_type, int len, int auth_req,
1923                 char* p_value)
1924 {
1925         CHECK_BTGATT_INIT();
1926
1927         DBG("svc isntance id:[%d]", srvc_id->id.inst_id);
1928         return _hal_write_characteristic_value(conn_id, srvc_id, char_id, write_type,
1929                                 len, auth_req, p_value);
1930 }
1931
1932 static void __hal_send_desc_read_event(hal_gatt_resp_data_t *resp_data, int result, uint8_t *value, int len)
1933 {
1934         struct hal_ev_gatt_client_read_data  ev;
1935
1936          if (!event_cb) {
1937                 ERR("gatt client callback not registered");
1938                 return;
1939         }
1940
1941         memset(&ev, 0, sizeof(ev));
1942         ev.conn_id = resp_data->conn_id;
1943         ev.inst_id = resp_data->srvc_id.id.inst_id;
1944         ev.is_primary = resp_data->srvc_id.is_primary;
1945         ev.status = result;
1946
1947         memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
1948         memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
1949         memcpy(ev.desc_uuid, resp_data->desc_id.uuid.uu, sizeof(ev.char_uuid));
1950
1951         ev.len = len;
1952         if (len > 0) {
1953                 /* building the desc read value */
1954                 memcpy(ev.value, value, len);
1955         }
1956
1957         DBG("sending gatt client desc read conn_id[%d] status[%d]", resp_data->conn_id, result);
1958
1959         event_cb(HAL_EV_GATT_CLIENT_READ_DESC, (void *)&ev, sizeof(ev));
1960 }
1961
1962 static void __hal_internal_read_desc_cb(GObject *source_object,
1963                 GAsyncResult *res, gpointer user_data)
1964 {
1965         GError *error = NULL;
1966         GDBusConnection *system_gconn = NULL;
1967         GVariant *value;
1968         GVariantIter *iter;
1969         GByteArray *gp_byte_array = NULL;
1970         guint8 g_byte;
1971         hal_gatt_resp_data_t *resp_data = user_data;
1972         int result = BT_STATUS_SUCCESS;
1973         int i;
1974
1975         DBG("+");
1976
1977         system_gconn = _bt_hal_get_system_gconn();
1978         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1979
1980         if (error) {
1981                 ERR("Read descriptor dbus failed Error:[%s]", error->message);
1982
1983                 //send failed event
1984                 result  = BT_STATUS_FAIL;
1985                 __hal_send_desc_read_event(resp_data, result, NULL, 0);
1986                 g_clear_error(&error);
1987                 g_free(resp_data);
1988                 return;
1989         }
1990
1991         gp_byte_array = g_byte_array_new();
1992         g_variant_get(value, "(ay)", &iter);
1993
1994         while (g_variant_iter_loop(iter, "y", &g_byte))
1995                 g_byte_array_append(gp_byte_array, &g_byte, 1);
1996
1997         //print the value
1998         DBG("value is");
1999         for (i = 0; i < gp_byte_array->len; i++)
2000                 DBG("%02x", gp_byte_array->data[i]);
2001
2002         //send value  event
2003         __hal_send_desc_read_event(resp_data, result, gp_byte_array->data, gp_byte_array->len);
2004
2005         g_free(resp_data);
2006
2007         g_byte_array_free(gp_byte_array, TRUE);
2008         g_variant_iter_free(iter);
2009         g_variant_unref(value);
2010
2011         DBG("-");
2012 }
2013
2014 static bt_status_t _hal_read_descriptor_value(int conn_id, btgatt_srvc_id_t *srvc_id,
2015                 btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *desc_id, int auth_req)
2016 {
2017         GDBusConnection *g_conn;
2018         hal_gatt_resp_data_t *resp_data;
2019         hal_gattc_service_t *gattc_service = NULL;
2020         GVariantBuilder *builder = NULL;
2021         guint16 offset = 0;
2022         hal_gattc_server_info_t * conn_info = NULL;
2023         hal_gattc_char_t *gattc_char = NULL;
2024         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
2025         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
2026         char desc_uuid_str[BT_HAL_UUID_STRING_LEN];
2027         char* desc_handle = NULL;
2028         GSList *l;
2029
2030         hal_gattc_desc_t *gattc_desc = NULL;
2031
2032         /* get the connection info */
2033         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
2034         if (NULL == conn_info) {
2035                 ERR("Failed to get the conn_info for conn_id [%d]", conn_id);
2036                 return BT_STATUS_FAIL;
2037         }
2038
2039         /* find service */
2040         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
2041         if (NULL == gattc_service) {
2042                 ERR("Failed to get the gatt service");
2043                 return BT_STATUS_FAIL;
2044         }
2045
2046         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
2047         DBG("%s %s", gattc_service->svc_path + 37, svc_uuid_str);
2048
2049         /* find characteristic */
2050         /* service can have two char with same uuid */
2051         for (l = gattc_service->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
2052                 gattc_char = (hal_gattc_char_t*)l->data;
2053                 if (gattc_char == NULL)
2054                         continue;
2055
2056                 if (!memcmp(&gattc_char->chr_uuid, &char_id->uuid, sizeof(bt_uuid_t))) {
2057                         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2058                         DBG("%s %s", gattc_char->chr_path + 37, char_uuid_str);
2059
2060                         /* find descriptor */
2061                         gattc_desc = _gattc_find_desc_from_uuid(gattc_char, &desc_id->uuid);
2062                         if (gattc_desc) {
2063                                 _bt_hal_convert_uuid_type_to_string(desc_uuid_str, gattc_desc->desc_uuid.uu);
2064                                 DBG("%s %s", gattc_desc->desc_path + 37, desc_uuid_str);
2065                                 break;
2066                         }
2067                 }
2068         }
2069
2070         if (NULL == gattc_desc) {
2071                 ERR("Failed to get the gatt desc");
2072                 return BT_STATUS_FAIL;
2073         }
2074
2075         g_conn = _bt_hal_get_system_gconn();
2076         if (NULL == g_conn) {
2077                  ERR("_bt_gdbus_get_system_gconn returned NULL");
2078                 return BT_STATUS_FAIL;
2079         }
2080
2081         resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
2082         resp_data->conn_id = conn_id;
2083         memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2084         memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2085         memcpy(&resp_data->desc_id, desc_id, sizeof(btgatt_gatt_id_t));
2086
2087         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2088
2089         /*offset*/
2090         g_variant_builder_add(builder, "{sv}", "offset",
2091                         g_variant_new("q", offset));
2092
2093         desc_handle = gattc_desc->desc_path;
2094
2095         DBG("calling desc read value");
2096
2097         g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, desc_handle, BT_HAL_GATT_DESC_INTERFACE,
2098                         "ReadValue", g_variant_new("(a{sv})", builder),
2099                         G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2100                         (GAsyncReadyCallback)__hal_internal_read_desc_cb,
2101                         (gpointer)resp_data);
2102         g_variant_builder_unref(builder);
2103
2104         return BT_STATUS_SUCCESS;
2105 }
2106
2107 /** Read the descriptor for a given characteristic */
2108 bt_status_t btif_read_descriptor(int conn_id,
2109                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
2110                 btgatt_gatt_id_t *descr_id, int auth_req)
2111 {
2112         CHECK_BTGATT_INIT();
2113
2114         return _hal_read_descriptor_value(conn_id, srvc_id, char_id, descr_id, auth_req);
2115 }
2116
2117 static void __hal_send_desc_write_event(hal_gatt_resp_data_t *resp_data, int result)
2118 {
2119         struct hal_ev_gatt_client_write_result  ev;
2120
2121          if (!event_cb) {
2122                 ERR("gatt client callback not registered");
2123                 return;
2124         }
2125
2126         memset(&ev, 0, sizeof(ev));
2127         ev.conn_id = resp_data->conn_id;
2128         ev.inst_id = resp_data->srvc_id.id.inst_id;
2129         ev.is_primary = resp_data->srvc_id.is_primary;
2130         ev.status = result;
2131
2132         memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
2133         memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
2134         memcpy(ev.desc_uuid, resp_data->desc_id.uuid.uu, sizeof(ev.desc_uuid));
2135
2136         DBG("sending gatt client charac write event. conn_id[%d] status[%d]", resp_data->conn_id, result);
2137
2138         event_cb(HAL_EV_GATT_CLIENT_WRITE_DESC, (void *)&ev, sizeof(ev));
2139 }
2140
2141 static void __hal_bluetooth_internal_desc_write_cb(GObject *source_object,
2142                 GAsyncResult *res, gpointer user_data)
2143 {
2144         GError *error = NULL;
2145         GDBusConnection *system_gconn = NULL;
2146         GVariant *value;
2147         hal_gatt_resp_data_t *resp_data = user_data;
2148         int result = BT_STATUS_SUCCESS;
2149
2150         DBG("+");
2151
2152         system_gconn = _bt_hal_get_system_gconn();
2153         value = g_dbus_connection_call_finish(system_gconn, res, &error);
2154
2155         if (error) {
2156                 ERR("write descriptor dbus failed Error: [%s]", error->message);
2157
2158                 //send failed event
2159                 result  = BT_STATUS_FAIL;
2160                 __hal_send_desc_write_event(resp_data, result);
2161                 g_clear_error(&error);
2162                 g_free(resp_data);
2163                 return;
2164         }
2165
2166         //send write value  event
2167         __hal_send_desc_write_event(resp_data, result);
2168
2169         g_free(resp_data);
2170         g_variant_unref(value);
2171
2172         DBG("-");
2173 }
2174
2175 static bt_status_t _hal_write_descriptor_value(int conn_id, btgatt_srvc_id_t *srvc_id,
2176                                 btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *descr_id,
2177                                 int write_type, int length, int auth_req, char* value)
2178 {
2179         GVariant *val, *options;
2180         GVariantBuilder *builder1;
2181         GVariantBuilder *builder2;
2182         GDBusConnection *g_conn;
2183         guint16 offset = 0;
2184         int i = 0;
2185         hal_gatt_resp_data_t  *resp_data;
2186         hal_gattc_service_t *gattc_service = NULL;
2187         hal_gattc_server_info_t * conn_info = NULL;
2188         hal_gattc_char_t *gattc_char = NULL;
2189         hal_gattc_desc_t *gattc_desc = NULL;
2190         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
2191         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
2192         char desc_uuid_str[BT_HAL_UUID_STRING_LEN];
2193         char* desc_handle = NULL;
2194         bt_gatt_characteristic_property_t write_prop = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE;
2195         int ret = BT_STATUS_SUCCESS;
2196         GSList *l;
2197
2198         DBG("+");
2199
2200         ret = __hal_get_write_prop(write_type, &write_prop);
2201         if (BT_STATUS_FAIL == ret) {
2202                 ERR("received invalid  write type:[%d] ", write_type);
2203                 return BT_STATUS_FAIL;
2204         }
2205
2206         /* get the connection info */
2207         conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
2208         if (NULL == conn_info) {
2209                 ERR("Failed to get the conn_info for conn_id [%d]", conn_id);
2210                 return BT_STATUS_FAIL;
2211         }
2212
2213         /* find service */
2214         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
2215         if (NULL == gattc_service) {
2216                 ERR("Failed to get the gatt service");
2217                 return BT_STATUS_FAIL;
2218         }
2219
2220         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
2221         DBG("%s %s", gattc_service->svc_path + 37, svc_uuid_str);
2222
2223         /* find characteristic */
2224         /* service can have two char with same uuid */
2225         for (l = gattc_service->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
2226                 gattc_char = (hal_gattc_char_t*)l->data;
2227                 if (gattc_char == NULL)
2228                         continue;
2229
2230                 if (!memcmp(&gattc_char->chr_uuid, &char_id->uuid, sizeof(bt_uuid_t))) {
2231                         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2232                         DBG("%s %s", gattc_char->chr_path + 37, char_uuid_str);
2233
2234                         /* find descriptor */
2235                         gattc_desc = _gattc_find_desc_from_uuid(gattc_char, &descr_id->uuid);
2236                         if (gattc_desc) {
2237                                 _bt_hal_convert_uuid_type_to_string(desc_uuid_str, gattc_desc->desc_uuid.uu);
2238                                 DBG("%s %s", gattc_desc->desc_path + 37, desc_uuid_str);
2239                                 break;
2240                         }
2241                 }
2242         }
2243
2244         if (NULL == gattc_desc) {
2245                 ERR("Failed to get the gatt desc");
2246                 return BT_STATUS_FAIL;
2247         }
2248
2249         g_conn = _bt_hal_get_system_gconn();
2250         if (NULL == g_conn) {
2251                  ERR("_bt_gdbus_get_system_gconn returned NULL");
2252                 return BT_STATUS_FAIL;
2253         }
2254
2255         resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
2256         resp_data->conn_id = conn_id;
2257         memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2258         memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2259         memcpy(&resp_data->desc_id, descr_id, sizeof(btgatt_gatt_id_t));
2260
2261         desc_handle = gattc_desc->desc_path;
2262
2263         builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2264
2265         for (i = 0; i < length; i++)
2266                 g_variant_builder_add(builder1, "y", value[i]);
2267
2268         val = g_variant_new("ay", builder1);
2269
2270         builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2271         /*offset*/
2272         g_variant_builder_add(builder2, "{sv}", "offset",
2273                         g_variant_new_uint16(offset));
2274
2275         options = g_variant_new("a{sv}", builder2);
2276
2277         g_dbus_connection_call(g_conn, BT_HAL_BLUEZ_NAME, desc_handle, BT_HAL_GATT_DESC_INTERFACE,
2278                         "WriteValue",
2279                         g_variant_new("(@ay@a{sv})", val, options),
2280                         NULL,
2281                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2282                         (GAsyncReadyCallback)__hal_bluetooth_internal_desc_write_cb,
2283                         (gpointer)resp_data);
2284
2285         g_variant_builder_unref(builder1);
2286         g_variant_builder_unref(builder2);
2287
2288         return BT_STATUS_SUCCESS;
2289 }
2290
2291 /** Write a remote descriptor for a given characteristic */
2292 bt_status_t btif_write_descriptor(int conn_id,
2293                 btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
2294                 btgatt_gatt_id_t *descr_id, int write_type, int len,
2295                 int auth_req, char* p_value)
2296 {
2297         CHECK_BTGATT_INIT();
2298
2299         return _hal_write_descriptor_value(conn_id, srvc_id, char_id, descr_id, write_type,
2300                         len, auth_req, p_value);
2301 }
2302
2303 /** Execute a prepared write operation */
2304 bt_status_t execute_write(int conn_id, int execute)
2305 {
2306         CHECK_BTGATT_INIT();
2307         return BT_STATUS_UNSUPPORTED;
2308 }
2309
2310 static gboolean _hal_watch_register_notifi_cb(gpointer user_data)
2311 {
2312         struct hal_ev_gatt_client_watch_notification ev;
2313         hal_gatt_resp_data_t *resp_data = user_data;
2314
2315         DBG("sending the watch register notification event");
2316         /* send the event */
2317         memset(&ev, 0, sizeof(ev));
2318         ev.conn_id = resp_data->conn_id;
2319         ev.registered = 1;
2320         ev.status = resp_data->result;
2321
2322         ev.is_primary = resp_data->srvc_id.is_primary;
2323         ev.inst_id = resp_data->srvc_id.id.inst_id;
2324
2325         memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
2326         memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
2327
2328         if (!event_cb)
2329                 ERR("GATT Callback not registered");
2330         else
2331                 event_cb(HAL_EV_GATT_CLIENT_WATCH_NOTIFICATION, (void *)&ev, sizeof(ev));
2332
2333         g_free(user_data);
2334
2335         return FALSE;
2336 }
2337
2338 static bt_status_t _hal_register_for_notification(int conn_id,
2339                 bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2340                 btgatt_gatt_id_t *char_id)
2341 {
2342         int result = BT_STATUS_SUCCESS;
2343         GError *error = NULL;
2344         GDBusConnection *g_conn;
2345         hal_gattc_client_info_t *gattc_client = NULL;
2346         hal_gattc_server_info_t * conn_info = NULL;
2347         hal_gattc_service_t *gattc_service = NULL;
2348         hal_gattc_char_t *gattc_char = NULL;
2349         char* char_handle = NULL;
2350         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
2351         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
2352         hal_gatt_resp_data_t *resp_data;
2353
2354         DBG("+");
2355
2356         gattc_client = __bt_find_gatt_client_info(bd_addr);
2357         if (gattc_client == NULL) {
2358                 ERR("failed to get the gatt client info");
2359                 return BT_STATUS_FAIL;
2360         }
2361
2362         if (gattc_client->conn_id != conn_id) {
2363                 ERR("could not find the gatt client for client id[%d]", conn_id);
2364                 return BT_STATUS_FAIL;
2365         }
2366
2367          /* get the connection info */
2368         conn_info = __bt_find_gatt_conn_info(bd_addr);
2369         if (NULL == conn_info) {
2370                 ERR("Failed to get the conn_info");
2371                 return BT_STATUS_FAIL;
2372         }
2373
2374         if (conn_info->inst_id != gattc_client->inst_id) {
2375                 ERR("could not fild the conn_info");
2376                 return BT_STATUS_FAIL;
2377         }
2378
2379         /* find service */
2380         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
2381         if (NULL == gattc_service) {
2382                 ERR("Failed to get the gatt service");
2383                 return BT_STATUS_FAIL;
2384         }
2385
2386         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
2387         DBG("%s %s", gattc_service->svc_path + 15, svc_uuid_str);
2388
2389
2390         /* find characteristic */
2391         gattc_char = _gattc_find_char_from_uuid_for_notify(gattc_service, &char_id->uuid);
2392         if (NULL == gattc_char) {
2393                 ERR("Failed to get the gatt char");
2394                 return BT_STATUS_FAIL;
2395         }
2396
2397         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2398         DBG("%s %s", gattc_char->chr_path + 15, char_uuid_str);
2399
2400         char_handle = gattc_char->chr_path;
2401
2402         g_conn = _bt_hal_get_system_gconn();
2403         if (g_conn == NULL) {
2404                 ERR("conn NULL");
2405                 return BT_STATUS_FAIL;
2406         }
2407
2408         resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
2409
2410         INFO_C("### Request StartNotify : %s [%s]", gattc_char->chr_path + 15, char_uuid_str);
2411
2412         g_dbus_connection_call_sync(g_conn,
2413                         BT_HAL_BLUEZ_NAME,
2414                         char_handle,
2415                         BT_HAL_GATT_CHAR_INTERFACE,
2416                         "StartNotify",
2417                         NULL,
2418                         NULL,
2419                         G_DBUS_CALL_FLAGS_NONE,
2420                         BT_HAL_MAX_DBUS_TIMEOUT, NULL, &error);
2421
2422         if (error) {
2423                 g_dbus_error_strip_remote_error(error);
2424                 ERR("### StartNotify Failed: %s", error->message);
2425                 if (g_strrstr(error->message, "Already notifying"))
2426                         result = BT_STATUS_SUCCESS;
2427                 else if (g_strrstr(error->message, "In Progress"))
2428                         result = BT_STATUS_BUSY;
2429                 else if (g_strrstr(error->message, "Operation is not supported"))
2430                         result = BT_STATUS_UNSUPPORTED;
2431                 /*failed because of either Insufficient Authorization or Write Not Permitted */
2432                 else if (g_strrstr(error->message, "Write not permitted") ||
2433                                 g_strrstr(error->message, "Operation Not Authorized"))
2434                         result = BT_STATUS_AUTH_FAILURE;
2435                 /* failed because of either Insufficient Authentication,
2436                    Insufficient Encryption Key Size, or Insufficient Encryption. */
2437                 else if (g_strrstr(error->message, "Not paired"))
2438                         result = BT_STATUS_NOT_READY;
2439                 else
2440                         result = BT_STATUS_FAIL;
2441
2442                 g_clear_error(&error);
2443         }
2444
2445         resp_data->conn_id = gattc_client->conn_id;
2446         resp_data->result = result;
2447         memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2448         memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2449
2450         g_idle_add(_hal_watch_register_notifi_cb, (gpointer)resp_data);
2451
2452         DBG("-");
2453
2454         return BT_STATUS_SUCCESS;
2455 }
2456
2457 /**
2458  * Register to receive notifications or indications for a given
2459  * characteristic
2460  */
2461 bt_status_t btif_register_for_notification(int conn_id,
2462                 const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2463                 btgatt_gatt_id_t *char_id)
2464 {
2465         CHECK_BTGATT_INIT();
2466
2467         return _hal_register_for_notification(conn_id, (bt_bdaddr_t *)bd_addr, srvc_id, char_id);
2468 }
2469
2470 static gboolean _hal_watch_deregister_notifi_cb(gpointer user_data)
2471 {
2472         struct hal_ev_gatt_client_watch_notification ev;
2473         hal_gatt_resp_data_t *resp_data = user_data;
2474
2475         DBG("sending the watch deregister notification event");
2476         /* send the event */
2477         memset(&ev, 0, sizeof(ev));
2478         ev.conn_id = resp_data->conn_id;
2479         ev.registered = 0;
2480         ev.status = resp_data->result;
2481
2482         ev.is_primary = resp_data->srvc_id.is_primary;
2483         ev.inst_id = resp_data->srvc_id.id.inst_id;
2484
2485         memcpy(ev.svc_uuid, resp_data->srvc_id.id.uuid.uu, sizeof(ev.svc_uuid));
2486         memcpy(ev.char_uuid, resp_data->char_id.uuid.uu, sizeof(ev.char_uuid));
2487
2488         if (!event_cb)
2489                 ERR("GATT Callback not registered");
2490         else
2491                 event_cb(HAL_EV_GATT_CLIENT_WATCH_NOTIFICATION, (void *)&ev, sizeof(ev));
2492
2493         g_free(user_data);
2494
2495         return FALSE;
2496 }
2497
2498 static bt_status_t _hal_deregister_for_notification(int conn_id,
2499                 bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2500                 btgatt_gatt_id_t *char_id)
2501 {
2502         int result = BT_STATUS_SUCCESS;
2503         GError *error = NULL;
2504         GDBusConnection *g_conn;
2505         hal_gattc_client_info_t *gattc_client = NULL;
2506         hal_gattc_server_info_t * conn_info = NULL;
2507         hal_gattc_service_t *gattc_service = NULL;
2508         hal_gattc_char_t *gattc_char = NULL;
2509         char* char_handle = NULL;
2510         char svc_uuid_str[BT_HAL_UUID_STRING_LEN];
2511         char char_uuid_str[BT_HAL_UUID_STRING_LEN];
2512         hal_gatt_resp_data_t *resp_data;
2513
2514         DBG("+");
2515
2516         gattc_client = __bt_find_gatt_client_info(bd_addr);
2517         if (gattc_client == NULL) {
2518                 ERR("failed to get the gatt client info");
2519                 return BT_STATUS_FAIL;
2520         }
2521
2522         if (gattc_client->conn_id != conn_id) {
2523                 ERR("could not find the gatt client for client id[%d]", conn_id);
2524                 return BT_STATUS_FAIL;
2525         }
2526
2527          /* get the connection info */
2528         conn_info = __bt_find_gatt_conn_info(bd_addr);
2529         if (NULL == conn_info) {
2530                 ERR("Failed to get the conn_info");
2531                 return BT_STATUS_FAIL;
2532         }
2533
2534         if (conn_info->inst_id != gattc_client->inst_id) {
2535                 ERR("could not fild the conn_info");
2536                 return BT_STATUS_FAIL;
2537         }
2538
2539         /* find service */
2540         gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
2541         if (NULL == gattc_service) {
2542                 ERR("Failed to get the gatt service");
2543                 return BT_STATUS_FAIL;
2544         }
2545
2546         _bt_hal_convert_uuid_type_to_string(svc_uuid_str, gattc_service->svc_uuid.uu);
2547         DBG("%s %s", gattc_service->svc_path + 15, svc_uuid_str);
2548
2549
2550         /* find characteristic */
2551         gattc_char = _gattc_find_char_from_uuid_for_notify(gattc_service, &char_id->uuid);
2552         if (NULL == gattc_char) {
2553                 ERR("Failed to get the gatt char");
2554                 return BT_STATUS_FAIL;
2555         }
2556
2557         _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
2558         DBG("%s %s", gattc_char->chr_path + 15, char_uuid_str);
2559
2560         char_handle = gattc_char->chr_path;
2561
2562         g_conn = _bt_hal_get_system_gconn();
2563         if (g_conn == NULL) {
2564                 ERR("conn NULL");
2565                 return BT_STATUS_FAIL;
2566         }
2567
2568         resp_data = g_malloc0(sizeof(hal_gatt_resp_data_t));
2569
2570         INFO("### Request StopNotify : %s [%s]", gattc_char->chr_path + 15, char_uuid_str);
2571         g_dbus_connection_call_sync(g_conn,
2572                         BT_HAL_BLUEZ_NAME,
2573                         char_handle,
2574                         BT_HAL_GATT_CHAR_INTERFACE,
2575                         "StopNotify",
2576                         NULL,
2577                         NULL,
2578                         G_DBUS_CALL_FLAGS_NONE,
2579                         BT_HAL_MAX_DBUS_TIMEOUT, NULL, &error);
2580
2581         if (error) {
2582                 ERR("### StopNotify Failed: %s", error->message);
2583                 g_clear_error(&error);
2584                 result = BT_STATUS_FAIL;
2585         }
2586
2587         resp_data->conn_id = gattc_client->conn_id;
2588         resp_data->result = result;
2589         memcpy(&resp_data->srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
2590         memcpy(&resp_data->char_id, char_id, sizeof(btgatt_gatt_id_t));
2591
2592         g_idle_add(_hal_watch_deregister_notifi_cb, (gpointer)resp_data);
2593
2594         DBG("-");
2595
2596         return BT_STATUS_SUCCESS;
2597 }
2598 /** Deregister a previous request for notifications/indications */
2599 bt_status_t btif_deregister_for_notification(int conn_id,
2600                 const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id,
2601                 btgatt_gatt_id_t *char_id)
2602 {
2603         CHECK_BTGATT_INIT();
2604         return _hal_deregister_for_notification(conn_id, (bt_bdaddr_t *)bd_addr, srvc_id, char_id);
2605 }
2606
2607 /** Request RSSI for a given remote device */
2608 bt_status_t read_remote_rssi(int client_if, const bt_bdaddr_t *bd_addr)
2609 {
2610         CHECK_BTGATT_INIT();
2611         return BT_STATUS_UNSUPPORTED;
2612 }
2613
2614 /** OTA firmware download */
2615 bt_status_t ota_fw_update(int client_if, int conn_id, const bt_bdaddr_t *bd_addr, char* path)
2616 {
2617         CHECK_BTGATT_INIT();
2618         return BT_STATUS_UNSUPPORTED;
2619 }
2620
2621 /** Determine the type of the remote device (LE, BR/EDR, Dual-mode) */
2622 int get_device_type(const bt_bdaddr_t *bd_addr)
2623 {
2624         CHECK_BTGATT_INIT();
2625         return BT_STATUS_UNSUPPORTED;
2626 }
2627
2628 static bt_status_t __hal_update_conn_parameter(bt_bdaddr_t *bd_addr,
2629                         int min_int, int max_int, int latency, int timeout)
2630 {
2631         gchar *device_path = NULL;
2632         GError *error = NULL;
2633         GDBusProxy *device_proxy = NULL;
2634         GDBusConnection *conn;
2635         GVariant *reply;
2636         int ret = BT_STATUS_SUCCESS;
2637         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
2638
2639         INFO("Min interval: %d, Max interval: %d, Latency: %d, Supervision timeout: %d",
2640                         min_int, max_int, latency, timeout);
2641
2642         conn = _bt_hal_get_system_gconn();
2643         if (conn == NULL) {
2644                 ERR("conn NULL");
2645                 return BT_STATUS_FAIL;
2646         }
2647
2648         _bt_hal_convert_addr_type_to_string(device_address,
2649                                 (unsigned char *)bd_addr->address);
2650         device_path = _bt_hal_get_device_object_path(device_address);
2651
2652         if (device_path == NULL) {
2653                 ERR("device_path NULL : [%s]", device_address);
2654                 return BT_STATUS_FAIL;
2655         }
2656
2657         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2658                         NULL, BT_HAL_BLUEZ_NAME,
2659                         device_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
2660
2661         g_free(device_path);
2662         if (NULL == device_proxy) {
2663                 ERR("device_proxy returned NULL");
2664                 return BT_STATUS_FAIL;
2665         }
2666
2667         DBG("Request LeConnUpdate");
2668         reply = g_dbus_proxy_call_sync(device_proxy, "LeConnUpdate",
2669                         g_variant_new("(uuuu)", min_int, max_int, latency, timeout),
2670                         G_DBUS_CALL_FLAGS_NONE,
2671                         -1,
2672                         NULL,
2673                         &error);
2674
2675         g_object_unref(device_proxy);
2676         if (reply == NULL) {
2677                 if (error) {
2678                         ERR("Error %s[%s]", error->message, device_address);
2679                         if (g_strrstr(error->message, "In Progress"))
2680                                 ret = BT_STATUS_SUCCESS;
2681                         else
2682                                 ret = BT_STATUS_FAIL;
2683                         g_error_free(error);
2684                         return ret;
2685                 }
2686         }
2687         g_variant_unref(reply);
2688
2689         DBG("LE Connection parameter Updated");
2690         return ret;
2691 }
2692
2693 /** Request a connection parameter update */
2694 bt_status_t btif_gattc_conn_parameter_update(bt_bdaddr_t *bd, int min_int, int max_int, int latency, int timeout)
2695 {
2696         CHECK_BTGATT_INIT();
2697
2698         return __hal_update_conn_parameter(bd, min_int, max_int, latency, timeout);
2699 }
2700
2701 /** Test mode interface */
2702 bt_status_t test_command(int command, btgatt_test_params_t* params)
2703 {
2704         CHECK_BTGATT_INIT();
2705         return BT_STATUS_UNSUPPORTED;
2706 }
2707
2708 static void __bt_request_att_mtu_device_cb(GDBusProxy *proxy, GAsyncResult *res,
2709                                                         gpointer user_data)
2710 {
2711         GError *g_error = NULL;
2712         GVariant *reply = NULL;
2713         int result = BT_STATUS_SUCCESS;
2714         struct hal_ev_gatt_client_mtu_exchange_completed  ev;
2715         struct conn_mtu_s *conn_mtu = (struct conn_mtu_s *)user_data;
2716
2717         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
2718         g_object_unref(proxy);
2719         if (reply == NULL) {
2720                 ERR("Connect LE Dbus Call Error");
2721                 if (g_error) {
2722                         ERR("Error occured in RequestAttMtu [%s]", g_error->message);
2723                         g_clear_error(&g_error);
2724                 }
2725                 result = BT_STATUS_FAIL;
2726         }
2727         g_variant_unref(reply);
2728
2729         memset(&ev, 0, sizeof(ev));
2730         ev.status = result;
2731         ev.mtu = conn_mtu->mtu;
2732         ev.conn_id = conn_mtu->conn_id;
2733
2734         if (!event_cb) {
2735                 ERR("gatt client callback not registered");
2736         } else {
2737                 DBG("sending gatt client MTU exchange completed event");
2738                 event_cb(HAL_EV_GATT_CLIENT_MTU_EXCHANGE_COMPLETED  , (void *)&ev, sizeof(ev));
2739         }
2740
2741         g_free(conn_mtu);
2742 }
2743
2744
2745 static bt_status_t __hal_configure_mtu(int conn_id, int mtu)
2746 {
2747         gchar *device_path = NULL;
2748         GDBusProxy *device_proxy = NULL;
2749         GDBusConnection *conn;
2750         hal_gattc_client_info_t *gattc_client = NULL;
2751         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
2752         struct conn_mtu_s *conn_mtu = g_malloc0(sizeof(struct conn_mtu_s));
2753
2754         conn = _bt_hal_get_system_gconn();
2755         if (conn == NULL) {
2756                 ERR("conn NULL");
2757                 g_free(conn_mtu);
2758                 return BT_STATUS_FAIL;
2759         }
2760
2761         gattc_client = __bt_find_gatt_client_info_from_conn_id(conn_id);
2762         if (gattc_client == NULL) {
2763                 INFO("GATT client conn info not found");
2764                 g_free(conn_mtu);
2765                 return BT_STATUS_FAIL;
2766         }
2767
2768         _bt_hal_convert_addr_type_to_string(device_address,
2769                                 (unsigned char *)gattc_client->bd_addr.address);
2770
2771         device_path = _bt_hal_get_device_object_path(device_address);
2772         if (device_path == NULL) {
2773                 ERR("device_path NULL : [%s]", device_address);
2774                 g_free(conn_mtu);
2775                 return BT_STATUS_FAIL;
2776         }
2777
2778         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2779                         NULL, BT_HAL_BLUEZ_NAME,
2780                         device_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
2781
2782         g_free(device_path);
2783         if (NULL == device_proxy) {
2784                 ERR("device_proxy returned NULL");
2785                 g_free(conn_mtu);
2786                 return BT_STATUS_FAIL;
2787         }
2788
2789         conn_mtu->conn_id = conn_id;
2790         conn_mtu->mtu = mtu;
2791
2792         g_dbus_proxy_call(device_proxy, "RequestAttMtu",
2793                         g_variant_new("(q)", mtu),
2794                         G_DBUS_CALL_FLAGS_NONE,
2795                         BT_HAL_MAX_DBUS_TIMEOUT,
2796                         NULL,
2797                         (GAsyncReadyCallback)__bt_request_att_mtu_device_cb,
2798                         conn_mtu);
2799
2800         return BT_STATUS_SUCCESS;
2801 }
2802
2803 /** MTU Exchange request from client */
2804 static bt_status_t configure_mtu(int conn_id, int mtu)
2805 {
2806         CHECK_BTGATT_INIT();
2807
2808         return __hal_configure_mtu(conn_id, mtu);
2809 }
2810
2811 /** Setup scan filter params */
2812 bt_status_t scan_filter_param_setup(int client_if, int action, int filt_index, int feat_seln,
2813                 int list_logic_type, int filt_logic_type, int rssi_high_thres,
2814                 int rssi_low_thres, int dely_mode, int found_timeout,
2815                 int lost_timeout, int found_timeout_cnt)
2816 {
2817         GDBusProxy *proxy;
2818         GError *error = NULL;
2819         GVariant *ret, *param;
2820         CHECK_BTGATT_INIT();
2821
2822         proxy = _bt_hal_get_adapter_proxy();
2823
2824         if (proxy == NULL)
2825                 return BT_STATUS_FAIL;
2826
2827         param = g_variant_new("(iiiiiiiiiiii)",
2828                                 client_if,
2829                                 action,
2830                                 filt_index,
2831                                 feat_seln,
2832                                 list_logic_type,
2833                                 filt_logic_type,
2834                                 rssi_high_thres,
2835                                 rssi_low_thres,
2836                                 dely_mode,
2837                                 found_timeout,
2838                                 lost_timeout,
2839                                 found_timeout_cnt);
2840         ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
2841                         param, G_DBUS_CALL_FLAGS_NONE,
2842                         -1, NULL, &error);
2843
2844         if (error) {
2845                 ERR("scan_filter_param_setup Fail: %s", error->message);
2846                 g_clear_error(&error);
2847                 return BT_STATUS_FAIL;
2848         }
2849
2850         if (ret)
2851                 g_variant_unref(ret);
2852
2853         return BT_STATUS_SUCCESS;
2854 }
2855
2856 /** Configure a scan filter condition */
2857 bt_status_t scan_filter_add_remove(int client_if, int action, int filt_type,
2858                 int filt_index, int company_id,
2859                 int company_id_mask, const bt_uuid_t *p_uuid,
2860                 const bt_uuid_t *p_uuid_mask, const bt_bdaddr_t *bd_addr,
2861                 char addr_type, int data_len, char* p_data, int mask_len,
2862                 char* p_mask)
2863 {
2864         GDBusProxy *proxy;
2865         GError *error = NULL;
2866         GVariant *ret, *param;
2867         GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
2868         GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
2869         GArray *arr_uuid = NULL;
2870         GArray *arr_uuid_mask = NULL;
2871         GArray *arr_data = NULL;
2872         GArray *arr_data_mask = NULL;
2873         CHECK_BTGATT_INIT();
2874
2875         proxy = _bt_hal_get_adapter_proxy();
2876
2877         if (proxy == NULL)
2878                 return BT_STATUS_FAIL;
2879
2880         if (filt_type == BT_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
2881
2882                 char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
2883
2884                 _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
2885
2886                 INFO("BT_SCAN_FILTER_FEATURE_DEVICE_ADDRESS being added\nRemote Device Address is [%s]", address);
2887
2888                 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
2889                                 NULL, 0, TRUE, NULL, NULL);
2890                 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2891                                 NULL, 0, TRUE, NULL, NULL);
2892                 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
2893                                 NULL, 0, TRUE, NULL, NULL);
2894                 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2895                                 NULL, 0, TRUE, NULL, NULL);
2896
2897                 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
2898                                         client_if,      // client_if
2899                                         action,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
2900                                         BT_SCAN_FILTER_FEATURE_DEVICE_ADDRESS,        // filter_type
2901                                         filt_index,       // filter_index
2902                                         company_id,      // company_id
2903                                         company_id_mask,      // company_id_mask
2904                                         arr_uuid_param, // p_uuid
2905                                         arr_uuid_mask_param,    // p_uuid_mask
2906                                         address,        // string
2907                                         addr_type,      // address_type
2908                                         arr_data_param, // p_data
2909                                         arr_data_mask_param);   // p_mask
2910
2911                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
2912                                 param, G_DBUS_CALL_FLAGS_NONE,
2913                                 -1, NULL, &error);
2914
2915                 if (error) {
2916                         ERR("scan_filter_add_remove Fail: %s", error->message);
2917                         g_clear_error(&error);
2918                         return BT_STATUS_FAIL;
2919                 }
2920
2921                 if (ret)
2922                         g_variant_unref(ret);
2923
2924                 return BT_STATUS_SUCCESS;
2925         }
2926
2927         if (filt_type == BT_SCAN_FILTER_FEATURE_DEVICE_NAME) {
2928
2929                 INFO("BT_SCAN_FILTER_FEATURE_DEVICE_NAME being added\nRemote Device Name is %s", p_data);
2930                 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
2931                                 NULL, 0, TRUE, NULL, NULL);
2932                 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2933                                 NULL, 0, TRUE, NULL, NULL);
2934                 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
2935                                 NULL, 0, TRUE, NULL, NULL);
2936                 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2937                                 NULL, 0, TRUE, NULL, NULL);
2938
2939                 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
2940                                         client_if,      // client_if
2941                                         action,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
2942                                         BT_SCAN_FILTER_FEATURE_DEVICE_NAME,   // filter_type
2943                                         filt_index,       // filter_index
2944                                         company_id,      // company_id
2945                                         company_id_mask,      // company_id_mask
2946                                         arr_uuid_param, // p_uuid
2947                                         arr_uuid_mask_param,    // p_uuid_mask
2948                                         p_data,    // string
2949                                         addr_type,      // address_type
2950                                         arr_data_param, // p_data
2951                                         arr_data_mask_param);
2952
2953                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
2954                                 param, G_DBUS_CALL_FLAGS_NONE,
2955                                 -1, NULL, &error);
2956
2957                 if (error) {
2958                         ERR("scan_filter_add_remove Fail: %s", error->message);
2959                         g_clear_error(&error);
2960                         return BT_STATUS_FAIL;
2961                 }
2962
2963                 if (ret)
2964                         g_variant_unref(ret);
2965
2966                 return BT_STATUS_SUCCESS;
2967         }
2968
2969         if (filt_type == BT_SCAN_FILTER_FEATURE_SERVICE_UUID) {
2970
2971                 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
2972                 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
2973
2974                 g_array_append_vals(arr_uuid, p_uuid->uu, data_len * sizeof(guint8));
2975                 g_array_append_vals(arr_uuid_mask, p_uuid_mask->uu, mask_len * sizeof(guint8));
2976
2977                 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
2978                                 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
2979                 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2980                                 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
2981                 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
2982                                 NULL, 0, TRUE, NULL, NULL);
2983                 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
2984                                 NULL, 0, TRUE, NULL, NULL);
2985
2986                 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
2987                                         client_if,      // client_if
2988                                         action,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
2989                                         BT_SCAN_FILTER_FEATURE_SERVICE_UUID,  // filter_type
2990                                         filt_index,       // filter_index
2991                                         company_id,      // company_id
2992                                         company_id_mask,      // company_id_mask
2993                                         arr_uuid_param, // p_uuid
2994                                         arr_uuid_mask_param,    // p_uuid_mask
2995                                         "",   // string
2996                                         addr_type,      // address_type
2997                                         arr_data_param, // p_data
2998                                         arr_data_mask_param);
2999
3000                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
3001                                 param, G_DBUS_CALL_FLAGS_NONE,
3002                                 -1, NULL, &error);
3003
3004                 if (error) {
3005                         ERR("scan_filter_add_remove Fail: %s", error->message);
3006                         g_clear_error(&error);
3007                         return BT_STATUS_FAIL;
3008                 }
3009
3010                 if (ret)
3011                         g_variant_unref(ret);
3012
3013                 g_array_free(arr_uuid, TRUE);
3014                 g_array_free(arr_uuid_mask, TRUE);
3015
3016                 return BT_STATUS_SUCCESS;
3017         }
3018
3019         if (filt_type == BT_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
3020
3021                 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
3022                 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
3023
3024                 g_array_append_vals(arr_uuid, p_uuid->uu, data_len * sizeof(guint8));
3025                 g_array_append_vals(arr_uuid_mask, p_uuid_mask->uu, mask_len * sizeof(guint8));
3026
3027                 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
3028                                 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
3029                 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
3030                                 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
3031                 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
3032                                 NULL, 0, TRUE, NULL, NULL);
3033                 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
3034                                 NULL, 0, TRUE, NULL, NULL);
3035
3036                 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
3037                                         client_if,      // client_if
3038                                         action,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
3039                                         BT_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID,     // filter_type
3040                                         filt_index,       // filter_index
3041                                         company_id,      // company_id
3042                                         company_id_mask,      // company_id_mask
3043                                         arr_uuid_param, // p_uuid
3044                                         arr_uuid_mask_param,    // p_uuid_mask
3045                                         "",   // string
3046                                         addr_type,      // address_type
3047                                         arr_data_param, // p_data
3048                                         arr_data_mask_param);
3049
3050                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
3051                                 G_DBUS_CALL_FLAGS_NONE,
3052                                 -1, NULL, &error);
3053
3054                 if (error) {
3055                         ERR("scan_filter_add_remove Fail: %s", error->message);
3056                         g_clear_error(&error);
3057                         return BT_STATUS_FAIL;
3058                 }
3059
3060                 if (ret)
3061                         g_variant_unref(ret);
3062
3063                 g_array_free(arr_uuid, TRUE);
3064                 g_array_free(arr_uuid_mask, TRUE);
3065
3066                 return BT_STATUS_SUCCESS;
3067         }
3068
3069         if (filt_type == BT_SCAN_FILTER_FEATURE_SERVICE_DATA) {
3070
3071                 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
3072                 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
3073
3074                 g_array_append_vals(arr_data, p_data, data_len * sizeof(guint8));
3075                 g_array_append_vals(arr_data_mask, p_mask, mask_len * sizeof(guint8));
3076
3077                 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
3078                                 NULL, 0, TRUE, NULL, NULL);
3079                 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
3080                                 NULL, 0, TRUE, NULL, NULL);
3081                 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
3082                                 arr_data->data, arr_data->len, TRUE, NULL, NULL);
3083                                 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
3084                                 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
3085
3086                 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
3087                                         client_if,      // client_if
3088                                         action,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
3089                                         BT_SCAN_FILTER_FEATURE_SERVICE_DATA,  // filter_type
3090                                         filt_index,       // filter_index
3091                                         company_id,      // company_id
3092                                         company_id_mask,      // company_id_mask
3093                                         arr_uuid_param, // p_uuid
3094                                         arr_uuid_mask_param,    // p_uuid_mask
3095                                         "",   // string
3096                                         addr_type,      // address_type
3097                                         arr_data_param, // p_data
3098                                         arr_data_mask_param);
3099
3100                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
3101                                 G_DBUS_CALL_FLAGS_NONE,
3102                                 -1, NULL, &error);
3103
3104                 if (error) {
3105                         ERR("scan_filter_add_remove Fail: %s", error->message);
3106                         g_clear_error(&error);
3107                         return BT_STATUS_FAIL;
3108                 }
3109
3110                 if (ret)
3111                         g_variant_unref(ret);
3112
3113                 g_array_free(arr_data, TRUE);
3114                 g_array_free(arr_data_mask, TRUE);
3115
3116                 return BT_STATUS_SUCCESS;
3117         }
3118
3119         if (filt_type == BT_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
3120
3121                 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
3122                 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
3123
3124                 g_array_append_vals(arr_data, p_data, data_len * sizeof(guint8));
3125                 g_array_append_vals(arr_data_mask, p_mask, mask_len * sizeof(guint8));
3126
3127                 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
3128                                 NULL, 0, TRUE, NULL, NULL);
3129                 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
3130                                 NULL, 0, TRUE, NULL, NULL);
3131                 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
3132                                 arr_data->data, arr_data->len, TRUE, NULL, NULL);
3133                 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
3134                                 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
3135
3136                 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
3137                                         client_if,      // client_if
3138                                         action,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
3139                                         BT_SCAN_FILTER_FEATURE_MANUFACTURER_DATA,     // filter_type
3140                                         filt_index,       // filter_index
3141                                         company_id,        // company_id
3142                                         company_id_mask, // company_id_mask
3143                                         arr_uuid_param, // p_uuid
3144                                         arr_uuid_mask_param,    // p_uuid_mask
3145                                         "",   // string
3146                                         addr_type,      // address_type
3147                                         arr_data_param, // p_data
3148                                         arr_data_mask_param);
3149
3150                 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
3151                                 G_DBUS_CALL_FLAGS_NONE,
3152                                 -1, NULL, &error);
3153
3154                 if (error) {
3155                         ERR("scan_filter_add_remove Fail: %s", error->message);
3156                         g_clear_error(&error);
3157                         return BT_STATUS_FAIL;
3158                 }
3159
3160                 if (ret)
3161                         g_variant_unref(ret);
3162
3163                 g_array_free(arr_data, TRUE);
3164                 g_array_free(arr_data_mask, TRUE);
3165
3166                 return BT_STATUS_SUCCESS;
3167         }
3168
3169         return BT_STATUS_UNSUPPORTED;
3170 }
3171
3172 /** Clear all scan filter conditions for specific filter index*/
3173 bt_status_t scan_filter_clear(int client_if, int filt_index)
3174 {
3175         GDBusProxy *proxy;
3176         GError *error = NULL;
3177         GVariant *ret;
3178         CHECK_BTGATT_INIT();
3179
3180         proxy = _bt_hal_get_adapter_proxy();
3181         if (proxy == NULL)
3182                 return BT_STATUS_FAIL;
3183
3184         ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
3185                                 g_variant_new("(ii)", client_if, filt_index),
3186                                 G_DBUS_CALL_FLAGS_NONE,
3187                                 -1, NULL, &error);
3188
3189         if (error) {
3190                 ERR("scan_filter_clear Fail: %s", error->message);
3191                 g_clear_error(&error);
3192                 return BT_STATUS_FAIL;
3193         }
3194         if (ret)
3195                 g_variant_unref(ret);
3196         return BT_STATUS_SUCCESS;
3197 }
3198
3199 /** Enable / disable scan filter feature*/
3200 bt_status_t scan_filter_enable(int client_if, bool enable)
3201 {
3202         GDBusProxy *proxy;
3203         GError *error = NULL;
3204         GVariant *ret;
3205         CHECK_BTGATT_INIT();
3206
3207         proxy = _bt_hal_get_adapter_proxy();
3208         if (proxy == NULL)
3209                 return BT_STATUS_FAIL;
3210
3211         ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
3212                                 g_variant_new("(ib)", client_if, enable),
3213                                 G_DBUS_CALL_FLAGS_NONE,
3214                                 -1, NULL, &error);
3215
3216         if (error) {
3217                 ERR("scan_filter_enable Fail: %s", error->message);
3218                 g_clear_error(&error);
3219                 return BT_STATUS_FAIL;
3220         }
3221         g_variant_unref(ret);
3222
3223         return BT_STATUS_SUCCESS;
3224 }
3225
3226 /** Sets the LE scan interval and window in units of N*0.625 msec */
3227 #ifdef TIZEN_BT_HAL
3228 bt_status_t set_scan_parameters(int scan_type, int scan_interval, int scan_window)
3229 {
3230         int ret;
3231
3232         CHECK_BTGATT_INIT();
3233
3234         le_scan_type = scan_type;
3235         ret = _bt_hal_adapter_le_set_scan_parameters(
3236                         scan_type, scan_interval, scan_window);
3237         return ret;
3238 }
3239 #else
3240 bt_status_t set_scan_parameters(int scan_interval, int scan_window)
3241 {
3242         CHECK_BTGATT_INIT();
3243         return BT_STATUS_UNSUPPORTED;
3244 }
3245 #endif
3246
3247 /* Configure the batchscan storage */
3248 bt_status_t batchscan_cfg_storage(int client_if, int batch_scan_full_max,
3249                 int batch_scan_trunc_max, int batch_scan_notify_threshold)
3250 {
3251         CHECK_BTGATT_INIT();
3252         return BT_STATUS_UNSUPPORTED;
3253 }
3254
3255 /* Enable batchscan */
3256 bt_status_t batchscan_enb_batch_scan(int client_if, int scan_mode,
3257                 int scan_interval, int scan_window, int addr_type, int discard_rule)
3258 {
3259         CHECK_BTGATT_INIT();
3260         return BT_STATUS_UNSUPPORTED;
3261 }
3262
3263 /* Disable batchscan */
3264 bt_status_t batchscan_dis_batch_scan(int client_if)
3265 {
3266         CHECK_BTGATT_INIT();
3267         return BT_STATUS_UNSUPPORTED;
3268 }
3269
3270 /* Read out batchscan reports */
3271 bt_status_t batchscan_read_reports(int client_if, int scan_mode)
3272 {
3273         CHECK_BTGATT_INIT();
3274         return BT_STATUS_UNSUPPORTED;
3275 }
3276
3277 bt_status_t btif_gatt_get_data_batching_available_packets(unsigned int *available_packets)
3278 {
3279         GDBusProxy *proxy;
3280         GError *error = NULL;
3281         GVariant *ret;
3282         guint32 available_pkts;
3283
3284         CHECK_BTGATT_INIT();
3285
3286         if (available_packets == NULL) {
3287                 ERR("available_packets is NULL");
3288                 return BT_STATUS_PARM_INVALID;
3289         }
3290
3291         proxy = _bt_hal_get_adapter_proxy();
3292         if (proxy == NULL) {
3293                 ERR("proxy is NULL");
3294                 return BT_STATUS_FAIL;
3295         }
3296
3297         ret = g_dbus_proxy_call_sync(proxy, "GetLeBatchingAvailablePkts",
3298                                 NULL,
3299                                 G_DBUS_CALL_FLAGS_NONE,
3300                                 -1, NULL, &error);
3301         if (error) {
3302                 int result = BT_STATUS_FAIL;
3303
3304                 ERR("SetLeBatchingParam Fail: %s", error->message);
3305                 if (g_strrstr(error->message, "Operation is not supported"))
3306                         result = BT_STATUS_UNSUPPORTED;
3307
3308                 g_clear_error(&error);
3309                 return result;
3310         }
3311         g_variant_get(ret, "(u)", &available_pkts);
3312         g_variant_unref(ret);
3313
3314         INFO("GATT Batching available packets: %u", available_pkts);
3315         *available_packets = available_pkts;
3316         return BT_STATUS_SUCCESS;
3317 }
3318
3319 bt_status_t btif_gatt_enable_data_batching(const bt_bdaddr_t *bd_addr, int packet_threshold, int timeout)
3320 {
3321         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
3322         GDBusProxy *proxy;
3323         GError *error = NULL;
3324         GVariant *ret;
3325         CHECK_BTGATT_INIT();
3326
3327         if (bd_addr == NULL) {
3328                 ERR("bd_addr is NULL");
3329                 return BT_STATUS_PARM_INVALID;
3330         }
3331
3332         proxy = _bt_hal_get_adapter_proxy();
3333         if (proxy == NULL) {
3334                 ERR("proxy is NULL");
3335                 return BT_STATUS_FAIL;
3336         }
3337
3338         _bt_hal_convert_addr_type_to_string(device_address,
3339                         (unsigned char *)bd_addr->address);
3340         ret = g_dbus_proxy_call_sync(proxy, "EnableLeBatching",
3341                                 g_variant_new("(sii)", device_address, packet_threshold, timeout),
3342                                 G_DBUS_CALL_FLAGS_NONE,
3343                                 -1, NULL, &error);
3344         if (error) {
3345                 int result = BT_STATUS_FAIL;
3346
3347                 ERR("SetLeBatchingParam Fail: %s", error->message);
3348                 if (g_strrstr(error->message, "Operation is not supported"))
3349                         result = BT_STATUS_UNSUPPORTED;
3350                 else if (g_strrstr(error->message, "Invalid arguments"))
3351                         result = BT_STATUS_PARM_INVALID;
3352
3353                 g_clear_error(&error);
3354                 return result;
3355         }
3356         g_variant_unref(ret);
3357
3358         INFO("GATT Batching is enabled");
3359         return BT_STATUS_SUCCESS;
3360 }
3361
3362 bt_status_t btif_gatt_disable_data_batching(const bt_bdaddr_t *bd_addr)
3363 {
3364         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
3365         GDBusProxy *proxy;
3366         GError *error = NULL;
3367         GVariant *ret;
3368         CHECK_BTGATT_INIT();
3369
3370         if (bd_addr == NULL) {
3371                 ERR("bd_addr is NULL");
3372                 return BT_STATUS_PARM_INVALID;
3373         }
3374
3375         proxy = _bt_hal_get_adapter_proxy();
3376         if (proxy == NULL) {
3377                 ERR("proxy is NULL");
3378                 return BT_STATUS_FAIL;
3379         }
3380
3381         _bt_hal_convert_addr_type_to_string(device_address,
3382                         (unsigned char *)bd_addr->address);
3383         ret = g_dbus_proxy_call_sync(proxy, "DisableLeBatching",
3384                                 g_variant_new("(s)", device_address),
3385                                 G_DBUS_CALL_FLAGS_NONE,
3386                                 -1, NULL, &error);
3387         if (error) {
3388                 int result = BT_STATUS_FAIL;
3389
3390                 ERR("SetLeBatching Fail: %s", error->message);
3391                 if (g_strrstr(error->message, "Operation is not supported"))
3392                         result = BT_STATUS_UNSUPPORTED;
3393
3394                 g_clear_error(&error);
3395                 return result;
3396         }
3397         g_variant_unref(ret);
3398
3399         INFO("GATT Batching is disabled");
3400         return BT_STATUS_SUCCESS;
3401 }
3402
3403 const btgatt_client_interface_t btgatt_client_interface = {
3404         .register_client = btif_gattc_register_client,
3405         .unregister_client = btif_gattc_unregister_client,
3406         .scan = scan,
3407         .connect = btif_gattc_client_connect,
3408         .disconnect = btif_gattc_client_disconnect,
3409         .refresh = refresh,
3410         .search_service = btif_gattc_client_search_service,
3411         .get_included_service = get_included_service,
3412         .get_characteristic = btif_gattc_get_characteristic,
3413         .get_descriptor = btif_gattc_get_descriptor,
3414         .read_characteristic = btif_read_characteristic,
3415         .write_characteristic = btif_write_characteristic,
3416         .acquire_write = btif_get_acquire_write_fd,
3417         .acquire_notify = btif_get_acquire_notify_fd,
3418         .read_descriptor = btif_read_descriptor,
3419         .write_descriptor = btif_write_descriptor,
3420         .execute_write = execute_write,
3421         .register_for_notification = btif_register_for_notification,
3422         .deregister_for_notification = btif_deregister_for_notification,
3423         .read_remote_rssi = read_remote_rssi,
3424         .ota_fw_update = ota_fw_update,
3425         .get_device_type = get_device_type,
3426         .conn_parameter_update = btif_gattc_conn_parameter_update,
3427         .test_command = test_command,
3428         .configure_mtu = configure_mtu,
3429         .scan_filter_param_setup = scan_filter_param_setup,
3430         .scan_filter_add_remove = scan_filter_add_remove,
3431         .scan_filter_clear = scan_filter_clear,
3432         .scan_filter_enable = scan_filter_enable,
3433         .set_scan_parameters = set_scan_parameters,
3434         .batchscan_cfg_storage = batchscan_cfg_storage,
3435         .batchscan_enb_batch_scan = batchscan_enb_batch_scan,
3436         .batchscan_dis_batch_scan = batchscan_dis_batch_scan,
3437         .batchscan_read_reports = batchscan_read_reports,
3438         .add_connection_info = btif_gattc_add_connection_info,
3439         .get_data_batching_available_packets = btif_gatt_get_data_batching_available_packets,
3440         .enable_data_batching = btif_gatt_enable_data_batching,
3441         .disable_data_batching = btif_gatt_disable_data_batching,
3442 };
3443
3444 static hal_gattc_server_info_t *__bt_find_gatt_conn_info(const bt_bdaddr_t *serv_addr)
3445 {
3446         GSList *l;
3447         hal_gattc_server_info_t *info = NULL;
3448
3449         for (l = hal_gattc_server_info_list; l != NULL; l = g_slist_next(l)) {
3450                 info = (hal_gattc_server_info_t*)l->data;
3451                 if (info == NULL)
3452                         continue;
3453
3454                 if (!memcmp(&info->bd_addr, serv_addr, sizeof(bt_bdaddr_t)))
3455                         return info;
3456         }
3457
3458         return NULL;
3459 }
3460
3461 static hal_gattc_client_info_t *__bt_find_gatt_client_info(bt_bdaddr_t *serv_addr)
3462 {
3463         GSList *l;
3464         hal_gattc_client_info_t *info = NULL;
3465
3466         for (l = hal_gattc_client_info_list; l != NULL; l = g_slist_next(l)) {
3467                 info = (hal_gattc_client_info_t*)l->data;
3468                 if (info == NULL)
3469                         continue;
3470
3471                 if (!memcmp(&info->bd_addr, serv_addr, sizeof(bt_bdaddr_t)))
3472                         return info;
3473         }
3474
3475         return NULL;
3476 }
3477
3478 static hal_gattc_client_info_t *__bt_find_gatt_client_info_from_conn_id(int conn_id)
3479 {
3480         GSList *l;
3481         hal_gattc_client_info_t *info = NULL;
3482
3483         for (l = hal_gattc_client_info_list; l != NULL; l = g_slist_next(l)) {
3484                 info = (hal_gattc_client_info_t*)l->data;
3485                 if (info == NULL)
3486                         continue;
3487
3488                 if (info->conn_id == conn_id)
3489                         return info;
3490         }
3491
3492         return NULL;
3493 }
3494
3495 static hal_gattc_server_info_t *__bt_find_gatt_conn_info_from_conn_id(int  conn_id)
3496 {
3497         GSList *l;
3498         hal_gattc_server_info_t *info = NULL;
3499         hal_gattc_client_info_t *gattc_client = NULL;
3500
3501         gattc_client = __bt_find_gatt_client_info_from_conn_id(conn_id);
3502         if (gattc_client == NULL) {
3503                 ERR("GATT client conn info not found");
3504                 return NULL;
3505         }
3506
3507         for (l = hal_gattc_server_info_list; l != NULL; l = g_slist_next(l)) {
3508                 info = (hal_gattc_server_info_t*)l->data;
3509                 if (info == NULL)
3510                         continue;
3511
3512                 if ((info->inst_id == gattc_client->inst_id) &&
3513                         !memcmp(&info->bd_addr, &gattc_client->bd_addr, sizeof(bt_bdaddr_t))) {
3514                         return info;
3515                 }
3516         }
3517         return NULL;
3518 }
3519
3520 static bt_status_t __bt_connect_le_device_internal(int client_if, const bt_bdaddr_t *bd_addr,
3521                 gboolean auto_connect)
3522 {
3523         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
3524         gchar *device_path = NULL;
3525         GDBusProxy *device_proxy = NULL;
3526         GDBusConnection *conn;
3527         int ret = BT_STATUS_SUCCESS;
3528         hal_gattc_client_info_t *gattc_data;
3529
3530         if (NULL == bd_addr) {
3531                 ERR("bd_addr is NULL");
3532                 return BT_STATUS_PARM_INVALID;
3533         }
3534
3535         conn = _bt_hal_get_system_gconn();
3536         if (NULL == conn) {
3537                 ERR("_bt_gdbus_get_system_gconn returned NULL");
3538                 return BT_STATUS_FAIL;
3539         }
3540
3541         _bt_hal_convert_addr_type_to_string(device_address,
3542                         (unsigned char *)bd_addr->address);
3543         device_path = _bt_hal_get_device_object_path(device_address);
3544         if (device_path == NULL) {
3545                 ERR("device_path NULL : [%s]", device_address);
3546                 ret = BT_STATUS_FAIL;
3547                 return ret;
3548         }
3549
3550         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
3551                         NULL, BT_HAL_BLUEZ_NAME,
3552                         device_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
3553         g_free(device_path);
3554         if (NULL == device_proxy) {
3555                 ERR("device_proxy returned NULL");
3556                 return BT_STATUS_FAIL;
3557         }
3558
3559         gattc_data = g_malloc0(sizeof(hal_gattc_client_info_t));
3560         memcpy(gattc_data->bd_addr.address, bd_addr->address,
3561                                         BT_HAL_ADDRESS_LENGTH_MAX);
3562
3563         DBG("ConnectLE [%s]", device_address);
3564
3565         gattc_data->client_if = client_if;
3566
3567         g_dbus_proxy_call(device_proxy, "ConnectLE",
3568                         g_variant_new("(b)", auto_connect),
3569                         G_DBUS_CALL_FLAGS_NONE,
3570                         BT_HAL_MAX_DBUS_TIMEOUT,
3571                         NULL,
3572                         (GAsyncReadyCallback)__le_connection_req_cb, gattc_data);
3573
3574         return ret;
3575 }
3576
3577 static bt_status_t _bt_hold_current_advertising()
3578 {
3579         int ret = BT_STATUS_FAIL;
3580         gboolean is_advertising = FALSE;
3581         DBG("+");
3582
3583         if (_bt_hal_is_support_multi_adv() == TRUE) {
3584                 DBG("VSC adv used");
3585                 return BT_STATUS_SUCCESS;
3586         }
3587
3588         /* Dependent on Kernel operation. Hold adv to prevent stopping adv on kernel  */
3589         is_advertising = _bt_hal_is_advertising_in_slot(0);
3590         if (is_advertising) {
3591                 DBG("+ Stop current advertising");
3592
3593                 ret = _bt_hal_enable_advertising(0, 0, FALSE, FALSE);
3594                 g_timeout_add(2000, __bt_hold_current_advertising_timeout_cb, NULL);
3595         }
3596
3597         return ret;
3598 }
3599
3600 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
3601 {
3602         DBG("+ start current advertising");
3603
3604         _bt_hal_enable_advertising(0, 0, TRUE, FALSE);
3605
3606         return FALSE;
3607 }
3608
3609 static gboolean __bt_connect_le_timer_cb(gpointer user_data)
3610 {
3611         DBG("Try to initiate pending LE connection");
3612
3613         pending_le_conn_timer_id = 0;
3614
3615         __bt_connect_le_device_internal(pending_le_conn_info->client_if,
3616                         &pending_le_conn_info->bd_addr,
3617                         pending_le_conn_info->auto_connect);
3618
3619         g_free(pending_le_conn_info);
3620         pending_le_conn_info = NULL;
3621
3622         return FALSE;
3623 }
3624
3625 static int __hal_generate_conn_id()
3626 {
3627          return ++hal_gatt_conn_id;
3628 }
3629
3630 static int __hal_generate_server_instance_id()
3631 {
3632         return ++bt_inst_id;
3633 }
3634
3635 static void __le_connection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
3636                 gpointer user_data)
3637 {
3638         GError *g_error = NULL;
3639         GVariant *reply = NULL;
3640         hal_gattc_client_info_t *gattc_data  = user_data;
3641         int result = BT_STATUS_SUCCESS;
3642         struct hal_ev_gatt_client_connected ev;
3643         hal_gattc_server_info_t *gatt_conn_info = NULL;
3644
3645         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
3646         g_object_unref(proxy);
3647         if (reply == NULL) {
3648                 ERR("Connect LE Dbus Call Error");
3649                 if (g_error) {
3650                         ERR("Error: %s\n", g_error->message);
3651                         g_clear_error(&g_error);
3652                 }
3653                 result = BT_STATUS_FAIL;
3654         }
3655         g_variant_unref(reply);
3656
3657         if (NULL == gattc_data) {
3658                 ERR("gattc_data is NULL");
3659                 return;
3660         }
3661
3662         /*send fail event*/
3663         if (result == BT_STATUS_FAIL) {
3664                 memset(&ev, 0, sizeof(ev));
3665                 ev.conn_id = -1;
3666                 ev.status = result;
3667                 ev.client_if = gattc_data->client_if;
3668                 memcpy(ev.bdaddr, gattc_data->bd_addr.address,
3669                                                 BT_HAL_ADDRESS_LENGTH_MAX);
3670
3671                 if (!event_cb) {
3672                         ERR("gatt client callback not registered");
3673                 } else {
3674                         DBG("sending gatt client connected event");
3675                         event_cb(HAL_EV_GATT_CLIENT_CONNECTED, (void *)&ev, sizeof(ev));
3676                 }
3677
3678                 goto fail;
3679         }
3680
3681         DBG("LE connected. Adding the gattc server/client conn info in list");
3682         gattc_data->conn_id = __hal_generate_conn_id() ;
3683         gattc_data->inst_id = __hal_generate_server_instance_id();
3684
3685         hal_gattc_client_info_list = g_slist_append(hal_gattc_client_info_list, gattc_data);
3686
3687         /*add gatt server connection info*/
3688         gatt_conn_info = g_malloc0(sizeof(hal_gattc_server_info_t));
3689         memcpy(gatt_conn_info->bd_addr.address, gattc_data->bd_addr.address, BT_HAL_ADDRESS_LENGTH_MAX);
3690         gatt_conn_info->conn_id = gattc_data->conn_id;
3691         gatt_conn_info->inst_id = gattc_data->inst_id;
3692         hal_gattc_server_info_list = g_slist_append(hal_gattc_server_info_list, gatt_conn_info);
3693
3694         return;
3695
3696 fail:
3697         /*remove conn_info*/
3698         if (gattc_data)
3699                 g_free(gattc_data);
3700 }
3701
3702 static void __hal_gattc_free_desc_info(hal_gattc_desc_t *desc_info)
3703 {
3704         g_free(desc_info->desc_path);
3705         g_free(desc_info);
3706 }
3707
3708 static void __hal_gattc_free_char_info(hal_gattc_char_t *char_info)
3709 {
3710         GSList *l = NULL;
3711         hal_gattc_desc_t *desc_info = NULL;
3712         for (l = char_info->gatt_list_descs; l != NULL; ) {
3713                 desc_info = l->data;
3714                 l = g_slist_next(l);
3715                 if (desc_info == NULL)
3716                         continue;
3717                 /* Remove descriptor element */
3718                 char_info->gatt_list_descs = g_slist_remove(char_info->gatt_list_descs, desc_info);
3719                 __hal_gattc_free_desc_info(desc_info);
3720         }
3721         g_slist_free(char_info->gatt_list_descs);
3722         g_free(char_info->chr_path);
3723         g_free(char_info);
3724 }
3725
3726 static void __hal_gattc_free_svc_info(hal_gattc_service_t *svc_info)
3727 {
3728         GSList *l = NULL;
3729         hal_gattc_char_t *char_info = NULL;
3730         for (l = svc_info->gatt_list_chars; l != NULL; ) {
3731                 char_info = l->data;
3732                 l = g_slist_next(l);
3733                 if (char_info == NULL)
3734                         continue;
3735                 /* Remove characteristic element */
3736                 svc_info->gatt_list_chars = g_slist_remove(svc_info->gatt_list_chars, char_info);
3737                 __hal_gattc_free_char_info(char_info);
3738         }
3739         g_slist_free(svc_info->gatt_list_chars);
3740         g_free(svc_info->svc_path);
3741         g_free(svc_info);
3742 }
3743
3744 static void __hal_clean_gattc_server_info(hal_gattc_server_info_t *conn_info)
3745 {
3746         GSList *l = NULL;
3747         hal_gattc_service_t *svc_info = NULL;
3748
3749         DBG("+");
3750
3751         for (l = conn_info->gatt_list_services; l != NULL; ) {
3752                 svc_info = (hal_gattc_service_t *)l->data;
3753                 l = g_slist_next(l);
3754                 if (svc_info == NULL)
3755                         continue;
3756                 /* Remove service element */
3757                 conn_info->gatt_list_services = g_slist_remove(conn_info->gatt_list_services, svc_info);
3758                 __hal_gattc_free_svc_info(svc_info);
3759         }
3760         g_slist_free(conn_info->gatt_list_services);
3761         g_free(conn_info);
3762 }
3763
3764 gboolean _bt_hal_check_gattc_is_existing(const char *address)
3765 {
3766         bt_bdaddr_t bd_addr;
3767         _bt_hal_convert_addr_string_to_type(bd_addr.address, address);
3768         if (__bt_find_gatt_client_info(&bd_addr) != NULL)
3769                 return TRUE;
3770         else
3771                 return FALSE;
3772 }
3773
3774 int _bt_hal_handle_gattc_connected_event(char* address, gboolean gatt_connected)
3775 {
3776         int result = BT_STATUS_SUCCESS;
3777         struct hal_ev_gatt_client_connected ev;
3778         hal_gattc_server_info_t *conn_info = NULL;
3779         bt_bdaddr_t bd_addr;
3780         int event;
3781         hal_gattc_client_info_t *gattc_client = NULL;
3782         int inst_id = -1;
3783
3784         event = gatt_connected ? HAL_EV_GATT_CLIENT_CONNECTED :
3785                                 HAL_EV_GATT_CLIENT_DISCONNECTED;
3786
3787         _bt_hal_convert_addr_string_to_type(bd_addr.address, address);
3788         /* find the gatt client info */
3789         gattc_client = __bt_find_gatt_client_info(&bd_addr);
3790         if (NULL == gattc_client) {
3791                 ERR("Fail to get gatt client info");
3792                 return -1;
3793         }
3794
3795         gattc_client->is_gatt_connected = gatt_connected;
3796
3797         //send event
3798         memset(&ev, 0, sizeof(ev));
3799         ev.conn_id = gattc_client->conn_id;
3800         ev.status = result;
3801         ev.client_if = gattc_client->client_if;
3802         memcpy(ev.bdaddr, gattc_client->bd_addr.address,
3803                                 BT_HAL_ADDRESS_LENGTH_MAX);
3804
3805         if (!event_cb) {
3806                 ERR("gatt client callback not registered");
3807         } else {
3808                 event_cb(event, (void *)&ev, sizeof(ev));
3809         }
3810
3811         if (!gatt_connected) {
3812                 inst_id = gattc_client->inst_id;
3813
3814                 /* remove the gatt client info from the client list also*/
3815                 hal_gattc_client_info_list = g_slist_remove(hal_gattc_client_info_list, gattc_client);
3816                 g_free(gattc_client);
3817
3818                 //find the connected server info
3819                 conn_info = __bt_find_gatt_conn_info(&bd_addr);
3820                 if (NULL == conn_info) {
3821                         ERR("Fail to get gatt server info");
3822                         return -1;
3823                 }
3824
3825                 if (inst_id != conn_info->inst_id) {
3826                         ERR("server instance is different");
3827                         return -1;
3828                 }
3829
3830                 //remove gatt conn info from the server list
3831                 DBG("remove the server conn_info from list after gatt disconnection");
3832                 hal_gattc_server_info_list = g_slist_remove(hal_gattc_server_info_list, conn_info);
3833                 __hal_clean_gattc_server_info(conn_info);
3834         }
3835
3836         return 0;
3837 }
3838
3839 static void _bt_hal_send_search_service_result_event(int conn_id, int is_primary,
3840                                                 const char* uuid_str, int inst_id)
3841 {
3842         struct hal_ev_gatt_client_search_result ev;
3843
3844          if (!event_cb) {
3845                 ERR("gatt client callback not registered");
3846                 return;
3847         }
3848
3849         DBG("Send service searching result. [%s] conn_id[%d]", uuid_str, conn_id);
3850
3851         memset(&ev, 0, sizeof(ev));
3852         ev.conn_id = conn_id;
3853         ev.inst_id = inst_id;
3854         ev.is_primary = is_primary;
3855         _bt_hal_convert_uuid_string_to_type(ev.uuid, uuid_str);
3856
3857         event_cb(HAL_EV_GATT_CLIENT_SEARCH_RESULT, (void *)&ev, sizeof(ev));
3858 }
3859
3860 static void _bt_hal_send_search_service_complete_event(int conn_id, int status)
3861 {
3862         struct hal_ev_gatt_client_search_complete ev;
3863
3864          if (!event_cb) {
3865                 ERR("gatt client callback not registered");
3866                 return;
3867         }
3868
3869         DBG("sending gatt client search service complete event conn_id[%d]", conn_id);
3870
3871
3872         memset(&ev, 0, sizeof(ev));
3873         ev.conn_id = conn_id;
3874         ev.status = status;
3875
3876         event_cb(HAL_EV_GATT_CLIENT_SEARCH_COMPLETE, (void *)&ev, sizeof(ev));
3877 }
3878
3879 static void _bt_hal_send_value_changed_event(hal_gattc_server_info_t *conn_info,
3880                 hal_gattc_service_t *svc_info, hal_gattc_char_t *char_info,
3881                 char *char_value, int len)
3882 {
3883         struct hal_ev_gatt_client_notify_changed_value ev;
3884         hal_gattc_client_info_t *gattc_client = NULL;
3885
3886         if (!event_cb) {
3887                 ERR("gatt client callback not registered");
3888                 return;
3889         }
3890
3891         gattc_client = __bt_find_gatt_client_info(&conn_info->bd_addr);
3892         if (NULL == gattc_client) {
3893                 ERR("failed to get the gatt client info");
3894                 return ;
3895         }
3896
3897         //send event
3898         DBG("sending gatt client connected status  event");
3899         memset(&ev, 0, sizeof(ev));
3900
3901         ev.conn_id = gattc_client->conn_id;
3902         ev.inst_id = conn_info->inst_id;
3903         ev.is_primary = svc_info->is_primary;
3904         memcpy(ev.svc_uuid, svc_info->svc_uuid.uu, sizeof(ev.svc_uuid));
3905         memcpy(ev.char_uuid, char_info->chr_uuid.uu, sizeof(ev.char_uuid));
3906
3907         memcpy(ev.bdaddr, conn_info->bd_addr.address, BT_HAL_ADDRESS_LENGTH_MAX);
3908
3909         if (len > 0 && (char_value != NULL)) {
3910                 memcpy(ev.value, char_value, len);
3911                 ev.len = len;
3912         }
3913
3914         event_cb(HAL_EV_GATT_CLIENT_NOTIFY_CHANGED_VALUE, (void *)&ev, sizeof(ev));
3915 }
3916
3917 void _bt_hal_handle_gattc_value_changed_event(int result, const char *char_handle,
3918                                                 char *char_value, int len)
3919 {
3920         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
3921         hal_gattc_server_info_t *conn_info = NULL;
3922         bt_bdaddr_t bd_addr;
3923         GSList *l;
3924         GSList *k;
3925         hal_gattc_service_t *svc_info = NULL;
3926         hal_gattc_char_t *char_info = NULL;
3927
3928         DBG("+");
3929
3930         _bt_hal_convert_device_path_to_address(char_handle, device_address);
3931         device_address[BT_HAL_ADDRESS_STRING_SIZE - 1] = '\0';
3932         DBG("device address:[%s]", device_address);
3933         DBG("char handle:[%s]", char_handle);
3934
3935         _bt_hal_convert_addr_string_to_type(bd_addr.address, device_address);
3936         conn_info =  __bt_find_gatt_conn_info(&bd_addr);
3937
3938         if (conn_info != NULL) {
3939                 //find service for notified char path
3940                 for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
3941                         svc_info = (hal_gattc_service_t*)l->data;
3942                         if (svc_info == NULL)
3943                                 continue;
3944
3945                         /* find characteristic object path */
3946                         for (k = svc_info->gatt_list_chars; k != NULL; k = g_slist_next(k)) {
3947                                 char_info = (hal_gattc_char_t *)k->data;
3948                                 if (char_info == NULL)
3949                                         continue;
3950
3951                                 if (g_strcmp0(char_info->chr_path, char_handle) == 0) {
3952                                         DBG("Found char handle[%s]", char_info->chr_path);
3953
3954                                         //send event
3955                                         _bt_hal_send_value_changed_event(conn_info, svc_info,
3956                                                         char_info, char_value, len);
3957                                         return;
3958                                 }
3959                         }
3960                 }
3961         }
3962 }
3963
3964 static bt_status_t __hal_gattc_get_service_info(hal_gattc_server_info_t *server_info, const char *service_path)
3965 {
3966         GDBusConnection *g_conn = NULL;
3967         GDBusProxy *properties_proxy = NULL;
3968         GVariant *result = NULL;
3969         GError *error = NULL;
3970         GVariantIter *property_iter = NULL;
3971         const gchar *key = NULL;
3972         GVariant *value = NULL;
3973         const char *uuid_str = NULL;
3974         gsize len = 0;
3975         gboolean is_primary = FALSE;
3976         GVariantIter *char_iter = NULL;
3977         const char *char_handle = NULL;
3978         GPtrArray *gp_char_array = NULL;
3979
3980         if (service_path == NULL) {
3981                 ERR("service_path is NULL");
3982                 return BT_STATUS_FAIL;
3983         }
3984
3985         DBG("service_path: %s", service_path);
3986
3987         g_conn = _bt_hal_get_system_gconn();
3988         if (g_conn == NULL) {
3989                 ERR("g_conn is NULL");
3990                 return BT_STATUS_FAIL;
3991         }
3992
3993         properties_proxy = g_dbus_proxy_new_sync(g_conn,
3994                         G_DBUS_PROXY_FLAGS_NONE, NULL,
3995                         BT_HAL_BLUEZ_NAME,
3996                         service_path,
3997                         BT_HAL_PROPERTIES_INTERFACE,
3998                         NULL, &error);
3999         if (properties_proxy == NULL) {
4000                 ERR("properties_proxy is NULL");
4001                 return BT_STATUS_FAIL;
4002         }
4003
4004         result = g_dbus_proxy_call_sync(properties_proxy,
4005                         "GetAll",
4006                         g_variant_new("(s)", BT_HAL_GATT_SERVICE_INTERFACE),
4007                         G_DBUS_CALL_FLAGS_NONE,
4008                         -1, NULL, &error);
4009         if (result == NULL) {
4010                 if (error != NULL) {
4011                         ERR("Fail to get properties (Error: %s)", error->message);
4012                         g_clear_error(&error);
4013                 } else {
4014                         ERR("Fail to get properties");
4015                 }
4016                 g_object_unref(properties_proxy);
4017                 return BT_STATUS_FAIL;
4018         }
4019
4020         g_variant_get(result, "(a{sv})", &property_iter);
4021
4022         while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
4023                 if (g_strcmp0(key, "UUID") == 0) {
4024                         uuid_str = g_variant_get_string(value, &len);
4025                 } else if (g_strcmp0(key, "Primary") == 0) {
4026                         is_primary = g_variant_get_boolean(value);
4027                 } else if (g_strcmp0(key, "Characteristics") == 0) {
4028                         g_variant_get(value, "ao", &char_iter);
4029                         if (char_iter != NULL) {
4030                                 if (gp_char_array == NULL)
4031                                         gp_char_array = g_ptr_array_new();
4032
4033                                 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
4034                                         DBG("char_handle: %s", char_handle);
4035                                         g_ptr_array_add(gp_char_array, (gpointer)char_handle);
4036                                 }
4037                                 g_variant_iter_free(char_iter);
4038                         }
4039                 }
4040         }
4041
4042         if (uuid_str == NULL || gp_char_array == NULL) {
4043                 ERR("uuid_str and gp_char_array should be set");
4044                 goto done;
4045         }
4046
4047         /* Create new service */
4048         _gattc_create_new_service(server_info, is_primary, uuid_str, service_path, gp_char_array);
4049
4050 done:
4051         g_variant_iter_free(property_iter);
4052         g_variant_unref(result);
4053         g_object_unref(properties_proxy);
4054
4055         return BT_STATUS_SUCCESS;
4056 }
4057
4058 static void __bt_hal_gattc_get_uuid_from_path(const char *path, char **service_uuid)
4059 {
4060         GDBusConnection *conn = NULL;
4061         GDBusProxy *proxy = NULL;
4062         GError *err = NULL;
4063         GVariant *ret = NULL;
4064         GVariant *value = NULL;
4065
4066         conn = _bt_hal_get_system_gconn();
4067         if (conn == NULL) {
4068                 ERR("_bt_gdbus_get_system_gconn returned NULL");
4069                 return;
4070         }
4071
4072         proxy = g_dbus_proxy_new_sync(conn,
4073                         G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
4074                         BT_HAL_BLUEZ_NAME, path, BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
4075         if (proxy == NULL) {
4076                 ERR("device_proxy returned NULL");
4077                 return;
4078         }
4079
4080         ret = g_dbus_proxy_call_sync(proxy, "Get",
4081                         g_variant_new("(ss)", BT_HAL_GATT_SERVICE_INTERFACE, "UUID"),
4082                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
4083         if (err) {
4084                 ERR("DBus Error : %s", err->message);
4085                 g_clear_error(&err);
4086         } else {
4087                 g_variant_get(ret, "(v)", &value);
4088                 *service_uuid = g_variant_dup_string(value, NULL);
4089                 g_variant_unref(value);
4090                 g_variant_unref(ret);
4091         }
4092
4093         if (proxy)
4094                 g_object_unref(proxy);
4095
4096         return;
4097 }
4098
4099 void _bt_hal_handle_gattc_service_changed_event(gboolean is_added, const char *path)
4100 {
4101         struct hal_ev_gatt_client_service_changed ev = {0, };
4102         char address[BT_HAL_ADDRESS_STRING_SIZE];
4103         hal_gattc_server_info_t *server_info = NULL;
4104         hal_gattc_client_info_t *gattc_client = NULL;
4105         hal_gattc_service_t *service = NULL;
4106         GSList *list = NULL;
4107         char *uuid_str = NULL;
4108
4109         _bt_hal_convert_device_path_to_address(path, address);
4110         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
4111         server_info = __bt_find_gatt_conn_info((bt_bdaddr_t *)ev.bdaddr);
4112         if (server_info == NULL) {
4113                 ERR("server_info is NULL");
4114                 return;
4115         }
4116
4117         gattc_client = __bt_find_gatt_client_info((bt_bdaddr_t *)ev.bdaddr);
4118         if (gattc_client == NULL) {
4119                 ERR("gattc_client is NULL");
4120                 return;
4121         }
4122
4123         if (server_info->is_gatt_connected == FALSE && gattc_client->is_gatt_connected == FALSE) {
4124                 DBG("GattConnected signal is not received yet. Just skip [%d %d]",
4125                         server_info->is_gatt_connected, gattc_client->is_gatt_connected);
4126                 return;
4127         }
4128
4129         if (is_added) {
4130                 /* Get service UUID from path */
4131                 __bt_hal_gattc_get_uuid_from_path(path, &uuid_str);
4132                 if (uuid_str) {
4133                         INFO("conn_id(%d) GATT Service(%s) Added", server_info->conn_id, uuid_str);
4134                         _bt_hal_convert_uuid_string_to_type(ev.uuid, uuid_str);
4135                         g_free(uuid_str);
4136                 } else {
4137                         ERR("uuid_str is NULL");
4138                         return;
4139                 }
4140
4141                 /* Create new service and append into the list */
4142                 __hal_gattc_get_service_info(server_info, path);
4143         } else {
4144                 /* Find service UUID from path */
4145                 for (list = server_info->gatt_list_services; list; list = g_slist_next(list)) {
4146                         service = (hal_gattc_service_t *)list->data;
4147                         if (service == NULL)
4148                                 continue;
4149
4150                         if (g_strcmp0(service->svc_path, path) == 0) {
4151                                 memcpy(ev.uuid, service->svc_uuid.uu, sizeof(bt_uuid_t));
4152                                 uuid_str = g_malloc0(BT_HAL_UUID_STRING_LEN);
4153                                 _bt_hal_convert_uuid_type_to_string(uuid_str, ev.uuid);
4154                                 INFO("conn_id(%d) GATT Service(%s) Removed", server_info->conn_id, uuid_str);
4155
4156                                 /* Remove service info in list */
4157                                 server_info->gatt_list_services = g_slist_remove(server_info->gatt_list_services, service);
4158                                 __hal_gattc_free_svc_info(service);
4159                                 break;
4160                         }
4161                 }
4162
4163                 if (uuid_str) {
4164                         g_free(uuid_str);
4165                 } else {
4166                         ERR("uuid_str is NULL");
4167                         return;
4168                 }
4169         }
4170
4171         /* Send GATT Client service changed event */
4172         ev.change_type = is_added;
4173         ev.conn_id = server_info->conn_id;
4174         ev.inst_id = server_info->inst_id;
4175         event_cb(HAL_EV_GATT_CLIENT_SERVICE_CHANGED, (void *)&ev, sizeof(ev));
4176 }