BT_OTP_NO_OPERATION = 0,
BT_OTP_OBJECT_DISCOVERY,
BT_OTP_OBJECT_READ,
+ BT_OTP_OBJECT_SELECT,
} bt_otp_api_info_e;
typedef struct {
bt_otp_client_read_op *oacp_read_op = NULL;
bool otc_connection_status = FALSE;
bt_otp_object_list_s *obj_list;
+uint64_t select_obj_id = 0;
object_metadata *metadata;
GSList *otp_client_list;
unsigned int timeout_id;
static void _bt_otp_client_notify_read_object_status(int result,
char *file_path, bt_otp_client_s *otp_client_s);
void __bt_otp_reset_api_info(bt_otp_client_s *otp_client_s);
+static void _bt_otp_client_send_select_object_callback(int result,
+ bt_otp_client_s *otp_client_s);
int __bt_check_otp_server_init_status(void)
{
static bt_otp_client_s *_bt_otp_client_find(const char *remote_address)
{
GSList *l;
+ bt_otp_client_s *info;
for (l = otp_client_list; l; l = g_slist_next(l)) {
+ info = l->data;
- if (!g_ascii_strcasecmp(((bt_otp_client_s *)l->data)->remote_address, remote_address))
- return ((bt_otp_client_s *)l->data);
+ if (info && !g_ascii_strcasecmp(info->remote_address, remote_address))
+ return info;
}
return NULL;
}
bt_otp_client_s *otp_client_s = NULL;
bool connected = false;
bluetooth_device_address_t addr_hex = { {0,} };
+ bt_otp_client_s *info;
GSList *l;
BT_INFO("+");
BT_CHECK_INPUT_PARAMETER(otp_client);
for (l = otp_client_list; l; l = g_slist_next(l)) {
- bt_otp_client_s *c = (bt_otp_client_s *)l->data;
+ info = l->data;
- if (!g_ascii_strcasecmp(c->remote_address, remote_address)) {
+ if (info && !g_ascii_strcasecmp(info->remote_address, remote_address)) {
BT_ERR("OTP Client for Remote device [%s] is already created",
remote_address);
- *otp_client = (bt_otp_client_h)c;
+ *otp_client = (bt_otp_client_h)info;
return BT_ERROR_ALREADY_DONE;
}
}
void _bt_otp_send_discovery_callback(int result, bt_otp_client_s *otp_client_s)
{
+ object_metadata *metadata;
GSList *l;
int k;
if (result != BLUETOOTH_ERROR_NONE) {
obj_list->num_objects = g_slist_length(otp_client_s->object_list);
obj_list->data = (otp_object_metadata_s **)g_malloc0(sizeof(otp_object_metadata_s)*obj_list->num_objects);
k = 0;
- for (l = otp_client_s->object_list; l != NULL; l = g_slist_next(l)) {
- object_metadata *metadata = l->data;
+ for (l = otp_client_s->object_list; l; l = g_slist_next(l)) {
+ metadata = l->data;
+ if (metadata == NULL)
+ continue;
otp_object_metadata_s *m_data = g_malloc0(sizeof(otp_object_metadata_s));
m_data->id = metadata->id;
m_data->name = g_strdup(metadata->name);
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);
- }
- if (otp_client_s->curr_op == BT_OTP_OBJECT_READ) {
+ } else 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_SELECT) {
+ _bt_otp_client_send_select_object_callback(result, otp_client_s);
+ __bt_otp_reset_api_info(otp_client_s);
}
}
}
if (resp_code != OACP_RESPONSE) {
BT_INFO("Indication Response Failed : Wrong Response Code");
result = BLUETOOTH_ERROR_INTERNAL;
- goto oacp_fail;
+ goto oacp_done;
}
if (result_code != OACP_SUCCESS) {
BT_INFO("Indication Response Fail [0x%x]", result_code);
result = BLUETOOTH_ERROR_INTERNAL;
- goto oacp_fail;
+ goto oacp_done;
}
switch (req_opcode) {
BT_INFO("OTC Connection Failed %s(0x%08x)",
_bt_convert_error_to_string(error_code), error_code);
result = error_code;
- goto oacp_fail;
+ goto oacp_done;
}
break;
case OACP_WRITE:
BT_INFO("Indication Failed : Wrong Req Opcode [0x%x], Reason [0x%x]",
req_opcode, result_code);
result = BLUETOOTH_ERROR_INTERNAL;
- goto oacp_fail;
+ goto oacp_done;
break;
}
return;
-oacp_fail:
+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);
/* Indication failed/timeout occured */
if (result != BLUETOOTH_ERROR_NONE)
- goto olcp_fail;
+ goto olcp_done;
BT_INFO("Resp_code [0x%x], Req_opcode [0x%x], result_code [0x%x]",
resp_code, req_opcode, result_code);
if (resp_code != OLCP_RESPONSE) {
BT_INFO("Indication Response Failed : Wrong Response Code");
result = BLUETOOTH_ERROR_INTERNAL;
- goto olcp_fail;
+ goto olcp_done;
}
if (result_code != OLCP_SUCCESS) {
result = BLUETOOTH_ERROR_INTERNAL;
break;
}
- goto olcp_fail;
+ goto olcp_done;
}
switch (req_opcode) {
if (error_code != BLUETOOTH_ERROR_NONE) {
BT_INFO("Read Charc Value Failed %s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
result = error_code;
- goto olcp_fail;
+ goto olcp_done;
}
} break;
- case OLCP_GOTO: /* TODO: */
+ case OLCP_GOTO:
+ /* Update the object id & notify client app*/
+ otp_client_s->object_id = select_obj_id;
+ select_obj_id = 0;
+ goto olcp_done;
break;
default:
BT_INFO("Indication Response Failed : Wrong Req Opcode [0x%x], Reason [0x%x]",
req_opcode, result_code);
result = BLUETOOTH_ERROR_INTERNAL;
- goto olcp_fail;
+ goto olcp_done;
break;
}
return;
-olcp_fail:
+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);
}
}
}
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);
- error_code = BT_ERROR_OPERATION_FAILED;
__bt_otp_reset_api_info(otp_client_s);
}
}
return error_code;
}
+static void _bt_otp_client_send_select_object_callback(int result,
+ bt_otp_client_s *otp_client_s)
+{
+ ((bt_otp_client_object_select_cb)otp_client_s->callback)(
+ result, otp_client_s->remote_address,
+ otp_client_s->object_id, otp_client_s->user_data);
+}
+
+int bt_otp_client_select_object(bt_otp_client_h otp_client, unsigned long long id,
+ bt_otp_client_object_select_cb callback, void *user_data)
+{
+ int error_code;
+ bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
+
+ BT_CHECK_LE_SUPPORT();
+ BT_CHECK_OTP_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(otp_client_s);
+
+ if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ if (otp_client_s->connected == false) {
+ BT_ERR("Remote device [%s] is not conencted", otp_client_s->remote_address);
+ return BT_ERROR_OPERATION_FAILED;
+ }
+
+ if (otp_client_s->object_id == id) {
+ BT_INFO("Object already selected");
+ return BLUETOOTH_ERROR_NONE;
+ }
+ if (otp_client_s->curr_op != BT_OTP_NO_OPERATION) {
+ BT_DBG("OTP client is busy");
+ return BT_ERROR_OPERATION_FAILED;
+ }
+
+ BT_DBG("OTP client select object [%llu] from Remote device [%s]", id, otp_client_s->remote_address);
+ otp_client_s->curr_op = BT_OTP_OBJECT_SELECT;
+ otp_client_s->callback = callback;
+ otp_client_s->user_data = user_data;
+
+ select_obj_id = id;
+
+ uint8_t value[7] = {0x00};
+ value[0] = OLCP_GOTO;
+ value[1] = select_obj_id & 0xFF;
+ value[2] = (select_obj_id >> 8) & 0xFF;
+ value[3] = (select_obj_id >> 16) & 0xFF;
+ value[4] = (select_obj_id >> 24) & 0xFF;
+ value[5] = (select_obj_id >> 32) & 0xFF;
+ value[6] = (select_obj_id >> 40) & 0xFF;
+
+ error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_olcp_control_point,
+ value, 7);
+ 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);
+ __bt_otp_reset_api_info(otp_client_s);
+ }
+
+ return error_code;
+}
static bool __bt_otc_connection_timeout_cb(gpointer user_data)
{
object_metadata *_bt_otp_client_find_object(GSList *list, uint64_t id)
{
GSList *l;
+ object_metadata *info;
for (l = list; l; l = g_slist_next(l)) {
+ info = l->data;
- if (((object_metadata *)l->data)->id == id)
- return ((object_metadata *)l->data);
+ if (info && (info->id == id))
+ return info;
}
return NULL;
}
, BT_UNIT_TEST_FUNCTION_OTP_CLIENT_DISCONNECT},
{"bt_otp_client_discover_all_objects"
, BT_UNIT_TEST_FUNCTION_OTP_CLIENT_DISCOVER_ALL_OBJECTS},
+ {"bt_otp_client_select_object"
+ , BT_UNIT_TEST_FUNCTION_OTP_CLIENT_SELECT_OBJ},
{"bt_otp_client_read_object_contents"
, BT_UNIT_TEST_FUNCTION_OTP_CLIENT_READ_OBJ_CONTENTS},
{NULL , 0x0000},
BT_ERR("Object discovery failed!");
}
+static void __bt_otp_client_object_select_cb(int result, const char *remote_address,
+ unsigned long long obj_id, void *user_data)
+{
+ TC_PRT("__bt_otp_client_object_select_cb");
+ TC_PRT("Result: %s", __bt_get_error_message(result));
+ TC_PRT("Remote addr [%s]", remote_address);
+
+ if (result == BT_ERROR_NONE)
+ TC_PRT("Object selected successfully! Current object[%llu]", obj_id);
+ else
+ BT_ERR("Object selection failed! Current object[%llu]", obj_id);
+}
+
static void __bt_otp_client_read_object_complete_cb(int result, const char *remote_address,
char *file_path, void *user_data)
{
break;
}
+ case BT_UNIT_TEST_FUNCTION_OTP_CLIENT_SELECT_OBJ: {
+ if (param_index == 0) {
+ g_test_param.param_count = 1;
+ g_test_param.params = g_malloc0(sizeof(char *) *g_test_param.param_count);
+ param_type = BT_UNIT_TEST_PARAM_TYPE_INT;
+ }
+
+ if (param_index > 0) {
+ int len = strlen(param);
+ g_test_param.params[param_index - 1] = g_malloc0(len + 1);
+ /* Remove new line character */
+ param[len - 1] = '\0';
+ strncpy(g_test_param.params[param_index - 1], param, strlen(param));
+ }
+
+ if (param_index == g_test_param.param_count) {
+ need_to_set_params = false;
+#ifdef ARCH64
+ test_input_callback((void *)(uintptr_t)test_id);
+#else
+ test_input_callback((void *)test_id);
+#endif
+ param_index = 0;
+ return 0;
+ }
+
+ switch (param_index) {
+ case 0:
+ TC_PRT("Input Value in uint64_t");
+ break;
+ }
+
+ param_index++;
+
+ break;
+ }
default:
TC_PRT("There is no param to set\n");
need_to_set_params = false;
}
break;
}
+ case BT_UNIT_TEST_FUNCTION_OTP_CLIENT_SELECT_OBJ: {
+ if (otp_client) {
+ unsigned long long id;
+ if (g_test_param.param_count < 1) {
+ TC_PRT("Input parameters first");
+ break;
+ }
+
+ id = atoi(g_test_param.params[0]);
+ TC_PRT("Object ID[%llu]", id);
+ ret = bt_otp_client_select_object(otp_client, id,
+ __bt_otp_client_object_select_cb, NULL);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ }
+ break;
+ }
case BT_UNIT_TEST_FUNCTION_OTP_CLIENT_READ_OBJ_CONTENTS: {
if (otp_client) {
ret = bt_otp_client_read_object_contents(otp_client,