1 /*
2 * Copyright (C) 2016 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holders nor the names of
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * 4. Any redistribution, use, or modification is done solely for
17 * personal benefit and not for any commercial purpose or for
18 * monetary gain.
19 *
20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Please inquire about commercial licensing options at
34 * [email protected]
35 *
36 */
37 #define BTSTACK_FILE__ "avdtp_acceptor.c"
38
39 #include <stdint.h>
40 #include <string.h>
41
42 #include "classic/avdtp.h"
43 #include "classic/avdtp_util.h"
44 #include "classic/avdtp_acceptor.h"
45
46 #include "btstack_debug.h"
47 #include "btstack_util.h"
48 #include "l2cap.h"
49
50
avdtp_acceptor_send_accept_response(uint16_t cid,uint8_t transaction_label,avdtp_signal_identifier_t identifier)51 static int avdtp_acceptor_send_accept_response(uint16_t cid, uint8_t transaction_label, avdtp_signal_identifier_t identifier){
52 uint8_t command[2];
53 command[0] = avdtp_header(transaction_label, AVDTP_SINGLE_PACKET, AVDTP_RESPONSE_ACCEPT_MSG);
54 command[1] = (uint8_t)identifier;
55 return l2cap_send(cid, command, sizeof(command));
56 }
57
58 // returns true if command complete
avdtp_acceptor_process_chunk(avdtp_signaling_packet_t * signaling_packet,uint8_t * packet,uint16_t size)59 static bool avdtp_acceptor_process_chunk(avdtp_signaling_packet_t * signaling_packet, uint8_t * packet, uint16_t size){
60 if ((signaling_packet->size + size) >= sizeof(signaling_packet->command)) {
61 log_info("Dropping incoming data, doesn't fit into command buffer");
62 signaling_packet->size = 0;
63 return false;
64 }
65
66 (void)memcpy(signaling_packet->command + signaling_packet->size, packet, size);
67 signaling_packet->size += size;
68 return (signaling_packet->packet_type == AVDTP_SINGLE_PACKET) || (signaling_packet->packet_type == AVDTP_END_PACKET);
69 }
70
avdtp_acceptor_validate_msg_length(avdtp_signal_identifier_t signal_identifier,uint16_t header_size,uint16_t msg_size)71 static int avdtp_acceptor_validate_msg_length(avdtp_signal_identifier_t signal_identifier, uint16_t header_size, uint16_t msg_size){
72 // payload length is num bytes after header (incl. signaling identifier), e.g. 1 for Get Capabilities
73 int minimal_payload_length;
74 switch (signal_identifier){
75 case AVDTP_SI_GET_CAPABILITIES:
76 case AVDTP_SI_GET_ALL_CAPABILITIES:
77 case AVDTP_SI_GET_CONFIGURATION:
78 case AVDTP_SI_RECONFIGURE:
79 case AVDTP_SI_OPEN:
80 case AVDTP_SI_START:
81 case AVDTP_SI_CLOSE:
82 case AVDTP_SI_ABORT:
83 case AVDTP_SI_SECURITY_CONTROL:
84 minimal_payload_length = 1;
85 break;
86 case AVDTP_SI_SET_CONFIGURATION:
87 minimal_payload_length = 2;
88 break;
89 case AVDTP_SI_DELAYREPORT:
90 minimal_payload_length = 3;
91 break;
92 case AVDTP_SI_DISCOVER:
93 default:
94 minimal_payload_length = 0;
95 break;
96 }
97 return msg_size >= (header_size + minimal_payload_length);
98 }
99
100 static void
avdtp_acceptor_handle_configuration_command(avdtp_connection_t * connection,int offset,uint16_t packet_size,avdtp_stream_endpoint_t * stream_endpoint)101 avdtp_acceptor_handle_configuration_command(avdtp_connection_t *connection, int offset, uint16_t packet_size, avdtp_stream_endpoint_t *stream_endpoint) {
102 log_info("W2_ANSWER_SET_CONFIGURATION cid 0x%02x", connection->avdtp_cid);
103 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_CONFIGURATION_SUBSTATEMACHINE;
104 stream_endpoint->connection = connection;
105
106 // process capabilities, first rejected service category is stored in connection
107 connection->reject_service_category = 0;
108 avdtp_sep_t sep;
109 sep.seid = connection->acceptor_signaling_packet.command[offset++] >> 2;
110 sep.configured_service_categories = avdtp_unpack_service_capabilities(connection, connection->acceptor_signaling_packet.signal_identifier, &sep.configuration, connection->acceptor_signaling_packet.command+offset, packet_size-offset);
111 sep.in_use = 1;
112
113 // test if sep already in use
114 if (stream_endpoint->sep.in_use != 0){
115 log_info("stream endpoint already in use");
116 connection->error_code = AVDTP_ERROR_CODE_SEP_IN_USE;
117 connection->reject_service_category = 0;
118 }
119
120 // let application validate media configuration as well
121 if (connection->error_code == 0){
122 if ((sep.configured_service_categories & (1 << AVDTP_MEDIA_CODEC)) != 0){
123 const adtvp_media_codec_capabilities_t * media = &sep.configuration.media_codec;
124 uint8_t error_code = avdtp_validate_media_configuration(stream_endpoint, connection->avdtp_cid, 0, media);
125 if (error_code != 0){
126 log_info("media codec rejected by validator, error 0x%02x", error_code);
127 connection->reject_service_category = AVDTP_MEDIA_CODEC;
128 connection->error_code = error_code;
129 }
130 }
131 }
132
133 if (connection->error_code){
134 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
135 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
136 return;
137 }
138
139 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ACCEPT_SET_CONFIGURATION;
140 // find or add sep
141
142 log_info("local seid %d, remote seid %d", connection->acceptor_local_seid, sep.seid);
143
144 if (is_avdtp_remote_seid_registered(stream_endpoint)){
145 if (stream_endpoint->remote_sep.in_use){
146 log_info("remote seid already in use");
147 connection->error_code = AVDTP_ERROR_CODE_SEP_IN_USE;
148 // find first registered category and fire the error
149 connection->reject_service_category = 0;
150 int i;
151 for (i = 1; i < 9; i++){
152 if (get_bit16(sep.configured_service_categories, i)){
153 connection->reject_service_category = i;
154 break;
155 }
156 }
157 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
158 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
159 return;
160 } else {
161 stream_endpoint->remote_sep = sep;
162 log_info("update remote seid %d", stream_endpoint->remote_sep.seid);
163 }
164 } else {
165 // add new
166 stream_endpoint->remote_sep = sep;
167 log_info("add remote seid %d", stream_endpoint->remote_sep.seid);
168 }
169
170 // mark as in_use
171 stream_endpoint->sep.in_use = 1;
172
173 // if media codec configuration set, copy configuration and emit event
174 if ((sep.configured_service_categories & (1 << AVDTP_MEDIA_CODEC)) != 0){
175 if (stream_endpoint->media_codec_configuration_len == sep.configuration.media_codec.media_codec_information_len){
176 (void) memcpy(stream_endpoint->media_codec_configuration_info, sep.configuration.media_codec.media_codec_information, stream_endpoint->media_codec_configuration_len);
177 // update media codec info to point to user configuration
178 stream_endpoint->remote_sep.configuration.media_codec.media_codec_information = stream_endpoint->media_codec_configuration_info;
179 // emit event
180 avdtp_signaling_emit_configuration(stream_endpoint, connection->avdtp_cid, 0, &sep.configuration, sep.configured_service_categories);
181 }
182 }
183
184 avdtp_signaling_emit_accept(connection->avdtp_cid, avdtp_local_seid(stream_endpoint),
185 connection->acceptor_signaling_packet.signal_identifier, false);
186 }
187
avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection,uint8_t * packet,uint16_t size,int offset)188 void avdtp_acceptor_stream_config_subsm(avdtp_connection_t *connection, uint8_t *packet, uint16_t size, int offset) {
189 avdtp_stream_endpoint_t * stream_endpoint = NULL;
190 connection->acceptor_transaction_label = connection->acceptor_signaling_packet.transaction_label;
191 if (!avdtp_acceptor_validate_msg_length(connection->acceptor_signaling_packet.signal_identifier, offset, size)) {
192 connection->error_code = AVDTP_ERROR_CODE_BAD_LENGTH;
193 connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE;
194 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
195 avdtp_request_can_send_now_acceptor(connection);
196 return;
197 }
198
199 int i;
200
201 // handle error cases
202 switch (connection->acceptor_signaling_packet.signal_identifier){
203 case AVDTP_SI_DISCOVER:
204 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return;
205 log_info("W2_ANSWER_DISCOVER_SEPS");
206 connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS;
207 avdtp_request_can_send_now_acceptor(connection);
208 return;
209
210 case AVDTP_SI_GET_CAPABILITIES:
211 case AVDTP_SI_GET_ALL_CAPABILITIES:
212 case AVDTP_SI_SET_CONFIGURATION:
213 case AVDTP_SI_GET_CONFIGURATION:
214 case AVDTP_SI_START:
215 case AVDTP_SI_CLOSE:
216 case AVDTP_SI_ABORT:
217 case AVDTP_SI_OPEN:
218 case AVDTP_SI_RECONFIGURE:
219 case AVDTP_SI_DELAYREPORT:
220 connection->acceptor_local_seid = packet[offset++] >> 2;
221 stream_endpoint = avdtp_get_stream_endpoint_for_seid(connection->acceptor_local_seid);
222 if (!stream_endpoint){
223 log_info("cmd %d - REJECT", connection->acceptor_signaling_packet.signal_identifier);
224 connection->error_code = AVDTP_ERROR_CODE_BAD_ACP_SEID;
225 if (connection->acceptor_signaling_packet.signal_identifier == AVDTP_SI_OPEN){
226 connection->error_code = AVDTP_ERROR_CODE_BAD_STATE;
227 }
228
229 connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE;
230 if (connection->acceptor_signaling_packet.signal_identifier == AVDTP_SI_RECONFIGURE){
231 connection->reject_service_category = connection->acceptor_local_seid;
232 connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
233 }
234 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
235 avdtp_request_can_send_now_acceptor(connection);
236 return;
237 }
238 break;
239
240 case AVDTP_SI_SUSPEND:
241 connection->num_suspended_seids = 0;
242 log_info("AVDTP_SI_SUSPEND");
243 for (i = offset; (i < size) && (connection->num_suspended_seids < AVDTP_MAX_NUM_SEPS); i++){
244 connection->suspended_seids[connection->num_suspended_seids] = packet[i] >> 2;
245 offset++;
246 log_info("%d, ", connection->suspended_seids[connection->num_suspended_seids]);
247 connection->num_suspended_seids++;
248 }
249 // reject if no SEIDs
250 if (connection->num_suspended_seids == 0) {
251 log_info("no suspended SEIDs, BAD_ACP_SEID");
252 connection->error_code = AVDTP_ERROR_CODE_BAD_ACP_SEID;
253 connection->reject_service_category = connection->acceptor_local_seid;
254 connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
255 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
256 avdtp_request_can_send_now_acceptor(connection);
257 return;
258 }
259 // deal with first suspended SEID
260 connection->acceptor_local_seid = connection->suspended_seids[0];
261 stream_endpoint = avdtp_get_stream_endpoint_for_seid(connection->acceptor_local_seid);
262 if (!stream_endpoint){
263 log_info("stream_endpoint not found, BAD_ACP_SEID");
264 connection->error_code = AVDTP_ERROR_CODE_BAD_ACP_SEID;
265 connection->reject_service_category = connection->acceptor_local_seid;
266 connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
267 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
268 connection->num_suspended_seids = 0;
269 avdtp_request_can_send_now_acceptor(connection);
270 return;
271 }
272 break;
273
274 default:
275 connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_GENERAL_REJECT_WITH_ERROR_CODE;
276 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
277 log_info("AVDTP_CMD_MSG signal %d not implemented, general reject", connection->acceptor_signaling_packet.signal_identifier);
278 avdtp_request_can_send_now_acceptor(connection);
279 return;
280 }
281
282 btstack_assert(stream_endpoint != NULL);
283
284 bool command_complete = avdtp_acceptor_process_chunk(&connection->acceptor_signaling_packet, packet, size);
285 if (!command_complete) return;
286
287 uint16_t packet_size = connection->acceptor_signaling_packet.size;
288 connection->acceptor_signaling_packet.size = 0;
289
290 int request_to_send = 1;
291 switch (stream_endpoint->acceptor_config_state){
292 case AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE:
293 switch (connection->acceptor_signaling_packet.signal_identifier){
294 case AVDTP_SI_DELAYREPORT:
295 log_info("W2_ANSWER_DELAY_REPORT, local seid %d", connection->acceptor_local_seid);
296 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ACCEPT_DELAY_REPORT;
297 avdtp_signaling_emit_delay(connection->avdtp_cid, connection->acceptor_local_seid,
298 big_endian_read_16(packet, offset));
299 break;
300
301 case AVDTP_SI_GET_ALL_CAPABILITIES:
302 log_info("AVDTP_SI_GET_ALL_CAPABILITIES, local seid %d", connection->acceptor_local_seid);
303 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ACCEPT_GET_ALL_CAPABILITIES;
304 break;
305 case AVDTP_SI_GET_CAPABILITIES:
306 log_info("W2_ANSWER_GET_CAPABILITIES, local seid %d", connection->acceptor_local_seid);
307 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ACCEPT_GET_CAPABILITIES;
308 break;
309 case AVDTP_SI_SET_CONFIGURATION:{
310 log_info("Received SET_CONFIGURATION cmd: config state %d", connection->configuration_state);
311 switch (connection->configuration_state){
312 case AVDTP_CONFIGURATION_STATE_IDLE:
313 avdtp_acceptor_handle_configuration_command(connection, offset, packet_size,
314 stream_endpoint);
315 connection->configuration_state = AVDTP_CONFIGURATION_STATE_REMOTE_INITIATED;
316 break;
317 case AVDTP_CONFIGURATION_STATE_LOCAL_INITIATED:
318 case AVDTP_CONFIGURATION_STATE_REMOTE_INITIATED:
319 log_info("Reject SET_CONFIGURATION BAD_STATE %d", connection->configuration_state);
320 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
321 connection->reject_service_category = 0;
322 connection->error_code = AVDTP_ERROR_CODE_BAD_STATE;
323 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
324 break;
325 case AVDTP_CONFIGURATION_STATE_LOCAL_CONFIGURED:
326 case AVDTP_CONFIGURATION_STATE_REMOTE_CONFIGURED:
327 log_info("Reject SET_CONFIGURATION SEP_IN_USE");
328 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
329 connection->reject_service_category = 0;
330 connection->error_code = AVDTP_ERROR_CODE_SEP_IN_USE;
331 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
332 break;
333 default:
334 break;
335 }
336 break;
337 }
338 case AVDTP_SI_RECONFIGURE:{
339 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ACCEPT_RECONFIGURE;
340 connection->reject_service_category = 0;
341
342 avdtp_sep_t sep;
343 log_info("W2_ANSWER_RECONFIGURE, local seid %d, remote seid %d", connection->acceptor_local_seid, stream_endpoint->remote_sep.seid);
344 sep.configured_service_categories = avdtp_unpack_service_capabilities(connection, connection->acceptor_signaling_packet.signal_identifier, &sep.configuration, connection->acceptor_signaling_packet.command+offset, packet_size-offset);
345 if (connection->error_code){
346 // fire configuration parsing errors
347 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
348 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
349 break;
350 }
351
352 // find sep or raise error
353 if (!is_avdtp_remote_seid_registered(stream_endpoint)){
354 log_info("REJECT AVDTP_SI_RECONFIGURE, BAD_ACP_SEID");
355 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
356 connection->error_code = AVDTP_ERROR_CODE_BAD_ACP_SEID;
357 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
358 break;
359 }
360 stream_endpoint->remote_sep.configured_service_categories = sep.configured_service_categories;
361 stream_endpoint->remote_sep.configuration = sep.configuration;
362
363 log_info("update active remote seid %d", stream_endpoint->remote_sep.seid);
364
365 // if media codec configuration updated, copy configuration and emit event
366 if ((sep.configured_service_categories & (1 << AVDTP_MEDIA_CODEC)) != 0){
367 if (stream_endpoint->media_codec_configuration_len == sep.configuration.media_codec.media_codec_information_len){
368 (void) memcpy(stream_endpoint->media_codec_configuration_info, sep.configuration.media_codec.media_codec_information, stream_endpoint->media_codec_configuration_len);
369 stream_endpoint->sep.configuration.media_codec = stream_endpoint->remote_configuration.media_codec;
370 avdtp_signaling_emit_configuration(stream_endpoint, connection->avdtp_cid, 1, &sep.configuration, sep.configured_service_categories);
371 }
372 }
373 break;
374 }
375
376 case AVDTP_SI_GET_CONFIGURATION:
377 log_info("W2_ANSWER_GET_CONFIGURATION");
378 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ACCEPT_GET_CONFIGURATION;
379 break;
380 case AVDTP_SI_OPEN:
381 if (stream_endpoint->state != AVDTP_STREAM_ENDPOINT_CONFIGURED){
382 log_info("REJECT AVDTP_SI_OPEN, BAD_STATE");
383 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE;
384 connection->error_code = AVDTP_ERROR_CODE_BAD_STATE;
385 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
386 break;
387 }
388 log_info("AVDTP_STREAM_ENDPOINT_W2_ANSWER_OPEN_STREAM");
389 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ACCEPT_OPEN_STREAM;
390 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_W4_L2CAP_FOR_MEDIA_CONNECTED;
391 connection->acceptor_local_seid = stream_endpoint->sep.seid;
392 break;
393 case AVDTP_SI_START:
394 if (stream_endpoint->state != AVDTP_STREAM_ENDPOINT_OPENED){
395 log_info("REJECT AVDTP_SI_START, BAD_STATE, state %d", stream_endpoint->state);
396 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
397 connection->error_code = AVDTP_ERROR_CODE_BAD_STATE;
398 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
399 break;
400 }
401 #ifdef ENABLE_AVDTP_ACCEPTOR_EXPLICIT_START_STREAM_CONFIRMATION
402 log_info("W2_ACCEPT_START_STREAM");
403 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W4_USER_CONFIRM_START_STREAM;
404 #else
405 log_info("W2_ANSWER_START_STREAM");
406 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ACCEPT_START_STREAM;
407 #endif
408 break;
409 case AVDTP_SI_CLOSE:
410 switch (stream_endpoint->state){
411 case AVDTP_STREAM_ENDPOINT_OPENED:
412 case AVDTP_STREAM_ENDPOINT_STREAMING:
413 log_info("W2_ANSWER_CLOSE_STREAM");
414 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_CLOSING;
415 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ACCEPT_CLOSE_STREAM;
416 break;
417 default:
418 log_info("AVDTP_SI_CLOSE, bad state %d ", stream_endpoint->state);
419 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE;
420 connection->error_code = AVDTP_ERROR_CODE_BAD_STATE;
421 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
422 break;
423 }
424 break;
425 case AVDTP_SI_ABORT:
426 switch (stream_endpoint->state){
427 case AVDTP_STREAM_ENDPOINT_CONFIGURED:
428 case AVDTP_STREAM_ENDPOINT_CLOSING:
429 case AVDTP_STREAM_ENDPOINT_OPENED:
430 case AVDTP_STREAM_ENDPOINT_STREAMING:
431 log_info("W2_ANSWER_ABORT_STREAM");
432 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_ABORTING;
433 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ACCEPT_ABORT_STREAM;
434 break;
435 default:
436 log_info("AVDTP_SI_ABORT, bad state %d ", stream_endpoint->state);
437 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE;
438 connection->error_code = AVDTP_ERROR_CODE_BAD_STATE;
439 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
440 break;
441 }
442 break;
443 case AVDTP_SI_SUSPEND:
444 switch (stream_endpoint->state){
445 case AVDTP_STREAM_ENDPOINT_STREAMING:
446 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_OPENED;
447 connection->num_suspended_seids--;
448 if (connection->num_suspended_seids <= 0){
449 log_info("W2_ANSWER_SUSPEND_STREAM");
450 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ACCEPT_SUSPEND_STREAM;
451 }
452 break;
453 default:
454 log_info("AVDTP_SI_SUSPEND, bad state %d", stream_endpoint->state);
455 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
456 connection->error_code = AVDTP_ERROR_CODE_BAD_STATE;
457 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
458 break;
459 }
460 break;
461 default:
462 log_info("NOT IMPLEMENTED, Reject signal_identifier %02x", connection->acceptor_signaling_packet.signal_identifier);
463 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_UNKNOWN_CMD;
464 connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
465 break;
466 }
467 break;
468 default:
469 return;
470 }
471
472 if (!request_to_send){
473 log_info("NOT IMPLEMENTED");
474 }
475 avdtp_request_can_send_now_acceptor(connection);
476 }
477
avdtp_acceptor_send_seps_response(uint16_t cid,uint8_t transaction_label,avdtp_stream_endpoint_t * endpoints)478 static int avdtp_acceptor_send_seps_response(uint16_t cid, uint8_t transaction_label, avdtp_stream_endpoint_t * endpoints){
479 uint8_t command[2+2*AVDTP_MAX_NUM_SEPS];
480 int pos = 0;
481 command[pos++] = avdtp_header(transaction_label, AVDTP_SINGLE_PACKET, AVDTP_RESPONSE_ACCEPT_MSG);
482 command[pos++] = (uint8_t)AVDTP_SI_DISCOVER;
483
484 btstack_linked_list_iterator_t it;
485 btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) endpoints);
486 while (btstack_linked_list_iterator_has_next(&it)){
487 avdtp_stream_endpoint_t * stream_endpoint = (avdtp_stream_endpoint_t *)btstack_linked_list_iterator_next(&it);
488 command[pos++] = (stream_endpoint->sep.seid << 2) | (stream_endpoint->sep.in_use<<1);
489 command[pos++] = (stream_endpoint->sep.media_type << 4) | (stream_endpoint->sep.type << 3);
490 }
491 return l2cap_send(cid, command, pos);
492 }
493
avdtp_acceptor_send_response_reject_service_category(uint16_t cid,avdtp_signal_identifier_t identifier,uint8_t category,uint8_t error_code,uint8_t transaction_label)494 static int avdtp_acceptor_send_response_reject_service_category(uint16_t cid, avdtp_signal_identifier_t identifier, uint8_t category, uint8_t error_code, uint8_t transaction_label){
495 uint8_t command[4];
496 command[0] = avdtp_header(transaction_label, AVDTP_SINGLE_PACKET, AVDTP_RESPONSE_REJECT_MSG);
497 command[1] = (uint8_t)identifier;
498 command[2] = category;
499 command[3] = error_code;
500 return l2cap_send(cid, command, sizeof(command));
501 }
502
avdtp_acceptor_send_response_general_reject(uint16_t cid,avdtp_signal_identifier_t identifier,uint8_t transaction_label)503 static int avdtp_acceptor_send_response_general_reject(uint16_t cid, avdtp_signal_identifier_t identifier, uint8_t transaction_label){
504 uint8_t command[2];
505 command[0] = avdtp_header(transaction_label, AVDTP_SINGLE_PACKET, AVDTP_GENERAL_REJECT_MSG);
506 command[1] = (uint8_t)identifier;
507 return l2cap_send(cid, command, sizeof(command));
508 }
509
avdtp_acceptor_send_response_reject(uint16_t cid,avdtp_signal_identifier_t identifier,uint8_t transaction_label)510 static int avdtp_acceptor_send_response_reject(uint16_t cid, avdtp_signal_identifier_t identifier, uint8_t transaction_label){
511 uint8_t command[2];
512 command[0] = avdtp_header(transaction_label, AVDTP_SINGLE_PACKET, AVDTP_RESPONSE_REJECT_MSG);
513 command[1] = (uint8_t)identifier;
514 return l2cap_send(cid, command, sizeof(command));
515 }
516
avdtp_acceptor_send_response_reject_with_error_code(uint16_t cid,avdtp_signal_identifier_t identifier,uint8_t error_code,uint8_t transaction_label)517 static int avdtp_acceptor_send_response_reject_with_error_code(uint16_t cid, avdtp_signal_identifier_t identifier, uint8_t error_code, uint8_t transaction_label){
518 uint8_t command[3];
519 command[0] = avdtp_header(transaction_label, AVDTP_SINGLE_PACKET, AVDTP_RESPONSE_REJECT_MSG);
520 command[1] = (uint8_t)identifier;
521 command[2] = error_code;
522 return l2cap_send(cid, command, sizeof(command));
523 }
524
avdtp_acceptor_stream_config_subsm_run(avdtp_connection_t * connection)525 void avdtp_acceptor_stream_config_subsm_run(avdtp_connection_t *connection) {
526 int sent = 1;
527 btstack_linked_list_t * stream_endpoints = avdtp_get_stream_endpoints();
528
529 switch (connection->acceptor_connection_state){
530 case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS:
531 connection->state = AVDTP_SIGNALING_CONNECTION_OPENED;
532 connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
533 avdtp_acceptor_send_seps_response(connection->l2cap_signaling_cid, connection->acceptor_transaction_label, (avdtp_stream_endpoint_t *) stream_endpoints);
534 avdtp_signaling_emit_accept(connection->avdtp_cid, 0, connection->acceptor_signaling_packet.signal_identifier, false);
535 break;
536 case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE:
537 connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
538 avdtp_acceptor_send_response_reject_with_error_code(connection->l2cap_signaling_cid, connection->reject_signal_identifier, connection->error_code, connection->acceptor_transaction_label);
539 break;
540 case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE:
541 connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
542 avdtp_acceptor_send_response_reject_service_category(connection->l2cap_signaling_cid, connection->reject_signal_identifier, connection->reject_service_category, connection->error_code, connection->acceptor_transaction_label);
543 break;
544 case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_GENERAL_REJECT_WITH_ERROR_CODE:
545 connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
546 avdtp_acceptor_send_response_general_reject(connection->l2cap_signaling_cid, connection->reject_signal_identifier, connection->acceptor_transaction_label);
547 break;
548 default:
549 sent = 0;
550 break;
551 }
552 if (sent){
553 log_info("DONE");
554 return;
555 }
556
557 avdtp_stream_endpoint_t * stream_endpoint = avdtp_get_stream_endpoint_for_seid(connection->acceptor_local_seid);
558 if (!stream_endpoint) return;
559
560 uint8_t reject_service_category = connection->reject_service_category;
561 avdtp_signal_identifier_t reject_signal_identifier = connection->reject_signal_identifier;
562 uint8_t error_code = connection->error_code;
563 uint16_t cid = stream_endpoint->connection ? stream_endpoint->connection->l2cap_signaling_cid : connection->l2cap_signaling_cid;
564 uint8_t trid = stream_endpoint->connection ? stream_endpoint->connection->acceptor_transaction_label : connection->acceptor_transaction_label;
565
566 avdtp_acceptor_stream_endpoint_state_t acceptor_config_state = stream_endpoint->acceptor_config_state;
567 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE;
568 uint8_t * out_buffer;
569 uint16_t pos;
570 avdtp_sep_t * remote_sep;
571
572 bool emit_accept = false;
573 bool emit_reject = false;
574
575 switch (acceptor_config_state){
576 case AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE:
577 break;
578 case AVDTP_ACCEPTOR_W2_ACCEPT_GET_CAPABILITIES:
579 avdtp_prepare_capabilities(&connection->acceptor_signaling_packet, trid, stream_endpoint->sep.registered_service_categories, stream_endpoint->sep.capabilities, AVDTP_SI_GET_CAPABILITIES);
580 l2cap_reserve_packet_buffer();
581 out_buffer = l2cap_get_outgoing_buffer();
582 pos = avdtp_signaling_create_fragment(cid, &connection->acceptor_signaling_packet, out_buffer);
583 if ((connection->acceptor_signaling_packet.packet_type != AVDTP_SINGLE_PACKET) && (connection->acceptor_signaling_packet.packet_type != AVDTP_END_PACKET)){
584 stream_endpoint->acceptor_config_state = acceptor_config_state;
585 log_info("fragmented");
586 } else {
587 log_info("ACP:DONE");
588 emit_accept = true;
589 }
590 l2cap_send_prepared(cid, pos);
591 break;
592 case AVDTP_ACCEPTOR_W2_ACCEPT_DELAY_REPORT:
593 log_info("DONE ");
594 avdtp_acceptor_send_accept_response(cid, trid, AVDTP_SI_DELAYREPORT);
595 emit_accept = true;
596 break;
597 case AVDTP_ACCEPTOR_W2_ACCEPT_GET_ALL_CAPABILITIES:
598 avdtp_prepare_capabilities(&connection->acceptor_signaling_packet, trid, stream_endpoint->sep.registered_service_categories, stream_endpoint->sep.capabilities, AVDTP_SI_GET_ALL_CAPABILITIES);
599 l2cap_reserve_packet_buffer();
600 out_buffer = l2cap_get_outgoing_buffer();
601 pos = avdtp_signaling_create_fragment(cid, &connection->acceptor_signaling_packet, out_buffer);
602 if ((connection->acceptor_signaling_packet.packet_type != AVDTP_SINGLE_PACKET) && (connection->acceptor_signaling_packet.packet_type != AVDTP_END_PACKET)){
603 stream_endpoint->acceptor_config_state = acceptor_config_state;
604 log_info("fragmented");
605 } else {
606 log_info("ACP:DONE");
607 emit_accept = true;
608 }
609 l2cap_send_prepared(cid, pos);
610 break;
611 case AVDTP_ACCEPTOR_W2_ACCEPT_SET_CONFIGURATION:
612 log_info("DONE");
613 log_info(" -> AVDTP_STREAM_ENDPOINT_CONFIGURED");
614 stream_endpoint->connection = connection;
615 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_CONFIGURED;
616 connection->configuration_state = AVDTP_CONFIGURATION_STATE_REMOTE_CONFIGURED;
617 // TODO: consider reconfiguration
618 avdtp_acceptor_send_accept_response(cid, trid, AVDTP_SI_SET_CONFIGURATION);
619 emit_accept = true;
620 break;
621 case AVDTP_ACCEPTOR_W2_ACCEPT_RECONFIGURE:
622 log_info("DONE ");
623 avdtp_acceptor_send_accept_response(cid, trid, AVDTP_SI_RECONFIGURE);
624 emit_accept = true;
625 break;
626 case AVDTP_ACCEPTOR_W2_ACCEPT_GET_CONFIGURATION:
627 remote_sep = &stream_endpoint->remote_sep;
628 avdtp_prepare_capabilities(&connection->acceptor_signaling_packet, trid, remote_sep->configured_service_categories, remote_sep->configuration, AVDTP_SI_GET_CONFIGURATION);
629 l2cap_reserve_packet_buffer();
630 out_buffer = l2cap_get_outgoing_buffer();
631 pos = avdtp_signaling_create_fragment(cid, &connection->acceptor_signaling_packet, out_buffer);
632 if ((connection->acceptor_signaling_packet.packet_type != AVDTP_SINGLE_PACKET) && (connection->acceptor_signaling_packet.packet_type != AVDTP_END_PACKET)){
633 stream_endpoint->acceptor_config_state = acceptor_config_state;
634 log_info("fragmented");
635 } else {
636 log_info("ACP:DONE");
637 emit_accept = true;
638 }
639 l2cap_send_prepared(cid, pos);
640 break;
641 case AVDTP_ACCEPTOR_W2_ACCEPT_OPEN_STREAM:
642 log_info("DONE");
643 avdtp_acceptor_send_accept_response(cid, trid, AVDTP_SI_OPEN);
644 emit_accept = true;
645 break;
646
647 #ifdef ENABLE_AVDTP_ACCEPTOR_EXPLICIT_START_STREAM_CONFIRMATION
648 case AVDTP_ACCEPTOR_W4_USER_CONFIRM_START_STREAM:
649 // keep state until user calls API to confirm or reject starting the stream
650 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W4_USER_CONFIRM_START_STREAM;
651 avdtp_signaling_emit_accept(connection->avdtp_cid, avdtp_local_seid(stream_endpoint), AVDTP_SI_ACCEPT_START, false);
652 break;
653 case AVDTP_ACCEPTOR_W2_REJECT_START_STREAM:
654 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_OPENED;
655 connection->acceptor_signaling_packet.signal_identifier = AVDTP_SI_START;
656 emit_reject = true;
657 avdtp_acceptor_send_response_reject(cid, AVDTP_SI_START, trid);
658 break;
659 #endif
660 case AVDTP_ACCEPTOR_W2_ACCEPT_START_STREAM:
661 log_info("DONE ");
662 log_info(" -> AVDTP_STREAM_ENDPOINT_STREAMING ");
663 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_STREAMING;
664 avdtp_acceptor_send_accept_response(cid, trid, AVDTP_SI_START);
665 emit_accept = true;
666 break;
667 case AVDTP_ACCEPTOR_W2_ACCEPT_CLOSE_STREAM:
668 log_info("DONE");
669 avdtp_acceptor_send_accept_response(cid, trid, AVDTP_SI_CLOSE);
670 connection->configuration_state = AVDTP_CONFIGURATION_STATE_IDLE;
671 emit_accept = true;
672 break;
673 case AVDTP_ACCEPTOR_W2_ACCEPT_ABORT_STREAM:
674 log_info("DONE");
675 avdtp_acceptor_send_accept_response(cid, trid, AVDTP_SI_ABORT);
676 emit_accept = true;
677 break;
678 case AVDTP_ACCEPTOR_W2_ACCEPT_SUSPEND_STREAM:
679 log_info("DONE");
680 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_OPENED;
681 avdtp_acceptor_send_accept_response(cid, trid, AVDTP_SI_SUSPEND);
682 emit_accept = true;
683 break;
684 case AVDTP_ACCEPTOR_W2_REJECT_UNKNOWN_CMD:
685 log_info("DONE REJECT");
686 connection->reject_signal_identifier = AVDTP_SI_NONE;
687 avdtp_acceptor_send_response_reject(cid, reject_signal_identifier, trid);
688 emit_reject = true;
689 break;
690 case AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE:
691 log_info("DONE REJECT CATEGORY");
692 connection->reject_service_category = 0;
693 avdtp_acceptor_send_response_reject_service_category(cid, reject_signal_identifier, reject_service_category, error_code, trid);
694 emit_reject = true;
695 break;
696 case AVDTP_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE:
697 log_info("DONE REJECT");
698 connection->reject_signal_identifier = AVDTP_SI_NONE;
699 connection->error_code = 0;
700 avdtp_acceptor_send_response_reject_with_error_code(cid, reject_signal_identifier, error_code, trid);
701 emit_reject = true;
702 break;
703 default:
704 log_info("NOT IMPLEMENTED");
705 sent = 0;
706 break;
707 }
708
709 if (emit_accept == true){
710 avdtp_signaling_emit_accept(connection->avdtp_cid, avdtp_local_seid(stream_endpoint),
711 connection->acceptor_signaling_packet.signal_identifier, false);
712 } else if (emit_reject == true){
713 avdtp_signaling_emit_reject(connection->avdtp_cid, avdtp_local_seid(stream_endpoint),
714 connection->acceptor_signaling_packet.signal_identifier, false);
715 }
716 // check fragmentation
717 if ((connection->acceptor_signaling_packet.packet_type != AVDTP_SINGLE_PACKET) && (connection->acceptor_signaling_packet.packet_type != AVDTP_END_PACKET)){
718 avdtp_request_can_send_now_acceptor(connection);
719 }
720 }
721