[OTP] Add support for OACP Read
[platform/core/connectivity/bluetooth-frwk.git] / bt-otp / bt-otpserver.c
1 /*
2  * Copyright (c) 2017 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 <dlog.h>
19 #include <gio/gio.h>
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdint.h>
24 #include <time.h>
25 #include <sys/stat.h>
26 #include <langinfo.h>
27 #include <inttypes.h>
28 #include <errno.h>
29 #include <gio/gunixfdlist.h>
30
31 #include "bt-otpserver.h"
32 #include "bluetooth-api.h"
33
34
35 #undef LOG_TAG
36 #define LOG_TAG "BLUETOOTH_OTP"
37
38 #define BT_INFO(fmt, arg...) SLOGI(fmt, ##arg)
39 #define BT_ERR(fmt, arg...) SLOGE(fmt, ##arg)
40 #define BT_DBG(fmt, arg...) SLOGD(fmt, ##arg)
41
42 /* OTP object paths */
43 char *otp_obj_path = NULL;
44 char *otp_feature_obj_path = NULL;
45 char *otp_object_name_obj_path = NULL;
46 char *otp_object_type_obj_path = NULL;
47 char *otp_object_size_obj_path = NULL;
48 char *otp_object_first_created_obj_path = NULL;
49 char *otp_object_last_modified_obj_path = NULL;
50 char *otp_object_id_obj_path = NULL;
51 char *otp_object_prop_obj_path = NULL;
52 char *otp_oacp_obj_path = NULL;
53 char *otp_olcp_obj_path = NULL;
54 char *otp_oacp_desc_obj_path = NULL;
55 char *otp_olcp_desc_obj_path = NULL;
56
57 static GMainLoop *main_loop;
58 GDBusNodeInfo *otp_node_info = NULL;
59 static GDBusConnection *conn;
60 static GDBusConnection *g_conn;
61
62 static int property_sub_id = -1;
63 static int adapter_sub_id = -1;
64 static int device_sub_id = -1;
65 static guint g_owner_id = 0;
66
67 struct otp_char_info {
68         gchar *char_path;
69         gchar *char_value;
70         int value_length;
71 };
72
73 struct indicate_info {
74         uint8_t resp_opcode;
75         uint8_t req_opcode;
76         uint8_t result_code;
77         uint8_t *resp_param;
78 };
79
80 /* Object metadata */
81 struct object_metadata {
82         gchar *name;
83         gchar *type;
84         uint32_t curr_size;
85         uint32_t alloc_size;
86         time_t first_created;
87         time_t last_modified;
88         uint64_t id;
89         uint32_t props;
90 };
91
92 struct oacp_operation {
93         char *remote_address;
94         uint32_t offset;
95         uint32_t length;
96         uint8_t opcode;
97         uint8_t mode;
98         int fd;
99 };
100
101 static struct object_metadata *selected_object = NULL;
102 static uint64_t object_id = OBJECT_START_ID;
103 static GSList *otp_object_list = NULL;
104 static GSList *otp_char_list = NULL;
105 static guint obj_curr_index;
106 static int adv_handle = 0;
107 static gboolean OACP_indicate = FALSE;
108 static gboolean OLCP_indicate = FALSE;
109 char *directory = NULL;
110 gboolean mutiple_obj_support = false;
111 static gboolean otc_connection_status = FALSE;
112 struct oacp_operation *oacp_read = NULL;
113
114 static const gchar otp_introspection_xml[] =
115 "<node name='/'>"
116 "       <interface name='org.projectx.otp_service'>"
117 "               <method name='enable'>"
118 "                       <arg type='s' name='directory'/>"
119 "                       <arg type='i' name='status' direction='out'/>"
120 "               </method>"
121 "               <method name='disable'>"
122 "                       <arg type='i' name='status' direction='out'/>"
123 "               </method>"
124 "     <method name='NewConnection'>"
125 "          <arg type='o' name='object' direction='in'/>"
126 "          <arg type='h' name='fd' direction='in'/>"
127 "     </method>"
128 "       </interface>"
129 "</node>";
130
131 void _bt_otp_deinit_event_receiver(void);
132 void _bt_otp_unregister_interface(void);
133 void update_obj_metadata_charc_value(struct object_metadata *object);
134 void _bt_convert_device_path_to_address(const char *device_path,
135                                                 char *device_address);
136
137 static void delete_all_objects(void)
138 {
139         GSList *tmp = NULL;
140         for (tmp = otp_object_list; tmp != NULL; tmp = tmp->next) {
141                 if (tmp->data) {
142                         struct object_metadata *obj_info = tmp->data;
143                         if (obj_info->name)
144                                 g_free(obj_info->name);
145                         if (obj_info->type)
146                                 g_free(obj_info->type);
147                         otp_object_list = g_slist_delete_link(otp_object_list, tmp->data);
148                 }
149         }
150         g_slist_free(otp_object_list);
151         otp_object_list = NULL;
152 }
153
154 static void delete_all_characterisitc(void)
155 {
156         GSList *tmp = NULL;
157         for (tmp = otp_char_list; tmp != NULL; tmp = tmp->next) {
158                 if (tmp->data) {
159                         struct otp_char_info *char_info = tmp->data;
160                         if (char_info->char_path)
161                                 g_free(char_info->char_path);
162                         if (char_info->char_value)
163                                 g_free(char_info->char_value);
164                         otp_char_list = g_slist_delete_link(otp_char_list, tmp->data);
165                 }
166         }
167         g_slist_free(otp_char_list);
168         otp_char_list = NULL;
169 }
170
171 void _bt_otp_exit(void)
172 {
173         int ret;
174         BT_DBG("");
175
176         if (otp_char_list)
177                 delete_all_characterisitc();
178
179         if (otp_object_list)
180                 delete_all_objects();
181
182         ret = bluetooth_gatt_deinit();
183         if (ret != BLUETOOTH_ERROR_NONE)
184                 BT_ERR("Failed to Deinit GATT %d", ret);
185
186         _bt_otp_deinit_event_receiver();
187
188         _bt_otp_unregister_interface();
189
190         /* TODO: Advertising is not getting stopped by this API.
191          * This is because OTP_SERVER_DEINIT dbus call is blocking
192          * BT_SET_ADVERTISING_DATA dbus call. But now advertisment
193          * is stopped because of terminated process logic.
194          */
195         ret = bluetooth_set_advertising(adv_handle, FALSE);
196         if (ret != BLUETOOTH_ERROR_NONE)
197                 BT_ERR("Failed to stop ADV %d", ret);
198
199         if (main_loop != NULL) {
200                 g_main_loop_quit(main_loop);
201         }
202 }
203
204 static void _bt_otp_set_char_value(const char *obj_path,
205                                 const char *value, int value_length)
206 {
207         GSList *tmp = NULL;
208
209         if (!value)
210                 return;
211         for (tmp = otp_char_list; tmp != NULL; tmp = tmp->next) {
212                 if (tmp->data) {
213                         struct otp_char_info *char_info = tmp->data;
214                         if (!g_strcmp0(char_info->char_path, obj_path)) {
215                                 char_info->char_value = g_try_realloc(char_info->char_value, value_length);
216                                 if (char_info->char_value) {
217                                         memcpy(char_info->char_value, value, value_length);
218                                         char_info->value_length = value_length;
219                                 }
220                                 return;
221                         }
222                 }
223         }
224         return;
225 }
226
227 int add_new_characteristic(const char *char_uuid, bt_gatt_permission_t perms,
228                 bt_gatt_characteristic_property_t props, char **obj_path)
229 {
230         int ret = BLUETOOTH_ERROR_NONE;
231         struct otp_char_info *char_info = NULL;
232
233         ret = bluetooth_gatt_add_new_characteristic(otp_obj_path,
234                                         char_uuid, perms, props, obj_path);
235         if (ret != BLUETOOTH_ERROR_NONE) {
236                 BT_ERR("Failed to add new char %d", ret);
237                 return ret;
238         }
239
240         char_info = g_new0(struct otp_char_info, 1);
241         char_info->char_path = g_strdup(*obj_path);
242         otp_char_list = g_slist_append(otp_char_list, char_info);
243
244         return ret;
245 }
246
247 static char *_otp_convert_uuid_to_uuid128(const char *uuid)
248 {
249         int len;
250         char *uuid128;
251
252         len = strlen(uuid);
253
254         switch (len) {
255         case 4:
256                 /* UUID 16bits */
257                 uuid128 = g_strdup_printf("0000%s-0000-1000-8000-00805f9b34fb",
258                                                                         uuid);
259                 break;
260
261         case 8:
262                 /* UUID 32bits */
263                 uuid128 = g_strdup_printf("%s-0000-1000-8000-00805f9b34fb",
264                                                                         uuid);
265                 break;
266
267         case 36:
268                 /* UUID 128bits */
269                 uuid128 = strdup(uuid);
270                 break;
271
272         default:
273                 return NULL;
274         }
275
276         return uuid128;
277 }
278
279 int _bt_otp_prepare_ots(void)
280 {
281         BT_DBG("+");
282         int ret = BLUETOOTH_ERROR_NONE;
283         char *service_uuid;
284         char *char_uuid;
285         char *desc_uuid;
286         bt_gatt_characteristic_property_t props;
287         bt_gatt_permission_t perms;
288         char supp_feat[OTP_FEATURE_LENGTH] = { 0x08, 0x00, 0x00, 0x00,
289                                                 0x80, 0x00, 0x00, 0x00 };
290
291         ret = bluetooth_gatt_init();
292         if (ret != BLUETOOTH_ERROR_NONE) {
293                 BT_ERR("Failed to Init GATT %d", ret);
294                 goto fail;
295         }
296
297         service_uuid = _otp_convert_uuid_to_uuid128(OTP_UUID);
298         ret = bluetooth_gatt_add_service(service_uuid, &otp_obj_path);
299         if (ret != BLUETOOTH_ERROR_NONE) {
300                 BT_ERR("Failed to add service %d", ret);
301                 goto fail;
302         }
303
304         /* Characteristic OTP Feature */
305         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
306         perms = BLUETOOTH_GATT_PERMISSION_READ;
307         char_uuid = _otp_convert_uuid_to_uuid128(OTP_FEATURE_UUID);
308         ret = add_new_characteristic(char_uuid, perms, props,
309                                                 &otp_feature_obj_path);
310         if (ret != BLUETOOTH_ERROR_NONE)
311                 goto fail;
312
313         ret = bluetooth_gatt_set_characteristic_value(otp_feature_obj_path,
314                                                 supp_feat, OTP_FEATURE_LENGTH);
315         if (ret != BLUETOOTH_ERROR_NONE) {
316                 BT_ERR("Failed to set char value %d", ret);
317                 return ret;
318         }
319
320         _bt_otp_set_char_value(otp_feature_obj_path, supp_feat,
321                                                 OTP_FEATURE_LENGTH);
322
323         /* Characteristic Object Name */
324         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
325         perms = BLUETOOTH_GATT_PERMISSION_READ;
326         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_NAME_UUID);
327         ret = add_new_characteristic(char_uuid, perms, props,
328                                         &otp_object_name_obj_path);
329         if (ret != BLUETOOTH_ERROR_NONE)
330                 goto fail;
331
332         /* Characteristic Object Type */
333         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
334         perms = BLUETOOTH_GATT_PERMISSION_READ;
335         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_TYPE_UUID);
336         ret = add_new_characteristic(char_uuid, perms, props,
337                                         &otp_object_type_obj_path);
338         if (ret != BLUETOOTH_ERROR_NONE)
339                 goto fail;
340
341         /* Characteristic Object Size */
342         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
343         perms = BLUETOOTH_GATT_PERMISSION_READ;
344         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_SIZE_UUID);
345         ret = add_new_characteristic(char_uuid, perms, props,
346                                         &otp_object_size_obj_path);
347         if (ret != BLUETOOTH_ERROR_NONE)
348                 goto fail;
349
350         /* Characteristic Object First-Created */
351         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ |
352                 BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
353         perms = BLUETOOTH_GATT_PERMISSION_READ |
354                 BLUETOOTH_GATT_PERMISSION_WRITE;
355         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_FIRST_CREATED_UUID);
356         ret = add_new_characteristic(char_uuid, perms, props,
357                                         &otp_object_first_created_obj_path);
358         if (ret != BLUETOOTH_ERROR_NONE)
359                 goto fail;
360
361         /* Characteristic Object Last-Modified */
362         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ |
363                 BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
364         perms = BLUETOOTH_GATT_PERMISSION_READ |
365                 BLUETOOTH_GATT_PERMISSION_WRITE;
366         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_LAST_MODIFIED_UUID);
367         ret = add_new_characteristic(char_uuid, perms, props,
368                                 &otp_object_last_modified_obj_path);
369         if (ret != BLUETOOTH_ERROR_NONE)
370                 goto fail;
371
372         /* Object ID is mandatory for mutiple object server */
373         if (mutiple_obj_support) {
374                 /* Characteristic Object ID */
375                 props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
376                 perms = BLUETOOTH_GATT_PERMISSION_READ;
377                 char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_ID_UUID);
378                 ret = add_new_characteristic(char_uuid, perms, props,
379                                                 &otp_object_id_obj_path);
380                 if (ret != BLUETOOTH_ERROR_NONE)
381                         goto fail;
382         }
383
384         /* Characteristic Object Properties */
385         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
386         perms = BLUETOOTH_GATT_PERMISSION_READ;
387         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_PROP_UUID);
388         ret = add_new_characteristic(char_uuid, perms, props,
389                                         &otp_object_prop_obj_path);
390         if (ret != BLUETOOTH_ERROR_NONE)
391                 goto fail;
392
393         /* Characteristic OACP */
394         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE |
395                 BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
396         perms = BLUETOOTH_GATT_PERMISSION_WRITE;
397         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OACP_UUID);
398         ret = add_new_characteristic(char_uuid, perms, props,
399                                                 &otp_oacp_obj_path);
400         if (ret != BLUETOOTH_ERROR_NONE)
401                 goto fail;
402
403         /* CCCD for OACP */
404         desc_uuid = _otp_convert_uuid_to_uuid128(OTP_CP_CCC_DESC_UUID);
405         perms = BLUETOOTH_GATT_PERMISSION_READ |
406                 BLUETOOTH_GATT_PERMISSION_WRITE;
407         ret = bluetooth_gatt_add_descriptor(otp_oacp_obj_path, desc_uuid,
408                                                 perms, &otp_oacp_desc_obj_path);
409         if (ret != BLUETOOTH_ERROR_NONE) {
410                 BT_ERR("Failed to add new char descriptor %d", ret);
411                 goto fail;
412         }
413
414         /* OLCP Characteristics is not required
415          * for single object server
416          */
417         if (mutiple_obj_support) {
418                 /* Characteristic OLCP */
419                 props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE |
420                         BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
421                 perms = BLUETOOTH_GATT_PERMISSION_WRITE;
422                 char_uuid = _otp_convert_uuid_to_uuid128(OTP_OLCP_UUID);
423                 ret = add_new_characteristic(char_uuid, perms, props,
424                                                         &otp_olcp_obj_path);
425                 if (ret != BLUETOOTH_ERROR_NONE)
426                         goto fail;
427
428                 /* CCCD for OLCP */
429                 desc_uuid = _otp_convert_uuid_to_uuid128(OTP_CP_CCC_DESC_UUID);
430                 perms = BLUETOOTH_GATT_PERMISSION_READ |
431                         BLUETOOTH_GATT_PERMISSION_WRITE;
432                 ret = bluetooth_gatt_add_descriptor(otp_olcp_obj_path, desc_uuid,
433                                                         perms, &otp_olcp_desc_obj_path);
434                 if (ret != BLUETOOTH_ERROR_NONE) {
435                         BT_ERR("Failed to add new char descriptor %d", ret);
436                         goto fail;
437                 }
438         }
439
440         /* Register service */
441         ret = bluetooth_gatt_register_service(otp_obj_path);
442         if (ret != BLUETOOTH_ERROR_NONE) {
443                 BT_ERR("Failed to register service %d", ret);
444                 goto fail;
445         }
446
447         /* Register Application */
448         ret = bluetooth_gatt_register_application();
449         if (ret != BLUETOOTH_ERROR_NONE) {
450                 BT_ERR("Failed to register application %d", ret);
451                 goto fail;
452         }
453
454         BT_DBG("-");
455         return ret;
456
457 fail:
458         delete_all_characterisitc();
459         return ret;
460 }
461
462 int _bt_otp_set_advertising_data(void)
463 {
464         int ret;
465         BT_DBG("");
466
467         /* OTP UUID */
468         guint8 data[4]  = {0x03, 0x02, 0x25, 0x18};
469         bluetooth_advertising_data_t adv;
470
471         BT_DBG("%x %x %x %x", data[0], data[1], data[2], data[3]);
472         memcpy(adv.data, data, sizeof(data));
473         ret = bluetooth_set_advertising_data(adv_handle, &adv, sizeof(data));
474         if (ret != BLUETOOTH_ERROR_NONE) {
475                 BT_ERR("Failed to set ADV data %d", ret);
476                 return ret;
477         }
478
479         ret = bluetooth_set_advertising(adv_handle, TRUE);
480         if (ret != BLUETOOTH_ERROR_NONE) {
481                 BT_ERR("Failed to set ADV %d", ret);
482                 return ret;
483         }
484
485         return 0;
486 }
487
488 void _bt_otp_start_write_on_fd()
489 {
490         char buf[BT_L2CAP_BUFFER_LEN];
491         int written = 0;
492         int read = 0;
493         FILE *fp;
494         char file_path[BT_FILE_PATH_MAX_LEN] = {0, };
495         int length;
496
497         if (!selected_object) {
498                 BT_DBG("Object not selected");
499                 goto fail;
500         }
501
502         snprintf(file_path, sizeof(file_path), "%s%s",
503                                         directory, selected_object->name);
504         BT_DBG("file_path = [%s]", file_path);
505
506         fp = fopen(file_path, "r");
507         if (!fp) {
508                 BT_DBG("fopen() failed : %s", strerror(errno));
509                 goto fail;
510         }
511
512         BT_DBG("length [%d]", oacp_read->length);
513         length = oacp_read->length;
514         if (length > BT_L2CAP_BUFFER_LEN) {
515                 int offset = oacp_read->offset;
516                 int len = 0;
517                 int written_len = 0;
518
519                 while (length > 0) {
520                         if (length < BT_L2CAP_BUFFER_LEN)
521                                 len = length;
522                         else
523                                 len = BT_L2CAP_BUFFER_LEN;
524
525                         fseek(fp, offset, SEEK_SET);
526                         read = fread(buf, 1, len, fp);
527
528                         written = write(oacp_read->fd, buf, len);
529                         BT_DBG("read [%d], Written [%d], len [%d], offset [%d], length [%d], written_len [%d]",
530                                                                                 read, written, len, offset, length, written_len);
531                         length -= len;
532                         offset += len;
533                         written_len += len;
534                 }
535         } else {
536                 read = fread(buf, 1, length, fp);
537                 written = write(oacp_read->fd, buf, oacp_read->length);
538                 BT_DBG("read [%d], Written [%d]", read, written);
539         }
540
541         fclose(fp);
542 fail:
543         g_free(oacp_read->remote_address);
544         g_free(oacp_read);
545         oacp_read = NULL;
546 }
547
548 static void _bt_otp_method(GDBusConnection *connection,
549                 const gchar *sender,
550                 const gchar *object_path,
551                 const gchar *interface_name,
552                 const gchar *method_name,
553                 GVariant *parameters,
554                 GDBusMethodInvocation *invocation,
555                 gpointer user_data)
556 {
557         BT_DBG("+");
558         int status = BLUETOOTH_ERROR_NONE;
559
560         BT_DBG("Method[%s] Object Path[%s] Interface Name[%s]",
561                         method_name, object_path, interface_name);
562
563         if (g_strcmp0(method_name, "enable") == 0) {
564                 GDir *dir = NULL;
565                 GError *error = NULL;
566                 const gchar *filename = NULL;
567                 char absolute_path[ABSOLUTE_PATH_MAX_LENGTH];
568                 GSList *list = NULL, *l = NULL;
569                 struct stat st;
570                 struct object_metadata *object = NULL;
571
572                 g_variant_get(parameters, "(s)", &directory);
573                 BT_DBG("Directory = [%s]", directory);
574
575                 dir = g_dir_open(directory, 0, &error);
576                 if (!dir) {
577                         BT_ERR("Failed to open directory: %s", error->message);
578                         g_error_free(error);
579                         status = BLUETOOTH_ERROR_INVALID_DIRECTORY;
580                         goto fail;
581                 }
582
583                 while ((filename = g_dir_read_name(dir))) {
584                         list = g_slist_append(list, (gpointer) filename);
585                 }
586
587                 g_dir_close(dir);
588
589                 if (!list) {
590                         BT_DBG("No object found in given directory");
591                         status = BLUETOOTH_ERROR_NO_OBJECTS_FOUND;
592                         goto fail;
593                 }
594
595                 if (g_slist_length(list) > 1)
596                         mutiple_obj_support = true;
597
598                 for (l = list; l != NULL; l = l->next) {
599                         if (!l->data) continue;
600                         snprintf(absolute_path, sizeof(absolute_path), "%s%s", directory,
601                                                         (char *)l->data);
602
603                         BT_INFO("filename: %s, absoulte_path: %s",
604                                         (char *)l->data, absolute_path);
605
606                         if (stat(absolute_path, &st) == -1) {
607                                 BT_INFO("stat failed: (%d)\n", errno);
608                                 continue;
609                         }
610
611                         object = g_new0(struct object_metadata, 1);
612
613                         object->name = g_strdup((const gchar *)l->data);
614                         object->type = _otp_convert_uuid_to_uuid128(UNSUPPORTED_OBJECT_TYPE_UUID);
615                         object->first_created = st.st_ctime;
616                         object->last_modified = st.st_ctime;
617                         object->curr_size = (uint32_t) st.st_size;
618                         object->alloc_size = (uint32_t) st.st_size;
619                         object->id = object_id;
620                         object->props = OBJECT_READ;
621
622                         otp_object_list = g_slist_append(otp_object_list,
623                                                                 object);
624
625                         object_id++;
626                 }
627
628                 BT_DBG("preparing");
629                 if (_bt_otp_prepare_ots() != BLUETOOTH_ERROR_NONE) {
630                         BT_ERR("Fail to prepare OTP Proxy");
631                         status = BLUETOOTH_ERROR_INTERNAL;
632                         goto fail;
633                 }
634
635                 /* If single object is supported, make that as
636                  * selected object and update the metadata for the same.
637                  */
638                 if (!mutiple_obj_support) {
639                         BT_INFO("Server supports single object");
640                         selected_object = (struct object_metadata *) g_slist_nth_data(otp_object_list, 0);
641                         if (selected_object)
642                                 update_obj_metadata_charc_value(selected_object);
643                 }
644
645                 BT_DBG("advertsing");
646                 if (_bt_otp_set_advertising_data() != BLUETOOTH_ERROR_NONE) {
647                         BT_ERR("Fail to set advertising data");
648                         status = BLUETOOTH_ERROR_INTERNAL;
649                         goto fail;
650                 }
651 fail:
652                 g_dbus_method_invocation_return_value(invocation,
653                                                 g_variant_new("(i)", status));
654
655         } else if (g_strcmp0(method_name, "disable") == 0) {
656                 g_dbus_method_invocation_return_value(invocation,
657                                                 g_variant_new("(i)", status));
658                 _bt_otp_exit();
659
660         } else if (g_strcmp0(method_name, "NewConnection") == 0) {
661                 int index;
662                 GDBusMessage *msg;
663                 GUnixFDList *fd_list;
664                 char *dev_path;
665                 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
666                 int fd;
667
668                 g_variant_get(parameters, "(oh)", &dev_path, &index);
669
670                 msg = g_dbus_method_invocation_get_message(invocation);
671                 fd_list = g_dbus_message_get_unix_fd_list(msg);
672                 if (fd_list == NULL) {
673                         BT_ERR("fd_list is NULL");
674                         return;
675                 }
676
677                 fd = g_unix_fd_list_get(fd_list, index, NULL);
678                 if (fd == -1) {
679                         BT_ERR("Invalid fd return");
680                         return;
681                 }
682
683                 _bt_convert_device_path_to_address(dev_path, address);
684
685                 BT_INFO("OTC Connected fd: %d, address %s", fd, address);
686                 if (!oacp_read) {
687                         /* OTC Connected, but no on going request */
688                         goto done;
689                 }
690                 oacp_read->fd = fd;
691                 otc_connection_status = TRUE;
692
693                 if (oacp_read->opcode == OACP_READ)
694                         _bt_otp_start_write_on_fd();
695 done:
696                 g_dbus_method_invocation_return_value(invocation, NULL);
697         }
698         BT_DBG("-");
699 }
700
701 static const GDBusInterfaceVTable otp_method_table = {
702         _bt_otp_method,
703         NULL,
704         NULL,
705 };
706
707 static void _bt_otp_on_bus_acquired(GDBusConnection *connection,
708                                 const gchar *name, gpointer user_data)
709 {
710         guint object_id;
711         GError *error = NULL;
712
713         BT_DBG("+");
714
715         g_conn = connection;
716
717         object_id = g_dbus_connection_register_object(connection,
718                                                 BT_OTP_OBJECT_PATH,
719                                                 otp_node_info->interfaces[0],
720                                                 &otp_method_table,
721                                                 NULL, NULL, &error);
722         if (object_id == 0) {
723                 BT_ERR("Failed to register method table: %s", error->message);
724                 g_error_free(error);
725                 g_dbus_node_info_unref(otp_node_info);
726         }
727
728         BT_DBG("-");
729 }
730
731 static void _bt_otp_on_name_acquired(GDBusConnection *connection,
732                                         const gchar     *name,
733                                         gpointer user_data)
734 {
735         BT_DBG("");
736 }
737
738 static void _bt_otp_on_name_lost(GDBusConnection *connection,
739                                 const gchar     *name,
740                                 gpointer user_data)
741 {
742         BT_DBG("");
743         g_object_unref(g_conn);
744         g_conn = NULL;
745         g_dbus_node_info_unref(otp_node_info);
746         g_bus_unown_name(g_owner_id);
747 }
748
749 int _bt_otp_register_interface(void)
750 {
751         BT_DBG("+");
752         GError *error = NULL;
753         guint owner_id;
754
755         otp_node_info = g_dbus_node_info_new_for_xml(otp_introspection_xml, &error);
756         if (!otp_node_info) {
757                 BT_ERR("Failed to install: %s", error->message);
758                 return BLUETOOTH_ERROR_INTERNAL;
759         }
760
761         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
762                                 BT_OTP_SERVICE_NAME,
763                                 G_BUS_NAME_OWNER_FLAGS_NONE,
764                                 _bt_otp_on_bus_acquired,
765                                 _bt_otp_on_name_acquired,
766                                 _bt_otp_on_name_lost,
767                                 NULL, NULL);
768         g_owner_id = owner_id;
769         BT_DBG("owner_id is [%d]\n", owner_id);
770
771         BT_DBG("-");
772         return BLUETOOTH_ERROR_NONE;
773 }
774
775 void _bt_otp_unregister_interface(void)
776 {
777         BT_DBG("+");
778
779         g_object_unref(g_conn);
780         g_conn = NULL;
781         g_dbus_node_info_unref(otp_node_info);
782         g_bus_unown_name(g_owner_id);
783
784         BT_DBG("-");
785         return;
786 }
787
788 void _bt_convert_device_path_to_address(const char *device_path,
789                                                 char *device_address)
790 {
791         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
792         char *dev_addr;
793
794         dev_addr = strstr(device_path, "dev_");
795         if (dev_addr != NULL) {
796                 char *pos = NULL;
797                 dev_addr += 4;
798                 g_strlcpy(address, dev_addr, sizeof(address));
799
800                 while ((pos = strchr(address, '_')) != NULL)
801                         *pos = ':';
802
803                 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
804         }
805 }
806
807 static char *__bt_extract_device_path(GVariantIter *iter, char *address)
808 {
809         char *object_path = NULL;
810         char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
811
812         /* Parse the signature: oa{sa{sv}}} */
813         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
814                         NULL)) {
815                 if (!object_path) {
816                         BT_ERR("Unable to get object path");
817                         return NULL;
818                 }
819                 _bt_convert_device_path_to_address(object_path, device_address);
820                 if (g_strcmp0(address, device_address) == 0)
821                         return g_strdup(object_path);
822
823         }
824
825         BT_ERR("Unable to get object path");
826         return NULL;
827 }
828
829 char *_bt_otp_get_device_object_path(char *address)
830 {
831         GError *err = NULL;
832         GDBusProxy *proxy = NULL;
833         GVariant *result = NULL;
834         GVariantIter *iter = NULL;
835         char *object_path = NULL;
836
837         proxy =  g_dbus_proxy_new_sync(conn,
838                         G_DBUS_PROXY_FLAGS_NONE, NULL,
839                         BT_BLUEZ_NAME,
840                         BT_MANAGER_PATH,
841                         BT_MANAGER_INTERFACE,
842                         NULL, &err);
843
844         if (!proxy) {
845                 BT_ERR("Unable to create proxy: %s", err->message);
846                 goto fail;
847         }
848
849         result = g_dbus_proxy_call_sync(proxy, "GetManagedObjects", NULL,
850                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
851         if (!result) {
852                 if (err != NULL)
853                         BT_ERR("Fail to get GetManagedObjects (Error: %s)", err->message);
854                 else
855                         BT_ERR("Fail to get GetManagedObjects");
856
857                 goto fail;
858         }
859
860         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
861         object_path = __bt_extract_device_path(iter, address);
862
863         g_variant_unref(result);
864         g_variant_iter_free(iter);
865
866 fail:
867         if (err)
868                 g_clear_error(&err);
869
870         if (proxy)
871                 g_object_unref(proxy);
872
873         return object_path;
874 }
875
876 int _bt_otp_open_otc_and_listen(char *address)
877 {
878         char *object_path;
879         GDBusProxy *device_proxy = NULL;
880         GVariant *result = NULL;
881         GError *error = NULL;
882         int ret = BLUETOOTH_ERROR_NONE;
883
884         object_path = _bt_otp_get_device_object_path(address);
885         if (object_path == NULL) {
886                 ret = BLUETOOTH_ERROR_NOT_PAIRED;
887                 goto fail;
888         }
889
890         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
891                                         NULL, BT_BLUEZ_NAME, object_path,
892                                         BT_DEVICE_INTERFACE,  NULL, NULL);
893         if (device_proxy == NULL) {
894                 ret = BLUETOOTH_ERROR_INTERNAL;
895                 goto fail;
896         }
897
898
899         result = g_dbus_proxy_call_sync(device_proxy, "ListenOtc",
900                                 NULL,
901                                 G_DBUS_CALL_FLAGS_NONE,
902                                 -1,
903                                 NULL,
904                                 &error);
905         if (result == NULL) {
906                 if (error != NULL) {
907                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
908                         g_error_free(error);
909                 }
910                 ret = BLUETOOTH_ERROR_INTERNAL;
911         }
912 fail:
913         if (object_path)
914                 g_free(object_path);
915         if (result)
916                 g_variant_unref(result);
917         if (device_proxy)
918                 g_object_unref(device_proxy);
919         return ret;
920 }
921
922 int _bt_otp_oacp_write_cb(char *value, int len, int offset,
923                                                         char *remote_addr, struct indicate_info *info)
924 {
925         int ret = OACP_SUCCESS;
926         int app_err = BLUETOOTH_ERROR_NONE;
927         int opcode = value[0];
928         uint32_t object_offset, length;
929
930         BT_INFO("OACP Opcode 0x%d", opcode);
931
932         if (!otp_object_list) {
933                 ret = OACP_INVALID_OBJ;
934                 goto fail;
935         }
936
937         switch (opcode) {
938         case OACP_CREATE:
939                 ret = OACP_OPCODE_NOT_SUPPORTED;
940                 break;
941         case OACP_DELETE:
942                 ret = OACP_OPCODE_NOT_SUPPORTED;
943                 break;
944         case OACP_CALC_CHECKSUM:
945                 ret = OACP_OPCODE_NOT_SUPPORTED;
946                 break;
947         case OACP_EXECUTE:
948                 ret = OACP_OPCODE_NOT_SUPPORTED;
949                 break;
950         case OACP_READ:
951                 object_offset = (uint32_t)(value[4] & 0xFF) << 24 |
952                                 (uint32_t)(value[3] & 0xFF) << 16 |
953                                 (uint32_t)(value[2] & 0xFF) << 8  |
954                                 (uint32_t)(value[1] & 0xFF);
955                 length = (uint32_t)(value[8] & 0xFF) << 24 |
956                         (uint32_t)(value[7] & 0xFF) << 16 |
957                         (uint32_t)(value[6] & 0xFF) << 8  |
958                         (uint32_t)(value[5] & 0xFF);
959
960                 BT_INFO("Offset = %lu, Length = %lu", object_offset, length);
961
962                 if (oacp_read && otc_connection_status) {
963                         /* Read operation already going on. */
964                         ret = OACP_OBJECT_LOCKED;
965                         goto fail;
966                 }
967                 oacp_read = g_malloc0(sizeof(struct oacp_operation));
968                 oacp_read->offset = object_offset;
969                 oacp_read->length = length;
970                 oacp_read->remote_address = g_strdup(remote_addr);
971                 oacp_read->opcode = OACP_READ;
972
973                 app_err = _bt_otp_open_otc_and_listen(remote_addr);
974                 if (app_err != BLUETOOTH_ERROR_NONE) {
975                         ret = OACP_OPERATION_FAILED;
976                         g_free(oacp_read->remote_address);
977                         g_free(oacp_read);
978                         oacp_read = NULL;
979                         goto fail;
980                 }
981                 ret = OACP_SUCCESS;
982                 break;
983         case OACP_WRITE:
984                 ret = OACP_OPCODE_NOT_SUPPORTED;
985                 break;
986         case OACP_ABORT:
987                 ret = OACP_OPCODE_NOT_SUPPORTED;
988                 break;
989         default:
990                 ret = OACP_OPCODE_NOT_SUPPORTED;
991                 break;
992         }
993 fail:
994         info->resp_opcode = OACP_RESPONSE;
995         info->req_opcode = opcode;
996         info->result_code = ret;
997         info->resp_param = NULL;
998         return app_err;
999 }
1000
1001 void convert_to_hex(struct object_metadata *object, char *type, char *value)
1002 {
1003         struct tm fc_tm;
1004
1005         BT_DBG("type : %s", type);
1006
1007         memset(value, 0, 8);
1008
1009         if (!g_strcmp0(type, "size")) {
1010
1011                 value[3] = (object->curr_size >> 24) & 0xFF;
1012                 value[2] = (object->curr_size >> 16) & 0xFF;
1013                 value[1] = (object->curr_size >> 8) & 0xFF;
1014                 value[0] = object->curr_size & 0xFF;
1015
1016                 value[7] = (object->alloc_size >> 24) & 0xFF;
1017                 value[6] = (object->alloc_size >> 16) & 0xFF;
1018                 value[5] = (object->alloc_size >> 8) & 0xFF;
1019                 value[4] = object->alloc_size & 0xFF;
1020
1021         } else if (!g_strcmp0(type, "date")) {
1022
1023                 localtime_r(&(object->first_created), &fc_tm);
1024
1025                 value[1] = ((fc_tm.tm_year+1900) >> 8) & 0xFF;
1026                 value[0] = (fc_tm.tm_year+1900) & 0xFF;
1027                 value[2] = (fc_tm.tm_mon+1) & 0xFF;
1028                 value[3] = fc_tm.tm_mday & 0xFF;
1029                 value[4] = fc_tm.tm_hour & 0xFF;
1030                 value[5] = fc_tm.tm_min & 0xFF;
1031                 value[6] = fc_tm.tm_sec & 0xFF;
1032
1033         } else if (!g_strcmp0(type, "id")) {
1034
1035                 value[5] = (object->id >> 48) & 0xFF;
1036                 value[4] = (object->id >> 32) & 0xFF;
1037                 value[3] = (object->id >> 24) & 0xFF;
1038                 value[2] = (object->id >> 16) & 0xFF;
1039                 value[1] = (object->id >> 8) & 0xFF;
1040                 value[0] = object->id & 0xFF;
1041
1042         } else if (!g_strcmp0(type, "props")) {
1043                 value[3] = (object->props >> 24) & 0xFF;
1044                 value[2] = (object->props >> 16) & 0xFF;
1045                 value[1] = (object->props >> 8) & 0xFF;
1046                 value[0] = object->props & 0xFF;
1047         }
1048 }
1049
1050 void update_obj_metadata_charc_value(struct object_metadata *object)
1051 {
1052         /* Value can be of maximum eight bytes */
1053         char value[8];
1054
1055         _bt_otp_set_char_value(otp_object_name_obj_path, object->name,
1056                                                         strlen(object->name));
1057         _bt_otp_set_char_value(otp_object_type_obj_path, object->type,
1058                                                         strlen(object->type));
1059
1060         convert_to_hex(object, "size", value);
1061         _bt_otp_set_char_value(otp_object_size_obj_path, value, 8);
1062
1063         convert_to_hex(object, "date", value);
1064         _bt_otp_set_char_value(otp_object_first_created_obj_path, value, 7);
1065         _bt_otp_set_char_value(otp_object_last_modified_obj_path, value, 7);
1066
1067         /* Object ID is optonal for single object server */
1068         if (mutiple_obj_support) {
1069                 convert_to_hex(object, "id", value);
1070                 _bt_otp_set_char_value(otp_object_id_obj_path, value, 6);
1071         }
1072
1073         convert_to_hex(object, "props", value);
1074         _bt_otp_set_char_value(otp_object_prop_obj_path, value, 4);
1075 }
1076
1077 int _bt_otp_olcp_write_cb(char *value, int len, int offset,
1078                                         struct indicate_info *info)
1079 {
1080         int ret = OLCP_SUCCESS;
1081         int opcode = value[0];
1082         struct object_metadata *object;
1083
1084         BT_INFO("OLCP Opcode 0x%d", opcode);
1085
1086         if (!otp_object_list) {
1087                 ret = OLCP_NO_OBJ;
1088                 goto fail;
1089         }
1090
1091         switch (opcode) {
1092         case OLCP_FIRST: {
1093                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, 0);
1094                 if (!object) {
1095                         ret = OLCP_OUT_OF_BOUNDS;
1096                         goto fail;
1097                 }
1098                 update_obj_metadata_charc_value(object);
1099                 selected_object = object;
1100                 obj_curr_index = 0;
1101         } break;
1102         case OLCP_LAST: {
1103                 len = g_slist_length(otp_object_list);
1104                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, len-1);
1105                 if (!object) {
1106                         ret = OLCP_OUT_OF_BOUNDS;
1107                         goto fail;
1108                 }
1109                 update_obj_metadata_charc_value(object);
1110                 selected_object = object;
1111                 obj_curr_index = len-1;
1112         } break;
1113         case OLCP_PREVIOUS: {
1114                 if (obj_curr_index == 0) {
1115                         ret = OLCP_OUT_OF_BOUNDS;
1116                         goto fail;
1117                 }
1118                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, obj_curr_index-1);
1119                 if (!object) {
1120                         ret = OLCP_OUT_OF_BOUNDS;
1121                         goto fail;
1122                 }
1123                 update_obj_metadata_charc_value(object);
1124                 selected_object = object;
1125                 obj_curr_index -= 1;
1126         } break;
1127         case OLCP_NEXT: {
1128                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, obj_curr_index+1);
1129                 if (!object) {
1130                         ret = OLCP_OUT_OF_BOUNDS;
1131                         goto fail;
1132                 }
1133                 update_obj_metadata_charc_value(object);
1134                 selected_object = object;
1135                 obj_curr_index += 1;
1136         } break;
1137         case OLCP_GOTO:
1138         case OLCP_ORDER:
1139         case OLCP_REQ_NO_OBJ:
1140         case OLCP_CLEAR_MARKING:
1141         default:
1142                 ret = OLCP_OPCODE_NOT_SUPPORTED;
1143                 break;
1144         }
1145 fail:
1146         info->resp_opcode = OLCP_RESPONSE;
1147         info->req_opcode = opcode;
1148         info->result_code = ret;
1149         info->resp_param = NULL;
1150         return BLUETOOTH_ERROR_NONE;
1151 }
1152
1153 static struct otp_char_info *otp_get_char_value(const char *path)
1154 {
1155         GSList *tmp = NULL;
1156
1157         for (tmp = otp_char_list; tmp != NULL; tmp = tmp->next) {
1158                 if (tmp->data) {
1159                         struct otp_char_info *char_info = tmp->data;
1160                         if (!g_strcmp0(char_info->char_path, path))
1161                                 return char_info;
1162                 }
1163         }
1164
1165         return NULL;
1166 }
1167
1168 int _bt_otp_read_cb(const char *obj_path, char **value, int *len)
1169 {
1170         struct otp_char_info *info = NULL;
1171
1172         if (!obj_path) {
1173                 BT_ERR("Wrong Obj path");
1174                 return BLUETOOTH_ERROR_INTERNAL;
1175         }
1176
1177         if (g_strcmp0(obj_path, otp_feature_obj_path)) {
1178                 if (!selected_object) {
1179                         return BLUETOOTH_ERROR_OBJECT_NOT_SELECTED;
1180                 }
1181         }
1182
1183         info = otp_get_char_value(obj_path);
1184         if (info) {
1185                 if (info->char_value == NULL || info->value_length == 0)
1186                         return BLUETOOTH_ERROR_INTERNAL;
1187
1188                 *len = info->value_length;
1189                 *value = (char *)malloc(sizeof(char)*(*len));
1190                 memcpy(*value, info->char_value, *len);
1191
1192                 return BLUETOOTH_ERROR_NONE;
1193         } else {
1194                 return BLUETOOTH_ERROR_INTERNAL;
1195         }
1196 }
1197
1198 static void _otp_convert_address_to_hex(bluetooth_device_address_t *addr_hex,
1199                                                         const char *addr_str)
1200 {
1201         int i = 0;
1202         unsigned int addr[BLUETOOTH_ADDRESS_LENGTH] = { 0, };
1203
1204         if (addr_str == NULL || addr_str[0] == '\0')
1205                 return;
1206
1207         i = sscanf(addr_str, "%X:%X:%X:%X:%X:%X", &addr[0], &addr[1],
1208                                 &addr[2], &addr[3], &addr[4], &addr[5]);
1209         if (i != BLUETOOTH_ADDRESS_LENGTH)
1210                 BT_ERR("Invalid format string - [%s]", addr_str);
1211
1212         for (i = 0; i < BLUETOOTH_ADDRESS_LENGTH; i++)
1213                 addr_hex->addr[i] = (unsigned char)addr[i];
1214 }
1215
1216 static void _bt_otp_send_indication(const char *obj_path,
1217                                 struct indicate_info *info,
1218                                 bluetooth_device_address_t *remote_address)
1219 {
1220         int ret = BLUETOOTH_ERROR_NONE;
1221         char value[7] = {0x00};
1222
1223         BT_DBG("");
1224
1225         value[0] = info->resp_opcode & 0xFF;
1226         value[1] = info->req_opcode & 0xFF;
1227         value[2] = info->result_code & 0xFF;
1228         if (info->resp_param) {
1229                 value[6] = (info->resp_param[3] >> 24) & 0xFF;
1230                 value[5] = (info->resp_param[4] >> 16) & 0xFF;
1231                 value[4] = (info->resp_param[5] >> 8) & 0xFF;
1232                 value[3] = info->resp_param[6] & 0xFF;
1233         }
1234
1235         BT_DBG("Opcode: %d", value[1]);
1236
1237         /* Store the status value */
1238         _bt_otp_set_char_value(obj_path, value, 7);
1239
1240         /* Send indication */
1241         ret = bluetooth_gatt_server_set_notification(obj_path, remote_address);
1242         if (ret != BLUETOOTH_ERROR_NONE) {
1243                 BT_ERR("_bt_otp_send_control_point_indication failed");
1244                 return;
1245         }
1246         ret = bluetooth_gatt_update_characteristic(obj_path, value, 7);
1247         if (ret != BLUETOOTH_ERROR_NONE) {
1248                 BT_ERR("_bt_otp_send_control_point_indication failed");
1249                 return;
1250         }
1251 }
1252
1253 void _bt_otp_gatt_char_property_changed_event(GVariant *msg,
1254                                 const char *path)
1255 {
1256         int result = BLUETOOTH_ERROR_NONE;
1257         GVariantIter value_iter;
1258         const char *property = NULL;
1259         const char *char_path = NULL;
1260         const char *svc_handle = NULL;
1261         GVariant *var = NULL;
1262         GVariant *val = NULL;
1263         g_variant_iter_init(&value_iter, msg);
1264
1265         while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &var))) {
1266
1267                 if (property == NULL) {
1268                         BT_ERR("Property NULL");
1269                         return;
1270                 }
1271
1272                 if (!g_strcmp0(property, "WriteValue")) {
1273                         int len = 0;
1274                         BT_INFO("WriteValue");
1275                         BT_INFO("Type '%s'\n", g_variant_get_type_string(var));
1276
1277                         if (var) {
1278                                 bluetooth_device_address_t addr_hex = { {0,} };
1279                                 gchar *addr = NULL;
1280                                 guint8 req_id = 1;
1281                                 guint16 offset = 0;
1282                                 char *value = NULL;
1283                                 struct indicate_info info;
1284                                 g_variant_get(var, "(&s&s&syq@ay)",
1285                                                 &char_path, &svc_handle,
1286                                                 &addr, &req_id, &offset, &val);
1287
1288                                 len = g_variant_get_size(val);
1289
1290                                 BT_DBG("Len = %d, BT_ADDR = %s", len, addr);
1291
1292                                 value = (char *) g_variant_get_data(val);
1293                                 _otp_convert_address_to_hex(&addr_hex, addr);
1294
1295                                 if (len != 0) {
1296                                         if (!g_strcmp0(char_path, otp_oacp_obj_path)) {
1297                                                 result = _bt_otp_oacp_write_cb(value, len, offset, addr, &info);
1298                                         } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) {
1299                                                 result = _bt_otp_olcp_write_cb(value, len, offset, &info);
1300                                         } else {
1301                                                 BT_ERR("Wrong Object Path %s", char_path);
1302                                                 result = BLUETOOTH_ERROR_INTERNAL;
1303                                         }
1304                                         bluetooth_gatt_send_response(req_id,
1305                                         BLUETOOTH_GATT_ATT_REQUEST_TYPE_WRITE,
1306                                                         result, 0, NULL, 0);
1307
1308                                         /* Send indication for CPs */
1309                                         if (!g_strcmp0(char_path, otp_oacp_obj_path)) {
1310                                                 if (OACP_indicate) {
1311                                                         _bt_otp_send_indication(char_path, &info, &addr_hex);
1312                                                 }
1313                                         } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) {
1314                                                 if (OLCP_indicate) {
1315                                                         _bt_otp_send_indication(char_path, &info, &addr_hex);
1316                                                 }
1317                                         }
1318                                 } else {
1319                                         BT_ERR("Array Len 0");
1320                                 }
1321                         } else {
1322                                 BT_ERR("var==NULL");
1323                         }
1324                 } else if (!g_strcmp0(property, "ReadValue")) {
1325                         gchar *addr = NULL;
1326                         guint8 req_id = 1;
1327                         guint16 offset = 0;
1328                         char *value = NULL;
1329                         int len = 0;
1330                         result = BLUETOOTH_ERROR_NONE;
1331
1332                         BT_INFO("ReadValue");
1333                         BT_INFO("Type '%s'\n", g_variant_get_type_string(var));
1334
1335                         g_variant_get(var, "(&s&s&syq)", &char_path,
1336                                         &svc_handle, &addr, &req_id, &offset);
1337
1338                         result = _bt_otp_read_cb(char_path, &value, &len);
1339
1340                         if (result != BLUETOOTH_ERROR_NONE) {
1341                                 BT_ERR("ReadValue failed %s", char_path);
1342                                 bluetooth_gatt_send_response(req_id,
1343                                 BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ,
1344                                                 result, offset, NULL, 0);
1345                         } else {
1346                                 bluetooth_gatt_send_response(req_id,
1347                                 BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ,
1348                                                 result, offset, value, len);
1349                                 if (value)
1350                                         g_free(value);
1351                         }
1352                 } else if (!g_strcmp0(property, "NotificationStateChanged")) {
1353                         gboolean indicate = FALSE;
1354
1355                         g_variant_get(var, "(&s&sb)", &char_path,
1356                                                 &svc_handle, &indicate);
1357
1358                         BT_INFO("%s : [%s]", property,
1359                                 indicate ? "StartNotify" : "StopNotify");
1360                         BT_INFO("Type '%s'\n", g_variant_get_type_string(var));
1361
1362                         if (!g_strcmp0(char_path, otp_oacp_obj_path)) {
1363                                 OACP_indicate = indicate;
1364                         } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) {
1365                                 OLCP_indicate = indicate;
1366                         }
1367                 }
1368         }
1369         return;
1370 }
1371
1372 void _bt_otp_property_event_filter(GDBusConnection *connection,
1373                                         const gchar *sender_name,
1374                                         const gchar *object_path,
1375                                         const gchar *interface_name,
1376                                         const gchar *signal_name,
1377                                         GVariant *parameters,
1378                                         gpointer user_data)
1379 {
1380         GVariant *value;
1381
1382         if (signal_name == NULL) {
1383                 BT_ERR("Wrong Signal");
1384                 return;
1385         }
1386
1387         if (g_strcmp0(signal_name, PROPERTIES_CHANGED) == 0) {
1388
1389                 g_variant_get(parameters, "(@a{sv}@as)", &value, NULL);
1390                 _bt_otp_gatt_char_property_changed_event(value, object_path);
1391         }
1392 }
1393
1394 void _bt_otp_adapter_event_filter(GDBusConnection *connection,
1395                                         const gchar *sender_name,
1396                                         const gchar *object_path,
1397                                         const gchar *interface_name,
1398                                         const gchar *signal_name,
1399                                         GVariant *parameters,
1400                                         gpointer user_data)
1401 {
1402         if (signal_name == NULL) {
1403                 BT_ERR("Wrong Signal");
1404                 return;
1405         }
1406
1407         BT_INFO("Interface %s, Signal %s", interface_name, signal_name);
1408
1409         if (g_strcmp0(interface_name, BT_OTP_INTERFACE_NAME) == 0) {
1410                 if (strcasecmp(signal_name, BLE_DISABLED) == 0) {
1411                         _bt_otp_exit();
1412                 }
1413         }
1414 }
1415
1416 void _bt_otc_disconnected_cb(GDBusConnection *connection,
1417                                         const gchar *sender_name,
1418                                         const gchar *object_path,
1419                                         const gchar *interface_name,
1420                                         const gchar *signal_name,
1421                                         GVariant *parameters,
1422                                         gpointer user_data)
1423 {
1424         if (signal_name == NULL) {
1425                 BT_ERR("Wrong Signal");
1426                 return;
1427         }
1428
1429         BT_INFO("Interface %s, Signal %s", interface_name, signal_name);
1430
1431         if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) {
1432                 if (strcasecmp(signal_name, OTC_DISCONNECTED) == 0) {
1433                         BT_DBG("OTC Channel Disconnected dev_path[%s]",
1434                                                                                         object_path);
1435                         otc_connection_status = FALSE;
1436                         if (oacp_read) {
1437                                 g_free(oacp_read->remote_address);
1438                                 g_free(oacp_read);
1439                         }
1440                 }
1441         }
1442 }
1443
1444 int _bt_otp_init_event_receiver()
1445 {
1446         BT_DBG("+");
1447         GError *error = NULL;
1448
1449         if (conn == NULL) {
1450                 conn =  g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1451                 if (error != NULL) {
1452                         BT_ERR("ERROR: Can't get on system bus [%s]",
1453                                                         error->message);
1454                         g_clear_error(&error);
1455                 }
1456         }
1457
1458         property_sub_id = g_dbus_connection_signal_subscribe(conn,
1459                                 NULL,
1460                                 BT_OTP_INTERFACE_NAME,
1461                                 PROPERTIES_CHANGED,
1462                                 BT_OTP_OBJECT_PATH, NULL, 0,
1463                                 _bt_otp_property_event_filter,
1464                                 NULL, NULL);
1465
1466         adapter_sub_id = g_dbus_connection_signal_subscribe(conn,
1467                                 NULL,
1468                                 BT_OTP_INTERFACE_NAME,
1469                                 BLE_DISABLED,
1470                                 BT_OTP_OBJECT_PATH, NULL, 0,
1471                                 _bt_otp_adapter_event_filter,
1472                                 NULL, NULL);
1473
1474         device_sub_id = g_dbus_connection_signal_subscribe(conn,
1475                                         NULL, BT_DEVICE_INTERFACE,
1476                                         OTC_DISCONNECTED, NULL, NULL, 0,
1477                                         _bt_otc_disconnected_cb,
1478                                         NULL, NULL);
1479
1480         BT_DBG("-");
1481         return 0;
1482 }
1483
1484 void _bt_otp_deinit_event_receiver(void)
1485 {
1486         BT_DBG("+");
1487
1488         g_dbus_connection_signal_unsubscribe(conn, property_sub_id);
1489         g_dbus_connection_signal_unsubscribe(conn, adapter_sub_id);
1490         g_dbus_connection_signal_unsubscribe(conn, device_sub_id);
1491         conn = NULL;
1492
1493         BT_DBG("-");
1494 }
1495
1496 static void _bt_otp_sig_handler(int sig)
1497 {
1498         BT_DBG("+");
1499         switch (sig) {
1500         case SIGTERM:
1501                 BT_DBG("caught signal - sigterm\n");
1502                 break;
1503         case SIGINT:
1504                 BT_DBG("caught signal - sigint\n");
1505                 break;
1506         case SIGKILL:
1507                 BT_DBG("caught signal - sigkill\n");
1508                 break;
1509         default:
1510                 BT_DBG("caught signal %d and ignored\n", sig);
1511                 break;
1512         }
1513         BT_DBG("-");
1514 }
1515
1516 /* OTP Service Main loop */
1517 int main(void)
1518 {
1519         struct sigaction sa;
1520         BT_ERR("Starting the bt-otp daemon");
1521
1522         memset(&sa, 0, sizeof(sa));
1523         sa.sa_handler = _bt_otp_sig_handler;
1524         sa.sa_flags = SA_SIGINFO;
1525         sigaction(SIGINT, &sa, NULL);
1526         sigaction(SIGTERM, &sa, NULL);
1527         sigaction(SIGKILL, &sa, NULL);
1528
1529         if (_bt_otp_register_interface() != BLUETOOTH_ERROR_NONE) {
1530                 BT_ERR("Fail to register otp service");
1531                 return -4;
1532         }
1533
1534         if (_bt_otp_init_event_receiver() != BLUETOOTH_ERROR_NONE) {
1535                 BT_ERR("Fail to init event reciever");
1536                 return -5;
1537         }
1538
1539         main_loop = g_main_loop_new(NULL, FALSE);
1540
1541         g_main_loop_run(main_loop);
1542
1543         BT_DBG("g_main_loop_quit called!");
1544
1545         if (main_loop != NULL) {
1546                 g_main_loop_unref(main_loop);
1547         }
1548
1549         return 0;
1550 }