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