[OTP] Add Object Changed Characteristics implementation 33/141633/1
authorGowtham Anandha Babu <gowtham.ab@samsung.com>
Tue, 1 Aug 2017 07:24:40 +0000 (12:54 +0530)
committerGowtham Anandha Babu <gowtham.ab@samsung.com>
Tue, 1 Aug 2017 07:24:40 +0000 (12:54 +0530)
Refactor OTP Client code.

Change-Id: Iabdd5a4bee810a936b74f582404a3d1ce56c7faf
Signed-off-by: Gowtham Anandha Babu <gowtham.ab@samsung.com>
src/bluetooth-otp.c

index 31c9bf9..dd67571 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdbool.h>
 #include <string.h>
 #include <sys/stat.h>
+#include <arpa/inet.h>
 #include <bluetooth-api.h>
 
 #include "bluetooth.h"
 #define BT_OTP_IS_EXECUTE_PERMITTED(props)     props & OBJECT_EXECUTE
 #define BT_OTP_IS_DELETE_PERMITTED(props)      props & OBJECT_DELETE
 
+#define BT_OTP_OBJ_CHANGED_SRC(flag)           (flag & 0x01)
+#define BT_OTP_OBJ_CHANGED_CONTENT(flag)       ((flag & 0x02) >> 1)
+#define BT_OTP_OBJ_CHANGED_META(flag)          ((flag & 0x04) >> 2)
+#define BT_OTP_OBJ_CHANGED_CREATE(flag)        ((flag & 0x08) >> 3)
+#define BT_OTP_OBJ_CHANGED_DELETE(flag)        ((flag & 0x10) >> 4)
+
 /* OTP Object Type Custom UUIDs */
 /* In SIG Assigned numbers not available */
 #define UNSUPPORTED_OBJECT_TYPE_UUID   "7fb0"
