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