diff --git a/test/avrcp/avrcp.c b/test/avrcp/avrcp.c index 552eaf3c4..88d93c740 100644 --- a/test/avrcp/avrcp.c +++ b/test/avrcp/avrcp.c @@ -474,9 +474,9 @@ static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connec switch (pdu_id){ case AVRCP_PDU_ID_GET_PLAY_STATUS:{ uint32_t song_length = big_endian_read_32(packet, pos); - pos += 32; + pos += 4; uint32_t song_position = big_endian_read_32(packet, pos); - pos += 32; + pos += 4; uint8_t status = packet[pos]; printf_hexdump(packet+pos, size - pos); printf(" GET_PLAY_STATUS length 0x%04X, position 0x%04X, status %d\n", song_length, song_position, status); @@ -741,3 +741,27 @@ void avrcp_get_play_status(uint16_t con_handle){ connection->cmd_operands_lenght = 7; avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); } + +void avrcp_register_notification(uint16_t con_handle, avrcp_notification_event_id_t event_id){ + avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle); + if (!connection){ + log_error("avrcp_get_play_status: coud not find a connection."); + return; + } + if (connection->state != AVCTP_CONNECTION_OPENED) return; + connection->state = AVCTP_W2_SEND_COMMAND; + + connection->transaction_label++; + connection->cmd_to_send = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; + connection->command_type = AVRCP_CTYPE_NOTIFY; + connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; + connection->subunit_id = 0; + big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); + connection->cmd_operands[3] = AVRCP_PDU_ID_REGISTER_NOTIFICATION; + connection->cmd_operands[4] = 0; // reserved(upper 6) | packet_type -> 0 + big_endian_store_16(connection->cmd_operands, 5, 1); // parameter length + connection->cmd_operands[7] = event_id; + connection->cmd_operands_lenght = 8; + avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); + // AVRCP_SPEC_V14.pdf 166 +} diff --git a/test/avrcp/avrcp.h b/test/avrcp/avrcp.h index 6bfb63b12..63f5814b0 100644 --- a/test/avrcp/avrcp.h +++ b/test/avrcp/avrcp.h @@ -62,13 +62,20 @@ typedef enum { } avrcp_pdu_id_t; typedef enum { - AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED , - AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED, - AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED, - AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED, - AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED, - AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED -} avrcp_notification_event_t; + AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED = 0x01, // Change in playback status of the current track. + AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED = 0x02, // Change of current track + AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_END = 0x03, // Reached end of a track + AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_START = 0x04, // Reached start of a track + AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED = 0x05, // Change in playback position. Returned after the specified playback notification change notification interval + AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED = 0x06, // Change in battery status + AVRCP_NOTIFICATION_EVENT_SYSTEM_STATUS_CHANGED = 0x07, // Change in system status + AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED = 0x08, // Change in player application setting + AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED = 0x09, // The content of the Now Playing list has changed, see 6.9.5. + AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED = 0x0a, // The available players have changed, see 6.9.4. + AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED = 0x0b, // The Addressed Player has been changed, see 6.9.2. + AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED = 0x0c, // The UIDs have changed, see 6.10.3.3. + AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED = 0x0d // The volume has been changed locally on the TG, see 6.13.3. +} avrcp_notification_event_id_t; typedef enum { AVRCP_CTYPE_CONTROL = 0, @@ -283,23 +290,13 @@ void avrcp_backward(uint16_t con_handle); */ void avrcp_get_play_status(uint16_t con_handle); -/** - * @brief Register notification. - * - EVENT_PLAYBACK_STATUS_CHANGED - * - EVENT_TRACK_CHANGED - * - EVENT_NOW_PLAYING_CONTENT_CHANGED - * - EVENT_AVAILABLE_PLAYERS_CHANGED - * - EVENT_ADDRESSED_PLAYER_CHANGED - * - EVENT_VOLUME_CHANGED - * @param con_handle - */ -// void avrcp_register_notification(uint16_t con_handle); /** - * @brief Get play status. + * @brief Register notification. * @param con_handle + * @param event_id */ -// void avrcp_get_play_status(uint16_t con_handle); +void avrcp_register_notification(uint16_t con_handle, avrcp_notification_event_id_t event_id); /* API_END */ #if defined __cplusplus diff --git a/test/avrcp/avrcp_test.c b/test/avrcp/avrcp_test.c index 10acb635e..e7a2e4afa 100644 --- a/test/avrcp/avrcp_test.c +++ b/test/avrcp/avrcp_test.c @@ -59,14 +59,13 @@ static btstack_packet_callback_registration_t hci_event_callback_registration; // mac 2011: static bd_addr_t remote = {0x04, 0x0C, 0xCE, 0xE4, 0x85, 0xD3}; // pts: static bd_addr_t remote = {0x00, 0x1B, 0xDC, 0x08, 0x0A, 0xA5}; // mac 2013: static bd_addr_t remote = {0x84, 0x38, 0x35, 0x65, 0xd1, 0x15}; -// phone: static bd_addr_t remote = {0x84, 0x38, 0x35, 0x65, 0xd1, 0x15}; +// phone: static bd_addr_t remote = {0xD8, 0xBB, 0x2C, 0xDF, 0xF1, 0x08}; -// static bd_addr_t remote = {0xD8, 0xBB, 0x2C, 0xDF, 0xF1, 0x08}; +static bd_addr_t remote = {0xD8, 0xBB, 0x2C, 0xDF, 0xF1, 0x08}; static uint16_t con_handle = 0; static uint8_t sdp_avrcp_controller_service_buffer[150]; -static bd_addr_t remote = {0x84, 0x38, 0x35, 0x65, 0xd1, 0x15}; static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ UNUSED(channel); UNUSED(size); @@ -128,6 +127,7 @@ static void show_usage(void){ printf("f - avrcp_forward\n"); printf("b - avrcp_backward\n"); printf("S - get play status\n"); + printf("N - register notification, AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED\n"); printf("Ctrl-c - exit\n"); printf("---\n"); } @@ -178,6 +178,9 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac case 'S': avrcp_get_play_status(con_handle); break; + case 'N': + avrcp_register_notification(con_handle, AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED); + break; default: show_usage(); break;