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