From 1a55a3b7e4e261161999a7598528899770014e38 Mon Sep 17 00:00:00 2001 From: Gowtham Anandha Babu Date: Tue, 1 Aug 2017 12:54:40 +0530 Subject: [PATCH] [OTP] Add Object Changed Characteristics implementation Refactor OTP Client code. Change-Id: Iabdd5a4bee810a936b74f582404a3d1ce56c7faf Signed-off-by: Gowtham Anandha Babu --- src/bluetooth-otp.c | 379 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 270 insertions(+), 109 deletions(-) diff --git a/src/bluetooth-otp.c b/src/bluetooth-otp.c index 31c9bf9..dd67571 100644 --- a/src/bluetooth-otp.c +++ b/src/bluetooth-otp.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "bluetooth.h" @@ -140,6 +141,12 @@ #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); -- 2.7.4