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