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