Correct the privilege check for BT_UPDATE_LE_CONNECTION_MODE
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-gatt-service.c
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include<gio/gio.h>
19 #include<glib.h>
20 #include<glib/gprintf.h>
21 #include<stdlib.h>
22 #include<unistd.h>
23 #include<stdint.h>
24 #include<stdbool.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <gio/gunixfdlist.h>
28
29 #include "bt-common.h"
30 /* TODO_40 : 4.0 merge - Need to check why includes bt-event-handler.h */
31 #include "bt-event-handler.h"
32 #include "bt-internal-types.h"
33
34
35 #include "bluetooth-gatt-server-api.h"
36 #include "bt-request-sender.h"
37 #define BT_GATT_ATT_UUID_LEN_MAX 50
38 #define BT_GATT_SERVER_DBUS_NAME_LEN_MAX 50
39
40 static GSList *gatt_characteristic_server_notify_list = NULL;;
41
42 /* Common defintions to follow , applicable for both
43    GATT_DIRECT and RELAY */
44
45
46 #define NUMBER_OF_FLAGS 10
47
48
49 int bluetooth_gatt_convert_prop2string(
50                         bt_gatt_characteristic_property_t properties,
51                         char *char_properties[])
52 {
53         int flag_count = 0;
54
55         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST) {
56                 char_properties[flag_count] = g_strdup("broadcast");
57                 flag_count++;
58         }
59         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ) {
60                 char_properties[flag_count] = g_strdup("read");
61                 flag_count++;
62         }
63         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) {
64                 char_properties[flag_count] = g_strdup("write-without-response");
65                 flag_count++;
66         }
67         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE) {
68                 char_properties[flag_count] = g_strdup("write");
69                 flag_count++;
70         }
71         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) {
72                 char_properties[flag_count] = g_strdup("notify");
73                 flag_count++;
74         }
75         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE) {
76                 char_properties[flag_count] = g_strdup("indicate");
77                 flag_count++;
78         }
79         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE) {
80                 char_properties[flag_count] = g_strdup("authenticated-signed-writes");
81                 flag_count++;
82         }
83         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE) {
84                 char_properties[flag_count] = g_strdup("reliable-write");
85                 flag_count++;
86         }
87         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES) {
88                 char_properties[flag_count] = g_strdup("writable-auxiliaries");
89                 flag_count++;
90         }
91         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ) {
92                 char_properties[flag_count] = g_strdup("encrypt-read");
93                 flag_count++;
94         }
95         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE) {
96                 char_properties[flag_count] = g_strdup("encrypt-write");
97                 flag_count++;
98         }
99         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ) {
100                 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
101                 flag_count++;
102         }
103         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE) {
104                 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
105                 flag_count++;
106         }
107
108         if (flag_count == 0) {
109                 char_properties[flag_count] = g_strdup("read");
110                 flag_count++;
111         }
112
113         return flag_count;
114 }
115
116 int bluetooth_gatt_convert_perm2string(
117                         bt_gatt_permission_t properties,
118                         char *char_properties[])
119 {
120         int flag_count = 0;
121
122         if (properties & BLUETOOTH_GATT_PERMISSION_READ) {
123                 char_properties[flag_count] = g_strdup("read");
124                 flag_count++;
125         }
126         if (properties & BLUETOOTH_GATT_PERMISSION_WRITE) {
127                 char_properties[flag_count] = g_strdup("write");
128                 flag_count++;
129         }
130         if (properties & BLUETOOTH_GATT_PERMISSION_ENCRYPT_READ) {
131                 char_properties[flag_count] = g_strdup("encrypt-read");
132                 flag_count++;
133         }
134         if (properties & BLUETOOTH_GATT_PERMISSION_ENCRYPT_WRITE) {
135                 char_properties[flag_count] = g_strdup("encrypt-write");
136                 flag_count++;
137         }
138         if (properties & BLUETOOTH_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ) {
139                 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
140                 flag_count++;
141         }
142         if (properties & BLUETOOTH_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE) {
143                 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
144                 flag_count++;
145         }
146
147         if (flag_count == 0) {
148                 char_properties[flag_count] = g_strdup("read");
149                 flag_count++;
150         }
151
152         return flag_count;
153 }
154
155
156 #define NUMBER_OF_FLAGS 10
157
158 static GDBusConnection *g_conn;
159 static guint owner_id;
160 static guint manager_id;
161 static gboolean new_service = FALSE;
162 static gboolean new_char = FALSE;
163 static int serv_id = 1;
164 static bool is_server_started = false;
165
166 static GCancellable *register_cancel;
167
168 /* Introspection data for the service we are exporting */
169 static const gchar service_introspection_xml[] =
170 "<node name='/'>"
171 "  <interface name='org.freedesktop.DBus.Properties'>"
172 "    <property type='s' name='UUID' access='read'>"
173 "    </property>"
174 "        <property type='b' name='primary' access='read'>"
175 "        </property>"
176 "        <property type='o' name='Device' access='read'>"
177 "        </property>"
178 "        <property type='ao' name='Characteristics' access='read'>"
179 "        </property>"
180 "        <property type='s' name='Includes' access='read'>"
181 "        </property>"
182 "  </interface>"
183 "</node>";
184
185 /* Introspection data for the characteristics we are exporting */
186 static const gchar characteristics_introspection_xml[] =
187 "<node name='/'>"
188 "  <interface name='org.bluez.GattCharacteristic1'>"
189 "        <method name='ReadValue'>"
190 "               <arg type='s' name='address' direction='in'/>"
191 "               <arg type='u' name='id' direction='in'/>"
192 "               <arg type='q' name='offset' direction='in'/>"
193 "               <arg type='ay' name='Value' direction='out'/>"
194 "        </method>"
195 "        <method name='WriteValue'>"
196 "               <arg type='s' name='address' direction='in'/>"
197 "               <arg type='u' name='id' direction='in'/>"
198 "               <arg type='q' name='offset' direction='in'/>"
199 "               <arg type='b' name='response_needed' direction='in'/>"
200 "               <arg type='ay' name='value' direction='in'/>"
201 "        </method>"
202 "        <method name='StartNotify'>"
203 "        </method>"
204 "        <method name='StopNotify'>"
205 "        </method>"
206 "        <method name='IndicateConfirm'>"
207 "               <arg type='s' name='address' direction='in'/>"
208 "               <arg type='b' name='complete' direction='in'/>"
209 "        </method>"
210 "  </interface>"
211 "  <interface name='org.freedesktop.DBus.Properties'>"
212 "    <property type='s' name='UUID' access='read'>"
213 "    </property>"
214 "    <property type='o' name='Service' access='read'>"
215 "    </property>"
216 "    <property type='ay' name='Value' access='readwrite'>"
217 "    </property>"
218 "        <property type='b' name='Notifying' access='read'>"
219 "        </property>"
220 "    <property type='as' name='Flags' access='read'>"
221 "    </property>"
222 "    <property type='s' name='Unicast' access='read'>"
223 "    </property>"
224 "        <property type='ao' name='Descriptors' access='read'>"
225 "        </property>"
226 "  </interface>"
227 "</node>";
228
229 /* Introspection data for the descriptor we are exporting */
230 static const gchar descriptor_introspection_xml[] =
231 "<node name='/'>"
232 "  <interface name='org.bluez.GattDescriptor1'>"
233 "        <method name='ReadValue'>"
234 "               <arg type='s' name='address' direction='in'/>"
235 "               <arg type='u' name='id' direction='in'/>"
236 "               <arg type='q' name='offset' direction='in'/>"
237 "               <arg type='ay' name='Value' direction='out'/>"
238 "        </method>"
239 "        <method name='WriteValue'>"
240 "               <arg type='s' name='address' direction='in'/>"
241 "               <arg type='u' name='id' direction='in'/>"
242 "               <arg type='q' name='offset' direction='in'/>"
243 "               <arg type='b' name='response_needed' direction='in'/>"
244 "               <arg type='ay' name='value' direction='in'/>"
245 "        </method>"
246 "  </interface>"
247 "  <interface name='org.freedesktop.DBus.Properties'>"
248 "    <property type='s' name='UUID' access='read'>"
249 "    </property>"
250 "    <property type='o' name='Characteristic' access='read'>"
251 "    </property>"
252 "    <property type='ay' name='Value' access='read'>"
253 "    </property>"
254 "    <property type='as' name='Flags' access='read'>"
255 "    </property>"
256 "  </interface>"
257 "</node>";
258
259 static const gchar manager_introspection_xml[] =
260 "<node name='/'>"
261 "  <interface name='org.freedesktop.DBus.ObjectManager'>"
262 "    <method name='GetManagedObjects'>"
263 "     <arg type='a{oa{sa{sv}}}' name='object_paths_interfaces_and_properties' direction='out'/>"
264 "        </method>"
265 "  </interface>"
266 "</node>";
267
268 struct gatt_service_info {
269         gchar *serv_path;
270         guint serv_id;
271         gchar *service_uuid;
272         guint manager_id;
273         GSList *char_data;
274         gboolean is_svc_registered;
275         gboolean is_svc_primary;
276 };
277
278 struct gatt_char_info {
279         gchar *char_path;
280         guint char_id;
281         gchar *char_uuid;
282         gchar *char_value;
283         gchar *char_flags[NUMBER_OF_FLAGS];
284         int value_length;
285         int flags_length;
286         GSList *desc_data;
287 };
288
289 struct gatt_desc_info {
290         gchar *desc_path;
291         guint desc_id;
292         gchar *desc_uuid;
293         gchar *desc_value;
294         gchar *desc_flags[NUMBER_OF_FLAGS];
295         int value_length;
296         int flags_length;
297 };
298
299 struct gatt_req_info {
300         gchar *attr_path;
301         gchar *svc_path;
302         guint  request_id;
303         guint  offset;
304         GDBusMethodInvocation *context;
305 };
306
307 static GSList *gatt_services = NULL;
308 static GSList *gatt_requests = NULL;
309 static gchar *app_path = NULL;
310
311 #define BT_GATT_SERVICE_NAME    "org.frwk.gatt_service"
312 #define BT_GATT_SERVICE_PATH "/org/frwk/gatt_service"
313
314 #define GATT_SERV_OBJECT_PATH   "/service"
315
316 #define GATT_MNGR_INTERFACE             "org.bluez.GattManager1"
317 #define GATT_SERV_INTERFACE             "org.bluez.GattService1"
318 #define GATT_CHAR_INTERFACE             "org.bluez.GattCharacteristic1"
319 #define GATT_DESC_INTERFACE             "org.bluez.GattDescriptor1"
320
321 #ifdef TIZEN_FEATURE_BT_HPS
322 #define BT_HPS_OBJECT_PATH "/org/projectx/httpproxy"
323 #define BT_HPS_INTERFACE_NAME "org.projectx.httpproxy_service"
324 #define PROPERTIES_CHANGED "PropertiesChanged"
325 #define BT_HPS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
326 #endif
327
328 #ifdef TIZEN_FEATURE_BT_OTP
329 #define BT_OTP_OBJECT_PATH              "/org/projectx/otp"
330 #define BT_OTP_INTERFACE_NAME           "org.projectx.otp_service"
331 #define PROPERTIES_CHANGED              "PropertiesChanged"
332 #define BT_OTP_PROPERTIES_INTERFACE     "org.freedesktop.DBus.Properties"
333 #endif
334
335 static GDBusProxy *manager_gproxy = NULL;
336
337 static struct gatt_char_info *__bt_gatt_find_gatt_char_info(
338                         const char *service_path, const char *char_path);
339 static struct gatt_desc_info *__bt_gatt_find_gatt_desc_info(
340                         const char *serv_path, const char *char_path,
341                         const char *desc_path);
342
343 static struct gatt_req_info *__bt_gatt_find_request_info(guint request_id);
344 static int __bt_gatt_unregister_service(struct gatt_service_info *svc_info);
345
346 static int bluetooth_get_characteristic_fd(int att_handle , char *address)
347 {
348         GSList *l;
349         int ret = -1;
350
351         BT_DBG("Find FD for address [%s] att_handle [ %d]", address, att_handle);
352
353         /* Check for NULL address */
354         if (g_strcmp0(address, "00:00:00:00:00:00") != 0) {
355                 BT_INFO("Unicast address: Use DBUS send indication");
356                 return ret;
357         }
358
359         for (l = gatt_characteristic_server_notify_list; l != NULL; l = l->next) {
360                 bluetooth_gatt_acquire_notify_info_t *info = l->data;
361
362                 if (info->att_hand == att_handle) {
363                         BT_INFO("ATT handle Matched: AquireNotify Set: Remote addr[%s]", info->address);
364                         return info->write_fd;
365                 }
366         }
367         return ret;
368 }
369
370 static bluetooth_gatt_acquire_notify_info_t * bluetooth_get_characteristic_info_from_path(int att_handle)
371 {
372         GSList *l;
373
374         BT_DBG("request found  att_handle [ %d]", att_handle);
375         for (l = gatt_characteristic_server_notify_list; l != NULL; l = l->next) {
376                 bluetooth_gatt_acquire_notify_info_t *info = l->data;
377                 BT_DBG(" sid [ %d]" , info->att_hand);
378                 if (info->att_hand == att_handle)
379                         return info;
380         }
381         return NULL;
382 }
383
384
385 static void bluetooth_characteristic_info_free(bluetooth_gatt_acquire_notify_info_t *chr_info)
386 {
387                 g_free(chr_info);
388 }
389
390 static gboolean bluetooth_gatt_write_channel_watch_cb(GIOChannel *gio,
391                                         GIOCondition cond, gpointer data)
392 {
393         BT_INFO("+");
394
395         bluetooth_gatt_acquire_notify_info_t *chr_info = (bluetooth_gatt_acquire_notify_info_t *)data;
396
397         if (!chr_info) {
398                 BT_INFO("chr_info is NULL");
399                 return FALSE;
400         }
401
402         if (cond & G_IO_NVAL) {
403                 BT_ERR("Invalid channel");
404                 return FALSE;
405         }
406
407         if (cond & (G_IO_HUP | G_IO_ERR)) {
408                 BT_ERR("Error : GIOCondition %d", cond);
409                 g_io_channel_shutdown(gio, TRUE, NULL);
410                 g_io_channel_unref(gio);
411
412                 if (g_slist_find(gatt_characteristic_server_notify_list, chr_info)) {
413                         BT_INFO("found char_info in the list");
414                         gatt_characteristic_server_notify_list = g_slist_remove(gatt_characteristic_server_notify_list, chr_info);
415                         bluetooth_characteristic_info_free(chr_info);
416                 }
417
418                 return FALSE;
419         }
420
421         if (g_slist_find(gatt_characteristic_server_notify_list, chr_info) == NULL) {
422                 BT_INFO("chr_info is not in the list");
423                 return FALSE;
424         }
425
426         return TRUE;
427 }
428
429 static int bluetooth_gatt_write_characteristics_value_to_fd_(
430                          int fd, const guint8 *value, int length,
431                         gpointer user_data)
432 {
433
434                 int written;
435                 int att_result = BLUETOOTH_ERROR_NONE;
436
437                 BT_CHECK_PARAMETER(value, return);
438
439                 written = write(fd, value, length);
440                 if (written != length) {
441                         att_result = BLUETOOTH_ERROR_INTERNAL;
442                         BT_ERR("write data failed  %d is ", written);
443                 }
444
445                 return att_result;
446 }
447
448 #ifdef TIZEN_FEATURE_BT_HPS
449 static int __bt_send_event_to_hps(int event, GVariant *var)
450 {
451         GError *error = NULL;
452         GVariant *parameters;
453         GDBusMessage *msg = NULL;
454
455         BT_DBG(" ");
456
457         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
458
459         if (event == BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED) {
460                 GVariantBuilder *inner_builder;
461                 GVariantBuilder *invalidated_builder;
462
463                 BT_DBG("BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED");
464                 inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
465
466                 g_variant_builder_add(inner_builder, "{sv}", "WriteValue", var);
467
468                 invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
469
470                 parameters = g_variant_new("(a{sv}as)", inner_builder, invalidated_builder);
471                 g_variant_builder_unref(invalidated_builder);
472                 g_variant_builder_unref(inner_builder);
473         } else if (event == BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED) {
474                 GVariantBuilder *inner_builder;
475                 GVariantBuilder *invalidated_builder;
476
477                 BT_DBG("BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED");
478                 inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
479
480                 g_variant_builder_add(inner_builder, "{sv}", "ReadValue", var);
481
482                 invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
483
484                 parameters = g_variant_new("(a{sv}as)", inner_builder, invalidated_builder);
485                 g_variant_builder_unref(invalidated_builder);
486                 g_variant_builder_unref(inner_builder);
487         } else {
488                 g_varaiant_unref(var);
489         }
490
491         msg = g_dbus_message_new_signal(BT_HPS_OBJECT_PATH, BT_HPS_INTERFACE_NAME, PROPERTIES_CHANGED);
492         g_dbus_message_set_body(msg, parameters);
493         if (!g_dbus_connection_send_message(g_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 0, NULL)) {
494                 if (error != NULL) {
495                         BT_ERR("D-Bus API failure: errCode[%x], \
496                                         message[%s]",
497                                         error->code, error->message);
498                         g_clear_error(&error);
499                 }
500                 return BLUETOOTH_ERROR_INTERNAL;
501         }
502         return BLUETOOTH_ERROR_NONE;
503 }
504 #endif
505
506 #ifdef TIZEN_FEATURE_BT_OTP
507 static int __bt_send_event_to_otp(int event, GVariant *var)
508 {
509         GError *error = NULL;
510         GVariant *parameters = NULL;
511         GDBusMessage *msg = NULL;
512
513         BT_DBG(" ");
514
515         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
516
517         if (event == BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED) {
518                 GVariantBuilder *inner_builder;
519                 GVariantBuilder *invalidated_builder;
520
521                 BT_DBG("BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED");
522                 inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
523
524                 g_variant_builder_add(inner_builder, "{sv}", "WriteValue", var);
525
526                 invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
527
528                 parameters = g_variant_new("(a{sv}as)", inner_builder, invalidated_builder);
529                 g_variant_builder_unref(invalidated_builder);
530                 g_variant_builder_unref(inner_builder);
531         } else if (event == BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED) {
532                 GVariantBuilder *inner_builder;
533                 GVariantBuilder *invalidated_builder;
534
535                 BT_DBG("BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED");
536                 inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
537
538                 g_variant_builder_add(inner_builder, "{sv}", "ReadValue", var);
539
540                 invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
541
542                 parameters = g_variant_new("(a{sv}as)", inner_builder, invalidated_builder);
543                 g_variant_builder_unref(invalidated_builder);
544                 g_variant_builder_unref(inner_builder);
545         } else if (event == BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED) {
546                 GVariantBuilder *inner_builder;
547                 GVariantBuilder *invalidated_builder;
548
549                 BT_DBG("BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED");
550                 inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
551
552                 g_variant_builder_add(inner_builder, "{sv}", "NotificationStateChanged", var);
553
554                 invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
555
556                 parameters = g_variant_new("(a{sv}as)", inner_builder, invalidated_builder);
557                 g_variant_builder_unref(invalidated_builder);
558                 g_variant_builder_unref(inner_builder);
559         }
560
561         msg = g_dbus_message_new_signal(BT_OTP_OBJECT_PATH, BT_OTP_INTERFACE_NAME, PROPERTIES_CHANGED);
562         g_dbus_message_set_body(msg, parameters);
563         if (!g_dbus_connection_send_message(g_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 0, NULL)) {
564                 if (error != NULL) {
565                         BT_ERR("D-Bus API failure: errCode[%x], \
566                                         message[%s]",
567                                         error->code, error->message);
568                         g_clear_error(&error);
569                 }
570                 return BLUETOOTH_ERROR_INTERNAL;
571         }
572         return BLUETOOTH_ERROR_NONE;
573 }
574 #endif
575
576 static void __bt_gatt_manager_method_call(GDBusConnection *connection,
577                                         const gchar *sender,
578                                         const gchar *object_path,
579                                         const gchar *interface_name,
580                                         const gchar *method_name,
581                                         GVariant *parameters,
582                                         GDBusMethodInvocation *invocation,
583                                         gpointer user_data)
584 {
585         if (g_strcmp0(method_name, "GetManagedObjects") == 0) {
586                 BT_DBG("Getting values for service, chars and descriptors");
587
588                 int svc_index = 0;
589                 GVariantBuilder *builder = NULL;
590                 GVariantBuilder *inner_builder1 = NULL;
591                 GVariant *svc_char = NULL;
592                 GSList *char_list = NULL;
593                 GSList *desc_list = NULL;
594
595                 /* Main Builder */
596                 builder = g_variant_builder_new(G_VARIANT_TYPE("a{oa{sa{sv}}}"));
597
598                 /* Prepare inner builder for GattService1 interface */
599                 svc_index = g_slist_length(gatt_services) - 1;
600                 for (; svc_index >= 0; svc_index--) {
601                         GVariantBuilder *svc_builder = NULL;
602                         GVariantBuilder *inner_builder = NULL;
603                         struct gatt_service_info *serv_info = NULL;
604
605                         serv_info = g_slist_nth_data(gatt_services, svc_index);
606                         if (serv_info == NULL) {
607                                 BT_ERR("serv_info is NULL");
608                                 continue;
609                         }
610
611                         /* Prepare inner builder for GattService1 interface */
612                         BT_DBG("Creating builder for service : %s", serv_info->service_uuid);
613                         svc_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
614                         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
615
616                         g_variant_builder_add(inner_builder, "{sv}", "UUID",
617                                         g_variant_new_string(serv_info->service_uuid));
618                         g_variant_builder_add(inner_builder, "{sv}", "Primary",
619                                         g_variant_new_boolean(serv_info->is_svc_primary));
620
621                         /* Characteristics */
622                         inner_builder1 = g_variant_builder_new(G_VARIANT_TYPE("ao"));
623
624                         BT_DBG("Adding Charatarisitcs list");
625                         for (char_list = serv_info->char_data; char_list != NULL; char_list = char_list->next) {
626                                 struct gatt_char_info *char_info = char_list->data;
627                                 g_variant_builder_add(inner_builder1, "o", char_info->char_path);
628                                 BT_DBG("%s", char_info->char_path);
629                         }
630
631                         svc_char = g_variant_new("ao", inner_builder1);
632                         g_variant_builder_add(inner_builder, "{sv}", "Characteristics", svc_char);
633                         g_variant_builder_add(svc_builder, "{sa{sv}}", GATT_SERV_INTERFACE, inner_builder);
634                         g_variant_builder_add(builder, "{oa{sa{sv}}}", serv_info->serv_path, svc_builder);
635                         g_variant_builder_unref(inner_builder1);
636
637                         /* Prepare inner builder for GattCharacteristic1 interface */
638                         for (char_list = serv_info->char_data; char_list != NULL; char_list = char_list->next) {
639                                 GVariantBuilder *char_builder = NULL;
640                                 GVariantBuilder *inner_builder = NULL;
641                                 GVariantBuilder *builder1 = NULL;
642                                 GVariantBuilder *builder2 = NULL;
643                                 GVariantBuilder *builder3 = NULL;
644                                 GVariant *char_val = NULL;
645                                 GVariant *flags_val = NULL;
646                                 GVariant *char_desc = NULL;
647                                 char *unicast = NULL;
648                                 gboolean notify = FALSE;
649                                 int i = 0;
650                                 struct gatt_char_info *char_info = char_list->data;
651
652                                 if (char_info == NULL) {
653                                         BT_ERR("char_info is NULL");
654                                         continue;
655                                 }
656
657                                 BT_DBG("Creating builder for characteristic : %s", char_info->char_uuid);
658                                 char_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
659                                 inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
660
661                                 /* UUID */
662                                 g_variant_builder_add(inner_builder, "{sv}", "UUID",
663                                                 g_variant_new_string(char_info->char_uuid));
664
665                                 /* Service */
666                                 g_variant_builder_add(inner_builder, "{sv}", "Service",
667                                                 g_variant_new("o", serv_info->serv_path));
668
669                                 /* Value */
670                                 builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
671                                 if (char_info->char_value != NULL) {
672                                         for (i = 0; i < char_info->value_length; i++) {
673                                                 g_variant_builder_add(builder1, "y", char_info->char_value[i]);
674                                         }
675                                         char_val = g_variant_new("ay", builder1);
676                                         g_variant_builder_add(inner_builder, "{sv}", "Value", char_val);
677                                 }
678
679                                 /*Flags*/
680                                 builder2 = g_variant_builder_new(G_VARIANT_TYPE("as"));
681                                 for (i = 0; i < char_info->flags_length; i++) {
682                                         g_variant_builder_add(builder2, "s", char_info->char_flags[i]);
683                                 }
684                                 flags_val = g_variant_new("as", builder2);
685                                 g_variant_builder_add(inner_builder, "{sv}", "Flags", flags_val);
686
687                                 /* Notifying */
688                                 g_variant_builder_add(inner_builder, "{sv}", "Notifying", g_variant_new("b", notify));
689
690                                 /* Unicast */
691                                 unicast = g_strdup("00:00:00:00:00:00");
692                                 g_variant_builder_add(inner_builder, "{sv}", "Unicast", g_variant_new("s", unicast));
693
694                                 /*Descriptors*/
695                                 builder3 = g_variant_builder_new(G_VARIANT_TYPE("ao"));
696                                 BT_DBG("Adding Descriptors list");
697                                 for (desc_list = char_info->desc_data; desc_list != NULL; desc_list = desc_list->next) {
698                                         struct gatt_desc_info *desc_info = desc_list->data;
699                                         g_variant_builder_add(builder3, "o", desc_info->desc_path);
700                                         BT_DBG("%s", desc_info->desc_path);
701                                 }
702
703                                 char_desc = g_variant_new("ao", builder3);
704                                 g_variant_builder_add(inner_builder, "{sv}", "Descriptors", char_desc);
705                                 g_variant_builder_add(char_builder, "{sa{sv}}", GATT_CHAR_INTERFACE , inner_builder);
706                                 g_variant_builder_add(builder, "{oa{sa{sv}}}", char_info->char_path, char_builder);
707
708                                 /*Prepare inner builder for GattDescriptor1 interface*/
709                                 for (desc_list = char_info->desc_data; desc_list != NULL; desc_list = desc_list->next) {
710                                         GVariantBuilder *desc_builder = NULL;
711                                         GVariantBuilder *inner_builder = NULL;
712                                         GVariantBuilder *builder1 = NULL;
713                                         GVariantBuilder *builder2 = NULL;
714                                         GVariant *desc_val = NULL;
715                                         struct gatt_desc_info *desc_info = desc_list->data;
716
717                                         if (desc_info == NULL) {
718                                                 BT_ERR("desc_info is NULL");
719                                                 continue;
720                                         }
721
722                                         BT_DBG("Creating builder for descriptor : %s", desc_info->desc_uuid);
723                                         desc_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
724                                         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
725
726                                         /* UUID */
727                                         g_variant_builder_add(inner_builder, "{sv}", "UUID",
728                                                         g_variant_new_string(desc_info->desc_uuid));
729
730                                         /* Characteristic */
731                                         g_variant_builder_add(inner_builder, "{sv}", "Characteristic",
732                                                         g_variant_new("o", char_info->char_path));
733
734                                         /* Value */
735                                         builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
736                                         if (desc_info->desc_value != NULL) {
737                                                 for (i = 0; i < desc_info->value_length; i++) {
738                                                         g_variant_builder_add(builder1, "y", desc_info->desc_value[i]);
739                                                 }
740                                                 desc_val = g_variant_new("ay", builder1);
741                                                 g_variant_builder_add(inner_builder, "{sv}", "Value", desc_val);
742                                         }
743
744                                         /* Flags */
745                                         builder2 = g_variant_builder_new(G_VARIANT_TYPE("as"));
746                                         for (i = 0; i < desc_info->flags_length; i++) {
747                                                 g_variant_builder_add(builder2, "s", desc_info->desc_flags[i]);
748                                         }
749                                         flags_val = g_variant_new("as", builder2);
750                                         g_variant_builder_add(inner_builder, "{sv}", "Flags", flags_val);
751
752                                         g_variant_builder_add(desc_builder, "{sa{sv}}", GATT_DESC_INTERFACE,
753                                                         inner_builder);
754                                         g_variant_builder_add(builder, "{oa{sa{sv}}}", desc_info->desc_path,
755                                                         desc_builder);
756
757                                         /* unref descriptor builder pointers */
758                                         g_variant_builder_unref(builder1);
759                                         g_variant_builder_unref(builder2);
760                                         g_variant_builder_unref(inner_builder);
761                                         g_variant_builder_unref(desc_builder);
762                                 }
763
764                                 if (unicast)
765                                         g_free(unicast);
766
767                                 /* unref char builder pointers */
768                                 g_variant_builder_unref(builder1);
769                                 g_variant_builder_unref(builder2);
770                                 g_variant_builder_unref(builder3);
771                                 g_variant_builder_unref(inner_builder);
772                                 g_variant_builder_unref(char_builder);
773                         }
774
775                         /* unref service builder pointers */
776                         g_variant_builder_unref(inner_builder);
777                         g_variant_builder_unref(svc_builder);
778                 }
779
780                 /* Return builder as method reply */
781                 BT_DBG("Sending gatt service builder values to Bluez");
782                 g_dbus_method_invocation_return_value(invocation,
783                                 g_variant_new("(a{oa{sa{sv}}})", builder));
784                 g_variant_builder_unref(builder);
785         }
786 }
787
788 static struct gatt_service_info *__bt_gatt_find_gatt_service_from_char(const char *char_path)
789 {
790         GSList *l1, *l2;
791
792         for (l1 = gatt_services; l1 != NULL; l1 = l1->next) {
793                 struct gatt_service_info *serv_info = l1->data;
794
795                 for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
796                         struct gatt_char_info *char_info = l2->data;
797
798                         if (g_strcmp0(char_info->char_path, char_path) == 0)
799                                 return serv_info;
800                 }
801         }
802         BT_ERR("Gatt service not found");
803         return NULL;
804 }
805
806 static struct gatt_service_info *__bt_gatt_find_gatt_service_from_desc(const char *desc_path)
807 {
808         GSList *l1, *l2, *l3;
809
810         for (l1 = gatt_services; l1 != NULL; l1 = l1->next) {
811                 struct gatt_service_info *serv_info = l1->data;
812
813                 for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
814                         struct gatt_char_info *char_info = l2->data;
815
816                         for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) {
817                                 struct gatt_desc_info *desc_info = l3->data;
818
819                                 if (g_strcmp0(desc_info->desc_path, desc_path) == 0)
820                                         return serv_info;
821                         }
822                 }
823         }
824         BT_ERR("Gatt service not found");
825         return NULL;
826 }
827
828 static void __bt_gatt_char_method_call(GDBusConnection *connection,
829                                         const gchar *sender,
830                                         const gchar *object_path,
831                                         const gchar *interface_name,
832                                         const gchar *method_name,
833                                         GVariant *parameters,
834                                         GDBusMethodInvocation *invocation,
835                                         gpointer user_data)
836 {
837
838         if (g_strcmp0(method_name, "ReadValue") == 0) {
839                 gchar *addr = NULL;
840                 guint req_id = 0;
841                 guint16 offset = 0;
842                 bt_gatt_read_req_t read_req = {0, };
843                 bt_user_info_t *user_info = NULL;
844                 struct gatt_req_info *req_info = NULL;
845                 struct gatt_service_info *svc_info = NULL;
846 #if defined(TIZEN_FEATURE_BT_HPS) || defined(TIZEN_FEATURE_BT_OTP)
847                 GVariant *param = NULL;
848 #endif
849
850                 BT_DBG("Application path = %s", object_path);
851                 BT_DBG("Sender = %s", sender);
852
853                 user_info = _bt_get_user_data(BT_COMMON);
854                 if (user_info == NULL) {
855                         BT_INFO("No callback is set for %s", object_path);
856                         g_dbus_method_invocation_return_value(invocation, NULL);
857                         return;
858                 }
859
860                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path);
861                 if (svc_info == NULL) {
862                         BT_ERR("Coudn't find service for %s", object_path);
863                         g_dbus_method_invocation_return_value(invocation, NULL);
864                         return;
865                 }
866
867                 g_variant_get(parameters, "(&suq)", &addr, &req_id, &offset);
868                 BT_DBG("Request id = %u, Offset = %u", req_id, offset);
869
870                 read_req.att_handle = (char *)object_path;
871                 read_req.address = addr;
872                 read_req.req_id = req_id;
873                 read_req.offset = offset;
874                 read_req.service_handle = svc_info->serv_path;
875
876                 /* Store requets information */
877                 req_info = g_new0(struct gatt_req_info, 1);
878                 req_info->attr_path = g_strdup(object_path);
879                 req_info->svc_path = g_strdup(read_req.service_handle);
880                 req_info->request_id = req_id;
881                 req_info->offset = offset;
882                 req_info->context = invocation;
883                 gatt_requests = g_slist_append(gatt_requests, req_info);
884
885 #if defined(TIZEN_FEATURE_BT_HPS) || defined(TIZEN_FEATURE_BT_OTP)
886                 param = g_variant_new("(sssyq)",
887                                 read_req.att_handle,
888                                 read_req.service_handle,
889                                 read_req.address,
890                                 read_req.req_id,
891                                 read_req.offset);
892 #ifdef TIZEN_FEATURE_BT_HPS
893                 __bt_send_event_to_hps(BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, param);
894 #endif
895 #ifdef TIZEN_FEATURE_BT_OTP
896                 __bt_send_event_to_otp(BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, param);
897 #endif
898 #endif
899
900                 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED,
901                                         BLUETOOTH_ERROR_NONE, &read_req,
902                                         user_info->cb, user_info->user_data);
903                 return;
904         } else if (g_strcmp0(method_name, "WriteValue") == 0) {
905                 GVariant *var = NULL;
906                 gchar *addr = NULL;
907                 guint req_id = 0;
908                 guint16 offset = 0;
909                 gboolean response_needed = FALSE;
910                 bt_gatt_value_change_t value_change = {0, };
911                 bt_user_info_t *user_info = NULL;
912                 int len = 0;
913                 struct gatt_service_info *svc_info = NULL;
914                 struct gatt_req_info *req_info = NULL;
915 #if defined(TIZEN_FEATURE_BT_HPS) || defined(TIZEN_FEATURE_BT_OTP)
916                 GVariant *param = NULL;
917 #endif
918
919                 BT_DBG("WriteValue");
920                 BT_DBG("Application path = %s", object_path);
921                 BT_DBG("Sender = %s", sender);
922
923                 g_variant_get(parameters, "(&suqb@ay)",
924                                 &addr, &req_id, &offset, &response_needed, &var);
925                 BT_DBG("Request id = %u, Offset = %u", req_id, offset);
926
927                 user_info = _bt_get_user_data(BT_COMMON);
928                 if (!user_info) {
929                         BT_INFO("No callback is set for %s", object_path);
930                         g_variant_unref(var);
931                         if (response_needed)
932                                 g_dbus_method_invocation_return_value(invocation, NULL);
933                         else
934                                 g_object_unref(invocation);
935                         return;
936                 }
937
938                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path);
939                 if (svc_info == NULL) {
940                         BT_ERR("Coudn't find service for %s", object_path);
941                         g_variant_unref(var);
942                         if (response_needed)
943                                 g_dbus_method_invocation_return_value(invocation, NULL);
944                         else
945                                 g_object_unref(invocation);
946                         return;
947                 }
948
949                 value_change.att_handle = (char *)object_path;
950                 value_change.address = addr;
951                 value_change.service_handle = svc_info->serv_path;
952                 value_change.offset = offset;
953                 value_change.req_id = req_id;
954                 value_change.response_needed = response_needed;
955
956                 len = g_variant_get_size(var);
957                 if (len > 0) {
958                         char *data;
959
960                         value_change.att_value = (guint8 *)g_malloc(len);
961
962                         data = (char *)g_variant_get_data(var);
963                         memcpy(value_change.att_value, data, len);
964                 }
965                 value_change.val_len = len;
966
967                 if (response_needed) {
968                         /* Store requets information */
969                         req_info = g_new0(struct gatt_req_info, 1);
970                         req_info->attr_path = g_strdup(object_path);
971                         req_info->svc_path = g_strdup(value_change.service_handle);
972                         req_info->request_id = req_id;
973                         req_info->offset = offset;
974                         req_info->context = invocation;
975                         gatt_requests = g_slist_append(gatt_requests, req_info);
976                 } else {
977                         g_object_unref(invocation);
978                 }
979
980 #if defined(TIZEN_FEATURE_BT_HPS) || defined(TIZEN_FEATURE_BT_OTP)
981                 if (len > 0) {
982                         gchar *svc_path;
983                         svc_path = g_strdup(svc_info->serv_path);
984                         param = g_variant_new("(sssyq@ay)",
985                                         object_path,
986                                         svc_path,
987                                         addr,
988                                         req_id,
989                                         offset,
990                                         var);
991 #ifdef TIZEN_FEATURE_BT_HPS
992                         __bt_send_event_to_hps(BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED, param);
993 #endif
994 #ifdef TIZEN_FEATURE_BT_OTP
995                         __bt_send_event_to_otp(BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED, param);
996 #endif
997                         if (svc_path)
998                                 g_free(svc_path);
999                 }
1000 #endif
1001
1002                 _bt_common_event_cb(
1003                         BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
1004                         BLUETOOTH_ERROR_NONE, &value_change,
1005                         user_info->cb, user_info->user_data);
1006
1007                 g_free(value_change.att_value);
1008                 g_variant_unref(var);
1009                 return;
1010         } else if (g_strcmp0(method_name, "StartNotify") == 0) {
1011                 bt_user_info_t *user_info = NULL;
1012                 bt_gatt_char_notify_change_t notify_change = {0, };
1013 #if TIZEN_FEATURE_BT_OTP
1014                 GVariant *param = NULL;
1015 #endif
1016                 BT_DBG("StartNotify");
1017                 user_info = _bt_get_user_data(BT_COMMON);
1018                 if (user_info != NULL) {
1019                         struct gatt_service_info *svc_info = NULL;
1020                         svc_info = __bt_gatt_find_gatt_service_from_char(object_path);
1021                         if (svc_info) {
1022                                 notify_change.service_handle = svc_info->serv_path;
1023                                 notify_change.att_handle = (char *)object_path;
1024                                 notify_change.att_notify = TRUE;
1025 #if TIZEN_FEATURE_BT_OTP
1026                                 param = g_variant_new("(ssb)",
1027                                 notify_change.att_handle,
1028                                 notify_change.service_handle,
1029                                 notify_change.att_notify);
1030                                 __bt_send_event_to_otp(BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED, param);
1031 #endif
1032                                 _bt_common_event_cb(
1033                                         BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
1034                                         BLUETOOTH_ERROR_NONE, &notify_change,
1035                                         user_info->cb, user_info->user_data);
1036                         }
1037                 }
1038                 g_object_unref(invocation);
1039                 return;
1040         } else if (g_strcmp0(method_name, "StopNotify") == 0) {
1041                 bt_user_info_t *user_info = NULL;
1042                 bt_gatt_char_notify_change_t notify_change = {0, };
1043 #if TIZEN_FEATURE_BT_OTP
1044                 GVariant *param = NULL;
1045 #endif
1046                 BT_DBG("StopNotify");
1047                 user_info = _bt_get_user_data(BT_COMMON);
1048                 if (user_info != NULL) {
1049                         struct gatt_service_info *svc_info = NULL;
1050                         svc_info = __bt_gatt_find_gatt_service_from_char(object_path);
1051                         if (svc_info) {
1052                                 notify_change.service_handle = svc_info->serv_path;
1053                                 notify_change.att_handle = (char *)object_path;
1054                                 notify_change.att_notify = FALSE;
1055 #if TIZEN_FEATURE_BT_OTP
1056                                 param = g_variant_new("(ssb)",
1057                                 notify_change.att_handle,
1058                                 notify_change.service_handle,
1059                                 notify_change.att_notify);
1060                                 __bt_send_event_to_otp(BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED, param);
1061 #endif
1062                                 _bt_common_event_cb(
1063                                         BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
1064                                         BLUETOOTH_ERROR_NONE, &notify_change,
1065                                         user_info->cb, user_info->user_data);
1066                         }
1067                 }
1068                 g_object_unref(invocation);
1069                 return;
1070         } else if (g_strcmp0(method_name, "IndicateConfirm") == 0) {
1071                 gchar *addr = NULL;
1072                 bt_gatt_indicate_confirm_t confirm = {0, };
1073                 bt_user_info_t *user_info = NULL;
1074                 gboolean complete = FALSE;
1075                 struct gatt_service_info *svc_info = NULL;
1076
1077                 BT_DBG("IndicateConfirm");
1078                 BT_DBG("Application path = %s", object_path);
1079                 BT_DBG("Sender = %s", sender);
1080
1081                 g_variant_get(parameters, "(&sb)", &addr, &complete);
1082                 BT_DBG("Remote Device address number = %s", addr);
1083
1084                 confirm.att_handle = (char *)object_path;
1085                 confirm.address = addr;
1086                 confirm.complete = complete;
1087
1088                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path);
1089                 if (svc_info != NULL) {
1090                         confirm.service_handle = svc_info->serv_path;
1091
1092                         user_info = _bt_get_user_data(BT_COMMON);
1093                         if (user_info != NULL) {
1094                                 _bt_common_event_cb(
1095                                         BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED,
1096                                         BLUETOOTH_ERROR_NONE, &confirm,
1097                                         user_info->cb, user_info->user_data);
1098                         }
1099                 }
1100         }
1101
1102         g_dbus_method_invocation_return_value(invocation, NULL);
1103 }
1104
1105 static void __bt_gatt_desc_method_call(GDBusConnection *connection,
1106                                         const gchar *sender,
1107                                         const gchar *object_path,
1108                                         const gchar *interface_name,
1109                                         const gchar *method_name,
1110                                         GVariant *parameters,
1111                                         GDBusMethodInvocation *invocation,
1112                                         gpointer user_data)
1113 {
1114         if (g_strcmp0(method_name, "ReadValue") == 0) {
1115                 gchar *addr = NULL;
1116                 guint req_id = 0;
1117                 guint16 offset = 0;
1118                 bt_gatt_read_req_t read_req = {0, };
1119                 bt_user_info_t *user_info = NULL;
1120                 struct gatt_req_info *req_info = NULL;
1121                 struct gatt_service_info *svc_info = NULL;
1122
1123                 BT_DBG("ReadValue");
1124                 BT_DBG("Application path = %s", object_path);
1125                 BT_DBG("Sender = %s", sender);
1126
1127                 user_info = _bt_get_user_data(BT_COMMON);
1128                 if (user_info == NULL) {
1129                         BT_INFO("No callback is set for %s", object_path);
1130                         g_dbus_method_invocation_return_value(invocation, NULL);
1131                         return;
1132                 }
1133
1134                 svc_info = __bt_gatt_find_gatt_service_from_desc(object_path);
1135                 if (svc_info == NULL) {
1136                         BT_ERR("Coudn't find service for %s", object_path);
1137                         g_dbus_method_invocation_return_value(invocation, NULL);
1138                         return;
1139                 }
1140
1141                 g_variant_get(parameters, "(&suq)", &addr, &req_id, &offset);
1142                 BT_DBG("Request id = %u, Offset = %u", req_id, offset);
1143
1144                 read_req.att_handle = (char *)object_path;
1145                 read_req.address = addr;
1146                 read_req.req_id = req_id;
1147                 read_req.offset = offset;
1148                 read_req.service_handle = svc_info->serv_path;
1149
1150                 /* Store requets information */
1151                 req_info = g_new0(struct gatt_req_info, 1);
1152                 req_info->attr_path = g_strdup(object_path);
1153                 req_info->svc_path = g_strdup(read_req.service_handle);
1154                 req_info->request_id = req_id;
1155                 req_info->offset = offset;
1156                 req_info->context = invocation;
1157                 gatt_requests = g_slist_append(gatt_requests, req_info);
1158
1159                 _bt_common_event_cb(
1160                                 BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED,
1161                                 BLUETOOTH_ERROR_NONE, &read_req,
1162                                 user_info->cb, user_info->user_data);
1163
1164                 return;
1165         } else if (g_strcmp0(method_name, "WriteValue") == 0) {
1166                 GVariant *var = NULL;
1167                 gchar *addr = NULL;
1168                 guint req_id = 0;
1169                 guint16 offset = 0;
1170                 gboolean response_needed = FALSE;
1171                 bt_gatt_value_change_t value_change = {0, };
1172                 bt_user_info_t *user_info = NULL;
1173                 int len = 0;
1174                 struct gatt_service_info *svc_info = NULL;
1175                 struct gatt_req_info *req_info = NULL;
1176
1177                 BT_DBG("WriteValue");
1178                 BT_DBG("Application path = %s", object_path);
1179                 BT_DBG("Sender = %s", sender);
1180
1181                 g_variant_get(parameters, "(&suqb@ay)",
1182                                 &addr, &req_id, &offset, &response_needed, &var);
1183                 BT_DBG("Request id = %u, Offset = %u", req_id, offset);
1184
1185                 user_info = _bt_get_user_data(BT_COMMON);
1186                 if (user_info == NULL) {
1187                         BT_INFO("No callback is set for %s", object_path);
1188                         g_variant_unref(var);
1189                         if (response_needed)
1190                                 g_dbus_method_invocation_return_value(invocation, NULL);
1191                         else
1192                                 g_object_unref(invocation);
1193                         return;
1194                 }
1195
1196                 svc_info = __bt_gatt_find_gatt_service_from_desc(object_path);
1197                 if (svc_info == NULL) {
1198                         BT_ERR("Coudn't find service for %s", object_path);
1199                         g_variant_unref(var);
1200                         if (response_needed)
1201                                 g_dbus_method_invocation_return_value(invocation, NULL);
1202                         else
1203                                 g_object_unref(invocation);
1204                         return;
1205                 }
1206
1207                 value_change.att_handle = (char *)object_path;
1208                 value_change.address = addr;
1209                 value_change.service_handle = svc_info->serv_path;
1210                 value_change.offset = offset;
1211                 value_change.req_id = req_id;
1212                 value_change.response_needed = response_needed;
1213
1214                 len = g_variant_get_size(var);
1215                 if (len > 0) {
1216                         char *data;
1217
1218                         value_change.att_value = (guint8 *)g_malloc(len);
1219
1220                         data = (char *)g_variant_get_data(var);
1221                         memcpy(value_change.att_value, data, len);
1222                 }
1223                 value_change.val_len = len;
1224
1225                 if (response_needed) {
1226                         /* Store requets information */
1227                         req_info = g_new0(struct gatt_req_info, 1);
1228                         req_info->attr_path = g_strdup(object_path);
1229                         req_info->svc_path = g_strdup(value_change.service_handle);
1230                         req_info->request_id = req_id;
1231                         req_info->offset = offset;
1232                         req_info->context = invocation;
1233                         gatt_requests = g_slist_append(gatt_requests, req_info);
1234                 } else {
1235                         g_object_unref(invocation);
1236                 }
1237
1238                 _bt_common_event_cb(
1239                         BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
1240                         BLUETOOTH_ERROR_NONE, &value_change,
1241                         user_info->cb, user_info->user_data);
1242
1243                 g_free(value_change.att_value);
1244                 g_variant_unref(var);
1245                 return;
1246         }
1247 }
1248
1249 gboolean __bt_gatt_emit_interface_removed(gchar *object_path, gchar *interface)
1250 {
1251         gboolean ret;
1252         GError *error = NULL;
1253         GVariantBuilder *array_builder;
1254
1255         array_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
1256         g_variant_builder_init(array_builder, G_VARIANT_TYPE("as"));
1257         g_variant_builder_add(array_builder, "s", interface);
1258
1259         ret = g_dbus_connection_emit_signal(g_conn, NULL, "/",
1260                                         "org.freedesktop.Dbus.Objectmanager",
1261                                         "InterfacesRemoved",
1262                                         g_variant_new("(oas)",
1263                                         object_path, array_builder),
1264                                         &error);
1265
1266         if (!ret) {
1267                 if (error != NULL) {
1268                         /* dbus gives error cause */
1269                         BT_ERR("d-bus api failure: errcode[%x], message[%s]",
1270                                 error->code, error->message);
1271                         g_clear_error(&error);
1272                 }
1273         }
1274         g_variant_builder_unref(array_builder);
1275
1276         return ret;
1277 }
1278
1279 static const GDBusInterfaceVTable desc_interface_vtable = {
1280         __bt_gatt_desc_method_call,
1281         NULL,
1282         NULL,
1283         { 0 }
1284 };
1285
1286 static const GDBusInterfaceVTable char_interface_vtable = {
1287         __bt_gatt_char_method_call,
1288         NULL,
1289         NULL,
1290         { 0 }
1291 };
1292
1293 static const GDBusInterfaceVTable serv_interface_vtable = {
1294         NULL,
1295         NULL,
1296         NULL,
1297         { 0 }
1298 };
1299
1300 static const GDBusInterfaceVTable manager_interface_vtable = {
1301         __bt_gatt_manager_method_call,
1302         NULL,
1303         NULL,
1304         { 0 }
1305 };
1306
1307 static GDBusNodeInfo *__bt_gatt_create_method_node_info(
1308                                 const gchar *introspection_data)
1309 {
1310         GError *err = NULL;
1311         GDBusNodeInfo *node_info = NULL;
1312
1313         if (introspection_data == NULL)
1314                 return NULL;
1315
1316
1317         BT_DBG("Create new node info");
1318         node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
1319
1320         if (err) {
1321                 BT_ERR("Unable to create node: %s", err->message);
1322                 g_clear_error(&err);
1323                 return NULL;
1324         }
1325
1326         return node_info;
1327 }
1328
1329 static struct gatt_service_info *__bt_gatt_find_gatt_service_info(
1330                         const char *service_path)
1331 {
1332         GSList *l;
1333
1334         for (l = gatt_services; l != NULL; l = l->next) {
1335                 struct gatt_service_info *info = l->data;
1336
1337                 if (g_strcmp0(info->serv_path, service_path) == 0)
1338                         return info;
1339         }
1340         BT_ERR("Gatt service not found");
1341         return NULL;
1342 }
1343
1344 static struct gatt_char_info *__bt_gatt_find_gatt_char_info(
1345                         const char *service_path, const char *char_path)
1346 {
1347         GSList *l1, *l2;
1348
1349         for (l1 = gatt_services; l1 != NULL; l1 = l1->next) {
1350                 struct gatt_service_info *serv_info = l1->data;
1351
1352                 if (g_strcmp0(serv_info->serv_path, service_path) == 0) {
1353
1354                         for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
1355                                 struct gatt_char_info *char_info = l2->data;
1356
1357                                 if (g_strcmp0(char_info->char_path, char_path) == 0)
1358                                         return char_info;
1359                         }
1360                         BT_ERR("Gatt characteristic not found");
1361                         return NULL;
1362                 }
1363         }
1364         BT_ERR("Gatt service not found");
1365         return NULL;
1366 }
1367
1368 static struct gatt_desc_info *__bt_gatt_find_gatt_desc_info(
1369                         const char *serv_path, const char *char_path,
1370                         const char *desc_path)
1371 {
1372         GSList *l1, *l2, *l3;
1373
1374         for (l1 = gatt_services; l1 != NULL; l1 = l1->next) {
1375                 struct gatt_service_info *serv_info = l1->data;
1376
1377                 if (g_strcmp0(serv_info->serv_path, serv_path) == 0) {
1378                         for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
1379                                 struct gatt_char_info *char_info = l2->data;
1380
1381                                 if (g_strcmp0(char_info->char_path, char_path) == 0) {
1382                                         for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) {
1383                                                 struct gatt_desc_info *desc_info = l3->data;
1384                                                 if (g_strcmp0(desc_info->desc_path,
1385                                                         desc_path) == 0) {
1386                                                         return desc_info;
1387                                                 }
1388                                         }
1389                                 }
1390                         }
1391                 }
1392         }
1393         BT_ERR("Gatt descriptor not found");
1394         return NULL;
1395 }
1396
1397 static struct gatt_req_info *__bt_gatt_find_request_info(guint request_id)
1398 {
1399         GSList *l;
1400
1401         for (l = gatt_requests; l != NULL; l = l->next) {
1402                 struct gatt_req_info *req_info = l->data;
1403
1404                 if (req_info && req_info->request_id == request_id)
1405                         return req_info;
1406         }
1407         BT_ERR("Gatt Request not found");
1408         return NULL;
1409 }
1410
1411 static GDBusProxy *__bt_gatt_gdbus_init_manager_proxy(const gchar *service,
1412                                 const gchar *path, const gchar *interface)
1413 {
1414         GDBusProxy *proxy;
1415         GError *err = NULL;
1416
1417         g_conn = _bt_get_system_shared_conn();
1418         if (!g_conn) {
1419                 BT_ERR("Unable to get connection");
1420                 return NULL;
1421         }
1422
1423         proxy =  g_dbus_proxy_new_sync(g_conn,
1424                         G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
1425                         service, path,
1426                         interface, NULL, &err);
1427
1428         if (!proxy) {
1429                 if (err) {
1430                         BT_ERR("Unable to create proxy: %s", err->message);
1431                         g_clear_error(&err);
1432                 }
1433                 return NULL;
1434         }
1435         manager_gproxy = proxy;
1436
1437         return proxy;
1438 }
1439
1440 static GDBusProxy *__bt_gatt_gdbus_get_manager_proxy(const gchar *service,
1441                                 const gchar *path, const gchar *interface)
1442 {
1443         return (manager_gproxy) ? manager_gproxy :
1444                         __bt_gatt_gdbus_init_manager_proxy(service,
1445                                 path, interface);
1446 }
1447
1448 static gboolean __bt_gatt_is_service_registered(const char *service_path)
1449 {
1450         struct gatt_service_info *svc_info = NULL;
1451
1452         svc_info = __bt_gatt_find_gatt_service_info(service_path);
1453
1454         if (svc_info != NULL) {
1455                 BT_DBG("Return the state of the gatt service %d",
1456                         svc_info->is_svc_registered);
1457                 return svc_info->is_svc_registered;
1458         }
1459
1460         BT_DBG("gatt service info is NULL");
1461         return FALSE;
1462 }
1463
1464 void get_service_cb(GObject *object, GAsyncResult *res, gpointer user_data)
1465 {
1466         GError *error = NULL;
1467         GVariant *result;
1468         GVariantIter *iter = NULL;
1469         const gchar *key = NULL;
1470         GVariant *value = NULL;
1471         const gchar *service = NULL;
1472         const gchar *characteristic = NULL;
1473         const gchar *descriptor = NULL;
1474         int n_char = 1;
1475
1476         BT_DBG(" ");
1477         result = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), res, &error);
1478
1479         if (result == NULL) {
1480                 BT_ERR("Dbus-RPC is failed");
1481                 if (error != NULL) {
1482                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
1483                                         error->code, error->message);
1484                         g_clear_error(&error);
1485                 }
1486         } else {
1487                 char *char_cmp = NULL;
1488                 g_variant_get(result, "(a{sv})", &iter);
1489                 char_cmp = g_strdup_printf("Characteristic%d", n_char);
1490
1491                 while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
1492                         if (g_strcmp0(key, "Service") == 0) {
1493                                 service = g_variant_get_string(value, NULL);
1494                                 BT_DBG("Service %s", service);
1495                         } else if (g_strcmp0(key, char_cmp) == 0) {
1496                                 characteristic = g_variant_get_string(value, NULL);
1497                                 g_free(char_cmp);
1498                                 char_cmp = g_strdup_printf("Characteristic%d", ++n_char);
1499                                 BT_DBG("%s", characteristic);
1500                         } else if (g_strcmp0(key, "Descriptor") == 0) {
1501                                 descriptor = g_variant_get_string(value, NULL);
1502                                 BT_DBG("Descriptor %s", descriptor);
1503                         }
1504                 }
1505                 g_variant_iter_free(iter);
1506
1507                 /* TODO: Store the service informationa and
1508                  * Send respponse to CAPI layer. */
1509
1510                 g_variant_unref(result);
1511                 if (char_cmp)
1512                         g_free(char_cmp);
1513         }
1514 }
1515 void register_application_cb(GObject *object, GAsyncResult *res, gpointer user_data)
1516 {
1517         BT_INFO("RegisterApplication is completed");
1518
1519         GError *error = NULL;
1520         GVariant *result;
1521
1522         if (register_cancel) {
1523                 g_object_unref(register_cancel);
1524                 register_cancel = NULL;
1525         }
1526
1527         result = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), res, &error);
1528         if (result == NULL) {
1529                 BT_ERR("Dbus-RPC is failed");
1530                 if (error != NULL) {
1531                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
1532                                         error->code, error->message);
1533                         g_clear_error(&error);
1534                 }
1535                 is_server_started = false;
1536         } else {
1537                 g_variant_unref(result);
1538         }
1539 }
1540
1541 BT_EXPORT_API int bluetooth_gatt_unregister_application(void)
1542 {
1543         GDBusProxy *proxy = NULL;
1544
1545         if (is_server_started) {
1546                 GVariant *ret;
1547                 GError *err = NULL;
1548
1549                 if (app_path == NULL) {
1550                         BT_ERR("app_path is NULL");
1551                         return BLUETOOTH_ERROR_INTERNAL;
1552                 }
1553
1554                 proxy = __bt_gatt_gdbus_get_manager_proxy("org.bluez",
1555                                 "/org/bluez/hci0", GATT_MNGR_INTERFACE);
1556                 if (proxy == NULL) {
1557                         BT_ERR("proxy is NULL");
1558                         return BLUETOOTH_ERROR_INTERNAL;
1559                 }
1560
1561                 BT_INFO("UnregisterApplication");
1562
1563                 /* Async Call to Unregister Service */
1564                 ret = g_dbus_proxy_call_sync(proxy, "UnregisterApplication",
1565                                 g_variant_new("(o)", app_path), G_DBUS_CALL_FLAGS_NONE, -1,
1566                                 NULL, &err);
1567                 if (ret == NULL) {
1568                         BT_ERR("dBUS-RPC is failed");
1569                         if (err != NULL) {
1570                                 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
1571                                                 err->code, err->message);
1572                                 if (err->code == G_DBUS_ERROR_SERVICE_UNKNOWN ||
1573                                         g_strrstr(err->message, BT_ERROR_DOES_NOT_EXIST)) {
1574                                         g_clear_error(&err);
1575                                         goto done;
1576                                 }
1577                                 g_clear_error(&err);
1578                         }
1579                         return BLUETOOTH_ERROR_INTERNAL;
1580                 }
1581                 g_variant_unref(ret);
1582
1583 done:
1584                 is_server_started = false;
1585
1586                 BT_INFO("UnregisterApplication is completed");
1587
1588                 return BLUETOOTH_ERROR_NONE;
1589         }
1590
1591         BT_INFO("GATT server not started");
1592         return BLUETOOTH_ERROR_NONE;
1593 }
1594
1595 BT_EXPORT_API int bluetooth_gatt_init(void)
1596 {
1597         GError *error = NULL;
1598         GDBusNodeInfo *node_info = NULL;
1599
1600         if (app_path != NULL) {
1601                 BT_ERR("app path already exists! initialized");
1602                 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
1603         }
1604
1605         g_conn = _bt_get_system_shared_conn();
1606         if (!g_conn) {
1607                 BT_ERR("Unable to get connection");
1608                 goto failed;
1609         }
1610
1611         if (owner_id == 0) {
1612                 gchar *name = g_strdup_printf("%s.p%d", BT_GATT_SERVICE_NAME, getpid());
1613                 BT_DBG("well-known name: %s", name);
1614
1615                 owner_id = g_bus_own_name_on_connection(g_conn, name,
1616                                         G_BUS_NAME_OWNER_FLAGS_NONE,
1617                                         NULL, NULL, NULL, NULL);
1618                 g_free(name);
1619         }
1620         BT_DBG("owner_id is [%d]", owner_id);
1621
1622         app_path = g_strdup_printf("/com/%d", getpid());
1623
1624         serv_id = 1;
1625
1626         /* Register ObjectManager interface */
1627         node_info = __bt_gatt_create_method_node_info(
1628                                         manager_introspection_xml);
1629         if (node_info == NULL) {
1630                 BT_ERR("failed to get node info");
1631                 goto failed;
1632         }
1633
1634         if (manager_id == 0) {
1635                 BT_INFO("manager_id does not exists");
1636
1637                 manager_id = g_dbus_connection_register_object(g_conn, app_path,
1638                                                         node_info->interfaces[0],
1639                                                         &manager_interface_vtable,
1640                                                         NULL, NULL, &error);
1641         }
1642         g_dbus_node_info_unref(node_info);
1643         if (manager_id == 0) {
1644                 BT_ERR("failed to register: %s", error->message);
1645                 g_error_free(error);
1646                 goto failed;
1647         }
1648
1649         return BLUETOOTH_ERROR_NONE;
1650
1651 failed:
1652         if (owner_id)
1653                 g_bus_unown_name(owner_id);
1654
1655         g_free(app_path);
1656
1657         app_path = NULL;
1658         owner_id = 0;
1659
1660         return BLUETOOTH_ERROR_INTERNAL;
1661 }
1662
1663 BT_EXPORT_API int bluetooth_gatt_deinit()
1664 {
1665         int ret = BLUETOOTH_ERROR_NONE;
1666
1667         if (register_cancel) {
1668                 g_cancellable_cancel(register_cancel);
1669                 g_object_unref(register_cancel);
1670                 register_cancel = NULL;
1671         }
1672
1673         if (owner_id == 0) {
1674                 BT_ERR("owner_id is zero");
1675                 return BLUETOOTH_ERROR_NOT_FOUND;
1676         }
1677
1678         BT_DBG("Removing all registered gatt services");
1679         bluetooth_gatt_delete_services();
1680
1681         /* Unregister the exported interface for object manager */
1682         if (manager_id) {
1683                 g_dbus_connection_unregister_object(g_conn, manager_id);
1684                 manager_id = 0;
1685         }
1686
1687         ret = bluetooth_gatt_unregister_application();
1688         if (ret != BLUETOOTH_ERROR_NONE) {
1689                 BT_ERR("Fail to unregister application");
1690         }
1691
1692         g_bus_unown_name(owner_id);
1693         owner_id = 0;
1694
1695         g_free(app_path);
1696         app_path = NULL;
1697
1698         if (manager_gproxy) {
1699                 g_object_unref(manager_gproxy);
1700                 manager_gproxy = NULL;
1701         }
1702
1703         BT_DBG("-");
1704         return ret;
1705 }
1706
1707 BT_EXPORT_API int bluetooth_gatt_add_service(const char *svc_uuid,
1708                         char **svc_path)
1709 {
1710         GError *error = NULL;
1711         guint object_id;
1712         GDBusNodeInfo *node_info;
1713         gchar *path = NULL;
1714         GVariantBuilder *builder = NULL;
1715         GVariantBuilder *builder1 = NULL;
1716         GVariantBuilder *inner_builder = NULL;
1717         gboolean svc_primary = TRUE;
1718         struct gatt_service_info *serv_info = NULL;
1719
1720         node_info = __bt_gatt_create_method_node_info(
1721                                         service_introspection_xml);
1722         if (node_info == NULL)
1723                 return BLUETOOTH_ERROR_INTERNAL;
1724
1725         path = g_strdup_printf("%s"GATT_SERV_OBJECT_PATH"%d", app_path, serv_id++);
1726         BT_DBG("gatt service path is [%s]", path);
1727
1728         object_id = g_dbus_connection_register_object(g_conn, path,
1729                                         node_info->interfaces[0],
1730                                         &serv_interface_vtable,
1731                                         NULL, NULL, &error);
1732         g_dbus_node_info_unref(node_info);
1733
1734         if (object_id == 0) {
1735                 BT_ERR("failed to register: %s", error->message);
1736                 g_error_free(error);
1737                 g_free(path);
1738
1739                 return BLUETOOTH_ERROR_INTERNAL;
1740         }
1741
1742         /* Add object_id/gatt service information; it's required at the time of
1743          *  service unregister and Getmanagedobjects
1744          */
1745         serv_info = g_new0(struct gatt_service_info, 1);
1746
1747         serv_info->serv_path = g_strdup(path);
1748         serv_info->serv_id = object_id;
1749         serv_info->service_uuid = g_strdup(svc_uuid);
1750         serv_info->is_svc_registered = FALSE;
1751         serv_info->is_svc_primary = svc_primary;
1752
1753         gatt_services = g_slist_append(gatt_services, serv_info);
1754
1755         /* emit interfacesadded signal here for service path */
1756         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
1757         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1758
1759         g_variant_builder_add(inner_builder, "{sv}",
1760                 "UUID", g_variant_new_string(svc_uuid));
1761
1762         g_variant_builder_add(inner_builder, "{sv}",
1763                 "Primary", g_variant_new_boolean(svc_primary));
1764
1765         builder1 = g_variant_builder_new(G_VARIANT_TYPE("ao"));
1766
1767         g_variant_builder_add(inner_builder, "{sv}", "Characteristics",
1768                                 g_variant_new("ao", builder1));
1769
1770         g_variant_builder_add(builder, "{sa{sv}}",
1771                 GATT_SERV_INTERFACE, inner_builder);
1772
1773         g_dbus_connection_emit_signal(g_conn, NULL, "/",
1774                                 "org.freedesktop.Dbus.ObjectManager",
1775                                 "InterfacesAdded",
1776                                 g_variant_new("(oa{sa{sv}})",
1777                                 path, builder),
1778                                 &error);
1779         if (error != NULL) {
1780                 /* dbus gives error cause */
1781                 BT_ERR("d-bus api failure: errcode[%x], message[%s]",
1782                                 error->code, error->message);
1783                 g_clear_error(&error);
1784         }
1785
1786         new_service = TRUE;
1787
1788         *svc_path = g_strdup(path);
1789
1790         g_free(path);
1791         g_variant_builder_unref(inner_builder);
1792         g_variant_builder_unref(builder);
1793         g_variant_builder_unref(builder1);
1794
1795         return BLUETOOTH_ERROR_NONE;
1796 }
1797
1798 BT_EXPORT_API int bluetooth_gatt_add_new_characteristic(
1799                         const char *svc_path, const char *char_uuid,
1800                         bt_gatt_permission_t permissions,
1801                         bt_gatt_characteristic_property_t properties,
1802                         char **char_path)
1803 {
1804         static int char_id;
1805         GError *error = NULL;
1806         guint object_id;
1807         GDBusNodeInfo *node_info;
1808         gchar *path = NULL;
1809         GVariantBuilder *builder = NULL;
1810         GVariantBuilder *inner_builder = NULL;
1811         struct gatt_service_info *serv_info = NULL;
1812         struct gatt_char_info *char_info = NULL;
1813         GVariantBuilder *builder2 = NULL;
1814         GVariantBuilder *builder3 = NULL;
1815         GVariant *flags_val = NULL;
1816         int i = 0;
1817         char *char_flags[NUMBER_OF_FLAGS];
1818         int flag_count = 0;
1819
1820         if (new_service) {
1821                 char_id = 1;
1822                 new_service = FALSE;
1823         }
1824
1825         BT_DBG("gatt svc_path path is [%s]", svc_path);
1826         serv_info = __bt_gatt_find_gatt_service_info(svc_path);
1827         if (serv_info == NULL)
1828                 return BLUETOOTH_ERROR_INVALID_PARAM;
1829
1830         node_info = __bt_gatt_create_method_node_info(
1831                                         characteristics_introspection_xml);
1832         if (node_info == NULL)
1833                 return BLUETOOTH_ERROR_INTERNAL;
1834
1835         path = g_strdup_printf("%s/characteristic%d", svc_path, char_id++);
1836         BT_DBG("gatt characteristic path is [%s]", path);
1837
1838         object_id = g_dbus_connection_register_object(g_conn, path,
1839                                         node_info->interfaces[0],
1840                                         &char_interface_vtable,
1841                                         NULL, NULL, &error);
1842         g_dbus_node_info_unref(node_info);
1843
1844         if (object_id == 0) {
1845                 BT_ERR("failed to register: %s", error->message);
1846                 g_error_free(error);
1847                 g_free(path);
1848
1849                 return BLUETOOTH_ERROR_INTERNAL;
1850         }
1851
1852         if (permissions & BLUETOOTH_GATT_PERMISSION_ENCRYPT_READ)
1853                 properties |= BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
1854         if (permissions & BLUETOOTH_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ)
1855                 properties |= BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
1856         if (permissions & BLUETOOTH_GATT_PERMISSION_ENCRYPT_WRITE)
1857                 properties |= BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
1858         if (permissions & BLUETOOTH_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE)
1859                 properties |= BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
1860
1861         flag_count = bluetooth_gatt_convert_prop2string(properties, char_flags);
1862
1863         char_info = g_new0(struct gatt_char_info, 1);
1864
1865         char_info->char_path = g_strdup(path);
1866         char_info->char_id = object_id;
1867         char_info->char_uuid = g_strdup(char_uuid);
1868
1869         for (i = 0; i < flag_count; i++)
1870                 char_info->char_flags[i] = char_flags[i];
1871
1872
1873         char_info->flags_length = flag_count;
1874
1875         serv_info->char_data = g_slist_append(serv_info->char_data, char_info);
1876
1877         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
1878         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1879
1880         g_variant_builder_add(inner_builder, "{sv}", "UUID",
1881                                 g_variant_new("s", char_uuid));
1882         g_variant_builder_add(inner_builder, "{sv}", "Service",
1883                                 g_variant_new("o", svc_path));
1884
1885         builder2 = g_variant_builder_new(G_VARIANT_TYPE("as"));
1886
1887         for (i = 0; i < flag_count; i++)
1888                 g_variant_builder_add(builder2, "s", char_flags[i]);
1889
1890         flags_val = g_variant_new("as", builder2);
1891         g_variant_builder_add(inner_builder, "{sv}", "Flags",
1892                                 flags_val);
1893
1894         builder3 = g_variant_builder_new(G_VARIANT_TYPE("ao"));
1895
1896         g_variant_builder_add(inner_builder, "{sv}", "Descriptors",
1897                                 g_variant_new("ao", builder3));
1898
1899         g_variant_builder_add(builder, "{sa{sv}}",
1900                                 GATT_CHAR_INTERFACE,
1901                                 inner_builder);
1902
1903         g_dbus_connection_emit_signal(g_conn, NULL, "/",
1904                                 "org.freedesktop.Dbus.ObjectManager",
1905                                 "InterfacesAdded",
1906                                 g_variant_new("(oa{sa{sv}})",
1907                                 path, builder),
1908                                 &error);
1909         if (error) {
1910                 /* dBUS gives error cause */
1911                 BT_ERR("Could not Emit Signal: errCode[%x], message[%s]",
1912                                 error->code, error->message);
1913                 g_clear_error(&error);
1914         }
1915
1916         *char_path = g_strdup(path);
1917
1918         new_char = TRUE;
1919
1920         g_free(path);
1921
1922         g_variant_builder_unref(inner_builder);
1923         g_variant_builder_unref(builder);
1924         g_variant_builder_unref(builder2);
1925         g_variant_builder_unref(builder3);
1926
1927         return BLUETOOTH_ERROR_NONE;
1928 }
1929
1930 BT_EXPORT_API int bluetooth_gatt_set_characteristic_value(
1931                         const char *characteristic, const char *char_value,
1932                         int     value_length)
1933 {
1934         gchar **line_argv = NULL;
1935         char *serv_path = NULL;
1936         struct gatt_char_info *char_info = NULL;
1937         GVariantBuilder *builder1 = NULL;
1938         GVariantBuilder *builder = NULL;
1939         GVariantBuilder *inner_builder = NULL;
1940         GVariant *char_val = NULL;
1941         GError *error = NULL;
1942         int i = 0;
1943         int res = BLUETOOTH_ERROR_NONE;
1944
1945         line_argv = g_strsplit_set(characteristic, "/", 0);
1946         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
1947
1948         char_info = __bt_gatt_find_gatt_char_info(serv_path, characteristic);
1949
1950         if (char_info == NULL) {
1951                 /* Fix : RESOURCE_LEAK */
1952                 res = BLUETOOTH_ERROR_INVALID_PARAM;
1953                 goto done;
1954         }
1955
1956         char_info->value_length = value_length;
1957
1958         char_info->char_value = (char *)malloc(value_length);
1959         /* Fix : NULL_RETURNS */
1960         if (char_info->char_value == NULL) {
1961                 res = BLUETOOTH_ERROR_MEMORY_ALLOCATION;
1962                 goto done;
1963         }
1964
1965         for (i = 0; i < value_length; i++)
1966                 char_info->char_value[i] = char_value[i];
1967
1968         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
1969         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1970
1971         builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
1972
1973         for (i = 0; i < value_length; i++)
1974                 g_variant_builder_add(builder1, "y", char_value[i]);
1975
1976         char_val = g_variant_new("ay", builder1);
1977         g_variant_builder_add(inner_builder, "{sv}", "Value", char_val);
1978
1979         g_variant_builder_add(builder, "{sa{sv}}",
1980                         GATT_CHAR_INTERFACE,
1981                         inner_builder);
1982
1983         g_dbus_connection_emit_signal(g_conn, NULL, "/",
1984                         "org.freedesktop.Dbus.ObjectManager",
1985                         "InterfacesAdded",
1986                         g_variant_new("(oa{sa{sv}})",
1987                                 char_info->char_path, builder),
1988                         &error);
1989
1990         if (error) {
1991                 /* dBUS gives error cause */
1992                 BT_ERR("Could not Emit Signal: errCode[%x], message[%s]",
1993                                 error->code, error->message);
1994                 g_clear_error(&error);
1995         }
1996         g_variant_builder_unref(inner_builder);
1997         g_variant_builder_unref(builder);
1998         g_variant_builder_unref(builder1);
1999 done:
2000         g_strfreev(line_argv);
2001         g_free(serv_path);
2002
2003         return res;
2004 }
2005
2006 BT_EXPORT_API int bluetooth_gatt_add_descriptor(
2007                         const char *char_path, const char *desc_uuid,
2008                         bt_gatt_permission_t permissions,
2009                         char **desc_path)
2010 {
2011         static int desc_id = 1;
2012         GError *error = NULL;
2013         guint object_id;
2014         GDBusNodeInfo *node_info;
2015         gchar *path = NULL;
2016         GVariantBuilder *builder = NULL;
2017         GVariantBuilder *inner_builder = NULL;
2018         struct gatt_char_info *char_info = NULL;
2019         struct gatt_desc_info *desc_info = NULL;
2020         gchar **line_argv = NULL;
2021         char *serv_path;
2022         GVariantBuilder *builder2 = NULL;
2023         GVariant *flags_val = NULL;
2024         int i = 0;
2025         char *desc_flags[NUMBER_OF_FLAGS];
2026         int flag_count = 0;
2027
2028         if (new_char) {
2029                 desc_id = 1;
2030                 new_char = FALSE;
2031         }
2032
2033         line_argv = g_strsplit_set(char_path, "/", 0);
2034         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
2035
2036         char_info = __bt_gatt_find_gatt_char_info(serv_path, char_path);
2037         if (char_info == NULL) {
2038                 g_strfreev(line_argv);
2039                 g_free(serv_path);
2040                 return BLUETOOTH_ERROR_INVALID_PARAM;
2041         }
2042
2043         node_info = __bt_gatt_create_method_node_info(
2044                                         descriptor_introspection_xml);
2045         if (node_info == NULL) {
2046                 g_strfreev(line_argv);
2047                 g_free(serv_path);
2048                 return BLUETOOTH_ERROR_INTERNAL;
2049         }
2050
2051         path = g_strdup_printf("%s/descriptor%d", char_path, desc_id++);
2052         BT_DBG("gatt descriptor path is [%s]", path);
2053
2054         object_id = g_dbus_connection_register_object(g_conn, path,
2055                                 node_info->interfaces[0],
2056                                 &desc_interface_vtable,
2057                                 NULL, NULL, &error);
2058         g_dbus_node_info_unref(node_info);
2059
2060         if (object_id == 0) {
2061                 BT_ERR("failed to register: %s", error->message);
2062                 g_error_free(error);
2063                 g_free(path);
2064                 g_strfreev(line_argv);
2065                 g_free(serv_path);
2066
2067                 return BLUETOOTH_ERROR_INTERNAL;
2068         }
2069
2070         flag_count = bluetooth_gatt_convert_perm2string(permissions, desc_flags);
2071
2072         desc_info = g_new0(struct gatt_desc_info, 1);
2073
2074         desc_info->desc_path = g_strdup(path);
2075         desc_info->desc_id = object_id;
2076         desc_info->desc_uuid = g_strdup(desc_uuid);
2077
2078         for (i = 0; i < flag_count; i++)
2079                 desc_info->desc_flags[i] = desc_flags[i];
2080
2081         desc_info->flags_length = flag_count;
2082
2083         char_info->desc_data = g_slist_append(char_info->desc_data, desc_info);
2084
2085         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
2086         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2087
2088         g_variant_builder_add(inner_builder, "{sv}", "UUID",
2089                                 g_variant_new("s", desc_uuid));
2090         g_variant_builder_add(inner_builder, "{sv}", "Characteristic",
2091                                 g_variant_new("o", char_path));
2092
2093         builder2 = g_variant_builder_new(G_VARIANT_TYPE("as"));
2094
2095         for (i = 0; i < flag_count; i++)
2096                 g_variant_builder_add(builder2, "s", desc_flags[i]);
2097
2098         flags_val = g_variant_new("as", builder2);
2099         g_variant_builder_add(inner_builder, "{sv}", "Flags",
2100                                 flags_val);
2101
2102         g_variant_builder_add(builder, "{sa{sv}}",
2103                                 GATT_DESC_INTERFACE,
2104                                 inner_builder);
2105
2106         g_dbus_connection_emit_signal(g_conn, NULL, "/",
2107                                 "org.freedesktop.Dbus.ObjectManager",
2108                                 "InterfacesAdded",
2109                                 g_variant_new("(oa{sa{sv}})",
2110                                 path, builder),
2111                                 &error);
2112         if (error) {
2113                 /* dBUS gives error cause */
2114                 BT_ERR("Could not Emit Signal: errCode[%x], message[%s]",
2115                                 error->code, error->message);
2116                 g_clear_error(&error);
2117         }
2118
2119         *desc_path = g_strdup(path);
2120
2121         g_free(path);
2122         g_free(serv_path);
2123         g_strfreev(line_argv);
2124         g_variant_builder_unref(inner_builder);
2125         g_variant_builder_unref(builder);
2126         g_variant_builder_unref(builder2);
2127
2128         return BLUETOOTH_ERROR_NONE;
2129 }
2130
2131 BT_EXPORT_API int bluetooth_gatt_set_descriptor_value(
2132                         const char *desc_path, const char *desc_value,
2133                         int value_length)
2134 {
2135         GError *error = NULL;
2136         GVariantBuilder *builder = NULL;
2137         GVariantBuilder *inner_builder = NULL;
2138         GVariantBuilder *builder1 = NULL;
2139         struct gatt_desc_info *desc_info = NULL;
2140         gchar **line_argv = NULL;
2141         char *char_path;
2142         GVariant *desc_val = NULL;
2143         char *serv_path = NULL;
2144         int i ;
2145
2146         line_argv = g_strsplit_set(desc_path, "/", 0);
2147         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
2148         char_path = g_strdup_printf("%s/%s", serv_path, line_argv[4]);
2149
2150         desc_info = __bt_gatt_find_gatt_desc_info(serv_path, char_path, desc_path);
2151
2152         /* Free the allocated memory */
2153         g_strfreev(line_argv);
2154         g_free(serv_path);
2155         g_free(char_path);
2156
2157         /* Fix : NULL_RETURNS */
2158         retv_if(desc_info == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
2159
2160         desc_info->desc_value = (char *)malloc(value_length);
2161
2162         /* Fix : NULL_RETURNS */
2163         retv_if(desc_info->desc_value == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
2164
2165         for (i = 0; i < value_length; i++)
2166                 desc_info->desc_value[i] = desc_value[i];
2167
2168         desc_info->value_length = value_length;
2169
2170         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
2171         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2172
2173         builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
2174
2175         for (i = 0; i < value_length; i++)
2176                 g_variant_builder_add(builder1, "y", desc_value[i]);
2177
2178         desc_val = g_variant_new("ay", builder1);
2179         g_variant_builder_add(inner_builder, "{sv}", "Value", desc_val);
2180
2181         g_variant_builder_add(builder, "{sa{sv}}",
2182                                 GATT_DESC_INTERFACE,
2183                                 inner_builder);
2184
2185         g_dbus_connection_emit_signal(g_conn, NULL, "/",
2186                                 "org.freedesktop.Dbus.ObjectManager",
2187                                 "InterfacesAdded",
2188                                 g_variant_new("(oa{sa{sv}})",
2189                                         desc_info->desc_path, builder),
2190                                 &error);
2191
2192         if (error != NULL) {
2193                 BT_ERR("D-Bus API failure: errCode[%x], \
2194                                 message[%s]",
2195                                 error->code, error->message);
2196                 g_clear_error(&error);
2197         }
2198
2199         g_variant_builder_unref(inner_builder);
2200         g_variant_builder_unref(builder);
2201         g_variant_builder_unref(builder1);
2202
2203         return BLUETOOTH_ERROR_NONE;
2204 }
2205
2206 int bluetooth_gatt_get_service(const char *svc_uuid)
2207 {
2208         GDBusProxy *proxy = NULL;
2209         gchar *uuid = NULL;
2210
2211         proxy = __bt_gatt_gdbus_get_manager_proxy("org.bluez",
2212                                         "/org/bluez/hci0", GATT_MNGR_INTERFACE);
2213         if (proxy == NULL)
2214                 return BLUETOOTH_ERROR_INTERNAL;
2215
2216         uuid = g_strdup(svc_uuid);
2217
2218         g_dbus_proxy_call(proxy,
2219                         "GetService",
2220                         g_variant_new("(s)",
2221                         uuid),
2222                         G_DBUS_CALL_FLAGS_NONE, -1,
2223                         NULL,
2224                         (GAsyncReadyCallback) get_service_cb,
2225                         NULL);
2226
2227         g_free(uuid);
2228
2229         return BLUETOOTH_ERROR_NONE;
2230 }
2231
2232 BT_EXPORT_API int bluetooth_gatt_register_service(const char *svc_path)
2233 {
2234         struct gatt_service_info *svc_info = NULL;
2235
2236         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_GATT_REGISTER_SERVICE)
2237                         == BLUETOOTH_ERROR_PERMISSION_DEINED) {
2238                 BT_ERR("Don't have aprivilege to use this API");
2239                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
2240         }
2241
2242         svc_info = __bt_gatt_find_gatt_service_info(svc_path);
2243         if (svc_info == NULL) {
2244                 BT_ERR("Cannot find service [%s]", svc_path);
2245                 return BLUETOOTH_ERROR_INTERNAL;
2246         }
2247         svc_info->is_svc_registered = TRUE;
2248
2249         return BLUETOOTH_ERROR_NONE;
2250 }
2251
2252 BT_EXPORT_API int bluetooth_gatt_register_application(void)
2253 {
2254         GDBusProxy *proxy = NULL;
2255
2256         if (!is_server_started) {
2257                 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_GATT_REGISTER_APPLICATION)
2258                                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
2259                         BT_ERR("Don't have aprivilege to use this API");
2260                         return BLUETOOTH_ERROR_PERMISSION_DEINED;
2261                 }
2262
2263                 if (g_slist_length(gatt_services) == 0) {
2264                         BT_ERR("There is no registered service");
2265                         return BLUETOOTH_ERROR_INTERNAL;
2266                 }
2267
2268                 if (app_path == NULL) {
2269                         BT_ERR("app_path is NULL");
2270                         return BLUETOOTH_ERROR_INTERNAL;
2271                 }
2272
2273                 proxy = __bt_gatt_gdbus_get_manager_proxy("org.bluez",
2274                                 "/org/bluez/hci0", GATT_MNGR_INTERFACE);
2275                 if (proxy == NULL) {
2276                         BT_ERR("proxy is NULL");
2277                         return BLUETOOTH_ERROR_INTERNAL;
2278                 }
2279
2280                 BT_INFO("RegisterApplication");
2281
2282                 if (register_cancel) {
2283                         g_cancellable_cancel(register_cancel);
2284                         g_object_unref(register_cancel);
2285                 }
2286                 register_cancel = g_cancellable_new();
2287
2288                 g_dbus_proxy_call(proxy, "RegisterApplication",
2289                                 g_variant_new("(oa{sv})", app_path, NULL),
2290                                 G_DBUS_CALL_FLAGS_NONE, -1, register_cancel,
2291                                 (GAsyncReadyCallback)register_application_cb, NULL);
2292
2293                 is_server_started = true;
2294
2295                 return BLUETOOTH_ERROR_NONE;
2296         }
2297
2298         BT_INFO("Already RegisterApplication");
2299
2300         return BLUETOOTH_ERROR_NONE;
2301 }
2302
2303 BT_EXPORT_API int bluetooth_gatt_delete_services(void)
2304 {
2305         GSList *l;
2306         int ret = BLUETOOTH_ERROR_NONE;
2307
2308         if (gatt_services == NULL) {
2309                 BT_DBG("There are no registered services");
2310                 serv_id = 1;
2311                 return ret;
2312         }
2313
2314         for (l = gatt_services; l != NULL; ) {
2315                 struct gatt_service_info *info = l->data;
2316
2317                 // In __bt_gatt_unregister_service, current node will be removed.
2318                 // Go forward to next node before calling __bt_gatt_unregister_service.
2319                 l = l->next;
2320                 if (__bt_gatt_unregister_service(info) != BLUETOOTH_ERROR_NONE) {
2321                         ret = BLUETOOTH_ERROR_INTERNAL;
2322                 }
2323         }
2324         BT_INFO("All services are removed : %d", ret);
2325
2326         g_slist_free(gatt_services);
2327         gatt_services = NULL;
2328         serv_id = 1;
2329
2330         return ret;
2331 }
2332
2333 BT_EXPORT_API int bluetooth_gatt_update_characteristic(
2334                         const char *char_path, const char* char_value,
2335                         int value_length)
2336 {
2337         GVariantBuilder *outer_builder;
2338         GVariantBuilder *inner_builder;
2339         GVariantBuilder *invalidated_builder;
2340         GVariant *update_value = NULL;
2341         GError *error = NULL;
2342         gboolean ret = FALSE;
2343         int err = BLUETOOTH_ERROR_NONE;
2344         int i = 0;
2345         gchar **line_argv = NULL;
2346         gchar *serv_path = NULL;
2347         const char *value = NULL;
2348
2349         line_argv = g_strsplit_set(char_path, "/", 0);
2350         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
2351
2352         if (!__bt_gatt_is_service_registered(serv_path)) {
2353                 BT_DBG("service not registered for this characteristic");
2354                 g_free(serv_path);
2355                 g_strfreev(line_argv);
2356                 return BLUETOOTH_ERROR_INTERNAL;
2357         }
2358
2359         outer_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2360         invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
2361
2362         inner_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
2363         for (i = 0; i < value_length; i++)
2364                 g_variant_builder_add(inner_builder, "y", char_value[i]);
2365
2366         update_value = g_variant_new("ay", inner_builder);
2367
2368         g_variant_builder_add(outer_builder, "{sv}", "Value",
2369                                         update_value);
2370
2371         BT_DBG("Updating characteristic value");
2372         ret = g_dbus_connection_emit_signal(g_conn, NULL,
2373                                         char_path,
2374                                         "org.freedesktop.DBus.Properties",
2375                                         "PropertiesChanged",
2376                                         g_variant_new("(sa{sv}as)",
2377                                         "org.bluez.GattCharacteristic1",
2378                                         outer_builder, invalidated_builder),
2379                                         &error);
2380
2381         if (!ret) {
2382                 if (error != NULL) {
2383                         BT_ERR("D-Bus API failure: errCode[%x], \
2384                                         message[%s]",
2385                                         error->code, error->message);
2386                         g_clear_error(&error);
2387                 }
2388                 err = BLUETOOTH_ERROR_INTERNAL;
2389         } else {
2390                 struct gatt_char_info *char_info = NULL;
2391
2392                 char_info = __bt_gatt_find_gatt_char_info(serv_path, char_path);
2393                 if (char_info == NULL) {
2394                         g_free(serv_path);
2395                         g_strfreev(line_argv);
2396                         g_variant_builder_unref(inner_builder);
2397                         g_variant_builder_unref(outer_builder);
2398                         g_variant_builder_unref(invalidated_builder);
2399
2400                         return BLUETOOTH_ERROR_INVALID_DATA;
2401                 }
2402
2403                 char_info->value_length = value_length;
2404
2405                 value = (char *)realloc(char_info->char_value, value_length);
2406                 if (value == NULL) {
2407                         g_free(serv_path);
2408                         g_strfreev(line_argv);
2409                         g_variant_builder_unref(inner_builder);
2410                         g_variant_builder_unref(outer_builder);
2411                         g_variant_builder_unref(invalidated_builder);
2412
2413                         return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
2414                 }
2415
2416                 char_info->char_value = (char*)value;
2417                 if (char_info->char_value) {
2418                         for (i = 0; i < value_length; i++)
2419                                 char_info->char_value[i] = char_value[i];
2420                 }
2421         }
2422
2423         g_free(serv_path);
2424         g_strfreev(line_argv);
2425         g_variant_builder_unref(inner_builder);
2426         g_variant_builder_unref(outer_builder);
2427         g_variant_builder_unref(invalidated_builder);
2428
2429         return err;
2430 }
2431
2432 static void __bt_gatt_free_descriptor_info(struct gatt_desc_info *desc_info)
2433 {
2434         int i;
2435
2436         if (!desc_info)
2437                 return;
2438
2439         g_free(desc_info->desc_path);
2440         g_free(desc_info->desc_uuid);
2441         g_free(desc_info->desc_value);
2442
2443         for (i = 0; i < desc_info->flags_length; i++)
2444                 g_free(desc_info->desc_flags[i]);
2445
2446         g_free(desc_info);
2447 }
2448
2449 static void __bt_gatt_free_characteristic_info(struct gatt_char_info *char_info)
2450 {
2451         int i;
2452
2453         if (!char_info)
2454                 return;
2455
2456         g_free(char_info->char_path);
2457         g_free(char_info->char_uuid);
2458         g_free(char_info->char_value);
2459
2460         for (i = 0; i < char_info->flags_length; i++)
2461                 g_free(char_info->char_flags[i]);
2462
2463         g_free(char_info);
2464 }
2465
2466 static void __bt_gatt_free_service_info(struct gatt_service_info *svc_info)
2467 {
2468         if (!svc_info)
2469                 return;
2470
2471         g_free(svc_info->serv_path);
2472         g_free(svc_info->service_uuid);
2473         g_free(svc_info);
2474 }
2475
2476 static void __desc_info_free(gpointer data, gpointer user_data)
2477 {
2478         struct gatt_desc_info *desc_info = data;
2479         int *err = user_data;
2480         int ret;
2481
2482         if (desc_info == NULL)
2483                 return;
2484
2485         ret = g_dbus_connection_unregister_object(g_conn, desc_info->desc_id);
2486         if (ret) {
2487                 __bt_gatt_emit_interface_removed(desc_info->desc_path, GATT_DESC_INTERFACE);
2488         } else {
2489                 *err = BLUETOOTH_ERROR_INTERNAL;
2490         }
2491         __bt_gatt_free_descriptor_info(desc_info);
2492 }
2493
2494 static void __char_info_free(gpointer data, gpointer user_data)
2495 {
2496         struct gatt_char_info *char_info = data;
2497         int *err = user_data;
2498         int ret;
2499
2500         if (char_info == NULL)
2501                 return;
2502
2503         g_slist_foreach(char_info->desc_data, __desc_info_free, user_data);
2504         g_slist_free(char_info->desc_data);
2505         char_info->desc_data = NULL;
2506
2507         ret = g_dbus_connection_unregister_object(g_conn, char_info->char_id);
2508         if (ret) {
2509                 __bt_gatt_emit_interface_removed(char_info->char_path, GATT_CHAR_INTERFACE);
2510         } else {
2511                 *err = BLUETOOTH_ERROR_INTERNAL;
2512         }
2513         __bt_gatt_free_characteristic_info(char_info);
2514 }
2515
2516 static int __bt_gatt_unregister_service(struct gatt_service_info *svc_info)
2517 {
2518         int ret = BLUETOOTH_ERROR_NONE;
2519
2520         if (svc_info == NULL) {
2521                 BT_ERR("svc_info is NULL");
2522                 return BLUETOOTH_ERROR_NOT_FOUND;
2523         }
2524
2525         if (svc_info->is_svc_registered == FALSE) {
2526                 BT_ERR("%s is not registered", svc_info->serv_path);
2527                 return BLUETOOTH_ERROR_NOT_FOUND;
2528         }
2529
2530         BT_DBG("svc_path %s", svc_info->serv_path);
2531
2532         g_slist_foreach(svc_info->char_data, __char_info_free, &ret);
2533         g_slist_free(svc_info->char_data);
2534         svc_info->char_data = NULL;
2535
2536         if (g_dbus_connection_unregister_object(g_conn, svc_info->serv_id) == FALSE) {
2537                 BT_ERR("Cannot unregister object for [%s]", svc_info->serv_path);
2538                 ret = BLUETOOTH_ERROR_INTERNAL;
2539         } else {
2540                 __bt_gatt_emit_interface_removed(svc_info->serv_path, GATT_SERV_INTERFACE);
2541         }
2542
2543         gatt_services = g_slist_remove(gatt_services, svc_info);
2544         __bt_gatt_free_service_info(svc_info);
2545
2546         new_service = FALSE;
2547
2548         if (gatt_services == NULL) {
2549                 serv_id = 1;
2550         } else if (gatt_services->next == NULL) {
2551                 serv_id--;
2552         }
2553
2554         return ret;
2555 }
2556
2557 BT_EXPORT_API int bluetooth_gatt_unregister_service(const char *svc_path)
2558 {
2559         struct gatt_service_info *svc_info;
2560         int ret = BLUETOOTH_ERROR_NONE;
2561
2562         BT_DBG("+");
2563
2564         svc_info = __bt_gatt_find_gatt_service_info(svc_path);
2565
2566         ret = __bt_gatt_unregister_service(svc_info);
2567         if (ret != BLUETOOTH_ERROR_NONE) {
2568                 BT_ERR("Could not unregister service [%s]", svc_path);
2569         }
2570
2571         BT_DBG("-");
2572         return ret;
2573 }
2574
2575 BT_EXPORT_API int bluetooth_gatt_send_response(int request_id, guint req_type,
2576                                         int resp_state, int offset, char *value, int value_length)
2577 {
2578         struct gatt_req_info *req_info = NULL;
2579
2580         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_GATT_SEND_RESPONSE)
2581                         == BLUETOOTH_ERROR_PERMISSION_DEINED) {
2582                 BT_ERR("Don't have aprivilege to use this API");
2583                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
2584         }
2585
2586         req_info = __bt_gatt_find_request_info(request_id);
2587         if (req_info == NULL) {
2588                 BT_ERR("Coundn't find request id [%d]", request_id);
2589                 return BLUETOOTH_ERROR_INTERNAL;
2590         }
2591
2592         if (resp_state != BLUETOOTH_ATT_ERROR_NONE) {
2593                 BT_ERR("resp_state is 0x%X", resp_state);
2594                 char err_msg[20] = { 0, };
2595                 g_snprintf(err_msg, sizeof(err_msg), "ATT error: 0x%02x", resp_state);
2596                 g_dbus_method_invocation_return_dbus_error(req_info->context,
2597                                                 "org.bluez.Error.Failed", err_msg);
2598
2599                 gatt_requests = g_slist_remove(gatt_requests, req_info);
2600
2601                 req_info->context = NULL;
2602                 if (req_info->attr_path)
2603                         g_free(req_info->attr_path);
2604                 if (req_info->svc_path)
2605                         g_free(req_info->svc_path);
2606                 g_free(req_info);
2607
2608                 return BLUETOOTH_ERROR_NONE;
2609         }
2610
2611         if (req_type == BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ) {
2612                 int i;
2613                 GVariantBuilder *inner_builder = NULL;
2614                 inner_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2615                 if (value_length > 0 && value != NULL) {
2616                         for (i = 0; i < value_length; i++)
2617                                 g_variant_builder_add(inner_builder, "y", value[i]);
2618                 }
2619                 g_dbus_method_invocation_return_value(req_info->context,
2620                                 g_variant_new("(ay)", inner_builder));
2621                 g_variant_builder_unref(inner_builder);
2622         } else {
2623                 g_dbus_method_invocation_return_value(req_info->context, NULL);
2624         }
2625         gatt_requests = g_slist_remove(gatt_requests, req_info);
2626
2627         req_info->context = NULL;
2628         if (req_info->attr_path)
2629                 g_free(req_info->attr_path);
2630         if (req_info->svc_path)
2631                 g_free(req_info->svc_path);
2632         g_free(req_info);
2633
2634         return BLUETOOTH_ERROR_NONE;
2635 }
2636
2637 BT_EXPORT_API int bluetooth_gatt_server_set_notification(const char *char_path,
2638                                                 bluetooth_device_address_t *unicast_address)
2639 {
2640         GVariantBuilder *outer_builder;
2641         GVariantBuilder *invalidated_builder;
2642         GError *error = NULL;
2643         gboolean notify = TRUE;
2644         gboolean ret = TRUE;
2645         int err = BLUETOOTH_ERROR_NONE;
2646         gchar **line_argv = NULL;
2647         gchar *serv_path = NULL;
2648         char addr[20] = { 0 };
2649
2650         line_argv = g_strsplit_set(char_path, "/", 0);
2651         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
2652
2653         if (!__bt_gatt_is_service_registered(serv_path)) {
2654                 BT_DBG("service not registered for this characteristic");
2655                 g_free(serv_path);
2656                 g_strfreev(line_argv);
2657                 return BLUETOOTH_ERROR_INTERNAL;
2658         }
2659
2660         g_free(serv_path);
2661
2662         outer_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2663         invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
2664
2665         g_variant_builder_add(outer_builder, "{sv}", "Notifying",
2666                                         g_variant_new("b", notify));
2667
2668         if (unicast_address) {
2669                 _bt_convert_addr_type_to_string(addr,
2670                                         (unsigned char *)unicast_address->addr);
2671         }
2672         g_variant_builder_add(outer_builder, "{sv}", "Unicast",
2673                                 g_variant_new("s", addr));
2674
2675         BT_DBG("Set characteristic Notification");
2676         ret = g_dbus_connection_emit_signal(g_conn, NULL,
2677                                         char_path,
2678                                         "org.freedesktop.DBus.Properties",
2679                                         "PropertiesChanged",
2680                                         g_variant_new("(sa{sv}as)",
2681                                         "org.bluez.GattCharacteristic1",
2682                                         outer_builder, invalidated_builder),
2683                                         &error);
2684
2685         if (!ret) {
2686                 if (error != NULL) {
2687                         BT_ERR("D-Bus API failure: errCode[%x], \
2688                                         message[%s]",
2689                                         error->code, error->message);
2690                         g_clear_error(&error);
2691                 }
2692                 err = BLUETOOTH_ERROR_INTERNAL;
2693         }
2694
2695         g_strfreev(line_argv);
2696         g_variant_builder_unref(outer_builder);
2697         g_variant_builder_unref(invalidated_builder);
2698
2699         return err;
2700 }
2701
2702 BT_EXPORT_API int bluetooth_gatt_server_init(int *instance_id, gatt_server_cb_func_ptr callback_ptr,
2703                                                 void *user_data)
2704 {
2705         int ret = BLUETOOTH_ERROR_NONE;
2706
2707         BT_INIT_PARAMS();
2708         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2709
2710         /* Register event handler for GATT */
2711         ret = _bt_register_event(BT_GATT_SERVER_EVENT, (void *)callback_ptr, user_data);
2712
2713         if (ret != BLUETOOTH_ERROR_NONE &&
2714                         ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
2715                 BT_ERR("Fail to init the event handler");
2716                 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2717                 goto done;
2718         }
2719
2720         ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_REGISTER,
2721                         in_param1, in_param2, in_param3, in_param4, &out_param);
2722
2723         /* App ID -1 is invalid */
2724         if (ret != BLUETOOTH_ERROR_NONE) {
2725                 BT_INFO("GATT Server Registration failed result [%d]", ret);
2726                 *instance_id = -1;
2727         } else {
2728                 *instance_id = g_array_index(out_param, int, 0);
2729                 BT_INFO("GATT Server Registered successfully: App Instance ID [%d]", *instance_id);
2730         }
2731
2732 done:
2733         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2734
2735         BT_INFO("GATT Server instance ID obtained [%d]", *instance_id);
2736         return ret;
2737 }
2738
2739 BT_EXPORT_API int bluetooth_gatt_server_deinit(void)
2740 {
2741         int ret;
2742         BT_INFO("GATT Server Deinitialize");
2743         /* Unregister the event */
2744         ret = _bt_unregister_event(BT_GATT_SERVER_EVENT);
2745
2746         if (ret != BLUETOOTH_ERROR_NONE) {
2747                 BT_ERR("Fail to deinit the event handler");
2748                 return ret;
2749         }
2750
2751         _bt_set_user_data(BT_GATT_SERVER, NULL, NULL);
2752
2753         return ret;
2754 }
2755
2756 BT_EXPORT_API int bluetooth_gatt_server_add_service(const char *svc_uuid, int type, int numhandles,
2757                 int instance_id, int *service_handle)
2758 {
2759         BT_CHECK_ENABLED(return);
2760         BT_CHECK_PARAMETER(svc_uuid, return);
2761
2762         int result;
2763         char uuid[BT_GATT_ATT_UUID_LEN_MAX + 1];
2764
2765         g_strlcpy(uuid, svc_uuid, sizeof(uuid));
2766
2767         BT_INIT_PARAMS();
2768         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2769
2770         g_array_append_vals(in_param1, &type, sizeof(int));
2771         g_array_append_vals(in_param2, &numhandles, sizeof(int));
2772         g_array_append_vals(in_param3, uuid, BT_GATT_ATT_UUID_LEN_MAX + 1);
2773         g_array_append_vals(in_param4, &instance_id, sizeof(int));
2774
2775         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_ADD_SERVICE,
2776                         in_param1, in_param2, in_param3, in_param4, &out_param);
2777
2778         /* ATT handle 0 is reserved, hence it can not be used by app.
2779            It will be used to indicate error in regsitering attribute */
2780         if (result != BLUETOOTH_ERROR_NONE)
2781                 *service_handle = 0;
2782         else
2783                 *service_handle = g_array_index(out_param, int, 0);
2784
2785         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2786
2787         return result;
2788 }
2789
2790 BT_EXPORT_API int bluetooth_gatt_server_add_new_characteristic(const char *char_uuid,
2791                 const bluetooth_gatt_server_attribute_params_t *param,
2792                                                 int *char_handle)
2793 {
2794         BT_CHECK_ENABLED(return);
2795         BT_CHECK_PARAMETER(char_uuid, return);
2796         BT_CHECK_PARAMETER(param, return);
2797
2798         int result;
2799         char uuid[BT_GATT_ATT_UUID_LEN_MAX + 1];
2800
2801         g_strlcpy(uuid, char_uuid, sizeof(uuid));
2802
2803         BT_INIT_PARAMS();
2804         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2805
2806         g_array_append_vals(in_param1, param, sizeof(bluetooth_gatt_server_attribute_params_t));
2807         g_array_append_vals(in_param2, uuid, BT_GATT_ATT_UUID_LEN_MAX + 1);
2808
2809         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_ADD_CHARACTERISTIC,
2810                         in_param1, in_param2, in_param3, in_param4, &out_param);
2811
2812         /* ATT handle 0 is reserved, hence it can not be used by app.
2813            It will be used to indicate error in regsitering attribute */
2814         if (result != BLUETOOTH_ERROR_NONE) {
2815                 BT_ERR("GATT Server Add characteristic failed.. result [%d]", result);
2816                 *char_handle = 0;
2817         } else {
2818                 *char_handle = g_array_index(out_param, int, 0);
2819                 BT_DBG("GATT Server Add characteristic success result [%d] char chandle [%d]", result, *char_handle);
2820         }
2821
2822         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2823         return result;
2824 }
2825
2826 BT_EXPORT_API int bluetooth_gatt_server_add_descriptor(const char *desc_uuid, bt_gatt_permission_t permissions,
2827                 int service_handle, int instance_id, int *descriptor_handle)
2828 {
2829         BT_CHECK_ENABLED(return);
2830         BT_CHECK_PARAMETER(desc_uuid, return);
2831
2832         int result;
2833         char uuid[BT_GATT_ATT_UUID_LEN_MAX + 1];
2834
2835         g_strlcpy(uuid, desc_uuid, sizeof(uuid));
2836
2837         BT_INIT_PARAMS();
2838         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2839
2840         g_array_append_vals(in_param1, &service_handle, sizeof(int));
2841         g_array_append_vals(in_param2, &instance_id, sizeof(int));
2842         g_array_append_vals(in_param3, &permissions, sizeof(bt_gatt_permission_t));
2843         g_array_append_vals(in_param4, uuid, BT_GATT_ATT_UUID_LEN_MAX + 1);
2844
2845         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_ADD_DESCRIPTOR,
2846                         in_param1, in_param2, in_param3, in_param4, &out_param);
2847
2848         /* ATT handle 0 is reserved, hence it can not be used by app.
2849            It will be used to indicate error in regsitering attribute */
2850         if (result != BLUETOOTH_ERROR_NONE) {
2851                 BT_ERR("GATT Server Add Descriptor failed.. result [%d] desc handle [%d]", result, *descriptor_handle);
2852                 *descriptor_handle = 0;
2853         } else {
2854                 *descriptor_handle = g_array_index(out_param, int, 0);
2855                 BT_INFO("GATT Server Add Descriptor Successful.. result [%d] desc handle [%d]", result, *descriptor_handle);
2856         }
2857
2858         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2859
2860         return result;
2861 }
2862
2863 BT_EXPORT_API int bluetooth_gatt_server_start_service(int service_handle, int instance_id)
2864 {
2865         BT_CHECK_ENABLED(return);
2866         int result;
2867
2868         BT_INIT_PARAMS();
2869         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2870
2871         g_array_append_vals(in_param1, &service_handle, sizeof(int));
2872         g_array_append_vals(in_param2, &instance_id, sizeof(int));
2873
2874         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_START_SERVICE,
2875                         in_param1, in_param2, in_param3, in_param4, &out_param);
2876
2877         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2878
2879         return result;
2880 }
2881
2882 BT_EXPORT_API int bluetooth_gatt_server_send_response(const bluetooth_gatt_server_response_params_t *param,
2883                 const bluetooth_gatt_att_data_t *value)
2884 {
2885         BT_CHECK_PARAMETER(param, return);
2886         BT_CHECK_PARAMETER(value, return);
2887         BT_CHECK_ENABLED(return);
2888         int result;
2889
2890         BT_INIT_PARAMS();
2891         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2892
2893         g_array_append_vals(in_param1, value, sizeof(bluetooth_gatt_att_data_t));
2894         g_array_append_vals(in_param2, param, sizeof(bluetooth_gatt_server_response_params_t));
2895
2896         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_SEND_RESPONSE,
2897                         in_param1, in_param2, in_param3, in_param4, &out_param);
2898
2899         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2900
2901         return result;
2902
2903 }
2904
2905 BT_EXPORT_API int bluetooth_gatt_server_send_indication(bluetooth_device_address_t *addr_hex,
2906                 bluetooth_gatt_server_indication_params_t *param,
2907                 const bluetooth_gatt_att_data_t *att_value)
2908 {
2909         BT_CHECK_PARAMETER(param, return);
2910         BT_CHECK_PARAMETER(att_value, return);
2911         BT_CHECK_ENABLED(return);
2912         int result = 0 ;
2913         char addr[BLUETOOTH_ADDRESS_STRING_LENGTH] ;
2914         int fd = -1;
2915
2916         BT_INIT_PARAMS();
2917         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2918
2919         g_array_append_vals(in_param1, att_value, sizeof(bluetooth_gatt_att_data_t));
2920         g_array_append_vals(in_param2, param, sizeof(bluetooth_gatt_server_indication_params_t));
2921         g_array_append_vals(in_param3, addr_hex, sizeof(bluetooth_device_address_t));
2922
2923         _bt_convert_addr_type_to_string(addr, addr_hex->addr);
2924         BT_INFO("Send Indication to address [%s]", addr);
2925         fd =  bluetooth_get_characteristic_fd(param->atrribute_handle, addr);
2926
2927         if (fd > -1) {
2928                 BT_INFO("Acquire Notify FD found: Send Multicast Indication over Socket");
2929                 result  = bluetooth_gatt_write_characteristics_value_to_fd_(fd, att_value->data, att_value->length, NULL);
2930                 param->fd = fd;
2931         } else {
2932                 BT_ERR("Acquire Notify FD not found for charatcristic handle: Send DBUS indication");
2933                 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_SEND_INDICATION,
2934                                 in_param1, in_param2, in_param3, in_param4, &out_param);
2935         }
2936
2937         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2938
2939         return result;
2940 }
2941
2942 BT_EXPORT_API int bluetooth_gatt_server_stop_service(int service_handle, int instance_id)
2943 {
2944         BT_CHECK_ENABLED(return);
2945         int result;
2946
2947         BT_INIT_PARAMS();
2948         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2949
2950         g_array_append_vals(in_param1, &service_handle, sizeof(int));
2951         g_array_append_vals(in_param2, &instance_id, sizeof(int));
2952
2953         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_STOP_SERVICE,
2954                         in_param1, in_param2, in_param3, in_param4, &out_param);
2955
2956         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2957
2958         return result;
2959 }
2960
2961 BT_EXPORT_API int bluetooth_gatt_server_delete_service(int service_handle, int instance_id)
2962 {
2963         BT_CHECK_ENABLED(return);
2964         int result;
2965
2966         BT_INIT_PARAMS();
2967         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2968
2969         g_array_append_vals(in_param1, &service_handle, sizeof(int));
2970         g_array_append_vals(in_param2, &instance_id, sizeof(int));
2971
2972         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_DELETE_SERVICE,
2973                         in_param1, in_param2, in_param3, in_param4, &out_param);
2974
2975         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2976
2977         return result;
2978 }
2979
2980 /* Tizen Platform Specific */
2981 BT_EXPORT_API int bluetooth_gatt_server_update_characteristic(int instance_id,
2982                                 const bluetooth_gatt_server_update_value_t *value)
2983 {
2984         BT_CHECK_ENABLED(return);
2985         BT_CHECK_PARAMETER(value, return);
2986         int result;
2987
2988         BT_INIT_PARAMS();
2989         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2990
2991         g_array_append_vals(in_param1, &instance_id, sizeof(int));
2992         g_array_append_vals(in_param2, value, sizeof(bluetooth_gatt_server_update_value_t));
2993
2994         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_UPDATE_VALUE,
2995                         in_param1, in_param2, in_param3, in_param4, &out_param);
2996
2997         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2998
2999         return result;
3000 }
3001
3002 BT_EXPORT_API int bluetooth_gatt_server_unregister(int instance_id)
3003 {
3004         BT_CHECK_ENABLED(return);
3005         int result;
3006
3007         BT_INIT_PARAMS();
3008         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
3009
3010         g_array_append_vals(in_param1, &instance_id, sizeof(int));
3011
3012         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_DEREGISTER,
3013                         in_param1, in_param2, in_param3, in_param4, &out_param);
3014
3015         if (result != BLUETOOTH_ERROR_NONE)
3016                 BT_INFO("GATT Server Unregistration failed result [%d]", result);
3017         else
3018                 BT_INFO("GATT Server Unregistration successful");
3019
3020         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
3021         return result;
3022 }
3023
3024
3025 static gboolean bluetooth_gatt_server_acquire_channel_write_cb(GIOChannel *gio,
3026                                         GIOCondition cond, gpointer data)
3027 {
3028
3029         bluetooth_gatt_server_acquire_write_info_t *write_data =  (bluetooth_gatt_server_acquire_write_info_t*)data;
3030
3031         BT_DBG("FD io write data  received [%s]", write_data->address);
3032
3033         if (cond & G_IO_NVAL) {
3034                 BT_ERR("Invalid channel");
3035                 return FALSE;
3036         }
3037
3038         if (cond & (G_IO_HUP | G_IO_ERR)) {
3039                 BT_ERR("Error : GIOCondition %d", cond);
3040                 g_io_channel_shutdown(gio, TRUE, NULL);
3041                 g_io_channel_unref(gio);
3042
3043                 return FALSE;
3044         }
3045
3046         if (cond & G_IO_IN) {
3047                 GIOStatus status = G_IO_STATUS_NORMAL;
3048                 GError *err = NULL;
3049                 char *buffer = NULL;
3050                 gsize len = 0;
3051                 int BUF = BLUETOOTH_GATT_ATT_DATA_LENGTH_MAX;
3052
3053                 buffer = g_malloc0(BUF);
3054
3055                 status = g_io_channel_read_chars(gio, buffer,
3056                                 BUF, &len, &err);
3057
3058                 if (status != G_IO_STATUS_NORMAL) {
3059                         BT_ERR("IO Channel read is failed with %d", status);
3060                         g_free(buffer);
3061                         if (err) {
3062                                 BT_ERR("IO Channel read error [%s]", err->message);
3063                                 if (status == G_IO_STATUS_ERROR) {
3064                                         BT_ERR("cond : %d", cond);
3065                                         g_error_free(err);
3066                                         g_io_channel_shutdown(gio, TRUE, NULL);
3067                                         g_io_channel_unref(gio);
3068
3069                                         return FALSE;
3070                                 }
3071                                 g_error_free(err);
3072                         }
3073                         return FALSE;
3074                 }
3075
3076                 if (len > 0) {
3077                         bluetooth_gatt_server_write_requested_info_t write_info;
3078                         if (len < BLUETOOTH_GATT_ATT_DATA_LENGTH_MAX)
3079                         memcpy(write_info.data.data, buffer, len);
3080
3081                         write_info.length = len;
3082                         write_info.need_resp = false;
3083                         write_info.attribute_handle = write_data->attribute_handle;
3084                         //memcpy()
3085                         _bt_convert_addr_string_to_type(write_info.device_address.addr,  write_data->address);
3086                         write_info.connection_id = write_data->connection_id;
3087                         write_info.offset = write_data->offset;
3088                         write_info.request_id = -2;
3089
3090                         bt_event_info_t *event_info;
3091                         event_info = _bt_event_get_cb_data(BT_GATT_SERVER_EVENT);
3092
3093                         if (event_info) {
3094
3095                                 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
3096                                                         BLUETOOTH_ERROR_NONE, &write_info,
3097                                                 event_info->cb, event_info->user_data);
3098                         } else {
3099                                 BT_ERR("eventinfo failed");
3100                         }
3101                 }
3102                 g_free(buffer);
3103
3104                 return TRUE;
3105         }
3106
3107         return TRUE;
3108 }
3109
3110 void  bluetooth_gatt_server_send_acquire_write_response(GVariant * parameters)
3111 {
3112         int con_id  =  -1;
3113         int tran_id  =  -1;
3114         int att_han  =  -1;
3115         int pipefd[2] = {-1,};
3116         int mtu  = -1;
3117         int offset  = -1;
3118         char err_msg[512] = {'\0'};
3119         GIOChannel *channel = NULL;
3120         char *addr = NULL;
3121         int result =  -1;
3122
3123         g_variant_get(parameters, "(iiiiii&s)",
3124                                         &result,
3125                                         &con_id,
3126                                         &tran_id,
3127                                         &att_han,
3128                                         &mtu,
3129                                         &offset,
3130                                         &addr);
3131
3132         BT_DBG("GATT Server  Acquire Write From Remote Client [%s]", addr);
3133         BT_DBG("GATT ServerAcquire  Conn ID:   [%d]", con_id);
3134         BT_DBG("GATT Server Acquire write  att handle:[%d]", att_han);
3135         BT_DBG("GATT Server Acquire Write Offset:    [%d]", offset);
3136
3137
3138         if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pipefd) < 0) {
3139                         strerror_r(errno, err_msg, sizeof(err_msg));
3140                         BT_ERR("socketpair(): %s", err_msg);
3141                         return ;
3142         }
3143
3144         BT_INIT_PARAMS();
3145         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
3146
3147         //param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
3148         bluetooth_gatt_server_acquire_response_params_t  data;
3149         data.req_type  = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_WRITE;
3150         data.fd = pipefd[1];
3151         data.mtu = mtu;
3152         data.request_id = tran_id;
3153
3154         bluetooth_gatt_server_acquire_write_info_t *write_info = g_malloc0(sizeof(bluetooth_gatt_server_acquire_write_info_t))  ;
3155
3156         write_info->attribute_handle = att_han;
3157         write_info->connection_id  = tran_id;
3158         write_info->offset = offset;
3159
3160          memcpy(write_info->address,  addr ,  BLUETOOTH_ADDRESS_STRING_LENGTH);
3161
3162         BT_INFO("FD read %d   remote address  [%s ] \n", pipefd[0], addr);
3163
3164         channel = g_io_channel_unix_new(pipefd[0]);
3165         g_io_channel_set_encoding(channel, NULL, NULL);
3166         g_io_channel_set_buffered(channel, FALSE);
3167         g_io_channel_set_close_on_unref(channel, TRUE);
3168         g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
3169         g_io_add_watch(channel, (G_IO_IN | G_IO_ERR | G_IO_HUP),
3170                         bluetooth_gatt_server_acquire_channel_write_cb, write_info);
3171
3172         GUnixFDList *fd_list = g_unix_fd_list_new();
3173         GError *error = NULL;
3174
3175         g_unix_fd_list_append(fd_list, pipefd[1], &error);
3176         g_assert_no_error(error);
3177         close(pipefd[1]);
3178
3179         g_array_append_vals(in_param1, &data, sizeof(bluetooth_gatt_server_acquire_response_params_t));
3180
3181         BT_INFO("Sending event BT_GATT_SERVER_ACQURE_WRITE_RESPONSE file descriptor value [%d] [ %s],", data.fd, addr);
3182
3183         result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_GATT_SERVER_ACQURE_WRITE_RESPONSE,
3184                         in_param1, in_param2, in_param3, in_param4, fd_list, &out_param, NULL);
3185
3186         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
3187         g_object_unref(fd_list);
3188 }
3189
3190 void  bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameters, bt_event_info_t *event_info)
3191 {
3192         int con_id  =  -1;
3193         int tran_id  =  -1;
3194         int att_han  =  -1;
3195         int pipefd[2] = {-1,};
3196         int mtu  = -1;
3197         int offset  = -1;
3198         char err_msg[512] = {'\0'};
3199         GIOChannel *channel = NULL;
3200         int result =  -1;
3201         int fd = -1;
3202         bluetooth_gatt_acquire_notify_info_t *chr_info;
3203         const char *address = NULL;
3204
3205         g_variant_get(parameters, "(iiiiii&s)",
3206                                         &result,
3207                                         &con_id,
3208                                         &tran_id,
3209                                         &att_han,
3210                                         &mtu,
3211                                         &offset,
3212                                         &address);
3213
3214                 BT_DBG("GATT ServerAcquire  Conn ID:   [%d]", con_id);
3215                 BT_DBG("GATT Server Acquire notify  att handle:[%d]", att_han);
3216                 BT_DBG("GATT Server Acquire Notify Offset:    [%d]", offset);
3217                 BT_DBG("GATT Server Acquire Notify address:    [%s]", address);
3218
3219
3220         if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd) < 0) {
3221                         strerror_r(errno, err_msg, sizeof(err_msg));
3222                         BT_ERR("socketpair(): %s", err_msg);
3223                         return ;
3224         }
3225
3226         fd = pipefd[0];
3227
3228         BT_INIT_PARAMS();
3229         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
3230
3231         //param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
3232         bluetooth_gatt_server_acquire_response_params_t  data;
3233         data.req_type  = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY;
3234         data.fd = pipefd[1];
3235         data.mtu = mtu;
3236         data.request_id = tran_id;
3237
3238         BT_INFO("FD write %d", pipefd[0]);
3239
3240         chr_info = bluetooth_get_characteristic_info_from_path(att_han);
3241         if (!chr_info) {
3242                 BT_INFO("char info not found for ATT handle [%u]", att_han);
3243                 chr_info = g_malloc0(sizeof(bluetooth_gatt_acquire_notify_info_t));
3244                 chr_info->write_fd = fd;
3245                 chr_info->att_hand = att_han;
3246                 memcpy(chr_info->address, address, BLUETOOTH_ADDRESS_STRING_LENGTH);
3247
3248                 gatt_characteristic_server_notify_list = g_slist_append(gatt_characteristic_server_notify_list, chr_info);
3249         } else {
3250                 BT_INFO("Already AcquireNotify Set for this attribute handle by remote Client [%s]", chr_info->address);
3251                 chr_info->write_fd = fd;
3252         }
3253
3254         channel = g_io_channel_unix_new(fd);
3255         chr_info->io_channel = channel;
3256         g_io_channel_set_encoding(channel, NULL, NULL);
3257         g_io_channel_set_buffered(channel, FALSE);
3258         g_io_channel_set_close_on_unref(channel, TRUE);
3259         g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
3260         chr_info->watch_id =
3261                 g_io_add_watch(channel,
3262                         (G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL),
3263                         bluetooth_gatt_write_channel_watch_cb, chr_info);
3264
3265         GUnixFDList *fd_list = g_unix_fd_list_new();
3266         GError *error = NULL;
3267
3268         g_unix_fd_list_append(fd_list, pipefd[1], &error);
3269         g_assert_no_error(error);
3270         close(pipefd[1]);
3271
3272         g_array_append_vals(in_param1, &data, sizeof(bluetooth_gatt_server_acquire_response_params_t));
3273
3274         BT_DBG("Sending event BT_GATT_SERVER_ACQUIRE_NOTIFY_RESPONSE file descriptor value [%d] ", data.fd);
3275
3276         result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_GATT_SERVER_ACQUIRE_NOTIFY_RESPONSE,
3277                         in_param1, in_param2, in_param3, in_param4, fd_list, &out_param, NULL);
3278
3279         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
3280         g_object_unref(fd_list);
3281
3282         //send
3283         if (result == BLUETOOTH_ERROR_NONE) {
3284                 BT_DBG("sending gatt server notification state changed event");
3285                 bluetooth_gatt_server_notification_changed_t info;
3286                 bluetooth_device_address_t dev_address = { {0} };
3287                 memset(&info, 0x00, sizeof(bluetooth_gatt_server_notification_changed_t));
3288
3289                 _bt_convert_addr_string_to_type(dev_address.addr, address);
3290                 memcpy(info.device_address.addr,
3291                                 dev_address.addr,
3292                                 BLUETOOTH_ADDRESS_LENGTH);
3293                 info.handle = att_han;
3294                 info.notification = TRUE;
3295
3296                 _bt_gatt_server_event_cb(BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
3297                                 result, &info,
3298                                 event_info->cb, event_info->user_data);
3299
3300         }
3301 }
3302
3303 void cleanup_gatt_acquire_fd(int handle)
3304 {
3305         bluetooth_gatt_acquire_notify_info_t *chr_info = NULL;
3306
3307         BT_INFO("+");
3308
3309         chr_info = bluetooth_get_characteristic_info_from_path(handle);
3310
3311         if (chr_info != NULL) {
3312                 BT_INFO("GATT Server: acquire notification char info found [%s]", chr_info->path);
3313
3314                 if (chr_info->watch_id > 0)
3315                         g_source_remove(chr_info->watch_id);
3316
3317                 if (chr_info->io_channel) {
3318                         g_io_channel_shutdown(chr_info->io_channel, TRUE, NULL);
3319                         g_io_channel_unref(chr_info->io_channel);
3320                 }
3321
3322                 BT_INFO("Removing char_info from the list");
3323                 gatt_characteristic_server_notify_list = g_slist_remove(gatt_characteristic_server_notify_list, chr_info);
3324                 bluetooth_characteristic_info_free(chr_info);
3325         }
3326 }