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