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