---
android/tester-main.c | 20 ++++++++++++++++++--
android/tester-main.h | 11 +++++++----
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/android/tester-main.c b/android/tester-main.c
index f4d18e2..8cf62c2 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -654,6 +654,22 @@ static bool match_data(struct step *step)
return false;
}
+ if (exp->callback_result.av_conn_state !=
+ step->callback_result.av_conn_state) {
+ tester_debug("Callback av conn state mismatch: 0x%x vs 0x%x",
+ step->callback_result.av_conn_state,
+ exp->callback_result.av_conn_state);
+ return false;
+ }
+
+ if (exp->callback_result.av_audio_state !=
+ step->callback_result.av_audio_state) {
+ tester_debug("Callback av audio state mismatch: 0x%x vs 0x%x",
+ step->callback_result.av_audio_state,
+ exp->callback_result.av_audio_state);
+ return false;
+ }
+
if (exp->callback_result.pairing_variant !=
step->callback_result.pairing_variant) {
tester_debug("Callback pairing result mismatch: %d vs %d",
@@ -1863,7 +1879,7 @@ static void a2dp_connection_state_cb(btav_connection_state_t state,
struct step *step = g_new0(struct step, 1);
step->callback = CB_A2DP_CONN_STATE;
- step->callback_result.state = state;
+ step->callback_result.av_conn_state = state;
schedule_callback_verification(step);
}
@@ -1873,7 +1889,7 @@ static void a2dp_audio_state_cb(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
struct step *step = g_new0(struct step, 1);
step->callback = CB_A2DP_AUDIO_STATE;
- step->callback_result.state = state;
+ step->callback_result.av_audio_state = state;
schedule_callback_verification(step);
}
diff --git a/android/tester-main.h b/android/tester-main.h
index c938d44..ff6e43c 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -387,14 +387,14 @@ struct pdu_set {
.callback_result.channel_state = cb_state, \
}
-#define CALLBACK_AV_CONN_STATE(cb, cb_state) { \
+#define CALLBACK_AV_CONN_STATE(cb, cb_av_conn_state) { \
.callback = cb, \
- .callback_result.state = cb_state, \
+ .callback_result.av_conn_state = cb_av_conn_state, \
}
-#define CALLBACK_AV_AUDIO_STATE(cb, cb_state) { \
+#define CALLBACK_AV_AUDIO_STATE(cb, cb_av_audio_state) { \
.callback = cb, \
- .callback_result.state = cb_state, \
+ .callback_result.av_audio_state = cb_av_audio_state, \
}
#define CALLBACK_DEVICE_PROPS(props, prop_cnt) \
@@ -641,6 +641,9 @@ struct bt_callback_data {
int mdep_cfg_index;
bthl_app_reg_state_t app_state;
bthl_channel_state_t channel_state;
+
+ btav_connection_state_t av_conn_state;
+ btav_audio_state_t av_audio_state;
};
/*
--
2.1.0
Hi Ravi,
On Mon, Oct 27, 2014 at 4:56 PM, Ravi kumar Veeramally
<[email protected]> wrote:
> ---
> android/tester-avrcp.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++
> android/tester-main.c | 26 +++++++++++++++
> android/tester-main.h | 10 ++++++
> 3 files changed, 121 insertions(+)
>
> diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
> index 06c2bd8..c78131e 100644
> --- a/android/tester-avrcp.c
> +++ b/android/tester-avrcp.c
> @@ -25,6 +25,7 @@
>
> static struct queue *list;
>
> +#define AVRCP_GET_ELEMENT_ATTRIBUTES 0x20
> #define AVRCP_GET_PLAY_STATUS 0x30
> #define AVRCP_REGISTER_NOTIFICATION 0x31
>
> @@ -90,6 +91,18 @@ static struct emu_l2cap_cid_data sdp_data = {
> 0x58, 0x31, 0x00, 0x00, 0x09, 0x02, 0xFF, 0xFF, \
> 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
>
> +#define req_ele_attr 0x00, 0x11, 0x0e, 0x01, 0x48, 0x00, 0x00, 0x19, 0x58, \
> + 0x20, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, \
Apparently check-patch don't like that you are breaking the line
before reaching the maximum column:
WARNING:LINE_CONTINUATIONS: Avoid unnecessary line continuations
#39: FILE: android/tester-avrcp.c:126:
+ .text = {0x47, 0x69, 0x76, 0x65, 0x20, 0x50, 0x65, 0x61, 0x63, 0x65, \
> + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07
> +
> +#define rsp_ele_attr 0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00, 0x00, 0x19, 0x58, \
> + 0x20, 0x00, 0x00, 0x2a, 0x02, 0x00, 0x00, 0x00, 0x01, \
> + 0x00, 0x6a, 0x00, 0x13, 0x47, 0x69, 0x76, 0x65, 0x20, \
> + 0x50, 0x65, 0x61, 0x63, 0x65, 0x20, 0x61, 0x20, 0x43, \
> + 0x68, 0x61, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x07, \
> + 0x00, 0x6a, 0x00, 0x06, 0x31, 0x30, 0x33, 0x30, 0x30, \
> + 0x30
> +
> static const struct pdu_set pdus[] = {
> { raw_pdu(req_dsc), raw_pdu(rsp_dsc) },
> { raw_pdu(req_get), raw_pdu(rsp_get) },
> @@ -107,6 +120,20 @@ static struct emu_l2cap_cid_data a2dp_data = {
>
> static struct emu_l2cap_cid_data avrcp_data;
>
> +static btrc_element_attr_val_t ele_attrs[2] = {
> + {
> + .attr_id = BTRC_MEDIA_ATTR_TITLE,
> + .text = {0x47, 0x69, 0x76, 0x65, 0x20, 0x50, 0x65, 0x61, 0x63, 0x65, \
> + 0x20, 0x61, 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65}
> + },
> + {
> + .attr_id = BTRC_MEDIA_ATTR_PLAYING_TIME,
> + .text = {0x31, 0x30, 0x33, 0x30, 0x30, 0x30}
> + }
> +};
> +
> +static btrc_element_attr_val_t exp_attrs[2];
> +
> static void print_avrcp(const char *str, void *user_data)
> {
> tester_debug("avrcp: %s", str);
> @@ -138,6 +165,19 @@ static void avrcp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
> schedule_callback_verification(step);
> }
> break;
> + case AVRCP_GET_ELEMENT_ATTRIBUTES:
> + step = g_new0(struct step, 1);
> + step->callback = CB_AVRCP_GET_ATTR_RSP;
> + step->callback_result.num_of_attrs = ((uint8_t *) data)[13];
> +
> + memset(exp_attrs, 0, 2 * sizeof(btrc_element_attr_val_t));
> + exp_attrs[0].attr_id = get_be16(data + 16);
> + memcpy(exp_attrs[0].text, data + 22, 19);
> + exp_attrs[1].attr_id = get_be16(data + 43);
> + memcpy(exp_attrs[1].text, data + 49, 6);
> + step->callback_result.attrs = exp_attrs;
> + schedule_callback_verification(step);
> + break;
> }
> }
>
> @@ -275,6 +315,29 @@ static void avrcp_reg_notif_track_changed_rsp(void)
> schedule_action_verification(step);
> }
>
> +static void avrcp_get_element_attributes_req(void)
> +{
> + struct test_data *data = tester_get_data();
> + struct bthost *bthost = hciemu_client_get_host(data->hciemu);
> + const struct iovec pdu = raw_pdu(req_ele_attr);
> + struct step *step = g_new0(struct step, 1);
> +
> + bthost_send_cid_v(bthost, avrcp_data.handle, avrcp_data.cid, &pdu, 1);
> + step->action_status = BT_STATUS_SUCCESS;
> + schedule_action_verification(step);
> +}
> +
> +static void avrcp_get_element_attributes_rsp(void)
> +{
> + struct test_data *data = tester_get_data();
> + struct step *step = g_new0(struct step, 1);
> +
> + step->action_status = data->if_avrcp->get_element_attr_rsp(2,
> + ele_attrs);
> +
> + schedule_action_verification(step);
> +}
> +
> static struct test_case test_cases[] = {
> TEST_CASE_BREDRLE("AVRCP Init",
> ACTION_SUCCESS(dummy_action, NULL),
> @@ -362,6 +425,28 @@ static struct test_case test_cases[] = {
> ACTION_SUCCESS(bluetooth_disable_action, NULL),
> CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
> ),
> + TEST_CASE_BREDRLE("AVRCP GetElementAttributes - Success",
> + ACTION_SUCCESS(bluetooth_enable_action, NULL),
> + CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
> + ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
> + ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
> + ACTION_SUCCESS(set_default_ssp_request_handler, NULL),
> + ACTION_SUCCESS(emu_add_l2cap_server_action, &sdp_setup_data),
> + ACTION_SUCCESS(emu_add_l2cap_server_action, &a2dp_setup_data),
> + ACTION_SUCCESS(emu_add_l2cap_server_action, &avrcp_setup_data),
> + ACTION_SUCCESS(avrcp_connect_action, NULL),
> + CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE,
> + BTAV_CONNECTION_STATE_CONNECTING),
> + CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE,
> + BTAV_CONNECTION_STATE_CONNECTED),
> + ACTION_SUCCESS(avrcp_get_element_attributes_req, NULL),
> + CALLBACK(CB_AVRCP_GET_ATTR_REQ),
> + ACTION_SUCCESS(avrcp_get_element_attributes_rsp, NULL),
> + CALLBACK_RC_GET_ELEMENT_ATTRIBUTES(CB_AVRCP_GET_ATTR_RSP, 2,
> + ele_attrs),
> + ACTION_SUCCESS(bluetooth_disable_action, NULL),
> + CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
> + ),
> };
>
> struct queue *get_avrcp_tests(void)
> diff --git a/android/tester-main.c b/android/tester-main.c
> index a416914..515c69e 100644
> --- a/android/tester-main.c
> +++ b/android/tester-main.c
> @@ -700,6 +700,22 @@ static bool match_data(struct step *step)
> return false;
> }
>
> + if (exp->callback_result.num_of_attrs !=
> + step->callback_result.num_of_attrs) {
> + tester_debug("Callback rc num of attrs mismatch");
> + return false;
> + }
> +
> + if (exp->callback_result.attrs) {
> + if (memcmp(step->callback_result.attrs,
> + exp->callback_result.attrs,
> + exp->callback_result.num_of_attrs *
> + sizeof(btrc_element_attr_val_t))) {
> + tester_debug("Callback rc element attributes doesn't match");
> + return false;
> + }
> + }
> +
> if (exp->callback_result.pairing_variant !=
> step->callback_result.pairing_variant) {
> tester_debug("Callback pairing result mismatch: %d vs %d",
> @@ -1947,10 +1963,20 @@ static void avrcp_register_notification_cb(btrc_event_id_t event_id,
> schedule_callback_verification(step);
> }
>
> +static void avrcp_get_element_attr_cb(uint8_t num_attr,
> + btrc_media_attr_t *p_attrs)
> +{
> + struct step *step = g_new0(struct step, 1);
> +
> + step->callback = CB_AVRCP_GET_ATTR_REQ;
> + schedule_callback_verification(step);
> +}
> +
> static btrc_callbacks_t btavrcp_callbacks = {
> .size = sizeof(btavrcp_callbacks),
> .get_play_status_cb = avrcp_get_play_status_cb,
> .register_notification_cb = avrcp_register_notification_cb,
> + .get_element_attr_cb = avrcp_get_element_attr_cb,
> };
>
> static const btgatt_client_callbacks_t btgatt_client_callbacks = {
> diff --git a/android/tester-main.h b/android/tester-main.h
> index d46b262..ac310a3 100644
> --- a/android/tester-main.h
> +++ b/android/tester-main.h
> @@ -409,6 +409,12 @@ struct pdu_set {
> .callback_result.rc_index = cb_index, \
> }
>
> +#define CALLBACK_RC_GET_ELEMENT_ATTRIBUTES(cb, cb_num_of_attrs, cb_attrs) { \
> + .callback = cb, \
> + .callback_result.num_of_attrs = cb_num_of_attrs, \
> + .callback_result.attrs = cb_attrs, \
> + }
> +
> #define CALLBACK_DEVICE_PROPS(props, prop_cnt) \
> CALLBACK_PROPS(CB_BT_REMOTE_DEVICE_PROPERTIES, props, prop_cnt)
>
> @@ -484,6 +490,8 @@ typedef enum {
> CB_AVRCP_PLAY_STATUS_RSP,
> CB_AVRCP_REG_NOTIF_REQ,
> CB_AVRCP_REG_NOTIF_RSP,
> + CB_AVRCP_GET_ATTR_REQ,
> + CB_AVRCP_GET_ATTR_RSP,
>
> /* Gatt client */
> CB_GATTC_REGISTER_CLIENT,
> @@ -666,6 +674,8 @@ struct bt_callback_data {
> uint32_t song_position;
> btrc_play_status_t play_status;
> uint64_t rc_index;
> + uint8_t num_of_attrs;
> + btrc_element_attr_val_t *attrs;
> };
>
> /*
> --
> 2.1.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Luiz Augusto von Dentz
Hi Ravi,
On Mon, Oct 27, 2014 at 4:56 PM, Ravi kumar Veeramally
<[email protected]> wrote:
> ---
Could you please add a description why this is needed, even though I
get it is always good idea to add a bit more description since it is
fixing something.
> android/tester-main.c | 20 ++++++++++++++++++--
> android/tester-main.h | 11 +++++++----
> 2 files changed, 25 insertions(+), 6 deletions(-)
>
> diff --git a/android/tester-main.c b/android/tester-main.c
> index f4d18e2..8cf62c2 100644
> --- a/android/tester-main.c
> +++ b/android/tester-main.c
> @@ -654,6 +654,22 @@ static bool match_data(struct step *step)
> return false;
> }
>
> + if (exp->callback_result.av_conn_state !=
> + step->callback_result.av_conn_state) {
> + tester_debug("Callback av conn state mismatch: 0x%x vs 0x%x",
> + step->callback_result.av_conn_state,
> + exp->callback_result.av_conn_state);
> + return false;
> + }
> +
> + if (exp->callback_result.av_audio_state !=
> + step->callback_result.av_audio_state) {
> + tester_debug("Callback av audio state mismatch: 0x%x vs 0x%x",
> + step->callback_result.av_audio_state,
> + exp->callback_result.av_audio_state);
> + return false;
> + }
> +
> if (exp->callback_result.pairing_variant !=
> step->callback_result.pairing_variant) {
> tester_debug("Callback pairing result mismatch: %d vs %d",
> @@ -1863,7 +1879,7 @@ static void a2dp_connection_state_cb(btav_connection_state_t state,
> struct step *step = g_new0(struct step, 1);
>
> step->callback = CB_A2DP_CONN_STATE;
> - step->callback_result.state = state;
> + step->callback_result.av_conn_state = state;
>
> schedule_callback_verification(step);
> }
> @@ -1873,7 +1889,7 @@ static void a2dp_audio_state_cb(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
> struct step *step = g_new0(struct step, 1);
>
> step->callback = CB_A2DP_AUDIO_STATE;
> - step->callback_result.state = state;
> + step->callback_result.av_audio_state = state;
>
> schedule_callback_verification(step);
> }
> diff --git a/android/tester-main.h b/android/tester-main.h
> index c938d44..ff6e43c 100644
> --- a/android/tester-main.h
> +++ b/android/tester-main.h
> @@ -387,14 +387,14 @@ struct pdu_set {
> .callback_result.channel_state = cb_state, \
> }
>
> -#define CALLBACK_AV_CONN_STATE(cb, cb_state) { \
> +#define CALLBACK_AV_CONN_STATE(cb, cb_av_conn_state) { \
> .callback = cb, \
> - .callback_result.state = cb_state, \
> + .callback_result.av_conn_state = cb_av_conn_state, \
> }
>
> -#define CALLBACK_AV_AUDIO_STATE(cb, cb_state) { \
> +#define CALLBACK_AV_AUDIO_STATE(cb, cb_av_audio_state) { \
> .callback = cb, \
> - .callback_result.state = cb_state, \
> + .callback_result.av_audio_state = cb_av_audio_state, \
> }
>
> #define CALLBACK_DEVICE_PROPS(props, prop_cnt) \
> @@ -641,6 +641,9 @@ struct bt_callback_data {
> int mdep_cfg_index;
> bthl_app_reg_state_t app_state;
> bthl_channel_state_t channel_state;
> +
> + btav_connection_state_t av_conn_state;
> + btav_audio_state_t av_audio_state;
> };
>
> /*
> --
> 2.1.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Luiz Augusto von Dentz
---
android/tester-avrcp.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++
android/tester-main.c | 26 +++++++++++++++
android/tester-main.h | 10 ++++++
3 files changed, 121 insertions(+)
diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
index 06c2bd8..c78131e 100644
--- a/android/tester-avrcp.c
+++ b/android/tester-avrcp.c
@@ -25,6 +25,7 @@
static struct queue *list;
+#define AVRCP_GET_ELEMENT_ATTRIBUTES 0x20
#define AVRCP_GET_PLAY_STATUS 0x30
#define AVRCP_REGISTER_NOTIFICATION 0x31
@@ -90,6 +91,18 @@ static struct emu_l2cap_cid_data sdp_data = {
0x58, 0x31, 0x00, 0x00, 0x09, 0x02, 0xFF, 0xFF, \
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+#define req_ele_attr 0x00, 0x11, 0x0e, 0x01, 0x48, 0x00, 0x00, 0x19, 0x58, \
+ 0x20, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, \
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07
+
+#define rsp_ele_attr 0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00, 0x00, 0x19, 0x58, \
+ 0x20, 0x00, 0x00, 0x2a, 0x02, 0x00, 0x00, 0x00, 0x01, \
+ 0x00, 0x6a, 0x00, 0x13, 0x47, 0x69, 0x76, 0x65, 0x20, \
+ 0x50, 0x65, 0x61, 0x63, 0x65, 0x20, 0x61, 0x20, 0x43, \
+ 0x68, 0x61, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x07, \
+ 0x00, 0x6a, 0x00, 0x06, 0x31, 0x30, 0x33, 0x30, 0x30, \
+ 0x30
+
static const struct pdu_set pdus[] = {
{ raw_pdu(req_dsc), raw_pdu(rsp_dsc) },
{ raw_pdu(req_get), raw_pdu(rsp_get) },
@@ -107,6 +120,20 @@ static struct emu_l2cap_cid_data a2dp_data = {
static struct emu_l2cap_cid_data avrcp_data;
+static btrc_element_attr_val_t ele_attrs[2] = {
+ {
+ .attr_id = BTRC_MEDIA_ATTR_TITLE,
+ .text = {0x47, 0x69, 0x76, 0x65, 0x20, 0x50, 0x65, 0x61, 0x63, 0x65, \
+ 0x20, 0x61, 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65}
+ },
+ {
+ .attr_id = BTRC_MEDIA_ATTR_PLAYING_TIME,
+ .text = {0x31, 0x30, 0x33, 0x30, 0x30, 0x30}
+ }
+};
+
+static btrc_element_attr_val_t exp_attrs[2];
+
static void print_avrcp(const char *str, void *user_data)
{
tester_debug("avrcp: %s", str);
@@ -138,6 +165,19 @@ static void avrcp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
schedule_callback_verification(step);
}
break;
+ case AVRCP_GET_ELEMENT_ATTRIBUTES:
+ step = g_new0(struct step, 1);
+ step->callback = CB_AVRCP_GET_ATTR_RSP;
+ step->callback_result.num_of_attrs = ((uint8_t *) data)[13];
+
+ memset(exp_attrs, 0, 2 * sizeof(btrc_element_attr_val_t));
+ exp_attrs[0].attr_id = get_be16(data + 16);
+ memcpy(exp_attrs[0].text, data + 22, 19);
+ exp_attrs[1].attr_id = get_be16(data + 43);
+ memcpy(exp_attrs[1].text, data + 49, 6);
+ step->callback_result.attrs = exp_attrs;
+ schedule_callback_verification(step);
+ break;
}
}
@@ -275,6 +315,29 @@ static void avrcp_reg_notif_track_changed_rsp(void)
schedule_action_verification(step);
}
+static void avrcp_get_element_attributes_req(void)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ const struct iovec pdu = raw_pdu(req_ele_attr);
+ struct step *step = g_new0(struct step, 1);
+
+ bthost_send_cid_v(bthost, avrcp_data.handle, avrcp_data.cid, &pdu, 1);
+ step->action_status = BT_STATUS_SUCCESS;
+ schedule_action_verification(step);
+}
+
+static void avrcp_get_element_attributes_rsp(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *step = g_new0(struct step, 1);
+
+ step->action_status = data->if_avrcp->get_element_attr_rsp(2,
+ ele_attrs);
+
+ schedule_action_verification(step);
+}
+
static struct test_case test_cases[] = {
TEST_CASE_BREDRLE("AVRCP Init",
ACTION_SUCCESS(dummy_action, NULL),
@@ -362,6 +425,28 @@ static struct test_case test_cases[] = {
ACTION_SUCCESS(bluetooth_disable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
),
+ TEST_CASE_BREDRLE("AVRCP GetElementAttributes - Success",
+ ACTION_SUCCESS(bluetooth_enable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
+ ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
+ ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
+ ACTION_SUCCESS(set_default_ssp_request_handler, NULL),
+ ACTION_SUCCESS(emu_add_l2cap_server_action, &sdp_setup_data),
+ ACTION_SUCCESS(emu_add_l2cap_server_action, &a2dp_setup_data),
+ ACTION_SUCCESS(emu_add_l2cap_server_action, &avrcp_setup_data),
+ ACTION_SUCCESS(avrcp_connect_action, NULL),
+ CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE,
+ BTAV_CONNECTION_STATE_CONNECTING),
+ CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE,
+ BTAV_CONNECTION_STATE_CONNECTED),
+ ACTION_SUCCESS(avrcp_get_element_attributes_req, NULL),
+ CALLBACK(CB_AVRCP_GET_ATTR_REQ),
+ ACTION_SUCCESS(avrcp_get_element_attributes_rsp, NULL),
+ CALLBACK_RC_GET_ELEMENT_ATTRIBUTES(CB_AVRCP_GET_ATTR_RSP, 2,
+ ele_attrs),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
};
struct queue *get_avrcp_tests(void)
diff --git a/android/tester-main.c b/android/tester-main.c
index a416914..515c69e 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -700,6 +700,22 @@ static bool match_data(struct step *step)
return false;
}
+ if (exp->callback_result.num_of_attrs !=
+ step->callback_result.num_of_attrs) {
+ tester_debug("Callback rc num of attrs mismatch");
+ return false;
+ }
+
+ if (exp->callback_result.attrs) {
+ if (memcmp(step->callback_result.attrs,
+ exp->callback_result.attrs,
+ exp->callback_result.num_of_attrs *
+ sizeof(btrc_element_attr_val_t))) {
+ tester_debug("Callback rc element attributes doesn't match");
+ return false;
+ }
+ }
+
if (exp->callback_result.pairing_variant !=
step->callback_result.pairing_variant) {
tester_debug("Callback pairing result mismatch: %d vs %d",
@@ -1947,10 +1963,20 @@ static void avrcp_register_notification_cb(btrc_event_id_t event_id,
schedule_callback_verification(step);
}
+static void avrcp_get_element_attr_cb(uint8_t num_attr,
+ btrc_media_attr_t *p_attrs)
+{
+ struct step *step = g_new0(struct step, 1);
+
+ step->callback = CB_AVRCP_GET_ATTR_REQ;
+ schedule_callback_verification(step);
+}
+
static btrc_callbacks_t btavrcp_callbacks = {
.size = sizeof(btavrcp_callbacks),
.get_play_status_cb = avrcp_get_play_status_cb,
.register_notification_cb = avrcp_register_notification_cb,
+ .get_element_attr_cb = avrcp_get_element_attr_cb,
};
static const btgatt_client_callbacks_t btgatt_client_callbacks = {
diff --git a/android/tester-main.h b/android/tester-main.h
index d46b262..ac310a3 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -409,6 +409,12 @@ struct pdu_set {
.callback_result.rc_index = cb_index, \
}
+#define CALLBACK_RC_GET_ELEMENT_ATTRIBUTES(cb, cb_num_of_attrs, cb_attrs) { \
+ .callback = cb, \
+ .callback_result.num_of_attrs = cb_num_of_attrs, \
+ .callback_result.attrs = cb_attrs, \
+ }
+
#define CALLBACK_DEVICE_PROPS(props, prop_cnt) \
CALLBACK_PROPS(CB_BT_REMOTE_DEVICE_PROPERTIES, props, prop_cnt)
@@ -484,6 +490,8 @@ typedef enum {
CB_AVRCP_PLAY_STATUS_RSP,
CB_AVRCP_REG_NOTIF_REQ,
CB_AVRCP_REG_NOTIF_RSP,
+ CB_AVRCP_GET_ATTR_REQ,
+ CB_AVRCP_GET_ATTR_RSP,
/* Gatt client */
CB_GATTC_REGISTER_CLIENT,
@@ -666,6 +674,8 @@ struct bt_callback_data {
uint32_t song_position;
btrc_play_status_t play_status;
uint64_t rc_index;
+ uint8_t num_of_attrs;
+ btrc_element_attr_val_t *attrs;
};
/*
--
2.1.0
---
android/tester-avrcp.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++-
android/tester-main.c | 16 ++++++++++++
android/tester-main.h | 8 ++++++
3 files changed, 93 insertions(+), 1 deletion(-)
diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
index 5a66910..06c2bd8 100644
--- a/android/tester-avrcp.c
+++ b/android/tester-avrcp.c
@@ -26,6 +26,7 @@
static struct queue *list;
#define AVRCP_GET_PLAY_STATUS 0x30
+#define AVRCP_REGISTER_NOTIFICATION 0x31
#define sdp_rsp_pdu 0x07, \
0x00, 0x00, \
@@ -81,6 +82,14 @@ static struct emu_l2cap_cid_data sdp_data = {
0x58, 0x30, 0x00, 0x00, 0x09, 0xbb, 0xbb, 0xbb, \
0xbb, 0xaa, 0xaa, 0xaa, 0xaa, 0x00
+#define req_track_notif 0x00, 0x11, 0x0e, 0x03, 0x48, 0x00, 0x00, 0x19, \
+ 0x58, 0x31, 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, \
+ 0x00, 0x00
+
+#define rsp_track_notif 0x00, 0x11, 0x0e, 0x0F, 0x48, 0x00, 0x00, 0x19, \
+ 0x58, 0x31, 0x00, 0x00, 0x09, 0x02, 0xFF, 0xFF, \
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+
static const struct pdu_set pdus[] = {
{ raw_pdu(req_dsc), raw_pdu(rsp_dsc) },
{ raw_pdu(req_get), raw_pdu(rsp_get) },
@@ -106,7 +115,7 @@ static void print_avrcp(const char *str, void *user_data)
static void avrcp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
{
struct step *step;
- uint8_t pdu;
+ uint8_t pdu, event;
util_hexdump('>', data, len, print_avrcp, NULL);
@@ -120,6 +129,15 @@ static void avrcp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
step->callback_result.play_status = ((uint8_t *) data)[21];
schedule_callback_verification(step);
break;
+ case AVRCP_REGISTER_NOTIFICATION:
+ event = ((uint8_t *) data)[13];
+ if (event == 0x02) {
+ step = g_new0(struct step, 1);
+ step->callback = CB_AVRCP_REG_NOTIF_RSP;
+ step->callback_result.rc_index = get_be64(data + 14);
+ schedule_callback_verification(step);
+ }
+ break;
}
}
@@ -229,6 +247,34 @@ static void avrcp_get_play_status_rsp(void)
schedule_action_verification(step);
}
+static void avrcp_reg_notif_track_changed_req(void)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ const struct iovec pdu = raw_pdu(req_track_notif);
+ struct step *step = g_new0(struct step, 1);
+
+ bthost_send_cid_v(bthost, avrcp_data.handle, avrcp_data.cid, &pdu, 1);
+ step->action_status = BT_STATUS_SUCCESS;
+ schedule_action_verification(step);
+}
+
+static void avrcp_reg_notif_track_changed_rsp(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *step = g_new0(struct step, 1);
+ uint64_t track;
+ btrc_register_notification_t reg;
+
+ track = 0xffffffffffffffff;
+ memcpy(reg.track, &track, sizeof(btrc_uid_t));
+ step->action_status = data->if_avrcp->register_notification_rsp(
+ BTRC_EVT_TRACK_CHANGE,
+ BTRC_NOTIFICATION_TYPE_INTERIM, ®);
+
+ schedule_action_verification(step);
+}
+
static struct test_case test_cases[] = {
TEST_CASE_BREDRLE("AVRCP Init",
ACTION_SUCCESS(dummy_action, NULL),
@@ -294,6 +340,28 @@ static struct test_case test_cases[] = {
ACTION_SUCCESS(bluetooth_disable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
),
+ TEST_CASE_BREDRLE("AVRCP RegNotifTrackChanged - Success",
+ ACTION_SUCCESS(bluetooth_enable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
+ ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
+ ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
+ ACTION_SUCCESS(set_default_ssp_request_handler, NULL),
+ ACTION_SUCCESS(emu_add_l2cap_server_action, &sdp_setup_data),
+ ACTION_SUCCESS(emu_add_l2cap_server_action, &a2dp_setup_data),
+ ACTION_SUCCESS(emu_add_l2cap_server_action, &avrcp_setup_data),
+ ACTION_SUCCESS(avrcp_connect_action, NULL),
+ CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE,
+ BTAV_CONNECTION_STATE_CONNECTING),
+ CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE,
+ BTAV_CONNECTION_STATE_CONNECTED),
+ ACTION_SUCCESS(avrcp_reg_notif_track_changed_req, NULL),
+ CALLBACK(CB_AVRCP_REG_NOTIF_REQ),
+ ACTION_SUCCESS(avrcp_reg_notif_track_changed_rsp, NULL),
+ CALLBACK_RC_REG_NOTIF_TRACK_CHANGED(CB_AVRCP_REG_NOTIF_RSP,
+ 0xffffffffffffffff),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
};
struct queue *get_avrcp_tests(void)
diff --git a/android/tester-main.c b/android/tester-main.c
index 7b1e4d8..a416914 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -694,6 +694,12 @@ static bool match_data(struct step *step)
return false;
}
+ if (exp->callback_result.rc_index !=
+ step->callback_result.rc_index) {
+ tester_debug("Callback rc_index mismatch");
+ return false;
+ }
+
if (exp->callback_result.pairing_variant !=
step->callback_result.pairing_variant) {
tester_debug("Callback pairing result mismatch: %d vs %d",
@@ -1932,9 +1938,19 @@ static void avrcp_get_play_status_cb(void)
schedule_callback_verification(step);
}
+static void avrcp_register_notification_cb(btrc_event_id_t event_id,
+ uint32_t param)
+{
+ struct step *step = g_new0(struct step, 1);
+
+ step->callback = CB_AVRCP_REG_NOTIF_REQ;
+ schedule_callback_verification(step);
+}
+
static btrc_callbacks_t btavrcp_callbacks = {
.size = sizeof(btavrcp_callbacks),
.get_play_status_cb = avrcp_get_play_status_cb,
+ .register_notification_cb = avrcp_register_notification_cb,
};
static const btgatt_client_callbacks_t btgatt_client_callbacks = {
diff --git a/android/tester-main.h b/android/tester-main.h
index 7301501..d46b262 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -404,6 +404,11 @@ struct pdu_set {
.callback_result.play_status = cb_status, \
}
+#define CALLBACK_RC_REG_NOTIF_TRACK_CHANGED(cb, cb_index) { \
+ .callback = cb, \
+ .callback_result.rc_index = cb_index, \
+ }
+
#define CALLBACK_DEVICE_PROPS(props, prop_cnt) \
CALLBACK_PROPS(CB_BT_REMOTE_DEVICE_PROPERTIES, props, prop_cnt)
@@ -477,6 +482,8 @@ typedef enum {
/* AVRCP */
CB_AVRCP_PLAY_STATUS_REQ,
CB_AVRCP_PLAY_STATUS_RSP,
+ CB_AVRCP_REG_NOTIF_REQ,
+ CB_AVRCP_REG_NOTIF_RSP,
/* Gatt client */
CB_GATTC_REGISTER_CLIENT,
@@ -658,6 +665,7 @@ struct bt_callback_data {
uint32_t song_length;
uint32_t song_position;
btrc_play_status_t play_status;
+ uint64_t rc_index;
};
/*
--
2.1.0
---
android/tester-avrcp.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++
android/tester-main.c | 33 ++++++++++++++++++++++++
android/tester-main.h | 14 ++++++++++
3 files changed, 116 insertions(+)
diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
index 192a48e..5a66910 100644
--- a/android/tester-avrcp.c
+++ b/android/tester-avrcp.c
@@ -25,6 +25,8 @@
static struct queue *list;
+#define AVRCP_GET_PLAY_STATUS 0x30
+
#define sdp_rsp_pdu 0x07, \
0x00, 0x00, \
0x00, 0x7f, \
@@ -73,6 +75,12 @@ static struct emu_l2cap_cid_data sdp_data = {
#define req_suspend 0x50, 0x09, 0x04
#define rsp_suspend 0x52, 0x09
+#define req_play_status 0x00, 0x11, 0x0e, 0x01, 0x48, 0x00, 0x00, 0x19, \
+ 0x58, 0x30, 0x00, 0x00, 0x00
+#define rsp_play_status 0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00, 0x00, 0x19, \
+ 0x58, 0x30, 0x00, 0x00, 0x09, 0xbb, 0xbb, 0xbb, \
+ 0xbb, 0xaa, 0xaa, 0xaa, 0xaa, 0x00
+
static const struct pdu_set pdus[] = {
{ raw_pdu(req_dsc), raw_pdu(rsp_dsc) },
{ raw_pdu(req_get), raw_pdu(rsp_get) },
@@ -97,7 +105,22 @@ static void print_avrcp(const char *str, void *user_data)
static void avrcp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
{
+ struct step *step;
+ uint8_t pdu;
+
util_hexdump('>', data, len, print_avrcp, NULL);
+
+ pdu = ((uint8_t *) data)[9];
+ switch (pdu) {
+ case AVRCP_GET_PLAY_STATUS:
+ step = g_new0(struct step, 1);
+ step->callback = CB_AVRCP_PLAY_STATUS_RSP;
+ step->callback_result.song_length = get_be32(data + 13);
+ step->callback_result.song_position = get_be32(data + 17);
+ step->callback_result.play_status = ((uint8_t *) data)[21];
+ schedule_callback_verification(step);
+ break;
+ }
}
static void avrcp_connect_request_cb(uint16_t handle, uint16_t cid,
@@ -129,6 +152,8 @@ static void a2dp_connect_request_cb(uint16_t handle, uint16_t cid,
cid_data->handle = handle;
cid_data->cid = cid;
+ avrcp_data.handle = handle;
+ avrcp_data.cid = cid;
tester_handle_l2cap_data_exchange(cid_data);
}
@@ -182,6 +207,28 @@ static void avrcp_disconnect_action(void)
schedule_action_verification(step);
}
+static void avrcp_get_play_status_req(void)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ const struct iovec pdu = raw_pdu(req_play_status);
+ struct step *step = g_new0(struct step, 1);
+
+ bthost_send_cid_v(bthost, avrcp_data.handle, avrcp_data.cid, &pdu, 1);
+ step->action_status = BT_STATUS_SUCCESS;
+ schedule_action_verification(step);
+}
+
+static void avrcp_get_play_status_rsp(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *step = g_new0(struct step, 1);
+
+ step->action_status = data->if_avrcp->get_play_status_rsp(0x00,
+ 0xbbbbbbbb, 0xaaaaaaaa);
+ schedule_action_verification(step);
+}
+
static struct test_case test_cases[] = {
TEST_CASE_BREDRLE("AVRCP Init",
ACTION_SUCCESS(dummy_action, NULL),
@@ -225,6 +272,28 @@ static struct test_case test_cases[] = {
ACTION_SUCCESS(bluetooth_disable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
),
+ TEST_CASE_BREDRLE("AVRCP GetPlayStatus - Success",
+ ACTION_SUCCESS(bluetooth_enable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
+ ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
+ ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
+ ACTION_SUCCESS(set_default_ssp_request_handler, NULL),
+ ACTION_SUCCESS(emu_add_l2cap_server_action, &sdp_setup_data),
+ ACTION_SUCCESS(emu_add_l2cap_server_action, &a2dp_setup_data),
+ ACTION_SUCCESS(emu_add_l2cap_server_action, &avrcp_setup_data),
+ ACTION_SUCCESS(avrcp_connect_action, NULL),
+ CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE,
+ BTAV_CONNECTION_STATE_CONNECTING),
+ CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE,
+ BTAV_CONNECTION_STATE_CONNECTED),
+ ACTION_SUCCESS(avrcp_get_play_status_req, NULL),
+ CALLBACK(CB_AVRCP_PLAY_STATUS_REQ),
+ ACTION_SUCCESS(avrcp_get_play_status_rsp, NULL),
+ CALLBACK_RC_PLAY_STATUS(CB_AVRCP_PLAY_STATUS_RSP, 0xbbbbbbbb,
+ 0xaaaaaaaa, 0x00),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
};
struct queue *get_avrcp_tests(void)
diff --git a/android/tester-main.c b/android/tester-main.c
index 8cf62c2..7b1e4d8 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -670,6 +670,30 @@ static bool match_data(struct step *step)
return false;
}
+ if (exp->callback_result.song_length !=
+ step->callback_result.song_length) {
+ tester_debug("Callback song_length mismatch: 0x%x vs 0x%x",
+ step->callback_result.song_length,
+ exp->callback_result.song_length);
+ return false;
+ }
+
+ if (exp->callback_result.song_position !=
+ step->callback_result.song_position) {
+ tester_debug("Callback song_position mismatch: 0x%x vs 0x%x",
+ step->callback_result.song_position,
+ exp->callback_result.song_position);
+ return false;
+ }
+
+ if (exp->callback_result.play_status !=
+ step->callback_result.play_status) {
+ tester_debug("Callback play_status mismatch: 0x%x vs 0x%x",
+ step->callback_result.play_status,
+ exp->callback_result.play_status);
+ return false;
+ }
+
if (exp->callback_result.pairing_variant !=
step->callback_result.pairing_variant) {
tester_debug("Callback pairing result mismatch: %d vs %d",
@@ -1900,8 +1924,17 @@ static btav_callbacks_t bta2dp_callbacks = {
.audio_state_cb = a2dp_audio_state_cb,
};
+static void avrcp_get_play_status_cb(void)
+{
+ struct step *step = g_new0(struct step, 1);
+
+ step->callback = CB_AVRCP_PLAY_STATUS_REQ;
+ schedule_callback_verification(step);
+}
+
static btrc_callbacks_t btavrcp_callbacks = {
.size = sizeof(btavrcp_callbacks),
+ .get_play_status_cb = avrcp_get_play_status_cb,
};
static const btgatt_client_callbacks_t btgatt_client_callbacks = {
diff --git a/android/tester-main.h b/android/tester-main.h
index ff6e43c..7301501 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -397,6 +397,13 @@ struct pdu_set {
.callback_result.av_audio_state = cb_av_audio_state, \
}
+#define CALLBACK_RC_PLAY_STATUS(cb, cb_length, cb_position, cb_status) { \
+ .callback = cb, \
+ .callback_result.song_length = cb_length, \
+ .callback_result.song_position = cb_position, \
+ .callback_result.play_status = cb_status, \
+ }
+
#define CALLBACK_DEVICE_PROPS(props, prop_cnt) \
CALLBACK_PROPS(CB_BT_REMOTE_DEVICE_PROPERTIES, props, prop_cnt)
@@ -467,6 +474,10 @@ typedef enum {
CB_A2DP_CONN_STATE,
CB_A2DP_AUDIO_STATE,
+ /* AVRCP */
+ CB_AVRCP_PLAY_STATUS_REQ,
+ CB_AVRCP_PLAY_STATUS_RSP,
+
/* Gatt client */
CB_GATTC_REGISTER_CLIENT,
CB_GATTC_SCAN_RESULT,
@@ -644,6 +655,9 @@ struct bt_callback_data {
btav_connection_state_t av_conn_state;
btav_audio_state_t av_audio_state;
+ uint32_t song_length;
+ uint32_t song_position;
+ btrc_play_status_t play_status;
};
/*
--
2.1.0