X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-otp%2Fbt-otpserver.c;h=81d915c88931940f15551413ee816768854674c8;hb=d3f64e9c21a3743c3b8fb36e4524a030945e3333;hp=1b62b0edbd8853bbd90478b1275b0801b296c3db;hpb=645df23b2ffb0266288192222a3e23d41d117f3c;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-otp/bt-otpserver.c b/bt-otp/bt-otpserver.c index 1b62b0e..81d915c 100644 --- a/bt-otp/bt-otpserver.c +++ b/bt-otp/bt-otpserver.c @@ -33,6 +33,7 @@ #include "bt-otpserver.h" #include "bluetooth-api.h" +#include #undef LOG_TAG #define LOG_TAG "BLUETOOTH_OTP" @@ -64,6 +65,7 @@ static GDBusConnection *g_conn; static int property_sub_id = -1; static int adapter_sub_id = -1; static int device_sub_id = -1; +static int device_property_sub_id = -1; static guint g_owner_id = 0; static guint server_watch_id = 0; @@ -118,6 +120,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 +145,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); @@ -208,9 +211,8 @@ void _bt_otp_exit(void) if (ret != BLUETOOTH_ERROR_NONE) BT_ERR("Failed to stop ADV %d", ret); - if (main_loop != NULL) { + if (main_loop != NULL) g_main_loop_quit(main_loop); - } } static void _bt_otp_set_char_value(const char *obj_path, @@ -510,14 +512,16 @@ void _bt_otp_start_write_on_fd() FILE *fp; char file_path[BT_FILE_PATH_MAX_LEN] = {0, }; int length; + char err_msg[256] = {0, }; - 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); fp = fopen(file_path, "r"); if (!fp) { - BT_DBG("fopen() failed : %s", strerror(errno)); + cynara_strerror(errno, err_msg, sizeof(err_msg)); + BT_ERR("fopen() failed : %s", err_msg); return; } @@ -568,6 +572,7 @@ static gboolean __server_data_received_cb(GIOChannel *chan, GIOCondition cond, gsize len = 0; int written; int fd; + char err_msg[256] = {0, }; BT_DBG(""); @@ -604,7 +609,7 @@ static gboolean __server_data_received_cb(GIOChannel *chan, GIOCondition cond, return TRUE; } - BT_DBG("Received data length %d, remote_addr = %s", len, remote_addr); + BT_DBG("Received data length %zu, remote_addr = %s", len, remote_addr); if (!oacp_op->fp) { char file_path[BT_FILE_PATH_MAX_LEN] = {0, }; @@ -615,13 +620,14 @@ 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); fp = fopen(file_path, "w"); if (!fp) { - BT_DBG("fopen() failed : %s", strerror(errno)); + cynara_strerror(errno, err_msg, sizeof(err_msg)); + BT_ERR("fopen() failed : %s", err_msg); goto fail; } oacp_op->fp = fp; @@ -630,7 +636,7 @@ static gboolean __server_data_received_cb(GIOChannel *chan, GIOCondition cond, if (oacp_op->length_sofar <= oacp_op->length) { written = fwrite(buffer, 1, len, oacp_op->fp); oacp_op->length_sofar += written; - BT_DBG("written [%d], length_sofar [%lu], received_buff_len [%d], size [%lu]", + BT_DBG("written [%d], length_sofar [%u], received_buff_len [%zu], size [%u]", written, oacp_op->length_sofar, len, oacp_op->length); } @@ -698,9 +704,8 @@ static void _bt_otp_method(GDBusConnection *connection, goto fail; } - while ((filename = g_dir_read_name(dir))) { + while ((filename = g_dir_read_name(dir))) list = g_slist_append(list, (gpointer) filename); - } g_dir_close(dir); @@ -715,7 +720,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", @@ -810,6 +815,9 @@ fail: _bt_otp_start_write_on_fd(); else if (oacp_op->opcode == OACP_WRITE) _bt_otp_start_read_on_fd(); + } else { + /* Close fd if oacp_op is NULL */ + close(fd); } g_dbus_method_invocation_return_value(invocation, NULL); } @@ -1047,8 +1055,9 @@ fail: static bool __bt_oacp_create_timeout_cb(gpointer user_data) { /* Delete the EMPTY object */ - _bt_otp_delete_empty_file(); - return TRUE; + BT_INFO("+"); + _bt_otp_restore_old_object(); + return FALSE; } static void _bt_otp_free_oacp_op() @@ -1071,7 +1080,7 @@ int _bt_otp_send_launch_request(char *absolute_path) { void *handle; char *error; - int ret; + int ret = BLUETOOTH_ERROR_NONE; /* check ARCH 64 or 32*/ if (!access(FILEPATH_ARCH_64, 0)) { @@ -1090,7 +1099,7 @@ int _bt_otp_send_launch_request(char *absolute_path) dlerror(); /* Clear any existing error */ int (*fun)(char *) = (int (*)(char *))dlsym(handle, - "bt_app_control_send_launch_request"); + "bt_app_control_send_launch_request"); if ((error = dlerror()) != NULL) { BT_ERR("Can not load symbol : %s", dlerror()); @@ -1098,7 +1107,8 @@ int _bt_otp_send_launch_request(char *absolute_path) return BLUETOOTH_ERROR_INTERNAL; } - ret = fun(absolute_path); + if (fun) + ret = fun(absolute_path); dlclose(handle); return ret; @@ -1148,30 +1158,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 +1170,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 +1188,12 @@ 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,15 +1201,13 @@ 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); + if (!object) { + BT_ERR("Object is NULL"); + return; + } + oacp_create = FALSE; update_obj_metadata_charc_value(object); selected_object = object; curr_obj_index = index; @@ -1240,7 +1222,7 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset, int opcode = value[0]; uint32_t object_offset, length, object_size; uint8_t mode = 0; - char *uuid; + char *uuid = NULL; char absolute_file_path[BT_FILE_PATH_MAX_LEN] = {0, }; BT_INFO("OACP Opcode 0x%d", opcode); @@ -1272,12 +1254,9 @@ 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); + g_free(uuid); if (oacp_create_timeout_id > 0) g_source_remove(oacp_create_timeout_id); @@ -1285,12 +1264,11 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset, (GSourceFunc)__bt_oacp_create_timeout_cb, NULL); break; case OACP_DELETE: - if (opcode == OACP_DELETE && - ~(selected_object->props & OBJECT_DELETE)) { + if (!(selected_object->props & OBJECT_DELETE)) { 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); @@ -1308,12 +1286,11 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset, ret = OACP_OPCODE_NOT_SUPPORTED; break; case OACP_EXECUTE: - if (opcode == OACP_EXECUTE && - ~(selected_object->props & OBJECT_EXECUTE)) { + if (!(selected_object->props & OBJECT_EXECUTE)) { 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); @@ -1330,13 +1307,13 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset, case OACP_READ: case OACP_WRITE: if (opcode == OACP_WRITE && - ~(selected_object->props & OBJECT_WRITE)) { + !(selected_object->props & OBJECT_WRITE)) { ret = OACP_PROCEDURE_NOT_SUPPORTED; goto fail; } if (opcode == OACP_READ && - ~(selected_object->props & OBJECT_READ)) { + !(selected_object->props & OBJECT_READ)) { ret = OACP_PROCEDURE_NOT_SUPPORTED; goto fail; } @@ -1353,7 +1330,7 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset, if (opcode == OACP_WRITE) mode = (uint8_t)value[9] & 0xFF; - BT_INFO("Offset = %lu, Length = %lu", object_offset, length, mode); + BT_INFO("Offset = %u, Length = %u", object_offset, length); if (oacp_op) { if (otc_connection_status) { @@ -1476,15 +1453,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")) { @@ -1509,8 +1488,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); @@ -1616,7 +1597,7 @@ int _bt_otp_olcp_write_cb(char *value, int len, int offset, (uint64_t)(value[3] & 0xFF) << 16 | (uint64_t)(value[2] & 0xFF) << 8 | (uint64_t)(value[1] & 0xFF); - BT_INFO("Object ID [%llu]", object_id); + BT_INFO("Object ID [%llu]", (unsigned long long int)object_id); if (selected_object && selected_object->id == object_id) goto fail; @@ -1649,32 +1630,72 @@ 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; + char err_msg[256] = {0, }; object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index); if (!object) - return BLUETOOTH_ERROR_WRITE_REQUEST_REJECTED; + 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)) { - ret = OBJECT_NAME_ALREADY_EXISTS; + 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) { + cynara_strerror(errno, err_msg, sizeof(err_msg)); + BT_ERR("fopen() failed : %s", err_msg); + 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; } @@ -1687,7 +1708,7 @@ int _bt_otp_obj_first_created_write_cb(char *value, int len) object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index); if (!object) - return BLUETOOTH_ERROR_WRITE_REQUEST_REJECTED; + return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED; year = (uint16_t)(value[1] & 0xFF) << 8 | (uint16_t)(value[0] & 0xFF); @@ -1713,7 +1734,7 @@ int _bt_otp_obj_last_modified_write_cb(char *value, int len) object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index); if (!object) - return BLUETOOTH_ERROR_WRITE_REQUEST_REJECTED; + return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED; year = (uint16_t)(value[1] & 0xFF) << 8 | (uint16_t)(value[0] & 0xFF); @@ -1738,11 +1759,11 @@ int _bt_otp_obj_props_write_cb(char *value, int len) /* Any attempt to write RFU bits is error */ if (value[1] || value[2] || value[3]) - return BLUETOOTH_ERROR_WRITE_REQUEST_REJECTED; + return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED; object = (struct object_metadata *) g_slist_nth_data(otp_object_list, curr_obj_index); if (!object) - return BLUETOOTH_ERROR_WRITE_REQUEST_REJECTED; + return BLUETOOTH_OTP_ERROR_WRITE_REQUEST_REJECTED; props = (uint32_t)(value[3] & 0xFF) << 24 | (uint32_t)(value[2] & 0xFF) << 16 | @@ -1770,33 +1791,45 @@ static struct otp_char_info *otp_get_char_value(const char *path) return NULL; } -int _bt_otp_read_cb(const char *obj_path, char **value, int *len) +int _bt_otp_read_cb(const char *obj_path, char **value, int *len, uint16_t offset) { struct otp_char_info *info = NULL; 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)) { - if (!selected_object) { - return BLUETOOTH_ERROR_OBJECT_NOT_SELECTED; - } + if (!selected_object) + return BLUETOOTH_OTP_ERROR_OBJECT_NOT_SELECTED; } 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; + + if (offset > info->value_length) + return BLUETOOTH_ATT_ERROR_INVALID_OFFSET; - *len = info->value_length; + *len = info->value_length - offset; *value = (char *)malloc(sizeof(char)*(*len)); + if (*value == NULL) + return BLUETOOTH_ATT_ERROR_INTERNAL; + 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; } } @@ -1832,9 +1865,9 @@ static void _bt_otp_send_indication(const char *obj_path, value[1] = info->req_opcode & 0xFF; value[2] = info->result_code & 0xFF; if (info->resp_param) { - value[6] = (info->resp_param[3] >> 24) & 0xFF; - value[5] = (info->resp_param[4] >> 16) & 0xFF; - value[4] = (info->resp_param[5] >> 8) & 0xFF; + value[6] = info->resp_param[3] & 0xFF; + value[5] = info->resp_param[4] & 0xFF; + value[4] = info->resp_param[5] & 0xFF; value[3] = info->resp_param[6] & 0xFF; length = OTP_INDICATION_LEN_WITH_RESP; } @@ -1903,12 +1936,12 @@ void _bt_otp_gatt_char_property_changed_event(GVariant *msg, if (len != 0) { if (!g_strcmp0(char_path, otp_oacp_obj_path)) { if (!OACP_indicate) - result = BLUETOOTH_ERROR_CCC_IMPROPERLY_CONFIGURED; + result = BLUETOOTH_ATT_ERROR_CCCD_IMPROPERLY_CONFIGURED; else result = _bt_otp_oacp_write_cb(value, len, offset, addr, &info); } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) { if (!OLCP_indicate) - result = BLUETOOTH_ERROR_CCC_IMPROPERLY_CONFIGURED; + result = BLUETOOTH_ATT_ERROR_CCCD_IMPROPERLY_CONFIGURED; else result = _bt_otp_olcp_write_cb(value, len, offset, &info); } else if (!g_strcmp0(char_path, otp_object_name_obj_path)) { @@ -1929,17 +1962,16 @@ void _bt_otp_gatt_char_property_changed_event(GVariant *msg, /* Send indication for CPs */ if (!g_strcmp0(char_path, otp_oacp_obj_path)) { - if (OACP_indicate) { + if (OACP_indicate) _bt_otp_send_indication(char_path, &info, &addr_hex); - } } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) { - if (OLCP_indicate) { + if (OLCP_indicate) _bt_otp_send_indication(char_path, &info, &addr_hex); - } } } else { BT_ERR("Array Len 0"); } + g_variant_unref(val); } else { BT_ERR("var==NULL"); } @@ -1949,7 +1981,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,9 +1989,9 @@ void _bt_otp_gatt_char_property_changed_event(GVariant *msg, g_variant_get(var, "(&s&s&syq)", &char_path, &svc_handle, &addr, &req_id, &offset); - result = _bt_otp_read_cb(char_path, &value, &len); + result = _bt_otp_read_cb(char_path, &value, &len, offset); - 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, @@ -1981,11 +2013,10 @@ void _bt_otp_gatt_char_property_changed_event(GVariant *msg, indicate ? "StartNotify" : "StopNotify"); BT_INFO("Type '%s'\n", g_variant_get_type_string(var)); - if (!g_strcmp0(char_path, otp_oacp_obj_path)) { + if (!g_strcmp0(char_path, otp_oacp_obj_path)) OACP_indicate = indicate; - } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) { + else if (!g_strcmp0(char_path, otp_olcp_obj_path)) OLCP_indicate = indicate; - } } } return; @@ -2029,9 +2060,8 @@ void _bt_otp_adapter_event_filter(GDBusConnection *connection, BT_INFO("Interface %s, Signal %s", interface_name, signal_name); if (g_strcmp0(interface_name, BT_OTP_INTERFACE_NAME) == 0) { - if (strcasecmp(signal_name, BLE_DISABLED) == 0) { + if (strcasecmp(signal_name, BLE_DISABLED) == 0) _bt_otp_exit(); - } } } @@ -2060,6 +2090,52 @@ void _bt_otc_disconnected_cb(GDBusConnection *connection, } } +void _bt_otp_device_property_event_filter(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + char *interfacename = NULL; + GVariant *val = NULL; + + g_variant_get(parameters, "(&s@a{sv}@as)", &interfacename, &val, NULL); + + if (strcasecmp(interfacename, BT_DEVICE_INTERFACE) == 0) { + GVariantIter value_iter; + GVariant *val1; + char *property = NULL; + + g_variant_iter_init(&value_iter, val); + while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &val1))) { + if (strcasecmp(property, "GattConnected") == 0) { + gboolean gatt_connected = FALSE; + char *address = NULL; + + g_variant_get(val1, "b", &gatt_connected); + + address = g_malloc0(BT_ADDRESS_STRING_SIZE); + + _bt_convert_device_path_to_address(object_path, address); + + BT_DBG("gatt_connected: %d", gatt_connected); + BT_DBG("address: %s", address); + if (!gatt_connected) { + if (oacp_create) + _bt_otp_restore_old_object(); + + if (oacp_create_timeout_id > 0) + g_source_remove(oacp_create_timeout_id); + } + g_free(address); + } + } + } + g_variant_unref(val); +} + int _bt_otp_init_event_receiver() { BT_DBG("+"); @@ -2096,6 +2172,12 @@ int _bt_otp_init_event_receiver() _bt_otc_disconnected_cb, NULL, NULL); + device_property_sub_id = g_dbus_connection_signal_subscribe(conn, + BT_BLUEZ_NAME, BT_PROPERTIES_INTERFACE, + PROPERTIES_CHANGED, NULL, NULL, 0, + _bt_otp_device_property_event_filter, + NULL, NULL); + BT_DBG("-"); return 0; } @@ -2107,6 +2189,7 @@ void _bt_otp_deinit_event_receiver(void) g_dbus_connection_signal_unsubscribe(conn, property_sub_id); g_dbus_connection_signal_unsubscribe(conn, adapter_sub_id); g_dbus_connection_signal_unsubscribe(conn, device_sub_id); + g_dbus_connection_signal_unsubscribe(conn, device_property_sub_id); conn = NULL; BT_DBG("-"); @@ -2161,9 +2244,8 @@ int main(void) BT_DBG("g_main_loop_quit called!"); - if (main_loop != NULL) { + if (main_loop != NULL) g_main_loop_unref(main_loop); - } return 0; }