Update the RFCOMM server connection information
[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
1193 void _bt_otp_restore_old_object()
1194 {
1195         struct object_metadata *object = NULL;
1196         guint index = 0;
1197
1198         object = _bt_otp_client_find_object(otp_object_list, curr_obj_id, &index);
1199         if (!object)
1200                 return;
1201
1202         otp_object_list = g_slist_remove(otp_object_list, object);
1203
1204         index = 0;
1205         object = _bt_otp_client_find_object(otp_object_list, prev_obj_id, &index);
1206         if (!object) {
1207                 BT_ERR("Object is NULL");
1208                 return;
1209         }
1210         oacp_create = FALSE;
1211         update_obj_metadata_charc_value(object);
1212         selected_object = object;
1213         curr_obj_index = index;
1214         object_id--;
1215 }
1216
1217 int _bt_otp_oacp_write_cb(char *value, int len, int offset,
1218                                                         char *remote_addr, struct indicate_info *info)
1219 {
1220         int ret = OACP_SUCCESS;
1221         int err = BLUETOOTH_ERROR_NONE;
1222         int opcode = value[0];
1223         uint32_t object_offset, length, object_size;
1224         uint8_t mode = 0;
1225         char *uuid = NULL;
1226         char absolute_file_path[BT_FILE_PATH_MAX_LEN] = {0, };
1227
1228         BT_INFO("OACP Opcode 0x%d", opcode);
1229
1230         if (!selected_object) {
1231                 BT_DBG("Object not selected");
1232                 ret = OACP_INVALID_OBJ;
1233                 goto fail;
1234         }
1235
1236         switch (opcode) {
1237         case OACP_CREATE:
1238                 BT_INFO("OACP_CREATE");
1239                 if (len < 7) {
1240                         BT_DBG("Error: invalid param");
1241                         ret = OACP_INVALID_PARAM;
1242                         goto fail;
1243                 }
1244                 /* UUIDs can be 2/4/16 bytes long.
1245                  * So based on remaining len, determine uuid len.
1246                  */
1247                 length = len - 5;
1248
1249                 uuid = _bt_otp_uuid_convert_hex_to_string(value + 1, length);
1250                 object_size = (uint32_t)(value[length + 4] & 0xFF) << 24 |
1251                                 (uint32_t)(value[length + 3] & 0xFF) << 16 |
1252                                 (uint32_t)(value[length + 2] & 0xFF) << 8  |
1253                                 (uint32_t)(value[length + 1] & 0xFF);
1254
1255                 BT_INFO("Size = %u, UUID = %s", object_size, uuid);
1256
1257                 oacp_create = TRUE;
1258                 _bt_otp_create_new_object(object_size, uuid);
1259                 g_free(uuid);
1260
1261                 if (oacp_create_timeout_id > 0)
1262                         g_source_remove(oacp_create_timeout_id);
1263                 oacp_create_timeout_id = g_timeout_add(BT_OACP_MAX_TIMEOUT,
1264                         (GSourceFunc)__bt_oacp_create_timeout_cb, NULL);
1265                 break;
1266         case OACP_DELETE:
1267                 if (!(selected_object->props & OBJECT_DELETE)) {
1268                         ret = OACP_PROCEDURE_NOT_SUPPORTED;
1269                         goto fail;
1270                 }
1271                 snprintf(absolute_file_path, BT_FILE_PATH_MAX_LEN,
1272                                                 "%s%s", directory, selected_object->name);
1273
1274                 BT_DBG("absolute_file_path = [%s]", absolute_file_path);
1275
1276                 if (remove(absolute_file_path) != 0) {
1277                         BT_DBG("Error: unable to delete the file");
1278                         ret = OACP_OPERATION_FAILED;
1279                         goto fail;
1280                 }
1281
1282                 BT_DBG("File deleted successfully");
1283                 selected_object = NULL;
1284                 break;
1285         case OACP_CALC_CHECKSUM:
1286                 ret = OACP_OPCODE_NOT_SUPPORTED;
1287                 break;
1288         case OACP_EXECUTE:
1289                 if (!(selected_object->props & OBJECT_EXECUTE)) {
1290                         ret = OACP_PROCEDURE_NOT_SUPPORTED;
1291                         goto fail;
1292                 }
1293                 snprintf(absolute_file_path, BT_FILE_PATH_MAX_LEN,
1294                                         "file://%s%s", directory, selected_object->name);
1295
1296                 BT_DBG("absolute_file_path = [%s]", absolute_file_path);
1297
1298                 err = _bt_otp_send_launch_request(absolute_file_path);
1299                 if (err != BLUETOOTH_ERROR_NONE) {
1300                         BT_DBG("Error: unable to launch the file");
1301                         ret = OACP_OPERATION_FAILED;
1302                         goto fail;
1303                 }
1304
1305                 BT_DBG("Successfully launched the file");
1306                 break;
1307         case OACP_READ:
1308         case OACP_WRITE:
1309                 if (opcode == OACP_WRITE &&
1310                                 !(selected_object->props & OBJECT_WRITE)) {
1311                         ret = OACP_PROCEDURE_NOT_SUPPORTED;
1312                         goto fail;
1313                 }
1314
1315                 if (opcode == OACP_READ &&
1316                                 !(selected_object->props & OBJECT_READ)) {
1317                         ret = OACP_PROCEDURE_NOT_SUPPORTED;
1318                         goto fail;
1319                 }
1320
1321                 object_offset = (uint32_t)(value[4] & 0xFF) << 24 |
1322                                 (uint32_t)(value[3] & 0xFF) << 16 |
1323                                 (uint32_t)(value[2] & 0xFF) << 8  |
1324                                 (uint32_t)(value[1] & 0xFF);
1325                 length = (uint32_t)(value[8] & 0xFF) << 24 |
1326                         (uint32_t)(value[7] & 0xFF) << 16 |
1327                         (uint32_t)(value[6] & 0xFF) << 8  |
1328                         (uint32_t)(value[5] & 0xFF);
1329
1330                 if (opcode == OACP_WRITE)
1331                         mode = (uint8_t)value[9] & 0xFF;
1332
1333                 BT_INFO("Offset = %u, Length = %u", object_offset, length);
1334
1335                 if (oacp_op) {
1336                         if (otc_connection_status) {
1337                                 /* Read/Write operation already going on. */
1338                                 ret = OACP_OBJECT_LOCKED;
1339                                 goto fail;
1340                         }
1341                         _bt_otp_free_oacp_op();
1342                 }
1343
1344                 oacp_op = g_malloc0(sizeof(struct oacp_operation));
1345                 oacp_op->offset = object_offset;
1346                 oacp_op->length = length;
1347                 oacp_op->remote_address = g_strdup(remote_addr);
1348                 oacp_op->mode = mode;
1349                 oacp_op->opcode = opcode;
1350                 oacp_op->length_sofar = 0;
1351                 oacp_op->fp = NULL;
1352
1353                 err = _bt_otp_open_otc_and_listen(remote_addr, "ListenOtc");
1354                 if (err != BLUETOOTH_ERROR_NONE) {
1355                         ret = OACP_CHANNEL_UNAVAILABLE;
1356                         _bt_otp_free_oacp_op();
1357                         goto fail;
1358                 }
1359                 break;
1360         case OACP_ABORT:
1361                 ret = OACP_OPCODE_NOT_SUPPORTED;
1362                 break;
1363         default:
1364                 ret = OACP_OPCODE_NOT_SUPPORTED;
1365                 break;
1366         }
1367 fail:
1368         info->resp_opcode = OACP_RESPONSE;
1369         info->req_opcode = opcode;
1370         info->result_code = ret;
1371         info->resp_param = NULL;
1372         return BLUETOOTH_ERROR_NONE;
1373 }
1374
1375 int _bt_otp_uuid_convert_string_to_hex(char *uuid, char *value)
1376 {
1377         int len, uuid_len;
1378         uint32_t data0, data4;
1379         uint16_t data1, data2, data3, data5;
1380
1381         if (!uuid) {
1382                 BT_ERR("Object Type UUID NULL");
1383                 return 0;
1384         }
1385
1386         len = strlen(uuid);
1387
1388         switch (len) {
1389         case 4:
1390                 /* UUID 16bits */
1391                 sscanf(uuid, "%04hx", &data1);
1392                 data1 = htons(data1);
1393                 memcpy(value, &data1, 2);
1394                 uuid_len = 2;
1395                 break;
1396
1397         case 8:
1398                 /* UUID 32bits */
1399                 sscanf(uuid, "%08x", &data0);
1400                 data0 = htonl(data0);
1401                 memcpy(value, &data0, 4);
1402                 uuid_len = 4;
1403                 break;
1404
1405         case 36:
1406                 /* UUID 128bits */
1407                 sscanf(uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
1408                         &data0, &data1, &data2,
1409                         &data3, &data4, &data5);
1410
1411                 data0 = htonl(data0);
1412                 data1 = htons(data1);
1413                 data2 = htons(data2);
1414                 data3 = htons(data3);
1415                 data4 = htonl(data4);
1416                 data5 = htons(data5);
1417
1418                 memcpy(value, &data0, 4);
1419                 memcpy(value+4, &data1, 2);
1420                 memcpy(value+6, &data2, 2);
1421                 memcpy(value+8, &data3, 2);
1422                 memcpy(value+10, &data4, 4);
1423                 memcpy(value+14, &data5, 2);
1424                 uuid_len = 16;
1425                 break;
1426
1427         default:
1428                 uuid_len = 0;
1429         }
1430
1431         return uuid_len;
1432 }
1433
1434 void convert_to_hex(struct object_metadata *object, char *metadata, char *value)
1435 {
1436         struct tm fc_tm;
1437
1438         BT_DBG("Metadata : %s", metadata);
1439
1440         memset(value, 0, 16);
1441
1442         if (!g_strcmp0(metadata, "size")) {
1443
1444                 value[3] = (object->curr_size >> 24) & 0xFF;
1445                 value[2] = (object->curr_size >> 16) & 0xFF;
1446                 value[1] = (object->curr_size >> 8) & 0xFF;
1447                 value[0] = object->curr_size & 0xFF;
1448
1449                 value[7] = (object->alloc_size >> 24) & 0xFF;
1450                 value[6] = (object->alloc_size >> 16) & 0xFF;
1451                 value[5] = (object->alloc_size >> 8) & 0xFF;
1452                 value[4] = object->alloc_size & 0xFF;
1453
1454         } else if (!g_strcmp0(metadata, "date")) {
1455
1456                 if (object->first_created) {
1457                         localtime_r(&(object->first_created), &fc_tm);
1458
1459                         value[1] = ((fc_tm.tm_year+1900) >> 8) & 0xFF;
1460                         value[0] = (fc_tm.tm_year+1900) & 0xFF;
1461                         value[2] = (fc_tm.tm_mon+1) & 0xFF;
1462                         value[3] = fc_tm.tm_mday & 0xFF;
1463                         value[4] = fc_tm.tm_hour & 0xFF;
1464                         value[5] = fc_tm.tm_min & 0xFF;
1465                         value[6] = fc_tm.tm_sec & 0xFF;
1466                 }
1467
1468         } else if (!g_strcmp0(metadata, "id")) {
1469
1470                 value[5] = (object->id >> 48) & 0xFF;
1471                 value[4] = (object->id >> 32) & 0xFF;
1472                 value[3] = (object->id >> 24) & 0xFF;
1473                 value[2] = (object->id >> 16) & 0xFF;
1474                 value[1] = (object->id >> 8) & 0xFF;
1475                 value[0] = object->id & 0xFF;
1476
1477         } else if (!g_strcmp0(metadata, "props")) {
1478                 value[3] = (object->props >> 24) & 0xFF;
1479                 value[2] = (object->props >> 16) & 0xFF;
1480                 value[1] = (object->props >> 8) & 0xFF;
1481                 value[0] = object->props & 0xFF;
1482         }
1483 }
1484
1485 void update_obj_metadata_charc_value(struct object_metadata *object)
1486 {
1487         /* Value can be of maximum 16 bytes */
1488         char value[16];
1489         int uuid_len;
1490
1491         if (!oacp_create) {
1492                 _bt_otp_set_char_value(otp_object_name_obj_path, object->name,
1493                                                                 strlen(object->name));
1494         }
1495
1496         uuid_len = _bt_otp_uuid_convert_string_to_hex(object->type, value);
1497         _bt_otp_set_char_value(otp_object_type_obj_path, value, uuid_len);
1498
1499         convert_to_hex(object, "size", value);
1500         _bt_otp_set_char_value(otp_object_size_obj_path, value, 8);
1501
1502         convert_to_hex(object, "date", value);
1503         _bt_otp_set_char_value(otp_object_first_created_obj_path, value, 7);
1504         _bt_otp_set_char_value(otp_object_last_modified_obj_path, value, 7);
1505
1506         /* Object ID is optonal for single object server */
1507         if (mutiple_obj_support) {
1508                 convert_to_hex(object, "id", value);
1509                 _bt_otp_set_char_value(otp_object_id_obj_path, value, 6);
1510         }
1511
1512         convert_to_hex(object, "props", value);
1513         _bt_otp_set_char_value(otp_object_prop_obj_path, value, 4);
1514 }
1515
1516 struct object_metadata *_bt_otp_client_find_object(GSList *list, uint64_t id, guint *index)
1517 {
1518         GSList *l;
1519         struct object_metadata *info;
1520
1521         for (l = list; l; l = g_slist_next(l)) {
1522                 (*index)++;
1523                 info = l->data;
1524
1525                 if (info && (info->id == id))
1526                         return info;
1527         }
1528         return NULL;
1529 }
1530
1531 int _bt_otp_olcp_write_cb(char *value, int len, int offset,
1532                                         struct indicate_info *info)
1533 {
1534         int ret = OLCP_SUCCESS;
1535         int opcode = value[0];
1536         struct object_metadata *object;
1537         uint64_t object_id;
1538         guint index = 0;
1539
1540         BT_INFO("OLCP Opcode 0x%d", opcode);
1541
1542         if (!otp_object_list) {
1543                 ret = OLCP_NO_OBJ;
1544                 goto fail;
1545         }
1546
1547         switch (opcode) {
1548         case OLCP_FIRST:
1549                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, 0);
1550                 if (!object) {
1551                         ret = OLCP_OUT_OF_BOUNDS;
1552                         goto fail;
1553                 }
1554                 update_obj_metadata_charc_value(object);
1555                 selected_object = object;
1556                 curr_obj_index = 0;
1557                 break;
1558         case OLCP_LAST:
1559                 len = g_slist_length(otp_object_list);
1560                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, len-1);
1561                 if (!object) {
1562                         ret = OLCP_OUT_OF_BOUNDS;
1563                         goto fail;
1564                 }
1565                 update_obj_metadata_charc_value(object);
1566                 selected_object = object;
1567                 curr_obj_index = len-1;
1568                 break;
1569         case OLCP_PREVIOUS:
1570                 if (curr_obj_index == 0) {
1571                         ret = OLCP_OUT_OF_BOUNDS;
1572                         goto fail;
1573                 }
1574                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index-1);
1575                 if (!object) {
1576                         ret = OLCP_OUT_OF_BOUNDS;
1577                         goto fail;
1578                 }
1579                 update_obj_metadata_charc_value(object);
1580                 selected_object = object;
1581                 curr_obj_index -= 1;
1582                 break;
1583         case OLCP_NEXT:
1584                 object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index+1);
1585                 if (!object) {
1586                         ret = OLCP_OUT_OF_BOUNDS;
1587                         goto fail;
1588                 }
1589                 update_obj_metadata_charc_value(object);
1590                 selected_object = object;
1591                 curr_obj_index += 1;
1592                 break;
1593         case OLCP_GOTO:
1594                 object_id = (uint64_t)(value[6] & 0xFF) << 40 |
1595                                 (uint64_t)(value[5] & 0xFF) << 32 |
1596                                 (uint64_t)(value[4] & 0xFF) << 24 |
1597                                 (uint64_t)(value[3] & 0xFF) << 16 |
1598                                 (uint64_t)(value[2] & 0xFF) << 8  |
1599                                 (uint64_t)(value[1] & 0xFF);
1600                 BT_INFO("Object ID [%llu]", (unsigned long long int)object_id);
1601                 if (selected_object && selected_object->id == object_id)
1602                         goto fail;
1603
1604                 object = _bt_otp_client_find_object(otp_object_list, object_id, &index);
1605                 if (!object) {
1606                         ret = OLCP_OJECT_ID_NOT_FOUND;
1607                         goto fail;
1608                 }
1609                 update_obj_metadata_charc_value(object);
1610                 selected_object = object;
1611                 curr_obj_index = index - 1;
1612                 break;
1613         case OLCP_ORDER:
1614         case OLCP_REQ_NO_OBJ:
1615         case OLCP_CLEAR_MARKING:
1616         default:
1617                 ret = OLCP_OPCODE_NOT_SUPPORTED;
1618                 break;
1619         }
1620 fail:
1621         info->resp_opcode = OLCP_RESPONSE;
1622         info->req_opcode = opcode;
1623         info->result_code = ret;
1624         info->resp_param = NULL;
1625         return BLUETOOTH_ERROR_NONE;
1626 }
1627
1628 int _bt_otp_obj_name_write_cb(char *value, int len)
1629 {
1630         struct object_metadata *object;
1631         char *filename;
1632         char new_abs_filepath[BT_FILE_PATH_MAX_LEN] = {0, };
1633         int ret = BLUETOOTH_ERROR_NONE;
1634         FILE *fp = NULL;
1635         char err_msg[256] = {0, };
1636
1637         object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index);
1638         if (!object)
1639                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1640
1641         filename = g_strndup(value, len);
1642         snprintf(new_abs_filepath, BT_FILE_PATH_MAX_LEN, "%s%s",
1643                         directory, filename);
1644         BT_DBG("file_path = [%s]", new_abs_filepath);
1645
1646         fp = fopen(new_abs_filepath, "r");
1647         /* fopen succeed means file already exists */
1648         if (fp) {
1649                 ret = BLUETOOTH_OTP_ERROR_OBJECT_NAME_EXISTS;
1650                 goto fail;
1651         }
1652
1653         if (oacp_create) {
1654                 struct stat st;
1655
1656                 fp = fopen(new_abs_filepath, "a");
1657                 if (!fp) {
1658                         cynara_strerror(errno, err_msg, sizeof(err_msg));
1659                         BT_ERR("fopen() failed : %s", err_msg);
1660                         ret = BLUETOOTH_ATT_ERROR_INTERNAL;
1661                         goto fail;
1662                 }
1663
1664                 if (stat(new_abs_filepath, &st) == -1) {
1665                         BT_INFO("stat failed: (%d)\n", errno);
1666                         ret = BLUETOOTH_ATT_ERROR_INTERNAL;
1667                         goto fail;
1668                 }
1669
1670                 object->name = g_strdup(filename);
1671                 object->first_created = st.st_ctime;
1672                 object->last_modified = st.st_ctime;
1673                 object->curr_size = (uint32_t) st.st_size;
1674                 oacp_create = FALSE;
1675         } else {
1676                 char old_abs_filepath[BT_FILE_PATH_MAX_LEN] = {0, };
1677                 snprintf(old_abs_filepath, BT_FILE_PATH_MAX_LEN, "%s%s",
1678                                 directory, object->name);
1679
1680                 if (rename(old_abs_filepath, new_abs_filepath)) {
1681                         ret = BLUETOOTH_ATT_ERROR_INTERNAL;
1682                         goto fail;
1683                 }
1684         }
1685
1686         memcpy(object->name, value, len);
1687         _bt_otp_set_char_value(otp_object_name_obj_path, value, len);
1688
1689 fail:
1690         if (oacp_create)
1691                 _bt_otp_restore_old_object();
1692
1693         if (oacp_create_timeout_id > 0)
1694                 g_source_remove(oacp_create_timeout_id);
1695
1696         if (fp)
1697                 fclose(fp);
1698
1699         g_free(filename);
1700         return ret;
1701 }
1702
1703 int _bt_otp_obj_first_created_write_cb(char *value, int len)
1704 {
1705         struct object_metadata *object;
1706         struct tm tm = {0};
1707         uint16_t year;
1708
1709         object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index);
1710         if (!object)
1711                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1712
1713         year = (uint16_t)(value[1] & 0xFF) << 8 |
1714                         (uint16_t)(value[0] & 0xFF);
1715         tm.tm_year = year-1900;
1716         tm.tm_mon = value[2] & 0xFF;
1717         tm.tm_mon = tm.tm_mon-1;
1718         tm.tm_mday = value[3] & 0xFF;
1719         tm.tm_hour = value[4] & 0xFF;
1720         tm.tm_min = value[5] & 0xFF;
1721         tm.tm_sec = value[6] & 0xFF;
1722
1723         object->first_created = mktime(&tm);
1724         _bt_otp_set_char_value(otp_object_first_created_obj_path, value, len);
1725
1726         return BLUETOOTH_ERROR_NONE;
1727 }
1728
1729 int _bt_otp_obj_last_modified_write_cb(char *value, int len)
1730 {
1731         struct object_metadata *object;
1732         struct tm tm = {0};
1733         uint16_t year;
1734
1735         object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index);
1736         if (!object)
1737                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1738
1739         year = (uint16_t)(value[1] & 0xFF) << 8 |
1740                         (uint16_t)(value[0] & 0xFF);
1741         tm.tm_year = year-1900;
1742         tm.tm_mon = value[2] & 0xFF;
1743         tm.tm_mon = tm.tm_mon-1;
1744         tm.tm_mday = value[3] & 0xFF;
1745         tm.tm_hour = value[4] & 0xFF;
1746         tm.tm_min = value[5] & 0xFF;
1747         tm.tm_sec = value[6] & 0xFF;
1748
1749         object->last_modified = mktime(&tm);
1750         _bt_otp_set_char_value(otp_object_last_modified_obj_path, value, len);
1751
1752         return BLUETOOTH_ERROR_NONE;
1753 }
1754
1755 int _bt_otp_obj_props_write_cb(char *value, int len)
1756 {
1757         struct object_metadata *object;
1758         uint32_t props;
1759
1760         /* Any attempt to write RFU bits is error */
1761         if (value[1] || value[2] || value[3])
1762                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1763
1764         object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index);
1765         if (!object)
1766                 return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED;
1767
1768         props = (uint32_t)(value[3] & 0xFF) << 24       |
1769                         (uint32_t)(value[2] & 0xFF) << 16       |
1770                         (uint32_t)(value[1] & 0xFF) << 8        |
1771                         (uint32_t)(value[0] & 0xFF);
1772
1773         object->props = props;
1774         _bt_otp_set_char_value(otp_object_prop_obj_path, value, len);
1775
1776         return BLUETOOTH_ERROR_NONE;
1777 }
1778
1779 static struct otp_char_info *otp_get_char_value(const char *path)
1780 {
1781         GSList *tmp = NULL;
1782
1783         for (tmp = otp_char_list; tmp != NULL; tmp = tmp->next) {
1784                 if (tmp->data) {
1785                         struct otp_char_info *char_info = tmp->data;
1786                         if (!g_strcmp0(char_info->char_path, path))
1787                                 return char_info;
1788                 }
1789         }
1790
1791         return NULL;
1792 }
1793
1794 int _bt_otp_read_cb(const char *obj_path, char **value, int *len, uint16_t offset)
1795 {
1796         struct otp_char_info *info = NULL;
1797
1798         if (!obj_path) {
1799                 BT_ERR("Wrong Obj path");
1800                 return BLUETOOTH_ATT_ERROR_INTERNAL;
1801         }
1802
1803         if (g_strcmp0(obj_path, otp_feature_obj_path)) {
1804                 if (!selected_object)
1805                         return BLUETOOTH_OTP_ERROR_OBJECT_NOT_SELECTED;
1806         }
1807
1808         info = otp_get_char_value(obj_path);
1809         if (info) {
1810                 if (oacp_create && !g_strcmp0(obj_path, otp_object_name_obj_path)) {
1811                         /* char_value is NULL, value_length is zero */
1812                         *value = NULL;
1813                         *len = 0;
1814                         return BLUETOOTH_ATT_ERROR_NONE;
1815                 }
1816
1817                 if (info->char_value == NULL || info->value_length == 0)
1818                         return BLUETOOTH_ATT_ERROR_INTERNAL;
1819
1820                 if (offset > info->value_length)
1821                         return BLUETOOTH_ATT_ERROR_INVALID_OFFSET;
1822
1823                 *len = info->value_length - offset;
1824                 *value = (char *)malloc(sizeof(char)*(*len));
1825                 if (*value == NULL)
1826                         return BLUETOOTH_ATT_ERROR_INTERNAL;
1827
1828                 memcpy(*value, info->char_value, *len);
1829
1830                 return BLUETOOTH_ATT_ERROR_NONE;
1831         } else {
1832                 return BLUETOOTH_ATT_ERROR_INTERNAL;
1833         }
1834 }
1835
1836 static void _otp_convert_address_to_hex(bluetooth_device_address_t *addr_hex,
1837                                                         const char *addr_str)
1838 {
1839         int i = 0;
1840         unsigned int addr[BLUETOOTH_ADDRESS_LENGTH] = { 0, };
1841
1842         if (addr_str == NULL || addr_str[0] == '\0')
1843                 return;
1844
1845         i = sscanf(addr_str, "%X:%X:%X:%X:%X:%X", &addr[0], &addr[1],
1846                                 &addr[2], &addr[3], &addr[4], &addr[5]);
1847         if (i != BLUETOOTH_ADDRESS_LENGTH)
1848                 BT_ERR("Invalid format string - [%s]", addr_str);
1849
1850         for (i = 0; i < BLUETOOTH_ADDRESS_LENGTH; i++)
1851                 addr_hex->addr[i] = (unsigned char)addr[i];
1852 }
1853
1854 static void _bt_otp_send_indication(const char *obj_path,
1855                                 struct indicate_info *info,
1856                                 bluetooth_device_address_t *remote_address)
1857 {
1858         int ret = BLUETOOTH_ERROR_NONE;
1859         char value[7] = {0x00};
1860         int length = OTP_INDICATION_LEN_WITHOUT_RESP;
1861
1862         BT_DBG("");
1863
1864         value[0] = info->resp_opcode & 0xFF;
1865         value[1] = info->req_opcode & 0xFF;
1866         value[2] = info->result_code & 0xFF;
1867         if (info->resp_param) {
1868                 value[6] = info->resp_param[3] & 0xFF;
1869                 value[5] = info->resp_param[4] & 0xFF;
1870                 value[4] = info->resp_param[5] & 0xFF;
1871                 value[3] = info->resp_param[6] & 0xFF;
1872                 length = OTP_INDICATION_LEN_WITH_RESP;
1873         }
1874
1875         BT_DBG("Opcode: %d", value[1]);
1876
1877         /* Store the status value */
1878         _bt_otp_set_char_value(obj_path, value, length);
1879
1880         /* Send indication */
1881         ret = bluetooth_gatt_server_set_notification(obj_path, remote_address);
1882         if (ret != BLUETOOTH_ERROR_NONE) {
1883                 BT_ERR("_bt_otp_send_control_point_indication failed");
1884                 return;
1885         }
1886         ret = bluetooth_gatt_update_characteristic(obj_path, value, length);
1887         if (ret != BLUETOOTH_ERROR_NONE) {
1888                 BT_ERR("_bt_otp_send_control_point_indication failed");
1889                 return;
1890         }
1891 }
1892
1893 void _bt_otp_gatt_char_property_changed_event(GVariant *msg,
1894                                 const char *path)
1895 {
1896         int result = BLUETOOTH_ERROR_NONE;
1897         GVariantIter value_iter;
1898         const char *property = NULL;
1899         const char *char_path = NULL;
1900         const char *svc_handle = NULL;
1901         GVariant *var = NULL;
1902         GVariant *val = NULL;
1903         g_variant_iter_init(&value_iter, msg);
1904
1905         while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &var))) {
1906
1907                 if (property == NULL) {
1908                         BT_ERR("Property NULL");
1909                         return;
1910                 }
1911
1912                 if (!g_strcmp0(property, "WriteValue")) {
1913                         int len = 0;
1914                         BT_INFO("WriteValue");
1915                         BT_INFO("Type '%s'\n", g_variant_get_type_string(var));
1916
1917                         if (var) {
1918                                 bluetooth_device_address_t addr_hex = { {0,} };
1919                                 gchar *addr = NULL;
1920                                 guint8 req_id = 1;
1921                                 guint16 offset = 0;
1922                                 char *value = NULL;
1923                                 struct indicate_info info;
1924
1925                                 g_variant_get(var, "(&s&s&syq@ay)",
1926                                                 &char_path, &svc_handle,
1927                                                 &addr, &req_id, &offset, &val);
1928
1929                                 len = g_variant_get_size(val);
1930
1931                                 BT_DBG("Len = %d, BT_ADDR = %s", len, addr);
1932
1933                                 value = (char *) g_variant_get_data(val);
1934                                 _otp_convert_address_to_hex(&addr_hex, addr);
1935
1936                                 if (len != 0) {
1937                                         if (!g_strcmp0(char_path, otp_oacp_obj_path)) {
1938                                                 if (!OACP_indicate)
1939                                                         result = BLUETOOTH_ATT_ERROR_CCCD_IMPROPERLY_CONFIGURED;
1940                                                 else
1941                                                         result = _bt_otp_oacp_write_cb(value, len, offset, addr, &info);
1942                                         } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) {
1943                                                 if (!OLCP_indicate)
1944                                                         result = BLUETOOTH_ATT_ERROR_CCCD_IMPROPERLY_CONFIGURED;
1945                                                 else
1946                                                         result = _bt_otp_olcp_write_cb(value, len, offset, &info);
1947                                         } else if (!g_strcmp0(char_path, otp_object_name_obj_path)) {
1948                                                 result = _bt_otp_obj_name_write_cb(value, len);
1949                                         } else if (!g_strcmp0(char_path, otp_object_first_created_obj_path)) {
1950                                                 result = _bt_otp_obj_first_created_write_cb(value, len);
1951                                         } else if (!g_strcmp0(char_path, otp_object_last_modified_obj_path)) {
1952                                                 result = _bt_otp_obj_last_modified_write_cb(value, len);
1953                                         } else if (!g_strcmp0(char_path, otp_object_prop_obj_path)) {
1954                                                 result = _bt_otp_obj_props_write_cb(value, len);
1955                                         } else {
1956                                                 BT_ERR("Wrong Object Path %s", char_path);
1957                                                 result = BLUETOOTH_ERROR_INTERNAL;
1958                                         }
1959                                         bluetooth_gatt_send_response(req_id,
1960                                         BLUETOOTH_GATT_ATT_REQUEST_TYPE_WRITE,
1961                                                         result, 0, NULL, 0);
1962
1963                                         /* Send indication for CPs */
1964                                         if (!g_strcmp0(char_path, otp_oacp_obj_path)) {
1965                                                 if (OACP_indicate)
1966                                                         _bt_otp_send_indication(char_path, &info, &addr_hex);
1967                                         } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) {
1968                                                 if (OLCP_indicate)
1969                                                         _bt_otp_send_indication(char_path, &info, &addr_hex);
1970                                         }
1971                                 } else {
1972                                         BT_ERR("Array Len 0");
1973                                 }
1974                                 g_variant_unref(val);
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         g_variant_unref(val);
2137 }
2138
2139 int _bt_otp_init_event_receiver()
2140 {
2141         BT_DBG("+");
2142         GError *error = NULL;
2143
2144         if (conn == NULL) {
2145                 conn =  g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
2146                 if (error != NULL) {
2147                         BT_ERR("ERROR: Can't get on system bus [%s]",
2148                                                         error->message);
2149                         g_clear_error(&error);
2150                 }
2151         }
2152
2153         property_sub_id = g_dbus_connection_signal_subscribe(conn,
2154                                 NULL,
2155                                 BT_OTP_INTERFACE_NAME,
2156                                 PROPERTIES_CHANGED,
2157                                 BT_OTP_OBJECT_PATH, NULL, 0,
2158                                 _bt_otp_property_event_filter,
2159                                 NULL, NULL);
2160
2161         adapter_sub_id = g_dbus_connection_signal_subscribe(conn,
2162                                 NULL,
2163                                 BT_OTP_INTERFACE_NAME,
2164                                 BLE_DISABLED,
2165                                 BT_OTP_OBJECT_PATH, NULL, 0,
2166                                 _bt_otp_adapter_event_filter,
2167                                 NULL, NULL);
2168
2169         device_sub_id = g_dbus_connection_signal_subscribe(conn,
2170                                         NULL, BT_DEVICE_INTERFACE,
2171                                         OTC_DISCONNECTED, NULL, NULL, 0,
2172                                         _bt_otc_disconnected_cb,
2173                                         NULL, NULL);
2174
2175         device_property_sub_id = g_dbus_connection_signal_subscribe(conn,
2176                                 BT_BLUEZ_NAME, BT_PROPERTIES_INTERFACE,
2177                                 PROPERTIES_CHANGED, NULL, NULL, 0,
2178                                 _bt_otp_device_property_event_filter,
2179                                 NULL, NULL);
2180
2181         BT_DBG("-");
2182         return 0;
2183 }
2184
2185 void _bt_otp_deinit_event_receiver(void)
2186 {
2187         BT_DBG("+");
2188
2189         g_dbus_connection_signal_unsubscribe(conn, property_sub_id);
2190         g_dbus_connection_signal_unsubscribe(conn, adapter_sub_id);
2191         g_dbus_connection_signal_unsubscribe(conn, device_sub_id);
2192         g_dbus_connection_signal_unsubscribe(conn, device_property_sub_id);
2193         conn = NULL;
2194
2195         BT_DBG("-");
2196 }
2197
2198 static void _bt_otp_sig_handler(int sig)
2199 {
2200         BT_DBG("+");
2201         switch (sig) {
2202         case SIGTERM:
2203                 BT_DBG("caught signal - sigterm\n");
2204                 break;
2205         case SIGINT:
2206                 BT_DBG("caught signal - sigint\n");
2207                 break;
2208         case SIGKILL:
2209                 BT_DBG("caught signal - sigkill\n");
2210                 break;
2211         default:
2212                 BT_DBG("caught signal %d and ignored\n", sig);
2213                 break;
2214         }
2215         BT_DBG("-");
2216 }
2217
2218 /* OTP Service Main loop */
2219 int main(void)
2220 {
2221         struct sigaction sa;
2222         BT_ERR("Starting the bt-otp daemon");
2223
2224         memset(&sa, 0, sizeof(sa));
2225         sa.sa_handler = _bt_otp_sig_handler;
2226         sa.sa_flags = SA_SIGINFO;
2227         sigaction(SIGINT, &sa, NULL);
2228         sigaction(SIGTERM, &sa, NULL);
2229         sigaction(SIGKILL, &sa, NULL);
2230
2231         if (_bt_otp_register_interface() != BLUETOOTH_ERROR_NONE) {
2232                 BT_ERR("Fail to register otp service");
2233                 return -4;
2234         }
2235
2236         if (_bt_otp_init_event_receiver() != BLUETOOTH_ERROR_NONE) {
2237                 BT_ERR("Fail to init event reciever");
2238                 return -5;
2239         }
2240
2241         main_loop = g_main_loop_new(NULL, FALSE);
2242
2243         g_main_loop_run(main_loop);
2244
2245         BT_DBG("g_main_loop_quit called!");
2246
2247         if (main_loop != NULL)
2248                 g_main_loop_unref(main_loop);
2249
2250         return 0;
2251 }