Fix memory leak and few cosmetic changes for static tools
[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
26 #include "bt-common.h"
27 #include "bt-internal-types.h"
28
29 #define NUMBER_OF_FLAGS 10
30
31 GDBusConnection *g_conn;
32 guint owner_id;
33 guint manager_id;
34 static gboolean new_service = FALSE;
35 static gboolean new_char = FALSE;
36 static int serv_id = 1;
37 static int register_pending_cnt = 0;
38 static bool is_server_started = false;
39
40 /* Introspection data for the service we are exporting */
41 static const gchar service_introspection_xml[] =
42 "<node name='/'>"
43 "  <interface name='org.freedesktop.DBus.Properties'>"
44 "    <property type='s' name='UUID' access='read'>"
45 "    </property>"
46 "        <property type='b' name='primary' access='read'>"
47 "        </property>"
48 "        <property type='o' name='Device' access='read'>"
49 "        </property>"
50 "        <property type='ao' name='Characteristics' access='read'>"
51 "        </property>"
52 "        <property type='s' name='Includes' access='read'>"
53 "        </property>"
54 "  </interface>"
55 "</node>";
56
57 /* Introspection data for the characteristics we are exporting */
58 static const gchar characteristics_introspection_xml[] =
59 "<node name='/'>"
60 "  <interface name='org.bluez.GattCharacteristic1'>"
61 "        <method name='ReadValue'>"
62 "               <arg type='s' name='address' direction='in'/>"
63 "               <arg type='u' name='id' direction='in'/>"
64 "               <arg type='q' name='offset' direction='in'/>"
65 "               <arg type='ay' name='Value' direction='out'/>"
66 "        </method>"
67 "        <method name='WriteValue'>"
68 "               <arg type='s' name='address' direction='in'/>"
69 "               <arg type='u' name='id' direction='in'/>"
70 "               <arg type='q' name='offset' direction='in'/>"
71 "               <arg type='b' name='response_needed' direction='in'/>"
72 "               <arg type='ay' name='value' direction='in'/>"
73 "        </method>"
74 "        <method name='StartNotify'>"
75 "        </method>"
76 "        <method name='StopNotify'>"
77 "        </method>"
78 "        <method name='IndicateConfirm'>"
79 "               <arg type='s' name='address' direction='in'/>"
80 "               <arg type='b' name='complete' direction='in'/>"
81 "        </method>"
82 "  </interface>"
83 "  <interface name='org.freedesktop.DBus.Properties'>"
84 "    <property type='s' name='UUID' access='read'>"
85 "    </property>"
86 "    <property type='o' name='Service' access='read'>"
87 "    </property>"
88 "    <property type='ay' name='Value' access='readwrite'>"
89 "    </property>"
90 "        <property type='b' name='Notifying' access='read'>"
91 "        </property>"
92 "    <property type='as' name='Flags' access='read'>"
93 "    </property>"
94 "    <property type='s' name='Unicast' access='read'>"
95 "    </property>"
96 "        <property type='ao' name='Descriptors' access='read'>"
97 "        </property>"
98 "  </interface>"
99 "</node>";
100
101 /* Introspection data for the descriptor we are exporting */
102 static const gchar descriptor_introspection_xml[] =
103 "<node name='/'>"
104 "  <interface name='org.bluez.GattDescriptor1'>"
105 "        <method name='ReadValue'>"
106 "               <arg type='s' name='address' direction='in'/>"
107 "               <arg type='u' name='id' direction='in'/>"
108 "               <arg type='q' name='offset' direction='in'/>"
109 "               <arg type='ay' name='Value' direction='out'/>"
110 "        </method>"
111 "        <method name='WriteValue'>"
112 "               <arg type='s' name='address' direction='in'/>"
113 "               <arg type='u' name='id' direction='in'/>"
114 "               <arg type='q' name='offset' direction='in'/>"
115 "               <arg type='b' name='response_needed' direction='in'/>"
116 "               <arg type='ay' name='value' direction='in'/>"
117 "        </method>"
118 "  </interface>"
119 "  <interface name='org.freedesktop.DBus.Properties'>"
120 "    <property type='s' name='UUID' access='read'>"
121 "    </property>"
122 "    <property type='o' name='Characteristic' access='read'>"
123 "    </property>"
124 "    <property type='ay' name='Value' access='read'>"
125 "    </property>"
126 "    <property type='as' name='Flags' access='read'>"
127 "    </property>"
128 "  </interface>"
129 "</node>";
130
131 static const gchar manager_introspection_xml[] =
132 "<node name='/'>"
133 "  <interface name='org.freedesktop.DBus.ObjectManager'>"
134 "    <method name='GetManagedObjects'>"
135 "     <arg type='a{oa{sa{sv}}}' name='object_paths_interfaces_and_properties' direction='out'/>"
136 "        </method>"
137 "  </interface>"
138 "</node>";
139
140 struct gatt_service_info {
141         gchar *serv_path;
142         guint serv_id;
143         gchar *service_uuid;
144         guint manager_id;
145         guint prop_id;
146         GSList *char_data;
147         gboolean is_svc_registered;
148         gboolean is_svc_primary;
149 };
150
151 struct gatt_char_info {
152         gchar *char_path;
153         guint char_id;
154         gchar *char_uuid;
155         gchar *char_value;
156         gchar *char_flags[NUMBER_OF_FLAGS];
157         int value_length;
158         int flags_length;
159         GSList *desc_data;
160 };
161
162 struct gatt_desc_info {
163         gchar *desc_path;
164         guint desc_id;
165         gchar *desc_uuid;
166         gchar *desc_value;
167         gchar *desc_flags[NUMBER_OF_FLAGS];
168         int value_length;
169         int flags_length;
170 };
171
172 struct gatt_req_info {
173         gchar *attr_path;
174         gchar *svc_path;
175         guint  request_id;
176         guint  offset;
177         GDBusMethodInvocation *context;
178 };
179
180 static GSList *gatt_services = NULL;
181 static GSList *gatt_requests = NULL;
182 static gchar *app_path = NULL;
183
184 #define BT_GATT_SERVICE_NAME    "org.frwk.gatt_service"
185 #define BT_GATT_SERVICE_PATH "/org/frwk/gatt_service"
186
187 #define GATT_SERV_OBJECT_PATH   "/service"
188
189 #define GATT_MNGR_INTERFACE             "org.bluez.GattManager1"
190 #define GATT_SERV_INTERFACE             "org.bluez.GattService1"
191 #define GATT_CHAR_INTERFACE             "org.bluez.GattCharacteristic1"
192 #define GATT_DESC_INTERFACE             "org.bluez.GattDescriptor1"
193
194 #ifdef TIZEN_FEATURE_BT_HPS
195 #define BT_HPS_OBJECT_PATH "/org/projectx/httpproxy"
196 #define BT_HPS_INTERFACE_NAME "org.projectx.httpproxy_service"
197 #define PROPERTIES_CHANGED "PropertiesChanged"
198 #define BT_HPS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
199 #endif
200
201 static GDBusProxy *manager_gproxy = NULL;
202
203 static struct gatt_char_info *__bt_gatt_find_gatt_char_info(
204                         const char *service_path, const char *char_path);
205 static struct gatt_desc_info *__bt_gatt_find_gatt_desc_info(
206                         const char *serv_path, const char *char_path,
207                         const char *desc_path);
208
209 static struct gatt_req_info *__bt_gatt_find_request_info(guint request_id);
210
211 static void __bt_gatt_close_gdbus_connection(void)
212 {
213         GError *err = NULL;
214
215         BT_DBG("+");
216
217         ret_if(g_conn == NULL);
218
219         if (!g_dbus_connection_flush_sync(g_conn, NULL, &err)) {
220                 BT_ERR("Fail to flush the connection: %s", err->message);
221                 g_error_free(err);
222                 err = NULL;
223         }
224
225         if (!g_dbus_connection_close_sync(g_conn, NULL, &err)) {
226                 if (err) {
227                         BT_ERR("Fail to close the dbus connection: %s", err->message);
228                         g_error_free(err);
229                 }
230         }
231
232         g_object_unref(g_conn);
233
234         g_conn = NULL;
235
236         BT_DBG("-");
237 }
238
239 #ifdef TIZEN_FEATURE_BT_HPS
240 static int __bt_send_event_to_hps(int event, GVariant *var)
241 {
242         GError *error = NULL;
243         GVariant *parameters;
244         GDBusMessage *msg = NULL;
245
246         BT_DBG(" ");
247
248         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
249
250         if (event == BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED) {
251                 GVariantBuilder *inner_builder;
252                 GVariantBuilder *invalidated_builder;
253
254                 BT_DBG("BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED");
255                 inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
256
257                 g_variant_builder_add(inner_builder, "{sv}", "WriteValue", var);
258
259                 invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
260
261                 parameters = g_variant_new("(a{sv}as)", inner_builder, invalidated_builder);
262                 g_variant_builder_unref(invalidated_builder);
263                 g_variant_builder_unref(inner_builder);
264         } else if (event == BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED) {
265                 GVariantBuilder *inner_builder;
266                 GVariantBuilder *invalidated_builder;
267
268                 BT_DBG("BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED");
269                 inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
270
271                 g_variant_builder_add(inner_builder, "{sv}", "ReadValue", var);
272
273                 invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
274
275                 parameters = g_variant_new("(a{sv}as)", inner_builder, invalidated_builder);
276                 g_variant_builder_unref(invalidated_builder);
277                 g_variant_builder_unref(inner_builder);
278         } else {
279                 g_varaiant_unref(var);
280         }
281
282         msg = g_dbus_message_new_signal(BT_HPS_OBJECT_PATH, BT_HPS_INTERFACE_NAME, PROPERTIES_CHANGED);
283         g_dbus_message_set_body(msg, parameters);
284         if (!g_dbus_connection_send_message(g_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 0, NULL)) {
285                 if (error != NULL) {
286                         BT_ERR("D-Bus API failure: errCode[%x], \
287                                         message[%s]",
288                                         error->code, error->message);
289                         g_clear_error(&error);
290                 }
291                 return BLUETOOTH_ERROR_INTERNAL;
292         }
293         return BLUETOOTH_ERROR_NONE;
294 }
295 #endif
296
297 static void __bt_gatt_manager_method_call(GDBusConnection *connection,
298                                         const gchar *sender,
299                                         const gchar *object_path,
300                                         const gchar *interface_name,
301                                         const gchar *method_name,
302                                         GVariant *parameters,
303                                         GDBusMethodInvocation *invocation,
304                                         gpointer user_data)
305 {
306         GSList *l1 = NULL;
307         int len = 0;
308         int i = 0;
309
310         if (g_strcmp0(method_name, "GetManagedObjects") == 0) {
311                 BT_DBG("Getting values for service, chars and descriptors");
312
313                 GVariantBuilder *builder;
314                 GVariantBuilder *inner_builder1 = NULL;
315                 GVariant *svc_char = NULL;
316                 GSList *l4;
317                 /*Main Builder */
318                 builder = g_variant_builder_new(
319                                 G_VARIANT_TYPE("a{oa{sa{sv}}}"));
320
321                 /* Prepare inner builder for GattService1 interface */
322
323                 len = g_slist_length(gatt_services);
324
325                 for (i = 0; i <= len; i++) {
326                         GVariantBuilder *svc_builder = NULL;
327                         GVariantBuilder *inner_builder = NULL;
328
329                         if (register_pending_cnt > 1)
330                                 l1 = g_slist_nth(gatt_services, len - register_pending_cnt);
331                         else
332                                 l1 = g_slist_last(gatt_services);
333
334                         register_pending_cnt--;
335
336                         if (l1 == NULL) {
337                                 BT_ERR("gatt service list is NULL");
338                                 g_dbus_method_invocation_return_value(invocation, NULL);
339                                 return;
340                         }
341
342                         struct gatt_service_info *serv_info = l1->data;
343                         if (serv_info == NULL) {
344                                 BT_ERR("service info value is NULL");
345                                 g_dbus_method_invocation_return_value(invocation, NULL);
346                                 return;
347                         }
348
349                         /* Prepare inner builder for GattService1 interface */
350                         BT_DBG("Creating builder for service");
351                         svc_builder = g_variant_builder_new(
352                                                 G_VARIANT_TYPE("a{sa{sv}}"));
353                         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
354
355                         g_variant_builder_add(inner_builder, "{sv}", "UUID",
356                                         g_variant_new_string(serv_info->service_uuid));
357
358                         g_variant_builder_add(inner_builder, "{sv}", "Primary",
359                                         g_variant_new_boolean(serv_info->is_svc_primary));
360
361                         /*Characteristics*/
362                         inner_builder1 = g_variant_builder_new(G_VARIANT_TYPE("ao"));
363                         BT_DBG("Adding Charatarisitcs list");
364                         for (l4 = serv_info->char_data; l4 != NULL; l4 = l4->next) {
365                                 struct gatt_char_info *char_info = l4->data;
366                                         g_variant_builder_add(inner_builder1, "o",
367                                                 char_info->char_path);
368                                         BT_DBG("%s", char_info->char_path);
369                         }
370
371                         svc_char = g_variant_new("ao", inner_builder1);
372                         g_variant_builder_add(inner_builder, "{sv}", "Characteristics",
373                                                 svc_char);
374
375                         g_variant_builder_add(svc_builder, "{sa{sv}}",
376                                                                 GATT_SERV_INTERFACE,
377                                                                 inner_builder);
378
379                         g_variant_builder_add(builder, "{oa{sa{sv}}}",
380                                                                 serv_info->serv_path,
381                                                                 svc_builder);
382
383                         g_variant_builder_unref(inner_builder1);
384
385                         /* Prepare inner builder for GattCharacteristic1 interface */
386
387                         GSList *l2 = serv_info->char_data;
388                         BT_DBG("Creating builder for characteristics \n");
389
390                         if (l2 == NULL)
391                                 BT_DBG("characteristic data is NULL");
392
393                         for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
394
395                                 GVariantBuilder *char_builder = NULL;
396                                 GVariantBuilder *inner_builder = NULL;
397                                 GVariantBuilder *builder1 = NULL;
398                                 GVariantBuilder *builder2 = NULL;
399                                 GVariantBuilder *builder3 = NULL;
400                                 GVariant *char_val = NULL;
401                                 GVariant *flags_val = NULL;
402                                 GVariant *char_desc = NULL;
403                                 char *unicast = NULL;
404                                 gboolean notify = FALSE;
405                                 int i = 0;
406
407                                 char_builder = g_variant_builder_new(
408                                                                 G_VARIANT_TYPE(
409                                                                         "a{sa{sv}}"));
410                                 inner_builder = g_variant_builder_new(
411                                                                 G_VARIANT_TYPE(
412                                                                         "a{sv}"));
413
414                                 struct gatt_char_info *char_info = l2->data;
415                                 if (char_info == NULL) {
416                                         BT_ERR("char_info is NULL");
417                                         continue;
418                                 }
419
420                                 /*Uuid*/
421                                 g_variant_builder_add(inner_builder, "{sv}", "UUID",
422                                         g_variant_new_string(char_info->char_uuid));
423                                 /*Service*/
424                                 g_variant_builder_add(inner_builder, "{sv}", "Service",
425                                         g_variant_new("o", serv_info->serv_path));
426                                 /*Value*/
427                                 builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
428
429                                 if (char_info->char_value != NULL) {
430                                         for (i = 0; i < char_info->value_length; i++) {
431                                                 g_variant_builder_add(builder1, "y",
432                                                         char_info->char_value[i]);
433                                         }
434                                         char_val = g_variant_new("ay", builder1);
435                                         g_variant_builder_add(inner_builder, "{sv}",
436                                                         "Value", char_val);
437                                 }
438                                 /*Flags*/
439                                 builder2 = g_variant_builder_new(G_VARIANT_TYPE("as"));
440
441                                 for (i = 0; i < char_info->flags_length; i++) {
442                                         g_variant_builder_add(builder2, "s",
443                                                 char_info->char_flags[i]);
444                                 }
445
446                                 flags_val = g_variant_new("as", builder2);
447                                 g_variant_builder_add(inner_builder, "{sv}", "Flags",
448                                                         flags_val);
449
450                                 /* Notifying */
451                                 g_variant_builder_add(inner_builder, "{sv}", "Notifying",
452                                                         g_variant_new("b", notify));
453
454                                 /* Unicast */
455                                 unicast = g_strdup("00:00:00:00:00:00");
456                                 g_variant_builder_add(inner_builder, "{sv}", "Unicast",
457                                                         g_variant_new("s", unicast));
458
459                                 /*Descriptors*/
460                                 builder3 = g_variant_builder_new(G_VARIANT_TYPE("ao"));
461                                 BT_DBG("Adding Descriptors list");
462
463                                 for (l4 = char_info->desc_data; l4 != NULL; l4 = l4->next) {
464                                         struct gatt_desc_info *desc_info = l4->data;
465                                                 g_variant_builder_add(builder3, "o",
466                                                         desc_info->desc_path);
467                                                 BT_DBG("%s", desc_info->desc_path);
468                                 }
469
470                                 char_desc = g_variant_new("ao", builder3);
471                                 g_variant_builder_add(inner_builder, "{sv}", "Descriptors",
472                                                         char_desc);
473
474                                 g_variant_builder_add(char_builder, "{sa{sv}}",
475                                                 GATT_CHAR_INTERFACE , inner_builder);
476                                 g_variant_builder_add(builder, "{oa{sa{sv}}}",
477                                                 char_info->char_path, char_builder);
478
479                                 /*Prepare inner builder for GattDescriptor1 interface*/
480
481                                 GSList *l3 = char_info->desc_data;
482
483                                 if (l3 == NULL)
484                                         BT_DBG("descriptor data is NULL");
485
486                                 for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) {
487
488                                         BT_DBG("Creating builder for descriptor \n");
489
490                                         GVariantBuilder *desc_builder = NULL;
491                                         GVariantBuilder *inner_builder = NULL;
492                                         GVariantBuilder *builder1 = NULL;
493                                         GVariantBuilder *builder2 = NULL;
494                                         GVariant *desc_val = NULL;
495
496                                         desc_builder = g_variant_builder_new(
497                                                                 G_VARIANT_TYPE(
498                                                                 "a{sa{sv}}"));
499                                         inner_builder = g_variant_builder_new(
500                                                                 G_VARIANT_TYPE(
501                                                                 "a{sv}"));
502
503                                         struct gatt_desc_info *desc_info = l3->data;
504                                         if (desc_info == NULL) {
505                                                 BT_ERR("desc_info is NULL");
506                                                 continue;
507                                         }
508
509                                         /*Uuid*/
510                                         g_variant_builder_add(inner_builder,
511                                                 "{sv}", "UUID",
512                                                 g_variant_new_string(
513                                                         desc_info->desc_uuid));
514
515                                         /*Characteristic*/
516                                         g_variant_builder_add(inner_builder, "{sv}",
517                                                 "Characteristic",
518                                                 g_variant_new("o",
519                                                         char_info->char_path));
520
521                                         /*Value*/
522                                         builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
523
524                                         if (desc_info->desc_value != NULL) {
525                                                 for (i = 0; i < desc_info->value_length; i++) {
526                                                         g_variant_builder_add(builder1, "y",
527                                                                 desc_info->desc_value[i]);
528                                                 }
529                                                 desc_val = g_variant_new("ay", builder1);
530                                                 g_variant_builder_add(inner_builder, "{sv}",
531                                                                 "Value", desc_val);
532                                         }
533
534                                         /*Flags*/
535                                         builder2 = g_variant_builder_new(G_VARIANT_TYPE("as"));
536
537                                         for (i = 0; i < desc_info->flags_length; i++) {
538                                                 g_variant_builder_add(builder2, "s",
539                                                         desc_info->desc_flags[i]);
540                                         }
541
542                                         flags_val = g_variant_new("as", builder2);
543                                         g_variant_builder_add(inner_builder, "{sv}", "Flags",
544                                                                 flags_val);
545
546                                         g_variant_builder_add(desc_builder, "{sa{sv}}",
547                                                         GATT_DESC_INTERFACE,
548                                                         inner_builder);
549
550                                         g_variant_builder_add(builder, "{oa{sa{sv}}}",
551                                                         desc_info->desc_path,
552                                                         desc_builder);
553
554                                         /*unref descriptor builder pointers*/
555                                         g_variant_builder_unref(builder1);
556                                         g_variant_builder_unref(builder2);
557                                         g_variant_builder_unref(inner_builder);
558                                         g_variant_builder_unref(desc_builder);
559                                 }
560
561                                 if (unicast)
562                                         g_free(unicast);
563                                 /*unref char builder pointers*/
564                                 g_variant_builder_unref(builder1);
565                                 g_variant_builder_unref(builder2);
566                                 g_variant_builder_unref(builder3);
567                                 g_variant_builder_unref(inner_builder);
568                                 g_variant_builder_unref(char_builder);
569                         }
570
571                         /*unref service builder pointers*/
572                         g_variant_builder_unref(inner_builder);
573                         g_variant_builder_unref(svc_builder);
574                 }
575
576                 /* Return builder as method reply */
577                 BT_DBG("Sending gatt service builder values to Bluez");
578                 g_dbus_method_invocation_return_value(invocation,
579                                                 g_variant_new(
580                                                 "(a{oa{sa{sv}}})",
581                                                 builder));
582         }
583 }
584
585 static struct gatt_service_info *__bt_gatt_find_gatt_service_from_char(const char *char_path)
586 {
587         GSList *l1, *l2;
588
589         for (l1 = gatt_services; l1 != NULL; l1 = l1->next) {
590                 struct gatt_service_info *serv_info = l1->data;
591
592                 for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
593                         struct gatt_char_info *char_info = l2->data;
594
595                         if (g_strcmp0(char_info->char_path, char_path)
596                                                 == 0)
597                                 return serv_info;
598                 }
599         }
600         BT_ERR("Gatt service not found");
601         return NULL;
602 }
603
604 static struct gatt_service_info *__bt_gatt_find_gatt_service_from_desc(const char *desc_path)
605 {
606         GSList *l1, *l2, *l3;
607
608         for (l1 = gatt_services; l1 != NULL; l1 = l1->next) {
609                 struct gatt_service_info *serv_info = l1->data;
610
611                 for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
612                         struct gatt_char_info *char_info = l2->data;
613
614                         for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) {
615                                 struct gatt_desc_info *desc_info = l3->data;
616
617                                 if (g_strcmp0(desc_info->desc_path, desc_path)
618                                                         == 0)
619                                         return serv_info;
620                         }
621                 }
622         }
623         BT_ERR("Gatt service not found");
624         return NULL;
625 }
626
627 static void __bt_gatt_char_method_call(GDBusConnection *connection,
628                                         const gchar *sender,
629                                         const gchar *object_path,
630                                         const gchar *interface_name,
631                                         const gchar *method_name,
632                                         GVariant *parameters,
633                                         GDBusMethodInvocation *invocation,
634                                         gpointer user_data)
635 {
636
637         if (g_strcmp0(method_name, "ReadValue") == 0) {
638                 gchar *addr = NULL;
639                 guint req_id = 0;
640                 guint16 offset = 0;
641                 bt_gatt_read_req_t read_req = {0, };
642                 bt_user_info_t *user_info = NULL;
643                 struct gatt_req_info *req_info = NULL;
644                 struct gatt_service_info *svc_info = NULL;
645 #ifdef TIZEN_FEATURE_BT_HPS
646                 GVariant *param = NULL;
647 #endif
648
649                 BT_DBG("Application path = %s", object_path);
650                 BT_DBG("Sender = %s", sender);
651
652                 user_info = _bt_get_user_data(BT_COMMON);
653                 if (user_info == NULL) {
654                         BT_INFO("No callback is set for %s", object_path);
655                         g_dbus_method_invocation_return_value(invocation, NULL);
656                         return;
657                 }
658
659                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path);
660                 if (svc_info == NULL) {
661                         BT_ERR("Coudn't find service for %s", object_path);
662                         g_dbus_method_invocation_return_value(invocation, NULL);
663                         return;
664                 }
665
666                 g_variant_get(parameters, "(&suq)", &addr, &req_id, &offset);
667                 BT_DBG("Request id = %u, Offset = %u", req_id, offset);
668
669                 read_req.att_handle = (char *)object_path;
670                 read_req.address = addr;
671                 read_req.req_id = req_id;
672                 read_req.offset = offset;
673                 read_req.service_handle = svc_info->serv_path;
674
675                 /* Store requets information */
676                 req_info = g_new0(struct gatt_req_info, 1);
677                 req_info->attr_path = g_strdup(object_path);
678                 req_info->svc_path = g_strdup(read_req.service_handle);
679                 req_info->request_id = req_id;
680                 req_info->offset = offset;
681                 req_info->context = invocation;
682                 gatt_requests = g_slist_append(gatt_requests, req_info);
683
684                 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED,
685                                         BLUETOOTH_ERROR_NONE, &read_req,
686                                         user_info->cb, user_info->user_data);
687
688 #ifdef TIZEN_FEATURE_BT_HPS
689                 param = g_variant_new("(sssyq)",
690                                 read_req.att_handle,
691                                 read_req.service_handle,
692                                 read_req.address,
693                                 read_req.req_id,
694                                 read_req.offset);
695                 __bt_send_event_to_hps(BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, param);
696 #endif
697
698                 return;
699         } else if (g_strcmp0(method_name, "WriteValue") == 0) {
700                 GVariant *var = NULL;
701                 gchar *addr = NULL;
702                 guint req_id = 0;
703                 guint16 offset = 0;
704                 gboolean response_needed = FALSE;
705                 bt_gatt_value_change_t value_change = {0, };
706                 bt_user_info_t *user_info = NULL;
707                 int len = 0;
708                 struct gatt_service_info *svc_info = NULL;
709                 struct gatt_req_info *req_info = NULL;
710 #ifdef TIZEN_FEATURE_BT_HPS
711                 GVariant *param = NULL;
712 #endif
713
714                 BT_DBG("WriteValue");
715                 BT_DBG("Application path = %s", object_path);
716                 BT_DBG("Sender = %s", sender);
717
718                 g_variant_get(parameters, "(&suqb@ay)",
719                                 &addr, &req_id, &offset, &response_needed, &var);
720                 BT_DBG("Request id = %u, Offset = %u", req_id, offset);
721
722                 user_info = _bt_get_user_data(BT_COMMON);
723                 if (!user_info) {
724                         BT_INFO("No callback is set for %s", object_path);
725                         g_variant_unref(var);
726                         if (response_needed)
727                                 g_dbus_method_invocation_return_value(invocation, NULL);
728                         else
729                                 g_object_unref(invocation);
730                         return;
731                 }
732
733                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path);
734                 if (svc_info == NULL) {
735                         BT_ERR("Coudn't find service for %s", object_path);
736                         g_variant_unref(var);
737                         if (response_needed)
738                                 g_dbus_method_invocation_return_value(invocation, NULL);
739                         else
740                                 g_object_unref(invocation);
741                         return;
742                 }
743
744                 value_change.att_handle = (char *)object_path;
745                 value_change.address = addr;
746                 value_change.service_handle = svc_info->serv_path;
747                 value_change.offset = offset;
748                 value_change.req_id = req_id;
749                 value_change.response_needed = response_needed;
750
751                 len = g_variant_get_size(var);
752                 if (len > 0) {
753                         char *data;
754
755                         value_change.att_value = (guint8 *)g_malloc(len);
756
757                         data = (char *)g_variant_get_data(var);
758                         memcpy(value_change.att_value, data, len);
759                 }
760                 value_change.val_len = len;
761
762                 if (response_needed) {
763                         /* Store requets information */
764                         req_info = g_new0(struct gatt_req_info, 1);
765                         req_info->attr_path = g_strdup(object_path);
766                         req_info->svc_path = g_strdup(value_change.service_handle);
767                         req_info->request_id = req_id;
768                         req_info->offset = offset;
769                         req_info->context = invocation;
770                         gatt_requests = g_slist_append(gatt_requests, req_info);
771                 } else {
772                         g_object_unref(invocation);
773                 }
774
775                 _bt_common_event_cb(
776                         BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
777                         BLUETOOTH_ERROR_NONE, &value_change,
778                         user_info->cb, user_info->user_data);
779
780 #ifdef TIZEN_FEATURE_BT_HPS
781                 if (len > 0) {
782                         gchar *svc_path;
783                         svc_path = g_strdup(svc_info->serv_path);
784                         param = g_variant_new("(sssyq@ay)",
785                                         object_path,
786                                         svc_path,
787                                         addr,
788                                         req_id,
789                                         offset,
790                                         var);
791                         __bt_send_event_to_hps(BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED, param);
792                         if (svc_path)
793                                 g_free(svc_path);
794                 }
795 #endif
796
797                 g_free(value_change.att_value);
798                 g_variant_unref(var);
799                 return;
800         } else if (g_strcmp0(method_name, "StartNotify") == 0) {
801                 bt_user_info_t *user_info = NULL;
802                 bt_gatt_char_notify_change_t notify_change = {0, };
803                 BT_DBG("StartNotify");
804                 user_info = _bt_get_user_data(BT_COMMON);
805                 if (user_info != NULL) {
806                         struct gatt_service_info *svc_info = NULL;
807                         svc_info = __bt_gatt_find_gatt_service_from_char(object_path);
808                         if (svc_info) {
809                                 notify_change.service_handle = svc_info->serv_path;
810                                 notify_change.att_handle = (char *)object_path;
811                                 notify_change.att_notify = TRUE;
812                                 _bt_common_event_cb(
813                                         BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
814                                         BLUETOOTH_ERROR_NONE, &notify_change,
815                                         user_info->cb, user_info->user_data);
816                         }
817                 }
818         } else if (g_strcmp0(method_name, "StopNotify") == 0) {
819                 bt_user_info_t *user_info = NULL;
820                 bt_gatt_char_notify_change_t notify_change = {0, };
821                 BT_DBG("StopNotify");
822                 user_info = _bt_get_user_data(BT_COMMON);
823                 if (user_info != NULL) {
824                         struct gatt_service_info *svc_info = NULL;
825                         svc_info = __bt_gatt_find_gatt_service_from_char(object_path);
826                         if (svc_info) {
827                                 notify_change.service_handle = svc_info->serv_path;
828                                 notify_change.att_handle = (char *)object_path;
829                                 notify_change.att_notify = FALSE;
830                                 _bt_common_event_cb(
831                                         BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
832                                         BLUETOOTH_ERROR_NONE, &notify_change,
833                                         user_info->cb, user_info->user_data);
834                         }
835                 }
836         } else if (g_strcmp0(method_name, "IndicateConfirm") == 0) {
837                 gchar *addr = NULL;
838                 bt_gatt_indicate_confirm_t confirm = {0, };
839                 bt_user_info_t *user_info = NULL;
840                 gboolean complete = FALSE;
841                 struct gatt_service_info *svc_info = NULL;
842
843                 BT_DBG("IndicateConfirm");
844                 BT_DBG("Application path = %s", object_path);
845                 BT_DBG("Sender = %s", sender);
846
847                 g_variant_get(parameters, "(&sb)", &addr, &complete);
848                 BT_DBG("Remote Device address number = %s", addr);
849
850                 confirm.att_handle = (char *)object_path;
851                 confirm.address = addr;
852                 confirm.complete = complete;
853
854                 svc_info = __bt_gatt_find_gatt_service_from_char(object_path);
855                 if (svc_info != NULL) {
856                         confirm.service_handle = svc_info->serv_path;
857
858                         user_info = _bt_get_user_data(BT_COMMON);
859                         if (user_info != NULL) {
860                                 _bt_common_event_cb(
861                                         BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED,
862                                         BLUETOOTH_ERROR_NONE, &confirm,
863                                         user_info->cb, user_info->user_data);
864                         }
865                 }
866         }
867
868         g_dbus_method_invocation_return_value(invocation, NULL);
869 }
870
871 static void __bt_gatt_desc_method_call(GDBusConnection *connection,
872                                         const gchar *sender,
873                                         const gchar *object_path,
874                                         const gchar *interface_name,
875                                         const gchar *method_name,
876                                         GVariant *parameters,
877                                         GDBusMethodInvocation *invocation,
878                                         gpointer user_data)
879 {
880         if (g_strcmp0(method_name, "ReadValue") == 0) {
881                 gchar *addr = NULL;
882                 guint req_id = 0;
883                 guint16 offset = 0;
884                 bt_gatt_read_req_t read_req = {0, };
885                 bt_user_info_t *user_info = NULL;
886                 struct gatt_req_info *req_info = NULL;
887                 struct gatt_service_info *svc_info = NULL;
888
889                 BT_DBG("ReadValue");
890                 BT_DBG("Application path = %s", object_path);
891                 BT_DBG("Sender = %s", sender);
892
893                 user_info = _bt_get_user_data(BT_COMMON);
894                 if (user_info == NULL) {
895                         BT_INFO("No callback is set for %s", object_path);
896                         g_dbus_method_invocation_return_value(invocation, NULL);
897                         return;
898                 }
899
900                 svc_info = __bt_gatt_find_gatt_service_from_desc(object_path);
901                 if (svc_info == NULL) {
902                         BT_ERR("Coudn't find service for %s", object_path);
903                         g_dbus_method_invocation_return_value(invocation, NULL);
904                         return;
905                 }
906
907                 g_variant_get(parameters, "(&suq)", &addr, &req_id, &offset);
908                 BT_DBG("Request id = %u, Offset = %u", req_id, offset);
909
910                 read_req.att_handle = (char *)object_path;
911                 read_req.address = addr;
912                 read_req.req_id = req_id;
913                 read_req.offset = offset;
914                 read_req.service_handle = svc_info->serv_path;
915
916                 /* Store requets information */
917                 req_info = g_new0(struct gatt_req_info, 1);
918                 req_info->attr_path = g_strdup(object_path);
919                 req_info->svc_path = g_strdup(read_req.service_handle);
920                 req_info->request_id = req_id;
921                 req_info->offset = offset;
922                 req_info->context = invocation;
923                 gatt_requests = g_slist_append(gatt_requests, req_info);
924
925                 _bt_common_event_cb(
926                                 BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED,
927                                 BLUETOOTH_ERROR_NONE, &read_req,
928                                 user_info->cb, user_info->user_data);
929
930                 return;
931         } else if (g_strcmp0(method_name, "WriteValue") == 0) {
932                 GVariant *var = NULL;
933                 gchar *addr = NULL;
934                 guint req_id = 0;
935                 guint16 offset = 0;
936                 gboolean response_needed = FALSE;
937                 bt_gatt_value_change_t value_change = {0, };
938                 bt_user_info_t *user_info = NULL;
939                 int len = 0;
940                 struct gatt_service_info *svc_info = NULL;
941                 struct gatt_req_info *req_info = NULL;
942
943                 BT_DBG("WriteValue");
944                 BT_DBG("Application path = %s", object_path);
945                 BT_DBG("Sender = %s", sender);
946
947                 g_variant_get(parameters, "(&suqb@ay)",
948                                 &addr, &req_id, &offset, &response_needed, &var);
949                 BT_DBG("Request id = %u, Offset = %u", req_id, offset);
950
951                 user_info = _bt_get_user_data(BT_COMMON);
952                 if (user_info == NULL) {
953                         BT_INFO("No callback is set for %s", object_path);
954                         g_variant_unref(var);
955                         if (response_needed)
956                                 g_dbus_method_invocation_return_value(invocation, NULL);
957                         else
958                                 g_object_unref(invocation);
959                         return;
960                 }
961
962                 svc_info = __bt_gatt_find_gatt_service_from_desc(object_path);
963                 if (svc_info == NULL) {
964                         BT_ERR("Coudn't find service for %s", object_path);
965                         g_variant_unref(var);
966                         if (response_needed)
967                                 g_dbus_method_invocation_return_value(invocation, NULL);
968                         else
969                                 g_object_unref(invocation);
970                         return;
971                 }
972
973                 value_change.att_handle = (char *)object_path;
974                 value_change.address = addr;
975                 value_change.service_handle = svc_info->serv_path;
976                 value_change.offset = offset;
977                 value_change.req_id = req_id;
978                 value_change.response_needed = response_needed;
979
980                 len = g_variant_get_size(var);
981                 if (len > 0) {
982                         char *data;
983
984                         value_change.att_value = (guint8 *)g_malloc(len);
985
986                         data = (char *)g_variant_get_data(var);
987                         memcpy(value_change.att_value, data, len);
988                 }
989                 value_change.val_len = len;
990
991                 if (response_needed) {
992                         /* Store requets information */
993                         req_info = g_new0(struct gatt_req_info, 1);
994                         req_info->attr_path = g_strdup(object_path);
995                         req_info->svc_path = g_strdup(value_change.service_handle);
996                         req_info->request_id = req_id;
997                         req_info->offset = offset;
998                         req_info->context = invocation;
999                         gatt_requests = g_slist_append(gatt_requests, req_info);
1000                 } else {
1001                         g_object_unref(invocation);
1002                 }
1003
1004                 _bt_common_event_cb(
1005                         BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
1006                         BLUETOOTH_ERROR_NONE, &value_change,
1007                         user_info->cb, user_info->user_data);
1008
1009                 g_free(value_change.att_value);
1010                 g_variant_unref(var);
1011                 return;
1012         }
1013 }
1014
1015 gboolean __bt_gatt_emit_interface_removed(gchar *object_path, gchar *interface)
1016 {
1017         gboolean ret;
1018         GError *error = NULL;
1019         GVariantBuilder *array_builder;
1020
1021         array_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
1022         g_variant_builder_init(array_builder, G_VARIANT_TYPE("as"));
1023         g_variant_builder_add(array_builder, "s", interface);
1024
1025         ret = g_dbus_connection_emit_signal(g_conn, NULL, "/",
1026                                         "org.freedesktop.Dbus.Objectmanager",
1027                                         "InterfacesRemoved",
1028                                         g_variant_new("(oas)",
1029                                         object_path, array_builder),
1030                                         &error);
1031
1032         if (!ret) {
1033                 if (error != NULL) {
1034                         /* dbus gives error cause */
1035                         BT_ERR("d-bus api failure: errcode[%x], message[%s]",
1036                                 error->code, error->message);
1037                         g_clear_error(&error);
1038                 }
1039         }
1040         g_variant_builder_unref(array_builder);
1041
1042         return ret;
1043 }
1044
1045 static const GDBusInterfaceVTable desc_interface_vtable = {
1046         __bt_gatt_desc_method_call,
1047         NULL,
1048         NULL,
1049 };
1050
1051 static const GDBusInterfaceVTable char_interface_vtable = {
1052         __bt_gatt_char_method_call,
1053         NULL,
1054         NULL,
1055 };
1056
1057 static const GDBusInterfaceVTable serv_interface_vtable = {
1058         NULL,
1059         NULL,
1060         NULL,
1061 };
1062
1063 static const GDBusInterfaceVTable manager_interface_vtable = {
1064         __bt_gatt_manager_method_call,
1065         NULL,
1066         NULL
1067 };
1068
1069 static GDBusNodeInfo *__bt_gatt_create_method_node_info(
1070                                 const gchar *introspection_data)
1071 {
1072         GError *err = NULL;
1073         GDBusNodeInfo *node_info = NULL;
1074
1075         if (introspection_data == NULL)
1076                 return NULL;
1077
1078
1079         BT_DBG("Create new node info");
1080         node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
1081
1082         if (err) {
1083                 BT_ERR("Unable to create node: %s", err->message);
1084                 g_clear_error(&err);
1085                 return NULL;
1086         }
1087
1088         return node_info;
1089 }
1090
1091 static struct gatt_service_info *__bt_gatt_find_gatt_service_info(
1092                         const char *service_path)
1093 {
1094         GSList *l;
1095
1096         for (l = gatt_services; l != NULL; l = l->next) {
1097                 struct gatt_service_info *info = l->data;
1098
1099                 if (g_strcmp0(info->serv_path, service_path) == 0)
1100                         return info;
1101         }
1102         BT_ERR("Gatt service not found");
1103         return NULL;
1104 }
1105
1106 static struct gatt_char_info *__bt_gatt_find_gatt_char_info(
1107                         const char *service_path, const char *char_path)
1108 {
1109         GSList *l1, *l2;
1110
1111         for (l1 = gatt_services; l1 != NULL; l1 = l1->next) {
1112                 struct gatt_service_info *serv_info = l1->data;
1113
1114                 if (g_strcmp0(serv_info->serv_path, service_path) == 0) {
1115
1116                         for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
1117                                 struct gatt_char_info *char_info = l2->data;
1118
1119                                 if (g_strcmp0(char_info->char_path, char_path)
1120                                                         == 0)
1121                                         return char_info;
1122                         }
1123                         BT_ERR("Gatt characteristic not found");
1124                         return NULL;
1125                 }
1126         }
1127         BT_ERR("Gatt service not found");
1128         return NULL;
1129 }
1130
1131 static struct gatt_desc_info *__bt_gatt_find_gatt_desc_info(
1132                         const char *serv_path, const char *char_path,
1133                         const char *desc_path)
1134 {
1135         GSList *l1, *l2, *l3;
1136
1137         for (l1 = gatt_services; l1 != NULL; l1 = l1->next) {
1138                 struct gatt_service_info *serv_info = l1->data;
1139
1140                 if (g_strcmp0(serv_info->serv_path, serv_path) == 0) {
1141                         for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) {
1142                                 struct gatt_char_info *char_info = l2->data;
1143
1144                                 if (g_strcmp0(char_info->char_path, char_path)
1145                                                         == 0) {
1146                                         for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) {
1147                                                 struct gatt_desc_info *desc_info = l3->data;
1148                                                 if (g_strcmp0(desc_info->desc_path,
1149                                                         desc_path) == 0) {
1150                                                         return desc_info;
1151                                                 }
1152                                         }
1153                                 }
1154                         }
1155                 }
1156         }
1157         BT_ERR("Gatt descriptor not found");
1158         return NULL;
1159 }
1160
1161 static struct gatt_req_info *__bt_gatt_find_request_info(guint request_id)
1162 {
1163         GSList *l;
1164
1165         for (l = gatt_requests; l != NULL; l = l->next) {
1166                 struct gatt_req_info *req_info = l->data;
1167
1168                 if (req_info && req_info->request_id == request_id)
1169                         return req_info;
1170         }
1171         BT_ERR("Gatt Request not found");
1172         return NULL;
1173 }
1174
1175 static GDBusProxy *__bt_gatt_gdbus_init_manager_proxy(const gchar *service,
1176                                 const gchar *path, const gchar *interface)
1177 {
1178         GDBusProxy *proxy;
1179         GError *err = NULL;
1180
1181         if (g_conn == NULL)
1182                 g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM,
1183                                                         NULL, &err);
1184
1185         if (!g_conn) {
1186                 if (err) {
1187                         BT_ERR("Unable to connect to gdbus: %s", err->message);
1188                         g_clear_error(&err);
1189                 }
1190                 return NULL;
1191         }
1192
1193         proxy =  g_dbus_proxy_new_sync(g_conn,
1194                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1195                         service, path,
1196                         interface, NULL, &err);
1197
1198         if (!proxy) {
1199                 if (err) {
1200                         BT_ERR("Unable to create proxy: %s", err->message);
1201                         g_clear_error(&err);
1202                 }
1203                 return NULL;
1204         }
1205         manager_gproxy = proxy;
1206
1207         return proxy;
1208 }
1209
1210 static GDBusProxy *__bt_gatt_gdbus_get_manager_proxy(const gchar *service,
1211                                 const gchar *path, const gchar *interface)
1212 {
1213         return (manager_gproxy) ? manager_gproxy :
1214                         __bt_gatt_gdbus_init_manager_proxy(service,
1215                                 path, interface);
1216 }
1217
1218 int bluetooth_gatt_convert_prop2string(
1219                         bt_gatt_characteristic_property_t properties,
1220                         char *char_properties[])
1221 {
1222         int flag_count = 0;
1223
1224         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST) {
1225                 char_properties[flag_count] = g_strdup("broadcast");
1226                 flag_count++;
1227         }
1228         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ) {
1229                 char_properties[flag_count] = g_strdup("read");
1230                 flag_count++;
1231         }
1232         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) {
1233                 char_properties[flag_count] = g_strdup("write-without-response");
1234                 flag_count++;
1235         }
1236         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE) {
1237                 char_properties[flag_count] = g_strdup("write");
1238                 flag_count++;
1239         }
1240         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) {
1241                 char_properties[flag_count] = g_strdup("notify");
1242                 flag_count++;
1243         }
1244         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE) {
1245                 char_properties[flag_count] = g_strdup("indicate");
1246                 flag_count++;
1247         }
1248         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE) {
1249                 char_properties[flag_count] = g_strdup("authenticated-signed-writes");
1250                 flag_count++;
1251         }
1252         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE) {
1253                 char_properties[flag_count] = g_strdup("reliable-write");
1254                 flag_count++;
1255         }
1256         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES) {
1257                 char_properties[flag_count] = g_strdup("writable-auxiliaries");
1258                 flag_count++;
1259         }
1260         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ) {
1261                 char_properties[flag_count] = g_strdup("encrypt-read");
1262                 flag_count++;
1263         }
1264         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE) {
1265                 char_properties[flag_count] = g_strdup("encrypt-write");
1266                 flag_count++;
1267         }
1268         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ) {
1269                 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1270                 flag_count++;
1271         }
1272         if (properties & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE) {
1273                 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1274                 flag_count++;
1275         }
1276
1277         if (flag_count == 0) {
1278                 char_properties[flag_count] = g_strdup("read");
1279                 flag_count++;
1280         }
1281
1282         return flag_count;
1283 }
1284
1285 int bluetooth_gatt_convert_perm2string(
1286                         bt_gatt_permission_t properties,
1287                         char *char_properties[])
1288 {
1289         int flag_count = 0;
1290
1291         if (properties & BLUETOOTH_GATT_PERMISSION_READ) {
1292                 char_properties[flag_count] = g_strdup("read");
1293                 flag_count++;
1294         }
1295         if (properties & BLUETOOTH_GATT_PERMISSION_WRITE) {
1296                 char_properties[flag_count] = g_strdup("write");
1297                 flag_count++;
1298         }
1299         if (properties & BLUETOOTH_GATT_PERMISSION_ENCRYPT_READ) {
1300                 char_properties[flag_count] = g_strdup("encrypt-read");
1301                 flag_count++;
1302         }
1303         if (properties & BLUETOOTH_GATT_PERMISSION_ENCRYPT_WRITE) {
1304                 char_properties[flag_count] = g_strdup("encrypt-write");
1305                 flag_count++;
1306         }
1307         if (properties & BLUETOOTH_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ) {
1308                 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1309                 flag_count++;
1310         }
1311         if (properties & BLUETOOTH_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE) {
1312                 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1313                 flag_count++;
1314         }
1315
1316         if (flag_count == 0) {
1317                 char_properties[flag_count] = g_strdup("read");
1318                 flag_count++;
1319         }
1320
1321         return flag_count;
1322 }
1323
1324 static void __bt_gatt_set_service_state(const char *service_path,
1325                         gboolean state)
1326 {
1327         struct gatt_service_info *svc_info = NULL;
1328         svc_info = __bt_gatt_find_gatt_service_info(service_path);
1329
1330         if (svc_info != NULL) {
1331                 BT_DBG("Updating the gatt service register state %d", state);
1332                 svc_info->is_svc_registered = state;
1333                 return;
1334         }
1335
1336         BT_DBG("gatt service not found");
1337 }
1338
1339 static gboolean __bt_gatt_get_service_state(const char *service_path)
1340 {
1341         struct gatt_service_info *svc_info = NULL;
1342
1343         svc_info = __bt_gatt_find_gatt_service_info(service_path);
1344
1345         if (svc_info != NULL) {
1346                 BT_DBG("Return the state of the gatt service %d",
1347                         svc_info->is_svc_registered);
1348                 return svc_info->is_svc_registered;
1349         }
1350
1351         BT_DBG("gatt service info is NULL");
1352         return FALSE;
1353 }
1354
1355 void get_service_cb(GObject *object, GAsyncResult *res, gpointer user_data)
1356 {
1357         GError *error = NULL;
1358         GVariant *result;
1359         GVariantIter *iter = NULL;
1360         const gchar *key = NULL;
1361         GVariant *value = NULL;
1362         const gchar *service = NULL;
1363         const gchar *characteristic = NULL;
1364         const gchar *descriptor = NULL;
1365         int n_char = 1;
1366
1367         BT_DBG(" ");
1368         result = g_dbus_proxy_call_finish(manager_gproxy, res, &error);
1369
1370         if (result == NULL) {
1371                 /* dBUS-RPC is failed */
1372                 BT_ERR("Dbus-RPC is failed\n");
1373
1374                 if (error != NULL) {
1375                 /* dBUS gives error cause */
1376                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]\n",
1377                                                 error->code, error->message);
1378                         g_clear_error(&error);
1379                 }
1380         } else {
1381                 char *char_cmp = NULL;
1382                 g_variant_get(result, "(a{sv})", &iter);
1383                 char_cmp = g_strdup_printf("Characteristic%d", n_char);
1384
1385                 while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
1386                         if (g_strcmp0(key, "Service") == 0) {
1387                                 service = g_variant_get_string(value, NULL);
1388                                 BT_DBG("Service %s", service);
1389                         } else if (g_strcmp0(key, char_cmp) == 0) {
1390                                 characteristic = g_variant_get_string(value, NULL);
1391                                 g_free(char_cmp);
1392                                 char_cmp = g_strdup_printf("Characteristic%d", ++n_char);
1393                                 BT_DBG("%s", characteristic);
1394                         } else if (g_strcmp0(key, "Descriptor") == 0) {
1395                                 descriptor = g_variant_get_string(value, NULL);
1396                                 BT_DBG("Descriptor %s", descriptor);
1397                         }
1398                 }
1399                 g_variant_iter_free(iter);
1400
1401                 /* TODO: Store the service informationa and
1402                  * Send respponse to CAPI layer. */
1403
1404                 g_variant_unref(result);
1405                 if (char_cmp)
1406                         g_free(char_cmp);
1407         }
1408 }
1409 void register_application_cb(GObject *object, GAsyncResult *res, gpointer user_data)
1410 {
1411         BT_INFO("RegisterApplication is completed");
1412
1413         GError *error = NULL;
1414         GVariant *result;
1415
1416         register_pending_cnt = 0;
1417
1418         result = g_dbus_proxy_call_finish(manager_gproxy, res, &error);
1419
1420         if (result == NULL) {
1421                 /* dBUS-RPC is failed */
1422                 BT_ERR("Dbus-RPC is failed\n");
1423
1424                 if (error != NULL) {
1425                 /* dBUS gives error cause */
1426                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]\n",
1427                                                 error->code, error->message);
1428                         g_clear_error(&error);
1429                 }
1430         } else {
1431                 g_variant_unref(result);
1432         }
1433 }
1434
1435 void unregister_application_cb(GObject *object, GAsyncResult *res,
1436                 gpointer user_data)
1437 {
1438         BT_INFO("UnregisterApplication is completed");
1439
1440         GError *error = NULL;
1441         GVariant *result;
1442
1443         result = g_dbus_proxy_call_finish(manager_gproxy, res, &error);
1444
1445         if (result == NULL) {
1446                 /* dBUS-RPC is failed */
1447                 BT_ERR("Dbus-RPC is failed\n");
1448
1449                 if (error != NULL) {
1450                         /* dBUS gives error cause */
1451                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]\n",
1452                                         error->code, error->message);
1453                         g_clear_error(&error);
1454                 }
1455         } else {
1456                 g_variant_unref(result);
1457         }
1458 }
1459
1460 static int __bt_gatt_unregister_service(const char *service_path)
1461 {
1462         if (!__bt_gatt_get_service_state(service_path)) {
1463                 BT_DBG("service not registered \n");
1464                 return BLUETOOTH_ERROR_NOT_FOUND;
1465         }
1466
1467         return BLUETOOTH_ERROR_NONE;
1468 }
1469
1470 BT_EXPORT_API int bluetooth_gatt_unregister_application(void)
1471 {
1472         GDBusProxy *proxy = NULL;
1473
1474         if (is_server_started) {
1475                 proxy = __bt_gatt_gdbus_get_manager_proxy("org.bluez",
1476                                 "/org/bluez/hci0", GATT_MNGR_INTERFACE);
1477
1478                 if (proxy == NULL || app_path == NULL)
1479                         return BLUETOOTH_ERROR_INTERNAL;
1480
1481                 BT_INFO("UnregisterApplication");
1482
1483                 /* Async Call to Unregister Service */
1484                 g_dbus_proxy_call(proxy,
1485                                 "UnregisterApplication",
1486                                 g_variant_new("(o)",
1487                                         app_path),
1488                                 G_DBUS_CALL_FLAGS_NONE, -1,
1489                                 NULL,
1490                                 (GAsyncReadyCallback) unregister_application_cb,
1491                                 NULL);
1492
1493                 is_server_started = false;
1494                 return BLUETOOTH_ERROR_NONE;
1495         }
1496
1497         BT_INFO("GATT server not started");
1498         return BLUETOOTH_ERROR_NONE;
1499 }
1500
1501 static GDBusConnection *__bt_gatt_get_gdbus_connection(void)
1502 {
1503         GDBusConnection *local_system_gconn = NULL;
1504         char *address;
1505         GError *err = NULL;
1506
1507         if (g_conn == NULL) {
1508                 address = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1509                 if (address == NULL) {
1510                         if (err) {
1511                                 BT_ERR("Failed to get bus address: %s", err->message);
1512                                 g_clear_error(&err);
1513                         }
1514                         return NULL;
1515                 }
1516
1517                 g_conn = g_dbus_connection_new_for_address_sync(address,
1518                                         G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
1519                                         G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
1520                                         NULL, /* GDBusAuthObserver */
1521                                         NULL,
1522                                         &err);
1523                 g_free(address);
1524                 if (!g_conn) {
1525                         if (err) {
1526                                 BT_ERR("Unable to connect to dbus: %s", err->message);
1527                                 g_clear_error(&err);
1528                         }
1529                         return NULL;
1530                 }
1531         } else if (g_dbus_connection_is_closed(g_conn)) {
1532                 address = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1533                 if (address == NULL) {
1534                         if (err) {
1535                                 BT_ERR("Failed to get bus address: %s", err->message);
1536                                 g_clear_error(&err);
1537                         }
1538                         return NULL;
1539                 }
1540
1541                 local_system_gconn = g_dbus_connection_new_for_address_sync(address,
1542                                         G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
1543                                         G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
1544                                         NULL, /* GDBusAuthObserver */
1545                                         NULL,
1546                                         &err);
1547                 g_free(address);
1548                 if (!local_system_gconn) {
1549                         BT_ERR("Unable to connect to dbus: %s", err->message);
1550                         g_clear_error(&err);
1551                 }
1552
1553                 g_conn = local_system_gconn;
1554         }
1555
1556         return g_conn;
1557 }
1558
1559 BT_EXPORT_API int bluetooth_gatt_init(void)
1560 {
1561         GDBusConnection *conn;
1562         GError *error = NULL;
1563         GDBusNodeInfo *node_info = NULL;
1564
1565         if (app_path != NULL) {
1566                 BT_ERR("app path already exists! initialized");
1567                 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
1568         }
1569
1570         if (owner_id == 0) {
1571                 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1572                                         BT_GATT_SERVICE_NAME,
1573                                         G_BUS_NAME_OWNER_FLAGS_NONE,
1574                                         NULL, NULL, NULL, NULL, NULL);
1575         }
1576
1577         BT_DBG("owner_id is [%d]", owner_id);
1578         app_path = g_strdup_printf("/com/%d", getpid());
1579
1580         serv_id = 1;
1581
1582         conn = __bt_gatt_get_gdbus_connection();
1583         if (!conn) {
1584                 BT_ERR("Unable to get connection");
1585                 goto failed;
1586         }
1587
1588         /* Register ObjectManager interface */
1589         node_info = __bt_gatt_create_method_node_info(
1590                                         manager_introspection_xml);
1591         if (node_info == NULL) {
1592                 BT_ERR("failed to get node info");
1593                 goto failed;
1594         }
1595
1596         if (manager_id == 0) {
1597                 BT_INFO("manager_id does not exists");
1598
1599                 manager_id = g_dbus_connection_register_object(g_conn, app_path,
1600                                                         node_info->interfaces[0],
1601                                                         &manager_interface_vtable,
1602                                                         NULL, NULL, &error);
1603         }
1604         g_dbus_node_info_unref(node_info);
1605         if (manager_id == 0) {
1606                 BT_ERR("failed to register: %s", error->message);
1607                 g_error_free(error);
1608                 goto failed;
1609         }
1610
1611         return BLUETOOTH_ERROR_NONE;
1612
1613 failed:
1614         if (owner_id)
1615                 g_bus_unown_name(owner_id);
1616
1617         g_free(app_path);
1618
1619         app_path = NULL;
1620         owner_id = 0;
1621
1622         __bt_gatt_close_gdbus_connection();
1623
1624         return BLUETOOTH_ERROR_INTERNAL;
1625 }
1626
1627 BT_EXPORT_API int bluetooth_gatt_deinit()
1628 {
1629         int ret = BLUETOOTH_ERROR_NONE;
1630         /* Unown gdbus bus */
1631         if (owner_id) {
1632                 /* remove/unregister all services */
1633                 BT_DBG("removing all registered gatt service\n");
1634                 bluetooth_gatt_delete_services();
1635
1636                 /* unregister the exported interface for object manager */
1637                 g_dbus_connection_unregister_object(g_conn,
1638                                         manager_id);
1639
1640                 manager_id = 0;
1641
1642                 ret = bluetooth_gatt_unregister_application();
1643                 if (ret != BLUETOOTH_ERROR_NONE)
1644                         BT_ERR("Fail to unregister application\n");
1645
1646                 g_bus_unown_name(owner_id);
1647                 owner_id = 0;
1648
1649                 g_free(app_path);
1650                 app_path = NULL;
1651
1652                 BT_DBG("Gatt service deinitialized \n");
1653
1654                 g_slist_free(gatt_services);
1655                 gatt_services = NULL;
1656
1657                 g_object_unref(manager_gproxy);
1658                 manager_gproxy = NULL;
1659
1660                 __bt_gatt_close_gdbus_connection();
1661
1662                 return ret;
1663         }
1664
1665         __bt_gatt_close_gdbus_connection();
1666
1667         return BLUETOOTH_ERROR_NOT_FOUND;
1668 }
1669
1670 BT_EXPORT_API int bluetooth_gatt_add_service(const char *svc_uuid,
1671                         char **svc_path)
1672 {
1673         GError *error = NULL;
1674         guint object_id;
1675         GDBusNodeInfo *node_info;
1676         gchar *path = NULL;
1677         GVariantBuilder *builder = NULL;
1678         GVariantBuilder *builder1 = NULL;
1679         GVariantBuilder *inner_builder = NULL;
1680         gboolean svc_primary = TRUE;
1681         struct gatt_service_info *serv_info = NULL;
1682
1683         node_info = __bt_gatt_create_method_node_info(
1684                                         service_introspection_xml);
1685         if (node_info == NULL)
1686                 return BLUETOOTH_ERROR_INTERNAL;
1687
1688         path = g_strdup_printf("%s"GATT_SERV_OBJECT_PATH"%d", app_path, serv_id++);
1689         BT_DBG("gatt service path is [%s]", path);
1690
1691         object_id = g_dbus_connection_register_object(g_conn, path,
1692                                         node_info->interfaces[0],
1693                                         &serv_interface_vtable,
1694                                         NULL, NULL, &error);
1695         g_dbus_node_info_unref(node_info);
1696
1697         if (object_id == 0) {
1698                 BT_ERR("failed to register: %s", error->message);
1699                 g_error_free(error);
1700                 g_free(path);
1701
1702                 return BLUETOOTH_ERROR_INTERNAL;
1703         }
1704
1705         /* Add object_id/gatt service information; it's required at the time of
1706          *  service unregister and Getmanagedobjects
1707          */
1708         serv_info = g_new0(struct gatt_service_info, 1);
1709
1710         serv_info->serv_path = g_strdup(path);
1711         serv_info->serv_id = object_id;
1712         serv_info->service_uuid = g_strdup(svc_uuid);
1713         serv_info->is_svc_registered = FALSE;
1714         serv_info->is_svc_primary = svc_primary;
1715
1716         gatt_services = g_slist_append(gatt_services, serv_info);
1717
1718         /* emit interfacesadded signal here for service path */
1719         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
1720         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1721
1722         g_variant_builder_add(inner_builder, "{sv}",
1723                 "UUID", g_variant_new_string(svc_uuid));
1724
1725         g_variant_builder_add(inner_builder, "{sv}",
1726                 "Primary", g_variant_new_boolean(svc_primary));
1727
1728         builder1 = g_variant_builder_new(G_VARIANT_TYPE("ao"));
1729
1730         g_variant_builder_add(inner_builder, "{sv}", "Characteristics",
1731                                 g_variant_new("ao", builder1));
1732
1733         g_variant_builder_add(builder, "{sa{sv}}",
1734                 GATT_SERV_INTERFACE, inner_builder);
1735
1736         g_dbus_connection_emit_signal(g_conn, NULL, "/",
1737                                 "org.freedesktop.Dbus.ObjectManager",
1738                                 "InterfacesAdded",
1739                                 g_variant_new("(oa{sa{sv}})",
1740                                 path, builder),
1741                                 &error);
1742
1743         new_service = TRUE;
1744
1745         *svc_path = g_strdup(path);
1746
1747         g_free(path);
1748         g_variant_builder_unref(inner_builder);
1749         g_variant_builder_unref(builder);
1750         g_variant_builder_unref(builder1);
1751
1752         return BLUETOOTH_ERROR_NONE;
1753 }
1754
1755 BT_EXPORT_API int bluetooth_gatt_add_new_characteristic(
1756                         const char *svc_path, const char *char_uuid,
1757                         bt_gatt_permission_t permissions,
1758                         bt_gatt_characteristic_property_t properties,
1759                         char **char_path)
1760 {
1761         static int char_id;
1762         GError *error = NULL;
1763         guint object_id;
1764         GDBusNodeInfo *node_info;
1765         gchar *path = NULL;
1766         GVariantBuilder *builder = NULL;
1767         GVariantBuilder *inner_builder = NULL;
1768         struct gatt_service_info *serv_info = NULL;
1769         struct gatt_char_info *char_info = NULL;
1770         GVariantBuilder *builder2 = NULL;
1771         GVariantBuilder *builder3 = NULL;
1772         GVariant *flags_val = NULL;
1773         int i = 0;
1774         char *char_flags[NUMBER_OF_FLAGS];
1775         int flag_count = 0;
1776
1777         if (new_service) {
1778                 char_id = 1;
1779                 new_service = FALSE;
1780         }
1781
1782         BT_DBG("gatt svc_path path is [%s]", svc_path);
1783         serv_info = __bt_gatt_find_gatt_service_info(svc_path);
1784         if (serv_info == NULL)
1785                 return BLUETOOTH_ERROR_INVALID_PARAM;
1786
1787         node_info = __bt_gatt_create_method_node_info(
1788                                         characteristics_introspection_xml);
1789         if (node_info == NULL)
1790                 return BLUETOOTH_ERROR_INTERNAL;
1791
1792         path = g_strdup_printf("%s/characteristic%d", svc_path, char_id++);
1793         BT_DBG("gatt characteristic path is [%s]", path);
1794
1795         object_id = g_dbus_connection_register_object(g_conn, path,
1796                                         node_info->interfaces[0],
1797                                         &char_interface_vtable,
1798                                         NULL, NULL, &error);
1799         g_dbus_node_info_unref(node_info);
1800
1801         if (object_id == 0) {
1802                 BT_ERR("failed to register: %s", error->message);
1803                 g_error_free(error);
1804                 g_free(path);
1805
1806                 return BLUETOOTH_ERROR_INTERNAL;
1807         }
1808
1809         if (permissions & BLUETOOTH_GATT_PERMISSION_ENCRYPT_READ)
1810                 properties |= BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
1811         if (permissions & BLUETOOTH_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ)
1812                 properties |= BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
1813         if (permissions & BLUETOOTH_GATT_PERMISSION_ENCRYPT_WRITE)
1814                 properties |= BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
1815         if (permissions & BLUETOOTH_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE)
1816                 properties |= BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
1817
1818         flag_count = bluetooth_gatt_convert_prop2string(properties, char_flags);
1819
1820         char_info = g_new0(struct gatt_char_info, 1);
1821
1822         char_info->char_path = g_strdup(path);
1823         char_info->char_id = object_id;
1824         char_info->char_uuid = g_strdup(char_uuid);
1825
1826         for (i = 0; i < flag_count; i++)
1827                 char_info->char_flags[i] = char_flags[i];
1828
1829
1830         char_info->flags_length = flag_count;
1831
1832         serv_info->char_data = g_slist_append(serv_info->char_data, char_info);
1833
1834         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
1835         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1836
1837         g_variant_builder_add(inner_builder, "{sv}", "UUID",
1838                                 g_variant_new("s", char_uuid));
1839         g_variant_builder_add(inner_builder, "{sv}", "Service",
1840                                 g_variant_new("o", svc_path));
1841
1842         builder2 = g_variant_builder_new(G_VARIANT_TYPE("as"));
1843
1844         for (i = 0; i < flag_count; i++)
1845                 g_variant_builder_add(builder2, "s", char_flags[i]);
1846
1847         flags_val = g_variant_new("as", builder2);
1848         g_variant_builder_add(inner_builder, "{sv}", "Flags",
1849                                 flags_val);
1850
1851         builder3 = g_variant_builder_new(G_VARIANT_TYPE("ao"));
1852
1853         g_variant_builder_add(inner_builder, "{sv}", "Descriptors",
1854                                 g_variant_new("ao", builder3));
1855
1856         g_variant_builder_add(builder, "{sa{sv}}",
1857                                 GATT_CHAR_INTERFACE,
1858                                 inner_builder);
1859
1860         g_dbus_connection_emit_signal(g_conn, NULL, "/",
1861                                 "org.freedesktop.Dbus.ObjectManager",
1862                                 "InterfacesAdded",
1863                                 g_variant_new("(oa{sa{sv}})",
1864                                 path, builder),
1865                                 &error);
1866
1867         *char_path = g_strdup(path);
1868
1869         new_char = TRUE;
1870
1871         g_free(path);
1872
1873         g_variant_builder_unref(inner_builder);
1874         g_variant_builder_unref(builder);
1875         g_variant_builder_unref(builder2);
1876         g_variant_builder_unref(builder3);
1877
1878         return BLUETOOTH_ERROR_NONE;
1879 }
1880
1881 BT_EXPORT_API int bluetooth_gatt_set_characteristic_value(
1882                         const char *characteristic, const char *char_value,
1883                         int     value_length)
1884 {
1885         gchar **line_argv = NULL;
1886         char *serv_path = NULL;
1887         struct gatt_char_info *char_info = NULL;
1888         GVariantBuilder *builder1 = NULL;
1889         GVariantBuilder *builder = NULL;
1890         GVariantBuilder *inner_builder = NULL;
1891         GVariant *char_val = NULL;
1892         GError *error = NULL;
1893         int i = 0;
1894         int res = BLUETOOTH_ERROR_NONE;
1895
1896         line_argv = g_strsplit_set(characteristic, "/", 0);
1897         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
1898
1899         char_info = __bt_gatt_find_gatt_char_info(serv_path, characteristic);
1900
1901         if (char_info == NULL) {
1902                 /* Fix : RESOURCE_LEAK */
1903                 res = BLUETOOTH_ERROR_INVALID_PARAM;
1904                 goto done;
1905         }
1906
1907         char_info->value_length = value_length;
1908
1909         char_info->char_value = (char *)malloc(value_length);
1910         /* Fix : NULL_RETURNS */
1911         if (char_info->char_value == NULL) {
1912                 res = BLUETOOTH_ERROR_MEMORY_ALLOCATION;
1913                 goto done;
1914         }
1915
1916         for (i = 0; i < value_length; i++)
1917                 char_info->char_value[i] = char_value[i];
1918
1919         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
1920         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1921
1922         builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
1923
1924         for (i = 0; i < value_length; i++)
1925                 g_variant_builder_add(builder1, "y", char_value[i]);
1926
1927         char_val = g_variant_new("ay", builder1);
1928                 g_variant_builder_add(inner_builder, "{sv}", "Value", char_val);
1929
1930         g_variant_builder_add(builder, "{sa{sv}}",
1931                         GATT_CHAR_INTERFACE,
1932                         inner_builder);
1933
1934         g_dbus_connection_emit_signal(g_conn, NULL, "/",
1935                         "org.freedesktop.Dbus.ObjectManager",
1936                         "InterfacesAdded",
1937                         g_variant_new("(oa{sa{sv}})",
1938                         char_info->char_path, builder),
1939                         &error);
1940
1941         g_variant_builder_unref(inner_builder);
1942         g_variant_builder_unref(builder);
1943         g_variant_builder_unref(builder1);
1944 done:
1945         g_strfreev(line_argv);
1946         g_free(serv_path);
1947
1948         return res;
1949 }
1950
1951 BT_EXPORT_API int bluetooth_gatt_add_descriptor(
1952                         const char *char_path, const char *desc_uuid,
1953                         bt_gatt_permission_t permissions,
1954                         char **desc_path)
1955 {
1956         static int desc_id = 1;
1957         GError *error = NULL;
1958         guint object_id;
1959         GDBusNodeInfo *node_info;
1960         gchar *path = NULL;
1961         GVariantBuilder *builder = NULL;
1962         GVariantBuilder *inner_builder = NULL;
1963         struct gatt_char_info *char_info = NULL;
1964         struct gatt_desc_info *desc_info = NULL;
1965         gchar **line_argv = NULL;
1966         char *serv_path;
1967         GVariantBuilder *builder2 = NULL;
1968         GVariant *flags_val = NULL;
1969         int i = 0;
1970         char *desc_flags[NUMBER_OF_FLAGS];
1971         int flag_count = 0;
1972
1973         if (new_char) {
1974                 desc_id = 1;
1975                 new_char = FALSE;
1976         }
1977
1978         line_argv = g_strsplit_set(char_path, "/", 0);
1979         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
1980
1981         char_info = __bt_gatt_find_gatt_char_info(serv_path, char_path);
1982         if (char_info == NULL) {
1983                 g_strfreev(line_argv);
1984                 g_free(serv_path);
1985                 return BLUETOOTH_ERROR_INVALID_PARAM;
1986         }
1987
1988         node_info = __bt_gatt_create_method_node_info(
1989                                         descriptor_introspection_xml);
1990         if (node_info == NULL) {
1991                 g_strfreev(line_argv);
1992                 g_free(serv_path);
1993                 return BLUETOOTH_ERROR_INTERNAL;
1994         }
1995
1996         path = g_strdup_printf("%s/descriptor%d", char_path, desc_id++);
1997         BT_DBG("gatt descriptor path is [%s]", path);
1998
1999         object_id = g_dbus_connection_register_object(g_conn, path,
2000                                 node_info->interfaces[0],
2001                                 &desc_interface_vtable,
2002                                 NULL, NULL, &error);
2003         g_dbus_node_info_unref(node_info);
2004
2005         if (object_id == 0) {
2006                 BT_ERR("failed to register: %s", error->message);
2007                 g_error_free(error);
2008                 g_free(path);
2009                 g_strfreev(line_argv);
2010                 g_free(serv_path);
2011
2012                 return BLUETOOTH_ERROR_INTERNAL;
2013         }
2014
2015         flag_count = bluetooth_gatt_convert_perm2string(permissions, desc_flags);
2016
2017         desc_info = g_new0(struct gatt_desc_info, 1);
2018
2019         desc_info->desc_path = g_strdup(path);
2020         desc_info->desc_id = object_id;
2021         desc_info->desc_uuid = g_strdup(desc_uuid);
2022
2023         for (i = 0; i < flag_count; i++)
2024                 desc_info->desc_flags[i] = desc_flags[i];
2025
2026         desc_info->flags_length = flag_count;
2027
2028         char_info->desc_data = g_slist_append(char_info->desc_data, desc_info);
2029
2030         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
2031         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2032
2033         g_variant_builder_add(inner_builder, "{sv}", "UUID",
2034                                 g_variant_new("s", desc_uuid));
2035         g_variant_builder_add(inner_builder, "{sv}", "Characteristic",
2036                                 g_variant_new("o", char_path));
2037
2038         builder2 = g_variant_builder_new(G_VARIANT_TYPE("as"));
2039
2040         for (i = 0; i < flag_count; i++)
2041                 g_variant_builder_add(builder2, "s", desc_flags[i]);
2042
2043         flags_val = g_variant_new("as", builder2);
2044         g_variant_builder_add(inner_builder, "{sv}", "Flags",
2045                                 flags_val);
2046
2047         g_variant_builder_add(builder, "{sa{sv}}",
2048                                 GATT_DESC_INTERFACE,
2049                                 inner_builder);
2050
2051         g_dbus_connection_emit_signal(g_conn, NULL, "/",
2052                                 "org.freedesktop.Dbus.ObjectManager",
2053                                 "InterfacesAdded",
2054                                 g_variant_new("(oa{sa{sv}})",
2055                                 path, builder),
2056                                 &error);
2057
2058         *desc_path = g_strdup(path);
2059
2060         g_free(path);
2061         g_free(serv_path);
2062         g_strfreev(line_argv);
2063         g_variant_builder_unref(inner_builder);
2064         g_variant_builder_unref(builder);
2065         g_variant_builder_unref(builder2);
2066
2067         return BLUETOOTH_ERROR_NONE;
2068 }
2069
2070 BT_EXPORT_API int bluetooth_gatt_set_descriptor_value(
2071                         const char *desc_path, const char *desc_value,
2072                         int value_length)
2073 {
2074         GError *error = NULL;
2075         GVariantBuilder *builder = NULL;
2076         GVariantBuilder *inner_builder = NULL;
2077         GVariantBuilder *builder1 = NULL;
2078         struct gatt_desc_info *desc_info = NULL;
2079         gchar **line_argv = NULL;
2080         char *char_path;
2081         GVariant *desc_val = NULL;
2082         char *serv_path = NULL;
2083         int i ;
2084
2085         line_argv = g_strsplit_set(desc_path, "/", 0);
2086         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
2087         char_path = g_strdup_printf("%s/%s", serv_path, line_argv[4]);
2088
2089         desc_info = __bt_gatt_find_gatt_desc_info(serv_path, char_path, desc_path);
2090
2091         /* Free the allocated memory */
2092         g_strfreev(line_argv);
2093         g_free(serv_path);
2094         g_free(char_path);
2095
2096         /* Fix : NULL_RETURNS */
2097         retv_if(desc_info == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
2098
2099         desc_info->desc_value = (char *)malloc(value_length);
2100
2101         /* Fix : NULL_RETURNS */
2102         retv_if(desc_info->desc_value == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
2103
2104         for (i = 0; i < value_length; i++)
2105                 desc_info->desc_value[i] = desc_value[i];
2106
2107         desc_info->value_length = value_length;
2108
2109         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
2110         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2111
2112         builder1 = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
2113
2114         for (i = 0; i < value_length; i++)
2115                 g_variant_builder_add(builder1, "y", desc_value[i]);
2116
2117         desc_val = g_variant_new("ay", builder1);
2118         g_variant_builder_add(inner_builder, "{sv}", "Value", desc_val);
2119
2120         g_variant_builder_add(builder, "{sa{sv}}",
2121                                 GATT_DESC_INTERFACE,
2122                                 inner_builder);
2123
2124         g_dbus_connection_emit_signal(g_conn, NULL, "/",
2125                                 "org.freedesktop.Dbus.ObjectManager",
2126                                 "InterfacesAdded",
2127                                 g_variant_new("(oa{sa{sv}})",
2128                                 desc_info->desc_path, builder),
2129                                 &error);
2130
2131         g_variant_builder_unref(inner_builder);
2132         g_variant_builder_unref(builder);
2133         g_variant_builder_unref(builder1);
2134
2135         return BLUETOOTH_ERROR_NONE;
2136 }
2137
2138 int bluetooth_gatt_get_service(const char *svc_uuid)
2139 {
2140         GDBusProxy *proxy = NULL;
2141         gchar *uuid = NULL;
2142
2143         proxy = __bt_gatt_gdbus_get_manager_proxy("org.bluez",
2144                                         "/org/bluez/hci0", GATT_MNGR_INTERFACE);
2145         if (proxy == NULL)
2146                 return BLUETOOTH_ERROR_INTERNAL;
2147
2148         uuid = g_strdup(svc_uuid);
2149
2150         g_dbus_proxy_call(proxy,
2151                         "GetService",
2152                         g_variant_new("(s)",
2153                         uuid),
2154                         G_DBUS_CALL_FLAGS_NONE, -1,
2155                         NULL,
2156                         (GAsyncReadyCallback) get_service_cb,
2157                         NULL);
2158
2159         g_free(uuid);
2160
2161         return BLUETOOTH_ERROR_NONE;
2162 }
2163
2164 BT_EXPORT_API int bluetooth_gatt_register_service(
2165                         const char *svc_path)
2166 {
2167         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_GATT_REGISTER_SERVICE)
2168                         == BLUETOOTH_ERROR_PERMISSION_DEINED) {
2169                 BT_ERR("Don't have aprivilege to use this API");
2170                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
2171         }
2172
2173         register_pending_cnt++;
2174
2175         if (__bt_gatt_get_service_state(svc_path)) {
2176                 BT_DBG("service already registered \n");
2177                 return BLUETOOTH_ERROR_NONE;
2178         }
2179
2180         __bt_gatt_set_service_state(svc_path, TRUE);
2181
2182         return BLUETOOTH_ERROR_NONE;
2183 }
2184
2185 BT_EXPORT_API int bluetooth_gatt_register_application(void)
2186 {
2187         GDBusProxy *proxy = NULL;
2188
2189         if (!is_server_started) {
2190
2191                 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_GATT_REGISTER_APPLICATION)
2192                                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
2193                         BT_ERR("Don't have aprivilege to use this API");
2194                         return BLUETOOTH_ERROR_PERMISSION_DEINED;
2195                 }
2196
2197                 proxy = __bt_gatt_gdbus_get_manager_proxy("org.bluez",
2198                                 "/org/bluez/hci0", GATT_MNGR_INTERFACE);
2199                 if (proxy == NULL || app_path == NULL)
2200                         return BLUETOOTH_ERROR_INTERNAL;
2201
2202                 BT_INFO("RegisterApplication");
2203
2204                 g_dbus_proxy_call(proxy,
2205                                 "RegisterApplication",
2206                                 g_variant_new("(oa{sv})",
2207                                         app_path, NULL),
2208                                 G_DBUS_CALL_FLAGS_NONE, -1,
2209                                 NULL,
2210                                 (GAsyncReadyCallback) register_application_cb,
2211                                 NULL);
2212
2213                 is_server_started = true;
2214
2215                 return BLUETOOTH_ERROR_NONE;
2216         }
2217
2218         BT_INFO("Already RegisterApplication");
2219
2220         return BLUETOOTH_ERROR_NONE;
2221 }
2222
2223 BT_EXPORT_API int bluetooth_gatt_delete_services(void)
2224 {
2225         GSList *l;
2226         int error = BLUETOOTH_ERROR_NONE;
2227         l = gatt_services;
2228
2229         if (l != NULL) {
2230                 for (l = gatt_services; l != NULL; l = l->next) {
2231                         struct gatt_service_info *info = l->data;
2232                         BT_DBG("svc_path is %s", info->serv_path);
2233                         if (bluetooth_gatt_unregister_service(info->serv_path)
2234                                         != BLUETOOTH_ERROR_NONE) {
2235                                 error = BLUETOOTH_ERROR_INTERNAL;
2236                                 BT_ERR("Error in removing service %s \n",
2237                                                  info->serv_path);
2238                         }
2239                 }
2240                 BT_DBG(" All services removed successfully.\n ");
2241         } else {
2242                 BT_DBG(" There are no registered services.\n ");
2243         }
2244
2245         g_slist_free(gatt_services);
2246         gatt_services = NULL;
2247         serv_id = 1;
2248
2249         if (error != BLUETOOTH_ERROR_NONE)
2250                 return error;
2251
2252         return BLUETOOTH_ERROR_NONE;
2253 }
2254
2255 BT_EXPORT_API int bluetooth_gatt_update_characteristic(
2256                         const char *char_path, const char* char_value,
2257                         int value_length)
2258 {
2259         GVariantBuilder *outer_builder;
2260         GVariantBuilder *inner_builder;
2261         GVariantBuilder *invalidated_builder;
2262         GVariant *update_value = NULL;
2263         GError *error = NULL;
2264         gboolean ret = FALSE;
2265         int err = BLUETOOTH_ERROR_NONE;
2266         int i = 0;
2267         gchar **line_argv = NULL;
2268         gchar *serv_path = NULL;
2269
2270         line_argv = g_strsplit_set(char_path, "/", 0);
2271         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
2272
2273         if (!__bt_gatt_get_service_state(serv_path)) {
2274                 BT_DBG("service not registered for this characteristic \n");
2275                 g_free(serv_path);
2276                 g_strfreev(line_argv);
2277                 return BLUETOOTH_ERROR_INTERNAL;
2278         }
2279
2280 /* Fix the svace issue : 185689
2281         outer_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2282 */
2283         invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
2284
2285         inner_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
2286         for (i = 0; i < value_length; i++)
2287                 g_variant_builder_add(inner_builder, "y", char_value[i]);
2288
2289         update_value = g_variant_new("ay", inner_builder);
2290
2291
2292         outer_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
2293         g_variant_builder_add(outer_builder, "{sv}", "Value",
2294                                         update_value);
2295
2296         BT_DBG("Updating characteristic value \n");
2297         ret = g_dbus_connection_emit_signal(g_conn, NULL,
2298                                         char_path,
2299                                         "org.freedesktop.DBus.Properties",
2300                                         "PropertiesChanged",
2301                                         g_variant_new("(sa{sv}as)",
2302                                         "org.bluez.GattCharacteristic1",
2303                                         outer_builder, invalidated_builder),
2304                                         &error);
2305
2306         if (!ret) {
2307                 if (error != NULL) {
2308                         BT_ERR("D-Bus API failure: errCode[%x], \
2309                                         message[%s]",
2310                                         error->code, error->message);
2311                         g_clear_error(&error);
2312                 }
2313                 err = BLUETOOTH_ERROR_INTERNAL;
2314         } else {
2315                 struct gatt_char_info *char_info = NULL;
2316
2317                 char_info = __bt_gatt_find_gatt_char_info(serv_path, char_path);
2318                 if (char_info == NULL) {
2319                         g_free(serv_path);
2320                         g_strfreev(line_argv);
2321                         g_variant_builder_unref(inner_builder);
2322                         g_variant_builder_unref(outer_builder);
2323                         g_variant_builder_unref(invalidated_builder);
2324
2325                         return BLUETOOTH_ERROR_INVALID_DATA;
2326                 }
2327
2328                 char_info->value_length = value_length;
2329
2330                 char_info->char_value = (char *)realloc(char_info->char_value, value_length);
2331                 if (char_info->char_value) {
2332                         for (i = 0; i < value_length; i++)
2333                                 char_info->char_value[i] = char_value[i];
2334                 }
2335         }
2336
2337         g_free(serv_path);
2338         g_strfreev(line_argv);
2339         g_variant_builder_unref(inner_builder);
2340         g_variant_builder_unref(outer_builder);
2341         g_variant_builder_unref(invalidated_builder);
2342
2343         return err;
2344 }
2345
2346 static void __bt_gatt_free_descriptor_info(struct gatt_desc_info *desc_info)
2347 {
2348         int i;
2349
2350         if (!desc_info)
2351                 return;
2352
2353         g_free(desc_info->desc_path);
2354         g_free(desc_info->desc_uuid);
2355         g_free(desc_info->desc_value);
2356
2357         for (i = 0; i < desc_info->flags_length; i++)
2358                 g_free(desc_info->desc_flags[i]);
2359
2360         g_free(desc_info);
2361 }
2362
2363 static void __bt_gatt_free_characteristic_info(struct gatt_char_info *char_info)
2364 {
2365         int i;
2366
2367         if (!char_info)
2368                 return;
2369
2370         g_free(char_info->char_path);
2371         g_free(char_info->char_uuid);
2372         g_free(char_info->char_value);
2373
2374         for (i = 0; i < char_info->flags_length; i++)
2375                 g_free(char_info->char_flags[i]);
2376
2377         g_free(char_info);
2378 }
2379
2380 static void __bt_gatt_free_service_info(struct gatt_service_info *svc_info)
2381 {
2382         if (!svc_info)
2383                 return;
2384
2385         g_free(svc_info->serv_path);
2386         g_free(svc_info->service_uuid);
2387         g_free(svc_info);
2388 }
2389
2390 BT_EXPORT_API int bluetooth_gatt_unregister_service(const char *svc_path)
2391 {
2392         GSList *l, *l1;
2393         struct gatt_service_info *svc_info;
2394         gboolean ret;
2395         int err = BLUETOOTH_ERROR_NONE;
2396
2397         BT_DBG("svc_path %s", svc_path);
2398         svc_info = __bt_gatt_find_gatt_service_info(svc_path);
2399
2400         if (!svc_info) {
2401                 BT_ERR("Unable to find service info");
2402                 return BLUETOOTH_ERROR_NOT_FOUND;
2403         }
2404
2405         err = __bt_gatt_unregister_service(svc_path);
2406         if (err != BLUETOOTH_ERROR_NONE) {
2407                 BT_ERR("Could not unregister application");
2408                 return err;
2409         }
2410
2411         for (l = svc_info->char_data; l != NULL; l = l->next) {
2412                 struct gatt_char_info *char_info = l->data;
2413
2414                 if (char_info == NULL)
2415                         break;
2416
2417                 for (l1 = char_info->desc_data; l1 != NULL; l1 = l1->next) {
2418                         struct gatt_desc_info *desc_info = l1->data;
2419
2420                         if (desc_info == NULL)
2421                                 break;
2422
2423                         ret = g_dbus_connection_unregister_object(g_conn,
2424                                                 desc_info->desc_id);
2425                         if (ret) {
2426                                 __bt_gatt_emit_interface_removed(
2427                                                 desc_info->desc_path,
2428                                                 GATT_DESC_INTERFACE);
2429                         } else {
2430                                 err = BLUETOOTH_ERROR_INTERNAL;
2431                         }
2432
2433                         /* list remove & free */
2434                         char_info->desc_data = g_slist_remove(char_info->desc_data, desc_info);
2435                         __bt_gatt_free_descriptor_info(desc_info);
2436                 }
2437
2438                 g_slist_free(char_info->desc_data);
2439                 char_info->desc_data = NULL;
2440
2441                 ret = g_dbus_connection_unregister_object(g_conn,
2442                                         char_info->char_id);
2443                 if (ret) {
2444                         __bt_gatt_emit_interface_removed(char_info->char_path,
2445                                                 GATT_CHAR_INTERFACE);
2446                 } else {
2447                         err = BLUETOOTH_ERROR_INTERNAL;
2448                 }
2449
2450                 /* list remove & free */
2451                 svc_info->char_data = g_slist_remove(svc_info->char_data, char_info);
2452                 __bt_gatt_free_characteristic_info(char_info);
2453         }
2454
2455         g_slist_free(svc_info->char_data);
2456         svc_info->char_data = NULL;
2457
2458         ret = g_dbus_connection_unregister_object(g_conn, svc_info->serv_id);
2459         if (ret) {
2460                 __bt_gatt_emit_interface_removed(svc_info->serv_path,
2461                                                 GATT_SERV_INTERFACE);
2462         } else {
2463                 err = BLUETOOTH_ERROR_INTERNAL;
2464         }
2465
2466         ret = g_dbus_connection_unregister_object(g_conn, svc_info->prop_id);
2467         if (ret)
2468                 BT_DBG("Unregistered the service on properties interface");
2469
2470         /* list remove & free */
2471         gatt_services = g_slist_remove(gatt_services, svc_info);
2472         __bt_gatt_free_service_info(svc_info);
2473
2474         new_service = FALSE;
2475
2476         if (gatt_services == NULL)
2477                 serv_id = 1;
2478         else if (gatt_services->next == NULL)
2479                 serv_id--;
2480
2481         return err;
2482 }
2483
2484 BT_EXPORT_API int bluetooth_gatt_send_response(int request_id, guint req_type,
2485                                         int resp_state, int offset, char *value, int value_length)
2486 {
2487         struct gatt_req_info *req_info = NULL;
2488
2489         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_GATT_SEND_RESPONSE)
2490                         == BLUETOOTH_ERROR_PERMISSION_DEINED) {
2491                 BT_ERR("Don't have aprivilege to use this API");
2492                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
2493         }
2494
2495         req_info = __bt_gatt_find_request_info(request_id);
2496         if (req_info == NULL) {
2497                 BT_ERR("Coundn't find request id [%d]", request_id);
2498                 return BLUETOOTH_ERROR_INTERNAL;
2499         }
2500
2501         if (resp_state != BLUETOOTH_ERROR_NONE) {
2502                 BT_ERR("resp_state is 0x%X", resp_state);
2503
2504                 g_dbus_method_invocation_return_dbus_error(req_info->context,
2505                                 "org.bluez.Error.Failed", "Application Error");
2506
2507                 gatt_requests = g_slist_remove(gatt_requests, req_info);
2508
2509                 req_info->context = NULL;
2510                 if (req_info->attr_path)
2511                         g_free(req_info->attr_path);
2512                 if (req_info->svc_path)
2513                         g_free(req_info->svc_path);
2514                 g_free(req_info);
2515
2516                 return BLUETOOTH_ERROR_NONE;
2517         }
2518
2519         if (req_type == BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ) {
2520                 int i;
2521                 GVariantBuilder *inner_builder = NULL;
2522                 inner_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2523                 if (value_length > 0 && value != NULL) {
2524                         for (i = 0; i < value_length; i++)
2525                                 g_variant_builder_add(inner_builder, "y", value[i]);
2526                 }
2527                 g_dbus_method_invocation_return_value(req_info->context,
2528                                 g_variant_new("(ay)", inner_builder));
2529                 g_variant_builder_unref(inner_builder);
2530         } else {
2531                 g_dbus_method_invocation_return_value(req_info->context, NULL);
2532         }
2533         gatt_requests = g_slist_remove(gatt_requests, req_info);
2534
2535         req_info->context = NULL;
2536         if (req_info->attr_path)
2537                 g_free(req_info->attr_path);
2538         if (req_info->svc_path)
2539                 g_free(req_info->svc_path);
2540         g_free(req_info);
2541
2542         return BLUETOOTH_ERROR_NONE;
2543 }
2544
2545 BT_EXPORT_API int bluetooth_gatt_server_set_notification(const char *char_path,
2546                                                 bluetooth_device_address_t *unicast_address)
2547 {
2548         GVariantBuilder *outer_builder;
2549         GVariantBuilder *invalidated_builder;
2550         GError *error = NULL;
2551         gboolean notify = TRUE;
2552         gboolean ret = TRUE;
2553         int err = BLUETOOTH_ERROR_NONE;
2554         gchar **line_argv = NULL;
2555         gchar *serv_path = NULL;
2556         char addr[20] = { 0 };
2557
2558         line_argv = g_strsplit_set(char_path, "/", 0);
2559         serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
2560
2561         if (!__bt_gatt_get_service_state(serv_path)) {
2562                 BT_DBG("service not registered for this characteristic \n");
2563                 g_free(serv_path);
2564                 g_strfreev(line_argv);
2565                 return BLUETOOTH_ERROR_INTERNAL;
2566         }
2567
2568         g_free(serv_path);
2569
2570         outer_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
2571         invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
2572
2573         g_variant_builder_add(outer_builder, "{sv}", "Notifying",
2574                                         g_variant_new("b", notify));
2575
2576         if (unicast_address) {
2577                 _bt_convert_addr_type_to_string(addr,
2578                                         (unsigned char *)unicast_address->addr);
2579         }
2580         g_variant_builder_add(outer_builder, "{sv}", "Unicast",
2581                                 g_variant_new("s", addr));
2582
2583         BT_DBG("Set characteristic Notification \n");
2584         ret = g_dbus_connection_emit_signal(g_conn, NULL,
2585                                         char_path,
2586                                         "org.freedesktop.DBus.Properties",
2587                                         "PropertiesChanged",
2588                                         g_variant_new("(sa{sv}as)",
2589                                         "org.bluez.GattCharacteristic1",
2590                                         outer_builder, invalidated_builder),
2591                                         &error);
2592
2593         if (!ret) {
2594                 if (error != NULL) {
2595                         BT_ERR("D-Bus API failure: errCode[%x], \
2596                                         message[%s]",
2597                                         error->code, error->message);
2598                         g_clear_error(&error);
2599                 }
2600                 err = BLUETOOTH_ERROR_INTERNAL;
2601         }
2602
2603         g_strfreev(line_argv);
2604         g_variant_builder_unref(outer_builder);
2605         g_variant_builder_unref(invalidated_builder);
2606
2607         return err;
2608 }