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