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