From 0da74a1afc2aec08ec225c925c78a2f6305f0418 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 26 Feb 2014 17:14:29 +0200 Subject: [PATCH] unit/avrcp: Add /TP/CFG/BV-02-C test Test verifies that the Target responds to Get Capability request. --- android/avrcp-lib.c | 16 ------------ android/avrcp-lib.h | 31 ++++++++++++++++++++++++ unit/test-avrcp.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 16 deletions(-) diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c index e620af546..05d651c7a 100644 --- a/android/avrcp-lib.c +++ b/android/avrcp-lib.c @@ -39,28 +39,12 @@ /* Company IDs for vendor dependent commands */ #define IEEEID_BTSIG 0x001958 -/* Status codes */ -#define AVRCP_STATUS_INVALID_COMMAND 0x00 -#define AVRCP_STATUS_INVALID_PARAM 0x01 -#define AVRCP_STATUS_PARAM_NOT_FOUND 0x02 -#define AVRCP_STATUS_INTERNAL_ERROR 0x03 -#define AVRCP_STATUS_SUCCESS 0x04 -#define AVRCP_STATUS_OUT_OF_BOUNDS 0x0b -#define AVRCP_STATUS_INVALID_PLAYER_ID 0x11 -#define AVRCP_STATUS_PLAYER_NOT_BROWSABLE 0x12 -#define AVRCP_STATUS_NO_AVAILABLE_PLAYERS 0x15 -#define AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED 0x16 - /* Packet types */ #define AVRCP_PACKET_TYPE_SINGLE 0x00 #define AVRCP_PACKET_TYPE_START 0x01 #define AVRCP_PACKET_TYPE_CONTINUING 0x02 #define AVRCP_PACKET_TYPE_END 0x03 -/* Capabilities for AVRCP_GET_CAPABILITIES pdu */ -#define CAP_COMPANY_ID 0x02 -#define CAP_EVENTS_SUPPORTED 0x03 - #if __BYTE_ORDER == __LITTLE_ENDIAN struct avrcp_header { diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h index f7276327c..75802b9ce 100644 --- a/android/avrcp-lib.h +++ b/android/avrcp-lib.h @@ -46,6 +46,37 @@ #define AVRCP_ADD_TO_NOW_PLAYING 0x90 #define AVRCP_GENERAL_REJECT 0xA0 +/* Notification events */ +#define AVRCP_EVENT_STATUS_CHANGED 0x01 +#define AVRCP_EVENT_TRACK_CHANGED 0x02 +#define AVRCP_EVENT_TRACK_REACHED_END 0x03 +#define AVRCP_EVENT_TRACK_REACHED_START 0x04 +#define AVRCP_EVENT_SETTINGS_CHANGED 0x08 +#define AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED 0x0a +#define AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED 0x0b +#define AVRCP_EVENT_UIDS_CHANGED 0x0c +#define AVRCP_EVENT_VOLUME_CHANGED 0x0d +#define AVRCP_EVENT_LAST AVRCP_EVENT_VOLUME_CHANGED + +/* Status codes */ +#define AVRCP_STATUS_INVALID_COMMAND 0x00 +#define AVRCP_STATUS_INVALID_PARAM 0x01 +#define AVRCP_STATUS_PARAM_NOT_FOUND 0x02 +#define AVRCP_STATUS_INTERNAL_ERROR 0x03 +#define AVRCP_STATUS_SUCCESS 0x04 +#define AVRCP_STATUS_OUT_OF_BOUNDS 0x0b +#define AVRCP_STATUS_INVALID_PLAYER_ID 0x11 +#define AVRCP_STATUS_PLAYER_NOT_BROWSABLE 0x12 +#define AVRCP_STATUS_NO_AVAILABLE_PLAYERS 0x15 +#define AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED 0x16 + +/* Capabilities for AVRCP_GET_CAPABILITIES pdu */ +#define CAP_COMPANY_ID 0x02 +#define CAP_EVENTS_SUPPORTED 0x03 + +/* Company IDs for vendor dependent commands */ +#define IEEEID_BTSIG 0x001958 + struct avrcp; struct avrcp_control_handler { diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c index 2906ca296..bcd8f88dc 100644 --- a/unit/test-avrcp.c +++ b/unit/test-avrcp.c @@ -93,6 +93,26 @@ struct context { g_test_add_data_func(name, &data, function); \ } while (0) +#if __BYTE_ORDER == __LITTLE_ENDIAN + +static inline void hton24(uint8_t dst[3], uint32_t src) +{ + dst[0] = (src >> 16) & 0xff; + dst[1] = (src >> 8) & 0xff; + dst[2] = src & 0xff; +} + +#elif __BYTE_ORDER == __BIG_ENDIAN + +static inline void hton24(uint8_t dst[3], uint32_t src) +{ + memcpy(&dst, src, sizeof(dst)); +} + +#else +#error "Unknown byte order" +#endif + static void test_debug(const char *str, void *user_data) { const char *prefix = user_data; @@ -285,12 +305,43 @@ static const struct avrcp_passthrough_handler passthrough_handlers[] = { { }, }; +static uint8_t avrcp_handle_get_capabilities(struct avrcp *session, + uint8_t transaction, uint16_t *params_len, + uint8_t *params, void *user_data) +{ + uint32_t id = 0x001958; + + if (*params_len != 1) + goto fail; + + switch (params[0]) { + case CAP_COMPANY_ID: + *params_len = 5; + params[1] = 1; + hton24(¶ms[2], id); + return AVC_CTYPE_STABLE; + } + +fail: + *params_len = htons(1); + params[0] = AVRCP_STATUS_INVALID_PARAM; + + return AVC_CTYPE_REJECTED; +} + +static const struct avrcp_control_handler control_handlers[] = { + { AVRCP_GET_CAPABILITIES, AVC_CTYPE_STATUS, + avrcp_handle_get_capabilities }, + { }, +}; + static void test_server(gconstpointer data) { struct context *context = create_context(0x0100, data); avrcp_set_passthrough_handlers(context->session, passthrough_handlers, context); + avrcp_set_control_handlers(context->session, control_handlers, NULL); g_idle_add(send_pdu, context); @@ -381,5 +432,13 @@ int main(int argc, char *argv[]) 0x00, 0x19, 0x58, 0x10, 0x00, 0x00, 0x01, 0x03)); + define_test("/TP/CFG/BV-02-C", test_server, + raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00, + 0x00, 0x19, 0x58, 0x10, 0x00, 0x00, + 0x01, 0x02), + raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00, + 0x00, 0x19, 0x58, 0x10, 0x00, 0x00, + 0x05, 0x02, 0x01, 0x00, 0x19, 0x58)); + return g_test_run(); } -- 2.47.3