Handle the pending dbus calls before termination
[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 #include <dlfcn.h>
31 #include <arpa/inet.h>
32
33 #include "bt-otpserver.h"
34 #include "bluetooth-api.h"
35
36 #include <cynara-client.h>
37
38 #undef LOG_TAG
39 #define LOG_TAG "BLUETOOTH_OTP"
40
41 #define BT_INFO(fmt, arg...) SLOGI(fmt, ##arg)
42 #define BT_ERR(fmt, arg...) SLOGE(fmt, ##arg)
43 #define BT_DBG(fmt, arg...) SLOGD(fmt, ##arg)
44
45 /* OTP object paths */
46 char *otp_obj_path = NULL;
47 char *otp_feature_obj_path = NULL;
48 char *otp_object_name_obj_path = NULL;
49 char *otp_object_type_obj_path = NULL;
50 char *otp_object_size_obj_path = NULL;
51 char *otp_object_first_created_obj_path = NULL;
52 char *otp_object_last_modified_obj_path = NULL;
53 char *otp_object_id_obj_path = NULL;
54 char *otp_object_prop_obj_path = NULL;
55 char *otp_oacp_obj_path = NULL;
56 char *otp_olcp_obj_path = NULL;
57 char *otp_oacp_desc_obj_path = NULL;
58 char *otp_olcp_desc_obj_path = NULL;
59
60 static GMainLoop *main_loop;
61 GDBusNodeInfo *otp_node_info = NULL;
62 static GDBusConnection *conn;
63 static GDBusConnection *g_conn;
64
65 static int property_sub_id = -1;
66 static int adapter_sub_id = -1;
67 static int device_sub_id = -1;
68 static int device_property_sub_id = -1;
69 static guint g_owner_id = 0;
70 static guint server_watch_id = 0;
71
72 struct otp_char_info {
73         gchar *char_path;
74         gchar *char_value;
75         int value_length;
76 };
77
78 struct indicate_info {
79         uint8_t resp_opcode;
80         uint8_t req_opcode;
81         uint8_t result_code;
82         uint8_t *resp_param;
83 };
84
85 /* Object metadata */
86 struct object_metadata {
87         gchar *name;
88         gchar *type;
89         uint32_t curr_size;
90         uint32_t alloc_size;
91         time_t first_created;
92         time_t last_modified;
93         uint64_t id;
94         uint32_t props;
95 };
96
97 struct oacp_operation {
98         char *remote_address;
99         uint32_t offset;
100         uint32_t length;
101         uint8_t opcode;
102         uint32_t length_sofar;
103         uint8_t mode;
104         int fd;
105         FILE *fp;
106 };
107
108 static struct object_metadata *selected_object = NULL;
109 static uint64_t object_id = OBJECT_START_ID;
110 static GSList *otp_object_list = NULL;
111 static GSList *otp_char_list = NULL;
112 static guint curr_obj_index;
113 static int adv_handle = 0;
114 static gboolean OACP_indicate = FALSE;
115 static gboolean OLCP_indicate = FALSE;
116 char *directory = NULL;
117 gboolean mutiple_obj_support = false;
118 static gboolean otc_connection_status = FALSE;
119 struct oacp_operation *oacp_op = NULL;
120 unsigned int timeout_id;
121 unsigned int oacp_create_timeout_id;
122 uint64_t curr_obj_id, prev_obj_id;
123 static gboolean oacp_create = FALSE;
124
125 static const gchar otp_introspection_xml[] =
126 "<node name='/'>"
127 "       <interface name='org.projectx.otp_service'>"
128 "               <method name='enable'>"
129 "                       <arg type='s' name='directory'/>"
130 "                       <arg type='i' name='status' direction='out'/>"
131 "               </method>"
132 "               <method name='disable'>"
133 "                       <arg type='i' name='status' direction='out'/>"
134 "               </method>"
135 "     <method name='NewConnection'>"
136 "          <arg type='o' name='object' direction='in'/>"
137 "          <arg type='h' name='fd' direction='in'/>"
138 "     </method>"
139 "       </interface>"
140 "</node>";
141
142 void _bt_otp_deinit_event_receiver(void);
143 void _bt_otp_unregister_interface(void);
144 void update_obj_metadata_charc_value(struct object_metadata *object);
145 void _bt_convert_device_path_to_address(const char *device_path,
146                                                 char *device_address);
147 int _bt_otp_open_otc_and_listen(char *address, char *method);
148 void _bt_otp_restore_old_object();
149 struct object_metadata *_bt_otp_client_find_object(GSList *list,
150                                                                         uint64_t id, guint *index);
151
152 static void delete_all_objects(void)
153 {
154         GSList *tmp = NULL;
155         for (tmp = otp_object_list; tmp != NULL; tmp = tmp->next) {
156                 if (tmp->data) {
157                         struct object_metadata *obj_info = tmp->data;
158                         if (obj_info->name)
159                                 g_free(obj_info->name);
160                         if (obj_info->type)
161                                 g_free(obj_info->type);
162                         otp_object_list = g_slist_delete_link(otp_object_list, tmp->data);
163                 }
164         }
165         g_slist_free(otp_object_list);
166         otp_object_list = NULL;
167 }
168
169 static void delete_all_characterisitc(void)
170 {
171         GSList *tmp = NULL;
172         for (tmp = otp_char_list; tmp != NULL; tmp = tmp->next) {
173                 if (tmp->data) {
174                         struct otp_char_info *char_info = tmp->data;
175                         if (char_info->char_path)
176                                 g_free(char_info->char_path);
177                         if (char_info->char_value)
178                                 g_free(char_info->char_value);
179                         otp_char_list = g_slist_delete_link(otp_char_list, tmp->data);
180                 }
181         }
182         g_slist_free(otp_char_list);
183         otp_char_list = NULL;
184 }
185
186 void _bt_otp_exit(void)
187 {
188         int ret;
189         BT_DBG("");
190
191         if (otp_char_list)
192                 delete_all_characterisitc();
193
194         if (otp_object_list)
195                 delete_all_objects();
196
197         ret = bluetooth_gatt_deinit();
198         if (ret != BLUETOOTH_ERROR_NONE)
199                 BT_ERR("Failed to Deinit GATT %d", ret);
200
201         _bt_otp_deinit_event_receiver();
202
203         _bt_otp_unregister_interface();
204
205         /* TODO: Advertising is not getting stopped by this API.
206          * This is because OTP_SERVER_DEINIT dbus call is blocking
207          * BT_SET_ADVERTISING_DATA dbus call. But now advertisment
208          * is stopped because of terminated process logic.
209          */
210         ret = bluetooth_set_advertising(adv_handle, FALSE);
211         if (ret != BLUETOOTH_ERROR_NONE)
212                 BT_ERR("Failed to stop ADV %d", ret);
213
214         if (main_loop != NULL)
215                 g_main_loop_quit(main_loop);
216 }
217
218 static void _bt_otp_set_char_value(const char *obj_path,
219                                 const char *value, int value_length)
220 {
221         GSList *tmp = NULL;
222
223         if (!value)
224                 return;
225         for (tmp = otp_char_list; tmp != NULL; tmp = tmp->next) {
226                 if (tmp->data) {
227                         struct otp_char_info *char_info = tmp->data;
228                         if (!g_strcmp0(char_info->char_path, obj_path)) {
229                                 char_info->char_value = g_try_realloc(char_info->char_value, value_length);
230                                 if (char_info->char_value) {
231                                         memcpy(char_info->char_value, value, value_length);
232                                         char_info->value_length = value_length;
233                                 }
234                                 return;
235                         }
236                 }
237         }
238         return;
239 }
240
241 int add_new_characteristic(const char *char_uuid, bt_gatt_permission_t perms,
242                 bt_gatt_characteristic_property_t props, char **obj_path)
243 {
244         int ret = BLUETOOTH_ERROR_NONE;
245         struct otp_char_info *char_info = NULL;
246
247         ret = bluetooth_gatt_add_new_characteristic(otp_obj_path,
248                                         char_uuid, perms, props, obj_path);
249         if (ret != BLUETOOTH_ERROR_NONE) {
250                 BT_ERR("Failed to add new char %d", ret);
251                 return ret;
252         }
253
254         char_info = g_new0(struct otp_char_info, 1);
255         char_info->char_path = g_strdup(*obj_path);
256         otp_char_list = g_slist_append(otp_char_list, char_info);
257
258         return ret;
259 }
260
261 static char *_otp_convert_uuid_to_uuid128(const char *uuid)
262 {
263         int len;
264         char *uuid128;
265
266         len = strlen(uuid);
267
268         switch (len) {
269         case 4:
270                 /* UUID 16bits */
271                 uuid128 = g_strdup_printf("0000%s-0000-1000-8000-00805f9b34fb",
272                                                                         uuid);
273                 break;
274
275         case 8:
276                 /* UUID 32bits */
277                 uuid128 = g_strdup_printf("%s-0000-1000-8000-00805f9b34fb",
278                                                                         uuid);
279                 break;
280
281         case 36:
282                 /* UUID 128bits */
283                 uuid128 = strdup(uuid);
284                 break;
285
286         default:
287                 return NULL;
288         }
289
290         return uuid128;
291 }
292
293 int _bt_otp_prepare_ots(void)
294 {
295         BT_DBG("+");
296         int ret = BLUETOOTH_ERROR_NONE;
297         char *service_uuid;
298         char *char_uuid;
299         char *desc_uuid;
300         bt_gatt_characteristic_property_t props;
301         bt_gatt_permission_t perms;
302         char supp_feat[OTP_FEATURE_LENGTH] = { 0x3B, 0x00, 0x00, 0x00,
303                                                 0x01, 0x00, 0x00, 0x00 };
304
305         ret = bluetooth_gatt_init();
306         if (ret != BLUETOOTH_ERROR_NONE) {
307                 BT_ERR("Failed to Init GATT %d", ret);
308                 goto fail;
309         }
310
311         service_uuid = _otp_convert_uuid_to_uuid128(OTP_UUID);
312         ret = bluetooth_gatt_add_service(service_uuid, &otp_obj_path);
313         if (ret != BLUETOOTH_ERROR_NONE) {
314                 BT_ERR("Failed to add service %d", ret);
315                 goto fail;
316         }
317
318         /* Characteristic OTP Feature */
319         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
320         perms = BLUETOOTH_GATT_PERMISSION_READ;
321         char_uuid = _otp_convert_uuid_to_uuid128(OTP_FEATURE_UUID);
322         ret = add_new_characteristic(char_uuid, perms, props,
323                                                 &otp_feature_obj_path);
324         if (ret != BLUETOOTH_ERROR_NONE)
325                 goto fail;
326
327         ret = bluetooth_gatt_set_characteristic_value(otp_feature_obj_path,
328                                                 supp_feat, OTP_FEATURE_LENGTH);
329         if (ret != BLUETOOTH_ERROR_NONE) {
330                 BT_ERR("Failed to set char value %d", ret);
331                 return ret;
332         }
333
334         _bt_otp_set_char_value(otp_feature_obj_path, supp_feat,
335                                                 OTP_FEATURE_LENGTH);
336
337         /* Characteristic Object Name */
338         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ |
339                 BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
340         perms = BLUETOOTH_GATT_PERMISSION_READ |
341                 BLUETOOTH_GATT_PERMISSION_WRITE;
342         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_NAME_UUID);
343         ret = add_new_characteristic(char_uuid, perms, props,
344                                         &otp_object_name_obj_path);
345         if (ret != BLUETOOTH_ERROR_NONE)
346                 goto fail;
347
348         /* Characteristic Object Type */
349         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
350         perms = BLUETOOTH_GATT_PERMISSION_READ;
351         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_TYPE_UUID);
352         ret = add_new_characteristic(char_uuid, perms, props,
353                                         &otp_object_type_obj_path);
354         if (ret != BLUETOOTH_ERROR_NONE)
355                 goto fail;
356
357         /* Characteristic Object Size */
358         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
359         perms = BLUETOOTH_GATT_PERMISSION_READ;
360         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_SIZE_UUID);
361         ret = add_new_characteristic(char_uuid, perms, props,
362                                         &otp_object_size_obj_path);
363         if (ret != BLUETOOTH_ERROR_NONE)
364                 goto fail;
365
366         /* Characteristic Object First-Created */
367         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ |
368                 BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
369         perms = BLUETOOTH_GATT_PERMISSION_READ |
370                 BLUETOOTH_GATT_PERMISSION_WRITE;
371         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_FIRST_CREATED_UUID);
372         ret = add_new_characteristic(char_uuid, perms, props,
373                                         &otp_object_first_created_obj_path);
374         if (ret != BLUETOOTH_ERROR_NONE)
375                 goto fail;
376
377         /* Characteristic Object Last-Modified */
378         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ |
379                 BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
380         perms = BLUETOOTH_GATT_PERMISSION_READ |
381                 BLUETOOTH_GATT_PERMISSION_WRITE;
382         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_LAST_MODIFIED_UUID);
383         ret = add_new_characteristic(char_uuid, perms, props,
384                                 &otp_object_last_modified_obj_path);
385         if (ret != BLUETOOTH_ERROR_NONE)
386                 goto fail;
387
388         /* Object ID is mandatory for mutiple object server */
389         if (mutiple_obj_support) {
390                 /* Characteristic Object ID */
391                 props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
392                 perms = BLUETOOTH_GATT_PERMISSION_READ;
393                 char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_ID_UUID);
394                 ret = add_new_characteristic(char_uuid, perms, props,
395                                                 &otp_object_id_obj_path);
396                 if (ret != BLUETOOTH_ERROR_NONE)
397                         goto fail;
398         }
399
400         /* Characteristic Object Properties */
401         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ |
402                         BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
403         perms = BLUETOOTH_GATT_PERMISSION_READ |
404                         BLUETOOTH_GATT_PERMISSION_WRITE;
405         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_PROP_UUID);
406         ret = add_new_characteristic(char_uuid, perms, props,
407                                         &otp_object_prop_obj_path);
408         if (ret != BLUETOOTH_ERROR_NONE)
409                 goto fail;
410
411         /* Characteristic OACP */
412         props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE |
413                 BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
414         perms = BLUETOOTH_GATT_PERMISSION_WRITE;
415         char_uuid = _otp_convert_uuid_to_uuid128(OTP_OACP_UUID);
416         ret = add_new_characteristic(char_uuid, perms, props,
417                                                 &otp_oacp_obj_path);
418         if (ret != BLUETOOTH_ERROR_NONE)
419                 goto fail;
420
421         /* CCCD for OACP */
422         desc_uuid = _otp_convert_uuid_to_uuid128(OTP_CP_CCC_DESC_UUID);
423         perms = BLUETOOTH_GATT_PERMISSION_READ |
424                 BLUETOOTH_GATT_PERMISSION_WRITE;
425         ret = bluetooth_gatt_add_descriptor(otp_oacp_obj_path, desc_uuid,
426                                                 perms, &otp_oacp_desc_obj_path);
427         if (ret != BLUETOOTH_ERROR_NONE) {
428                 BT_ERR("Failed to add new char descriptor %d", ret);
429                 goto fail;
430         }
431
432         /* OLCP Characteristics is not required
433          * for single object server
434          */
435         if (mutiple_obj_support) {
436                 /* Characteristic OLCP */
437                 props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE |
438                         BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
439                 perms = BLUETOOTH_GATT_PERMISSION_WRITE;
440                 char_uuid = _otp_convert_uuid_to_uuid128(OTP_OLCP_UUID);
441                 ret = add_new_characteristic(char_uuid, perms, props,
442                                                         &otp_olcp_obj_path);
443                 if (ret != BLUETOOTH_ERROR_NONE)
444                         goto fail;
445
446                 /* CCCD for OLCP */
447                 desc_uuid = _otp_convert_uuid_to_uuid128(OTP_CP_CCC_DESC_UUID);
448                 perms = BLUETOOTH_GATT_PERMISSION_READ |
449                         BLUETOOTH_GATT_PERMISSION_WRITE;
450                 ret = bluetooth_gatt_add_descriptor(otp_olcp_obj_path, desc_uuid,
451                                                         perms, &otp_olcp_desc_obj_path);
452                 if (ret != BLUETOOTH_ERROR_NONE) {
453                         BT_ERR("Failed to add new char descriptor %d", ret);
454                         goto fail;
455                 }
456         }
457
458         /* Register service */
459         ret = bluetooth_gatt_register_service(otp_obj_path);
460         if (ret != BLUETOOTH_ERROR_NONE) {
461                 BT_ERR("Failed to register service %d", ret);
462                 goto fail;
463         }
464
465         /* Register Application */
466         ret = bluetooth_gatt_register_application();
467         if (ret != BLUETOOTH_ERROR_NONE) {
468                 BT_ERR("Failed to register application %d", ret);
469                 goto fail;
470         }
471
472         BT_DBG("-");
473         return ret;
474
475 fail:
476         delete_all_characterisitc();
477         return ret;
478 }
479
480 int _bt_otp_set_advertising_data(void)
481 {
482         int ret;
483         BT_DBG("");
484
485         /* OTP UUID */
486         guint8 data[4]  = {0x03, 0x02, 0x25, 0x18};
487         bluetooth_advertising_data_t adv;
488
489         BT_DBG("%x %x %x %x", data[0], data[1], data[2], data[3]);
490         memcpy(adv.data, data, sizeof(data));
491         ret = bluetooth_set_advertising_data(adv_handle, &adv, sizeof(data));
492         if (ret != BLUETOOTH_ERROR_NONE) {
493                 BT_ERR("Failed to set ADV data %d", ret);
494                 return ret;
495         }
496
497         ret = bluetooth_set_advertising(adv_handle, TRUE);
498         if (ret != BLUETOOTH_ERROR_NONE) {
499                 BT_ERR("Failed to set ADV %d", ret);
500                 return ret;
501         }
502
503         return 0;
504 }
505
506 void _bt_otp_start_write_on_fd()
507 {
508         char buf[BT_L2CAP_BUFFER_LEN];
509         int written;
510         int read;
511         int len;
512         FILE *fp;
513         char file_path[BT_FILE_PATH_MAX_LEN] = {0, };
514         int length;
515         char err_msg[256] = {0, };
516
517         snprintf(file_path, BT_FILE_PATH_MAX_LEN, "%s%s",
518                                         directory, selected_object->name);
519         BT_DBG("file_path = [%s]", file_path);
520
521         fp = fopen(file_path, "r");
522         if (!fp) {
523                 cynara_strerror(errno, err_msg, sizeof(err_msg));
524                 BT_ERR("fopen() failed : %s", err_msg);
525                 return;
526         }
527
528         BT_DBG("length [%d]", oacp_op->length);
529         length = oacp_op->length;
530
531         while (length > 0) {
532                 if (length < BT_L2CAP_BUFFER_LEN)
533                         len = length;
534                 else
535                         len = BT_L2CAP_BUFFER_LEN;
536
537                 read = fread(buf, 1, len, fp);
538                 written = write(oacp_op->fd, buf, len);
539
540                 if (written < 0)
541                         goto fail;
542
543                 length -= written;
544
545                 BT_DBG("read [%d], written [%d], rem_len [%d]",
546                                                 read, written, length);
547         }
548 fail:
549         fclose(fp);
550 }
551
552
553 static bool __bt_otc_connection_timeout_cb(gpointer user_data)
554 {
555         int err = BLUETOOTH_ERROR_NONE;
556         char *remote_addr = oacp_op->remote_address;
557
558         err = _bt_otp_open_otc_and_listen(remote_addr, "DisconnectOtc");
559         if (err != BLUETOOTH_ERROR_NONE)
560                 BT_ERR("Disconnect OTC failed");
561
562         return TRUE;
563 }
564
565 static gboolean __server_data_received_cb(GIOChannel *chan, GIOCondition cond,
566                                                                 gpointer data)
567 {
568         char *remote_addr = oacp_op->remote_address;
569         GIOStatus status = G_IO_STATUS_NORMAL;
570         GError *err = NULL;
571         char *buffer = NULL;
572         gsize len = 0;
573         int written;
574         int fd;
575         char err_msg[256] = {0, };
576
577         BT_DBG("");
578
579         fd = g_io_channel_unix_get_fd(chan);
580         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
581                 otc_connection_status = FALSE;
582                 BT_ERR("OTC disconnected: %d", fd);
583                 close(fd);
584                 g_source_remove(server_watch_id);
585                 return FALSE;
586         }
587
588         buffer = g_malloc0(BT_L2CAP_BUFFER_LEN + 1);
589
590         status = g_io_channel_read_chars(chan, buffer,
591                                                         BT_L2CAP_BUFFER_LEN,
592                                                         &len, &err);
593         if (status != G_IO_STATUS_NORMAL) {
594                 BT_ERR("IO Channel read is failed with %d", status);
595
596                 g_free(buffer);
597                 if (err) {
598                         otc_connection_status = FALSE;
599                         BT_ERR("IO Channel read error [%s]", err->message);
600                         if (status == G_IO_STATUS_ERROR) {
601                                 BT_ERR("cond : %d", cond);
602                                 g_error_free(err);
603                                 close(fd);
604                                 g_source_remove(server_watch_id);
605                                 return FALSE;
606                         }
607                         g_error_free(err);
608                 }
609                 return TRUE;
610         }
611
612         BT_DBG("Received data length %zu, remote_addr = %s", len, remote_addr);
613
614         if (!oacp_op->fp) {
615                 char file_path[BT_FILE_PATH_MAX_LEN] = {0, };
616                 FILE *fp = NULL;
617
618                 if (!selected_object) {
619                         BT_DBG("Object not selected");
620                         goto fail;
621                 }
622
623                 snprintf(file_path, BT_FILE_PATH_MAX_LEN, "%s%s",
624                                                 directory, selected_object->name);
625
626                 BT_DBG("file_path = [%s]", file_path);
627                 fp = fopen(file_path, "w");
628                 if (!fp) {
629                         cynara_strerror(errno, err_msg, sizeof(err_msg));
630                         BT_ERR("fopen() failed : %s", err_msg);
631                         goto fail;
632                 }
633                 oacp_op->fp = fp;
634         }
635
636         if (oacp_op->length_sofar <= oacp_op->length) {
637                 written = fwrite(buffer, 1, len, oacp_op->fp);
638                 oacp_op->length_sofar += written;
639                 BT_DBG("written [%d], length_sofar [%u], received_buff_len [%zu], size [%u]",
640                                         written, oacp_op->length_sofar, len, oacp_op->length);
641         }
642
643         if (timeout_id > 0) {
644                 g_source_remove(timeout_id);
645                 timeout_id = g_timeout_add(BT_OACP_MAX_TIMEOUT,
646                         (GSourceFunc)__bt_otc_connection_timeout_cb, NULL);
647         }
648 fail:
649         g_free(buffer);
650         return TRUE;
651 }
652
653 static void _bt_otp_start_read_on_fd()
654 {
655         GIOChannel *data_io;
656         data_io = g_io_channel_unix_new(oacp_op->fd);
657
658         g_io_channel_set_encoding(data_io, NULL, NULL);
659         g_io_channel_set_flags(data_io, G_IO_FLAG_NONBLOCK, NULL);
660
661         server_watch_id = g_io_add_watch(data_io,
662                 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
663                 __server_data_received_cb, NULL);
664
665         if (timeout_id > 0)
666                         g_source_remove(timeout_id);
667
668         timeout_id = g_timeout_add(BT_OACP_MAX_TIMEOUT,
669                 (GSourceFunc)__bt_otc_connection_timeout_cb, NULL);
670 }
671
672 static void _bt_otp_method(GDBusConnection *connection,
673                 const gchar *sender,
674                 const gchar *object_path,
675                 const gchar *interface_name,
676                 const gchar *method_name,
677                 GVariant *parameters,
678                 GDBusMethodInvocation *invocation,
679                 gpointer user_data)
680 {
681         BT_DBG("+");
682         int status = BLUETOOTH_ERROR_NONE;
683
684         BT_DBG("Method[%s] Object Path[%s] Interface Name[%s]",
685                         method_name, object_path, interface_name);
686
687         if (g_strcmp0(method_name, "enable") == 0) {
688                 GDir *dir = NULL;
689                 GError *error = NULL;
690                 const gchar *filename = NULL;
691                 char absolute_path[BT_FILE_PATH_MAX_LEN];
692                 GSList *list = NULL, *l = NULL;
693                 struct stat st;
694                 struct object_metadata *object = NULL;
695
696                 g_variant_get(parameters, "(s)", &directory);
697                 BT_DBG("Directory = [%s]", directory);
698
699                 dir = g_dir_open(directory, 0, &error);
700                 if (!dir) {
701                         BT_ERR("Failed to open directory: %s", error->message);
702                         g_error_free(error);
703                         status = BLUETOOTH_ERROR_INVALID_DIRECTORY;
704                         goto fail;
705                 }
706
707                 while ((filename = g_dir_read_name(dir)))
708                         list = g_slist_append(list, (gpointer) filename);
709
710                 g_dir_close(dir);
711
712                 if (!list) {
713                         BT_DBG("No object found in given directory");
714                         status = BLUETOOTH_ERROR_NO_OBJECTS_FOUND;
715                         goto fail;
716                 }
717
718                 if (g_slist_length(list) > 1)
719                         mutiple_obj_support = true;
720
721                 for (l = list; l != NULL; l = l->next) {
722                         if (!l->data) continue;
723                         snprintf(absolute_path, BT_FILE_PATH_MAX_LEN, "%s%s", directory,
724                                                         (char *)l->data);
725
726                         BT_INFO("filename: %s, absoulte_path: %s",
727                                         (char *)l->data, absolute_path);
728
729                         if (stat(absolute_path, &st) == -1) {
730                                 BT_INFO("stat failed: (%d)\n", errno);
731                                 continue;
732                         }
733
734                         object = g_new0(struct object_metadata, 1);
735
736                         object->name = g_strdup((const gchar *)l->data);
737                         object->type = g_strdup(UNSUPPORTED_OBJECT_TYPE_UUID);
738                         object->first_created = st.st_ctime;
739                         object->last_modified = st.st_ctime;
740                         object->curr_size = (uint32_t) st.st_size;
741                         object->alloc_size = (uint32_t) st.st_size;
742                         object->id = object_id;
743                         object->props = OBJECT_READ | OBJECT_WRITE |
744                                         OBJECT_EXECUTE | OBJECT_DELETE;
745
746                         otp_object_list = g_slist_append(otp_object_list,
747                                                                 object);
748
749                         object_id++;
750                 }
751
752                 BT_DBG("preparing");
753                 if (_bt_otp_prepare_ots() != BLUETOOTH_ERROR_NONE) {
754                         BT_ERR("Fail to prepare OTP Proxy");
755                         status = BLUETOOTH_ERROR_INTERNAL;
756                         goto fail;
757                 }
758
759                 /* If single object is supported, make that as
760                  * selected object and update the metadata for the same.
761                  */
762                 if (!mutiple_obj_support) {
763                         BT_INFO("Server supports single object");
764                         selected_object = (struct object_metadata *) g_slist_nth_data(otp_object_list, 0);
765                         if (selected_object)
766                                 update_obj_metadata_charc_value(selected_object);
767                 }
768
769                 BT_DBG("advertsing");
770                 if (_bt_otp_set_advertising_data() != BLUETOOTH_ERROR_NONE) {
771                         BT_ERR("Fail to set advertising data");
772                         status = BLUETOOTH_ERROR_INTERNAL;
773                         goto fail;
774                 }
775 fail:
776                 g_dbus_method_invocation_return_value(invocation,
777                                                 g_variant_new("(i)", status));
778
779         } else if (g_strcmp0(method_name, "disable") == 0) {
780                 g_dbus_method_invocation_return_value(invocation,
781                                                 g_variant_new("(i)", status));
782                 _bt_otp_exit();
783
784         } else if (g_strcmp0(method_name, "NewConnection") == 0) {
785                 int index;
786                 GDBusMessage *msg;
787                 GUnixFDList *fd_list;
788                 char *dev_path;
789                 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
790                 int fd;
791
792                 g_variant_get(parameters, "(oh)", &dev_path, &index);
793
794                 msg = g_dbus_method_invocation_get_message(invocation);
795                 fd_list = g_dbus_message_get_unix_fd_list(msg);
796                 if (fd_list == NULL) {
797                         BT_ERR("fd_list is NULL");
798                         return;
799                 }
800
801                 fd = g_unix_fd_list_get(fd_list, index, NULL);
802                 if (fd == -1) {
803                         BT_ERR("Invalid fd return");
804                         return;
805                 }
806
807                 _bt_convert_device_path_to_address(dev_path, address);
808
809                 BT_INFO("OTC Connected fd: %d, address %s", fd, address);
810                 otc_connection_status = TRUE;
811                 if (oacp_op) {
812                         oacp_op->fd = fd;
813
814                         if (oacp_op->opcode == OACP_READ)
815                                 _bt_otp_start_write_on_fd();
816                         else if (oacp_op->opcode == OACP_WRITE)
817                                 _bt_otp_start_read_on_fd();
818                 } else {
819                         /* Close fd if oacp_op is NULL */
820                         close(fd);
821                 }
822                 g_dbus_method_invocation_return_value(invocation, NULL);
823         }
824         BT_DBG("-");
825 }
826
827 static const GDBusInterfaceVTable otp_method_table = {
828         _bt_otp_method,
829         NULL,
830         NULL,
831 };
832
833 static void _bt_otp_on_bus_acquired(GDBusConnection *connection,
834                                 const gchar *name, gpointer user_data)
835 {
836         guint object_id;
837         GError *error = NULL;
838
839         BT_DBG("+");
840
841         g_conn = connection;
842
843         object_id = g_dbus_connection_register_object(connection,
844                                                 BT_OTP_OBJECT_PATH,
845                                                 otp_node_info->interfaces[0],
846                                                 &otp_method_table,
847                                                 NULL, NULL, &error);
848         if (object_id == 0) {
849                 BT_ERR("Failed to register method table: %s", error->message);
850                 g_error_free(error);
851                 g_dbus_node_info_unref(otp_node_info);
852         }
853
854         BT_DBG("-");
855 }
856
857 static void _bt_otp_on_name_acquired(GDBusConnection *connection,
858                                         const gchar     *name,
859                                         gpointer user_data)
860 {
861         BT_DBG("");
862 }
863
864 static void _bt_otp_on_name_lost(GDBusConnection *connection,
865                                 const gchar     *name,
866                                 gpointer user_data)
867 {
868         BT_DBG("");
869         g_object_unref(g_conn);
870         g_conn = NULL;
871         g_dbus_node_info_unref(otp_node_info);
872         g_bus_unown_name(g_owner_id);
873 }
874
875 int _bt_otp_register_interface(void)
876 {
877         BT_DBG("+");
878         GError *error = NULL;
879         guint owner_id;
880
881         otp_node_info = g_dbus_node_info_new_for_xml(otp_introspection_xml, &error);
882         if (!otp_node_info) {
883                 BT_ERR("Failed to install: %s", error->message);
884                 return BLUETOOTH_ERROR_INTERNAL;
885         }
886
887         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
888                                 BT_OTP_SERVICE_NAME,
889                                 G_BUS_NAME_OWNER_FLAGS_NONE,
890                                 _bt_otp_on_bus_acquired,
891                                 _bt_otp_on_name_acquired,
892                                 _bt_otp_on_name_lost,
893                                 NULL, NULL);
894         g_owner_id = owner_id;
895         BT_DBG("owner_id is [%d]\n", owner_id);
896
897         BT_DBG("-");
898         return BLUETOOTH_ERROR_NONE;
899 }
900
901 void _bt_otp_unregister_interface(void)
902 {
903         BT_DBG("+");
904
905         g_object_unref(g_conn);
906         g_conn = NULL;
907         g_dbus_node_info_unref(otp_node_info);
908         g_bus_unown_name(g_owner_id);
909
910         BT_DBG("-");
911         return;
912 }
913
914 void _bt_convert_device_path_to_address(const char *device_path,
915                                                 char *device_address)
916 {
917         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
918         char *dev_addr;
919
920         dev_addr = strstr(device_path, "dev_");
921         if (dev_addr != NULL) {
922                 char *pos = NULL;
923                 dev_addr += 4;
924                 g_strlcpy(address, dev_addr, sizeof(address));
925
926                 while ((pos = strchr(address, '_')) != NULL)
927                         *pos = ':';
928
929                 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
930         }
931 }
932
933 static char *__bt_extract_device_path(GVariantIter *iter, char *address)
934 {
935         char *object_path = NULL;
936         char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
937
938         /* Parse the signature: oa{sa{sv}}} */
939         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
940                         NULL)) {
941                 if (!object_path) {
942                         BT_ERR("Unable to get object path");
943                         return NULL;
944                 }
945                 _bt_convert_device_path_to_address(object_path, device_address);
946                 if (g_strcmp0(address, device_address) == 0)
947                         return g_strdup(object_path);
948
949         }
950
951         BT_ERR("Unable to get object path");
952         return NULL;
953 }
954
955 char *_bt_otp_get_device_object_path(char *address)
956 {
957         GError *err = NULL;
958         GDBusProxy *proxy = NULL;
959         GVariant *result = NULL;
960         GVariantIter *iter = NULL;
961         char *object_path = NULL;
962
963         proxy =  g_dbus_proxy_new_sync(conn,
964                         G_DBUS_PROXY_FLAGS_NONE, NULL,
965                         BT_BLUEZ_NAME,
966                         BT_MANAGER_PATH,
967                         BT_MANAGER_INTERFACE,
968                         NULL, &err);
969
970         if (!proxy) {
971                 BT_ERR("Unable to create proxy: %s", err->message);
972                 goto fail;
973         }
974
975         result = g_dbus_proxy_call_sync(proxy, "GetManagedObjects", NULL,
976                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
977         if (!result) {
978                 if (err != NULL)
979                         BT_ERR("Fail to get GetManagedObjects (Error: %s)", err->message);
980                 else
981                         BT_ERR("Fail to get GetManagedObjects");
982
983                 goto fail;
984         }
985
986         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
987         object_path = __bt_extract_device_path(iter, address);
988
989         g_variant_unref(result);
990         g_variant_iter_free(iter);
991
992 fail:
993         if (err)
994                 g_clear_error(&err);
995
996         if (proxy)
997                 g_object_unref(proxy);
998
999         return object_path;
1000 }
1001
1002 int _bt_otp_open_otc_and_listen(char *address, char *method)
1003 {
1004         char *object_path;
1005         GDBusProxy *device_proxy = NULL;
1006         GVariant *result = NULL;
1007         GError *error = NULL;
1008         int ret = BLUETOOTH_ERROR_NONE;
1009
1010         if (method == NULL)
1011                 return BLUETOOTH_ERROR_INTERNAL;
1012
1013         if (g_strcmp0(method, "ListenOtc") &&
1014                         g_strcmp0(method, "DisconnectOtc"))
1015                 return BLUETOOTH_ERROR_INTERNAL;
1016
1017         object_path = _bt_otp_get_device_object_path(address);
1018         if (object_path == NULL) {
1019                 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1020                 goto fail;
1021         }
1022
1023         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1024                                         NULL, BT_BLUEZ_NAME, object_path,
1025                                         BT_DEVICE_INTERFACE,  NULL, NULL);
1026         if (device_proxy == NULL) {
1027                 ret = BLUETOOTH_ERROR_INTERNAL;
1028                 goto fail;
1029         }
1030
1031
1032         result = g_dbus_proxy_call_sync(device_proxy, method,
1033                                 NULL,
1034                                 G_DBUS_CALL_FLAGS_NONE,
1035                                 -1,
1036                                 NULL,
1037                                 &error);
1038         if (result == NULL) {
1039                 if (error != NULL) {
1040                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
1041                         g_error_free(error);
1042                 }
1043                 ret = BLUETOOTH_ERROR_INTERNAL;
1044         }
1045 fail:
1046         if (object_path)
1047                 g_free(object_path);
1048         if (result)
1049                 g_variant_unref(result);
1050         if (device_proxy)
1051                 g_object_unref(device_proxy);
1052         return ret;
1053 }
1054
1055 static bool __bt_oacp_create_timeout_cb(gpointer user_data)
1056 {
1057         /* Delete the EMPTY object */
1058         BT_INFO("+");
1059         _bt_otp_restore_old_object();
1060         return FALSE;
1061 }
1062
1063 static void _bt_otp_free_oacp_op()
1064 {
1065         if (timeout_id > 0) {
1066                 g_source_remove(timeout_id);
1067                 timeout_id = 0;
1068         }
1069
1070         if (oacp_op) {
1071                 g_free(oacp_op->remote_address);
1072                 if (oacp_op->fp)
1073                         fclose(oacp_op->fp);
1074                 g_free(oacp_op);
1075                 oacp_op = NULL;
1076         }
1077 }
1078
1079 int _bt_otp_send_launch_request(char *absolute_path)
1080 {
1081         void *handle;
1082         char *error;
1083         int ret = BLUETOOTH_ERROR_NONE;
1084
1085         /* check ARCH 64 or 32*/
1086         if (!access(FILEPATH_ARCH_64, 0)) {
1087                 BT_INFO("plugin loading for ARCH 64");
1088                 handle = dlopen(HEADED_PLUGIN_FILEPATH64, RTLD_NOW);
1089         } else {
1090                 BT_INFO("plugin loading for ARCH 32");
1091                 handle = dlopen(HEADED_PLUGIN_FILEPATH, RTLD_NOW);
1092         }
1093
1094         if (!handle) {
1095                 BT_ERR("Can not load plugin %s", dlerror());
1096                 return BLUETOOTH_ERROR_INTERNAL;
1097         }
1098
1099         dlerror();      /* Clear any existing error */
1100
1101         int (*fun)(char *) = (int (*)(char *))dlsym(handle,
1102                         "bt_app_control_send_launch_request");
1103
1104         if ((error = dlerror()) != NULL)  {
1105                 BT_ERR("Can not load symbol : %s", dlerror());
1106                 dlclose(handle);
1107                 return BLUETOOTH_ERROR_INTERNAL;
1108         }
1109
1110         if (fun)
1111                 ret = fun(absolute_path);
1112         dlclose(handle);
1113
1114         return ret;
1115 }
1116
1117 char *_bt_otp_uuid_convert_hex_to_string(char *value, uint32_t length)
1118 {
1119         char *uuid = NULL;
1120         unsigned int   data0;
1121         unsigned short data1;
1122         unsigned short data2;
1123         unsigned short data3;
1124         unsigned int   data4;
1125         unsigned short data5;
1126         size_t n;
1127
1128         uuid = (char *) g_malloc0(2 * length * sizeof(char));
1129         n = 2 * length + 1;
1130
1131         switch (length) {
1132         case 2:
1133                 memcpy(&data1, &value[0], 2);
1134                 snprintf(uuid, n, "%.4x", ntohs(data1));
1135                 break;
1136         case 4:
1137                 memcpy(&data0, &value[0], 4);
1138                 snprintf(uuid, n, "%.8x", ntohl(data0));
1139                 break;
1140         case 16:
1141                 memcpy(&data0, &value[0], 4);
1142                 memcpy(&data1, &value[4], 2);
1143                 memcpy(&data2, &value[6], 2);
1144                 memcpy(&data3, &value[8], 2);
1145                 memcpy(&data4, &value[10], 4);
1146                 memcpy(&data5, &value[14], 2);
1147
1148                 snprintf(uuid, n + 4, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
1149                                         ntohl(data0), ntohs(data1),
1150                                         ntohs(data2), ntohs(data3),
1151                                         ntohl(data4), ntohs(data5));
1152                 break;
1153         default:
1154                 g_free(uuid);
1155                 return NULL;
1156         }
1157
1158         return uuid;
1159 }
1160
1161 void _bt_otp_create_new_object(uint32_t size, char *uuid)
1162 {
1163         struct object_metadata *object = NULL;
1164
1165         /* Store current object id.
1166          * Incase of OACP Create fail, need to restore
1167          * it back.
1168          */
1169         prev_obj_id = selected_object->id;
1170
1171         object = g_new0(struct object_metadata, 1);
1172
1173         object->name = NULL;
1174         object->type = g_strdup(uuid);
1175         object->first_created = 0;
1176         object->last_modified = 0;
1177         object->curr_size = 0;
1178         object->alloc_size = size;
1179         object->id = object_id;
1180         object->props = OBJECT_READ | OBJECT_WRITE |
1181                                         OBJECT_EXECUTE | OBJECT_DELETE;
1182
1183         otp_object_list = g_slist_append(otp_object_list,
1184                                                 object);
1185
1186         update_obj_metadata_charc_value(object);
1187         selected_object = object;
1188         curr_obj_index = g_slist_length(otp_object_list) - 1;
1189         curr_obj_id = selected_object->id;
1190         object_id++;
1191
1192         free(uuid);
1193 }
1194
1195 void _bt_otp_restore_old_object()
1196 {
1197         struct object_metadata *object = NULL;
1198         guint index = 0;
1199
1200         object = _bt_otp_client_find_object(otp_object_list, curr_obj_id, &index);
1201         if (!object)
1202                 return;
1203
1204         otp_object_list = g_slist_remove(otp_object_list, object);
1205
1206         index = 0;
1207         object = _bt_otp_client_find_object(otp_object_list, prev_obj_id, &index);
1208         if (!object) {
1209                 BT_ERR("Object is NULL");
1210                 return;
1211         }
1212         oacp_create = FALSE;
1213         update_obj_metadata_charc_value(object);
1214         selected_object = object;
1215         curr_obj_index = index;
1216         object_id--;
1217 }
1218
1219 int _bt_otp_oacp_write_cb(char *value, int len, int offset,
1220                                                         char *remote_addr, struct indicate_info *info)
1221 {
1222         int ret = OACP_SUCCESS;
1223         int err = BLUETOOTH_ERROR_NONE;
1224         int opcode = value[0];
1225         uint32_t object_offset, length, object_size;
1226         uint8_t mode = 0;
1227         char *uuid;
1228         char absolute_file_path[BT_FILE_PATH_MAX_LEN] = {0, };
1229
1230         BT_INFO("OACP Opcode 0x%d", opcode);
1231
1232         if (!selected_object) {
1233                 BT_DBG("Object not selected");
1234                 ret = OACP_INVALID_OBJ;
1235                 goto fail;
1236         }
1237
1238         switch (opcode) {
1239         case OACP_CREATE:
1240                 BT_INFO("OACP_CREATE");
1241                 if (len < 7) {
1242                         BT_DBG("Error: invalid param");
1243                         ret = OACP_INVALID_PARAM;
1244                         goto fail;
1245                 }
1246                 /* UUIDs can be 2/4/16 bytes long.
1247                  * So based on remaining len, determine uuid len.
1248                  */
1249                 length = len - 5;
1250
1251                 uuid = _bt_otp_uuid_convert_hex_to_string(value + 1, length);
1252                 object_size = (uint32_t)(value[length + 4] & 0xFF) << 24 |
1253                                 (uint32_t)(value[length + 3] & 0xFF) << 16 |
1254                                 (uint32_t)(value[length + 2] & 0xFF) << 8  |
1255                                 (uint32_t)(value[length + 1] & 0xFF);
1256
1257                 BT_INFO("Size = %u, UUID = %s", object_size, uuid);
1258
1259                 oacp_create = TRUE;
1260                 _bt_otp_create_new_object(object_size, uuid);
1261
1262                 if (oacp_create_timeout_id > 0)
1263                         g_source_remove(oacp_create_timeout_id);
1264                 oacp_create_timeout_id = g_timeout_add(BT_OACP_MAX_TIMEOUT,
1265                         (GSourceFunc)__bt_oacp_create_timeout_cb, NULL);
1266                 break;
1267         case OACP_DELETE:
1268                 if (!(selected_object->props & OBJECT_DELETE)) {
1269                         ret = OACP_PROCEDURE_NOT_SUPPORTED;
1270                         goto fail;
1271                 }
1272                 snprintf(absolute_file_path, BT_FILE_PATH_MAX_LEN,
1273                                                 "%s%s", directory, selected_object->name);
1274
1275                 BT_DBG("absolute_file_path = [%s]", absolute_file_path);
1276
1277                 if (remove(absolute_file_path) != 0) {
1278                         BT_DBG("Error: unable to delete the file");
1279                         ret = OACP_OPERATION_FAILED;
1280                         goto fail;
1281                 }
1282
1283                 BT_DBG("File deleted successfully");
1284                 selected_object = NULL;
1285                 break;
1286         case OACP_CALC_CHECKSUM:
1287                 ret = OACP_OPCODE_NOT_SUPPORTED;
1288                 break;
1289         case OACP_EXECUTE:
1290                 if (!(selected_object->props & OBJECT_EXECUTE)) {
1291                         ret = OACP_PROCEDURE_NOT_SUPPORTED;
1292                         goto fail;
1293                 }
1294                 snprintf(absolute_file_path, BT_FILE_PATH_MAX_LEN,
1295                                         "file://%s%s", directory, selected_object->name);
1296
1297                 BT_DBG("absolute_file_path = [%s]", absolute_file_path);
1298
1299                 err = _bt_otp_send_launch_request(absolute_file_path);
1300                 if (err != BLUETOOTH_ERROR_NONE) {
1301                         BT_DBG("Error: unable to launch the file");
1302                         ret = OACP_OPERATION_FAILED;
1303                         goto fail;
1304                 }
1305
1306                 BT_DBG("Successfully launched the file");
1307                 break;
1308         case OACP_READ:
1309         case OACP_WRITE:
1310                 if (opcode == OACP_WRITE &&
1311                                 !(selected_object->props & OBJECT_WRITE)) {
1312                         ret = OACP_PROCEDURE_NOT_SUPPORTED;
1313                         goto fail;
1314                 }
1315
1316                 if (opcode == OACP_READ &&
1317                                 !(selected_object->props & OBJECT_READ)) {
1318                         ret = OACP_PROCEDURE_NOT_SUPPORTED;
1319                         goto fail;
1320                 }
1321
1322                 object_offset = (uint32_t)(value[4] & 0xFF) << 24 |
1323                                 (uint32_t)(value[3] & 0xFF) << 16 |
1324                                 (uint32_t)(value[2] & 0xFF) << 8  |
1325                                 (uint32_t)(value[1] & 0xFF);
1326                 length = (uint32_t)(value[8] & 0xFF) << 24 |
1327                         (uint32_t)(value[7] & 0xFF) << 16 |
1328                         (uint32_t)(value[6] & 0xFF) << 8  |
1329                         (uint32_t)(value[5] & 0xFF);
1330
1331                 if (opcode == OACP_WRITE)
1332                         mode = (uint8_t)value[9] & 0xFF;
1333
1334                 BT_INFO("Offset = %u, Length = %u", object_offset, length);
1335
1336                 if (oacp_op) {
1337                         if (otc_connection_status) {
1338                                 /* Read/Write operation already going on. */
1339                                 ret = OACP_OBJECT_LOCKED;
1340                                 goto fail;
1341                         }
1342                         _bt_otp_free_oacp_op();
1343                 }
1344
1345                 oacp_op = g_malloc0(sizeof(struct oacp_operation));
1346                 oacp_op->offset = object_offset;
1347                 oacp_op->length = length;
1348                 oacp_op->remote_address = g_strdup(remote_addr);
1349                 oacp_op->mode = mode;
1350                 oacp_op->opcode = opcode;
1351                 oacp_op->length_sofar = 0;
1352                 oacp_op->fp = NULL;
1353
1354                 err = _bt_otp_open_otc_and_listen(remote_addr, "ListenOtc");
1355                 if (err != BLUETOOTH_ERROR_NONE) {
1356                         ret = OACP_CHANNEL_UNAVAILABLE;
1357                         _bt_otp_free_oacp_op();
1358                         goto fail;
1359                 }
1360                 break;
1361         case OACP_ABORT:
1362                 ret = OACP_OPCODE_NOT_SUPPORTED;
1363                 break;
1364         default:
1365                 ret = OACP_OPCODE_NOT_SUPPORTED;
1366                 break;
1367         }
1368 fail:
1369         info->resp_opcode = OACP_RESPONSE;
1370         info->req_opcode = opcode;
1371         info->result_code = ret;
1372         info->resp_param = NULL;
1373         return BLUETOOTH_ERROR_NONE;
1374 }
1375
1376 int _bt_otp_uuid_convert_string_to_hex(char *uuid, char *value)
1377 {
1378         int len, uuid_len;
1379         uint32_t data0, data4;
1380         uint16_t data1, data2, data3, data5;
1381
1382         if (!uuid) {
1383                 BT_ERR("Object Type UUID NULL");
1384                 return 0;
1385         }
1386
1387         len = strlen(uuid);
1388
1389         switch (len) {
1390         case 4:
1391                 /* UUID 16bits */
1392                 sscanf(uuid, "%04hx", &data1);
1393                 data1 = htons(data1);
1394                 memcpy(value, &data1, 2);
1395                 uuid_len = 2;
1396                 break;
1397
1398         case 8:
1399                 /* UUID 32bits */
1400                 sscanf(uuid, "%08x", &data0);
1401                 data0 = htonl(data0);
1402                 memcpy(value, &data0, 4);
1403                 uuid_len = 4;
1404                 break;
1405
1406         case 36:
1407                 /* UUID 128bits */
1408                 sscanf(uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
1409                         &data0, &data1, &data2,
1410                         &data3, &data4, &data5);
1411
1412                 data0 = htonl(data0);
1413                 data1 = htons(data1);
1414                 data2 = htons(data2);
1415                 data3 = htons(data3);
1416                 data4 = htonl(data4);
1417                 data5 = htons(data5);
1418
1419                 memcpy(value, &data0, 4);
1420                 memcpy(value+4, &data1, 2);
1421                 memcpy(value+6, &data2, 2);
1422                 memcpy(value+8, &data3, 2);
1423                 memcpy(value+10, &data4, 4);
1424                 memcpy(value+14, &data5, 2);
1425                 uuid_len = 16;
1426                 break;
1427
1428         default:
1429                 uuid_len = 0;
1430         }
1431
1432         return uuid_len;
1433 }
1434
1435 void convert_to_hex(struct object_metadata *object, char *metadata, char *value)
1436 {
1437         struct tm fc_tm;
1438
1439         BT_DBG("Metadata : %s", metadata);
1440
1441         memset(value, 0, 16);
1442
1443         if (!g_strcmp0(metadata, "size")) {
1444
1445                 value[3] = (object->curr_size >> 24) & 0xFF;
1446                 value[2] = (object->curr_size >> 16) & 0xFF;
1447                 value[1] = (object->curr_size >> 8) & 0xFF;
1448                 value[0] = object->curr_size & 0xFF;
1449
1450                 value[7] = (object->alloc_size >> 24) & 0xFF;
1451                 value[6] = (object->alloc_size >> 16) & 0xFF;
1452                 value[5] = (object->alloc_size >> 8) & 0xFF;
1453                 value[4] = object->alloc_size & 0xFF;
1454
1455         } else if (!g_strcmp0(metadata, "date")) {
1456
1457                 if (object->first_created) {
1458                         localtime_r(&(object->first_created), &fc_tm);
1459
1460                         value[1] = ((fc_tm.tm_year+1900) >> 8) & 0xFF;
1461                         value[0] = (fc_tm.tm_year+1900) & 0xFF;
1462                         value[2] = (fc_tm.tm_mon+1) & 0xFF;
1463                         value[3] = fc_tm.tm_mday & 0xFF;
1464                         value[4] = fc_tm.tm_hour & 0xFF;
1465                         value[5] = fc_tm.tm_min & 0xFF;
1466                         value[6] = fc_tm.tm_sec & 0xFF;
1467                 }
1468
1469         } else if (!g_strcmp0(metadata, "id")) {
1470
1471                 value[5] = (object->id >> 48) & 0xFF;
1472                 value[4] = (object->id >> 32) & 0xFF;
1473                 value[3] = (object->id >> 24) & 0xFF;
1474                 value[2] = (object->id >> 16) & 0xFF;
1475                 value[1] = (object->id >> 8) & 0xFF;
1476                 value[0] = object->id & 0xFF;
1477
1478         } else if (!g_strcmp0(metadata, "props")) {
1479                 value[3] = (object->props >> 24) & 0xFF;
1480                 value[2] = (object->props >> 16) & 0xFF;
1481                 value[1] = (object->props >> 8) & 0xFF;
1482                 value[0] = object->props & 0xFF;
1483         }
1484 }
1485
1486 void update_obj_metadata_charc_value(struct object_metadata *object)
1487 {
1488         /* Value can be of maximum 16 bytes */
1489         char value[16];
1490         int uuid_len;
1491
1492         if (!oacp_create) {
1493                 _bt_otp_set_char_value(otp_object_name_obj_path, object->name,
1494                                                                 strlen(object->name));
1495         }
1496
1497         uuid_len = _bt_otp_uuid_convert_string_to_hex(object->type, value);
1498         _bt_otp_set_char_value(otp_object_type_obj_path, value, uuid_len);
1499
1500         convert_to_hex(object, "size", value);
1501         _bt_otp_set_char_value(otp_object_size_obj_path, value, 8);
1502
1503         convert_to_hex(object, "date", value);
1504         _bt_otp_set_char_value(otp_object_first_created_obj_path, value, 7);
1505         _bt_otp_set_char_value(otp_object_last_modified_obj_path, value, 7);
1506
1507         /* Object ID is optonal for single object server */
1508         if (mutiple_obj_support) {
1509                 convert_to_hex(object, "id", value);
1510                 _bt_otp_set_char_value(otp_object_id_obj_path, value, 6);
1511         }
1512
1513         convert_to_hex(object, "props", value);
1514         _bt_otp_set_char_value(otp_object_prop_obj_path, value, 4);
1515 }
1516
1517 struct object_metadata *_bt_otp_client_find_object(GSList *list, uint64_t id, guint *index)
1518 {
1519         GSList *l;
1520         struct object_metadata *info;
1521
1522         for (l = list; l; l = g_slist_next(l)) {
1523                 (*index)++;
1524                 info = l->data;
1525
1526                 if (info && (info->id == id))
1527                         return info;
1528         }
1529         return NULL;
1530 }
1531
1532 int _bt_otp_olcp_write_cb(char *value, int len, int offset,
1533                                         struct indicate_info *info)
1534 {
1535         int ret = OLCP_SUCCESS;
1536         int opcode = value[0];
1537         struct object_metadata *object;
1538         uint64_t object_id;
1539         guint index = 0;
1540
1541         BT_INFO("OLCP Opcode 0x%d", opcode);
1542
1543         if (!otp_object_list) {
1544                 ret = OLCP_NO_OBJ;
1545                 goto fail;
1546         }
1547
1548         switch (opcode) {
1549         case OLCP_FIRST:
1550                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, 0);
1551                 if (!object) {
1552                         ret = OLCP_OUT_OF_BOUNDS;
1553                         goto fail;
1554                 }
1555                 update_obj_metadata_charc_value(object);
1556                 selected_object = object;
1557                 curr_obj_index = 0;
1558                 break;
1559         case OLCP_LAST:
1560                 len = g_slist_length(otp_object_list);
1561                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, len-1);
1562                 if (!object) {
1563                         ret = OLCP_OUT_OF_BOUNDS;
1564                         goto fail;
1565                 }
1566                 update_obj_metadata_charc_value(object);
1567                 selected_object = object;
1568                 curr_obj_index = len-1;
1569                 break;
1570         case OLCP_PREVIOUS:
1571                 if (curr_obj_index == 0) {
1572                         ret = OLCP_OUT_OF_BOUNDS;
1573                         goto fail;
1574                 }
1575                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index-1);
1576                 if (!object) {
1577                         ret = OLCP_OUT_OF_BOUNDS;
1578                         goto fail;
1579                 }
1580                 update_obj_metadata_charc_value(object);
1581                 selected_object = object;
1582                 curr_obj_index -= 1;
1583                 break;
1584         case OLCP_NEXT:
1585                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index+1);
1586                 if (!object) {
1587                         ret = OLCP_OUT_OF_BOUNDS;
1588                         goto fail;
1589                 }
1590                 update_obj_metadata_charc_value(object);
1591                 selected_object = object;
1592                 curr_obj_index += 1;
1593                 break;
1594         case OLCP_GOTO:
1595                 object_id = (uint64_t)(value[6] & 0xFF) << 40 |
1596                                 (uint64_t)(value[5] & 0xFF) << 32 |
1597                                 (uint64_t)(value[4] & 0xFF) << 24 |
1598                                 (uint64_t)(value[3] & 0xFF) << 16 |
1599                                 (uint64_t)(value[2] & 0xFF) << 8  |
1600                                 (uint64_t)(value[1] & 0xFF);
1601                 BT_INFO("Object ID [%llu]", (unsigned long long int)object_id);
1602                 if (selected_object && selected_object->id == object_id)
1603                         goto fail;
1604
1605                 object = _bt_otp_client_find_object(otp_object_list, object_id, &index);
1606                 if (!object) {
1607                         ret = OLCP_OJECT_ID_NOT_FOUND;
1608                         goto fail;
1609                 }
1610                 update_obj_metadata_charc_value(object);
1611                 selected_object = object;
1612                 curr_obj_index = index - 1;
1613                 break;
1614         case OLCP_ORDER:
1615         case OLCP_REQ_NO_OBJ:
1616         case OLCP_CLEAR_MARKING:
1617         default:
1618                 ret = OLCP_OPCODE_NOT_SUPPORTED;
1619                 break;
1620         }
1621 fail:
1622         info->resp_opcode = OLCP_RESPONSE;
1623         info->req_opcode = opcode;
1624         info->result_code = ret;
1625         info->resp_param = NULL;
1626         return BLUETOOTH_ERROR_NONE;
1627 }
1628
1629 int _bt_otp_obj_name_write_cb(char *value, int len)
1630 {
1631         struct object_metadata *object;
1632         char *filename;
1633         char new_abs_filepath[BT_FILE_PATH_MAX_LEN] = {0, };
1634         int ret = BLUETOOTH_ERROR_NONE;
1635         FILE *fp = NULL;
1636         char err_msg[256] = {0, };
1637
1638         object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index);
1639         if (!object)
1640                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1641
1642         filename = g_strndup(value, len);
1643         snprintf(new_abs_filepath, BT_FILE_PATH_MAX_LEN, "%s%s",
1644                         directory, filename);
1645         BT_DBG("file_path = [%s]", new_abs_filepath);
1646
1647         fp = fopen(new_abs_filepath, "r");
1648         /* fopen succeed means file already exists */
1649         if (fp) {
1650                 ret = BLUETOOTH_OTP_ERROR_OBJECT_NAME_EXISTS;
1651                 goto fail;
1652         }
1653
1654         if (oacp_create) {
1655                 struct stat st;
1656
1657                 fp = fopen(new_abs_filepath, "a");
1658                 if (!fp) {
1659                         cynara_strerror(errno, err_msg, sizeof(err_msg));
1660                         BT_ERR("fopen() failed : %s", err_msg);
1661                         ret = BLUETOOTH_ATT_ERROR_INTERNAL;
1662                         goto fail;
1663                 }
1664
1665                 if (stat(new_abs_filepath, &st) == -1) {
1666                         BT_INFO("stat failed: (%d)\n", errno);
1667                         ret = BLUETOOTH_ATT_ERROR_INTERNAL;
1668                         goto fail;
1669                 }
1670
1671                 object->name = g_strdup(filename);
1672                 object->first_created = st.st_ctime;
1673                 object->last_modified = st.st_ctime;
1674                 object->curr_size = (uint32_t) st.st_size;
1675                 oacp_create = FALSE;
1676         } else {
1677                 char old_abs_filepath[BT_FILE_PATH_MAX_LEN] = {0, };
1678                 snprintf(old_abs_filepath, BT_FILE_PATH_MAX_LEN, "%s%s",
1679                                 directory, object->name);
1680
1681                 if (rename(old_abs_filepath, new_abs_filepath)) {
1682                         ret = BLUETOOTH_ATT_ERROR_INTERNAL;
1683                         goto fail;
1684                 }
1685         }
1686
1687         memcpy(object->name, value, len);
1688         _bt_otp_set_char_value(otp_object_name_obj_path, value, len);
1689
1690 fail:
1691         if (oacp_create)
1692                 _bt_otp_restore_old_object();
1693
1694         if (oacp_create_timeout_id > 0)
1695                 g_source_remove(oacp_create_timeout_id);
1696
1697         if (fp)
1698                 fclose(fp);
1699
1700         g_free(filename);
1701         return ret;
1702 }
1703
1704 int _bt_otp_obj_first_created_write_cb(char *value, int len)
1705 {
1706         struct object_metadata *object;
1707         struct tm tm = {0};
1708         uint16_t year;
1709
1710         object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index);
1711         if (!object)
1712                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1713
1714         year = (uint16_t)(value[1] & 0xFF) << 8 |
1715                         (uint16_t)(value[0] & 0xFF);
1716         tm.tm_year = year-1900;
1717         tm.tm_mon = value[2] & 0xFF;
1718         tm.tm_mon = tm.tm_mon-1;
1719         tm.tm_mday = value[3] & 0xFF;
1720         tm.tm_hour = value[4] & 0xFF;
1721         tm.tm_min = value[5] & 0xFF;
1722         tm.tm_sec = value[6] & 0xFF;
1723
1724         object->first_created = mktime(&tm);
1725         _bt_otp_set_char_value(otp_object_first_created_obj_path, value, len);
1726
1727         return BLUETOOTH_ERROR_NONE;
1728 }
1729
1730 int _bt_otp_obj_last_modified_write_cb(char *value, int len)
1731 {
1732         struct object_metadata *object;
1733         struct tm tm = {0};
1734         uint16_t year;
1735
1736         object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index);
1737         if (!object)
1738                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1739
1740         year = (uint16_t)(value[1] & 0xFF) << 8 |
1741                         (uint16_t)(value[0] & 0xFF);
1742         tm.tm_year = year-1900;
1743         tm.tm_mon = value[2] & 0xFF;
1744         tm.tm_mon = tm.tm_mon-1;
1745         tm.tm_mday = value[3] & 0xFF;
1746         tm.tm_hour = value[4] & 0xFF;
1747         tm.tm_min = value[5] & 0xFF;
1748         tm.tm_sec = value[6] & 0xFF;
1749
1750         object->last_modified = mktime(&tm);
1751         _bt_otp_set_char_value(otp_object_last_modified_obj_path, value, len);
1752
1753         return BLUETOOTH_ERROR_NONE;
1754 }
1755
1756 int _bt_otp_obj_props_write_cb(char *value, int len)
1757 {
1758         struct object_metadata *object;
1759         uint32_t props;
1760
1761         /* Any attempt to write RFU bits is error */
1762         if (value[1] || value[2] || value[3])
1763                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1764
1765         object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index);
1766         if (!object)
1767                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1768
1769         props = (uint32_t)(value[3] & 0xFF) << 24       |
1770                         (uint32_t)(value[2] & 0xFF) << 16       |
1771                         (uint32_t)(value[1] & 0xFF) << 8        |
1772                         (uint32_t)(value[0] & 0xFF);
1773
1774         object->props = props;
1775         _bt_otp_set_char_value(otp_object_prop_obj_path, value, len);
1776
1777         return BLUETOOTH_ERROR_NONE;
1778 }
1779
1780 static struct otp_char_info *otp_get_char_value(const char *path)
1781 {
1782         GSList *tmp = NULL;
1783
1784         for (tmp = otp_char_list; tmp != NULL; tmp = tmp->next) {
1785                 if (tmp->data) {
1786                         struct otp_char_info *char_info = tmp->data;
1787                         if (!g_strcmp0(char_info->char_path, path))
1788                                 return char_info;
1789                 }
1790         }
1791
1792         return NULL;
1793 }
1794
1795 int _bt_otp_read_cb(const char *obj_path, char **value, int *len, uint16_t offset)
1796 {
1797         struct otp_char_info *info = NULL;
1798
1799         if (!obj_path) {
1800                 BT_ERR("Wrong Obj path");
1801                 return BLUETOOTH_ATT_ERROR_INTERNAL;
1802         }
1803
1804         if (g_strcmp0(obj_path, otp_feature_obj_path)) {
1805                 if (!selected_object)
1806                         return BLUETOOTH_OTP_ERROR_OBJECT_NOT_SELECTED;
1807         }
1808
1809         info = otp_get_char_value(obj_path);
1810         if (info) {
1811                 if (oacp_create && !g_strcmp0(obj_path, otp_object_name_obj_path)) {
1812                         /* char_value is NULL, value_length is zero */
1813                         *value = NULL;
1814                         *len = 0;
1815                         return BLUETOOTH_ATT_ERROR_NONE;
1816                 }
1817
1818                 if (info->char_value == NULL || info->value_length == 0)
1819                         return BLUETOOTH_ATT_ERROR_INTERNAL;
1820
1821                 if (offset > info->value_length)
1822                         return BLUETOOTH_ATT_ERROR_INVALID_OFFSET;
1823
1824                 *len = info->value_length - offset;
1825                 *value = (char *)malloc(sizeof(char)*(*len));
1826                 if (*value == NULL)
1827                         return BLUETOOTH_ATT_ERROR_INTERNAL;
1828
1829                 memcpy(*value, info->char_value, *len);
1830
1831                 return BLUETOOTH_ATT_ERROR_NONE;
1832         } else {
1833                 return BLUETOOTH_ATT_ERROR_INTERNAL;
1834         }
1835 }
1836
1837 static void _otp_convert_address_to_hex(bluetooth_device_address_t *addr_hex,
1838                                                         const char *addr_str)
1839 {
1840         int i = 0;
1841         unsigned int addr[BLUETOOTH_ADDRESS_LENGTH] = { 0, };
1842
1843         if (addr_str == NULL || addr_str[0] == '\0')
1844                 return;
1845
1846         i = sscanf(addr_str, "%X:%X:%X:%X:%X:%X", &addr[0], &addr[1],
1847                                 &addr[2], &addr[3], &addr[4], &addr[5]);
1848         if (i != BLUETOOTH_ADDRESS_LENGTH)
1849                 BT_ERR("Invalid format string - [%s]", addr_str);
1850
1851         for (i = 0; i < BLUETOOTH_ADDRESS_LENGTH; i++)
1852                 addr_hex->addr[i] = (unsigned char)addr[i];
1853 }
1854
1855 static void _bt_otp_send_indication(const char *obj_path,
1856                                 struct indicate_info *info,
1857                                 bluetooth_device_address_t *remote_address)
1858 {
1859         int ret = BLUETOOTH_ERROR_NONE;
1860         char value[7] = {0x00};
1861         int length = OTP_INDICATION_LEN_WITHOUT_RESP;
1862
1863         BT_DBG("");
1864
1865         value[0] = info->resp_opcode & 0xFF;
1866         value[1] = info->req_opcode & 0xFF;
1867         value[2] = info->result_code & 0xFF;
1868         if (info->resp_param) {
1869                 value[6] = info->resp_param[3] & 0xFF;
1870                 value[5] = info->resp_param[4] & 0xFF;
1871                 value[4] = info->resp_param[5] & 0xFF;
1872                 value[3] = info->resp_param[6] & 0xFF;
1873                 length = OTP_INDICATION_LEN_WITH_RESP;
1874         }
1875
1876         BT_DBG("Opcode: %d", value[1]);
1877
1878         /* Store the status value */
1879         _bt_otp_set_char_value(obj_path, value, length);
1880
1881         /* Send indication */
1882         ret = bluetooth_gatt_server_set_notification(obj_path, remote_address);
1883         if (ret != BLUETOOTH_ERROR_NONE) {
1884                 BT_ERR("_bt_otp_send_control_point_indication failed");
1885                 return;
1886         }
1887         ret = bluetooth_gatt_update_characteristic(obj_path, value, length);
1888         if (ret != BLUETOOTH_ERROR_NONE) {
1889                 BT_ERR("_bt_otp_send_control_point_indication failed");
1890                 return;
1891         }
1892 }
1893
1894 void _bt_otp_gatt_char_property_changed_event(GVariant *msg,
1895                                 const char *path)
1896 {
1897         int result = BLUETOOTH_ERROR_NONE;
1898         GVariantIter value_iter;
1899         const char *property = NULL;
1900         const char *char_path = NULL;
1901         const char *svc_handle = NULL;
1902         GVariant *var = NULL;
1903         GVariant *val = NULL;
1904         g_variant_iter_init(&value_iter, msg);
1905
1906         while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &var))) {
1907
1908                 if (property == NULL) {
1909                         BT_ERR("Property NULL");
1910                         return;
1911                 }
1912
1913                 if (!g_strcmp0(property, "WriteValue")) {
1914                         int len = 0;
1915                         BT_INFO("WriteValue");
1916                         BT_INFO("Type '%s'\n", g_variant_get_type_string(var));
1917
1918                         if (var) {
1919                                 bluetooth_device_address_t addr_hex = { {0,} };
1920                                 gchar *addr = NULL;
1921                                 guint8 req_id = 1;
1922                                 guint16 offset = 0;
1923                                 char *value = NULL;
1924                                 struct indicate_info info;
1925
1926                                 g_variant_get(var, "(&s&s&syq@ay)",
1927                                                 &char_path, &svc_handle,
1928                                                 &addr, &req_id, &offset, &val);
1929
1930                                 len = g_variant_get_size(val);
1931
1932                                 BT_DBG("Len = %d, BT_ADDR = %s", len, addr);
1933
1934                                 value = (char *) g_variant_get_data(val);
1935                                 _otp_convert_address_to_hex(&addr_hex, addr);
1936
1937                                 if (len != 0) {
1938                                         if (!g_strcmp0(char_path, otp_oacp_obj_path)) {
1939                                                 if (!OACP_indicate)
1940                                                         result = BLUETOOTH_ATT_ERROR_CCCD_IMPROPERLY_CONFIGURED;
1941                                                 else
1942                                                         result = _bt_otp_oacp_write_cb(value, len, offset, addr, &info);
1943                                         } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) {
1944                                                 if (!OLCP_indicate)
1945                                                         result = BLUETOOTH_ATT_ERROR_CCCD_IMPROPERLY_CONFIGURED;
1946                                                 else
1947                                                         result = _bt_otp_olcp_write_cb(value, len, offset, &info);
1948                                         } else if (!g_strcmp0(char_path, otp_object_name_obj_path)) {
1949                                                 result = _bt_otp_obj_name_write_cb(value, len);
1950                                         } else if (!g_strcmp0(char_path, otp_object_first_created_obj_path)) {
1951                                                 result = _bt_otp_obj_first_created_write_cb(value, len);
1952                                         } else if (!g_strcmp0(char_path, otp_object_last_modified_obj_path)) {
1953                                                 result = _bt_otp_obj_last_modified_write_cb(value, len);
1954                                         } else if (!g_strcmp0(char_path, otp_object_prop_obj_path)) {
1955                                                 result = _bt_otp_obj_props_write_cb(value, len);
1956                                         } else {
1957                                                 BT_ERR("Wrong Object Path %s", char_path);
1958                                                 result = BLUETOOTH_ERROR_INTERNAL;
1959                                         }
1960                                         bluetooth_gatt_send_response(req_id,
1961                                         BLUETOOTH_GATT_ATT_REQUEST_TYPE_WRITE,
1962                                                         result, 0, NULL, 0);
1963
1964                                         /* Send indication for CPs */
1965                                         if (!g_strcmp0(char_path, otp_oacp_obj_path)) {
1966                                                 if (OACP_indicate)
1967                                                         _bt_otp_send_indication(char_path, &info, &addr_hex);
1968                                         } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) {
1969                                                 if (OLCP_indicate)
1970                                                         _bt_otp_send_indication(char_path, &info, &addr_hex);
1971                                         }
1972                                 } else {
1973                                         BT_ERR("Array Len 0");
1974                                 }
1975                         } else {
1976                                 BT_ERR("var==NULL");
1977                         }
1978                 } else if (!g_strcmp0(property, "ReadValue")) {
1979                         gchar *addr = NULL;
1980                         guint8 req_id = 1;
1981                         guint16 offset = 0;
1982                         char *value = NULL;
1983                         int len = 0;
1984                         result = BLUETOOTH_ATT_ERROR_NONE;
1985
1986                         BT_INFO("ReadValue");
1987                         BT_INFO("Type '%s'\n", g_variant_get_type_string(var));
1988
1989                         g_variant_get(var, "(&s&s&syq)", &char_path,
1990                                         &svc_handle, &addr, &req_id, &offset);
1991
1992                         result = _bt_otp_read_cb(char_path, &value, &len, offset);
1993
1994                         if (result != BLUETOOTH_ATT_ERROR_NONE) {
1995                                 BT_ERR("ReadValue failed %s", char_path);
1996                                 bluetooth_gatt_send_response(req_id,
1997                                 BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ,
1998                                                 result, offset, NULL, 0);
1999                         } else {
2000                                 bluetooth_gatt_send_response(req_id,
2001                                 BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ,
2002                                                 result, offset, value, len);
2003                                 if (value)
2004                                         g_free(value);
2005                         }
2006                 } else if (!g_strcmp0(property, "NotificationStateChanged")) {
2007                         gboolean indicate = FALSE;
2008
2009                         g_variant_get(var, "(&s&sb)", &char_path,
2010                                                 &svc_handle, &indicate);
2011
2012                         BT_INFO("%s : [%s]", property,
2013                                 indicate ? "StartNotify" : "StopNotify");
2014                         BT_INFO("Type '%s'\n", g_variant_get_type_string(var));
2015
2016                         if (!g_strcmp0(char_path, otp_oacp_obj_path))
2017                                 OACP_indicate = indicate;
2018                         else if (!g_strcmp0(char_path, otp_olcp_obj_path))
2019                                 OLCP_indicate = indicate;
2020                 }
2021         }
2022         return;
2023 }
2024
2025 void _bt_otp_property_event_filter(GDBusConnection *connection,
2026                                         const gchar *sender_name,
2027                                         const gchar *object_path,
2028                                         const gchar *interface_name,
2029                                         const gchar *signal_name,
2030                                         GVariant *parameters,
2031                                         gpointer user_data)
2032 {
2033         GVariant *value;
2034
2035         if (signal_name == NULL) {
2036                 BT_ERR("Wrong Signal");
2037                 return;
2038         }
2039
2040         if (g_strcmp0(signal_name, PROPERTIES_CHANGED) == 0) {
2041
2042                 g_variant_get(parameters, "(@a{sv}@as)", &value, NULL);
2043                 _bt_otp_gatt_char_property_changed_event(value, object_path);
2044         }
2045 }
2046
2047 void _bt_otp_adapter_event_filter(GDBusConnection *connection,
2048                                         const gchar *sender_name,
2049                                         const gchar *object_path,
2050                                         const gchar *interface_name,
2051                                         const gchar *signal_name,
2052                                         GVariant *parameters,
2053                                         gpointer user_data)
2054 {
2055         if (signal_name == NULL) {
2056                 BT_ERR("Wrong Signal");
2057                 return;
2058         }
2059
2060         BT_INFO("Interface %s, Signal %s", interface_name, signal_name);
2061
2062         if (g_strcmp0(interface_name, BT_OTP_INTERFACE_NAME) == 0) {
2063                 if (strcasecmp(signal_name, BLE_DISABLED) == 0)
2064                         _bt_otp_exit();
2065         }
2066 }
2067
2068 void _bt_otc_disconnected_cb(GDBusConnection *connection,
2069                                         const gchar *sender_name,
2070                                         const gchar *object_path,
2071                                         const gchar *interface_name,
2072                                         const gchar *signal_name,
2073                                         GVariant *parameters,
2074                                         gpointer user_data)
2075 {
2076         if (signal_name == NULL) {
2077                 BT_ERR("Wrong Signal");
2078                 return;
2079         }
2080
2081         BT_INFO("Interface %s, Signal %s", interface_name, signal_name);
2082
2083         if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) {
2084                 if (strcasecmp(signal_name, OTC_DISCONNECTED) == 0) {
2085                         BT_DBG("OTC Channel Disconnected dev_path[%s]",
2086                                                                 object_path);
2087                         otc_connection_status = FALSE;
2088                         _bt_otp_free_oacp_op();
2089                 }
2090         }
2091 }
2092
2093 void _bt_otp_device_property_event_filter(GDBusConnection *connection,
2094                                         const gchar *sender_name,
2095                                         const gchar *object_path,
2096                                         const gchar *interface_name,
2097                                         const gchar *signal_name,
2098                                         GVariant *parameters,
2099                                         gpointer user_data)
2100 {
2101         char *interfacename = NULL;
2102         GVariant *val = NULL;
2103
2104         g_variant_get(parameters, "(&s@a{sv}@as)", &interfacename, &val, NULL);
2105
2106         if (strcasecmp(interfacename, BT_DEVICE_INTERFACE) == 0) {
2107                 GVariantIter value_iter;
2108                 GVariant *val1;
2109                 char *property = NULL;
2110
2111                 g_variant_iter_init(&value_iter, val);
2112                 while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &val1))) {
2113                         if (strcasecmp(property, "GattConnected") == 0) {
2114                                 gboolean gatt_connected = FALSE;
2115                                 char *address = NULL;
2116
2117                                 g_variant_get(val1, "b", &gatt_connected);
2118
2119                                 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2120
2121                                 _bt_convert_device_path_to_address(object_path, address);
2122
2123                                 BT_DBG("gatt_connected: %d", gatt_connected);
2124                                 BT_DBG("address: %s", address);
2125                                 if (!gatt_connected) {
2126                                         if (oacp_create)
2127                                                 _bt_otp_restore_old_object();
2128
2129                                         if (oacp_create_timeout_id > 0)
2130                                                 g_source_remove(oacp_create_timeout_id);
2131                                 }
2132                                 g_free(address);
2133                         }
2134                 }
2135         }
2136 }
2137
2138 int _bt_otp_init_event_receiver()
2139 {
2140         BT_DBG("+");
2141         GError *error = NULL;
2142
2143         if (conn == NULL) {
2144                 conn =  g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
2145                 if (error != NULL) {
2146                         BT_ERR("ERROR: Can't get on system bus [%s]",
2147                                                         error->message);
2148                         g_clear_error(&error);
2149                 }
2150         }
2151
2152         property_sub_id = g_dbus_connection_signal_subscribe(conn,
2153                                 NULL,
2154                                 BT_OTP_INTERFACE_NAME,
2155                                 PROPERTIES_CHANGED,
2156                                 BT_OTP_OBJECT_PATH, NULL, 0,
2157                                 _bt_otp_property_event_filter,
2158                                 NULL, NULL);
2159
2160         adapter_sub_id = g_dbus_connection_signal_subscribe(conn,
2161                                 NULL,
2162                                 BT_OTP_INTERFACE_NAME,
2163                                 BLE_DISABLED,
2164                                 BT_OTP_OBJECT_PATH, NULL, 0,
2165                                 _bt_otp_adapter_event_filter,
2166                                 NULL, NULL);
2167
2168         device_sub_id = g_dbus_connection_signal_subscribe(conn,
2169                                         NULL, BT_DEVICE_INTERFACE,
2170                                         OTC_DISCONNECTED, NULL, NULL, 0,
2171                                         _bt_otc_disconnected_cb,
2172                                         NULL, NULL);
2173
2174         device_property_sub_id = g_dbus_connection_signal_subscribe(conn,
2175                                 NULL, BT_PROPERTIES_INTERFACE,
2176                                 PROPERTIES_CHANGED, NULL, NULL, 0,
2177                                 _bt_otp_device_property_event_filter,
2178                                 NULL, NULL);
2179
2180         BT_DBG("-");
2181         return 0;
2182 }
2183
2184 void _bt_otp_deinit_event_receiver(void)
2185 {
2186         BT_DBG("+");
2187
2188         g_dbus_connection_signal_unsubscribe(conn, property_sub_id);
2189         g_dbus_connection_signal_unsubscribe(conn, adapter_sub_id);
2190         g_dbus_connection_signal_unsubscribe(conn, device_sub_id);
2191         g_dbus_connection_signal_unsubscribe(conn, device_property_sub_id);
2192         conn = NULL;
2193
2194         BT_DBG("-");
2195 }
2196
2197 static void _bt_otp_sig_handler(int sig)
2198 {
2199         BT_DBG("+");
2200         switch (sig) {
2201         case SIGTERM:
2202                 BT_DBG("caught signal - sigterm\n");
2203                 break;
2204         case SIGINT:
2205                 BT_DBG("caught signal - sigint\n");
2206                 break;
2207         case SIGKILL:
2208                 BT_DBG("caught signal - sigkill\n");
2209                 break;
2210         default:
2211                 BT_DBG("caught signal %d and ignored\n", sig);
2212                 break;
2213         }
2214         BT_DBG("-");
2215 }
2216
2217 /* OTP Service Main loop */
2218 int main(void)
2219 {
2220         struct sigaction sa;
2221         BT_ERR("Starting the bt-otp daemon");
2222
2223         memset(&sa, 0, sizeof(sa));
2224         sa.sa_handler = _bt_otp_sig_handler;
2225         sa.sa_flags = SA_SIGINFO;
2226         sigaction(SIGINT, &sa, NULL);
2227         sigaction(SIGTERM, &sa, NULL);
2228         sigaction(SIGKILL, &sa, NULL);
2229
2230         if (_bt_otp_register_interface() != BLUETOOTH_ERROR_NONE) {
2231                 BT_ERR("Fail to register otp service");
2232                 return -4;
2233         }
2234
2235         if (_bt_otp_init_event_receiver() != BLUETOOTH_ERROR_NONE) {
2236                 BT_ERR("Fail to init event reciever");
2237                 return -5;
2238         }
2239
2240         main_loop = g_main_loop_new(NULL, FALSE);
2241
2242         g_main_loop_run(main_loop);
2243
2244         BT_DBG("g_main_loop_quit called!");
2245
2246         if (main_loop != NULL)
2247                 g_main_loop_unref(main_loop);
2248
2249         return 0;
2250 }