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