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