1 /** @file
2  *  @brief Audio Video Control Transport Protocol internal header.
3  */
4 
5 /*
6  * Copyright (c) 2015-2016 Intel Corporation
7  * Copyright (C) 2024 Xiaomi Corporation
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #define BT_L2CAP_PSM_AVCTP 0x0017
13 
14 typedef enum __packed {
15 	BT_AVCTP_IPID_NONE = 0b0,
16 	BT_AVCTP_IPID_INVALID = 0b1,
17 } bt_avctp_ipid_t;
18 
19 typedef enum __packed {
20 	BT_AVCTP_CMD = 0b0,
21 	BT_AVCTP_RESPONSE = 0b1,
22 } bt_avctp_cr_t;
23 
24 typedef enum __packed {
25 	BT_AVCTP_PKT_TYPE_SINGLE = 0b00,
26 	BT_AVCTP_PKT_TYPE_START = 0b01,
27 	BT_AVCTP_PKT_TYPE_CONTINUE = 0b10,
28 	BT_AVCTP_PKT_TYPE_END = 0b11,
29 } bt_avctp_pkt_type_t;
30 
31 struct bt_avctp_header {
32 	uint8_t byte0; /** [7:4]: Transaction label, [3:2]: Packet_type, [1]: C/R, [0]: IPID */
33 	uint16_t pid;  /** Profile Identifier */
34 } __packed;
35 
36 /** Transaction label provided by the application and is replicated by the sender of the message in
37  *  each packet of the sequence. It isused at the receiver side to identify packets that belong to
38  *  the same message.
39  */
40 #define BT_AVCTP_HDR_GET_TRANSACTION_LABLE(hdr) FIELD_GET(GENMASK(7, 4), ((hdr)->byte0))
41 /** Set to zero (00) to indicate that the command/response message is transmitted in a single L2CAP
42  *  packet. Alternatively, set to (01) for start, (10) for continue, or (11) for end packet.
43  */
44 #define BT_AVCTP_HDR_GET_PACKET_TYPE(hdr)       FIELD_GET(GENMASK(3, 2), ((hdr)->byte0))
45 /** Indicates whether the messageconveys a command frame (0) or a response frame (1). */
46 #define BT_AVCTP_HDR_GET_CR(hdr)                FIELD_GET(BIT(1), ((hdr)->byte0))
47 /** The IPID bit is set in a response message to indicate an invalid Profile Identifier received in
48  *  the command message of the same transaction; otherwise this bit is set to zero. In command
49  *  messages this bit is set to zero. This field is only present in the start packet of the message.
50  */
51 #define BT_AVCTP_HDR_GET_IPID(hdr)              FIELD_GET(BIT(0), ((hdr)->byte0))
52 
53 /** Transaction label provided by the application and is replicated by the sender of the message in
54  *  each packet of the sequence. It isused at the receiver side to identify packets that belong to
55  *  the same message.
56  */
57 #define BT_AVCTP_HDR_SET_TRANSACTION_LABLE(hdr, tl)                                                \
58 	(hdr)->byte0 = (((hdr)->byte0) & ~GENMASK(7, 4)) | FIELD_PREP(GENMASK(7, 4), (tl))
59 /** Set to zero (00) to indicate that the command/response message is transmitted in a single L2CAP
60  *  packet. Alternatively, set to (01) for start, (10) for continue, or (11) for end packet.
61  */
62 #define BT_AVCTP_HDR_SET_PACKET_TYPE(hdr, packet_type)                                             \
63 	(hdr)->byte0 = (((hdr)->byte0) & ~GENMASK(3, 2)) | FIELD_PREP(GENMASK(3, 2), (packet_type))
64 /** Indicates whether the messageconveys a command frame (0) or a response frame (1). */
65 #define BT_AVCTP_HDR_SET_CR(hdr, cr)                                                               \
66 	(hdr)->byte0 = (((hdr)->byte0) & ~BIT(1)) | FIELD_PREP(BIT(1), (cr))
67 /** The IPID bit is set in a response message to indicate an invalid Profile Identifier received in
68  *  the command message of the same transaction; otherwise this bit is set to zero. In command
69  *  messages this bit is set to zero. This field is only present in the start packet of the message.
70  */
71 #define BT_AVCTP_HDR_SET_IPID(hdr, ipid)                                                           \
72 	(hdr)->byte0 = (((hdr)->byte0) & ~BIT(0)) | FIELD_PREP(BIT(0), (ipid))
73 
74 struct bt_avctp;
75 
76 struct bt_avctp_ops_cb {
77 	void (*connected)(struct bt_avctp *session);
78 	void (*disconnected)(struct bt_avctp *session);
79 	int (*recv)(struct bt_avctp *session, struct net_buf *buf);
80 };
81 
82 struct bt_avctp {
83 	struct bt_l2cap_br_chan br_chan;
84 	const struct bt_avctp_ops_cb *ops;
85 };
86 
87 struct bt_avctp_event_cb {
88 	int (*accept)(struct bt_conn *conn, struct bt_avctp **session);
89 };
90 
91 /* Initialize AVCTP layer*/
92 int bt_avctp_init(void);
93 
94 /* Application register with AVCTP layer */
95 int bt_avctp_register(const struct bt_avctp_event_cb *cb);
96 
97 /* AVCTP connect */
98 int bt_avctp_connect(struct bt_conn *conn, struct bt_avctp *session);
99 
100 /* AVCTP disconnect */
101 int bt_avctp_disconnect(struct bt_avctp *session);
102 
103 /* Create AVCTP PDU */
104 struct net_buf *bt_avctp_create_pdu(struct bt_avctp *session, bt_avctp_cr_t cr,
105 				    bt_avctp_pkt_type_t pkt_type, bt_avctp_ipid_t ipid,
106 				    uint8_t *tid, uint16_t pid);
107 
108 /* Send AVCTP PDU */
109 int bt_avctp_send(struct bt_avctp *session, struct net_buf *buf);
110