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