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