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