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