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