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