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