SVACE Fixes
[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 %d, 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 [%lu], received_buff_len [%d], size [%lu]",
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                 }
819                 g_dbus_method_invocation_return_value(invocation, NULL);
820         }
821         BT_DBG("-");
822 }
823
824 static const GDBusInterfaceVTable otp_method_table = {
825         _bt_otp_method,
826         NULL,
827         NULL,
828 };
829
830 static void _bt_otp_on_bus_acquired(GDBusConnection *connection,
831                                 const gchar *name, gpointer user_data)
832 {
833         guint object_id;
834         GError *error = NULL;
835
836         BT_DBG("+");
837
838         g_conn = connection;
839
840         object_id = g_dbus_connection_register_object(connection,
841                                                 BT_OTP_OBJECT_PATH,
842                                                 otp_node_info->interfaces[0],
843                                                 &otp_method_table,
844                                                 NULL, NULL, &error);
845         if (object_id == 0) {
846                 BT_ERR("Failed to register method table: %s", error->message);
847                 g_error_free(error);
848                 g_dbus_node_info_unref(otp_node_info);
849         }
850
851         BT_DBG("-");
852 }
853
854 static void _bt_otp_on_name_acquired(GDBusConnection *connection,
855                                         const gchar     *name,
856                                         gpointer user_data)
857 {
858         BT_DBG("");
859 }
860
861 static void _bt_otp_on_name_lost(GDBusConnection *connection,
862                                 const gchar     *name,
863                                 gpointer user_data)
864 {
865         BT_DBG("");
866         g_object_unref(g_conn);
867         g_conn = NULL;
868         g_dbus_node_info_unref(otp_node_info);
869         g_bus_unown_name(g_owner_id);
870 }
871
872 int _bt_otp_register_interface(void)
873 {
874         BT_DBG("+");
875         GError *error = NULL;
876         guint owner_id;
877
878         otp_node_info = g_dbus_node_info_new_for_xml(otp_introspection_xml, &error);
879         if (!otp_node_info) {
880                 BT_ERR("Failed to install: %s", error->message);
881                 return BLUETOOTH_ERROR_INTERNAL;
882         }
883
884         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
885                                 BT_OTP_SERVICE_NAME,
886                                 G_BUS_NAME_OWNER_FLAGS_NONE,
887                                 _bt_otp_on_bus_acquired,
888                                 _bt_otp_on_name_acquired,
889                                 _bt_otp_on_name_lost,
890                                 NULL, NULL);
891         g_owner_id = owner_id;
892         BT_DBG("owner_id is [%d]\n", owner_id);
893
894         BT_DBG("-");
895         return BLUETOOTH_ERROR_NONE;
896 }
897
898 void _bt_otp_unregister_interface(void)
899 {
900         BT_DBG("+");
901
902         g_object_unref(g_conn);
903         g_conn = NULL;
904         g_dbus_node_info_unref(otp_node_info);
905         g_bus_unown_name(g_owner_id);
906
907         BT_DBG("-");
908         return;
909 }
910
911 void _bt_convert_device_path_to_address(const char *device_path,
912                                                 char *device_address)
913 {
914         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
915         char *dev_addr;
916
917         dev_addr = strstr(device_path, "dev_");
918         if (dev_addr != NULL) {
919                 char *pos = NULL;
920                 dev_addr += 4;
921                 g_strlcpy(address, dev_addr, sizeof(address));
922
923                 while ((pos = strchr(address, '_')) != NULL)
924                         *pos = ':';
925
926                 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
927         }
928 }
929
930 static char *__bt_extract_device_path(GVariantIter *iter, char *address)
931 {
932         char *object_path = NULL;
933         char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
934
935         /* Parse the signature: oa{sa{sv}}} */
936         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
937                         NULL)) {
938                 if (!object_path) {
939                         BT_ERR("Unable to get object path");
940                         return NULL;
941                 }
942                 _bt_convert_device_path_to_address(object_path, device_address);
943                 if (g_strcmp0(address, device_address) == 0)
944                         return g_strdup(object_path);
945
946         }
947
948         BT_ERR("Unable to get object path");
949         return NULL;
950 }
951
952 char *_bt_otp_get_device_object_path(char *address)
953 {
954         GError *err = NULL;
955         GDBusProxy *proxy = NULL;
956         GVariant *result = NULL;
957         GVariantIter *iter = NULL;
958         char *object_path = NULL;
959
960         proxy =  g_dbus_proxy_new_sync(conn,
961                         G_DBUS_PROXY_FLAGS_NONE, NULL,
962                         BT_BLUEZ_NAME,
963                         BT_MANAGER_PATH,
964                         BT_MANAGER_INTERFACE,
965                         NULL, &err);
966
967         if (!proxy) {
968                 BT_ERR("Unable to create proxy: %s", err->message);
969                 goto fail;
970         }
971
972         result = g_dbus_proxy_call_sync(proxy, "GetManagedObjects", NULL,
973                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
974         if (!result) {
975                 if (err != NULL)
976                         BT_ERR("Fail to get GetManagedObjects (Error: %s)", err->message);
977                 else
978                         BT_ERR("Fail to get GetManagedObjects");
979
980                 goto fail;
981         }
982
983         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
984         object_path = __bt_extract_device_path(iter, address);
985
986         g_variant_unref(result);
987         g_variant_iter_free(iter);
988
989 fail:
990         if (err)
991                 g_clear_error(&err);
992
993         if (proxy)
994                 g_object_unref(proxy);
995
996         return object_path;
997 }
998
999 int _bt_otp_open_otc_and_listen(char *address, char *method)
1000 {
1001         char *object_path;
1002         GDBusProxy *device_proxy = NULL;
1003         GVariant *result = NULL;
1004         GError *error = NULL;
1005         int ret = BLUETOOTH_ERROR_NONE;
1006
1007         if (method == NULL)
1008                 return BLUETOOTH_ERROR_INTERNAL;
1009
1010         if (g_strcmp0(method, "ListenOtc") &&
1011                         g_strcmp0(method, "DisconnectOtc"))
1012                 return BLUETOOTH_ERROR_INTERNAL;
1013
1014         object_path = _bt_otp_get_device_object_path(address);
1015         if (object_path == NULL) {
1016                 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1017                 goto fail;
1018         }
1019
1020         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1021                                         NULL, BT_BLUEZ_NAME, object_path,
1022                                         BT_DEVICE_INTERFACE,  NULL, NULL);
1023         if (device_proxy == NULL) {
1024                 ret = BLUETOOTH_ERROR_INTERNAL;
1025                 goto fail;
1026         }
1027
1028
1029         result = g_dbus_proxy_call_sync(device_proxy, method,
1030                                 NULL,
1031                                 G_DBUS_CALL_FLAGS_NONE,
1032                                 -1,
1033                                 NULL,
1034                                 &error);
1035         if (result == NULL) {
1036                 if (error != NULL) {
1037                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
1038                         g_error_free(error);
1039                 }
1040                 ret = BLUETOOTH_ERROR_INTERNAL;
1041         }
1042 fail:
1043         if (object_path)
1044                 g_free(object_path);
1045         if (result)
1046                 g_variant_unref(result);
1047         if (device_proxy)
1048                 g_object_unref(device_proxy);
1049         return ret;
1050 }
1051
1052 static bool __bt_oacp_create_timeout_cb(gpointer user_data)
1053 {
1054         /* Delete the EMPTY object */
1055         BT_INFO("+");
1056         _bt_otp_restore_old_object();
1057         return FALSE;
1058 }
1059
1060 static void _bt_otp_free_oacp_op()
1061 {
1062         if (timeout_id > 0) {
1063                 g_source_remove(timeout_id);
1064                 timeout_id = 0;
1065         }
1066
1067         if (oacp_op) {
1068                 g_free(oacp_op->remote_address);
1069                 if (oacp_op->fp)
1070                         fclose(oacp_op->fp);
1071                 g_free(oacp_op);
1072                 oacp_op = NULL;
1073         }
1074 }
1075
1076 int _bt_otp_send_launch_request(char *absolute_path)
1077 {
1078         void *handle;
1079         char *error;
1080         int ret = BLUETOOTH_ERROR_NONE;
1081
1082         /* check ARCH 64 or 32*/
1083         if (!access(FILEPATH_ARCH_64, 0)) {
1084                 BT_INFO("plugin loading for ARCH 64");
1085                 handle = dlopen(HEADED_PLUGIN_FILEPATH64, RTLD_NOW);
1086         } else {
1087                 BT_INFO("plugin loading for ARCH 32");
1088                 handle = dlopen(HEADED_PLUGIN_FILEPATH, RTLD_NOW);
1089         }
1090
1091         if (!handle) {
1092                 BT_ERR("Can not load plugin %s", dlerror());
1093                 return BLUETOOTH_ERROR_INTERNAL;
1094         }
1095
1096         dlerror();      /* Clear any existing error */
1097
1098         int (*fun)(char *) = (int (*)(char *))dlsym(handle,
1099                         "bt_app_control_send_launch_request");
1100
1101         if ((error = dlerror()) != NULL)  {
1102                 BT_ERR("Can not load symbol : %s", dlerror());
1103                 dlclose(handle);
1104                 return BLUETOOTH_ERROR_INTERNAL;
1105         }
1106
1107         if (fun)
1108                 ret = fun(absolute_path);
1109         dlclose(handle);
1110
1111         return ret;
1112 }
1113
1114 char *_bt_otp_uuid_convert_hex_to_string(char *value, uint32_t length)
1115 {
1116         char *uuid = NULL;
1117         unsigned int   data0;
1118         unsigned short data1;
1119         unsigned short data2;
1120         unsigned short data3;
1121         unsigned int   data4;
1122         unsigned short data5;
1123         size_t n;
1124
1125         uuid = (char *) g_malloc0(2 * length * sizeof(char));
1126         n = 2 * length + 1;
1127
1128         switch (length) {
1129         case 2:
1130                 memcpy(&data1, &value[0], 2);
1131                 snprintf(uuid, n, "%.4x", ntohs(data1));
1132                 break;
1133         case 4:
1134                 memcpy(&data0, &value[0], 4);
1135                 snprintf(uuid, n, "%.8x", ntohl(data0));
1136                 break;
1137         case 16:
1138                 memcpy(&data0, &value[0], 4);
1139                 memcpy(&data1, &value[4], 2);
1140                 memcpy(&data2, &value[6], 2);
1141                 memcpy(&data3, &value[8], 2);
1142                 memcpy(&data4, &value[10], 4);
1143                 memcpy(&data5, &value[14], 2);
1144
1145                 snprintf(uuid, n + 4, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
1146                                         ntohl(data0), ntohs(data1),
1147                                         ntohs(data2), ntohs(data3),
1148                                         ntohl(data4), ntohs(data5));
1149                 break;
1150         default:
1151                 g_free(uuid);
1152                 return NULL;
1153         }
1154
1155         return uuid;
1156 }
1157
1158 void _bt_otp_create_new_object(uint32_t size, char *uuid)
1159 {
1160         struct object_metadata *object = NULL;
1161
1162         /* Store current object id.
1163          * Incase of OACP Create fail, need to restore
1164          * it back.
1165          */
1166         prev_obj_id = selected_object->id;
1167
1168         object = g_new0(struct object_metadata, 1);
1169
1170         object->name = NULL;
1171         object->type = g_strdup(uuid);
1172         object->first_created = 0;
1173         object->last_modified = 0;
1174         object->curr_size = 0;
1175         object->alloc_size = size;
1176         object->id = object_id;
1177         object->props = OBJECT_READ | OBJECT_WRITE |
1178                                         OBJECT_EXECUTE | OBJECT_DELETE;
1179
1180         otp_object_list = g_slist_append(otp_object_list,
1181                                                 object);
1182
1183         update_obj_metadata_charc_value(object);
1184         selected_object = object;
1185         curr_obj_index = g_slist_length(otp_object_list) - 1;
1186         curr_obj_id = selected_object->id;
1187         object_id++;
1188
1189         free(uuid);
1190 }
1191
1192 void _bt_otp_restore_old_object()
1193 {
1194         struct object_metadata *object = NULL;
1195         guint index = 0;
1196
1197         object = _bt_otp_client_find_object(otp_object_list, curr_obj_id, &index);
1198         if (!object)
1199                 return;
1200
1201         otp_object_list = g_slist_remove(otp_object_list, object);
1202
1203         index = 0;
1204         object = _bt_otp_client_find_object(otp_object_list, prev_obj_id, &index);
1205         if (!object) {
1206                 BT_ERR("Object is NULL");
1207                 return;
1208         }
1209         oacp_create = FALSE;
1210         update_obj_metadata_charc_value(object);
1211         selected_object = object;
1212         curr_obj_index = index;
1213         object_id--;
1214 }
1215
1216 int _bt_otp_oacp_write_cb(char *value, int len, int offset,
1217                                                         char *remote_addr, struct indicate_info *info)
1218 {
1219         int ret = OACP_SUCCESS;
1220         int err = BLUETOOTH_ERROR_NONE;
1221         int opcode = value[0];
1222         uint32_t object_offset, length, object_size;
1223         uint8_t mode = 0;
1224         char *uuid;
1225         char absolute_file_path[BT_FILE_PATH_MAX_LEN] = {0, };
1226
1227         BT_INFO("OACP Opcode 0x%d", opcode);
1228
1229         if (!selected_object) {
1230                 BT_DBG("Object not selected");
1231                 ret = OACP_INVALID_OBJ;
1232                 goto fail;
1233         }
1234
1235         switch (opcode) {
1236         case OACP_CREATE:
1237                 BT_INFO("OACP_CREATE");
1238                 if (len < 7) {
1239                         BT_DBG("Error: invalid param");
1240                         ret = OACP_INVALID_PARAM;
1241                         goto fail;
1242                 }
1243                 /* UUIDs can be 2/4/16 bytes long.
1244                  * So based on remaining len, determine uuid len.
1245                  */
1246                 length = len - 5;
1247
1248                 uuid = _bt_otp_uuid_convert_hex_to_string(value + 1, length);
1249                 object_size = (uint32_t)(value[length + 4] & 0xFF) << 24 |
1250                                 (uint32_t)(value[length + 3] & 0xFF) << 16 |
1251                                 (uint32_t)(value[length + 2] & 0xFF) << 8  |
1252                                 (uint32_t)(value[length + 1] & 0xFF);
1253
1254                 BT_INFO("Size = %u, UUID = %s", object_size, uuid);
1255
1256                 oacp_create = TRUE;
1257                 _bt_otp_create_new_object(object_size, uuid);
1258
1259                 if (oacp_create_timeout_id > 0)
1260                         g_source_remove(oacp_create_timeout_id);
1261                 oacp_create_timeout_id = g_timeout_add(BT_OACP_MAX_TIMEOUT,
1262                         (GSourceFunc)__bt_oacp_create_timeout_cb, NULL);
1263                 break;
1264         case OACP_DELETE:
1265                 if (!(selected_object->props & OBJECT_DELETE)) {
1266                         ret = OACP_PROCEDURE_NOT_SUPPORTED;
1267                         goto fail;
1268                 }
1269                 snprintf(absolute_file_path, BT_FILE_PATH_MAX_LEN,
1270                                                 "%s%s", directory, selected_object->name);
1271
1272                 BT_DBG("absolute_file_path = [%s]", absolute_file_path);
1273
1274                 if (remove(absolute_file_path) != 0) {
1275                         BT_DBG("Error: unable to delete the file");
1276                         ret = OACP_OPERATION_FAILED;
1277                         goto fail;
1278                 }
1279
1280                 BT_DBG("File deleted successfully");
1281                 selected_object = NULL;
1282                 break;
1283         case OACP_CALC_CHECKSUM:
1284                 ret = OACP_OPCODE_NOT_SUPPORTED;
1285                 break;
1286         case OACP_EXECUTE:
1287                 if (!(selected_object->props & OBJECT_EXECUTE)) {
1288                         ret = OACP_PROCEDURE_NOT_SUPPORTED;
1289                         goto fail;
1290                 }
1291                 snprintf(absolute_file_path, BT_FILE_PATH_MAX_LEN,
1292                                         "file://%s%s", directory, selected_object->name);
1293
1294                 BT_DBG("absolute_file_path = [%s]", absolute_file_path);
1295
1296                 err = _bt_otp_send_launch_request(absolute_file_path);
1297                 if (err != BLUETOOTH_ERROR_NONE) {
1298                         BT_DBG("Error: unable to launch the file");
1299                         ret = OACP_OPERATION_FAILED;
1300                         goto fail;
1301                 }
1302
1303                 BT_DBG("Successfully launched the file");
1304                 break;
1305         case OACP_READ:
1306         case OACP_WRITE:
1307                 if (opcode == OACP_WRITE &&
1308                                 !(selected_object->props & OBJECT_WRITE)) {
1309                         ret = OACP_PROCEDURE_NOT_SUPPORTED;
1310                         goto fail;
1311                 }
1312
1313                 if (opcode == OACP_READ &&
1314                                 !(selected_object->props & OBJECT_READ)) {
1315                         ret = OACP_PROCEDURE_NOT_SUPPORTED;
1316                         goto fail;
1317                 }
1318
1319                 object_offset = (uint32_t)(value[4] & 0xFF) << 24 |
1320                                 (uint32_t)(value[3] & 0xFF) << 16 |
1321                                 (uint32_t)(value[2] & 0xFF) << 8  |
1322                                 (uint32_t)(value[1] & 0xFF);
1323                 length = (uint32_t)(value[8] & 0xFF) << 24 |
1324                         (uint32_t)(value[7] & 0xFF) << 16 |
1325                         (uint32_t)(value[6] & 0xFF) << 8  |
1326                         (uint32_t)(value[5] & 0xFF);
1327
1328                 if (opcode == OACP_WRITE)
1329                         mode = (uint8_t)value[9] & 0xFF;
1330
1331                 BT_INFO("Offset = %lu, Length = %lu", object_offset, length, mode);
1332
1333                 if (oacp_op) {
1334                         if (otc_connection_status) {
1335                                 /* Read/Write operation already going on. */
1336                                 ret = OACP_OBJECT_LOCKED;
1337                                 goto fail;
1338                         }
1339                         _bt_otp_free_oacp_op();
1340                 }
1341
1342                 oacp_op = g_malloc0(sizeof(struct oacp_operation));
1343                 oacp_op->offset = object_offset;
1344                 oacp_op->length = length;
1345                 oacp_op->remote_address = g_strdup(remote_addr);
1346                 oacp_op->mode = mode;
1347                 oacp_op->opcode = opcode;
1348                 oacp_op->length_sofar = 0;
1349                 oacp_op->fp = NULL;
1350
1351                 err = _bt_otp_open_otc_and_listen(remote_addr, "ListenOtc");
1352                 if (err != BLUETOOTH_ERROR_NONE) {
1353                         ret = OACP_CHANNEL_UNAVAILABLE;
1354                         _bt_otp_free_oacp_op();
1355                         goto fail;
1356                 }
1357                 break;
1358         case OACP_ABORT:
1359                 ret = OACP_OPCODE_NOT_SUPPORTED;
1360                 break;
1361         default:
1362                 ret = OACP_OPCODE_NOT_SUPPORTED;
1363                 break;
1364         }
1365 fail:
1366         info->resp_opcode = OACP_RESPONSE;
1367         info->req_opcode = opcode;
1368         info->result_code = ret;
1369         info->resp_param = NULL;
1370         return BLUETOOTH_ERROR_NONE;
1371 }
1372
1373 int _bt_otp_uuid_convert_string_to_hex(char *uuid, char *value)
1374 {
1375         int len, uuid_len;
1376         uint32_t data0, data4;
1377         uint16_t data1, data2, data3, data5;
1378
1379         if (!uuid) {
1380                 BT_ERR("Object Type UUID NULL");
1381                 return 0;
1382         }
1383
1384         len = strlen(uuid);
1385
1386         switch (len) {
1387         case 4:
1388                 /* UUID 16bits */
1389                 sscanf(uuid, "%04hx", &data1);
1390                 data1 = htons(data1);
1391                 memcpy(value, &data1, 2);
1392                 uuid_len = 2;
1393                 break;
1394
1395         case 8:
1396                 /* UUID 32bits */
1397                 sscanf(uuid, "%08x", &data0);
1398                 data0 = htonl(data0);
1399                 memcpy(value, &data0, 4);
1400                 uuid_len = 4;
1401                 break;
1402
1403         case 36:
1404                 /* UUID 128bits */
1405                 sscanf(uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
1406                         &data0, &data1, &data2,
1407                         &data3, &data4, &data5);
1408
1409                 data0 = htonl(data0);
1410                 data1 = htons(data1);
1411                 data2 = htons(data2);
1412                 data3 = htons(data3);
1413                 data4 = htonl(data4);
1414                 data5 = htons(data5);
1415
1416                 memcpy(value, &data0, 4);
1417                 memcpy(value+4, &data1, 2);
1418                 memcpy(value+6, &data2, 2);
1419                 memcpy(value+8, &data3, 2);
1420                 memcpy(value+10, &data4, 4);
1421                 memcpy(value+14, &data5, 2);
1422                 uuid_len = 16;
1423                 break;
1424
1425         default:
1426                 uuid_len = 0;
1427         }
1428
1429         return uuid_len;
1430 }
1431
1432 void convert_to_hex(struct object_metadata *object, char *metadata, char *value)
1433 {
1434         struct tm fc_tm;
1435
1436         BT_DBG("Metadata : %s", metadata);
1437
1438         memset(value, 0, 16);
1439
1440         if (!g_strcmp0(metadata, "size")) {
1441
1442                 value[3] = (object->curr_size >> 24) & 0xFF;
1443                 value[2] = (object->curr_size >> 16) & 0xFF;
1444                 value[1] = (object->curr_size >> 8) & 0xFF;
1445                 value[0] = object->curr_size & 0xFF;
1446
1447                 value[7] = (object->alloc_size >> 24) & 0xFF;
1448                 value[6] = (object->alloc_size >> 16) & 0xFF;
1449                 value[5] = (object->alloc_size >> 8) & 0xFF;
1450                 value[4] = object->alloc_size & 0xFF;
1451
1452         } else if (!g_strcmp0(metadata, "date")) {
1453
1454                 if (object->first_created) {
1455                         localtime_r(&(object->first_created), &fc_tm);
1456
1457                         value[1] = ((fc_tm.tm_year+1900) >> 8) & 0xFF;
1458                         value[0] = (fc_tm.tm_year+1900) & 0xFF;
1459                         value[2] = (fc_tm.tm_mon+1) & 0xFF;
1460                         value[3] = fc_tm.tm_mday & 0xFF;
1461                         value[4] = fc_tm.tm_hour & 0xFF;
1462                         value[5] = fc_tm.tm_min & 0xFF;
1463                         value[6] = fc_tm.tm_sec & 0xFF;
1464                 }
1465
1466         } else if (!g_strcmp0(metadata, "id")) {
1467
1468                 value[5] = (object->id >> 48) & 0xFF;
1469                 value[4] = (object->id >> 32) & 0xFF;
1470                 value[3] = (object->id >> 24) & 0xFF;
1471                 value[2] = (object->id >> 16) & 0xFF;
1472                 value[1] = (object->id >> 8) & 0xFF;
1473                 value[0] = object->id & 0xFF;
1474
1475         } else if (!g_strcmp0(metadata, "props")) {
1476                 value[3] = (object->props >> 24) & 0xFF;
1477                 value[2] = (object->props >> 16) & 0xFF;
1478                 value[1] = (object->props >> 8) & 0xFF;
1479                 value[0] = object->props & 0xFF;
1480         }
1481 }
1482
1483 void update_obj_metadata_charc_value(struct object_metadata *object)
1484 {
1485         /* Value can be of maximum 16 bytes */
1486         char value[16];
1487         int uuid_len;
1488
1489         if (!oacp_create) {
1490                 _bt_otp_set_char_value(otp_object_name_obj_path, object->name,
1491                                                                 strlen(object->name));
1492         }
1493
1494         uuid_len = _bt_otp_uuid_convert_string_to_hex(object->type, value);
1495         _bt_otp_set_char_value(otp_object_type_obj_path, value, uuid_len);
1496
1497         convert_to_hex(object, "size", value);
1498         _bt_otp_set_char_value(otp_object_size_obj_path, value, 8);
1499
1500         convert_to_hex(object, "date", value);
1501         _bt_otp_set_char_value(otp_object_first_created_obj_path, value, 7);
1502         _bt_otp_set_char_value(otp_object_last_modified_obj_path, value, 7);
1503
1504         /* Object ID is optonal for single object server */
1505         if (mutiple_obj_support) {
1506                 convert_to_hex(object, "id", value);
1507                 _bt_otp_set_char_value(otp_object_id_obj_path, value, 6);
1508         }
1509
1510         convert_to_hex(object, "props", value);
1511         _bt_otp_set_char_value(otp_object_prop_obj_path, value, 4);
1512 }
1513
1514 struct object_metadata *_bt_otp_client_find_object(GSList *list, uint64_t id, guint *index)
1515 {
1516         GSList *l;
1517         struct object_metadata *info;
1518
1519         for (l = list; l; l = g_slist_next(l)) {
1520                 (*index)++;
1521                 info = l->data;
1522
1523                 if (info && (info->id == id))
1524                         return info;
1525         }
1526         return NULL;
1527 }
1528
1529 int _bt_otp_olcp_write_cb(char *value, int len, int offset,
1530                                         struct indicate_info *info)
1531 {
1532         int ret = OLCP_SUCCESS;
1533         int opcode = value[0];
1534         struct object_metadata *object;
1535         uint64_t object_id;
1536         guint index = 0;
1537
1538         BT_INFO("OLCP Opcode 0x%d", opcode);
1539
1540         if (!otp_object_list) {
1541                 ret = OLCP_NO_OBJ;
1542                 goto fail;
1543         }
1544
1545         switch (opcode) {
1546         case OLCP_FIRST:
1547                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, 0);
1548                 if (!object) {
1549                         ret = OLCP_OUT_OF_BOUNDS;
1550                         goto fail;
1551                 }
1552                 update_obj_metadata_charc_value(object);
1553                 selected_object = object;
1554                 curr_obj_index = 0;
1555                 break;
1556         case OLCP_LAST:
1557                 len = g_slist_length(otp_object_list);
1558                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, len-1);
1559                 if (!object) {
1560                         ret = OLCP_OUT_OF_BOUNDS;
1561                         goto fail;
1562                 }
1563                 update_obj_metadata_charc_value(object);
1564                 selected_object = object;
1565                 curr_obj_index = len-1;
1566                 break;
1567         case OLCP_PREVIOUS:
1568                 if (curr_obj_index == 0) {
1569                         ret = OLCP_OUT_OF_BOUNDS;
1570                         goto fail;
1571                 }
1572                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index-1);
1573                 if (!object) {
1574                         ret = OLCP_OUT_OF_BOUNDS;
1575                         goto fail;
1576                 }
1577                 update_obj_metadata_charc_value(object);
1578                 selected_object = object;
1579                 curr_obj_index -= 1;
1580                 break;
1581         case OLCP_NEXT:
1582                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index+1);
1583                 if (!object) {
1584                         ret = OLCP_OUT_OF_BOUNDS;
1585                         goto fail;
1586                 }
1587                 update_obj_metadata_charc_value(object);
1588                 selected_object = object;
1589                 curr_obj_index += 1;
1590                 break;
1591         case OLCP_GOTO:
1592                 object_id = (uint64_t)(value[6] & 0xFF) << 40 |
1593                                 (uint64_t)(value[5] & 0xFF) << 32 |
1594                                 (uint64_t)(value[4] & 0xFF) << 24 |
1595                                 (uint64_t)(value[3] & 0xFF) << 16 |
1596                                 (uint64_t)(value[2] & 0xFF) << 8  |
1597                                 (uint64_t)(value[1] & 0xFF);
1598                 BT_INFO("Object ID [%llu]", object_id);
1599                 if (selected_object && selected_object->id == object_id)
1600                         goto fail;
1601
1602                 object = _bt_otp_client_find_object(otp_object_list, object_id, &index);
1603                 if (!object) {
1604                         ret = OLCP_OJECT_ID_NOT_FOUND;
1605                         goto fail;
1606                 }
1607                 update_obj_metadata_charc_value(object);
1608                 selected_object = object;
1609                 curr_obj_index = index - 1;
1610                 break;
1611         case OLCP_ORDER:
1612         case OLCP_REQ_NO_OBJ:
1613         case OLCP_CLEAR_MARKING:
1614         default:
1615                 ret = OLCP_OPCODE_NOT_SUPPORTED;
1616                 break;
1617         }
1618 fail:
1619         info->resp_opcode = OLCP_RESPONSE;
1620         info->req_opcode = opcode;
1621         info->result_code = ret;
1622         info->resp_param = NULL;
1623         return BLUETOOTH_ERROR_NONE;
1624 }
1625
1626 int _bt_otp_obj_name_write_cb(char *value, int len)
1627 {
1628         struct object_metadata *object;
1629         char *filename;
1630         char new_abs_filepath[BT_FILE_PATH_MAX_LEN] = {0, };
1631         int ret = BLUETOOTH_ERROR_NONE;
1632         FILE *fp = NULL;
1633         char err_msg[256] = {0, };
1634
1635         object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index);
1636         if (!object)
1637                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1638
1639         filename = g_strndup(value, len);
1640         snprintf(new_abs_filepath, BT_FILE_PATH_MAX_LEN, "%s%s",
1641                         directory, filename);
1642         BT_DBG("file_path = [%s]", new_abs_filepath);
1643
1644         fp = fopen(new_abs_filepath, "r");
1645         /* fopen succeed means file already exists */
1646         if (fp) {
1647                 ret = BLUETOOTH_OTP_ERROR_OBJECT_NAME_EXISTS;
1648                 goto fail;
1649         }
1650
1651         if (oacp_create) {
1652                 struct stat st;
1653
1654                 fp = fopen(new_abs_filepath, "a");
1655                 if (!fp) {
1656                         cynara_strerror(errno, err_msg, sizeof(err_msg));
1657                         BT_ERR("fopen() failed : %s", err_msg);
1658                         ret = BLUETOOTH_ATT_ERROR_INTERNAL;
1659                         goto fail;
1660                 }
1661
1662                 if (stat(new_abs_filepath, &st) == -1) {
1663                         BT_INFO("stat failed: (%d)\n", errno);
1664                         ret = BLUETOOTH_ATT_ERROR_INTERNAL;
1665                         goto fail;
1666                 }
1667
1668                 object->name = g_strdup(filename);
1669                 object->first_created = st.st_ctime;
1670                 object->last_modified = st.st_ctime;
1671                 object->curr_size = (uint32_t) st.st_size;
1672                 oacp_create = FALSE;
1673         } else {
1674                 char old_abs_filepath[BT_FILE_PATH_MAX_LEN] = {0, };
1675                 snprintf(old_abs_filepath, BT_FILE_PATH_MAX_LEN, "%s%s",
1676                                 directory, object->name);
1677
1678                 if (rename(old_abs_filepath, new_abs_filepath)) {
1679                         ret = BLUETOOTH_ATT_ERROR_INTERNAL;
1680                         goto fail;
1681                 }
1682         }
1683
1684         memcpy(object->name, value, len);
1685         _bt_otp_set_char_value(otp_object_name_obj_path, value, len);
1686
1687 fail:
1688         if (oacp_create)
1689                 _bt_otp_restore_old_object();
1690
1691         if (oacp_create_timeout_id > 0)
1692                 g_source_remove(oacp_create_timeout_id);
1693
1694         if (fp)
1695                 fclose(fp);
1696
1697         g_free(filename);
1698         return ret;
1699 }
1700
1701 int _bt_otp_obj_first_created_write_cb(char *value, int len)
1702 {
1703         struct object_metadata *object;
1704         struct tm tm = {0};
1705         uint16_t year;
1706
1707         object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index);
1708         if (!object)
1709                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1710
1711         year = (uint16_t)(value[1] & 0xFF) << 8 |
1712                         (uint16_t)(value[0] & 0xFF);
1713         tm.tm_year = year-1900;
1714         tm.tm_mon = value[2] & 0xFF;
1715         tm.tm_mon = tm.tm_mon-1;
1716         tm.tm_mday = value[3] & 0xFF;
1717         tm.tm_hour = value[4] & 0xFF;
1718         tm.tm_min = value[5] & 0xFF;
1719         tm.tm_sec = value[6] & 0xFF;
1720
1721         object->first_created = mktime(&tm);
1722         _bt_otp_set_char_value(otp_object_first_created_obj_path, value, len);
1723
1724         return BLUETOOTH_ERROR_NONE;
1725 }
1726
1727 int _bt_otp_obj_last_modified_write_cb(char *value, int len)
1728 {
1729         struct object_metadata *object;
1730         struct tm tm = {0};
1731         uint16_t year;
1732
1733         object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index);
1734         if (!object)
1735                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1736
1737         year = (uint16_t)(value[1] & 0xFF) << 8 |
1738                         (uint16_t)(value[0] & 0xFF);
1739         tm.tm_year = year-1900;
1740         tm.tm_mon = value[2] & 0xFF;
1741         tm.tm_mon = tm.tm_mon-1;
1742         tm.tm_mday = value[3] & 0xFF;
1743         tm.tm_hour = value[4] & 0xFF;
1744         tm.tm_min = value[5] & 0xFF;
1745         tm.tm_sec = value[6] & 0xFF;
1746
1747         object->last_modified = mktime(&tm);
1748         _bt_otp_set_char_value(otp_object_last_modified_obj_path, value, len);
1749
1750         return BLUETOOTH_ERROR_NONE;
1751 }
1752
1753 int _bt_otp_obj_props_write_cb(char *value, int len)
1754 {
1755         struct object_metadata *object;
1756         uint32_t props;
1757
1758         /* Any attempt to write RFU bits is error */
1759         if (value[1] || value[2] || value[3])
1760                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1761
1762         object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index);
1763         if (!object)
1764                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1765
1766         props = (uint32_t)(value[3] & 0xFF) << 24       |
1767                         (uint32_t)(value[2] & 0xFF) << 16       |
1768                         (uint32_t)(value[1] & 0xFF) << 8        |
1769                         (uint32_t)(value[0] & 0xFF);
1770
1771         object->props = props;
1772         _bt_otp_set_char_value(otp_object_prop_obj_path, value, len);
1773
1774         return BLUETOOTH_ERROR_NONE;
1775 }
1776
1777 static struct otp_char_info *otp_get_char_value(const char *path)
1778 {
1779         GSList *tmp = NULL;
1780
1781         for (tmp = otp_char_list; tmp != NULL; tmp = tmp->next) {
1782                 if (tmp->data) {
1783                         struct otp_char_info *char_info = tmp->data;
1784                         if (!g_strcmp0(char_info->char_path, path))
1785                                 return char_info;
1786                 }
1787         }
1788
1789         return NULL;
1790 }
1791
1792 int _bt_otp_read_cb(const char *obj_path, char **value, int *len, uint16_t offset)
1793 {
1794         struct otp_char_info *info = NULL;
1795
1796         if (!obj_path) {
1797                 BT_ERR("Wrong Obj path");
1798                 return BLUETOOTH_ATT_ERROR_INTERNAL;
1799         }
1800
1801         if (g_strcmp0(obj_path, otp_feature_obj_path)) {
1802                 if (!selected_object)
1803                         return BLUETOOTH_OTP_ERROR_OBJECT_NOT_SELECTED;
1804         }
1805
1806         info = otp_get_char_value(obj_path);
1807         if (info) {
1808                 if (oacp_create && !g_strcmp0(obj_path, otp_object_name_obj_path)) {
1809                         /* char_value is NULL, value_length is zero */
1810                         *value = NULL;
1811                         *len = 0;
1812                         return BLUETOOTH_ATT_ERROR_NONE;
1813                 }
1814
1815                 if (info->char_value == NULL || info->value_length == 0)
1816                         return BLUETOOTH_ATT_ERROR_INTERNAL;
1817
1818                 if (offset > info->value_length)
1819                         return BLUETOOTH_ATT_ERROR_INVALID_OFFSET;
1820
1821                 *len = info->value_length - offset;
1822                 *value = (char *)malloc(sizeof(char)*(*len));
1823                 memcpy(*value, info->char_value, *len);
1824
1825                 return BLUETOOTH_ATT_ERROR_NONE;
1826         } else {
1827                 return BLUETOOTH_ATT_ERROR_INTERNAL;
1828         }
1829 }
1830
1831 static void _otp_convert_address_to_hex(bluetooth_device_address_t *addr_hex,
1832                                                         const char *addr_str)
1833 {
1834         int i = 0;
1835         unsigned int addr[BLUETOOTH_ADDRESS_LENGTH] = { 0, };
1836
1837         if (addr_str == NULL || addr_str[0] == '\0')
1838                 return;
1839
1840         i = sscanf(addr_str, "%X:%X:%X:%X:%X:%X", &addr[0], &addr[1],
1841                                 &addr[2], &addr[3], &addr[4], &addr[5]);
1842         if (i != BLUETOOTH_ADDRESS_LENGTH)
1843                 BT_ERR("Invalid format string - [%s]", addr_str);
1844
1845         for (i = 0; i < BLUETOOTH_ADDRESS_LENGTH; i++)
1846                 addr_hex->addr[i] = (unsigned char)addr[i];
1847 }
1848
1849 static void _bt_otp_send_indication(const char *obj_path,
1850                                 struct indicate_info *info,
1851                                 bluetooth_device_address_t *remote_address)
1852 {
1853         int ret = BLUETOOTH_ERROR_NONE;
1854         char value[7] = {0x00};
1855         int length = OTP_INDICATION_LEN_WITHOUT_RESP;
1856
1857         BT_DBG("");
1858
1859         value[0] = info->resp_opcode & 0xFF;
1860         value[1] = info->req_opcode & 0xFF;
1861         value[2] = info->result_code & 0xFF;
1862         if (info->resp_param) {
1863                 value[6] = info->resp_param[3] & 0xFF;
1864                 value[5] = info->resp_param[4] & 0xFF;
1865                 value[4] = info->resp_param[5] & 0xFF;
1866                 value[3] = info->resp_param[6] & 0xFF;
1867                 length = OTP_INDICATION_LEN_WITH_RESP;
1868         }
1869
1870         BT_DBG("Opcode: %d", value[1]);
1871
1872         /* Store the status value */
1873         _bt_otp_set_char_value(obj_path, value, length);
1874
1875         /* Send indication */
1876         ret = bluetooth_gatt_server_set_notification(obj_path, remote_address);
1877         if (ret != BLUETOOTH_ERROR_NONE) {
1878                 BT_ERR("_bt_otp_send_control_point_indication failed");
1879                 return;
1880         }
1881         ret = bluetooth_gatt_update_characteristic(obj_path, value, length);
1882         if (ret != BLUETOOTH_ERROR_NONE) {
1883                 BT_ERR("_bt_otp_send_control_point_indication failed");
1884                 return;
1885         }
1886 }
1887
1888 void _bt_otp_gatt_char_property_changed_event(GVariant *msg,
1889                                 const char *path)
1890 {
1891         int result = BLUETOOTH_ERROR_NONE;
1892         GVariantIter value_iter;
1893         const char *property = NULL;
1894         const char *char_path = NULL;
1895         const char *svc_handle = NULL;
1896         GVariant *var = NULL;
1897         GVariant *val = NULL;
1898         g_variant_iter_init(&value_iter, msg);
1899
1900         while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &var))) {
1901
1902                 if (property == NULL) {
1903                         BT_ERR("Property NULL");
1904                         return;
1905                 }
1906
1907                 if (!g_strcmp0(property, "WriteValue")) {
1908                         int len = 0;
1909                         BT_INFO("WriteValue");
1910                         BT_INFO("Type '%s'\n", g_variant_get_type_string(var));
1911
1912                         if (var) {
1913                                 bluetooth_device_address_t addr_hex = { {0,} };
1914                                 gchar *addr = NULL;
1915                                 guint8 req_id = 1;
1916                                 guint16 offset = 0;
1917                                 char *value = NULL;
1918                                 struct indicate_info info;
1919
1920                                 g_variant_get(var, "(&s&s&syq@ay)",
1921                                                 &char_path, &svc_handle,
1922                                                 &addr, &req_id, &offset, &val);
1923
1924                                 len = g_variant_get_size(val);
1925
1926                                 BT_DBG("Len = %d, BT_ADDR = %s", len, addr);
1927
1928                                 value = (char *) g_variant_get_data(val);
1929                                 _otp_convert_address_to_hex(&addr_hex, addr);
1930
1931                                 if (len != 0) {
1932                                         if (!g_strcmp0(char_path, otp_oacp_obj_path)) {
1933                                                 if (!OACP_indicate)
1934                                                         result = BLUETOOTH_ATT_ERROR_CCCD_IMPROPERLY_CONFIGURED;
1935                                                 else
1936                                                         result = _bt_otp_oacp_write_cb(value, len, offset, addr, &info);
1937                                         } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) {
1938                                                 if (!OLCP_indicate)
1939                                                         result = BLUETOOTH_ATT_ERROR_CCCD_IMPROPERLY_CONFIGURED;
1940                                                 else
1941                                                         result = _bt_otp_olcp_write_cb(value, len, offset, &info);
1942                                         } else if (!g_strcmp0(char_path, otp_object_name_obj_path)) {
1943                                                 result = _bt_otp_obj_name_write_cb(value, len);
1944                                         } else if (!g_strcmp0(char_path, otp_object_first_created_obj_path)) {
1945                                                 result = _bt_otp_obj_first_created_write_cb(value, len);
1946                                         } else if (!g_strcmp0(char_path, otp_object_last_modified_obj_path)) {
1947                                                 result = _bt_otp_obj_last_modified_write_cb(value, len);
1948                                         } else if (!g_strcmp0(char_path, otp_object_prop_obj_path)) {
1949                                                 result = _bt_otp_obj_props_write_cb(value, len);
1950                                         } else {
1951                                                 BT_ERR("Wrong Object Path %s", char_path);
1952                                                 result = BLUETOOTH_ERROR_INTERNAL;
1953                                         }
1954                                         bluetooth_gatt_send_response(req_id,
1955                                         BLUETOOTH_GATT_ATT_REQUEST_TYPE_WRITE,
1956                                                         result, 0, NULL, 0);
1957
1958                                         /* Send indication for CPs */
1959                                         if (!g_strcmp0(char_path, otp_oacp_obj_path)) {
1960                                                 if (OACP_indicate)
1961                                                         _bt_otp_send_indication(char_path, &info, &addr_hex);
1962                                         } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) {
1963                                                 if (OLCP_indicate)
1964                                                         _bt_otp_send_indication(char_path, &info, &addr_hex);
1965                                         }
1966                                 } else {
1967                                         BT_ERR("Array Len 0");
1968                                 }
1969                         } else {
1970                                 BT_ERR("var==NULL");
1971                         }
1972                 } else if (!g_strcmp0(property, "ReadValue")) {
1973                         gchar *addr = NULL;
1974                         guint8 req_id = 1;
1975                         guint16 offset = 0;
1976                         char *value = NULL;
1977                         int len = 0;
1978                         result = BLUETOOTH_ATT_ERROR_NONE;
1979
1980                         BT_INFO("ReadValue");
1981                         BT_INFO("Type '%s'\n", g_variant_get_type_string(var));
1982
1983                         g_variant_get(var, "(&s&s&syq)", &char_path,
1984                                         &svc_handle, &addr, &req_id, &offset);
1985
1986                         result = _bt_otp_read_cb(char_path, &value, &len, offset);
1987
1988                         if (result != BLUETOOTH_ATT_ERROR_NONE) {
1989                                 BT_ERR("ReadValue failed %s", char_path);
1990                                 bluetooth_gatt_send_response(req_id,
1991                                 BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ,
1992                                                 result, offset, NULL, 0);
1993                         } else {
1994                                 bluetooth_gatt_send_response(req_id,
1995                                 BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ,
1996                                                 result, offset, value, len);
1997                                 if (value)
1998                                         g_free(value);
1999                         }
2000                 } else if (!g_strcmp0(property, "NotificationStateChanged")) {
2001                         gboolean indicate = FALSE;
2002
2003                         g_variant_get(var, "(&s&sb)", &char_path,
2004                                                 &svc_handle, &indicate);
2005
2006                         BT_INFO("%s : [%s]", property,
2007                                 indicate ? "StartNotify" : "StopNotify");
2008                         BT_INFO("Type '%s'\n", g_variant_get_type_string(var));
2009
2010                         if (!g_strcmp0(char_path, otp_oacp_obj_path))
2011                                 OACP_indicate = indicate;
2012                         else if (!g_strcmp0(char_path, otp_olcp_obj_path))
2013                                 OLCP_indicate = indicate;
2014                 }
2015         }
2016         return;
2017 }
2018
2019 void _bt_otp_property_event_filter(GDBusConnection *connection,
2020                                         const gchar *sender_name,
2021                                         const gchar *object_path,
2022                                         const gchar *interface_name,
2023                                         const gchar *signal_name,
2024                                         GVariant *parameters,
2025                                         gpointer user_data)
2026 {
2027         GVariant *value;
2028
2029         if (signal_name == NULL) {
2030                 BT_ERR("Wrong Signal");
2031                 return;
2032         }
2033
2034         if (g_strcmp0(signal_name, PROPERTIES_CHANGED) == 0) {
2035
2036                 g_variant_get(parameters, "(@a{sv}@as)", &value, NULL);
2037                 _bt_otp_gatt_char_property_changed_event(value, object_path);
2038         }
2039 }
2040
2041 void _bt_otp_adapter_event_filter(GDBusConnection *connection,
2042                                         const gchar *sender_name,
2043                                         const gchar *object_path,
2044                                         const gchar *interface_name,
2045                                         const gchar *signal_name,
2046                                         GVariant *parameters,
2047                                         gpointer user_data)
2048 {
2049         if (signal_name == NULL) {
2050                 BT_ERR("Wrong Signal");
2051                 return;
2052         }
2053
2054         BT_INFO("Interface %s, Signal %s", interface_name, signal_name);
2055
2056         if (g_strcmp0(interface_name, BT_OTP_INTERFACE_NAME) == 0) {
2057                 if (strcasecmp(signal_name, BLE_DISABLED) == 0)
2058                         _bt_otp_exit();
2059         }
2060 }
2061
2062 void _bt_otc_disconnected_cb(GDBusConnection *connection,
2063                                         const gchar *sender_name,
2064                                         const gchar *object_path,
2065                                         const gchar *interface_name,
2066                                         const gchar *signal_name,
2067                                         GVariant *parameters,
2068                                         gpointer user_data)
2069 {
2070         if (signal_name == NULL) {
2071                 BT_ERR("Wrong Signal");
2072                 return;
2073         }
2074
2075         BT_INFO("Interface %s, Signal %s", interface_name, signal_name);
2076
2077         if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) {
2078                 if (strcasecmp(signal_name, OTC_DISCONNECTED) == 0) {
2079                         BT_DBG("OTC Channel Disconnected dev_path[%s]",
2080                                                                 object_path);
2081                         otc_connection_status = FALSE;
2082                         _bt_otp_free_oacp_op();
2083                 }
2084         }
2085 }
2086
2087 void _bt_otp_device_property_event_filter(GDBusConnection *connection,
2088                                         const gchar *sender_name,
2089                                         const gchar *object_path,
2090                                         const gchar *interface_name,
2091                                         const gchar *signal_name,
2092                                         GVariant *parameters,
2093                                         gpointer user_data)
2094 {
2095         char *interfacename = NULL;
2096         GVariant *val = NULL;
2097
2098         g_variant_get(parameters, "(&s@a{sv}@as)", &interfacename, &val, NULL);
2099
2100         if (strcasecmp(interfacename, BT_DEVICE_INTERFACE) == 0) {
2101                 GVariantIter value_iter;
2102                 GVariant *val1;
2103                 char *property = NULL;
2104
2105                 g_variant_iter_init(&value_iter, val);
2106                 while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &val1))) {
2107                         if (strcasecmp(property, "GattConnected") == 0) {
2108                                 gboolean gatt_connected = FALSE;
2109                                 char *address = NULL;
2110
2111                                 g_variant_get(val1, "b", &gatt_connected);
2112
2113                                 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
2114
2115                                 _bt_convert_device_path_to_address(object_path, address);
2116
2117                                 BT_DBG("gatt_connected: %d", gatt_connected);
2118                                 BT_DBG("address: %s", address);
2119                                 if (!gatt_connected) {
2120                                         if (oacp_create)
2121                                                 _bt_otp_restore_old_object();
2122
2123                                         if (oacp_create_timeout_id > 0)
2124                                                 g_source_remove(oacp_create_timeout_id);
2125                                 }
2126                                 g_free(address);
2127                         }
2128                 }
2129         }
2130 }
2131
2132 int _bt_otp_init_event_receiver()
2133 {
2134         BT_DBG("+");
2135         GError *error = NULL;
2136
2137         if (conn == NULL) {
2138                 conn =  g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
2139                 if (error != NULL) {
2140                         BT_ERR("ERROR: Can't get on system bus [%s]",
2141                                                         error->message);
2142                         g_clear_error(&error);
2143                 }
2144         }
2145
2146         property_sub_id = g_dbus_connection_signal_subscribe(conn,
2147                                 NULL,
2148                                 BT_OTP_INTERFACE_NAME,
2149                                 PROPERTIES_CHANGED,
2150                                 BT_OTP_OBJECT_PATH, NULL, 0,
2151                                 _bt_otp_property_event_filter,
2152                                 NULL, NULL);
2153
2154         adapter_sub_id = g_dbus_connection_signal_subscribe(conn,
2155                                 NULL,
2156                                 BT_OTP_INTERFACE_NAME,
2157                                 BLE_DISABLED,
2158                                 BT_OTP_OBJECT_PATH, NULL, 0,
2159                                 _bt_otp_adapter_event_filter,
2160                                 NULL, NULL);
2161
2162         device_sub_id = g_dbus_connection_signal_subscribe(conn,
2163                                         NULL, BT_DEVICE_INTERFACE,
2164                                         OTC_DISCONNECTED, NULL, NULL, 0,
2165                                         _bt_otc_disconnected_cb,
2166                                         NULL, NULL);
2167
2168         device_property_sub_id = g_dbus_connection_signal_subscribe(conn,
2169                                 NULL, BT_PROPERTIES_INTERFACE,
2170                                 PROPERTIES_CHANGED, NULL, NULL, 0,
2171                                 _bt_otp_device_property_event_filter,
2172                                 NULL, NULL);
2173
2174         BT_DBG("-");
2175         return 0;
2176 }
2177
2178 void _bt_otp_deinit_event_receiver(void)
2179 {
2180         BT_DBG("+");
2181
2182         g_dbus_connection_signal_unsubscribe(conn, property_sub_id);
2183         g_dbus_connection_signal_unsubscribe(conn, adapter_sub_id);
2184         g_dbus_connection_signal_unsubscribe(conn, device_sub_id);
2185         g_dbus_connection_signal_unsubscribe(conn, device_property_sub_id);
2186         conn = NULL;
2187
2188         BT_DBG("-");
2189 }
2190
2191 static void _bt_otp_sig_handler(int sig)
2192 {
2193         BT_DBG("+");
2194         switch (sig) {
2195         case SIGTERM:
2196                 BT_DBG("caught signal - sigterm\n");
2197                 break;
2198         case SIGINT:
2199                 BT_DBG("caught signal - sigint\n");
2200                 break;
2201         case SIGKILL:
2202                 BT_DBG("caught signal - sigkill\n");
2203                 break;
2204         default:
2205                 BT_DBG("caught signal %d and ignored\n", sig);
2206                 break;
2207         }
2208         BT_DBG("-");
2209 }
2210
2211 /* OTP Service Main loop */
2212 int main(void)
2213 {
2214         struct sigaction sa;
2215         BT_ERR("Starting the bt-otp daemon");
2216
2217         memset(&sa, 0, sizeof(sa));
2218         sa.sa_handler = _bt_otp_sig_handler;
2219         sa.sa_flags = SA_SIGINFO;
2220         sigaction(SIGINT, &sa, NULL);
2221         sigaction(SIGTERM, &sa, NULL);
2222         sigaction(SIGKILL, &sa, NULL);
2223
2224         if (_bt_otp_register_interface() != BLUETOOTH_ERROR_NONE) {
2225                 BT_ERR("Fail to register otp service");
2226                 return -4;
2227         }
2228
2229         if (_bt_otp_init_event_receiver() != BLUETOOTH_ERROR_NONE) {
2230                 BT_ERR("Fail to init event reciever");
2231                 return -5;
2232         }
2233
2234         main_loop = g_main_loop_new(NULL, FALSE);
2235
2236         g_main_loop_run(main_loop);
2237
2238         BT_DBG("g_main_loop_quit called!");
2239
2240         if (main_loop != NULL)
2241                 g_main_loop_unref(main_loop);
2242
2243         return 0;
2244 }