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