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