blob: 6d4e329da812717e121c92323dfca244cb143940 [file] [log] [blame]
/** @file
* @brief Audio Video Remote Control Profile internal header.
*/
/*
* Copyright (c) 2015-2016 Intel Corporation
* Copyright (C) 2024 Xiaomi Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#define AVCTP_VER_1_4 (0x0104u)
#define AVRCP_VER_1_6 (0x0106u)
#define AVRCP_CAT_1 BIT(0) /* Player/Recorder */
#define AVRCP_CAT_2 BIT(1) /* Monitor/Amplifier */
#define AVRCP_CAT_3 BIT(2) /* Tuner */
#define AVRCP_CAT_4 BIT(3) /* Menu */
#define AVRCP_SUBUNIT_PAGE (0) /* Fixed value according to AVRCP */
#define AVRCP_SUBUNIT_EXTENSION_CODE (7) /* Fixed value according to TA Document 2001012 */
typedef enum __packed {
BT_AVRCP_SUBUNIT_ID_ZERO = 0x0,
BT_AVRCP_SUBUNIT_ID_IGNORE = 0x7,
} bt_avrcp_subunit_id_t;
typedef enum __packed {
BT_AVRCP_SUBUNIT_TYPE_PANEL = 0x9,
BT_AVRCP_SUBUNIT_TYPE_UNIT = 0x1F,
} bt_avrcp_subunit_type_t;
typedef enum __packed {
BT_AVRCP_OPC_VENDOR_DEPENDENT = 0x0,
BT_AVRCP_OPC_UNIT_INFO = 0x30,
BT_AVRCP_OPC_SUBUNIT_INFO = 0x31,
BT_AVRCP_OPC_PASS_THROUGH = 0x7c,
} bt_avrcp_opcode_t;
typedef enum __packed {
BT_AVRVP_PKT_TYPE_SINGLE = 0b00,
BT_AVRVP_PKT_TYPE_START = 0b01,
BT_AVRVP_PKT_TYPE_CONTINUE = 0b10,
BT_AVRVP_PKT_TYPE_END = 0b11,
} bt_avrcp_pkt_type_t;
typedef enum __packed {
/** Capabilities */
BT_AVRCP_PDU_ID_GET_CAPS = 0x10,
/** Player Application Settings */
BT_AVRCP_PDU_ID_LIST_PLAYER_APP_SETTING_ATTRS = 0x11,
BT_AVRCP_PDU_ID_LIST_PLAYER_APP_SETTING_VALS = 0x12,
BT_AVRCP_PDU_ID_GET_CURR_PLAYER_APP_SETTING_VAL = 0x13,
BT_AVRCP_PDU_ID_SET_PLAYER_APP_SETTING_VAL = 0x14,
BT_AVRCP_PDU_ID_GET_PLAYER_APP_SETTING_ATTR_TEXT = 0x15,
BT_AVRCP_PDU_ID_GET_PLAYER_APP_SETTING_VAL_TEXT = 0x16,
BT_AVRCP_PDU_ID_INFORM_DISPLAYABLE_CHAR_SET = 0x17,
BT_AVRCP_PDU_ID_INFORM_BATT_STATUS_OF_CT = 0x18,
/** Metadata Attributes for Current Media Item */
BT_AVRCP_PDU_ID_GET_ELEMENT_ATTRS = 0x20,
/** Notifications */
BT_AVRCP_PDU_ID_GET_PLAY_STATUS = 0x30,
BT_AVRCP_PDU_ID_REGISTER_NOTIFICATION = 0x31,
BT_AVRCP_PDU_ID_EVT_PLAYBACK_STATUS_CHANGED = 0x31,
BT_AVRCP_PDU_ID_EVT_TRACK_CHANGED = 0x31,
BT_AVRCP_PDU_ID_EVT_TRACK_REACHED_END = 0x31,
BT_AVRCP_PDU_ID_EVT_TRACK_REACHED_START = 0x31,
BT_AVRCP_PDU_ID_EVT_PLAYBACK_POS_CHANGED = 0x31,
BT_AVRCP_PDU_ID_EVT_BATT_STATUS_CHANGED = 0x31,
BT_AVRCP_PDU_ID_EVT_SYSTEM_STATUS_CHANGED = 0x31,
BT_AVRCP_PDU_ID_EVT_PLAYER_APP_SETTING_CHANGED = 0x31,
BT_AVRCP_PDU_ID_EVT_VOLUME_CHANGED = 0x31,
BT_AVRCP_PDU_ID_EVT_ADDRESSED_PLAYER_CHANGED = 0x31,
BT_AVRCP_PDU_ID_EVT_AVAILABLE_PLAYERS_CHANGED = 0x31,
BT_AVRCP_PDU_ID_EVT_UIDS_CHANGED = 0x31,
/** Continuation */
BT_AVRCP_PDU_ID_REQ_CONTINUING_RSP = 0x40,
BT_AVRCP_PDU_ID_ABORT_CONTINUING_RSP = 0x41,
/** Absolute Volume */
BT_AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME = 0x50,
/** Media Player Selection */
BT_AVRCP_PDU_ID_SET_ADDRESSED_PLAYER = 0x60,
/** Browsing */
BT_AVRCP_PDU_ID_SET_BROWSED_PLAYER = 0x70,
BT_AVRCP_PDU_ID_GET_FOLDER_ITEMS = 0x71,
BT_AVRCP_PDU_ID_CHANGE_PATH = 0x72,
BT_AVRCP_PDU_ID_GET_ITEM_ATTRS = 0x73,
BT_AVRCP_PDU_ID_PLAY_ITEM = 0x74,
BT_AVRCP_PDU_ID_GET_TOTAL_NUMBER_OF_ITEMS = 0x75,
/** Search */
BT_AVRCP_PDU_ID_SEARCH = 0x80,
/** Now Playing */
BT_AVRCP_PDU_ID_ADD_TO_NOW_PLAYING = 0x90,
/** Error Response */
BT_AVRCP_PDU_ID_GENERAL_REJECT = 0xa0,
} bt_avrcp_pdu_id_t;
struct bt_avrcp_req {
uint8_t tid;
uint8_t subunit;
uint8_t opcode;
};
struct bt_avrcp_header {
uint8_t byte0; /**< [7:4]: RFA, [3:0]: Ctype */
uint8_t byte1; /**< [7:3]: Subunit_type, [2:0]: Subunit_ID */
uint8_t opcode; /**< Unit Info, Subunit Info, Vendor Dependent, or Pass Through */
} __packed;
struct bt_avrcp_avc_pdu {
uint8_t pdu_id;
uint8_t pkt_type; /**< [7:2]: Reserved, [1:0]: Packet Type */
uint16_t param_len;
uint8_t param[];
} __packed;
/** The 4-bit command type or the 4-bit response code. */
#define BT_AVRCP_HDR_GET_CTYPE_OR_RSP(hdr) FIELD_GET(GENMASK(3, 0), ((hdr)->byte0))
/** Taken together, the subunit_type and subunit_ID fields define the command recipient’s address
* within the target. These fields enable the target to determine whether the command is
* addressed to the target unit, or to a specific subunit within the target. The values in these
* fields remain unchanged in the response frame.
*/
#define BT_AVRCP_HDR_GET_SUBUNIT_ID(hdr) FIELD_GET(GENMASK(2, 0), ((hdr)->byte1))
/** Taken together, the subunit_type and subunit_ID fields define the command recipient’s address
* within the target. These fields enable the target to determine whether the command is
* addressed to the target unit, or to a specific subunit within the target. The values in these
* fields remain unchanged in the response frame.
*/
#define BT_AVRCP_HDR_GET_SUBUNIT_TYPE(hdr) FIELD_GET(GENMASK(7, 3), ((hdr)->byte1))
/** The 4-bit command type or the 4-bit response code. */
#define BT_AVRCP_HDR_SET_CTYPE_OR_RSP(hdr, ctype) \
(hdr)->byte0 = (((hdr)->byte0) & ~GENMASK(3, 0)) | FIELD_PREP(GENMASK(3, 0), (ctype))
/** Taken together, the subunit_type and subunit_ID fields define the command recipient’s address
* within the target. These fields enable the target to determine whether the command is
* addressed to the target unit, or to a specific subunit within the target. The values in these
* fields remain unchanged in the response frame.
*/
#define BT_AVRCP_HDR_SET_SUBUNIT_ID(hdr, subunit_id) \
(hdr)->byte1 = (((hdr)->byte1) & ~GENMASK(2, 0)) | FIELD_PREP(GENMASK(2, 0), (subunit_id))
/** Taken together, the subunit_type and subunit_ID fields define the command recipient’s address
* within the target. These fields enable the target to determine whether the command is
* addressed to the target unit, or to a specific subunit within the target. The values in these
* fields remain unchanged in the response frame.
*/
#define BT_AVRCP_HDR_SET_SUBUNIT_TYPE(hdr, subunit_type) \
(hdr)->byte1 = (((hdr)->byte1) & ~GENMASK(7, 3)) | FIELD_PREP(GENMASK(7, 3), (subunit_type))
/** The Packet Type field qualifies each packet as either start (Packet Type=01), continue
* (Packet Type=10), or end packet (Packet Type=11). In the case of a non-fragmented message, this
* field (Packet Type=00) simply indicates that the message is sent in a single AV/C frame.
*/
#define BT_AVRCP_AVC_PDU_GET_PACKET_TYPE(pdu) FIELD_GET(GENMASK(1, 0), ((pdu)->pkt_type))
/** The Packet Type field qualifies each packet as either start (Packet Type=01), continue
* (Packet Type=10), or end packet (Packet Type=11). In the case of a non-fragmented message, this
* field (Packet Type=00) simply indicates that the message is sent in a single AV/C frame.
*/
#define BT_AVRCP_AVC_PDU_SET_PACKET_TYPE(pdu, packet_type) \
(pdu)->pkt_type = FIELD_PREP(GENMASK(1, 0), (packet_type))
struct bt_avrcp_frame {
struct bt_avrcp_header hdr;
uint8_t data[];
} __packed;
int bt_avrcp_init(void);