@@ -194,9 +201,12 @@ typedef struct {
        char *otp_props_obj_path;               /* OTP Object Properties characteristic handle */
 
        char *otp_list_filter_obj_path; /* OTP Object List Filter handle */
+       char *otp_obj_changed_obj_path;         /* OTP Object Changed handle */
+       char *otp_obj_changed_cccd;             /* OTP Object Changed CCCD handle */
 
        bool oacp_cccd_enabled;                 /* OTP OACP Control Point CCCD is enabled or not */
        bool olcp_cccd_enabled;                 /* OTP OLCP Control Point CCCD is enabled or not */
+       bool obj_changed_cccd_enabed;   /* OTP Object Changed CCCD is enabled or not */
        bool multiple_obj_supp;                 /* Indicates whether remote server supports
                                                 * multiple-objects or not
                                                 */
@@ -260,6 +270,8 @@ static void _bt_otp_client_send_execute_object_callback(int result,
                                        bt_otp_client_s *otp_client_s);
 static void _bt_otp_client_send_delete_object_callback(int result,
                                        bt_otp_client_s *otp_client_s);
+static void _bt_otp_send_callback(int result, char *file_path, uint64_t id,
+                       unsigned int length, bt_otp_client_s *otp_client_s);
 
 int __bt_check_otp_server_init_status(void)
 {
@@ -345,13 +357,38 @@ static bt_otp_client_s *_bt_otp_client_find(const char *remote_address)
        return NULL;
 }
 
-char *free_object_path(char *path)
+static char *free_object_path(char *path)
 {
-       if (path)
-               g_free(path);
+       g_free(path);
        return NULL;
 }
 
+static void _bt_otp_client_free_object_list(bt_otp_client_s *otp_client_s)
+{
+       GSList *tmp = NULL;
+       for (tmp = otp_client_s->object_list; tmp != NULL; tmp = tmp->next) {
+               if (tmp->data) {
+                       object_metadata *metadata_info = tmp->data;
+                       g_free(metadata_info->name);
+                       g_free(metadata_info->type);
+                       otp_client_s->object_list = g_slist_delete_link(otp_client_s->object_list, tmp->data);
+               }
+       }
+       g_slist_free(otp_client_s->object_list);
+       otp_client_s->object_list = NULL;
+}
+
+static void _bt_otp_client_init(bt_otp_client_s *otp_client_s)
+{
+       /* Reset CCCD */
+       otp_client_s->oacp_cccd_enabled = FALSE;
+       otp_client_s->olcp_cccd_enabled = FALSE;
+       otp_client_s->obj_changed_cccd_enabed = FALSE;
+
+       otp_client_s->curr_op = BT_OTP_NO_OPERATION;
+       otp_client_s->multiple_obj_supp = FALSE;
+}
+
 static void __bt_otp_client_reset_server_data(bt_otp_client_s *otp_client_s)
 {
        int k;
@@ -384,10 +421,10 @@ static void __bt_otp_client_reset_server_data(bt_otp_client_s *otp_client_s)
                        free_object_path(otp_client_s->otp_props_obj_path);
        otp_client_s->otp_list_filter_obj_path =
                        free_object_path(otp_client_s->otp_list_filter_obj_path);
-
-       /* Reset CCCD */
-       otp_client_s->oacp_cccd_enabled = FALSE;
-       otp_client_s->olcp_cccd_enabled = FALSE;
+       otp_client_s->otp_obj_changed_obj_path =
+                       free_object_path(otp_client_s->otp_obj_changed_obj_path);
+       otp_client_s->otp_obj_changed_cccd =
+                       free_object_path(otp_client_s->otp_obj_changed_cccd);
 
        /* Free GSList */
        if (obj_list) {
@@ -400,6 +437,9 @@ static void __bt_otp_client_reset_server_data(bt_otp_client_s *otp_client_s)
                obj_list = NULL;
        }
 
+       /* Free Object List */
+       _bt_otp_client_free_object_list(otp_client_s);
+
        if (oacp_read_op) {
                fclose(oacp_read_op->fp);
                g_free(oacp_read_op->file_path);
@@ -413,6 +453,8 @@ static void __bt_otp_client_reset_server_data(bt_otp_client_s *otp_client_s)
                g_free(oacp_create_op);
                oacp_create_op = NULL;
        }
+
+       _bt_otp_client_init(otp_client_s);
 }
 
 int bt_otp_client_set_connection_state_changed_cb(bt_otp_client_h otp_client,
@@ -613,10 +655,36 @@ static int __bt_update_otp_server_data(bluetooth_device_address_t *address, bt_o
                                otp_client_s->otp_list_filter_obj_path = g_strdup(characteristic.handle);
 
                                BT_DBG("OTP Object List Filter handle [%s]", otp_client_s->otp_list_filter_obj_path);
+                       }  else if (g_strstr_len(characteristic.uuid, -1, BT_OTP_OBJECT_CHANGED_UUID)) {
+                               BT_DBG("OTP Object Changed characteristic discovered");
+                               bt_gatt_char_descriptor_property_t desc_property;
+                               memset(&desc_property, 0x00, sizeof(desc_property));
+
+                               /* Get CCCD for Object Changed Charc */
+                               ret = bluetooth_gatt_get_char_descriptor_property(
+                                               characteristic.char_desc_handle.handle[0], &desc_property);
+
+                               if (ret != BLUETOOTH_ERROR_NONE) {
+                                       BT_ERR("Failed to discover CCCD for Object Changed Charc");
+                                       bluetooth_gatt_free_service_property(&service);
+                                       bluetooth_gatt_free_char_property(&characteristic);
+                                       bluetooth_gatt_free_desc_property(&desc_property);
+                                       goto fail;
+                               }
+                               if (otp_client_s->otp_obj_changed_obj_path)
+                                       g_free(otp_client_s->otp_obj_changed_obj_path);
+                               otp_client_s->otp_obj_changed_obj_path = g_strdup(characteristic.handle);
+
+                               if (otp_client_s->otp_obj_changed_cccd)
+                                       g_free(otp_client_s->otp_obj_changed_cccd);
+                               otp_client_s->otp_obj_changed_cccd = g_strdup(desc_property.handle);
+
+                               BT_DBG("OTP Object Changed handle [%s]", otp_client_s->otp_obj_changed_obj_path);
+                               BT_DBG("OTP Object Changed CCCD handle [%s]", otp_client_s->otp_obj_changed_cccd);
                        }       else {
                                BT_DBG("Other OTP Characteristic handle [%s]", characteristic.handle);
                                BT_DBG("UUID [%s]", characteristic.uuid);
-                       } /* Control Point characteristic */
+                       }
                } /* Characteristic property get successful */
                bluetooth_gatt_free_char_property(&characteristic);
        } /* Next Charatceristic */
