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