From 8b9f6b4b0491b32f07f2219688641418ff029b6b Mon Sep 17 00:00:00 2001 From: Gowtham Anandha Babu Date: Tue, 13 Jun 2017 15:53:54 +0530 Subject: [PATCH] [OTP] Handle Object Create request Change-Id: Ie4a4a9ab144d506c8f3c9b972e54538cc91178b5 Signed-off-by: Gowtham Anandha Babu --- bt-otp/bt-otpserver.c | 146 +++++++++++++++++++++++++++++++++++++++----- bt-otp/bt-otpserver.h | 4 ++ bt-service/bt-service-otp.c | 1 + 3 files changed, 137 insertions(+), 14 deletions(-) diff --git a/bt-otp/bt-otpserver.c b/bt-otp/bt-otpserver.c index c8e372b..d75ed46 100644 --- a/bt-otp/bt-otpserver.c +++ b/bt-otp/bt-otpserver.c @@ -98,6 +98,14 @@ struct oacp_operation { int fd; }; +struct oacp_create_operation { + char *remote_address; + char *filename; + char *uuid; + uint32_t size; + time_t first_created; +}; + static struct object_metadata *selected_object = NULL; static uint64_t object_id = OBJECT_START_ID; static GSList *otp_object_list = NULL; @@ -110,6 +118,8 @@ char *directory = NULL; gboolean mutiple_obj_support = false; static gboolean otc_connection_status = FALSE; struct oacp_operation *oacp_read = NULL; +struct oacp_create_operation *oacp_create = NULL; +unsigned int timeout_id; static const gchar otp_introspection_xml[] = "" @@ -285,7 +295,7 @@ int _bt_otp_prepare_ots(void) char *desc_uuid; bt_gatt_characteristic_property_t props; bt_gatt_permission_t perms; - char supp_feat[OTP_FEATURE_LENGTH] = { 0x08, 0x00, 0x00, 0x00, + char supp_feat[OTP_FEATURE_LENGTH] = { 0x88, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }; ret = bluetooth_gatt_init(); @@ -321,8 +331,10 @@ int _bt_otp_prepare_ots(void) OTP_FEATURE_LENGTH); /* Characteristic Object Name */ - props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ; - perms = BLUETOOTH_GATT_PERMISSION_READ; + props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ | + BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE; + perms = BLUETOOTH_GATT_PERMISSION_READ | + BLUETOOTH_GATT_PERMISSION_WRITE; char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_NAME_UUID); ret = add_new_characteristic(char_uuid, perms, props, &otp_object_name_obj_path); @@ -672,16 +684,13 @@ fail: _bt_convert_device_path_to_address(dev_path, address); BT_INFO("OTC Connected fd: %d, address %s", fd, address); - if (!oacp_read) { - /* OTC Connected, but no on going request */ - goto done; - } - oacp_read->fd = fd; - otc_connection_status = TRUE; + if (oacp_read) { + oacp_read->fd = fd; + otc_connection_status = TRUE; - if (oacp_read->opcode == OACP_READ) - _bt_otp_start_write_on_fd(); -done: + if (oacp_read->opcode == OACP_READ) + _bt_otp_start_write_on_fd(); + } g_dbus_method_invocation_return_value(invocation, NULL); } BT_DBG("-"); @@ -908,13 +917,24 @@ fail: return ret; } +static bool __bt_oacp_create_timeout_cb(gpointer user_data) +{ + if (oacp_create) { + g_free(oacp_create->uuid); + g_free(oacp_create); + oacp_create = NULL; + } + return TRUE; +} + int _bt_otp_oacp_write_cb(char *value, int len, int offset, char *remote_addr, struct indicate_info *info) { int ret = OACP_SUCCESS; int app_err = BLUETOOTH_ERROR_NONE; int opcode = value[0]; - uint32_t object_offset, length; + uint32_t object_offset, length, object_size; + char *uuid; BT_INFO("OACP Opcode 0x%d", opcode); @@ -925,7 +945,29 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset, switch (opcode) { case OACP_CREATE: - ret = OACP_OPCODE_NOT_SUPPORTED; + BT_INFO("OACP_CREATE"); + object_size = (uint32_t)(value[4] & 0xFF) << 24 | + (uint32_t)(value[3] & 0xFF) << 16 | + (uint32_t)(value[2] & 0xFF) << 8 | + (uint32_t)(value[1] & 0xFF); + + uuid = g_strndup(value + 5, len - 5); + BT_INFO("Size = %lu, UUID = %s", object_size, uuid); + + if (oacp_create) { + /* Create operation already going on. */ + ret = OACP_OPERATION_FAILED; + goto fail; + } + oacp_create = g_malloc0(sizeof(struct oacp_create_operation)); + oacp_create->size = object_size; + oacp_create->uuid = g_strdup(uuid); + if (timeout_id > 0) + g_source_remove(timeout_id); + timeout_id = g_timeout_add(BT_OACP_CREATE_MAX_TIMEOUT, + (GSourceFunc)__bt_oacp_create_timeout_cb, NULL); + g_free(uuid); + ret = OACP_SUCCESS; break; case OACP_DELETE: ret = OACP_OPCODE_NOT_SUPPORTED; @@ -1175,6 +1217,68 @@ fail: return BLUETOOTH_ERROR_NONE; } +int _bt_otp_obj_name_cb(char *value, int len) +{ + int ret = BLUETOOTH_ERROR_NONE; + + struct object_metadata *object = NULL; + struct stat st; + char *file_path; + char *filename; + int length; + FILE *fp = NULL; + + filename = g_strndup(value, len); + length = len + strlen(BT_OTP_BASE_DIR_PATH) + 1; + file_path = malloc(length); + + snprintf(file_path, length, "%s%s", + BT_OTP_BASE_DIR_PATH, filename); + BT_DBG("file_path = [%s]", file_path); + + fp = fopen(file_path, "a"); + if (!fp) { + BT_DBG("fopen() failed : %s", strerror(errno)); + ret = BLUETOOTH_ERROR_INTERNAL; + goto fail; + } + + if (stat(file_path, &st) == -1) { + BT_INFO("stat failed: (%d)\n", errno); + ret = BLUETOOTH_ERROR_INTERNAL; + goto fail; + } + + object = g_new0(struct object_metadata, 1); + + object->name = g_strdup(filename); + object->type = _otp_convert_uuid_to_uuid128(oacp_create->uuid); + object->first_created = st.st_ctime; + object->last_modified = st.st_ctime; + object->curr_size = (uint32_t)st.st_size; + object->alloc_size = oacp_create->size; + object->id = object_id; + object->props = OBJECT_READ | OBJECT_WRITE; + + otp_object_list = g_slist_append(otp_object_list, + object); + + update_obj_metadata_charc_value(object); + selected_object = object; + obj_curr_index = g_slist_length(otp_object_list) - 1; + object_id++; +fail: + if (fp) + fclose(fp); + g_free(filename); + free(file_path); + g_free(oacp_create->uuid); + g_free(oacp_create); + oacp_create = NULL; + + return ret; +} + static struct otp_char_info *otp_get_char_value(const char *path) { GSList *tmp = NULL; @@ -1322,6 +1426,20 @@ void _bt_otp_gatt_char_property_changed_event(GVariant *msg, result = _bt_otp_oacp_write_cb(value, len, offset, addr, &info); } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) { result = _bt_otp_olcp_write_cb(value, len, offset, &info); + } else if (!g_strcmp0(char_path, otp_object_name_obj_path)) { + if (oacp_create) { + /* OACP_CREATE is ongoing */ + result = _bt_otp_obj_name_cb(value, len); + } else { + /* Dont permit writting object name except while creating object. + * As this is directly pointing local objects. + */ + result = BLUETOOTH_ERROR_WRITE_REQUEST_REJECTED; + } + } else if (!g_strcmp0(char_path, otp_object_first_created_obj_path)) { + _bt_otp_set_char_value(otp_object_first_created_obj_path, value, len); + } else if (!g_strcmp0(char_path, otp_object_last_modified_obj_path)) { + _bt_otp_set_char_value(otp_object_last_modified_obj_path, value, len); } else { BT_ERR("Wrong Object Path %s", char_path); result = BLUETOOTH_ERROR_INTERNAL; diff --git a/bt-otp/bt-otpserver.h b/bt-otp/bt-otpserver.h index fa4aa1f..98f6c7a 100755 --- a/bt-otp/bt-otpserver.h +++ b/bt-otp/bt-otpserver.h @@ -35,6 +35,10 @@ #define BT_ADDRESS_STRING_SIZE 18 +#define BT_OTP_BASE_DIR_PATH "/home/owner/media/otp/" + +#define BT_OACP_CREATE_MAX_TIMEOUT 10000 /* Timeout for OACP_CREATE in msec */ + /* OTP Service and Chanracteristics UUID */ #define OTP_UUID "1825" #define OTP_FEATURE_UUID "2abd" diff --git a/bt-service/bt-service-otp.c b/bt-service/bt-service-otp.c index dc8716d..0c61c19 100644 --- a/bt-service/bt-service-otp.c +++ b/bt-service/bt-service-otp.c @@ -799,6 +799,7 @@ int _bt_otp_write_characteristic_value(int request_id, char *sender, char *handl otp_notification_info_list = g_slist_append(otp_notification_info_list, info); } info->req_id = request_id; + /* Set timeout only for cp charc */ info->notification_timeout_id = g_timeout_add(BT_INDICATION_TIMEOUT_MAX, (GSourceFunc)__bt_otp_indication_timeout_cb, (gpointer)info->handle); -- 2.7.4