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