@@ -738,11 +806,7 @@ int bt_otp_client_create(const char *remote_address, bt_otp_client_h *otp_client
                return BT_ERROR_OUT_OF_MEMORY;
        }
 
-       otp_client_s->otp_olcp_control_point = NULL;
-       otp_client_s->olcp_cccd_enabled = FALSE;
-       otp_client_s->oacp_cccd_enabled = FALSE;
-       otp_client_s->curr_op = BT_OTP_NO_OPERATION;
-       otp_client_s->multiple_obj_supp = FALSE;
+       _bt_otp_client_init(otp_client_s);
 
        otp_client_list = g_slist_append(otp_client_list, otp_client_s);
        *otp_client = (bt_otp_client_h)otp_client_s;
@@ -896,7 +960,7 @@ void _bt_otp_client_read_value_response(int result, char *char_path,
 
        if (result != BLUETOOTH_ERROR_NONE) {
                BT_INFO("Read failed for [%s]", char_path);
-               goto read_fail;
+               goto done;
        }
 
        if (!g_strcmp0(otp_client_s->otp_feature_obj_path, char_path)) {
@@ -909,7 +973,7 @@ void _bt_otp_client_read_value_response(int result, char *char_path,
                                                                (uint64_t)(value[6] & 0xFF) << 8        |
                                                                (uint64_t)(value[7] & 0xFF);
                        otp_client_s->otp_feature = feature;
-                       BT_INFO("OTP Feature [%lld]", feature);
+                       BT_INFO("OTP Feature [%u]", feature);
 
                        if (BT_OTP_IS_OACP_SUPPORTED(otp_client_s->otp_feature)
                                                                && !otp_client_s->oacp_cccd_enabled
@@ -927,6 +991,13 @@ void _bt_otp_client_read_value_response(int result, char *char_path,
                                if (error_code != BT_ERROR_NONE)
                                        BT_ERR("OLCP Notification enable failed %s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
                        }
+
+                       if (!otp_client_s->obj_changed_cccd_enabed
+                                       && otp_client_s->otp_obj_changed_obj_path) {
+                               error_code = bluetooth_otp_enable_notification(otp_client_s->otp_obj_changed_obj_path);
+                               if (error_code != BT_ERROR_NONE)
+                                       BT_ERR("Object Changed Notification enable failed %s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+                       }
        } else {
                if (!g_strcmp0(otp_client_s->otp_name_obj_path, char_path)) {
                        char *name = NULL;
@@ -939,7 +1010,9 @@ void _bt_otp_client_read_value_response(int result, char *char_path,
                                if (error_code != BLUETOOTH_ERROR_NONE) {
                                        BT_INFO("Read Charc Value Failed %s(0x%08x)",
                                                        _bt_convert_error_to_string(error_code), error_code);
-                                       goto read_fail;
+                                       result = error_code;
+                                       g_free(name);
+                                       goto done;
                                }
                        }
                        g_free(name);
@@ -954,10 +1027,11 @@ void _bt_otp_client_read_value_response(int result, char *char_path,
                                if (error_code != BLUETOOTH_ERROR_NONE) {
                                        BT_INFO("Read Charc Value Failed %s(0x%08x)",
                                                        _bt_convert_error_to_string(error_code), error_code);
-                                       goto read_fail;
+                                       result = error_code;
+                                       g_free(type);
+                                       goto done;
                                }
                        }
-
                        g_free(type);
                } else if (!g_strcmp0(otp_client_s->otp_size_obj_path, char_path)) {
                        uint32_t csize, asize;
@@ -980,10 +1054,10 @@ void _bt_otp_client_read_value_response(int result, char *char_path,
                                if (error_code != BLUETOOTH_ERROR_NONE) {
                                        BT_INFO("Read Charc Value Failed %s(0x%08x)",
                                                        _bt_convert_error_to_string(error_code), error_code);
-                                       goto read_fail;
+                                       result = error_code;
+                                       goto done;
                                }
                        }
-
                } else if (!g_strcmp0(otp_client_s->otp_props_obj_path, char_path)) {
                        uint32_t props;
                        props = (uint32_t)(value[3] & 0xFF) << 24               |
@@ -1000,14 +1074,16 @@ void _bt_otp_client_read_value_response(int result, char *char_path,
                                        if (error_code != BLUETOOTH_ERROR_NONE) {
                                                BT_INFO("Read Charc Value Failed %s(0x%08x)",
                                                                _bt_convert_error_to_string(error_code), error_code);
-                                               goto read_fail;
+                                               result = error_code;
+                                               goto done;
                                        }
                                } else if (otp_client_s->otp_last_modified_obj_path) {
                                        error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_last_modified_obj_path);
                                        if (error_code != BLUETOOTH_ERROR_NONE) {
                                                BT_INFO("Read Charc Value Failed %s(0x%08x)",
                                                                        _bt_convert_error_to_string(error_code), error_code);
-                                               goto read_fail;
+                                               result = error_code;
+                                               goto done;
                                        }
                                } else {
                                        /* Reading Object ID characteristics makes sense if server
@@ -1017,15 +1093,15 @@ void _bt_otp_client_read_value_response(int result, char *char_path,
                                                metadata->id = 0x256;
                                                otp_client_s->object_id = metadata->id;
                                                otp_client_s->object_list = g_slist_append(otp_client_s->object_list, metadata);
-                                               _bt_otp_send_discovery_callback(BLUETOOTH_ERROR_NONE, otp_client_s);
-                                               __bt_otp_reset_api_info(otp_client_s);
+                                               goto done;
                                        } else {
                                                if (otp_client_s->otp_id_obj_path) {
                                                        error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_id_obj_path);
                                                        if (error_code != BLUETOOTH_ERROR_NONE) {
                                                                BT_INFO("Read Charc Value Failed %s(0x%08x)",
                                                                                _bt_convert_error_to_string(error_code), error_code);
-                                                               goto read_fail;
+                                                               result = error_code;
+                                                               goto done;
                                                        }
                                                }
                                        }
@@ -1052,22 +1128,23 @@ void _bt_otp_client_read_value_response(int result, char *char_path,
                                        if (error_code != BLUETOOTH_ERROR_NONE) {
                                                BT_INFO("Read Charc Value Failed %s(0x%08x)",
                                                                        _bt_convert_error_to_string(error_code), error_code);
-                                               goto read_fail;
+                                               result = error_code;
+                                               goto done;
                                        }
                                } else {
                                        if (otp_client_s->multiple_obj_supp) {
                                                metadata->id = 0x256;
                                                otp_client_s->object_id = metadata->id;
                                                otp_client_s->object_list = g_slist_append(otp_client_s->object_list, metadata);
-                                               _bt_otp_send_discovery_callback(BLUETOOTH_ERROR_NONE, otp_client_s);
-                                               __bt_otp_reset_api_info(otp_client_s);
+                                               goto done;
                                        } else {
                                                if (otp_client_s->otp_id_obj_path) {
                                                        error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_id_obj_path);
                                                        if (error_code != BLUETOOTH_ERROR_NONE) {
                                                                BT_INFO("Read Charc Value Failed %s(0x%08x)",
                                                                                        _bt_convert_error_to_string(error_code), error_code);
-                                                               goto read_fail;
+                                                               result = error_code;
+                                                               goto done;
                                                        }
                                                }
                                        }
@@ -1094,15 +1171,15 @@ void _bt_otp_client_read_value_response(int result, char *char_path,
                                        metadata->id = 0x256;
                                        otp_client_s->object_id = metadata->id;
                                        otp_client_s->object_list = g_slist_append(otp_client_s->object_list, metadata);
-                                       _bt_otp_send_discovery_callback(BLUETOOTH_ERROR_NONE, otp_client_s);
-                                       __bt_otp_reset_api_info(otp_client_s);
+                                       goto done;
                                } else {
                                        if (otp_client_s->otp_id_obj_path) {
                                                error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_id_obj_path);
                                                if (error_code != BLUETOOTH_ERROR_NONE) {
                                                        BT_INFO("Read Charc Value Failed %s(0x%08x)",
                                                                                _bt_convert_error_to_string(error_code), error_code);
-                                                       goto read_fail;
+                                                       result = error_code;
+                                                       goto done;
                                                }
                                        }
                                }
@@ -1127,7 +1204,8 @@ void _bt_otp_client_read_value_response(int result, char *char_path,
                                error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_olcp_control_point, value, 1);
                                if (error_code != BT_ERROR_NONE) {
                                        BT_ERR("Failed to write control point : %s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
-                                       goto read_fail;
+                                       result = error_code;
+                                       goto done;
                                }
                        } else if (otp_client_s->curr_op == BT_OTP_OBJECT_CREATE) {
                                metadata = g_malloc0(sizeof(object_metadata));
@@ -1142,26 +1220,57 @@ void _bt_otp_client_read_value_response(int result, char *char_path,
                                metadata->id = id;
                                otp_client_s->object_id = metadata->id;
                                otp_client_s->object_list = g_slist_append(otp_client_s->object_list, metadata);
+                               goto done;
                        }
                }
-read_fail:
-               if (otp_client_s->curr_op == BT_OTP_OBJECT_DISCOVERY) {
-                       if (result != BLUETOOTH_ERROR_NONE) {
-                               _bt_otp_send_discovery_callback(result, otp_client_s);
-                               __bt_otp_reset_api_info(otp_client_s);
-                       } else if (error_code != BLUETOOTH_ERROR_NONE) {
-                               _bt_otp_send_discovery_callback(error_code, otp_client_s);
-                               __bt_otp_reset_api_info(otp_client_s);
-                       }
-               }
-               if (otp_client_s->curr_op == BT_OTP_OBJECT_CREATE) {
-                       _bt_otp_client_send_create_object_callback(result,
-                                       otp_client_s->object_id, otp_client_s);
-                       __bt_otp_reset_api_info(otp_client_s);
+               return;
+done:
+               switch (otp_client_s->curr_op) {
+               case BT_OTP_OBJECT_DISCOVERY:
+               case BT_OTP_OBJECT_CREATE:
+                       _bt_otp_send_callback(result, NULL, otp_client_s->object_id, 0, otp_client_s);
+                       break;
+               default:
+                       break;
                }
        }
 }
 
+static void _bt_otp_send_callback(int result, char *file_path, uint64_t id,
+                       unsigned int length, bt_otp_client_s *otp_client_s)
+{
+       switch (otp_client_s->curr_op) {
+       case BT_OTP_OBJECT_DISCOVERY:
+               _bt_otp_send_discovery_callback(result, otp_client_s);
+               break;
+       case BT_OTP_OBJECT_READ:
+               _bt_otp_client_notify_read_object_status(result,
+                                                       file_path, otp_client_s);
+               break;
+       case BT_OTP_OBJECT_SELECT:
+               _bt_otp_client_send_select_object_callback(result, otp_client_s);
+               break;
+       case BT_OTP_OBJECT_CREATE:
+               _bt_otp_client_send_create_object_callback(result, id, otp_client_s);
+               break;
+       case BT_OTP_OBJECT_WRITE:
+               _bt_otp_client_send_write_object_callback(result, length, otp_client_s);
+               break;
+       case BT_OTP_OBJECT_EXECUTE:
+               _bt_otp_client_send_execute_object_callback(result, otp_client_s);
+               break;
+       case BT_OTP_OBJECT_DELETE:
+               _bt_otp_client_send_delete_object_callback(result, otp_client_s);
+               break;
+       case BT_OTP_NO_OPERATION:
+               break;
+       default:
+               break;
+       }
+
+       __bt_otp_reset_api_info(otp_client_s);
+}
+
 void _bt_otp_client_write_value_response(int result, char *handle)
 {
        bt_otp_client_s *otp_client_s = NULL;
@@ -1227,39 +1336,7 @@ void _bt_otp_client_write_value_response(int result, char *handle)
        }
        return;
 fail:
-       switch (otp_client_s->curr_op) {
-       case BT_OTP_OBJECT_DISCOVERY:
-               _bt_otp_send_discovery_callback(result, otp_client_s);
-               __bt_otp_reset_api_info(otp_client_s);
-               break;
-       case BT_OTP_OBJECT_READ:
-               _bt_otp_client_notify_read_object_status(result,
-                                                       NULL, otp_client_s);
-               __bt_otp_reset_api_info(otp_client_s);
-               break;
-       case BT_OTP_OBJECT_SELECT:
-               _bt_otp_client_send_select_object_callback(result, otp_client_s);
-               __bt_otp_reset_api_info(otp_client_s);
-               break;
-       case BT_OTP_OBJECT_CREATE:
-               _bt_otp_client_send_create_object_callback(result, 0, otp_client_s);
-               __bt_otp_reset_api_info(otp_client_s);
-               break;
-       case BT_OTP_OBJECT_WRITE:
-               _bt_otp_client_send_write_object_callback(result, 0, otp_client_s);
-               __bt_otp_reset_api_info(otp_client_s);
-               break;
-       case BT_OTP_OBJECT_EXECUTE:
-               _bt_otp_client_send_execute_object_callback(result, otp_client_s);
-               __bt_otp_reset_api_info(otp_client_s);
-               break;
-       case BT_OTP_OBJECT_DELETE:
-               _bt_otp_client_send_delete_object_callback(result, otp_client_s);
-               __bt_otp_reset_api_info(otp_client_s);
-               break;
-       case BT_OTP_NO_OPERATION:
-               break;
-       }
+       _bt_otp_send_callback(result, NULL, 0, 0, otp_client_s);
 }
 
 void _bt_otp_client_notification_enabled(int result, char *handle)
@@ -1291,6 +1368,14 @@ void _bt_otp_client_notification_enabled(int result, char *handle)
                } else {
                        otp_client_s->olcp_cccd_enabled = TRUE;
                }
+       } else if (!g_strcmp0(otp_client_s->otp_obj_changed_obj_path, handle)) {
+               if (result != BLUETOOTH_ERROR_NONE) {
+                       otp_client_s->obj_changed_cccd_enabed = FALSE;
+                       BT_ERR("Failed to enable Object changed notification : %s(0x%08x)",
+                                       _bt_convert_error_to_string(result), result);
+               } else {
+                       otp_client_s->obj_changed_cccd_enabed = TRUE;
+               }
        }
 }
 
@@ -1387,21 +1472,16 @@ void _bt_otp_client_indication(int result, bluetooth_otp_resp_info_t *info)
                }
                return;
 oacp_done:
-               if (otp_client_s->curr_op == BT_OTP_OBJECT_READ) {
-                       _bt_otp_client_notify_read_object_status(result, NULL, otp_client_s);
-                       __bt_otp_reset_api_info(otp_client_s);
-               } else  if (otp_client_s->curr_op == BT_OTP_OBJECT_CREATE) {
-                       _bt_otp_client_send_create_object_callback(result, 0, otp_client_s);
-                       __bt_otp_reset_api_info(otp_client_s);
-               } else  if (otp_client_s->curr_op == BT_OTP_OBJECT_WRITE) {
-                       _bt_otp_client_send_write_object_callback(result, 0, otp_client_s);
-                       __bt_otp_reset_api_info(otp_client_s);
-               } else if (otp_client_s->curr_op == BT_OTP_OBJECT_EXECUTE) {
-                       _bt_otp_client_send_execute_object_callback(result, otp_client_s);
-                       __bt_otp_reset_api_info(otp_client_s);
-               } else if (otp_client_s->curr_op == BT_OTP_OBJECT_DELETE) {
-                       _bt_otp_client_send_delete_object_callback(result, otp_client_s);
-                       __bt_otp_reset_api_info(otp_client_s);
+               switch (otp_client_s->curr_op) {
+               case BT_OTP_OBJECT_READ:
+               case BT_OTP_OBJECT_CREATE:
+               case BT_OTP_OBJECT_WRITE:
+               case BT_OTP_OBJECT_EXECUTE:
+               case BT_OTP_OBJECT_DELETE:
+                       _bt_otp_send_callback(result, NULL, 0, 0, otp_client_s);
+                       break;
+               default:
+                       break;
                }
        } else if (!g_strcmp0(otp_client_s->otp_olcp_control_point, info->handle)) {
                uint8_t resp_code = info->data[0];
@@ -1477,13 +1557,31 @@ oacp_done:
                }
                return;
 olcp_done:
-               if (otp_client_s->curr_op == BT_OTP_OBJECT_DISCOVERY) {
-                       _bt_otp_send_discovery_callback(result, otp_client_s);
-                       __bt_otp_reset_api_info(otp_client_s);
-               } else if (otp_client_s->curr_op == BT_OTP_OBJECT_SELECT) {
-                       _bt_otp_client_send_select_object_callback(result, otp_client_s);
-                       __bt_otp_reset_api_info(otp_client_s);
+               switch (otp_client_s->curr_op) {
+               case BT_OTP_OBJECT_DISCOVERY:
+               case BT_OTP_OBJECT_SELECT:
+                       _bt_otp_send_callback(result, NULL, 0, 0, otp_client_s);
+                       break;
+               default:
+                       break;
                }
+       } else if (!g_strcmp0(otp_client_s->otp_obj_changed_obj_path, info->handle)) {
+               BT_INFO("Indication Received for Object Changed Characteristic");
+               uint8_t flag = info->data[0];
+               uint64_t id = 0;
+               BT_INFO("Source of change : %s", BT_OTP_OBJ_CHANGED_SRC(flag) ? "Client" : "Server");
+               BT_INFO("Change occurred to obj contents : %s", BT_OTP_OBJ_CHANGED_CONTENT(flag) ? "True" : "False");
+               BT_INFO("Change occurred to obj metadata : %s", BT_OTP_OBJ_CHANGED_META(flag) ? "True" : "False");
+               BT_INFO("Object creation : %s", BT_OTP_OBJ_CHANGED_CREATE(flag) ? "True" : "False");
+               BT_INFO("Object Deletion : %s", BT_OTP_OBJ_CHANGED_DELETE(flag) ? "True" : "False");
+
+               id = (uint64_t)(info->data[6] & 0xFF) << 40 |
+                               (uint64_t)(info->data[5] & 0xFF) << 32 |
+                               (uint64_t)(info->data[4] & 0xFF) << 24 |
+                               (uint64_t)(info->data[3] & 0xFF) << 16 |
+                               (uint64_t)(info->data[2] & 0xFF) << 8  |
+                               (uint64_t)(info->data[1] & 0xFF);
+               BT_INFO("Changed occurred to object id %u", id);
        }
 }
 
@@ -1524,6 +1622,8 @@ int bt_otp_client_discover_all_objects(bt_otp_client_h otp_client,
        otp_client_s->callback = callback;
        otp_client_s->user_data = user_data;
 
+       _bt_otp_client_free_object_list(otp_client_s);
+
        if (!otp_client_s->otp_olcp_control_point) {
                /* Remote server supports only single object */
                otp_client_s->multiple_obj_supp = TRUE;
@@ -2013,6 +2113,65 @@ static void _bt_otp_client_send_create_object_callback(int result,
        }
 }
 
+int _bt_otp_uuid_convert_string_to_hex(char *uuid, char *value)
+{
+       int len, uuid_len;
+       uint32_t data0, data4;
+       uint16_t data1, data2, data3, data5;
+
+       if (!uuid) {
+               BT_ERR("Object Type UUID NULL");
+               return 0;
+       }
+
+       len = strlen(uuid);
+
+       switch (len) {
+       case 4:
+               /* UUID 16bits */
+               sscanf(uuid, "%04hx", &data1);
+               data1 = htons(data1);
+               memcpy(value, &data1, 2);
+               uuid_len = 2;
+               break;
+
+       case 8:
+               /* UUID 32bits */
+               sscanf(uuid, "%08x", &data0);
+               data0 = htonl(data0);
+               memcpy(value, &data0, 4);
+               uuid_len = 4;
+               break;
+
+       case 36:
+               /* UUID 128bits */
+               sscanf(uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
+                       &data0, &data1, &data2,
+                       &data3, &data4, &data5);
+
+               data0 = htonl(data0);
+               data1 = htons(data1);
+               data2 = htons(data2);
+               data3 = htons(data3);
+               data4 = htonl(data4);
+               data5 = htons(data5);
+
+               memcpy(value, &data0, 4);
+               memcpy(value+4, &data1, 2);
+               memcpy(value+6, &data2, 2);
+               memcpy(value+8, &data3, 2);
+               memcpy(value+10, &data4, 4);
+               memcpy(value+14, &data5, 2);
+               uuid_len = 16;
+               break;
+
+       default:
+               uuid_len = 0;
+       }
+
+       return uuid_len;
+}
+
 int bt_otp_client_create_object(bt_otp_client_h otp_client,
                                        const char *file_path,
                                        bt_otp_client_object_create_cb callback,
@@ -2065,7 +2224,7 @@ int bt_otp_client_create_object(bt_otp_client_h otp_client,
        last_token = strrchr(file_path, '/');
        file_name = last_token + 1;
 
-       BT_INFO("Filepath [%s], Filename [%s], Size[%llu]\n",
+       BT_INFO("Filepath [%s], Filename [%s], Size[%u]\n",
                                        file_path, file_name, size);
 
        oacp_create_op = g_malloc0(sizeof(bt_otp_client_create_op));
@@ -2081,16 +2240,18 @@ int bt_otp_client_create_object(bt_otp_client_h otp_client,
 
        /* UUIDs can be 128/64/16 bits */
        uint8_t value[40] = {0x00};
-       value[0] = OACP_CREATE;
-       value[1] = size & 0xFF;
-       value[2] = (size >> 8) & 0xFF;
-       value[3] = (size >> 16) & 0xFF;
-       value[4] = (size >> 24) & 0xFF;
+       int len;
 
-       memcpy(value + 5, type_uuid, strlen(type_uuid));
+       value[0] = OACP_CREATE;
+       len = 1;
+       len += _bt_otp_uuid_convert_string_to_hex(type_uuid, (char *)value + 1);
+       value[++len] = size & 0xFF;
+       value[++len] = (size >> 8) & 0xFF;
+       value[++len] = (size >> 16) & 0xFF;
+       value[++len] = (size >> 24) & 0xFF;
 
        error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_oacp_control_point,
-                                                                       value, 5 + strlen(type_uuid));
+                                                                       value, len);
        if (error_code != BT_ERROR_NONE) {
                BT_ERR("Failed to write control point : %s(0x%08x)",
                        _bt_convert_error_to_string(error_code), error_code);