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