summaryrefslogtreecommitdiff
path: root/src/bluetooth-otp.c
diff options
context:
space:
mode:
authorGowtham Anandha Babu <gowtham.ab@samsung.com>2017-08-01 12:54:40 +0530
committerGowtham Anandha Babu <gowtham.ab@samsung.com>2017-08-01 12:54:40 +0530
commit1a55a3b7e4e261161999a7598528899770014e38 (patch)
tree15aa9f46076d4b9b75c7778789b970dda2ac6cc2 /src/bluetooth-otp.c
parentaa8f030f4844e9dee994675ffbbce4076f49b4eb (diff)
downloadbluetooth-1a55a3b7e4e261161999a7598528899770014e38.tar.gz
bluetooth-1a55a3b7e4e261161999a7598528899770014e38.tar.bz2
bluetooth-1a55a3b7e4e261161999a7598528899770014e38.zip
[OTP] Add Object Changed Characteristics implementation
Refactor OTP Client code. Change-Id: Iabdd5a4bee810a936b74f582404a3d1ce56c7faf Signed-off-by: Gowtham Anandha Babu <gowtham.ab@samsung.com>
Diffstat (limited to 'src/bluetooth-otp.c')
-rw-r--r--src/bluetooth-otp.c379
1 files 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 <stdbool.h>
#include <string.h>
#include <sys/stat.h>
+#include <arpa/inet.h>
#include <bluetooth-api.h>
#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);