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