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