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