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