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