31
31
LOG_MODULE_REGISTER (bt_avctp );
32
32
33
33
#define AVCTP_CHAN (_ch ) CONTAINER_OF(_ch, struct bt_avctp, br_chan.chan)
34
-
35
- static const struct bt_avctp_event_cb * event_cb ;
34
+ /* L2CAP Server list */
35
+ static sys_slist_t avctp_l2cap_server = SYS_SLIST_STATIC_INIT (& avctp_l2cap_server );
36
+ static struct k_sem avctp_server_lock ;
36
37
37
38
static void avctp_l2cap_connected (struct bt_l2cap_chan * chan )
38
39
{
@@ -80,7 +81,6 @@ static int avctp_l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
80
81
struct bt_avctp * session = AVCTP_CHAN (chan );
81
82
struct bt_avctp_header * hdr = (void * )buf -> data ;
82
83
uint8_t tid ;
83
- bt_avctp_pkt_type_t pkt_type ;
84
84
bt_avctp_cr_t cr ;
85
85
int err ;
86
86
@@ -90,46 +90,34 @@ static int avctp_l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
90
90
}
91
91
92
92
tid = BT_AVCTP_HDR_GET_TRANSACTION_LABLE (hdr );
93
- pkt_type = BT_AVCTP_HDR_GET_PACKET_TYPE (hdr );
94
93
cr = BT_AVCTP_HDR_GET_CR (hdr );
95
94
96
- switch (pkt_type ) {
97
- case BT_AVCTP_PKT_TYPE_SINGLE :
98
- break ;
99
- case BT_AVCTP_PKT_TYPE_START :
100
- case BT_AVCTP_PKT_TYPE_CONTINUE :
101
- case BT_AVCTP_PKT_TYPE_END :
102
- default :
103
- LOG_ERR ("fragmented AVCTP message is not supported, pkt_type = %d" , pkt_type );
104
- return - EINVAL ;
95
+ LOG_DBG ("AVCTP msg received, cr:0x%X, tid:0x%X, pid: 0x%04X" ,
96
+ cr , tid , sys_be16_to_cpu (hdr -> pid ));
97
+
98
+ if (sys_be16_to_cpu (hdr -> pid ) == session -> pid ) {
99
+ return session -> ops -> recv (session , buf );
105
100
}
106
101
107
- switch (hdr -> pid ) {
108
- #if defined(CONFIG_BT_AVRCP )
109
- case sys_cpu_to_be16 (BT_SDP_AV_REMOTE_SVCLASS ):
110
- break ;
111
- #endif
112
- default :
113
- LOG_ERR ("unsupported AVCTP PID received: 0x%04x" , sys_be16_to_cpu (hdr -> pid ));
114
- if (cr == BT_AVCTP_CMD ) {
115
- rsp = bt_avctp_create_pdu (session , BT_AVCTP_RESPONSE ,
116
- BT_AVCTP_PKT_TYPE_SINGLE , BT_AVCTP_IPID_INVALID ,
117
- tid , hdr -> pid );
118
- if (!rsp ) {
119
- return - ENOMEM ;
120
- }
121
-
122
- err = bt_avctp_send (session , rsp );
123
- if (err < 0 ) {
124
- net_buf_unref (rsp );
125
- LOG_ERR ("AVCTP send fail, err = %d" , err );
126
- return err ;
127
- }
102
+ LOG_ERR ("unsupported AVCTP PID received: 0x%04x" , sys_be16_to_cpu (hdr -> pid ));
103
+ if (cr == BT_AVCTP_CMD ) {
104
+ rsp = bt_avctp_create_pdu (session , BT_AVCTP_RESPONSE ,
105
+ BT_AVCTP_PKT_TYPE_SINGLE , BT_AVCTP_IPID_INVALID ,
106
+ tid , hdr -> pid );
107
+ if (rsp == NULL ) {
108
+ __ASSERT (0 , "Failed to create AVCTP response PDU" );
109
+ return - ENOMEM ;
128
110
}
129
- return 0 ; /* No need to report to the upper layer */
130
- }
131
111
132
- return session -> ops -> recv (session , buf );
112
+ err = bt_avctp_send (session , rsp );
113
+ if (err < 0 ) {
114
+ net_buf_unref (rsp );
115
+ LOG_ERR ("AVCTP send fail, err = %d" , err );
116
+ bt_avctp_disconnect (session );
117
+ return err ;
118
+ }
119
+ }
120
+ return 0 ; /* No need to report to the upper layer */
133
121
}
134
122
135
123
static const struct bt_l2cap_chan_ops ops = {
@@ -139,17 +127,14 @@ static const struct bt_l2cap_chan_ops ops = {
139
127
.recv = avctp_l2cap_recv ,
140
128
};
141
129
142
- int bt_avctp_connect (struct bt_conn * conn , struct bt_avctp * session )
130
+ int bt_avctp_connect (struct bt_conn * conn , uint16_t psm , struct bt_avctp * session )
143
131
{
144
132
if (!session ) {
145
133
return - EINVAL ;
146
134
}
147
135
148
- session -> br_chan .rx .mtu = BT_L2CAP_RX_MTU ;
149
136
session -> br_chan .chan .ops = & ops ;
150
- session -> br_chan .required_sec_level = BT_SECURITY_L2 ;
151
-
152
- return bt_l2cap_chan_connect (conn , & session -> br_chan .chan , BT_L2CAP_PSM_AVCTP );
137
+ return bt_l2cap_chan_connect (conn , & session -> br_chan .chan , psm );
153
138
}
154
139
155
140
int bt_avctp_disconnect (struct bt_avctp * session )
@@ -163,6 +148,19 @@ int bt_avctp_disconnect(struct bt_avctp *session)
163
148
return bt_l2cap_chan_disconnect (& session -> br_chan .chan );
164
149
}
165
150
151
+ void bt_avctp_set_header (struct bt_avctp_header * avctp_hdr , bt_avctp_cr_t cr ,
152
+ bt_avctp_pkt_type_t pkt_type , bt_avctp_ipid_t ipid ,
153
+ uint8_t tid , uint16_t pid )
154
+ {
155
+ LOG_DBG ("" );
156
+
157
+ BT_AVCTP_HDR_SET_TRANSACTION_LABLE (avctp_hdr , tid );
158
+ BT_AVCTP_HDR_SET_PACKET_TYPE (avctp_hdr , pkt_type );
159
+ BT_AVCTP_HDR_SET_CR (avctp_hdr , cr );
160
+ BT_AVCTP_HDR_SET_IPID (avctp_hdr , ipid );
161
+ avctp_hdr -> pid = pid ;
162
+ }
163
+
166
164
struct net_buf * bt_avctp_create_pdu (struct bt_avctp * session , bt_avctp_cr_t cr ,
167
165
bt_avctp_pkt_type_t pkt_type , bt_avctp_ipid_t ipid ,
168
166
uint8_t tid , uint16_t pid )
@@ -179,11 +177,7 @@ struct net_buf *bt_avctp_create_pdu(struct bt_avctp *session, bt_avctp_cr_t cr,
179
177
}
180
178
181
179
hdr = net_buf_add (buf , sizeof (* hdr ));
182
- BT_AVCTP_HDR_SET_TRANSACTION_LABLE (hdr , tid );
183
- BT_AVCTP_HDR_SET_PACKET_TYPE (hdr , pkt_type );
184
- BT_AVCTP_HDR_SET_CR (hdr , cr );
185
- BT_AVCTP_HDR_SET_IPID (hdr , ipid );
186
- hdr -> pid = pid ;
180
+ bt_avctp_set_header (hdr , cr , pkt_type , ipid , tid , pid );
187
181
188
182
LOG_DBG ("cr:0x%lX, tid:0x%02lX" , BT_AVCTP_HDR_GET_CR (hdr ),
189
183
BT_AVCTP_HDR_GET_TRANSACTION_LABLE (hdr ));
@@ -195,63 +189,78 @@ int bt_avctp_send(struct bt_avctp *session, struct net_buf *buf)
195
189
return bt_l2cap_chan_send (& session -> br_chan .chan , buf );
196
190
}
197
191
198
- int bt_avctp_register (const struct bt_avctp_event_cb * cb )
199
- {
200
- LOG_DBG ("" );
201
-
202
- if (event_cb ) {
203
- return - EALREADY ;
204
- }
205
-
206
- event_cb = cb ;
207
-
208
- return 0 ;
209
- }
210
-
211
192
static int avctp_l2cap_accept (struct bt_conn * conn , struct bt_l2cap_server * server ,
212
193
struct bt_l2cap_chan * * chan )
213
194
{
214
195
struct bt_avctp * session = NULL ;
196
+ struct bt_avctp_server * avctp_server ;
215
197
int err ;
216
198
217
199
LOG_DBG ("conn %p" , conn );
218
200
219
- if (!event_cb ) {
220
- LOG_WRN ("AVCTP server is unsupported" );
221
- return - ENOTSUP ;
201
+ avctp_server = CONTAINER_OF (server , struct bt_avctp_server , l2cap );
202
+
203
+ k_sem_take (& avctp_server_lock , K_FOREVER );
204
+
205
+ if (!sys_slist_find (& avctp_l2cap_server , & avctp_server -> node , NULL )) {
206
+ LOG_WRN ("Invalid l2cap server" );
207
+ k_sem_give (& avctp_server_lock );
208
+ return - EINVAL ;
222
209
}
223
210
211
+ k_sem_give (& avctp_server_lock );
212
+
224
213
/* Get the AVCTP session from upper layer */
225
- err = event_cb -> accept (conn , & session );
214
+ err = avctp_server -> accept (conn , & session );
226
215
if (err < 0 ) {
227
- LOG_ERR ("Get the AVCTP session failed %d" , err );
216
+ LOG_ERR ("Incoming connection rejected" );
228
217
return err ;
229
218
}
230
219
231
- session -> br_chan .rx .mtu = BT_L2CAP_RX_MTU ;
232
- session -> br_chan .psm = BT_L2CAP_PSM_AVCTP ;
233
220
session -> br_chan .chan .ops = & ops ;
234
221
* chan = & session -> br_chan .chan ;
235
222
236
223
return 0 ;
237
224
}
238
225
239
- int bt_avctp_init ( void )
226
+ int bt_avctp_server_register ( struct bt_avctp_server * server )
240
227
{
241
228
int err ;
242
- static struct bt_l2cap_server avctp_l2cap = {
243
- .psm = BT_L2CAP_PSM_AVCTP ,
244
- .sec_level = BT_SECURITY_L2 ,
245
- .accept = avctp_l2cap_accept ,
246
- };
247
-
248
229
LOG_DBG ("" );
249
230
250
- /* Register AVCTP PSM with L2CAP */
251
- err = bt_l2cap_br_server_register (& avctp_l2cap );
231
+ if ((server == NULL ) || (server -> accept == NULL )) {
232
+ LOG_DBG ("Invalid parameter" );
233
+ return - EINVAL ;
234
+ }
235
+
236
+ k_sem_take (& avctp_server_lock , K_FOREVER );
237
+
238
+ if (sys_slist_find (& avctp_l2cap_server , & server -> node , NULL )) {
239
+ LOG_WRN ("L2CAP server has been registered" );
240
+ k_sem_give (& avctp_server_lock );
241
+ return - EEXIST ;
242
+ }
243
+
244
+ server -> l2cap .accept = avctp_l2cap_accept ;
245
+ err = bt_l2cap_br_server_register (& server -> l2cap );
252
246
if (err < 0 ) {
253
247
LOG_ERR ("AVCTP L2CAP registration failed %d" , err );
248
+ k_sem_give (& avctp_server_lock );
249
+ return err ;
254
250
}
255
251
252
+ LOG_DBG ("Register L2CAP server %p" , server );
253
+ sys_slist_append (& avctp_l2cap_server , & server -> node );
254
+
255
+ k_sem_give (& avctp_server_lock );
256
+
256
257
return err ;
257
258
}
259
+
260
+ int bt_avctp_init (void )
261
+ {
262
+ LOG_DBG ("Initializing AVCTP" );
263
+ /* Locking semaphore initialized to 1 (unlocked) */
264
+ k_sem_init (& avctp_server_lock , 1 , 1 );
265
+ return 0 ;
266
+ }
0 commit comments