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