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