From 8bc29d968c7de4487e6baede51f4cd83f6942068 Mon Sep 17 00:00:00 2001 From: Gowtham Anandha Babu Date: Tue, 1 Aug 2017 12:53:45 +0530 Subject: [PATCH] [OTP] Fix OACP Create procedure Change-Id: Ifa72fc6e7cf23b8533587ed1cce38e5cefcf9f4e Signed-off-by: Gowtham Anandha Babu --- bt-otp/bt-otpserver.c | 168 +++++++++++++++++++++++++++----------------------- bt-otp/bt-otpserver.h | 1 - 2 files changed, 92 insertions(+), 77 deletions(-) diff --git a/bt-otp/bt-otpserver.c b/bt-otp/bt-otpserver.c index 761b6af..5095f87 100644 --- a/bt-otp/bt-otpserver.c +++ b/bt-otp/bt-otpserver.c @@ -118,6 +118,7 @@ struct oacp_operation *oacp_op = NULL; unsigned int timeout_id; unsigned int oacp_create_timeout_id; uint64_t curr_obj_id, prev_obj_id; +static gboolean oacp_create = FALSE; static const gchar otp_introspection_xml[] = "" @@ -142,7 +143,7 @@ void update_obj_metadata_charc_value(struct object_metadata *object); void _bt_convert_device_path_to_address(const char *device_path, char *device_address); int _bt_otp_open_otc_and_listen(char *address, char *method); -void _bt_otp_delete_empty_file(); +void _bt_otp_restore_old_object(); struct object_metadata *_bt_otp_client_find_object(GSList *list, uint64_t id, guint *index); @@ -511,7 +512,7 @@ void _bt_otp_start_write_on_fd() char file_path[BT_FILE_PATH_MAX_LEN] = {0, }; int length; - snprintf(file_path, sizeof(file_path), "%s%s", + snprintf(file_path, BT_FILE_PATH_MAX_LEN, "%s%s", directory, selected_object->name); BT_DBG("file_path = [%s]", file_path); @@ -615,7 +616,7 @@ static gboolean __server_data_received_cb(GIOChannel *chan, GIOCondition cond, goto fail; } - snprintf(file_path, sizeof(file_path), "%s%s", + snprintf(file_path, BT_FILE_PATH_MAX_LEN, "%s%s", directory, selected_object->name); BT_DBG("file_path = [%s]", file_path); @@ -715,7 +716,7 @@ static void _bt_otp_method(GDBusConnection *connection, for (l = list; l != NULL; l = l->next) { if (!l->data) continue; - snprintf(absolute_path, sizeof(absolute_path), "%s%s", directory, + snprintf(absolute_path, BT_FILE_PATH_MAX_LEN, "%s%s", directory, (char *)l->data); BT_INFO("filename: %s, absoulte_path: %s", @@ -1047,7 +1048,8 @@ fail: static bool __bt_oacp_create_timeout_cb(gpointer user_data) { /* Delete the EMPTY object */ - _bt_otp_delete_empty_file(); + oacp_create = FALSE; + _bt_otp_restore_old_object(); return TRUE; } @@ -1148,30 +1150,9 @@ char *_bt_otp_uuid_convert_hex_to_string(char *value, uint32_t length) return uuid; } -int _bt_otp_create_empty_file(uint32_t size, char *uuid) +void _bt_otp_create_new_object(uint32_t size, char *uuid) { - int ret = BLUETOOTH_ERROR_NONE; struct object_metadata *object = NULL; - struct stat st; - char absolute_file_path[BT_FILE_PATH_MAX_LEN] = {0, }; - FILE *fp = NULL; - - snprintf(absolute_file_path, sizeof(absolute_file_path), - "%s%s", directory, BT_OTP_EMPTY_FILENAME); - BT_DBG("file_path = [%s]", absolute_file_path); - - fp = fopen(absolute_file_path, "a"); - if (!fp) { - BT_DBG("fopen() failed : %s", strerror(errno)); - ret = BLUETOOTH_ERROR_INTERNAL; - goto fail; - } - - if (stat(absolute_file_path, &st) == -1) { - BT_INFO("stat failed: (%d)\n", errno); - ret = BLUETOOTH_ERROR_INTERNAL; - goto fail; - } /* Store current object id. * Incase of OACP Create fail, need to restore @@ -1181,14 +1162,15 @@ int _bt_otp_create_empty_file(uint32_t size, char *uuid) object = g_new0(struct object_metadata, 1); - object->name = g_strdup(BT_OTP_EMPTY_FILENAME); + object->name = NULL; object->type = g_strdup(uuid); - object->first_created = st.st_ctime; - object->last_modified = st.st_ctime; - object->curr_size = (uint32_t)st.st_size; + object->first_created = 0; + object->last_modified = 0; + object->curr_size = 0; object->alloc_size = size; object->id = object_id; - object->props = OBJECT_READ | OBJECT_WRITE; + object->props = OBJECT_READ | OBJECT_WRITE | + OBJECT_EXECUTE | OBJECT_DELETE; otp_object_list = g_slist_append(otp_object_list, object); @@ -1198,18 +1180,14 @@ int _bt_otp_create_empty_file(uint32_t size, char *uuid) curr_obj_index = g_slist_length(otp_object_list) - 1; curr_obj_id = selected_object->id; object_id++; -fail: - if (fp) - fclose(fp); + free(uuid); - return ret; } -void _bt_otp_delete_empty_file() +void _bt_otp_restore_old_object() { struct object_metadata *object = NULL; guint index = 0; - char absolute_file_path[BT_FILE_PATH_MAX_LEN] = {0, }; object = _bt_otp_client_find_object(otp_object_list, curr_obj_id, &index); if (!object) @@ -1217,13 +1195,6 @@ void _bt_otp_delete_empty_file() otp_object_list = g_slist_remove(otp_object_list, object); - snprintf(absolute_file_path, sizeof(absolute_file_path), - "%s%s", directory, object->name); - - if (remove(absolute_file_path) != 0) { - BT_DBG("Error: unable to delete the file"); - } - index = 0; object = _bt_otp_client_find_object(otp_object_list, prev_obj_id, &index); update_obj_metadata_charc_value(object); @@ -1272,12 +1243,8 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset, BT_INFO("Size = %u, UUID = %s", object_size, uuid); - err = _bt_otp_create_empty_file(object_size, uuid); - if (err != BLUETOOTH_ERROR_NONE) { - BT_ERR("Failed to create empty file"); - ret = OACP_OPERATION_FAILED; - goto fail; - } + oacp_create = TRUE; + _bt_otp_create_new_object(object_size, uuid); if (oacp_create_timeout_id > 0) g_source_remove(oacp_create_timeout_id); @@ -1289,7 +1256,7 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset, ret = OACP_PROCEDURE_NOT_SUPPORTED; goto fail; } - snprintf(absolute_file_path, sizeof(absolute_file_path), + snprintf(absolute_file_path, BT_FILE_PATH_MAX_LEN, "%s%s", directory, selected_object->name); BT_DBG("absolute_file_path = [%s]", absolute_file_path); @@ -1311,7 +1278,7 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset, ret = OACP_PROCEDURE_NOT_SUPPORTED; goto fail; } - snprintf(absolute_file_path, sizeof(absolute_file_path), + snprintf(absolute_file_path, BT_FILE_PATH_MAX_LEN, "file://%s%s", directory, selected_object->name); BT_DBG("absolute_file_path = [%s]", absolute_file_path); @@ -1474,15 +1441,17 @@ void convert_to_hex(struct object_metadata *object, char *metadata, char *value) } else if (!g_strcmp0(metadata, "date")) { - localtime_r(&(object->first_created), &fc_tm); + if (object->first_created) { + localtime_r(&(object->first_created), &fc_tm); - value[1] = ((fc_tm.tm_year+1900) >> 8) & 0xFF; - value[0] = (fc_tm.tm_year+1900) & 0xFF; - value[2] = (fc_tm.tm_mon+1) & 0xFF; - value[3] = fc_tm.tm_mday & 0xFF; - value[4] = fc_tm.tm_hour & 0xFF; - value[5] = fc_tm.tm_min & 0xFF; - value[6] = fc_tm.tm_sec & 0xFF; + value[1] = ((fc_tm.tm_year+1900) >> 8) & 0xFF; + value[0] = (fc_tm.tm_year+1900) & 0xFF; + value[2] = (fc_tm.tm_mon+1) & 0xFF; + value[3] = fc_tm.tm_mday & 0xFF; + value[4] = fc_tm.tm_hour & 0xFF; + value[5] = fc_tm.tm_min & 0xFF; + value[6] = fc_tm.tm_sec & 0xFF; + } } else if (!g_strcmp0(metadata, "id")) { @@ -1507,8 +1476,10 @@ void update_obj_metadata_charc_value(struct object_metadata *object) char value[16]; int uuid_len; - _bt_otp_set_char_value(otp_object_name_obj_path, object->name, - strlen(object->name)); + if (!oacp_create) { + _bt_otp_set_char_value(otp_object_name_obj_path, object->name, + strlen(object->name)); + } uuid_len = _bt_otp_uuid_convert_string_to_hex(object->type, value); _bt_otp_set_char_value(otp_object_type_obj_path, value, uuid_len); @@ -1647,32 +1618,70 @@ int _bt_otp_obj_name_write_cb(char *value, int len) struct object_metadata *object; char *filename; char new_abs_filepath[BT_FILE_PATH_MAX_LEN] = {0, }; - char old_abs_filepath[BT_FILE_PATH_MAX_LEN] = {0, }; int ret = BLUETOOTH_ERROR_NONE; + FILE *fp = NULL; object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index); if (!object) return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED; filename = g_strndup(value, len); - snprintf(new_abs_filepath, strlen(new_abs_filepath), "%s%s", + snprintf(new_abs_filepath, BT_FILE_PATH_MAX_LEN, "%s%s", directory, filename); + BT_DBG("file_path = [%s]", new_abs_filepath); - snprintf(old_abs_filepath, strlen(old_abs_filepath), "%s%s", - directory, object->name); - - if (rename(old_abs_filepath, new_abs_filepath)) { + fp = fopen(new_abs_filepath, "r"); + /* fopen succeed means file already exists */ + if (fp) { ret = BLUETOOTH_OTP_ERROR_OBJECT_NAME_EXISTS; goto fail; } + if (oacp_create) { + struct stat st; + + fp = fopen(new_abs_filepath, "a"); + if (!fp) { + BT_DBG("fopen() failed : %s", strerror(errno)); + ret = BLUETOOTH_ATT_ERROR_INTERNAL; + goto fail; + } + + if (stat(new_abs_filepath, &st) == -1) { + BT_INFO("stat failed: (%d)\n", errno); + ret = BLUETOOTH_ATT_ERROR_INTERNAL; + goto fail; + } + + object->name = g_strdup(filename); + object->first_created = st.st_ctime; + object->last_modified = st.st_ctime; + object->curr_size = (uint32_t) st.st_size; + oacp_create = FALSE; + } else { + char old_abs_filepath[BT_FILE_PATH_MAX_LEN] = {0, }; + snprintf(old_abs_filepath, BT_FILE_PATH_MAX_LEN, "%s%s", + directory, object->name); + + if (rename(old_abs_filepath, new_abs_filepath)) { + ret = BLUETOOTH_ATT_ERROR_INTERNAL; + goto fail; + } + } + memcpy(object->name, value, len); _bt_otp_set_char_value(otp_object_name_obj_path, value, len); +fail: + if (oacp_create) + _bt_otp_restore_old_object(); + if (oacp_create_timeout_id > 0) g_source_remove(oacp_create_timeout_id); -fail: + if (fp) + fclose(fp); + g_free(filename); return ret; } @@ -1774,7 +1783,7 @@ int _bt_otp_read_cb(const char *obj_path, char **value, int *len) if (!obj_path) { BT_ERR("Wrong Obj path"); - return BLUETOOTH_ERROR_INTERNAL; + return BLUETOOTH_ATT_ERROR_INTERNAL; } if (g_strcmp0(obj_path, otp_feature_obj_path)) { @@ -1785,16 +1794,23 @@ int _bt_otp_read_cb(const char *obj_path, char **value, int *len) info = otp_get_char_value(obj_path); if (info) { + if (oacp_create && !g_strcmp0(obj_path, otp_object_name_obj_path)) { + /* char_value is NULL, value_length is zero */ + *value = NULL; + *len = 0; + return BLUETOOTH_ATT_ERROR_NONE; + } + if (info->char_value == NULL || info->value_length == 0) - return BLUETOOTH_ERROR_INTERNAL; + return BLUETOOTH_ATT_ERROR_INTERNAL; *len = info->value_length; *value = (char *)malloc(sizeof(char)*(*len)); memcpy(*value, info->char_value, *len); - return BLUETOOTH_ERROR_NONE; + return BLUETOOTH_ATT_ERROR_NONE; } else { - return BLUETOOTH_ERROR_INTERNAL; + return BLUETOOTH_ATT_ERROR_INTERNAL; } } @@ -1947,7 +1963,7 @@ void _bt_otp_gatt_char_property_changed_event(GVariant *msg, guint16 offset = 0; char *value = NULL; int len = 0; - result = BLUETOOTH_ERROR_NONE; + result = BLUETOOTH_ATT_ERROR_NONE; BT_INFO("ReadValue"); BT_INFO("Type '%s'\n", g_variant_get_type_string(var)); @@ -1957,7 +1973,7 @@ void _bt_otp_gatt_char_property_changed_event(GVariant *msg, result = _bt_otp_read_cb(char_path, &value, &len); - if (result != BLUETOOTH_ERROR_NONE) { + if (result != BLUETOOTH_ATT_ERROR_NONE) { BT_ERR("ReadValue failed %s", char_path); bluetooth_gatt_send_response(req_id, BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ, diff --git a/bt-otp/bt-otpserver.h b/bt-otp/bt-otpserver.h index 87e815e..0a80eb0 100755 --- a/bt-otp/bt-otpserver.h +++ b/bt-otp/bt-otpserver.h @@ -40,7 +40,6 @@ #define BT_ADDRESS_STRING_SIZE 18 #define BT_OTP_BASE_DIR_PATH "/home/owner/media/otp/" -#define BT_OTP_EMPTY_FILENAME " " #define BT_OACP_MAX_TIMEOUT 10000 /* Timeout for OACP operation in msec */ -- 2.7.4