4f108516b2807f2e4dd1c41006e17d58163f7070
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-gatt-server.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 <gio/gio.h>
29 #include <glib.h>
30 #include <dlog.h>
31 #include <vconf.h>
32 #include <stdbool.h>
33 #include <stddef.h>
34 #include <string.h>
35 #include <fcntl.h>
36
37 #include "bt-hal.h"
38 #include "bt-hal-log.h"
39 #include "bt-hal-msg.h"
40 #include "bt-hal-utils.h"
41 #include "bt-hal-dbus-common-utils.h"
42
43 #include "bt-hal-adapter-le.h"
44 #include "bt-hal-event-receiver.h"
45
46 #define NUMBER_OF_FLAGS 10
47
48 #define GATT_SERV_INTERFACE             "org.bluez.GattService1"
49 #define GATT_CHAR_INTERFACE             "org.bluez.GattCharacteristic1"
50 #define GATT_DESC_INTERFACE             "org.bluez.GattDescriptor1"
51
52 #define BT_GATT_SERVICE_NAME    "org.frwk.gatt_service"
53 #define GATT_SERV_OBJECT_PATH   "/service"
54
55 static GDBusProxy *manager_gproxy = NULL;
56
57 /************************************************************************************
58  **  Static variables
59  ************************************************************************************/
60 extern const btgatt_callbacks_t *bt_gatt_callbacks;
61 guint owner_id;
62 GDBusConnection *g_conn = NULL;
63 //GDBusConnection *conn = NULL;
64 GDBusNodeInfo *manager_node_info = NULL;
65 guint manager_id;
66
67 /* Global handles which needs to be incremented during each addition */
68 static int gatt_service_handle = 10;
69 static int gatt_char_handle = 20;
70 static int gatt_desc_handle = 30;
71
72 struct gatt_service_info {
73         gchar *serv_path;
74         guint serv_id;
75         gchar *service_uuid;
76         guint manager_id;
77         guint prop_id;
78         GSList *char_data;
79         gboolean is_svc_registered;
80         gboolean is_svc_primary;
81         int service_handle;
82 };
83
84 struct gatt_char_info {
85         gchar *char_path;
86         guint char_id;
87         gchar *char_uuid;
88         gchar *char_value;
89         gchar *char_flags[NUMBER_OF_FLAGS];
90         int value_length;
91         int flags_length;
92         int char_handle;
93         GSList *desc_data;
94 };
95
96 struct gatt_desc_info {
97         gchar *desc_path;
98         guint desc_id;
99         gchar *desc_uuid;
100         gchar *desc_value;
101         gchar *desc_flags[NUMBER_OF_FLAGS];
102         int value_length;
103         int flags_length;
104         int desc_handle;
105 };
106
107 /**
108  * GATT Server Request type
109  */
110 typedef enum {
111         BT_HAL_GATT_REQUEST_TYPE_READ = 0x00,       /* Read Requested */
112         BT_HAL_GATT_REQUEST_TYPE_WRITE = 0x01,      /* Write Requested */
113         BT_HAL_GATT_REQUEST_TYPE_EXEC_WRITE = 0x02, /* Exec Write Requested */
114         BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_WRITE = 0x03, /* Exec Write Requested */
115         BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY = 0x04, /* Exec Write Requested */
116 } bt_gatt_request_type_e;
117
118 struct gatt_req_info {
119         gchar *attr_path;
120         gchar *svc_path;
121         guint  request_id;
122         guint  offset;
123         bt_gatt_request_type_e request_type;  /* Read or Write request */
124         GDBusMethodInvocation *context;
125 };
126
127 struct gatt_server_app {
128         int slot;
129         char *app_path;
130         GSList *services;
131 };
132
133 /* Linked List of gatt server app's */
134 static GSList *gatt_server_apps = NULL;
135
136 static GSList *gatt_services = NULL;
137
138 static int conn_id = 0;
139
140 /* Linked List of connected Remote GATT clients */
141 static GSList *gatt_client_info_list = NULL;
142
143 /* GATT Client Info List Structure */
144 struct gatt_client_info_t {
145         int connection_id;                               /* This value will uniquely identify a GATT client-server connection */
146         int instance_id;                                 /* This value unique identifies a GATT server instance */
147         char *addr;                                      /* Remote GATT client address */
148         GSList *gatt_req_info_list;                              /* List of transactions per Connection*/
149 };
150
151 static handle_stack_msg event_cb = NULL;
152
153 typedef struct {
154         uint32_t instance_data;
155         bt_uuid_t uuid;
156 } hal_register_server_data;
157
158 typedef struct {
159         uint32_t instance_data;
160         uint32_t srvc_hdl;
161         bt_uuid_t uuid;
162         uint8_t is_primary;
163 } hal_gatt_service_added;
164
165 typedef struct {
166         uint32_t instance_data;
167         uint32_t srvc_hdl;
168 } hal_gatt_service_started;
169
170 typedef struct {
171         uint32_t instance_data;
172         uint32_t srvc_hdl;
173 } hal_gatt_service_deleted;
174
175 typedef struct {
176         uint32_t instance_data;
177         uint32_t srvc_hdl;
178         uint32_t char_hdl;
179         bt_uuid_t uuid;
180 } hal_gatt_char_added;
181
182 typedef struct {
183         uint32_t instance_data;
184         uint32_t srvc_hdl;
185         uint32_t desc_hdl;
186         bt_uuid_t uuid;
187 } hal_gatt_desc_added;
188
189 #define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
190 {\
191         ERR("%s: BTGATT not initialized", __FUNCTION__);\
192         return BT_STATUS_NOT_READY;\
193 } else {\
194         DBG("%s", __FUNCTION__);\
195 }
196
197 static gboolean __bt_hal_gatt_service_added_cb(gpointer user_data);
198
199 static void __bt_hal_gatt_deinit(char *app_path);
200
201 static void __bt_hal_register_application_cb(GObject *object,
202                                 GAsyncResult *res, gpointer user_data);
203
204 static void __bt_hal_unregister_application_cb(GObject *object, GAsyncResult *res,
205                 gpointer user_data);
206
207 static GDBusProxy *__bt_gatt_gdbus_get_gatt_manager_proxy(const gchar *service,
208                 const gchar *path, const gchar *interface);
209
210 /* Introspection data for the service we are exporting */
211 static const gchar service_introspection_xml[] =
212 "<node name='/'>"
213 "  <interface name='org.freedesktop.DBus.Properties'>"
214 "    <property type='s' name='UUID' access='read'>"
215 "    </property>"
216 "        <property type='b' name='primary' access='read'>"
217 "        </property>"
218 "        <property type='o' name='Device' access='read'>"
219 "        </property>"
220 "        <property type='ao' name='Characteristics' access='read'>"
221 "        </property>"
222 "        <property type='s' name='Includes' access='read'>"
223 "        </property>"
224 "  </interface>"
225 "</node>";
226
227 /* Introspection data for the characteristics we are exporting */
228 static const gchar characteristics_introspection_xml[] =
229 "<node name='/'>"
230 "  <interface name='org.bluez.GattCharacteristic1'>"
231 "        <method name='ReadValue'>"
232 "               <arg type='s' name='address' direction='in'/>"
233 "               <arg type='u' name='id' direction='in'/>"
234 "               <arg type='q' name='offset' direction='in'/>"
235 "               <arg type='ay' name='Value' direction='out'/>"
236 "        </method>"
237 "        <method name='WriteValue'>"
238 "               <arg type='s' name='address' direction='in'/>"
239 "               <arg type='u' name='id' direction='in'/>"
240 "               <arg type='q' name='offset' direction='in'/>"
241 "               <arg type='b' name='response_needed' direction='in'/>"
242 "               <arg type='ay' name='value' direction='in'/>"
243 "        </method>"
244 "       <method name ='AcquireWrite'>"
245 "      <arg type='a{sv}' name='properties' direction='in'/>"
246 "               <arg type='h' name='fd' direction='out'/>"
247 "               <arg type='q' name='mtu' direction='out'/>"
248 "        </method>"
249 "       <method name = 'AcquireNotify'>"
250 "               <arg type='a{sv}' name='properties' direction='in'/>"
251 "               <arg type='h' name='fd' direction='out'/>"
252 "               <arg type='q' name='mtu' direction='out'/>"
253 "        </method>"
254 "        <method name='StartNotify'>"
255 "        </method>"
256 "        <method name='StopNotify'>"
257 "        </method>"
258 "        <method name='IndicateConfirm'>"
259 "               <arg type='s' name='address' direction='in'/>"
260 "               <arg type='b' name='complete' direction='in'/>"
261 "        </method>"
262 "  </interface>"
263 "  <interface name='org.freedesktop.DBus.Properties'>"
264 "    <property type='s' name='UUID' access='read'>"
265 "    </property>"
266 "    <property type='o' name='Service' access='read'>"
267 "    </property>"
268 "    <property type='ay' name='Value' access='readwrite'>"
269 "    </property>"
270 "        <property type='b' name='Notifying' access='read'>"
271 "        </property>"
272 "    <property type='as' name='Flags' access='read'>"
273 "    </property>"
274 "    <property type='s' name='Unicast' access='read'>"
275 "    </property>"
276 "        <property type='ao' name='Descriptors' access='read'>"
277 "        </property>"
278 "        <property type='b' name='WriteAcquired' access='read'>"
279 "        </property>"
280 "        <property type='b' name='NotifyAcquired' access='read'>"
281 "        </property>"
282 "  </interface>"
283 "</node>";
284
285 /* Introspection data for the descriptor we are exporting */
286 static const gchar descriptor_introspection_xml[] =
287 "<node name='/'>"
288 "  <interface name='org.bluez.GattDescriptor1'>"
289 "        <method name='ReadValue'>"
290 "               <arg type='s' name='address' direction='in'/>"
291 "               <arg type='u' name='id' direction='in'/>"
292 "               <arg type='q' name='offset' direction='in'/>"
293 "               <arg type='ay' name='Value' direction='out'/>"
294 "        </method>"
295 "        <method name='WriteValue'>"
296 "               <arg type='s' name='address' direction='in'/>"
297 "               <arg type='u' name='id' direction='in'/>"
298 "               <arg type='q' name='offset' direction='in'/>"
299 "               <arg type='b' name='response_needed' direction='in'/>"
300 "               <arg type='ay' name='value' direction='in'/>"
301 "        </method>"
302 "  </interface>"
303 "  <interface name='org.freedesktop.DBus.Properties'>"
304 "    <property type='s' name='UUID' access='read'>"
305 "    </property>"
306 "    <property type='o' name='Characteristic' access='read'>"
307 "    </property>"
308 "    <property type='ay' name='Value' access='read'>"
309 "    </property>"
310 "    <property type='as' name='Flags' access='read'>"
311 "    </property>"
312 "  </interface>"
313 "</node>";
314
315
316 static const gchar manager_introspection_xml[] =
317 "<node name='/'>"
318 "  <interface name='org.freedesktop.DBus.ObjectManager'>"
319 "    <method name='GetManagedObjects'>"
320 "     <arg type='a{oa{sa{sv}}}' name='object_paths_interfaces_and_properties' direction='out'/>"
321 "        </method>"
322 "  </interface>"
323 "</node>";
324
325 static GSList *_bt_get_service_list_from_server(int instance)
326 {
327         GSList *l;
328         INFO("Number of GATT Server apps [%d]", g_slist_length(gatt_server_apps));
329         INFO("Find App with slot [%d]", instance);
330
331         for (l = gatt_server_apps; l; l = g_slist_next(l)) {
332                 struct gatt_server_app *app = (struct gatt_server_app *)l->data;
333
334                 if (app->slot == instance) {
335                         INFO("App slot [%d] Found, Number of services registered [%d]",
336                                         app->slot, g_slist_length(app->services));
337                         return app->services;
338                 }
339         }
340         return NULL;
341 }
342
343 static void _bt_remote_service_from_gatt_server(int instance, int service_handle)
344 {
345         GSList *l;
346         GSList *l1;
347
348         for (l = gatt_server_apps; l; l = g_slist_next(l)) {
349                 struct gatt_server_app *app = (struct gatt_server_app *)l->data;
350
351                 if (app->slot == instance) {
352                         for (l1 = app->services; l1; l1 = g_slist_next(l1)) {
353                                 struct gatt_service_info *srv = (struct gatt_service_info *)l1->data;
354                                 if (srv->service_handle == service_handle) {
355                                         app->services = g_slist_remove(app->services, srv);
356                                         return;
357                                 }
358                         }
359                 }
360         }
361 }
362
363 static void _bt_hal_update_gatt_service_in_gatt_server(int slot, struct gatt_service_info *serv_info)
364 {
365         GSList *l;
366         for (l = gatt_server_apps; l; l = g_slist_next(l)) {
367                 struct gatt_server_app *app = (struct gatt_server_app *)l->data;
368
369                 if (app->slot == slot) {
370                         INFO("Updating service in GATT server's service list service handle [%d] slot [%d]",
371                                 serv_info->service_handle, slot);
372                         app->services = g_slist_append(app->services, serv_info);
373                 }
374         }
375 }
376
377 int _bt_get_remote_gatt_client_conn_id(char *address)
378 {
379         GSList *l;
380         struct gatt_client_info_t *info = NULL;
381
382         for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
383                 info = (struct gatt_client_info_t*)l->data;
384                 if (info == NULL)
385                         continue;
386
387                 if (!g_strcmp0(info->addr, address)) {
388                         INFO("Remote GATT client found addr[%s]", info->addr);
389                         return info->connection_id;
390                 }
391         }
392         return 0;
393 }
394
395 static struct gatt_client_info_t *__bt_find_remote_gatt_client_info(char *address)
396 {
397         GSList *l;
398         struct gatt_client_info_t *info = NULL;
399
400         for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
401                 info = (struct gatt_client_info_t*)l->data;
402                 if (info == NULL)
403                         continue;
404
405                 if (!g_strcmp0(info->addr, address)) {
406                         INFO("Remote GATT client found addr[%s]", info->addr);
407                         return info;
408                 }
409         }
410         return NULL;
411 }
412
413 static struct gatt_client_info_t *__bt_find_remote_gatt_client_info_from_conn(int conn_id)
414 {
415         GSList *l;
416         struct gatt_client_info_t *info = NULL;
417
418         for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
419                 info = (struct gatt_client_info_t*)l->data;
420                 if (info == NULL)
421                         continue;
422
423                 if (info->connection_id == conn_id) {
424                         INFO("Remote GATT client found addr[%s]", info->addr);
425                         return info;
426                 }
427         }
428         return NULL;
429 }
430
431 static struct gatt_req_info *__bt_find_remote_gatt_client_request_info(int conn_id, int trans_id)
432 {
433         GSList *l;
434         GSList *l1;
435
436         struct gatt_client_info_t *info = NULL;
437         struct gatt_req_info *info1 = NULL;
438
439         for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
440                 info = (struct gatt_client_info_t*)l->data;
441
442                 if (info == NULL)
443                         continue;
444                 if (info->connection_id == conn_id) {
445
446                         for (l1 = info->gatt_req_info_list; l1; l1 = g_slist_next(l1)) {
447
448                                 info1 = (struct gatt_req_info*)l1->data;
449                                 if (info1 == NULL)
450                                         continue;
451
452                                 if (info1->request_id == trans_id) {
453                                         INFO("Remote GATT client found addr[%s]", info->addr);
454                                         return info1;
455                                 }
456                         }
457                 }
458         }
459         return NULL;
460 }
461
462 void _bt_hal_gatt_connected_state_event(gboolean is_connected, char *address)
463 {
464         struct hal_ev_gatt_server_connected ev;
465         struct gatt_client_info_t *conn_info = NULL;
466         int instance = -1;
467         memset(&ev, 0, sizeof(ev));
468
469         /* Find Server Instance */
470         _bt_hal_get_gatt_server_instance_initialized(&instance);
471         if (instance == -1) {
472                 ERR("Not even a single GATT server is registered");
473                 return;
474         }
475
476         /* Convert address to hex */
477         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
478
479         /* Create Connection ID */
480         /* Check if device is already in connected list */
481         conn_info = __bt_find_remote_gatt_client_info(address);
482
483
484         /* If disconnected, and conn info found, then remove conn info */
485         if (is_connected == FALSE) {
486                 DBG("GATT Disconnected");
487                 if (conn_info) {
488                         INFO("Remove GATT client info from List..");
489                         /* Remove info from List */
490                         gatt_client_info_list = g_slist_remove(gatt_client_info_list, conn_info);
491                         INFO("Total num of connected GATT clients [%d]", g_slist_length(gatt_client_info_list));
492
493                         if (!event_cb)
494                                 ERR("GATT callback not registered");
495                         else {
496                                 DBG("GATT callback registered: server if [%d] Is Connected [%d] addr[%s] conn ID [%d]",
497                                                 conn_info->instance_id, is_connected, conn_info->addr, conn_info->connection_id);
498                                 ev.conn_id = conn_info->connection_id;
499                                 ev.server_instance = conn_info->instance_id;
500                                 ev.connected = is_connected;
501
502                                 event_cb(HAL_EV_GATT_SERVER_CONNECTED, (void *)&ev, sizeof(ev));
503                         }
504                         g_free(conn_info->addr);
505                         g_free(conn_info);
506                 }
507                 /* If connected, and conn info NOT found, then add conn info */
508         } else {
509                 if (!conn_info) {
510                         /* Save Connection info */
511                         conn_info = g_new0(struct gatt_client_info_t, 1);
512                         conn_info->addr = g_strdup(address);
513                         INFO("Added GATT client addr[%s]", conn_info->addr);
514                         conn_info->connection_id = ++conn_id;
515                         conn_info->instance_id = instance;
516                         gatt_client_info_list = g_slist_append(gatt_client_info_list, conn_info);
517                         INFO("Total num of connected GATT clients [%d]", g_slist_length(gatt_client_info_list));
518
519                         if (!event_cb)
520                                 ERR("GATT callback not registered");
521                         else {
522                                 DBG("GATT callback registered: server if [%d] Is Connected [%d] addr[%s] conn ID [%d]",
523                                                 conn_info->instance_id, is_connected, conn_info->addr, conn_info->connection_id);
524                                 ev.conn_id = conn_info->connection_id;
525                                 ev.server_instance = conn_info->instance_id;
526                                 ev.connected = is_connected;
527
528                                 event_cb(HAL_EV_GATT_SERVER_CONNECTED, (void *)&ev, sizeof(ev));
529                         }
530                 }
531         }
532         /* Send GATT connected or disconnected event */
533 }
534
535 static struct gatt_service_info *__bt_gatt_find_gatt_service_from_char(const char *char_path, int *char_hdl)
536 {
537         GSList *l1, *l2;
538
539         for (l1 = gatt_services; l1 != NULL; l1 = l1->next) {
540                 struct gatt_service_info *serv_info = l1->data;
541
542                 for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
543                         struct gatt_char_info *char_info = l2->data;
544
545                         if (g_strcmp0(char_info->char_path, char_path)
546                                         == 0) {
547                                 *char_hdl = char_info->char_handle;
548                                 return serv_info;
549                         }
550                 }
551         }
552         ERR("Gatt service not found");
553         return NULL;
554 }
555
556 static char *__bt_gatt_find_char_path_from_handle(int char_hdl)
557 {
558         GSList *l1, *l2;
559
560         for (l1 = gatt_services; l1 != NULL; l1 = l1->next) {
561                 struct gatt_service_info *serv_info = l1->data;
562
563                 for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
564                         struct gatt_char_info *char_info = l2->data;
565
566                         if (char_info->char_handle == char_hdl)
567                                 return char_info->char_path;
568                 }
569         }
570         ERR("Not found");
571         return NULL;
572 }
573
574 static struct gatt_char_info *__bt_gatt_find_char_info_from_handle(int char_hdl)
575 {
576         GSList *l1, *l2;
577
578         for (l1 = gatt_services; l1 != NULL; l1 = l1->next) {
579                 struct gatt_service_info *serv_info = l1->data;
580
581                 for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
582                         struct gatt_char_info *char_info = l2->data;
583
584                         if (char_info->char_handle == char_hdl)
585                                 return char_info;
586                 }
587         }
588         ERR("Not found");
589         return NULL;
590 }
591
592 static struct gatt_service_info *__bt_gatt_find_gatt_service_from_desc(const char *desc_path, int *desc_hdl)
593 {
594         GSList *l1, *l2, *l3;
595
596         for (l1 = gatt_services; l1 != NULL; l1 = l1->next) {
597                 struct gatt_service_info *serv_info = l1->data;
598
599                 for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
600                         struct gatt_char_info *char_info = l2->data;
601
602                         for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) {
603                                 struct gatt_desc_info *desc_info = l3->data;
604
605                                 if (g_strcmp0(desc_info->desc_path, desc_path)
606                                                 == 0) {
607                                         *desc_hdl = desc_info->desc_handle;
608                                         return serv_info;
609                                 }
610                         }
611                 }
612         }
613         ERR("Gatt service not found");
614         return NULL;
615 }
616
617 static void __bt_gatt_manager_method_call(GDBusConnection *connection,
618                 const gchar *sender,
619                 const gchar *object_path,
620                 const gchar *interface_name,
621                 const gchar *method_name,
622                 GVariant *parameters,
623                 GDBusMethodInvocation *invocation,
624                 gpointer user_data)
625 {
626         GSList *l = NULL;
627
628         if (g_strcmp0(method_name, "GetManagedObjects") == 0) {
629                 GVariantBuilder *builder;
630                 GVariantBuilder *inner_builder1 = NULL;
631                 GVariant *svc_char = NULL;
632                 GSList *l4;
633                 GSList *gatt_services = NULL;
634                 int *instance;
635                 instance = (int*)user_data;
636                 gboolean writeAcquired = FALSE;
637                 gboolean notifyAcquired = FALSE;
638
639                 DBG("Getting values for service, chars and descriptors");
640                 DBG("GATT Server App for which services are requested [%d]", *instance);
641
642                 /*Main Builder */
643                 builder = g_variant_builder_new(
644                                 G_VARIANT_TYPE("a{oa{sa{sv}}}"));
645
646
647                 gatt_services = _bt_get_service_list_from_server(*instance);
648
649                 if (g_slist_length(gatt_services) == 0) {
650                         ERR("No registered GATT services!!!!");
651                         g_dbus_method_invocation_return_value(invocation, NULL);
652                         g_variant_builder_unref(builder);
653                         return;
654                 }
655
656                 for (l = gatt_services; l != NULL; l = l->next) {
657                         GVariantBuilder *svc_builder = NULL;
658                         GVariantBuilder *inner_builder = NULL;
659                         struct gatt_service_info *serv_info = l->data;
660                         INFO("GATT Service fetched handle [%d]", serv_info->service_handle);
661
662                         /* Prepare inner builder for GattService1 interface */
663                         DBG("Creating builder for service");
664                         svc_builder = g_variant_builder_new(
665                                         G_VARIANT_TYPE("a{sa{sv}}"));
666                         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
667
668                         g_variant_builder_add(inner_builder, "{sv}", "UUID",
669                                         g_variant_new_string(serv_info->service_uuid));
670
671                         g_variant_builder_add(inner_builder, "{sv}", "Primary",
672                                         g_variant_new_boolean(serv_info->is_svc_primary));
673
674                         /*Characteristics*/
675                         inner_builder1 = g_variant_builder_new(G_VARIANT_TYPE("ao"));
676                         DBG("Adding Charatarisitcs list");
677                         for (l4 = serv_info->char_data; l4 != NULL; l4 = l4->next) {
678                                 struct gatt_char_info *char_info = l4->data;
679                                 INFO("GATT Char handle [%d] found in GATT service handle [%d]",
680                                                 char_info->char_handle, serv_info->service_handle);
681                                 g_variant_builder_add(inner_builder1, "o",
682                                                 char_info->char_path);
683                                 DBG("%s", char_info->char_path);
684                         }
685
686                         svc_char = g_variant_new("ao", inner_builder1);
687                         g_variant_builder_add(inner_builder, "{sv}", "Characteristics",
688                                         svc_char);
689
690                         g_variant_builder_add(svc_builder, "{sa{sv}}",
691                                         GATT_SERV_INTERFACE,
692                                         inner_builder);
693
694                         g_variant_builder_add(builder, "{oa{sa{sv}}}",
695                                         serv_info->serv_path,
696                                         svc_builder);
697
698                         g_variant_builder_unref(inner_builder1);
699
700                         /* Prepare inner builder for GattCharacteristic1 interface */
701
702                         GSList *l2 = serv_info->char_data;
703                         DBG("Creating builder for characteristics \n");
704
705                         if (l2 == NULL)
706                                 DBG("characteristic data is NULL");
707
708                         for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
709
710                                 GVariantBuilder *char_builder = NULL;
711                                 GVariantBuilder *inner_builder = NULL;
712                                 GVariantBuilder *builder1 = NULL;
713                                 GVariantBuilder *builder2 = NULL;
714                                 GVariantBuilder *builder3 = NULL;
715                                 GVariant *char_val = NULL;
716                                 GVariant *flags_val = NULL;
717                                 GVariant *char_desc = NULL;
718                                 char *unicast = NULL;
719                                 gboolean notify = FALSE;
720                                 int i = 0;
721
722                                 char_builder = g_variant_builder_new(
723                                                 G_VARIANT_TYPE(
724                                                         "a{sa{sv}}"));
725                                 inner_builder = g_variant_builder_new(
726                                                 G_VARIANT_TYPE(
727                                                         "a{sv}"));
728
729                                 struct gatt_char_info *char_info = l2->data;
730                                 if (char_info == NULL) {
731                                         ERR("char_info is NULL");
732                                         continue;
733                                 }
734
735                                 /*Uuid*/
736                                 g_variant_builder_add(inner_builder, "{sv}", "UUID",
737                                                 g_variant_new_string(char_info->char_uuid));
738                                 /*Service*/
739                                 g_variant_builder_add(inner_builder, "{sv}", "Service",
740                                                 g_variant_new("o", serv_info->serv_path));
741                                 /*Value*/
742                                 builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
743
744                                 if (char_info->char_value != NULL) {
745                                         for (i = 0; i < char_info->value_length; i++) {
746                                                 g_variant_builder_add(builder1, "y",
747                                                                 char_info->char_value[i]);
748                                         }
749                                         char_val = g_variant_new("ay", builder1);
750                                         g_variant_builder_add(inner_builder, "{sv}",
751                                                         "Value", char_val);
752                                 }
753                                 /*Flags*/
754                                 builder2 = g_variant_builder_new(G_VARIANT_TYPE("as"));
755                                 for (i = 0; i < char_info->flags_length; i++) {
756                                         g_variant_builder_add(builder2, "s",
757                                                         char_info->char_flags[i]);
758
759                                         if (strncmp(char_info->char_flags[i], "write-without-response", 16) == 0) {
760                                                 DBG("setting WriteAcquired property");
761                                                 writeAcquired = TRUE;
762                                         }
763
764                                         if (strncmp(char_info->char_flags[i], "notify", 4) == 0) {
765                                                 DBG("setting NotifyAcquired property");
766                                                 notifyAcquired = TRUE;
767                                         }
768                                 }
769
770                                 flags_val = g_variant_new("as", builder2);
771                                 g_variant_builder_add(inner_builder, "{sv}", "Flags",
772                                                 flags_val);
773
774                                 /* Notifying */
775                                 g_variant_builder_add(inner_builder, "{sv}", "Notifying",
776                                                 g_variant_new("b", notify));
777
778                                 /* WriteAcquired */
779                                 if (writeAcquired == TRUE) {
780                                         DBG("adding WriteAcquired property");
781                                         g_variant_builder_add(inner_builder, "{sv}", "WriteAcquired",
782                                                                         g_variant_new("b", writeAcquired));
783                                 }
784
785                                 /* NotifyAcquired */
786                                 if (notifyAcquired == TRUE) {
787                                         DBG("adding NotifyAcquired property");
788                                         g_variant_builder_add(inner_builder, "{sv}", "NotifyAcquired",
789                                                         g_variant_new("b", notifyAcquired));
790                                 }
791
792                                 /* Unicast */
793                                 unicast = g_strdup("00:00:00:00:00:00");
794                                 g_variant_builder_add(inner_builder, "{sv}", "Unicast",
795                                                 g_variant_new("s", unicast));
796
797                                 /*Descriptors*/
798                                 builder3 = g_variant_builder_new(G_VARIANT_TYPE("ao"));
799                                 DBG("Adding Descriptors list");
800
801                                 for (l4 = char_info->desc_data; l4 != NULL; l4 = l4->next) {
802                                         struct gatt_desc_info *desc_info = l4->data;
803                                         INFO("GATT Descriptor handle [%d] found inside GATT Char handle [%d] found in GATT service handle [%d]",
804                                                         desc_info->desc_handle, char_info->char_handle, serv_info->service_handle);
805                                         g_variant_builder_add(builder3, "o",
806                                                         desc_info->desc_path);
807                                         DBG("%s", desc_info->desc_path);
808                                 }
809
810                                 char_desc = g_variant_new("ao", builder3);
811                                 g_variant_builder_add(inner_builder, "{sv}", "Descriptors",
812                                                 char_desc);
813
814                                 g_variant_builder_add(char_builder, "{sa{sv}}",
815                                                 GATT_CHAR_INTERFACE , inner_builder);
816                                 g_variant_builder_add(builder, "{oa{sa{sv}}}",
817                                                 char_info->char_path, char_builder);
818
819                                 /*Prepare inner builder for GattDescriptor1 interface*/
820
821                                 GSList *l3 = char_info->desc_data;
822
823                                 if (l3 == NULL)
824                                         DBG("descriptor data is NULL");
825
826                                 for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) {
827
828                                         DBG("Creating builder for descriptor \n");
829
830                                         GVariantBuilder *desc_builder = NULL;
831                                         GVariantBuilder *inner_builder = NULL;
832                                         GVariantBuilder *builder1 = NULL;
833                                         GVariantBuilder *builder2 = NULL;
834                                         GVariant *desc_val = NULL;
835
836                                         desc_builder = g_variant_builder_new(
837                                                         G_VARIANT_TYPE(
838                                                                 "a{sa{sv}}"));
839                                         inner_builder = g_variant_builder_new(
840                                                         G_VARIANT_TYPE(
841                                                                 "a{sv}"));
842
843                                         struct gatt_desc_info *desc_info = l3->data;
844                                         if (desc_info == NULL) {
845                                                 ERR("desc_info is NULL");
846                                                 continue;
847                                         }
848
849                                         /*Uuid*/
850                                         g_variant_builder_add(inner_builder,
851                                                         "{sv}", "UUID",
852                                                         g_variant_new_string(
853                                                                 desc_info->desc_uuid));
854
855                                         /*Characteristic*/
856                                         g_variant_builder_add(inner_builder, "{sv}",
857                                                         "Characteristic",
858                                                         g_variant_new("o",
859                                                                 char_info->char_path));
860
861                                         /*Value*/
862                                         builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
863
864                                         if (desc_info->desc_value != NULL) {
865                                                 for (i = 0; i < desc_info->value_length; i++) {
866                                                         g_variant_builder_add(builder1, "y",
867                                                                         desc_info->desc_value[i]);
868                                                 }
869                                                 desc_val = g_variant_new("ay", builder1);
870                                                 g_variant_builder_add(inner_builder, "{sv}",
871                                                                 "Value", desc_val);
872                                         }
873
874                                         /*Flags*/
875                                         builder2 = g_variant_builder_new(G_VARIANT_TYPE("as"));
876
877                                         for (i = 0; i < desc_info->flags_length; i++) {
878                                                 g_variant_builder_add(builder2, "s",
879                                                                 desc_info->desc_flags[i]);
880                                         }
881
882                                         flags_val = g_variant_new("as", builder2);
883                                         g_variant_builder_add(inner_builder, "{sv}", "Flags",
884                                                         flags_val);
885
886                                         g_variant_builder_add(desc_builder, "{sa{sv}}",
887                                                         GATT_DESC_INTERFACE,
888                                                         inner_builder);
889
890                                         g_variant_builder_add(builder, "{oa{sa{sv}}}",
891                                                         desc_info->desc_path,
892                                                         desc_builder);
893
894                                         /*unref descriptor builder pointers*/
895                                         g_variant_builder_unref(builder1);
896                                         g_variant_builder_unref(builder2);
897                                         g_variant_builder_unref(inner_builder);
898                                         g_variant_builder_unref(desc_builder);
899                                 }
900
901                                 if (unicast)
902                                         g_free(unicast);
903                                 /*unref char builder pointers*/
904                                 g_variant_builder_unref(builder1);
905                                 g_variant_builder_unref(builder2);
906                                 g_variant_builder_unref(builder3);
907                                 g_variant_builder_unref(inner_builder);
908                                 g_variant_builder_unref(char_builder);
909                         }
910
911                         /*unref service builder pointers*/
912                         g_variant_builder_unref(inner_builder);
913                         g_variant_builder_unref(svc_builder);
914
915                 }
916                 /* Return builder as method reply */
917                 DBG("Sending gatt service builder values to Bluez");
918                 g_dbus_method_invocation_return_value(invocation,
919                                 g_variant_new(
920                                         "(a{oa{sa{sv}}})",
921                                         builder));
922         }
923
924         /* Free User Data */
925         g_free(user_data);
926 }
927
928 static void __bt_gatt_desc_method_call(GDBusConnection *connection,
929                 const gchar *sender,
930                 const gchar *object_path,
931                 const gchar *interface_name,
932                 const gchar *method_name,
933                 GVariant *parameters,
934                 GDBusMethodInvocation *invocation,
935                 gpointer user_data)
936 {
937
938         if (g_strcmp0(method_name, "ReadValue") == 0) {
939                 struct hal_ev_gatt_server_read_req ev;
940
941                 gchar *addr = NULL;
942                 guint req_id = 0;
943                 guint16 offset = 0;
944                 struct gatt_client_info_t *conn_info = NULL;
945                 struct gatt_req_info *req_info = NULL;
946                 struct gatt_service_info *svc_info = NULL;
947                 int desc_hdl = -1;
948
949                 DBG("ReadValue");
950                 DBG("Application path = %s", object_path);
951                 DBG("Sender = %s", sender);
952
953                 svc_info = __bt_gatt_find_gatt_service_from_desc(object_path, &desc_hdl);
954                 if (svc_info == NULL) {
955                         ERR("Coudn't find service for %s", object_path);
956                         g_dbus_method_invocation_return_value(invocation, NULL);
957                         return;
958                 }
959
960                 g_variant_get(parameters, "(&suq)", &addr, &req_id, &offset);
961                 DBG("Request id = %u, Offset = %u", req_id, offset);
962
963                 /* Check if device is already in connected list */
964                 conn_info = __bt_find_remote_gatt_client_info(addr);
965
966                 if (conn_info == NULL) {
967                         ERR("Coudn't find Connection info for %s", addr);
968                         g_dbus_method_invocation_return_value(invocation, NULL);
969                         return;
970                 }
971
972                 if (!event_cb) {
973                         ERR("GATT callback NOT registered");
974                         g_dbus_method_invocation_return_value(invocation, NULL);
975                         return;
976                 }
977
978                 /* Store requests information */
979                 req_info = g_new0(struct gatt_req_info, 1);
980                 req_info->attr_path = g_strdup(object_path);
981                 req_info->svc_path = g_strdup(svc_info->serv_path);
982                 req_info->request_id = req_id;
983                 req_info->request_type = BT_HAL_GATT_REQUEST_TYPE_READ;
984                 req_info->offset = offset;
985                 req_info->context = invocation;
986
987                 /* Append request info in list of requests for the particular connection */
988                 conn_info->gatt_req_info_list = g_slist_append(conn_info->gatt_req_info_list, req_info);
989
990                 /* Send HAL event */
991                 memset(&ev, 0, sizeof(ev));
992                 ev.conn_id = conn_info->connection_id;
993                 ev.trans_id = req_id;
994                 ev.att_handle = desc_hdl;
995                 ev.offset = offset;
996                 ev.is_long = false; /* TODO*/
997
998                 /* Convert address to hex */
999                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, addr);
1000
1001                 event_cb(HAL_EV_GATT_READ_REQUESTED, (void *)&ev, sizeof(ev));
1002                 return;
1003         } else if (g_strcmp0(method_name, "WriteValue") == 0) {
1004
1005                 GVariant *var = NULL;
1006                 gchar *addr = NULL;
1007                 guint req_id = 0;
1008                 guint16 offset = 0;
1009                 gboolean response_needed = FALSE;
1010                 struct hal_ev_gatt_server_write_req ev;
1011                 int desc_hdl = -1;
1012                 int len;
1013
1014                 struct gatt_service_info *svc_info = NULL;
1015                 struct gatt_client_info_t *conn_info = NULL;
1016                 struct gatt_req_info *req_info = NULL;
1017
1018                 memset(&ev, 0, sizeof(ev));
1019
1020                 DBG("WriteValue");
1021                 DBG("Application path = %s", object_path);
1022                 DBG("Sender = %s", sender);
1023
1024                 g_variant_get(parameters, "(&suqb@ay)",
1025                                 &addr, &req_id, &offset, &response_needed, &var);
1026                 DBG("Request id = %u, Offset = %u", req_id, offset);
1027
1028                 /* Check if device is already in connected list */
1029                 conn_info = __bt_find_remote_gatt_client_info(addr);
1030
1031                 svc_info = __bt_gatt_find_gatt_service_from_desc(object_path, &desc_hdl);
1032
1033                 if (conn_info == NULL || svc_info == NULL || event_cb == NULL) {
1034                         g_variant_unref(var);
1035                         if (response_needed)
1036                                 g_dbus_method_invocation_return_value(invocation, NULL);
1037                         else
1038                                 g_object_unref(invocation);
1039                         return;
1040                 }
1041
1042                 len = g_variant_get_size(var);
1043                 if (len > 0 && len < 600) {
1044                         char *data;
1045                         data = (char *)g_variant_get_data(var);
1046                         memcpy(ev.value, data, len);
1047                         ev.length = len;
1048                 }
1049                 if (response_needed) {
1050                         /* Store request information */
1051                         req_info = g_new0(struct gatt_req_info, 1);
1052                         req_info->attr_path = g_strdup(object_path);
1053                         req_info->svc_path = g_strdup(svc_info->serv_path);
1054                         req_info->request_id = req_id;
1055                         req_info->request_type = BT_HAL_GATT_REQUEST_TYPE_WRITE;
1056                         req_info->offset = offset;
1057                         req_info->context = invocation;
1058
1059                         /* Append request info in list of requests for the particular connection */
1060                         conn_info->gatt_req_info_list = g_slist_append(conn_info->gatt_req_info_list, req_info);
1061                 } else {
1062                         g_object_unref(invocation);
1063                 }
1064
1065                 /* Send HAL event */
1066                 ev.conn_id = conn_info->connection_id;
1067                 ev.trans_id = req_id;
1068                 ev.att_handle = desc_hdl;
1069                 ev.offset = offset;
1070                 ev.need_rsp = response_needed;
1071                 ev.is_prep = 0;
1072
1073                 /* Convert address to hex */
1074                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, addr);
1075
1076                 event_cb(HAL_EV_GATT_WRITE_REQUESTED, (void *)&ev, sizeof(ev));
1077
1078                 g_variant_unref(var);
1079                 return;
1080         }
1081 }
1082
1083 static void __bt_gatt_char_method_call(GDBusConnection *connection,
1084                 const gchar *sender,
1085                 const gchar *object_path,
1086                 const gchar *interface_name,
1087                 const gchar *method_name,
1088                 GVariant *parameters,
1089                 GDBusMethodInvocation *invocation,
1090                 gpointer user_data)
1091 {
1092         if (g_strcmp0(method_name, "ReadValue") == 0) {
1093                 gchar *addr = NULL;
1094                 guint req_id = 0;
1095                 guint16 offset = 0;
1096                 struct hal_ev_gatt_server_read_req ev;
1097                 int char_hdl = -1;
1098
1099                 struct gatt_req_info *req_info = NULL;
1100                 struct gatt_client_info_t *conn_info = NULL;
1101                 struct gatt_service_info *svc_info = NULL;
1102
1103                 g_variant_get(parameters, "(&suq)",
1104                                         &addr, &req_id, &offset);
1105
1106                 DBG("Request id = %u, Offset = %u", req_id, offset);
1107                 DBG("Application path = %s", object_path);
1108                 DBG("Sender = %s", sender);
1109                 DBG("Address = %s", addr);
1110
1111                 /* Check if device is already in connected list */
1112                 conn_info = __bt_find_remote_gatt_client_info(addr);
1113
1114                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
1115
1116                 if (svc_info == NULL || conn_info == NULL) {
1117                         g_dbus_method_invocation_return_value(invocation, NULL);
1118                         return;
1119                 }
1120
1121                 if (!event_cb) {
1122                         ERR("GATT callback NOT registered");
1123                         g_dbus_method_invocation_return_value(invocation, NULL);
1124                         return;
1125                 }
1126
1127                 /* Store requets information */
1128                 req_info = g_new0(struct gatt_req_info, 1);
1129                 req_info->attr_path = g_strdup(object_path);
1130                 req_info->svc_path = g_strdup(svc_info->serv_path);
1131                 req_info->request_id = req_id;
1132                 req_info->request_type = BT_HAL_GATT_REQUEST_TYPE_READ;
1133                 req_info->offset = offset;
1134                 req_info->context = invocation;
1135
1136                 /* Append request info in list of requests for the particular connection */
1137                 conn_info->gatt_req_info_list = g_slist_append(conn_info->gatt_req_info_list, req_info);
1138
1139                 /* Send HAL event */
1140                 memset(&ev, 0, sizeof(ev));
1141                 ev.conn_id = conn_info->connection_id;
1142                 ev.trans_id = req_id;
1143                 ev.att_handle = char_hdl;
1144                 ev.offset = offset;
1145                 ev.is_long = false; /* TODO*/
1146
1147                 /* Convert address to hex */
1148                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, addr);
1149                 event_cb(HAL_EV_GATT_READ_REQUESTED, (void *)&ev, sizeof(ev));
1150                 return;
1151         } else if (g_strcmp0(method_name, "WriteValue") == 0) {
1152                 GVariant *var = NULL;
1153                 gchar *addr = NULL;
1154                 guint req_id = 0;
1155                 guint16 offset = 0;
1156                 gboolean response_needed = FALSE;
1157                 struct hal_ev_gatt_server_write_req ev;
1158                 int char_hdl = -1;
1159                 int len;
1160
1161                 struct gatt_service_info *svc_info = NULL;
1162                 struct gatt_req_info *req_info = NULL;
1163                 struct gatt_client_info_t *conn_info = NULL;
1164
1165                 memset(&ev, 0, sizeof(ev));
1166
1167                 DBG("WriteValue");
1168                 DBG("Application path = %s", object_path);
1169                 DBG("Sender = %s", sender);
1170
1171                 g_variant_get(parameters, "(&suqb@ay)",
1172                                 &addr, &req_id, &offset, &response_needed, &var);
1173                 DBG("Request id = %u, Offset = %u", req_id, offset);
1174
1175                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
1176
1177                 /* Check if device is already in connected list */
1178                 conn_info = __bt_find_remote_gatt_client_info(addr);
1179
1180                 if (svc_info == NULL || conn_info == NULL || event_cb == NULL) {
1181                         g_variant_unref(var);
1182                         if (response_needed)
1183                                 g_dbus_method_invocation_return_value(invocation, NULL);
1184                         else
1185                                 g_object_unref(invocation);
1186                         return;
1187                 }
1188
1189                 len = g_variant_get_size(var);
1190                 if (len > 0 && len < 600) {
1191                         char *data;
1192                         data = (char *)g_variant_get_data(var);
1193                         memcpy(ev.value, data, len);
1194                         ev.length = len;
1195                 }
1196
1197                 if (response_needed) {
1198                         /* Store requets information */
1199                         req_info = g_new0(struct gatt_req_info, 1);
1200                         req_info->attr_path = g_strdup(object_path);
1201                         req_info->svc_path = g_strdup(svc_info->serv_path);
1202                         req_info->request_id = req_id;
1203                         req_info->request_type = BT_HAL_GATT_REQUEST_TYPE_WRITE;
1204                         req_info->offset = offset;
1205                         req_info->context = invocation;
1206
1207                         /* Append request info in list of requests for the particular connection */
1208                         conn_info->gatt_req_info_list = g_slist_append(conn_info->gatt_req_info_list, req_info);
1209
1210                 } else {
1211                         g_object_unref(invocation);
1212                 }
1213
1214                 /* Send HAL event */
1215                 ev.conn_id = conn_info->connection_id;
1216                 ev.trans_id = req_id;
1217                 ev.att_handle = char_hdl;
1218                 ev.offset = offset;
1219                 ev.need_rsp = response_needed;
1220                 ev.is_prep = 0;
1221
1222                 /* Convert address to hex */
1223                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, addr);
1224
1225                 event_cb(HAL_EV_GATT_WRITE_REQUESTED, (void *)&ev, sizeof(ev));
1226
1227                 g_variant_unref(var);
1228                 return;
1229
1230         } else if (g_strcmp0(method_name, "StartNotify") == 0) {
1231                 DBG("StartNotify");
1232 #ifdef TIZEN_BT_HAL
1233                 struct gatt_service_info *svc_info = NULL;
1234                 struct hal_ev_gatt_server_notifcation_change ev;
1235                 int char_hdl = -1;
1236
1237                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
1238                 if (svc_info == NULL || event_cb == NULL)
1239                         return;
1240
1241                 /* Send HAL event */
1242                 memset(&ev, 0, sizeof(ev));
1243                 ev.conn_id = -1;  /*TODO Bluez does not provide remote GATT client address, so no conn_id */
1244                 ev.trans_id = -1; /*TODO Bluez does not provide request id or transacion ID */
1245                 ev.att_handle = char_hdl;
1246                 ev.notify = true;
1247
1248                 /* Convert address to hex */
1249                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, "00:00:00:00:00"); /* TODO Bluez Does not provide address of GATT client */
1250
1251                 event_cb(HAL_EV_GATT_NOTIFICATION_CHANGE, (void *)&ev, sizeof(ev));
1252 #endif
1253
1254         } else if (g_strcmp0(method_name, "StopNotify") == 0) {
1255                 DBG("StopNotify");
1256 #ifdef TIZEN_BT_HAL
1257                 struct gatt_service_info *svc_info = NULL;
1258                 struct hal_ev_gatt_server_notifcation_change ev;
1259                 int char_hdl = -1;
1260
1261                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
1262                 if (svc_info == NULL || event_cb == NULL)
1263                         return;
1264
1265                 /* Send HAL event */
1266                 memset(&ev, 0, sizeof(ev));
1267                 ev.conn_id = -1;  /*TODO Bluez does not provide remote GATT client address, so no conn_id */
1268                 ev.trans_id = -1; /*TODO Bluez does not provide request id or transacion ID */
1269                 ev.att_handle = char_hdl;
1270                 ev.notify = false;
1271
1272                 /* Convert address to hex */
1273                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, "00:00:00:00:00"); /* TODO Bluez DOes not provide address of GATT client */
1274
1275                 event_cb(HAL_EV_GATT_NOTIFICATION_CHANGE, (void *)&ev, sizeof(ev));
1276 #endif
1277
1278         } else if (g_strcmp0(method_name, "IndicateConfirm") == 0) {
1279                 gchar *addr = NULL;
1280                 gboolean complete = FALSE;
1281                 int char_hdl = -1;
1282
1283                 struct gatt_service_info *svc_info = NULL;
1284                 struct gatt_client_info_t *conn_info = NULL;
1285
1286                 struct hal_ev_gatt_server_indicate_cfm ev;
1287
1288                 DBG("IndicateConfirm");
1289                 DBG("Application path = %s", object_path);
1290                 DBG("Sender = %s", sender);
1291
1292                 g_variant_get(parameters, "(&sb)", &addr, &complete);
1293                 DBG("Remote Device address number = %s", addr);
1294                 DBG("Is Indicate confirmation for last device [%d]", complete);
1295
1296                 /* Check if device is already in connected list */
1297                 conn_info = __bt_find_remote_gatt_client_info(addr);
1298
1299                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
1300
1301                 if (svc_info == NULL || conn_info == NULL
1302                         || event_cb == NULL) {
1303                         return;
1304                 }
1305
1306                 /* Send HAL event */
1307                 memset(&ev, 0, sizeof(ev));
1308                 ev.conn_id = conn_info->connection_id;
1309                 ev.trans_id = -1; /*TODO Bluez does not provide Transaction ID or request ID */
1310                 ev.att_handle = char_hdl;
1311
1312                 /* Convert address to hex */
1313                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, addr);
1314
1315                 event_cb(HAL_EV_GATT_INDICATE_CFM, (void *)&ev, sizeof(ev));
1316         } else if (g_strcmp0(method_name, "AcquireWrite") == 0) {
1317
1318                                 uint16_t mtu = 512;
1319                                 int char_hdl = -1;
1320                                 struct hal_ev_gatt_server_acquire_write_res  ev;
1321                                 struct gatt_service_info *svc_info = NULL;
1322                                 struct gatt_req_info *req_info = NULL;
1323                                 struct gatt_client_info_t *conn_info = NULL;
1324                                 char * dev_path = NULL;
1325                                 char * link = 0;
1326                                 char  addr[BT_HAL_ADDRESS_STRING_SIZE];
1327
1328                                 DBG("AcquireWrite");
1329                                 DBG("Application path = %s", object_path);
1330                                 DBG("Sender = %s", sender);
1331
1332                                 GVariantIter* iter;
1333                                 g_variant_get(parameters, "(a{sv})", &iter);
1334                                 char* key = NULL;
1335                                 GVariant* value = NULL;
1336                                 while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
1337                                                 if (g_strcmp0(key, "MTU") == 0)
1338                                                         g_variant_get(value, "i", &mtu);
1339                                                 else if (g_strcmp0(key, "link") == 0)
1340                                                         g_variant_get(value, "s", &link);
1341                                                 else if (g_strcmp0(key, "device") == 0)
1342                                                         g_variant_get(value, "o", &dev_path);
1343                                 }
1344
1345                                 DBG("AcquireWrite   values retived");
1346                                 DBG(" path  %s LINK = %s, MTU = %u", addr, link, mtu);
1347
1348                                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
1349
1350                                 _bt_hal_convert_device_path_to_address(dev_path, addr);
1351
1352                                 DBG("remote address %s", addr);
1353
1354                                 /* Check if device is already in connected list */
1355                                 conn_info = __bt_find_remote_gatt_client_info(addr);
1356
1357                                 if (conn_info == NULL) {
1358                                         ERR("Cleint info not found\n");
1359                                         goto done;
1360                                 }
1361
1362                                 if (svc_info == NULL) {
1363                                         ERR("svc_info  info not found\n");
1364                                         goto done;
1365                                 }
1366
1367                                 /* Store requets information */
1368                                 req_info = g_new0(struct gatt_req_info, 1);
1369                                 req_info->attr_path = g_strdup(object_path);
1370                                 req_info->svc_path = g_strdup(svc_info->serv_path);
1371                                 req_info->request_id = conn_info->connection_id;
1372                                 req_info->request_type = BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_WRITE;
1373                                 req_info->offset = mtu;
1374                                 req_info->context = invocation;
1375
1376                                 /* Append request info in list of requests for the particular connection */
1377                                 conn_info->gatt_req_info_list = g_slist_append(conn_info->gatt_req_info_list, req_info);
1378
1379                                 /* Send HAL event */
1380                                 memset(&ev, 0, sizeof(ev));
1381                                 ev.conn_id = conn_info->connection_id;
1382                                 ev.char_handl = char_hdl;
1383                                 ev.mtu = mtu;
1384                                 ev.trans_id = conn_info->connection_id;
1385                                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, addr);
1386                                 event_cb(HAL_EV_GATT_SERVER_ACQUIRE_WRITE_RES, (void *)&ev, sizeof(ev));
1387
1388                                 DBG("HAL_EV_GATT_ACQUIRE_WRITE_RES   called");
1389
1390
1391                         return;
1392                 } else if (g_strcmp0(method_name, "AcquireNotify") == 0) {
1393
1394                                 uint16_t mtu = 512;
1395                                 int char_hdl = -1;
1396                                 struct hal_ev_gatt_server_acquire_notify  ev;
1397                                 struct gatt_service_info *svc_info = NULL;
1398                                 struct gatt_client_info_t *conn_info = NULL;
1399                                 struct gatt_req_info *req_info = NULL;
1400
1401                                 DBG("AcquireNotify");
1402                                 DBG("Application path = %s", object_path);
1403                                 DBG("Sender = %s", sender);
1404
1405                                 GVariantIter* iter;
1406                                 g_variant_get(parameters, "(a{sv})", &iter);
1407                                 char* key = NULL;
1408                                 GVariant* value = NULL;
1409                                 while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
1410                                                 if (g_strcmp0(key, "MTU") == 0)
1411                                                         g_variant_get(value, "q", &mtu);
1412                                 }
1413
1414                                 DBG("AcquireNotify  values retived");
1415                                 DBG(" MTU = %u",  mtu);
1416
1417                                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
1418
1419                         if (svc_info == NULL) {
1420                                         ERR("svc_info  info not found\n");
1421                                         goto done;
1422                                 }
1423
1424                                 /* Store requets information */
1425                                 req_info = g_new0(struct gatt_req_info, 1);
1426                                 req_info->attr_path = g_strdup(object_path);
1427                                 req_info->svc_path = g_strdup(svc_info->serv_path);
1428                                 req_info->request_id = 33;
1429                                 req_info->request_type = BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY;
1430                                 req_info->offset = mtu;
1431                                 req_info->context = invocation;
1432
1433                                 conn_info = g_new0(struct gatt_client_info_t, 1);
1434                                 conn_info->addr = g_strdup(object_path);
1435                                 INFO("Added GATT client path[%s]", conn_info->addr);
1436                                 conn_info->connection_id = 33;
1437                                 conn_info->instance_id = 33;
1438                                 /* Append request info in list of requests for the particular connection */
1439                                 conn_info->gatt_req_info_list = g_slist_append(conn_info->gatt_req_info_list, req_info);
1440                                 gatt_client_info_list = g_slist_append(gatt_client_info_list, conn_info);
1441
1442                                 /* Send HAL event */
1443                                 memset(&ev, 0, sizeof(ev));
1444                                 ev.conn_id = 33;
1445                                 ev.char_handl = char_hdl;
1446                                 ev.mtu = mtu;
1447                                 ev.trans_id = 33;
1448
1449                                 event_cb(HAL_EV_GATT_SERVER_ACQUIRE_NOTIFY_RES, (void *)&ev, sizeof(ev));
1450
1451                                 DBG("HAL_EV_GATT_ACQUIRE_NOTIFY_RES   called");
1452
1453                                 return;
1454         }
1455
1456 done:
1457         g_dbus_method_invocation_return_value(invocation, NULL);
1458 }
1459
1460 static gboolean __bt_hal_gatt_emit_interface_removed(gchar *object_path, gchar *interface)
1461 {
1462         gboolean ret;
1463         GError *error = NULL;
1464         GVariantBuilder *array_builder;
1465
1466         array_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
1467         g_variant_builder_init(array_builder, G_VARIANT_TYPE("as"));
1468         g_variant_builder_add(array_builder, "s", interface);
1469
1470         ret = g_dbus_connection_emit_signal(g_conn, NULL, "/",
1471                         "org.freedesktop.Dbus.Objectmanager",
1472                         "InterfacesRemoved",
1473                         g_variant_new("(oas)",
1474                                 object_path, array_builder),
1475                         &error);
1476
1477         if (!ret) {
1478                 if (error != NULL) {
1479                         /* dbus gives error cause */
1480                         ERR("d-bus api failure: errcode[%x], message[%s]",
1481                                         error->code, error->message);
1482                         g_clear_error(&error);
1483                 }
1484         }
1485         g_variant_builder_unref(array_builder);
1486
1487         return ret;
1488 }
1489
1490 static void __bt_hal_gatt_free_descriptor_info(struct gatt_desc_info *desc_info)
1491 {
1492         int i;
1493
1494         if (!desc_info)
1495                 return;
1496
1497         g_free(desc_info->desc_path);
1498         g_free(desc_info->desc_uuid);
1499         g_free(desc_info->desc_value);
1500
1501         for (i = 0; i < desc_info->flags_length; i++)
1502                 g_free(desc_info->desc_flags[i]);
1503
1504         g_free(desc_info);
1505 }
1506
1507 static void __bt_hal_gatt_free_characteristic_info(struct gatt_char_info *char_info)
1508 {
1509         int i;
1510
1511         if (!char_info)
1512                 return;
1513
1514         g_free(char_info->char_path);
1515         g_free(char_info->char_uuid);
1516         g_free(char_info->char_value);
1517
1518         for (i = 0; i < char_info->flags_length; i++)
1519                 g_free(char_info->char_flags[i]);
1520
1521         g_free(char_info);
1522 }
1523
1524
1525 static void __bt_hal_gatt_free_service_info(struct gatt_service_info *svc_info)
1526 {
1527         if (!svc_info)
1528                 return;
1529
1530         g_free(svc_info->serv_path);
1531         g_free(svc_info->service_uuid);
1532         g_free(svc_info);
1533 }
1534
1535 static const GDBusInterfaceVTable desc_interface_vtable = {
1536         __bt_gatt_desc_method_call,
1537         NULL,
1538         NULL,
1539 };
1540
1541 static const GDBusInterfaceVTable char_interface_vtable = {
1542         __bt_gatt_char_method_call,
1543         NULL,
1544         NULL,
1545 };
1546
1547 static const GDBusInterfaceVTable serv_interface_vtable = {
1548         NULL,
1549         NULL,
1550         NULL,
1551 };
1552
1553 static const GDBusInterfaceVTable manager_interface_vtable = {
1554         __bt_gatt_manager_method_call,
1555         NULL,
1556         NULL
1557 };
1558
1559
1560 static GDBusNodeInfo *__bt_gatt_create_method_node_info(
1561                 const gchar *introspection_data)
1562 {
1563         GError *err = NULL;
1564         GDBusNodeInfo *node_info = NULL;
1565
1566         if (introspection_data == NULL)
1567                 return NULL;
1568
1569
1570         DBG("Create new node info");
1571         node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
1572
1573         if (err) {
1574                 ERR("Unable to create node: %s", err->message);
1575                 g_clear_error(&err);
1576                 return NULL;
1577         }
1578
1579         return node_info;
1580 }
1581
1582 /* To send stack event to hal-av handler */
1583 void _bt_hal_register_gatt_server_handler_cb(handle_stack_msg cb)
1584 {
1585         event_cb = cb;
1586 }
1587
1588 void _bt_hal_unregister_gatt_server_handler_cb(void)
1589 {
1590         event_cb = NULL;
1591 }
1592
1593 static gboolean __bt_hal_gatt_desc_added_cb(gpointer user_data)
1594 {
1595         struct hal_ev_gatt_desc_added ev;
1596         hal_gatt_desc_added *data = (hal_gatt_desc_added*) user_data;
1597
1598         /* Prepare to GATT characteristic added event */
1599         memset(&ev, 0, sizeof(ev));
1600         ev.status = BT_STATUS_SUCCESS;
1601         ev.server_instance = data->instance_data;
1602         memcpy(ev.desc_uuid, data->uuid.uu, sizeof(data->uuid.uu));
1603         ev.service_handle = data->srvc_hdl;
1604         ev.desc_handle = data->desc_hdl;
1605
1606         if (!event_cb)
1607                 ERR("GATT Descriptor Added callback registered");
1608         else {
1609                 DBG("GATT Descriptor Added: server if [%d] Service handle [%d] Descriptor Handle [%d]",
1610                                 data->instance_data, data->srvc_hdl, data->desc_hdl);
1611
1612                 event_cb(HAL_EV_GATT_DESC_ADDED, (void *)&ev, sizeof(ev));
1613         }
1614
1615         g_free(data);
1616         return FALSE;
1617 }
1618
1619 static gboolean __bt_hal_gatt_char_added_cb(gpointer user_data)
1620 {
1621         struct hal_ev_gatt_char_added ev;
1622         hal_gatt_char_added *data = (hal_gatt_char_added*) user_data;
1623
1624         /* Prepare to GATT characteristic added event */
1625         memset(&ev, 0, sizeof(ev));
1626         ev.status = BT_STATUS_SUCCESS;
1627         ev.server_instance = data->instance_data;
1628         memcpy(ev.char_uuid, data->uuid.uu, sizeof(data->uuid.uu));
1629         ev.service_handle = data->srvc_hdl;
1630         ev.char_handle = data->char_hdl;
1631
1632         if (!event_cb)
1633                 ERR("GATT Characteristic Added callback registered");
1634         else {
1635                 DBG("GATT Characteristic Added: server if [%d] Service handle [%d] Characteristic handle [%d]",
1636                                 data->instance_data, data->srvc_hdl, data->char_hdl);
1637
1638                 event_cb(HAL_EV_GATT_CHAR_ADDED, (void *)&ev, sizeof(ev));
1639         }
1640
1641         g_free(data);
1642         return FALSE;
1643 }
1644
1645 static gboolean __bt_hal_gatt_service_added_cb(gpointer user_data)
1646 {
1647         struct hal_ev_gatt_service_added ev;
1648         hal_gatt_service_added *data = (hal_gatt_service_added*) user_data;
1649
1650         /* Prepare to GATT Service added event */
1651         memset(&ev, 0, sizeof(ev));
1652         ev.status = BT_STATUS_SUCCESS;
1653         ev.server_instance = data->instance_data;
1654         memcpy(ev.svc_uuid, data->uuid.uu, sizeof(data->uuid.uu));
1655         ev.service_handle = data->srvc_hdl;
1656         ev.is_primary = data->is_primary;
1657
1658         if (!event_cb)
1659                 ERR("GATT Service Added callback registered");
1660         else {
1661                 DBG("GATT Service Added: server if [%d] Service handle [%d]",
1662                                 data->instance_data,  data->srvc_hdl);
1663                 event_cb(HAL_EV_GATT_SERVICE_ADDED, (void *)&ev, sizeof(ev));
1664         }
1665
1666         g_free(data);
1667         return FALSE;
1668 }
1669
1670 static gboolean __bt_hal_gatt_service_started_cb(gpointer user_data)
1671 {
1672         struct hal_ev_gatt_service_started ev;
1673         hal_gatt_service_started *data = (hal_gatt_service_started*) user_data;
1674
1675         /* Prepare to GATT Service added event */
1676         memset(&ev, 0, sizeof(ev));
1677         ev.status = BT_STATUS_SUCCESS;
1678         ev.server_instance = data->instance_data;
1679         ev.service_handle = data->srvc_hdl;
1680
1681         if (!event_cb)
1682                 ERR("GATT Service Started callback registered");
1683         else {
1684                 DBG("GATT Service Started: server if [%d] Service handle [%d]",
1685                                 data->instance_data,  data->srvc_hdl);
1686                 event_cb(HAL_EV_GATT_SERVICE_STARTED, (void *)&ev, sizeof(ev));
1687         }
1688
1689         g_free(data);
1690         return FALSE;
1691 }
1692
1693 static gboolean __bt_hal_gatt_service_deleted_cb(gpointer user_data)
1694 {
1695         struct hal_ev_gatt_service_deleted ev;
1696         hal_gatt_service_deleted *data = (hal_gatt_service_deleted*) user_data;
1697
1698         /* Prepare to GATT Service added event */
1699         memset(&ev, 0, sizeof(ev));
1700         ev.status = BT_STATUS_SUCCESS;
1701         ev.server_instance = data->instance_data;
1702         ev.service_handle = data->srvc_hdl;
1703
1704         if (!event_cb)
1705                 ERR("GATT Service Deleted callback registered");
1706         else {
1707                 DBG("GATT Service Deleted: server if [%d] Service handle [%d]",
1708                                 data->instance_data,  data->srvc_hdl);
1709                 event_cb(HAL_EV_GATT_SERVICE_DELETED, (void *)&ev, sizeof(ev));
1710         }
1711
1712         g_free(data);
1713         return FALSE;
1714 }
1715
1716 static gboolean __bt_hal_register_slot_id_cb(gpointer user_data)
1717 {
1718         struct hal_ev_server_instance_registered ev;
1719         hal_register_server_data *data = (hal_register_server_data*) user_data;
1720
1721         /* Prepare to send AV connecting event */
1722         memset(&ev, 0, sizeof(ev));
1723         ev.status = BT_STATUS_SUCCESS;
1724         ev.server_instance = data->instance_data;
1725         memcpy(ev.app_uuid, data->uuid.uu, sizeof(ev.app_uuid));
1726
1727         if (!event_cb)
1728                 ERR("GATT Register Server Instance Callback not registered");
1729         else {
1730                 DBG("Server Instance is registered!! server if [%d]", data->instance_data);
1731                 event_cb(HAL_EV_SERVER_INSTANCE_INITIALIZED, (void *)&ev, sizeof(ev));
1732         }
1733
1734         g_free(data);
1735         return FALSE;
1736 }
1737
1738 static bt_status_t gatt_server_register_app(bt_uuid_t *uuid)
1739 {
1740         CHECK_BTGATT_INIT();
1741         int status = BT_STATUS_FAIL;
1742         int server_if;
1743         DBG("Register server instance request");
1744         hal_register_server_data *user_data = g_malloc0(sizeof(hal_register_server_data));
1745
1746         /* Check if slot available */
1747         server_if = _bt_hal_get_available_adv_slot_id(uuid, FALSE);
1748
1749         if (server_if == -1) {
1750                 ERR("Allocation of server instance failed");
1751                 g_free(user_data);
1752                 return status;
1753         } else {
1754                 user_data->instance_data = server_if;
1755                 DBG("Allocated new Advertising slot with Stack [%d]", user_data->instance_data);
1756         }
1757
1758         /*
1759          * As we need to provide async callback to user from HAL, simply schedule a
1760          * callback method which will carry actual result
1761          */
1762         memcpy(user_data->uuid.uu, uuid->uu, sizeof(bt_uuid_t));
1763         g_idle_add(__bt_hal_register_slot_id_cb, (gpointer)user_data);
1764
1765         /* If available, then return success, else return error */
1766         return BT_STATUS_SUCCESS;
1767 }
1768
1769 static void _bt_hal_remove_gatt_server_from_list(int server_if)
1770 {
1771         GSList *l;
1772         struct gatt_server_app *info = NULL;
1773
1774         for (l = gatt_server_apps; l != NULL;) {
1775                 info = (struct gatt_server_app*)l->data;
1776                 l = g_slist_next(l);
1777                 if (info == NULL)
1778                         continue;
1779                 if (info->slot == server_if) {
1780                         INFO("Found Matching GATT Server in List path[%s] slot [%d]",
1781                                 info->app_path, info->slot);
1782
1783                         /* Only if all services are deleted from the GATT Server, then only Unregister it.
1784                         Reason: it is possible, GATT Server app oly wants to disable multi advertising
1785                         In above case, only advertising block will be deallocated, Gatt Server will remain
1786                         unaffected */
1787                         if (info->services == NULL) {
1788                                 gatt_server_apps = g_slist_remove(gatt_server_apps, (gpointer)info);
1789                                 INFO("Total gatt server apps still existing after removing above is [%d]",
1790                                                 g_slist_length(gatt_server_apps));
1791
1792                                 /* DBUS Unregister only for current app */
1793                                 __bt_hal_gatt_deinit(info->app_path);
1794
1795                                 g_free(info->app_path);
1796                                 g_free(info);
1797                                 return;
1798                         } else {
1799                                 INFO("GATT Server still has services count[%d] in it..Can not remove it!!!",
1800                                         g_slist_length(info->services));
1801                         }
1802                 }
1803         }
1804 }
1805
1806 static bt_status_t gatt_server_unregister_app(int server_if)
1807 {
1808         CHECK_BTGATT_INIT();
1809         DBG("Un-Register server instance request [%d]", server_if);
1810
1811         if (_bt_hal_is_advertising_in_slot(server_if) == FALSE)
1812                 _bt_hal_free_server_slot(server_if);
1813
1814         /* If server_if belongs to a GATT Server, then delete the GATT server from List */
1815         _bt_hal_remove_gatt_server_from_list(server_if);
1816         return BT_STATUS_SUCCESS;
1817 }
1818
1819 static bt_status_t gatt_server_open(int server_if, const bt_bdaddr_t *bd_addr, bool is_direct)
1820 {
1821         CHECK_BTGATT_INIT();
1822         return BT_STATUS_SUCCESS;
1823 }
1824
1825 static void __le_disconnection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
1826                 gpointer user_data)
1827 {
1828         GError *g_error = NULL;
1829         GVariant *reply = NULL;
1830
1831         DBG("+");
1832
1833         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
1834         g_object_unref(proxy);
1835         if (reply == NULL) {
1836                 ERR("Disconnect LE Dbus Call Error");
1837                 if (g_error) {
1838                         ERR("Error: %s\n", g_error->message);
1839                         g_clear_error(&g_error);
1840                 }
1841         }
1842         g_variant_unref(reply);
1843 }
1844
1845
1846 static bt_status_t gatt_server_close(int server_if, const bt_bdaddr_t *bd_addr, int conn_id)
1847 {
1848         CHECK_BTGATT_INIT();
1849
1850         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1851         gchar *device_path;
1852         GDBusProxy *device_proxy;
1853         GDBusConnection *g_conn;
1854         struct gatt_client_info_t *conn_info = NULL;
1855
1856         INFO("+");
1857
1858         if (NULL == bd_addr) {
1859                 ERR("bd_addr is NULL");
1860                 return BT_STATUS_PARM_INVALID;
1861         }
1862
1863         /* GDBUS Connection Info validate */
1864         g_conn = _bt_hal_get_system_gconn();
1865         if (g_conn == NULL) {
1866                 ERR("Could not get System DBUS Connection");
1867                 return  BT_STATUS_FAIL;
1868         }
1869
1870         /* Connection Info validate */
1871         conn_info = __bt_find_remote_gatt_client_info_from_conn(conn_id);
1872         if (conn_info == NULL) {
1873                 ERR("No Connection Inforamtion!!!");
1874                 return BT_STATUS_FAIL;
1875         }
1876
1877         _bt_hal_convert_addr_type_to_string(device_address,
1878                                 (unsigned char *)bd_addr->address);
1879
1880         //check if connection has the same device address
1881         if (g_strcmp0(conn_info->addr, device_address)  != 0) {
1882                 ERR("device address [%s] does not match", device_address);
1883                 return BT_STATUS_FAIL;
1884         }
1885
1886         device_path = _bt_hal_get_device_object_path(conn_info->addr);
1887         if (device_path == NULL) {
1888                 ERR("device_path is NULL");
1889                 return BT_STATUS_PARM_INVALID;
1890         }
1891
1892         device_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
1893                         NULL, BT_HAL_BLUEZ_NAME,
1894                         device_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
1895
1896
1897         g_free(device_path);
1898         if (device_proxy == NULL)
1899                 return BT_STATUS_FAIL;
1900
1901         INFO("Disconnect LE [%s]", device_address);
1902
1903         g_dbus_proxy_call(device_proxy, "DisconnectLE",
1904                 NULL,
1905                 G_DBUS_CALL_FLAGS_NONE,
1906                 BT_HAL_MAX_DBUS_TIMEOUT,
1907                 NULL,
1908                 (GAsyncReadyCallback)__le_disconnection_req_cb, conn_info);
1909
1910         INFO("-");
1911         return BT_STATUS_SUCCESS;
1912 }
1913
1914 static char* __bt_hal_convert_uuid_to_string(bt_uuid_t *srvc_id)
1915 {
1916         char uuid_buf[5];
1917         const char *uuid;
1918
1919         uuid = btuuid2str(srvc_id->uu);
1920         DBG("Original UUID [%s]", uuid);
1921
1922         if (_bt_hal_uuid_is_standard(srvc_id) == TRUE) {
1923                 /* Extract Standard UUID string */
1924                 memcpy(uuid_buf, &uuid[4], 4);
1925                 uuid_buf[4] = '\0';
1926                 DBG("Converted string [%s]", uuid_buf);
1927                 return g_strdup(uuid_buf);
1928         } else
1929                 return strdup(uuid);
1930 }
1931
1932 static int __bt_hal_add_service_to_dbus(char *app_path, int slot, btgatt_srvc_id_t *srvc_id)
1933 {
1934         gboolean ret;
1935         /* For GATT service specific */
1936         GDBusNodeInfo *node_info;
1937         guint object_id;
1938         gchar *path = NULL;
1939         struct gatt_service_info *serv_info = NULL;
1940         GVariantBuilder *builder = NULL;
1941         GVariantBuilder *builder1 = NULL;
1942         GVariantBuilder *inner_builder = NULL;
1943         gboolean svc_primary = TRUE;
1944         GError *error = NULL;
1945         hal_gatt_service_added *user_data = NULL;
1946         DBG("Service add to DBUS slot [%d]", slot);
1947
1948         node_info = __bt_gatt_create_method_node_info(
1949                         service_introspection_xml);
1950
1951         if (node_info == NULL)
1952                 return BT_STATUS_FAIL;
1953
1954         DBG("Add new GATT Service: Current GATT Service handle [%d]", gatt_service_handle);
1955         path = g_strdup_printf("%s"GATT_SERV_OBJECT_PATH"%d", app_path, ++gatt_service_handle);
1956         DBG("gatt service path is [%s]", path);
1957
1958         object_id = g_dbus_connection_register_object(g_conn, path,
1959                         node_info->interfaces[0],
1960                         &serv_interface_vtable,
1961                         NULL, NULL, &error);
1962
1963         if (object_id == 0) {
1964                 ERR("failed to register: %s", error->message);
1965                 g_error_free(error);
1966                 g_free(path);
1967                 return BT_STATUS_FAIL;
1968         }
1969         /* Add object_id/gatt service information; it's required at the time of
1970          *  service unregister and Getmanagedobjects
1971          */
1972         serv_info = g_new0(struct gatt_service_info, 1);
1973
1974         serv_info->serv_path = g_strdup(path);
1975         serv_info->serv_id = object_id;
1976         serv_info->service_uuid = __bt_hal_convert_uuid_to_string(&srvc_id->id.uuid);//g_strdup(btuuid2str(srvc_id->id.uuid.uu));
1977         serv_info->is_svc_registered = FALSE;
1978         serv_info->is_svc_primary = svc_primary;
1979         DBG("Service Handle to be added is [%d]", gatt_service_handle);
1980         serv_info->service_handle = gatt_service_handle;
1981
1982         /* Update service in GATT Server service List */
1983         gatt_services = g_slist_append(gatt_services, serv_info);
1984
1985         /* emit interfacesadded signal here for service path */
1986         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
1987         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1988
1989         g_variant_builder_add(inner_builder, "{sv}",
1990                         "UUID", g_variant_new_string(btuuid2str(srvc_id->id.uuid.uu)));
1991
1992         g_variant_builder_add(inner_builder, "{sv}",
1993                         "Primary", g_variant_new_boolean(svc_primary));
1994
1995         builder1 = g_variant_builder_new(G_VARIANT_TYPE("ao"));
1996
1997         g_variant_builder_add(inner_builder, "{sv}", "Characteristics",
1998                         g_variant_new("ao", builder1));
1999
2000         g_variant_builder_add(builder, "{sa{sv}}",
2001                         GATT_SERV_INTERFACE, inner_builder);
2002
2003         ret = g_dbus_connection_emit_signal(g_conn, NULL, "/",
2004                         "org.freedesktop.Dbus.ObjectManager",
2005                         "InterfacesAdded",
2006                         g_variant_new("(oa{sa{sv}})",
2007                                 path, builder),
2008                         &error);
2009         if (!ret) {
2010                 if (error) {
2011                         /* dbus gives error cause */
2012                         ERR("d-bus api failure: errcode[%x], message[%s]",
2013                                         error->code, error->message);
2014                         g_clear_error(&error);
2015                 }
2016         }
2017
2018         /* Send Service handle to application */
2019         user_data = g_malloc0(sizeof(hal_gatt_service_added));
2020         user_data->srvc_hdl = serv_info->service_handle;
2021         user_data->instance_data = slot;
2022         memcpy(user_data->uuid.uu, srvc_id->id.uuid.uu, sizeof(srvc_id->id.uuid.uu));
2023         g_idle_add(__bt_hal_gatt_service_added_cb, (gpointer)user_data);
2024
2025         /* Save newly created service in GATT Server's service list */
2026         _bt_hal_update_gatt_service_in_gatt_server(slot, serv_info);
2027
2028         /* Free data */
2029         g_free(path);
2030         g_variant_builder_unref(inner_builder);
2031         g_variant_builder_unref(builder);
2032         g_variant_builder_unref(builder1);
2033         return BT_STATUS_SUCCESS;
2034 }
2035
2036 static void __bt_hal_unregister_application_cb(GObject *object, GAsyncResult *res,
2037                 gpointer user_data)
2038 {
2039         char *app_path = (char*)user_data;
2040         INFO("UnregisterApplication is completed app [%s]", app_path);
2041         GError *error = NULL;
2042         GVariant *result = NULL;
2043
2044         if (manager_gproxy)
2045         result = g_dbus_proxy_call_finish(manager_gproxy, res, &error);
2046
2047         if (result == NULL) {
2048                 /* dBUS-RPC is failed */
2049                 ERR("Dbus-RPC is failed\n");
2050
2051                 if (error != NULL) {
2052                         /* dBUS gives error cause */
2053                         ERR("D-Bus API failure: errCode[%x], message[%s]\n",
2054                                         error->code, error->message);
2055                         g_clear_error(&error);
2056                 }
2057         } else {
2058                 g_variant_unref(result);
2059         }
2060         g_free(app_path);
2061 }
2062
2063 static void __bt_hal_gatt_deinit(char *app_path)
2064 {
2065         GDBusProxy *proxy = NULL;
2066         char *data;
2067         INFO("+");
2068
2069         /* Step1: Remove requested App */
2070         proxy = __bt_gatt_gdbus_get_gatt_manager_proxy("org.bluez",
2071                         "/org/bluez/hci0", "org.bluez.GattManager1");
2072
2073         if (proxy == NULL)
2074                 return;
2075
2076         INFO("UnregisterApplication : path [%s]", app_path);
2077
2078         /* Async Call to Unregister Service */
2079         data = g_strdup(app_path);
2080         g_dbus_proxy_call(proxy,
2081                         "UnregisterApplication",
2082                         g_variant_new("(o)",
2083                                 app_path),
2084                         G_DBUS_CALL_FLAGS_NONE, -1,
2085                         NULL,
2086                         (GAsyncReadyCallback)__bt_hal_unregister_application_cb,
2087                         (gpointer)data);
2088
2089         /* If requested app is last GATT Server app, then clean all resources */
2090         if (gatt_server_apps == NULL) {
2091                 INFO("All GATT servers are removed, clean all DBUS resources");
2092                 if (owner_id) {
2093                         /* unregister the exported interface for object manager */
2094                         g_dbus_connection_unregister_object(g_conn, manager_id);
2095                         manager_id = 0;
2096                         g_bus_unown_name(owner_id);
2097                         owner_id = 0;
2098
2099                         g_object_unref(manager_gproxy);
2100                         manager_gproxy = NULL;
2101                 }
2102         }
2103         INFO("-");
2104 }
2105
2106 static int __bt_hal_gatt_init(void)
2107 {
2108         DBG("+");
2109
2110         /* Only once for ALL GATT Servers */
2111         if (owner_id == 0) {
2112                 GError *err = NULL;
2113                 gchar *name = NULL;
2114
2115                 g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
2116                 if (!g_conn) {
2117                         if (err) {
2118                                 ERR("Unable to connect to gdbus: %s", err->message);
2119                                 g_clear_error(&err);
2120                         }
2121                         return BT_STATUS_FAIL;
2122                 }
2123
2124                 name = g_strdup_printf("%s.p%d", BT_GATT_SERVICE_NAME, getpid());
2125                 INFO("well-known name: %s", name);
2126
2127                 owner_id = g_bus_own_name_on_connection(g_conn, name,
2128                                         G_BUS_NAME_OWNER_FLAGS_NONE,
2129                                         NULL, NULL, NULL, NULL);
2130         }
2131         INFO("Owner ID [%d]", owner_id);
2132
2133         /* Only once for ALL GATT Servers */
2134         if (manager_node_info == NULL) {
2135                 /* Register ObjectManager interface */
2136                 manager_node_info = __bt_gatt_create_method_node_info(
2137                                 manager_introspection_xml);
2138
2139                 if (manager_node_info == NULL) {
2140                         ERR("failed to get node info");
2141                         return BT_STATUS_FAIL;
2142                 }
2143         }
2144
2145         INFO("-");
2146         return BT_STATUS_SUCCESS;
2147 }
2148
2149 static void _bt_hal_is_gatt_server_initialzed(int slot, char **app_path)
2150 {
2151         GSList *l;
2152
2153         for (l = gatt_server_apps; l; l = g_slist_next(l)) {
2154                 struct gatt_server_app *app = (struct gatt_server_app *)l->data;
2155                 if (app->slot == slot) {
2156                         INFO("GATT Server app found app path [%s] instance [%d]",
2157                                         app->app_path, app->slot);
2158                         *app_path = app->app_path;
2159                         return;
2160                 }
2161         }
2162         /* GATT Server not found */
2163         *app_path = NULL;
2164 }
2165
2166 static void _bt_hal_update_gatt_server_path(int slot, char *app_path)
2167 {
2168         if (app_path == NULL)
2169                 return;
2170
2171         struct gatt_server_app *app = g_malloc0(sizeof(struct gatt_server_app));
2172         app->app_path = g_strdup(app_path);
2173         app->slot = slot;
2174         gatt_server_apps = g_slist_append(gatt_server_apps, app);
2175         INFO("GATT Server: Path [%s] Slot [%d]-> Updated", app_path, slot);
2176
2177 }
2178
2179
2180 static bt_status_t gatt_server_add_service(int server_if, btgatt_srvc_id_t *srvc_id,
2181                 int num_handles)
2182 {
2183         CHECK_BTGATT_INIT();
2184         char *app_path = NULL;
2185         GError *error = NULL;
2186         int *app_id = NULL;
2187
2188         int result = BT_STATUS_SUCCESS;
2189
2190         DBG("GATT Server Add service request: Instance ID[%d] Is Primary [%d] UUID [%s]",
2191                         server_if, srvc_id->is_primary, btuuid2str(srvc_id->id.uuid.uu));
2192
2193         /* Check if this GATT server Application is already registered with DBUS */
2194         _bt_hal_is_gatt_server_initialzed(server_if, &app_path);
2195
2196         if (app_path != NULL) {
2197                 DBG("GATT server path is already defined [%s]", app_path);
2198                 return __bt_hal_add_service_to_dbus(app_path, server_if, srvc_id);
2199         } else {
2200                 DBG("GATT server application path for instance [%d] is not defined yet", server_if);
2201                 result = __bt_hal_gatt_init();
2202                 if (result != BT_STATUS_SUCCESS)
2203                         return result;
2204
2205                 /* Only once for each GATT Server */
2206                 app_path = g_strdup_printf("/com/%d", server_if);
2207
2208                 app_id = g_malloc0(sizeof(int));
2209                 *app_id = server_if;
2210
2211                 manager_id = g_dbus_connection_register_object(g_conn, app_path,
2212                                 manager_node_info->interfaces[0],
2213                                 &manager_interface_vtable,
2214                                 (gpointer)app_id, NULL, &error);
2215
2216                 if (manager_id == 0) {
2217                         ERR("failed to register: %s", error->message);
2218                         g_error_free(error);
2219                         goto failed;
2220                 }
2221                 INFO("manager_id [%d]", manager_id);
2222
2223                 /* For current GATT Server, app_path is created, save it in Table */
2224                 _bt_hal_update_gatt_server_path(server_if, app_path);
2225
2226                 /* Add GATT Service to DBUS */
2227                 if (__bt_hal_add_service_to_dbus(app_path, server_if, srvc_id) != BT_STATUS_SUCCESS)
2228                         goto failed;
2229
2230                 g_free(app_path);
2231         }
2232
2233         INFO("Successfully added service");
2234         return BT_STATUS_SUCCESS;
2235 failed:
2236
2237         g_free(app_id);
2238
2239         if (app_path)
2240                 g_free(app_path);
2241         INFO("Service addition failed!!");
2242         return BT_STATUS_FAIL;
2243 }
2244
2245 static bt_status_t gatt_server_add_included_service(int server_if, int service_handle,
2246                 int included_handle)
2247 {
2248         CHECK_BTGATT_INIT();
2249         return BT_STATUS_SUCCESS;
2250 }
2251
2252
2253 static gboolean __bt_is_service_last_in_server_list(int instance, int service_handle)
2254 {
2255         GSList *l;
2256         GSList *gatt_services = NULL;
2257         int len;
2258         struct gatt_service_info *info = NULL;
2259
2260         gatt_services =  _bt_get_service_list_from_server(instance);
2261
2262         len = g_slist_length(gatt_services);
2263         l = g_slist_nth(gatt_services, len -1);
2264         if (NULL == l)
2265                 return FALSE;
2266
2267         info = l->data;
2268
2269         if (info->service_handle == service_handle)
2270                 return TRUE;
2271         return FALSE;
2272 }
2273
2274 static struct gatt_service_info *__bt_gatt_find_gatt_service_info(int instance,
2275                 int service_handle)
2276 {
2277         GSList *l;
2278         GSList *gatt_services = NULL;
2279         INFO("Find Service: svc handle [%d] from GATT Server slot[%d]", service_handle, instance);
2280
2281         gatt_services = _bt_get_service_list_from_server(instance);
2282
2283         for (l = gatt_services; l != NULL; l = g_slist_next(l)) {
2284                 struct gatt_service_info *info = l->data;
2285                 INFO("Got one service with handle [%d]", info->service_handle);
2286                 if (info->service_handle == service_handle)
2287                         return info;
2288         }
2289         ERR("Gatt service with handle [%d] not found", service_handle);
2290         return NULL;
2291 }
2292
2293 static bt_status_t gatt_server_add_characteristic(int slot, int service_handle,
2294                 bt_uuid_t *uuid, int properties,
2295                 int permissions)
2296 {
2297         gboolean ret;
2298         GError *error = NULL;
2299         guint object_id;
2300         GDBusNodeInfo *node_info;
2301         gchar *path = NULL;
2302         GVariantBuilder *builder = NULL;
2303         GVariantBuilder *inner_builder = NULL;
2304         struct gatt_service_info *serv_info = NULL;
2305         struct gatt_char_info *char_info = NULL;
2306         GVariantBuilder *builder2 = NULL;
2307         GVariantBuilder *builder3 = NULL;
2308         GVariant *flags_val = NULL;
2309         int i = 0;
2310         char *char_flags[NUMBER_OF_FLAGS];
2311         int flag_count = 0;
2312         hal_gatt_char_added *user_data = NULL;
2313         int *app_id;
2314
2315         CHECK_BTGATT_INIT();
2316         DBG("Add new characteristic to GATT Service handle [%d]", service_handle);
2317         DBG("Properties of new charateristic [%d] Permission [%d]", properties, permissions);
2318
2319         serv_info = __bt_gatt_find_gatt_service_info(slot, service_handle);
2320         if (serv_info == NULL)
2321                 return BT_STATUS_FAIL;
2322
2323         node_info = __bt_gatt_create_method_node_info(
2324                         characteristics_introspection_xml);
2325
2326         if (node_info == NULL)
2327                 return BT_STATUS_FAIL;
2328
2329         DBG("Add new GATT characteristic: Current GATT char handle [%d]", gatt_char_handle);
2330         path = g_strdup_printf("%s/characteristic%d", serv_info->serv_path, ++gatt_char_handle);
2331         DBG("gatt characteristic path is [%s]", path);
2332
2333         app_id = g_malloc0(sizeof(int));
2334         *app_id = slot;
2335
2336         object_id = g_dbus_connection_register_object(g_conn, path,
2337                         node_info->interfaces[0],
2338                         &char_interface_vtable,
2339                         (gpointer)app_id, NULL, &error);
2340
2341         if (object_id == 0) {
2342                 ERR("failed to register: %s", error->message);
2343                 g_error_free(error);
2344                 g_free(path);
2345                 g_free(app_id);
2346                 return BT_STATUS_FAIL;
2347         }
2348
2349         if (permissions & BT_HAL_GATT_PERMISSION_ENCRYPT_READ)
2350                 properties |= BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
2351         if (permissions & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ)
2352                 properties |= BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
2353         if (permissions & BT_HAL_GATT_PERMISSION_ENCRYPT_WRITE)
2354                 properties |= BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
2355         if (permissions & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE)
2356                 properties |= BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
2357
2358         flag_count = bt_hal_gatt_convert_prop2string(properties, char_flags);
2359
2360         char_info = g_new0(struct gatt_char_info, 1);
2361
2362         char_info->char_path = g_strdup(path);
2363         char_info->char_id = object_id;
2364         char_info->char_uuid = __bt_hal_convert_uuid_to_string(uuid);//g_strdup(btuuid2str(uuid->uu));
2365         for (i = 0; i < flag_count; i++)
2366                 char_info->char_flags[i] = char_flags[i];
2367
2368
2369         char_info->flags_length = flag_count;
2370         char_info->char_handle = gatt_char_handle;
2371
2372
2373         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
2374         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2375
2376         g_variant_builder_add(inner_builder, "{sv}", "UUID",
2377                         g_variant_new("s", char_info->char_uuid));
2378         g_variant_builder_add(inner_builder, "{sv}", "Service",
2379                         g_variant_new("o", serv_info->serv_path));
2380
2381         builder2 = g_variant_builder_new(G_VARIANT_TYPE("as"));
2382
2383         for (i = 0; i < flag_count; i++)
2384                 g_variant_builder_add(builder2, "s", char_flags[i]);
2385
2386         flags_val = g_variant_new("as", builder2);
2387         g_variant_builder_add(inner_builder, "{sv}", "Flags",
2388                         flags_val);
2389
2390         builder3 = g_variant_builder_new(G_VARIANT_TYPE("ao"));
2391
2392         g_variant_builder_add(inner_builder, "{sv}", "Descriptors",
2393                         g_variant_new("ao", builder3));
2394
2395         g_variant_builder_add(builder, "{sa{sv}}",
2396                         GATT_CHAR_INTERFACE,
2397                         inner_builder);
2398
2399         ret = g_dbus_connection_emit_signal(g_conn, NULL, "/",
2400                         "org.freedesktop.Dbus.ObjectManager",
2401                         "InterfacesAdded",
2402                         g_variant_new("(oa{sa{sv}})",
2403                                 path, builder),
2404                         &error);
2405         if (!ret) {
2406                 if (error) {
2407                         /* dbus gives error cause */
2408                         ERR("d-bus api failure: errcode[%x], message[%s]",
2409                                         error->code, error->message);
2410                         g_clear_error(&error);
2411                 }
2412         }
2413
2414         //*char_path = g_strdup(path);
2415
2416         //new_char = TRUE;
2417
2418
2419         /* Send Service handle to application */
2420         user_data = g_malloc0(sizeof(hal_gatt_char_added));
2421         user_data->srvc_hdl = serv_info->service_handle;
2422         user_data->char_hdl = gatt_char_handle;
2423         user_data->instance_data = slot;
2424         memcpy(user_data->uuid.uu, uuid->uu, sizeof(uuid->uu));
2425         g_idle_add(__bt_hal_gatt_char_added_cb, (gpointer)user_data);
2426
2427         /* Save newly created charatcristic to GATT Server's service's characteristic  list */
2428         serv_info->char_data = g_slist_append(serv_info->char_data, char_info);
2429
2430         /* Free data */
2431         g_free(path);
2432
2433         g_variant_builder_unref(inner_builder);
2434         g_variant_builder_unref(builder);
2435         g_variant_builder_unref(builder2);
2436         g_variant_builder_unref(builder3);
2437
2438         return BT_STATUS_SUCCESS;
2439 }
2440
2441 static bt_status_t gatt_server_add_descriptor(int slot, int service_handle, bt_uuid_t *uuid,
2442                 int permissions)
2443 {
2444         CHECK_BTGATT_INIT();
2445
2446 //      static int desc_id = 1;
2447         GError *error = NULL;
2448         guint object_id;
2449         GDBusNodeInfo *node_info;
2450         gchar *path = NULL;
2451         GVariantBuilder *builder = NULL;
2452         GVariantBuilder *inner_builder = NULL;
2453
2454         struct gatt_char_info *char_info = NULL;
2455         struct gatt_desc_info *desc_info = NULL;
2456         struct gatt_service_info *serv_info = NULL;
2457
2458         gchar **line_argv = NULL;
2459         char *serv_path;
2460         char *char_path = NULL;
2461         GSList *l;
2462
2463         GVariantBuilder *builder2 = NULL;
2464         GVariant *flags_val = NULL;
2465         int i = 0;
2466         char *desc_flags[NUMBER_OF_FLAGS];
2467         int flag_count = 0;
2468         int *app_id;
2469
2470         hal_gatt_desc_added *user_data = NULL;
2471 #if 0
2472         if (new_char) {
2473                 desc_id = 1;
2474                 new_char = FALSE;
2475         }
2476 #endif
2477         /* Fetch service data for the GATT server */
2478         serv_info = __bt_gatt_find_gatt_service_info(slot, service_handle);
2479         if (serv_info == NULL)
2480                 return BT_STATUS_FAIL;
2481
2482         /* Fetch list of characteristics from the service info */
2483         l = serv_info->char_data;
2484
2485         /* Fetch last char info from the characteristic list */
2486         char_info = g_slist_last(l)->data;
2487         if (char_info == NULL)
2488                 return BT_STATUS_FAIL;
2489
2490         /* Fetch characteristic path from char info */
2491         char_path = char_info->char_path;
2492
2493         line_argv = g_strsplit_set(char_path, "/", 0);
2494         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
2495
2496
2497         node_info = __bt_gatt_create_method_node_info(
2498                         descriptor_introspection_xml);
2499
2500         if (node_info == NULL) {
2501                 g_strfreev(line_argv);
2502                 g_free(serv_path);
2503                 return BT_STATUS_FAIL;
2504         }
2505
2506         DBG("Add new Descriptor: Current GATT desc handle [%d]", gatt_desc_handle);
2507
2508         path = g_strdup_printf("%s/descriptor%d", char_path, ++gatt_desc_handle);
2509         DBG("gatt descriptor path is [%s]", path);
2510
2511         app_id = g_malloc0(sizeof(int));
2512         *app_id = slot;
2513
2514         object_id = g_dbus_connection_register_object(g_conn, path,
2515                         node_info->interfaces[0],
2516                         &desc_interface_vtable,
2517                         (gpointer)app_id, NULL, &error);
2518
2519         if (object_id == 0) {
2520                 ERR("failed to register: %s", error->message);
2521                 g_error_free(error);
2522                 g_free(path);
2523                 g_strfreev(line_argv);
2524                 g_free(serv_path);
2525                 g_free(app_id);
2526                 return BT_STATUS_FAIL;
2527         }
2528
2529         flag_count = bt_hal_gatt_convert_perm2string(permissions, desc_flags);
2530
2531         desc_info = g_new0(struct gatt_desc_info, 1);
2532
2533         desc_info->desc_path = g_strdup(path);
2534         desc_info->desc_id = object_id;
2535         desc_info->desc_uuid = __bt_hal_convert_uuid_to_string(uuid);//g_strdup(btuuid2str(uuid->uu));
2536
2537         for (i = 0; i < flag_count; i++)
2538                 desc_info->desc_flags[i] = desc_flags[i];
2539
2540         desc_info->flags_length = flag_count;
2541         desc_info->desc_handle = gatt_desc_handle;
2542
2543
2544         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
2545         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2546
2547         g_variant_builder_add(inner_builder, "{sv}", "UUID",
2548                         g_variant_new("s", btuuid2str(uuid->uu)));
2549         g_variant_builder_add(inner_builder, "{sv}", "Characteristic",
2550                         g_variant_new("o", char_path));
2551
2552         builder2 = g_variant_builder_new(G_VARIANT_TYPE("as"));
2553
2554         for (i = 0; i < flag_count; i++)
2555                 g_variant_builder_add(builder2, "s", desc_flags[i]);
2556
2557         flags_val = g_variant_new("as", builder2);
2558         g_variant_builder_add(inner_builder, "{sv}", "Flags",
2559                         flags_val);
2560
2561         g_variant_builder_add(builder, "{sa{sv}}",
2562                         GATT_DESC_INTERFACE,
2563                         inner_builder);
2564
2565         g_dbus_connection_emit_signal(g_conn, NULL, "/",
2566                         "org.freedesktop.Dbus.ObjectManager",
2567                         "InterfacesAdded",
2568                         g_variant_new("(oa{sa{sv}})",
2569                                 path, builder),
2570                         &error);
2571         if (error != NULL) {
2572                 ERR("g_dbus_connection_emit_signal failed: errCode[%x], message[%s]",
2573                                 error->code, error->message);
2574                 g_clear_error(&error);
2575         }
2576
2577         //*desc_path = g_strdup(path);
2578
2579         /* Save newly created descriptor to GATT server's service's characteristic */
2580         char_info->desc_data = g_slist_append(char_info->desc_data, desc_info);
2581
2582         /* Send descriptor handle to application */
2583         user_data = g_malloc0(sizeof(hal_gatt_desc_added));
2584         user_data->srvc_hdl = serv_info->service_handle;
2585         user_data->desc_hdl = gatt_desc_handle;
2586         user_data->instance_data = slot;
2587         memcpy(user_data->uuid.uu, uuid->uu, sizeof(uuid->uu));
2588         g_idle_add(__bt_hal_gatt_desc_added_cb, (gpointer)user_data);
2589
2590         /* Free data */
2591         g_free(path);
2592         g_free(serv_path);
2593         g_strfreev(line_argv);
2594         g_variant_builder_unref(inner_builder);
2595         g_variant_builder_unref(builder);
2596         return BT_STATUS_SUCCESS;
2597 }
2598
2599 static void __bt_hal_register_application_cb(GObject *object, GAsyncResult *res, gpointer user_data)
2600 {
2601         GError *error = NULL;
2602         GVariant *result;
2603         char *data = (char*) user_data;
2604         INFO("RegisterApplication is completed path [%s]", data);
2605
2606         result = g_dbus_proxy_call_finish(manager_gproxy, res, &error);
2607
2608         if (result == NULL) {
2609                 /* dBUS-RPC is failed */
2610                 ERR("Dbus-RPC is failed\n");
2611
2612                 if (error != NULL) {
2613                         /* dBUS gives error cause */
2614                         ERR("D-Bus API failure: errCode[%x], message[%s]\n",
2615                                         error->code, error->message);
2616                         g_clear_error(&error);
2617                 }
2618         } else {
2619                 g_variant_unref(result);
2620         }
2621         g_free(data);
2622 }
2623
2624 static GDBusProxy *__bt_hal_gatt_gdbus_init_manager_proxy(const gchar *service,
2625                 const gchar *path, const gchar *interface)
2626 {
2627         GDBusProxy *proxy;
2628         GError *err = NULL;
2629
2630         if (g_conn == NULL)
2631                 g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM,
2632                                 NULL, &err);
2633
2634         if (!g_conn) {
2635                 if (err) {
2636                         ERR("Unable to connect to gdbus: %s", err->message);
2637                         g_clear_error(&err);
2638                 }
2639                 return NULL;
2640         }
2641
2642         proxy =  g_dbus_proxy_new_sync(g_conn,
2643                         G_DBUS_PROXY_FLAGS_NONE, NULL,
2644                         service, path,
2645                         interface, NULL, &err);
2646
2647         if (!proxy) {
2648                 if (err) {
2649                         ERR("Unable to create proxy: %s", err->message);
2650                         g_clear_error(&err);
2651                 }
2652                 return NULL;
2653         }
2654         manager_gproxy = proxy;
2655
2656         return proxy;
2657 }
2658
2659 static GDBusProxy *__bt_gatt_gdbus_get_gatt_manager_proxy(const gchar *service,
2660                 const gchar *path, const gchar *interface)
2661 {
2662         return (manager_gproxy) ? manager_gproxy :
2663                 __bt_hal_gatt_gdbus_init_manager_proxy(service,
2664                                 path, interface);
2665 }
2666
2667 static void __bt_register_application_to_dbus(int slot)
2668 {
2669         GDBusProxy *proxy = NULL;
2670         char *app_path = NULL;
2671         char *data;
2672         DBG("RegisterApplication slot [%d]", slot);
2673
2674         /* It is impossible that app path is still not initialized */
2675         _bt_hal_is_gatt_server_initialzed(slot, &app_path);
2676
2677         proxy = __bt_gatt_gdbus_get_gatt_manager_proxy("org.bluez",
2678                         "/org/bluez/hci0", "org.bluez.GattManager1");
2679
2680         data = g_strdup(app_path);
2681         g_dbus_proxy_call(proxy,
2682                         "RegisterApplication",
2683                         g_variant_new("(oa{sv})",
2684                                 app_path, NULL),
2685                         G_DBUS_CALL_FLAGS_NONE, -1,
2686                         NULL,
2687                         (GAsyncReadyCallback)__bt_hal_register_application_cb,
2688                         (gpointer)data);
2689         INFO("GATT server started");
2690 }
2691
2692 static bt_status_t gatt_server_start_service(int server_if, int service_handle, int transport)
2693 {
2694         CHECK_BTGATT_INIT();
2695         struct gatt_service_info *serv_info = NULL;
2696         hal_gatt_service_started *user_data = NULL;
2697         DBG("Start GATT Service svc hdl [%d], slot [%d]", service_handle, server_if);
2698
2699         /* Fetch service data for the GATT server */
2700         serv_info = __bt_gatt_find_gatt_service_info(server_if, service_handle);
2701         if (serv_info == NULL)
2702                 return BT_STATUS_FAIL;
2703
2704         if (serv_info->is_svc_registered)
2705                 DBG("service already registered \n");
2706
2707         serv_info->is_svc_registered = TRUE;
2708
2709         /* Send Service handle to application */
2710         user_data = g_malloc0(sizeof(hal_gatt_service_started));
2711         user_data->srvc_hdl = serv_info->service_handle;
2712         user_data->instance_data = server_if;
2713         g_idle_add(__bt_hal_gatt_service_started_cb, (gpointer)user_data);
2714
2715         /* If this is nth Service that is started, then register application at this point */
2716         if (__bt_is_service_last_in_server_list(server_if, service_handle)) {
2717                 DBG("This is the last service started from the GATT Server's list of services handle [%d]",
2718                         service_handle);
2719                 __bt_register_application_to_dbus(server_if);
2720         }
2721
2722         return BT_STATUS_SUCCESS;
2723 }
2724
2725 static bt_status_t gatt_server_stop_service(int server_if, int service_handle)
2726 {
2727         CHECK_BTGATT_INIT();
2728         INFO("Stop service successful");
2729         return BT_STATUS_SUCCESS;
2730 }
2731
2732 static bt_status_t gatt_server_delete_service(int server_if, int service_handle)
2733 {
2734         CHECK_BTGATT_INIT();
2735         struct gatt_service_info *serv_info = NULL;
2736         hal_gatt_service_deleted *user_data = NULL;
2737         GSList *l = NULL;
2738         GSList *l1 = NULL;
2739         int err = BT_STATUS_SUCCESS;
2740         int ret = BT_STATUS_SUCCESS;
2741         INFO("Slot [%d] service handle [%d]", server_if, service_handle);
2742
2743         /* Fetch service data for the GATT server */
2744         serv_info = __bt_gatt_find_gatt_service_info(server_if, service_handle);
2745         if (serv_info == NULL) {
2746                 ERR("Could not find service info svc handle [%d] server slot [%d]",
2747                                 service_handle, server_if);
2748                 return BT_STATUS_FAIL;
2749         }
2750
2751         if (serv_info->is_svc_registered == FALSE) {
2752                 ERR("service Not registered path [%s] handle [%d]",
2753                         serv_info->serv_path, service_handle);
2754         }
2755
2756         for (l = serv_info->char_data; l != NULL; l = g_slist_next(l)) {
2757                 struct gatt_char_info *char_info = l->data;
2758
2759                 if (char_info == NULL)
2760                         break;
2761
2762                 for (l1 = char_info->desc_data; l1 != NULL; l1 = g_slist_next(l1)) {
2763                         struct gatt_desc_info *desc_info = l1->data;
2764
2765                         if (desc_info == NULL)
2766                                 break;
2767
2768                         ret = g_dbus_connection_unregister_object(g_conn,
2769                                         desc_info->desc_id);
2770                         if (ret) {
2771                                 __bt_hal_gatt_emit_interface_removed(
2772                                                 desc_info->desc_path,
2773                                                 GATT_DESC_INTERFACE);
2774                         } else {
2775                                 err = BT_STATUS_FAIL;
2776                         }
2777
2778                         /* list remove & free */
2779                         char_info->desc_data = g_slist_remove(char_info->desc_data, desc_info);
2780                         __bt_hal_gatt_free_descriptor_info(desc_info);
2781                 }
2782
2783                 g_slist_free(char_info->desc_data);
2784                 char_info->desc_data = NULL;
2785
2786                 ret = g_dbus_connection_unregister_object(g_conn,
2787                                 char_info->char_id);
2788                 if (ret) {
2789                         __bt_hal_gatt_emit_interface_removed(char_info->char_path,
2790                                         GATT_CHAR_INTERFACE);
2791                 } else {
2792                         INFO("Err");
2793                         err = BT_STATUS_FAIL;
2794                 }
2795
2796                 /* list remove & free */
2797                 serv_info->char_data = g_slist_remove(serv_info->char_data, char_info);
2798                 __bt_hal_gatt_free_characteristic_info(char_info);
2799         }
2800
2801         g_slist_free(serv_info->char_data);
2802         serv_info->char_data = NULL;
2803
2804         ret = g_dbus_connection_unregister_object(g_conn, serv_info->serv_id);
2805         if (ret) {
2806                 __bt_hal_gatt_emit_interface_removed(serv_info->serv_path,
2807                                 GATT_SERV_INTERFACE);
2808         } else {
2809                 INFO("Failed!!");
2810                 err = BT_STATUS_FAIL;
2811         }
2812
2813         ret = g_dbus_connection_unregister_object(g_conn, serv_info->prop_id);
2814         if (ret)
2815                 DBG("Unregistered the service on properties interface");
2816
2817         /* Remove from global list */
2818         gatt_services = g_slist_remove(gatt_services, serv_info);
2819         INFO("After removing from global list total service dount [%d]", g_slist_length(gatt_services));
2820
2821         /* Remove from GATT Server's list of services */
2822         _bt_remote_service_from_gatt_server(server_if, service_handle);
2823
2824         if (gatt_services == NULL)
2825                 INFO("All GATT Services of all GATT Servers are unregistered");
2826
2827         if (err == BT_STATUS_SUCCESS) {
2828                 INFO("Send GATT Service deleted Event");
2829                 /* Send Service handle to application */
2830                 user_data = g_malloc0(sizeof(hal_gatt_service_deleted));
2831                 user_data->srvc_hdl = serv_info->service_handle;
2832                 user_data->instance_data = server_if;
2833                 g_idle_add(__bt_hal_gatt_service_deleted_cb, (gpointer)user_data);
2834         }
2835
2836         /* Free the service */
2837         __bt_hal_gatt_free_service_info(serv_info);
2838         return err;
2839 }
2840
2841 static gboolean __bt_gatt_get_service_state(const char *service_path)
2842 {
2843         struct gatt_service_info *svc_info = NULL;
2844         GSList *l = NULL;
2845         for (l = gatt_services; l; l = g_slist_next(l)) {
2846
2847                 svc_info = (struct gatt_service_info *)l->data;
2848
2849
2850                 if (!g_strcmp0(svc_info->serv_path, service_path)) {
2851                         DBG("Return the state of the gatt service %d",
2852                                         svc_info->is_svc_registered);
2853                         return svc_info->is_svc_registered;
2854                 }
2855         }
2856
2857         DBG("gatt service info is NULL");
2858         return FALSE;
2859 }
2860
2861 static bt_status_t gatt_server_send_indication(int server_if, int attribute_handle, int conn_id,
2862                 int len, int confirm, char* p_value)
2863 {
2864         CHECK_BTGATT_INIT();
2865
2866         /* For Notifying */
2867         GVariantBuilder *outer_builder;
2868         GVariantBuilder *invalidated_builder;
2869
2870         /* For Value update via PropertyChange */
2871         GVariantBuilder *outer_builder1;
2872         GVariantBuilder *inner_builder1;
2873         GVariantBuilder *invalidated_builder1;
2874         GVariant *update_value = NULL;
2875
2876         /* Other variables */
2877         struct gatt_client_info_t *conn_info = NULL;
2878         gchar *serv_path = NULL;
2879         char *char_path = NULL;
2880         gchar **line_argv = NULL;
2881         gboolean notify = TRUE;
2882         gboolean ret = TRUE;
2883         int err = BT_STATUS_SUCCESS;
2884         char addr[20];
2885         GError *error = NULL;
2886         int i;
2887
2888         memset(addr, 0x00, sizeof(addr));
2889
2890         conn_info = __bt_find_remote_gatt_client_info_from_conn(conn_id);
2891         if (conn_info == NULL) {
2892                 ERR("No Connection Inforamtion!!!");
2893                 return BT_STATUS_FAIL;
2894         }
2895
2896         DBG("Send Indication to GATT client addr [%s]", conn_info->addr);
2897
2898         char_path = __bt_gatt_find_char_path_from_handle(attribute_handle);
2899         if (char_path == NULL)
2900                 return BT_STATUS_FAIL;
2901
2902         line_argv = g_strsplit_set(char_path, "/", 0);
2903         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
2904
2905         if (!__bt_gatt_get_service_state(serv_path)) {
2906                 DBG("service not registered for this characteristic \n");
2907                 g_free(serv_path);
2908                 g_strfreev(line_argv);
2909                 return BT_STATUS_FAIL;
2910         }
2911
2912         outer_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2913         invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
2914
2915         g_variant_builder_add(outer_builder, "{sv}", "Notifying",
2916                         g_variant_new("b", notify));
2917
2918         memcpy(addr, conn_info->addr, BT_HAL_ADDRESS_STRING_SIZE);
2919         DBG("Send Indication to Unicast addr [%s]", addr);
2920
2921         g_variant_builder_add(outer_builder, "{sv}", "Unicast",
2922                         g_variant_new("s", addr));
2923
2924         DBG("Set characteristic Notification \n");
2925         ret = g_dbus_connection_emit_signal(g_conn, NULL,
2926                         char_path,
2927                         "org.freedesktop.DBus.Properties",
2928                         "PropertiesChanged",
2929                         g_variant_new("(sa{sv}as)",
2930                                 "org.bluez.GattCharacteristic1",
2931                                 outer_builder, invalidated_builder),
2932                         &error);
2933
2934         if (!ret) {
2935                 if (error != NULL) {
2936                         ERR("D-Bus API failure: errCode[%x], \
2937                                         message[%s]",
2938                                         error->code, error->message);
2939                         g_clear_error(&error);
2940                 }
2941                 err = BT_STATUS_FAIL;
2942         }
2943
2944         g_variant_builder_unref(outer_builder);
2945         g_variant_builder_unref(invalidated_builder);
2946
2947
2948         /* Notifying Done, now update Value to Bluez via PropertyChanged */
2949         invalidated_builder1 = g_variant_builder_new(G_VARIANT_TYPE("as"));
2950
2951         inner_builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
2952         for (i = 0; i < len; i++)
2953                 g_variant_builder_add(inner_builder1, "y", p_value[i]);
2954
2955         update_value = g_variant_new("ay", inner_builder1);
2956
2957
2958         outer_builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
2959         g_variant_builder_add(outer_builder1, "{sv}", "Value",
2960                         update_value);
2961
2962         DBG("Updating characteristic value \n");
2963         ret = g_dbus_connection_emit_signal(g_conn, NULL,
2964                         char_path,
2965                         "org.freedesktop.DBus.Properties",
2966                         "PropertiesChanged",
2967                         g_variant_new("(sa{sv}as)",
2968                                 "org.bluez.GattCharacteristic1",
2969                                 outer_builder1, invalidated_builder1),
2970                         &error);
2971
2972         if (!ret) {
2973                 if (error != NULL) {
2974                         ERR("D-Bus API failure: errCode[%x], \
2975                                         message[%s]",
2976                                         error->code, error->message);
2977                         g_clear_error(&error);
2978                 }
2979                 err = BT_STATUS_FAIL;
2980         } else {
2981                 struct gatt_char_info *char_info = NULL;
2982
2983                 char_info = __bt_gatt_find_char_info_from_handle(attribute_handle);
2984                 if (char_info == NULL) {
2985                         g_free(serv_path);
2986                         g_strfreev(line_argv);
2987                         g_variant_builder_unref(inner_builder1);
2988                         g_variant_builder_unref(outer_builder1);
2989                         g_variant_builder_unref(invalidated_builder1);
2990
2991                         return BT_STATUS_FAIL;
2992                 }
2993
2994                 char_info->value_length = len;
2995
2996                 char_info->char_value = (char *)realloc(char_info->char_value, len);
2997                 if (char_info->char_value) {
2998                         for (i = 0; i < len; i++)
2999                                 char_info->char_value[i] = p_value[i];
3000                 }
3001         }
3002
3003         g_free(serv_path);
3004         g_strfreev(line_argv);
3005         g_variant_builder_unref(inner_builder1);
3006         g_variant_builder_unref(outer_builder1);
3007         g_variant_builder_unref(invalidated_builder1);
3008
3009         return err;
3010 }
3011
3012 static bt_status_t gatt_server_send_response(int conn_id, int trans_id,
3013                 int status, btgatt_response_t *response)
3014 {
3015         CHECK_BTGATT_INIT();
3016
3017         struct gatt_req_info *req_info = NULL;
3018         struct gatt_client_info_t *conn_info = NULL;
3019         int i;
3020
3021         DBG("GATT Server Send Response Conn ID [%d]", conn_id);
3022
3023         conn_info = __bt_find_remote_gatt_client_info_from_conn(conn_id);
3024         if (conn_info == NULL) {
3025                 ERR("No Connection Inforamtion!!!");
3026                 return BT_STATUS_FAIL;
3027         }
3028
3029         req_info =  __bt_find_remote_gatt_client_request_info(conn_id, trans_id);
3030         if (req_info == NULL) {
3031                 ERR("No Request Inforamtion!!!");
3032                 return BT_STATUS_FAIL;
3033         }
3034
3035         if (status != BT_STATUS_SUCCESS) {
3036                 ERR("resp_state is 0x%X", status);
3037
3038                 g_dbus_method_invocation_return_dbus_error(req_info->context,
3039                                 "org.bluez.Error.Failed", "Application Error");
3040
3041                 conn_info->gatt_req_info_list = g_slist_remove(conn_info->gatt_req_info_list, req_info);
3042
3043                 req_info->context = NULL;
3044                 if (req_info->attr_path)
3045                         g_free(req_info->attr_path);
3046                 if (req_info->svc_path)
3047                         g_free(req_info->svc_path);
3048                 g_free(req_info);
3049
3050                 return BT_STATUS_SUCCESS;
3051         }
3052
3053         DBG("Reponse Value length [%d]", response->attr_value.len);
3054         DBG("Request type: [%d]", req_info->request_type);
3055
3056         /* DEBUG */
3057         for (i = 0; i < response->attr_value.len; i++)
3058                 DBG("Resonse [%d] = [0x%x]", i, response->attr_value.value[i]);
3059
3060         if (req_info->request_type == BT_HAL_GATT_REQUEST_TYPE_READ) {
3061                 GVariantBuilder *inner_builder = NULL;
3062                 inner_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
3063
3064                 if (response->attr_value.len > 0) {
3065                         for (i = 0; i < response->attr_value.len; i++)
3066                                 g_variant_builder_add(inner_builder, "y", response->attr_value.value[i]);
3067                 }
3068                 g_dbus_method_invocation_return_value(req_info->context,
3069                                 g_variant_new("(ay)", inner_builder));
3070
3071                 g_variant_builder_unref(inner_builder);
3072         } else {
3073                 g_dbus_method_invocation_return_value(req_info->context, NULL);
3074         }
3075         conn_info->gatt_req_info_list = g_slist_remove(conn_info->gatt_req_info_list, req_info);
3076
3077         req_info->context = NULL;
3078         if (req_info->attr_path)
3079                 g_free(req_info->attr_path);
3080         if (req_info->svc_path)
3081                 g_free(req_info->svc_path);
3082         g_free(req_info);
3083
3084         return BT_STATUS_SUCCESS;
3085 }
3086
3087
3088 static bt_status_t gatt_server_send_acquire_response(int conn_id, int trans_id,
3089                 int status, int fd, int mtu, void *fdlist)
3090 {
3091         CHECK_BTGATT_INIT();
3092
3093         struct gatt_req_info *req_info = NULL;
3094         struct gatt_client_info_t *conn_info = NULL;
3095
3096         DBG("GATT Server Send Response Conn ID [%d]", conn_id);
3097
3098         conn_info = __bt_find_remote_gatt_client_info_from_conn(conn_id);
3099         if (conn_info == NULL) {
3100                 ERR("No Connection Inforamtion!!!");
3101                 return BT_STATUS_FAIL;
3102         }
3103
3104         req_info =  __bt_find_remote_gatt_client_request_info(conn_id, trans_id);
3105         if (req_info == NULL) {
3106                 ERR("No Request Inforamtion!!!");
3107                 return BT_STATUS_FAIL;
3108         }
3109
3110         if (status != BT_STATUS_SUCCESS) {
3111                 ERR("resp_state is 0x%X", status);
3112
3113                 g_dbus_method_invocation_return_dbus_error(req_info->context,
3114                                 "org.bluez.Error.Failed", "Application Error");
3115
3116                 conn_info->gatt_req_info_list = g_slist_remove(conn_info->gatt_req_info_list, req_info);
3117
3118                 req_info->context = NULL;
3119                 if (req_info->attr_path)
3120                         g_free(req_info->attr_path);
3121                 if (req_info->svc_path)
3122                         g_free(req_info->svc_path);
3123                 g_free(req_info);
3124
3125                 return BT_STATUS_SUCCESS;
3126         }
3127
3128
3129          if (req_info->request_type == BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_WRITE) {
3130
3131                 INFO("GATT Server Send Response BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_WRITE to bluez  %d\n", fd);
3132                 g_dbus_method_invocation_return_value_with_unix_fd_list(
3133                                 req_info->context, g_variant_new("(hq)", 0, mtu), (GUnixFDList*)fdlist);
3134
3135         } else if (req_info->request_type == BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY) {
3136
3137                 INFO("GATT Server Send Response BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY  to bluez  %d\n", fd);
3138                 g_dbus_method_invocation_return_value_with_unix_fd_list(
3139                                 req_info->context, g_variant_new("(hq)", 0, mtu), (GUnixFDList*)fdlist);
3140
3141         } else {
3142                 g_dbus_method_invocation_return_value(req_info->context, NULL);
3143         }
3144         conn_info->gatt_req_info_list = g_slist_remove(conn_info->gatt_req_info_list, req_info);
3145
3146         req_info->context = NULL;
3147         if (req_info->attr_path)
3148                 g_free(req_info->attr_path);
3149         if (req_info->svc_path)
3150                 g_free(req_info->svc_path);
3151         g_free(req_info);
3152
3153         return BT_STATUS_SUCCESS;
3154 }
3155
3156
3157 static bt_status_t gatt_server_update_att_value(int server_if, int attribute_handle,
3158                 int value_length, char* att_value)
3159 {
3160         CHECK_BTGATT_INIT();
3161
3162         /* Other variables */
3163         char *char_path = NULL;
3164         gboolean ret = TRUE;
3165         GError *error = NULL;
3166
3167         GVariantBuilder *outer_builder;
3168         GVariantBuilder *inner_builder;
3169         GVariantBuilder *invalidated_builder;
3170         GVariant *update_value = NULL;
3171         int err = BT_STATUS_SUCCESS;
3172         int i = 0;
3173         gchar **line_argv = NULL;
3174         gchar *serv_path = NULL;
3175
3176         char_path = __bt_gatt_find_char_path_from_handle(attribute_handle);
3177         if (char_path == NULL)
3178                 return BT_STATUS_FAIL;
3179
3180         line_argv = g_strsplit_set(char_path, "/", 0);
3181         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
3182
3183         if (!__bt_gatt_get_service_state(serv_path)) {
3184                 DBG("service not registered for this characteristic \n");
3185                 g_free(serv_path);
3186                 g_strfreev(line_argv);
3187                 return BT_STATUS_FAIL;
3188         }
3189
3190         g_free(serv_path);
3191         line_argv = g_strsplit_set(char_path, "/", 0);
3192         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
3193
3194         if (!__bt_gatt_get_service_state(serv_path)) {
3195                 DBG("service not registered for this characteristic \n");
3196                 g_free(serv_path);
3197                 g_strfreev(line_argv);
3198                 return BT_STATUS_FAIL;
3199         }
3200
3201         outer_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
3202         invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
3203
3204         inner_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
3205         for (i = 0; i < value_length; i++)
3206                 g_variant_builder_add(inner_builder, "y", att_value[i]);
3207
3208         update_value = g_variant_new("ay", inner_builder);
3209
3210         g_variant_builder_add(outer_builder, "{sv}", "Value",
3211                         update_value);
3212
3213         DBG("Updating characteristic value \n");
3214         ret = g_dbus_connection_emit_signal(g_conn, NULL,
3215                         char_path,
3216                         "org.freedesktop.DBus.Properties",
3217                         "PropertiesChanged",
3218                         g_variant_new("(sa{sv}as)",
3219                                 "org.bluez.GattCharacteristic1",
3220                                 outer_builder, invalidated_builder),
3221                         &error);
3222
3223         if (!ret) {
3224                 if (error != NULL) {
3225                         ERR("D-Bus API failure: errCode[%x], \
3226                                         message[%s]",
3227                                         error->code, error->message);
3228                         g_clear_error(&error);
3229                 }
3230                 err = BT_STATUS_FAIL;
3231         } else {
3232                 struct gatt_char_info *char_info = NULL;
3233
3234                 char_info = __bt_gatt_find_char_info_from_handle(attribute_handle);
3235                 if (char_info == NULL) {
3236                         g_free(serv_path);
3237                         g_strfreev(line_argv);
3238                         g_variant_builder_unref(inner_builder);
3239                         g_variant_builder_unref(outer_builder);
3240                         g_variant_builder_unref(invalidated_builder);
3241
3242                         return BT_STATUS_FAIL;
3243                 }
3244
3245                 char_info->value_length = value_length;
3246
3247                 char_info->char_value = (char *)realloc(char_info->char_value, value_length);
3248                 if (char_info->char_value) {
3249                         for (i = 0; i < value_length; i++)
3250                                 char_info->char_value[i] = att_value[i];
3251                 }
3252         }
3253
3254         /* Free data */
3255         g_free(serv_path);
3256         g_strfreev(line_argv);
3257         g_variant_builder_unref(inner_builder);
3258         g_variant_builder_unref(outer_builder);
3259         g_variant_builder_unref(invalidated_builder);
3260
3261         return err;
3262 }
3263
3264 static bt_status_t gatt_server_listen(int server_if, bool start)
3265 {
3266         CHECK_BTGATT_INIT();
3267         /* Send Data to LE Module */
3268         return _bt_hal_enable_advertising(server_if, start, FALSE);
3269 }
3270
3271 static bt_status_t gatt_server_set_adv_data(int server_if, bool set_scan_rsp, bool include_name,
3272                 bool include_txpower, int min_interval, int max_interval, int appearance,
3273                 uint16_t manufacturer_len, char* manufacturer_data,
3274                 uint16_t service_data_len, char* service_data,
3275                 uint16_t service_uuid_len, char* service_uuid)
3276 {
3277         CHECK_BTGATT_INIT();
3278         return BT_STATUS_SUCCESS;
3279 }
3280
3281 static bt_status_t gatt_server_multi_adv_enable(int server_if)
3282 {
3283         CHECK_BTGATT_INIT();
3284         /* Send Enable Advertising request to LE Module */
3285         return _bt_hal_enable_advertising(server_if, TRUE, TRUE);
3286 }
3287
3288 static bt_status_t gatt_server_multi_adv_update(int server_if, int min_interval, int max_interval, int adv_type,
3289                 int chnl_map, int tx_power, int timeout_s)
3290 {
3291         CHECK_BTGATT_INIT();
3292         DBG("+");
3293         /* Send Advertising parameters to LE Module */
3294         return _bt_hal_set_advertising_params(server_if, min_interval, max_interval, adv_type,
3295                         chnl_map, tx_power, timeout_s);
3296 }
3297
3298 static bt_status_t gatt_server_multi_adv_set_inst_data(btgatt_adv_param_setup_t adv_param_setup)
3299 {
3300         CHECK_BTGATT_INIT();
3301         DBG("+");
3302         /* Send Data to LE Module */
3303         return _bt_hal_set_advertising_data(adv_param_setup);
3304 }
3305
3306 static bt_status_t gatt_server_multi_adv_disable(int server_if)
3307 {
3308         CHECK_BTGATT_INIT();
3309         /* Send Data to LE Module */
3310         return _bt_hal_enable_advertising(server_if, FALSE, TRUE);
3311 }
3312
3313 static bt_status_t gatt_server_get_mtu_size(int conn_id, int *mtu_size)
3314 {
3315         CHECK_BTGATT_INIT();
3316         char *object_path = NULL;
3317
3318         GDBusProxy *device_proxy;
3319         GError *error = NULL;
3320         GVariant *value;
3321         GVariant *tmp_value;
3322         GDBusConnection *conn;
3323         GVariant *result = NULL;
3324         int ret = BT_STATUS_SUCCESS;
3325         struct gatt_client_info_t *conn_info = NULL;
3326         unsigned int mtu;
3327
3328         if (mtu_size == NULL)
3329                 return BT_STATUS_PARM_INVALID;
3330
3331         /* GDBUS Connection Info validate */
3332         conn = _bt_hal_get_system_gconn();
3333         if (conn == NULL) {
3334                 ERR("Could not get System DBUS Connection");
3335                 return  BT_STATUS_FAIL;
3336         }
3337
3338         /* Connection Info validate */
3339         conn_info = __bt_find_remote_gatt_client_info_from_conn(conn_id);
3340         if (conn_info == NULL) {
3341                 ERR("No Connection Inforamtion!!!");
3342                 return BT_STATUS_FAIL;
3343         }
3344
3345
3346         object_path = _bt_hal_get_device_object_path(conn_info->addr);
3347         if (object_path == NULL)
3348                 return BT_STATUS_FAIL;
3349
3350         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
3351                         NULL, BT_HAL_BLUEZ_NAME, object_path,
3352                         BT_HAL_PROPERTIES_INTERFACE,  NULL, NULL);
3353
3354         g_free(object_path);
3355         if (device_proxy == NULL)
3356                 return BT_STATUS_FAIL;
3357
3358         result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
3359                         g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
3360                         G_DBUS_CALL_FLAGS_NONE,
3361                         -1,
3362                         NULL,
3363                         &error);
3364         if (result == NULL) {
3365                 if (error != NULL) {
3366                         ERR("Error occured in Proxy call [%s]\n", error->message);
3367                         g_error_free(error);
3368                 }
3369                 g_object_unref(device_proxy);
3370                 return BT_STATUS_FAIL;
3371         }
3372
3373         g_variant_get(result , "(@a{sv})", &value);
3374         g_variant_unref(result);
3375
3376         tmp_value = g_variant_lookup_value(value, "AttMtu", G_VARIANT_TYPE_UINT16);
3377         if (tmp_value == NULL) {
3378                 g_object_unref(device_proxy);
3379                 g_variant_unref(value);
3380                 return BT_STATUS_FAIL;
3381         }
3382
3383         mtu = g_variant_get_uint16(tmp_value);
3384
3385         DBG("ATT MTU : [%d]", mtu);
3386
3387         g_variant_unref(tmp_value);
3388         g_variant_unref(value);
3389         g_object_unref(device_proxy);
3390
3391         *mtu_size = (int) mtu;
3392
3393         return ret;
3394 }
3395
3396 const btgatt_server_interface_t btgatt_server_interface = {
3397         .register_server = gatt_server_register_app,
3398         .unregister_server = gatt_server_unregister_app,
3399         .connect = gatt_server_open,
3400         .disconnect = gatt_server_close,
3401         .add_service = gatt_server_add_service,
3402         .add_included_service = gatt_server_add_included_service,
3403         .add_characteristic = gatt_server_add_characteristic,
3404         .add_descriptor = gatt_server_add_descriptor,
3405         .start_service = gatt_server_start_service,
3406         .stop_service = gatt_server_stop_service,
3407         .delete_service = gatt_server_delete_service,
3408         .send_indication = gatt_server_send_indication,
3409         .send_response = gatt_server_send_response,
3410         .update_att_value = gatt_server_update_att_value,
3411         .listen = gatt_server_listen,
3412         .set_adv_data = gatt_server_set_adv_data,
3413         .multi_adv_enable = gatt_server_multi_adv_enable,
3414         .multi_adv_update = gatt_server_multi_adv_update,
3415         .multi_adv_set_inst_data = gatt_server_multi_adv_set_inst_data,
3416         .multi_adv_disable = gatt_server_multi_adv_disable,
3417         .get_att_mtu = gatt_server_get_mtu_size,
3418         .send_response_acquire = gatt_server_send_acquire_response
3419 };