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