avdtp.c (5cfe7f4cc81075ececf34a61639f3bc15baacb2c) | avdtp.c (6484b28a8cf2e8dc89acafacb3c57e97937a4b51) |
---|---|
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 --- 36 unchanged lines hidden (view full) --- 45#include <unistd.h> 46 47#include "btstack.h" 48#include "avdtp.h" 49#include "avdtp_util.h" 50#include "avdtp_acceptor.h" 51#include "avdtp_initiator.h" 52 | 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 --- 36 unchanged lines hidden (view full) --- 45#include <unistd.h> 46 47#include "btstack.h" 48#include "avdtp.h" 49#include "avdtp_util.h" 50#include "avdtp_acceptor.h" 51#include "avdtp_initiator.h" 52 |
53static uint8_t audio_samples_storage[44100*4]; // 1s buffer 54// static btstack_ring_buffer_t audio_ring_buffer; 55 56static uint8_t sbc_samples_storage[44100*4]; 57// static btstack_ring_buffer_t sbc_ring_buffer; 58 |
|
53static void (*handle_media_data)(avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size); 54 55void avdtp_register_media_transport_category(avdtp_stream_endpoint_t * stream_endpoint){ 56 if (!stream_endpoint){ 57 log_error("avdtp_register_media_transport_category: stream endpoint with given seid is not registered"); 58 return; 59 } 60 uint16_t bitmap = store_bit16(stream_endpoint->sep.registered_service_categories, AVDTP_MEDIA_TRANSPORT, 1); --- 50 unchanged lines hidden (view full) --- 111 } 112 uint16_t bitmap = store_bit16(stream_endpoint->sep.registered_service_categories, AVDTP_HEADER_COMPRESSION, 1); 113 stream_endpoint->sep.registered_service_categories = bitmap; 114 stream_endpoint->sep.capabilities.header_compression.back_ch = back_ch; 115 stream_endpoint->sep.capabilities.header_compression.media = media; 116 stream_endpoint->sep.capabilities.header_compression.recovery = recovery; 117} 118 | 59static void (*handle_media_data)(avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size); 60 61void avdtp_register_media_transport_category(avdtp_stream_endpoint_t * stream_endpoint){ 62 if (!stream_endpoint){ 63 log_error("avdtp_register_media_transport_category: stream endpoint with given seid is not registered"); 64 return; 65 } 66 uint16_t bitmap = store_bit16(stream_endpoint->sep.registered_service_categories, AVDTP_MEDIA_TRANSPORT, 1); --- 50 unchanged lines hidden (view full) --- 117 } 118 uint16_t bitmap = store_bit16(stream_endpoint->sep.registered_service_categories, AVDTP_HEADER_COMPRESSION, 1); 119 stream_endpoint->sep.registered_service_categories = bitmap; 120 stream_endpoint->sep.capabilities.header_compression.back_ch = back_ch; 121 stream_endpoint->sep.capabilities.header_compression.media = media; 122 stream_endpoint->sep.capabilities.header_compression.recovery = recovery; 123} 124 |
119void avdtp_register_media_codec_category(avdtp_stream_endpoint_t * stream_endpoint, avdtp_media_type_t media_type, avdtp_media_codec_type_t media_codec_type, uint8_t * media_codec_info, uint16_t media_codec_info_len){ | 125void avdtp_register_media_codec_category(avdtp_stream_endpoint_t * stream_endpoint, avdtp_media_type_t media_type, avdtp_media_codec_type_t media_codec_type, const uint8_t * media_codec_info, uint16_t media_codec_info_len){ |
120 if (!stream_endpoint){ 121 log_error("avdtp_register_media_transport_category: stream endpoint with given seid is not registered"); 122 return; 123 } 124 uint16_t bitmap = store_bit16(stream_endpoint->sep.registered_service_categories, AVDTP_MEDIA_CODEC, 1); 125 stream_endpoint->sep.registered_service_categories = bitmap; 126 printf("registered services AVDTP_MEDIA_CODEC(%d) %02x\n", AVDTP_MEDIA_CODEC, stream_endpoint->sep.registered_service_categories); 127 stream_endpoint->sep.capabilities.media_codec.media_type = media_type; --- 64 unchanged lines hidden (view full) --- 192 193avdtp_stream_endpoint_t * avdtp_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type, avdtp_context_t * context){ 194 avdtp_stream_endpoint_t * stream_endpoint = btstack_memory_avdtp_stream_endpoint_get(); 195 memset(stream_endpoint, 0, sizeof(avdtp_stream_endpoint_t)); 196 context->stream_endpoints_id_counter++; 197 stream_endpoint->sep.seid = context->stream_endpoints_id_counter; 198 stream_endpoint->sep.media_type = media_type; 199 stream_endpoint->sep.type = sep_type; | 126 if (!stream_endpoint){ 127 log_error("avdtp_register_media_transport_category: stream endpoint with given seid is not registered"); 128 return; 129 } 130 uint16_t bitmap = store_bit16(stream_endpoint->sep.registered_service_categories, AVDTP_MEDIA_CODEC, 1); 131 stream_endpoint->sep.registered_service_categories = bitmap; 132 printf("registered services AVDTP_MEDIA_CODEC(%d) %02x\n", AVDTP_MEDIA_CODEC, stream_endpoint->sep.registered_service_categories); 133 stream_endpoint->sep.capabilities.media_codec.media_type = media_type; --- 64 unchanged lines hidden (view full) --- 198 199avdtp_stream_endpoint_t * avdtp_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type, avdtp_context_t * context){ 200 avdtp_stream_endpoint_t * stream_endpoint = btstack_memory_avdtp_stream_endpoint_get(); 201 memset(stream_endpoint, 0, sizeof(avdtp_stream_endpoint_t)); 202 context->stream_endpoints_id_counter++; 203 stream_endpoint->sep.seid = context->stream_endpoints_id_counter; 204 stream_endpoint->sep.media_type = media_type; 205 stream_endpoint->sep.type = sep_type; |
206 207 memset(audio_samples_storage, 0, sizeof(audio_samples_storage)); 208 btstack_ring_buffer_init(&stream_endpoint->audio_ring_buffer, audio_samples_storage, sizeof(audio_samples_storage)); 209 210 memset(sbc_samples_storage, 0, sizeof(sbc_samples_storage)); 211 btstack_ring_buffer_init(&stream_endpoint->sbc_ring_buffer, sbc_samples_storage, sizeof(sbc_samples_storage)); 212 213 |
|
200 btstack_linked_list_add(&context->stream_endpoints, (btstack_linked_item_t *) stream_endpoint); 201 return stream_endpoint; 202} 203 204 205static void handle_l2cap_data_packet_for_signaling_connection(avdtp_connection_t * connection, uint8_t *packet, uint16_t size, avdtp_context_t * context){ 206 int offset = avdtp_read_signaling_header(&connection->signaling_packet, packet, size); 207 switch (connection->signaling_packet.message_type){ --- 21 unchanged lines hidden (view full) --- 229 case HCI_EVENT_PACKET: 230 switch (event){ 231 case L2CAP_EVENT_CHANNEL_OPENED: 232 if (stream_endpoint->l2cap_media_cid == 0){ 233 if (stream_endpoint->state != AVDTP_STREAM_ENDPOINT_W4_L2CAP_FOR_MEDIA_CONNECTED) return; 234 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_OPENED; 235 stream_endpoint->connection = connection; 236 stream_endpoint->l2cap_media_cid = l2cap_event_channel_opened_get_local_cid(packet); | 214 btstack_linked_list_add(&context->stream_endpoints, (btstack_linked_item_t *) stream_endpoint); 215 return stream_endpoint; 216} 217 218 219static void handle_l2cap_data_packet_for_signaling_connection(avdtp_connection_t * connection, uint8_t *packet, uint16_t size, avdtp_context_t * context){ 220 int offset = avdtp_read_signaling_header(&connection->signaling_packet, packet, size); 221 switch (connection->signaling_packet.message_type){ --- 21 unchanged lines hidden (view full) --- 243 case HCI_EVENT_PACKET: 244 switch (event){ 245 case L2CAP_EVENT_CHANNEL_OPENED: 246 if (stream_endpoint->l2cap_media_cid == 0){ 247 if (stream_endpoint->state != AVDTP_STREAM_ENDPOINT_W4_L2CAP_FOR_MEDIA_CONNECTED) return; 248 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_OPENED; 249 stream_endpoint->connection = connection; 250 stream_endpoint->l2cap_media_cid = l2cap_event_channel_opened_get_local_cid(packet); |
237 stream_endpoint->media_con_handle = l2cap_event_channel_opened_get_handle(packet); 238 printf(" -> AVDTP_STREAM_ENDPOINT_OPENED, media con handle 0x%02x, l2cap_media_cid 0x%02x\n", stream_endpoint->media_con_handle, stream_endpoint->l2cap_media_cid); 239 avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->l2cap_signaling_cid, stream_endpoint->sep.seid, connection->remote_seps[stream_endpoint->remote_sep_index].seid, 0); | 251 printf(" -> AVDTP_STREAM_ENDPOINT_OPENED, stream endpoint %p, connection %p\n", stream_endpoint, connection); 252 avdtp_streaming_emit_connection_established(context->avdtp_callback, stream_endpoint->l2cap_media_cid, 0); |
240 break; 241 } 242 break; 243 case L2CAP_EVENT_CHANNEL_CLOSED: 244 local_cid = l2cap_event_channel_closed_get_local_cid(packet); 245 if (stream_endpoint->l2cap_media_cid == local_cid){ 246 stream_endpoint->l2cap_media_cid = 0; 247 printf(" -> L2CAP_EVENT_CHANNEL_CLOSED: AVDTP_STREAM_ENDPOINT_IDLE\n"); 248 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_IDLE; 249 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE; 250 stream_endpoint->initiator_config_state = AVDTP_INITIATOR_STREAM_CONFIG_IDLE; | 253 break; 254 } 255 break; 256 case L2CAP_EVENT_CHANNEL_CLOSED: 257 local_cid = l2cap_event_channel_closed_get_local_cid(packet); 258 if (stream_endpoint->l2cap_media_cid == local_cid){ 259 stream_endpoint->l2cap_media_cid = 0; 260 printf(" -> L2CAP_EVENT_CHANNEL_CLOSED: AVDTP_STREAM_ENDPOINT_IDLE\n"); 261 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_IDLE; 262 stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE; 263 stream_endpoint->initiator_config_state = AVDTP_INITIATOR_STREAM_CONFIG_IDLE; |
251 stream_endpoint->remote_sep_index = 0; | 264 stream_endpoint->remote_seps_num = 0; 265 memset(stream_endpoint->remote_seps, 0, sizeof(avdtp_sep_t)*MAX_NUM_SEPS); 266 stream_endpoint->remote_sep_index = AVDTP_INVALID_SEP_INDEX; |
252 break; 253 } 254 if (stream_endpoint->l2cap_recovery_cid == local_cid){ 255 log_info(" -> L2CAP_EVENT_CHANNEL_CLOSED recovery cid 0x%0x", local_cid); 256 stream_endpoint->l2cap_recovery_cid = 0; 257 break; 258 } 259 --- 113 unchanged lines hidden (view full) --- 373 374 if (connection->l2cap_signaling_cid == 0) { 375 if (connection->state != AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED) break; 376 connection->l2cap_signaling_cid = local_cid; 377 connection->con_handle = con_handle; 378 connection->query_seid = 0; 379 connection->state = AVDTP_SIGNALING_CONNECTION_OPENED; 380 printf(" -> AVDTP_SIGNALING_CONNECTION_OPENED, connection %p\n", connection); | 267 break; 268 } 269 if (stream_endpoint->l2cap_recovery_cid == local_cid){ 270 log_info(" -> L2CAP_EVENT_CHANNEL_CLOSED recovery cid 0x%0x", local_cid); 271 stream_endpoint->l2cap_recovery_cid = 0; 272 break; 273 } 274 --- 113 unchanged lines hidden (view full) --- 388 389 if (connection->l2cap_signaling_cid == 0) { 390 if (connection->state != AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED) break; 391 connection->l2cap_signaling_cid = local_cid; 392 connection->con_handle = con_handle; 393 connection->query_seid = 0; 394 connection->state = AVDTP_SIGNALING_CONNECTION_OPENED; 395 printf(" -> AVDTP_SIGNALING_CONNECTION_OPENED, connection %p\n", connection); |
381 avdtp_signaling_emit_connection_established(context->avdtp_callback, connection->l2cap_signaling_cid, event_addr, 0); | 396 avdtp_signaling_emit_connection_established(context->avdtp_callback, con_handle, event_addr, 0); |
382 break; 383 } 384 385 stream_endpoint = avdtp_stream_endpoint_for_seid(connection->query_seid, context); 386 if (!stream_endpoint){ 387 printf("L2CAP_EVENT_CHANNEL_OPENED: stream_endpoint not found"); 388 return; 389 } --- 27 unchanged lines hidden (view full) --- 417 case HCI_EVENT_DISCONNECTION_COMPLETE: 418 break; 419 420 case L2CAP_EVENT_CAN_SEND_NOW: 421 connection = avdtp_connection_for_l2cap_signaling_cid(channel, context); 422 if (!connection) { 423 stream_endpoint = avdtp_stream_endpoint_for_l2cap_cid(channel, context); 424 if (!stream_endpoint->connection) break; | 397 break; 398 } 399 400 stream_endpoint = avdtp_stream_endpoint_for_seid(connection->query_seid, context); 401 if (!stream_endpoint){ 402 printf("L2CAP_EVENT_CHANNEL_OPENED: stream_endpoint not found"); 403 return; 404 } --- 27 unchanged lines hidden (view full) --- 432 case HCI_EVENT_DISCONNECTION_COMPLETE: 433 break; 434 435 case L2CAP_EVENT_CAN_SEND_NOW: 436 connection = avdtp_connection_for_l2cap_signaling_cid(channel, context); 437 if (!connection) { 438 stream_endpoint = avdtp_stream_endpoint_for_l2cap_cid(channel, context); 439 if (!stream_endpoint->connection) break; |
440 if (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING_W2_SEND){ 441 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_STREAMING; 442 //send sbc 443 uint8_t rtp_version = 2; 444 uint8_t padding = 0; 445 uint8_t extension = 0; 446 uint8_t csrc_count = 0; 447 uint8_t marker = 0; 448 uint8_t payload_type = 0x60; 449 uint16_t sequence_number = stream_endpoint->sequence_number; 450 uint32_t timestamp = btstack_run_loop_get_time_ms(); 451 uint32_t ssrc = 0x11223344; 452 453 // rtp header (min size 12B) 454 int pos = 0; 455 int mtu = l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid); 456 457 uint8_t media_packet[mtu]; 458 media_packet[pos++] = (rtp_version << 6) | (padding << 5) | (extension << 4) | csrc_count; 459 media_packet[pos++] = (marker << 1) | payload_type; 460 big_endian_store_16(media_packet, pos, sequence_number); 461 pos += 2; 462 big_endian_store_32(media_packet, pos, timestamp); 463 pos += 4; 464 big_endian_store_32(media_packet, pos, ssrc); // only used for multicast 465 pos += 4; 466 467 // media payload 468 // sbc_header (size 1B) 469 uint8_t sbc_header_index = pos; 470 pos++; 471 uint8_t fragmentation = 0; 472 uint8_t starting_packet = 0; // set to 1 for the first packet of a fragmented SBC frame 473 uint8_t last_packet = 0; // set to 1 for the last packet of a fragmented SBC frame 474 uint8_t num_frames = 0; 475 476 uint32_t total_sbc_bytes_read = 0; 477 uint8_t sbc_frame_size = 0; 478 // payload 479 while (mtu - 13 - total_sbc_bytes_read >= 120 && btstack_ring_buffer_bytes_available(&stream_endpoint->sbc_ring_buffer)){ 480 uint32_t number_of_bytes_read = 0; 481 btstack_ring_buffer_read(&stream_endpoint->sbc_ring_buffer, &sbc_frame_size, 1, &number_of_bytes_read); 482 btstack_ring_buffer_read(&stream_endpoint->sbc_ring_buffer, media_packet + pos, sbc_frame_size, &number_of_bytes_read); 483 pos += sbc_frame_size; 484 total_sbc_bytes_read += sbc_frame_size; 485 num_frames++; 486 // printf("send sbc frame: timestamp %d, seq. nr %d\n", timestamp, stream_endpoint->sequence_number); 487 } 488 media_packet[sbc_header_index] = (fragmentation << 7) | (starting_packet << 6) | (last_packet << 5) | num_frames; 489 stream_endpoint->sequence_number++; 490 l2cap_send(stream_endpoint->l2cap_media_cid, media_packet, pos); 491 if (btstack_ring_buffer_bytes_available(&stream_endpoint->sbc_ring_buffer)){ 492 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_STREAMING_W2_SEND; 493 l2cap_request_can_send_now_event(stream_endpoint->l2cap_media_cid); 494 } 495 } |
|
425 connection = stream_endpoint->connection; 426 } 427 avdtp_handle_can_send_now(connection, channel, context); 428 break; 429 default: 430 printf("unknown HCI event type %02x\n", hci_event_packet_get_type(packet)); 431 break; 432 } 433 break; 434 435 default: 436 // other packet type 437 break; 438 } 439} 440 | 496 connection = stream_endpoint->connection; 497 } 498 avdtp_handle_can_send_now(connection, channel, context); 499 break; 500 default: 501 printf("unknown HCI event type %02x\n", hci_event_packet_get_type(packet)); 502 break; 503 } 504 break; 505 506 default: 507 // other packet type 508 break; 509 } 510} 511 |
441void avdtp_disconnect(uint16_t avdtp_cid, avdtp_context_t * context){ 442 avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context); | 512void avdtp_disconnect(uint16_t con_handle, avdtp_context_t * context){ 513 avdtp_connection_t * connection = avdtp_connection_for_con_handle(con_handle, context); |
443 if (!connection) return; 444 if (connection->state == AVDTP_SIGNALING_CONNECTION_IDLE) return; 445 if (connection->state == AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED) return; 446 447 connection->disconnect = 1; 448 avdtp_request_can_send_now_self(connection, connection->l2cap_signaling_cid); 449} 450 | 514 if (!connection) return; 515 if (connection->state == AVDTP_SIGNALING_CONNECTION_IDLE) return; 516 if (connection->state == AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED) return; 517 518 connection->disconnect = 1; 519 avdtp_request_can_send_now_self(connection, connection->l2cap_signaling_cid); 520} 521 |
451void avdtp_open_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_context_t * context){ 452 avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context); | 522void avdtp_open_stream(uint16_t con_handle, uint8_t acp_seid, avdtp_context_t * context){ 523 avdtp_connection_t * connection = avdtp_connection_for_con_handle(con_handle, context); |
453 if (!connection){ | 524 if (!connection){ |
454 printf("avdtp_media_connect: no connection for signaling cid 0x%02x found\n", avdtp_cid); | 525 printf("avdtp_media_connect: no connection for handle 0x%02x found\n", con_handle); |
455 return; 456 } | 526 return; 527 } |
457 if (avdtp_find_remote_sep(connection, acp_seid) == 0xFF){ 458 printf("avdtp_media_connect: no remote sep for seid %d found\n", acp_seid); 459 return; 460 } 461 | 528 |
462 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) { 463 printf("avdtp_media_connect: wrong connection state %d\n", connection->state); 464 return; 465 } 466 | 529 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) { 530 printf("avdtp_media_connect: wrong connection state %d\n", connection->state); 531 return; 532 } 533 |
467 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context); | 534 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_associated_with_acp_seid(acp_seid, context); |
468 if (!stream_endpoint) { | 535 if (!stream_endpoint) { |
469 printf("avdtp_media_connect: no stream_endpoint with seid %d found\n", int_seid); | 536 printf("avdtp_media_connect: no stream_endpoint with acp seid %d found\n", acp_seid); |
470 return; 471 } 472 473 if (stream_endpoint->state < AVDTP_STREAM_ENDPOINT_CONFIGURED) return; | 537 return; 538 } 539 540 if (stream_endpoint->state < AVDTP_STREAM_ENDPOINT_CONFIGURED) return; |
474 if (stream_endpoint->remote_sep_index == 0xFF) return; | 541 if (stream_endpoint->remote_sep_index == AVDTP_INVALID_SEP_INDEX) return; |
475 476 connection->initiator_transaction_label++; 477 connection->acp_seid = acp_seid; 478 connection->int_seid = stream_endpoint->sep.seid; 479 stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_OPEN_STREAM; 480 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_W2_REQUEST_OPEN_STREAM; 481 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 482} 483 | 542 543 connection->initiator_transaction_label++; 544 connection->acp_seid = acp_seid; 545 connection->int_seid = stream_endpoint->sep.seid; 546 stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_OPEN_STREAM; 547 stream_endpoint->state = AVDTP_STREAM_ENDPOINT_W2_REQUEST_OPEN_STREAM; 548 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 549} 550 |
484void avdtp_start_stream(uint8_t int_seid, avdtp_context_t * context){ 485 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context); 486 if (!stream_endpoint) { 487 printf("avdtp_start_stream: no stream_endpoint with seid %d found\n", int_seid); | 551void avdtp_start_stream(uint16_t con_handle, uint8_t acp_seid, avdtp_context_t * context){ 552 avdtp_connection_t * connection = avdtp_connection_for_con_handle(con_handle, context); 553 if (!connection){ 554 printf("avdtp_media_connect: no connection for handle 0x%02x found\n", con_handle); |
488 return; 489 } | 555 return; 556 } |
490 avdtp_connection_t * connection = stream_endpoint->connection; 491 if (!connection){ 492 printf("avdtp_start_stream: no connection for seid %d found\n",stream_endpoint->sep.seid); | 557 558 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) { 559 printf("avdtp_media_connect: wrong connection state %d\n", connection->state); |
493 return; 494 } | 560 return; 561 } |
495 496 if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->start_stream) return; 497 stream_endpoint->start_stream = 1; 498 connection->int_seid = int_seid; 499 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 500} | |
501 | 562 |
502void avdtp_stop_stream(uint8_t int_seid, avdtp_context_t * context){ 503 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context); | 563 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_associated_with_acp_seid(acp_seid, context); |
504 if (!stream_endpoint) { | 564 if (!stream_endpoint) { |
505 printf("avdtp_stop_stream: no stream_endpoint with seid %d found\n", int_seid); | 565 printf("avdtp_media_connect: no stream_endpoint with acp_seid %d found\n", acp_seid); |
506 return; 507 } | 566 return; 567 } |
508 avdtp_connection_t * connection = stream_endpoint->connection; | 568 if (stream_endpoint->remote_sep_index == AVDTP_INVALID_SEP_INDEX) return; 569 if (stream_endpoint->state < AVDTP_STREAM_ENDPOINT_OPENED) return; 570 connection->initiator_transaction_label++; 571 connection->acp_seid = acp_seid; 572 connection->int_seid = stream_endpoint->sep.seid; 573 stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_STREAMING_START; 574 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 575} 576 577void avdtp_stop_stream(uint16_t con_handle, uint8_t acp_seid, avdtp_context_t * context){ 578 avdtp_connection_t * connection = avdtp_connection_for_con_handle(con_handle, context); |
509 if (!connection){ | 579 if (!connection){ |
510 printf("avdtp_stop_stream: no connection for seid %d found\n",stream_endpoint->sep.seid); | 580 printf("avdtp_stop_stream: no connection for handle 0x%02x found\n", con_handle); |
511 return; 512 } | 581 return; 582 } |
513 if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->stop_stream) return; 514 stream_endpoint->stop_stream = 1; 515 connection->int_seid = int_seid; 516 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 517} | 583 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) { 584 printf("avdtp_stop_stream: wrong connection state %d\n", connection->state); 585 return; 586 } |
518 | 587 |
519void avdtp_abort_stream(uint8_t int_seid, avdtp_context_t * context){ 520 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context); | 588 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_associated_with_acp_seid(acp_seid, context); |
521 if (!stream_endpoint) { | 589 if (!stream_endpoint) { |
522 printf("avdtp_abort_stream: no stream_endpoint with seid %d found\n", int_seid); | 590 printf("avdtp_stop_stream: no stream_endpoint with acp seid %d found\n", acp_seid); |
523 return; 524 } | 591 return; 592 } |
525 avdtp_connection_t * connection = stream_endpoint->connection; | 593 if (stream_endpoint->remote_sep_index == AVDTP_INVALID_SEP_INDEX) return; 594 switch (stream_endpoint->state){ 595 case AVDTP_STREAM_ENDPOINT_OPENED: 596 case AVDTP_STREAM_ENDPOINT_STREAMING: 597 printf(" AVDTP_INITIATOR_W2_STREAMING_STOP \n"); 598 connection->initiator_transaction_label++; 599 connection->acp_seid = acp_seid; 600 connection->int_seid = stream_endpoint->sep.seid; 601 stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_STREAMING_STOP; 602 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 603 break; 604 default: 605 break; 606 } 607} 608 609void avdtp_abort_stream(uint16_t con_handle, uint8_t acp_seid, avdtp_context_t * context){ 610 avdtp_connection_t * connection = avdtp_connection_for_con_handle(con_handle, context); |
526 if (!connection){ | 611 if (!connection){ |
527 printf("avdtp_abort_stream: no connection for seid %d found\n",stream_endpoint->sep.seid); | 612 printf("avdtp_abort_stream: no connection for handle 0x%02x found\n", con_handle); |
528 return; 529 } | 613 return; 614 } |
530 if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->abort_stream) return; 531 stream_endpoint->abort_stream = 1; 532 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 533} | 615 616 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) { 617 printf("avdtp_abort_stream: wrong connection state %d\n", connection->state); 618 return; 619 } |
534 | 620 |
535void avdtp_suspend_stream(uint8_t int_seid, avdtp_context_t * context){ 536 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context); | 621 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_associated_with_acp_seid(acp_seid, context); |
537 if (!stream_endpoint) { | 622 if (!stream_endpoint) { |
538 printf("avdtp_abort_stream: no stream_endpoint with seid %d found\n", int_seid); | 623 printf("avdtp_abort_stream: no stream_endpoint for seid %d found\n", acp_seid); |
539 return; 540 } | 624 return; 625 } |
541 avdtp_connection_t * connection = stream_endpoint->connection; 542 if (!connection){ 543 printf("avdtp_abort_stream: no connection for seid %d found\n",stream_endpoint->sep.seid); 544 return; | 626 if (stream_endpoint->remote_sep_index == AVDTP_INVALID_SEP_INDEX) return; 627 switch (stream_endpoint->state){ 628 case AVDTP_STREAM_ENDPOINT_CONFIGURED: 629 case AVDTP_STREAM_ENDPOINT_CLOSING: 630 case AVDTP_STREAM_ENDPOINT_OPENED: 631 case AVDTP_STREAM_ENDPOINT_STREAMING: 632 printf(" AVDTP_INITIATOR_W2_STREAMING_ABORT \n"); 633 connection->initiator_transaction_label++; 634 connection->acp_seid = acp_seid; 635 connection->int_seid = stream_endpoint->sep.seid; 636 stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_STREAMING_ABORT; 637 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 638 break; 639 default: 640 break; |
545 } | 641 } |
546 if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->suspend_stream) return; 547 stream_endpoint->suspend_stream = 1; 548 connection->int_seid = int_seid; 549 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); | |
550} 551 | 642} 643 |
552void avdtp_discover_stream_endpoints(uint16_t avdtp_cid, avdtp_context_t * context){ 553 avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context); | 644void avdtp_discover_stream_endpoints(uint16_t con_handle, avdtp_context_t * context){ 645 avdtp_connection_t * connection = avdtp_connection_for_con_handle(con_handle, context); |
554 if (!connection){ | 646 if (!connection){ |
555 printf("avdtp_discover_stream_endpoints: no connection for signaling cid 0x%02x found\n", avdtp_cid); | 647 printf("avdtp_discover_stream_endpoints: no connection for handle 0x%02x found\n", con_handle); |
556 return; 557 } 558 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return; 559 560 switch (connection->initiator_connection_state){ 561 case AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE: 562 connection->initiator_transaction_label++; 563 connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_DISCOVER_SEPS; 564 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 565 break; 566 default: 567 printf("avdtp_discover_stream_endpoints: wrong state\n"); 568 break; 569 } 570} 571 572 | 648 return; 649 } 650 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return; 651 652 switch (connection->initiator_connection_state){ 653 case AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE: 654 connection->initiator_transaction_label++; 655 connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_DISCOVER_SEPS; 656 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 657 break; 658 default: 659 printf("avdtp_discover_stream_endpoints: wrong state\n"); 660 break; 661 } 662} 663 664 |
573void avdtp_get_capabilities(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context_t * context){ 574 printf("avdtp_get_capabilities: acp_seid %d\n", acp_seid); 575 avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context); | 665void avdtp_get_capabilities(uint16_t con_handle, uint8_t acp_seid, avdtp_context_t * context){ 666 avdtp_connection_t * connection = avdtp_connection_for_con_handle(con_handle, context); |
576 if (!connection){ | 667 if (!connection){ |
577 printf("avdtp_get_capabilities: no connection for signaling cid 0x%02x found\n", avdtp_cid); | 668 printf("avdtp_get_capabilities: no connection for handle 0x%02x found\n", con_handle); |
578 return; 579 } 580 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return; 581 if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return; 582 connection->initiator_transaction_label++; 583 connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CAPABILITIES; 584 connection->acp_seid = acp_seid; 585 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 586} 587 588 | 669 return; 670 } 671 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return; 672 if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return; 673 connection->initiator_transaction_label++; 674 connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CAPABILITIES; 675 connection->acp_seid = acp_seid; 676 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 677} 678 679 |
589void avdtp_get_all_capabilities(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context_t * context){ 590 printf("avdtp_get_all_capabilities: acp_seid %d\n", acp_seid); 591 avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context); | 680void avdtp_get_all_capabilities(uint16_t con_handle, uint8_t acp_seid, avdtp_context_t * context){ 681 avdtp_connection_t * connection = avdtp_connection_for_con_handle(con_handle, context); |
592 if (!connection){ | 682 if (!connection){ |
593 printf("avdtp_get_all_capabilities: no connection for signaling cid 0x%02x found\n", avdtp_cid); | 683 printf("avdtp_get_all_capabilities: no connection for handle 0x%02x found\n", con_handle); |
594 return; 595 } 596 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return; 597 if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return; 598 connection->initiator_transaction_label++; 599 connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_ALL_CAPABILITIES; 600 connection->acp_seid = acp_seid; 601 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 602} 603 | 684 return; 685 } 686 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return; 687 if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return; 688 connection->initiator_transaction_label++; 689 connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_ALL_CAPABILITIES; 690 connection->acp_seid = acp_seid; 691 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 692} 693 |
604void avdtp_get_configuration(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context_t * context){ 605 avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context); | 694void avdtp_get_configuration(uint16_t con_handle, uint8_t acp_seid, avdtp_context_t * context){ 695 avdtp_connection_t * connection = avdtp_connection_for_con_handle(con_handle, context); |
606 if (!connection){ | 696 if (!connection){ |
607 printf("avdtp_get_configuration: no connection for signaling cid 0x%02x found\n", avdtp_cid); | 697 printf("avdtp_get_configuration: no connection for handle 0x%02x found\n", con_handle); |
608 return; 609 } 610 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return; 611 if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return; 612 connection->initiator_transaction_label++; 613 connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CONFIGURATION; 614 connection->acp_seid = acp_seid; 615 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 616} 617 | 698 return; 699 } 700 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return; 701 if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return; 702 connection->initiator_transaction_label++; 703 connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CONFIGURATION; 704 connection->acp_seid = acp_seid; 705 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 706} 707 |
618void avdtp_set_configuration(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context){ 619 avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context); | 708void avdtp_set_configuration(uint16_t con_handle, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context){ 709 avdtp_connection_t * connection = avdtp_connection_for_con_handle(con_handle, context); |
620 if (!connection){ | 710 if (!connection){ |
621 log_error("avdtp_set_configuration: no connection for signaling cid 0x%02x found\n", avdtp_cid); | 711 log_error("avdtp_set_configuration: no connection for handle 0x%02x found\n", con_handle); |
622 return; 623 } 624 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return; 625 if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return; 626 627 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(int_seid, context); 628 if (!stream_endpoint) { 629 log_error("avdtp_set_configuration: no initiator stream endpoint for seid %d\n", int_seid); 630 return; 631 } 632 // printf("avdtp_set_configuration int seid %d, acp seid %d\n", int_seid, acp_seid); 633 634 connection->initiator_transaction_label++; 635 connection->acp_seid = acp_seid; 636 connection->int_seid = int_seid; | 712 return; 713 } 714 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return; 715 if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return; 716 717 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(int_seid, context); 718 if (!stream_endpoint) { 719 log_error("avdtp_set_configuration: no initiator stream endpoint for seid %d\n", int_seid); 720 return; 721 } 722 // printf("avdtp_set_configuration int seid %d, acp seid %d\n", int_seid, acp_seid); 723 724 connection->initiator_transaction_label++; 725 connection->acp_seid = acp_seid; 726 connection->int_seid = int_seid; |
637 stream_endpoint->remote_capabilities_bitmap = configured_services_bitmap; 638 stream_endpoint->remote_capabilities = configuration; | 727 connection->remote_capabilities_bitmap = configured_services_bitmap; 728 connection->remote_capabilities = configuration; |
639 stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_SET_CONFIGURATION; 640 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 641} 642 | 729 stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_SET_CONFIGURATION; 730 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 731} 732 |
643void avdtp_reconfigure(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context){ 644 avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context); | 733void avdtp_reconfigure(uint16_t con_handle, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context){ 734 avdtp_connection_t * connection = avdtp_connection_for_con_handle(con_handle, context); |
645 if (!connection){ | 735 if (!connection){ |
646 printf("avdtp_reconfigure: no connection for signaling cid 0x%02x found\n", avdtp_cid); | 736 printf("avdtp_reconfigure: no connection for handle 0x%02x found\n", con_handle); |
647 return; 648 } 649 //TODO: if opened only app capabilities, enable reconfigure for not opened 650 if (connection->state < AVDTP_SIGNALING_CONNECTION_OPENED) return; 651 if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return; | 737 return; 738 } 739 //TODO: if opened only app capabilities, enable reconfigure for not opened 740 if (connection->state < AVDTP_SIGNALING_CONNECTION_OPENED) return; 741 if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return; |
652 653 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(int_seid, context); 654 if (!stream_endpoint) { 655 log_error("avdtp_reconfigure: no initiator stream endpoint for seid %d\n", int_seid); 656 return; 657 } 658 659 if (stream_endpoint->remote_sep_index == 0xFF){ 660 log_error("avdtp_reconfigure: no associated remote sep\n"); 661 return; 662 } 663 | 742 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_associated_with_acp_seid(acp_seid, context); 743 if (!stream_endpoint) return; 744 if (stream_endpoint->remote_sep_index == AVDTP_INVALID_SEP_INDEX) return; |
664 connection->initiator_transaction_label++; 665 connection->acp_seid = acp_seid; 666 connection->int_seid = stream_endpoint->sep.seid; | 745 connection->initiator_transaction_label++; 746 connection->acp_seid = acp_seid; 747 connection->int_seid = stream_endpoint->sep.seid; |
667 stream_endpoint->remote_capabilities_bitmap = configured_services_bitmap; 668 stream_endpoint->remote_capabilities = configuration; | 748 connection->remote_capabilities_bitmap = configured_services_bitmap; 749 connection->remote_capabilities = configuration; |
669 stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_RECONFIGURE_STREAM_WITH_SEID; 670 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 671} 672 | 750 stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_RECONFIGURE_STREAM_WITH_SEID; 751 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); 752} 753 |
673uint8_t avdtp_remote_seps_num(uint16_t avdtp_cid, avdtp_context_t * context){ 674 avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context); | 754void avdtp_suspend(uint16_t con_handle, uint8_t acp_seid, avdtp_context_t * context){ 755 avdtp_connection_t * connection = avdtp_connection_for_con_handle(con_handle, context); |
675 if (!connection){ | 756 if (!connection){ |
676 printf("avdtp_suspend: no connection for signaling cid 0x%02x found\n", avdtp_cid); 677 return 0; 678 } 679 return connection->remote_seps_num; 680} 681 682avdtp_sep_t * avdtp_remote_sep(uint16_t avdtp_cid, uint8_t index, avdtp_context_t * context){ 683 avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context); 684 if (!connection){ 685 printf("avdtp_suspend: no connection for signaling cid 0x%02x found\n", avdtp_cid); 686 return NULL; 687 } 688 return &connection->remote_seps[index]; 689} 690 691void avdtp_initialize_sbc_configuration_storage(avdtp_stream_endpoint_t * stream_endpoint, uint8_t * config_storage, uint16_t storage_size, uint8_t * packet, uint16_t packet_size){ 692 UNUSED(packet_size); 693 if (storage_size < 4) { 694 printf("storage must have 4 bytes\n"); | 757 printf("avdtp_suspend: no connection for handle 0x%02x found\n", con_handle); |
695 return; 696 } | 758 return; 759 } |
697 uint8_t sampling_frequency = avdtp_choose_sbc_sampling_frequency(stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_sampling_frequency_bitmap(packet)); 698 uint8_t channel_mode = avdtp_choose_sbc_channel_mode(stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_channel_mode_bitmap(packet)); 699 uint8_t block_length = avdtp_choose_sbc_block_length(stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_block_length_bitmap(packet)); 700 uint8_t subbands = avdtp_choose_sbc_subbands(stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_subbands_bitmap(packet)); 701 702 uint8_t allocation_method = avdtp_choose_sbc_allocation_method(stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_allocation_method_bitmap(packet)); 703 uint8_t max_bitpool_value = avdtp_choose_sbc_max_bitpool_value(stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_max_bitpool_value(packet)); 704 uint8_t min_bitpool_value = avdtp_choose_sbc_min_bitpool_value(stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_min_bitpool_value(packet)); 705 706 config_storage[0] = (sampling_frequency << 4) | channel_mode; 707 config_storage[1] = (block_length << 4) | (subbands << 2) | allocation_method; 708 config_storage[2] = min_bitpool_value; 709 config_storage[3] = max_bitpool_value; 710 711 stream_endpoint->remote_configuration_bitmap = store_bit16(stream_endpoint->remote_configuration_bitmap, AVDTP_MEDIA_CODEC, 1); 712 stream_endpoint->remote_configuration.media_codec.media_type = AVDTP_AUDIO; 713 stream_endpoint->remote_configuration.media_codec.media_codec_type = AVDTP_CODEC_SBC; 714 stream_endpoint->remote_configuration.media_codec.media_codec_information_len = storage_size; 715 stream_endpoint->remote_configuration.media_codec.media_codec_information = config_storage; | 760 if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return; 761 if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return; 762 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_associated_with_acp_seid(acp_seid, context); 763 if (!stream_endpoint) return; 764 if (stream_endpoint->remote_sep_index == AVDTP_INVALID_SEP_INDEX) return; 765 connection->initiator_transaction_label++; 766 connection->acp_seid = acp_seid; 767 connection->int_seid = stream_endpoint->sep.seid; 768 stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_SUSPEND_STREAM_WITH_SEID; 769 avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); |
716} | 770} |
717 718uint8_t avdtp_choose_sbc_channel_mode(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_channel_mode_bitmap){ 719 uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information; 720 uint8_t channel_mode_bitmap = (media_codec[0] & 0x0F) & remote_channel_mode_bitmap; 721 722 uint8_t channel_mode = AVDTP_SBC_STEREO; 723 if (channel_mode_bitmap & AVDTP_SBC_JOINT_STEREO){ 724 channel_mode = AVDTP_SBC_JOINT_STEREO; 725 } else if (channel_mode_bitmap & AVDTP_SBC_STEREO){ 726 channel_mode = AVDTP_SBC_STEREO; 727 } else if (channel_mode_bitmap & AVDTP_SBC_DUAL_CHANNEL){ 728 channel_mode = AVDTP_SBC_DUAL_CHANNEL; 729 } else if (channel_mode_bitmap & AVDTP_SBC_MONO){ 730 channel_mode = AVDTP_SBC_MONO; 731 } 732 return channel_mode; 733} 734 735uint8_t avdtp_choose_sbc_allocation_method(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_allocation_method_bitmap){ 736 uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information; 737 uint8_t allocation_method_bitmap = (media_codec[1] & 0x03) & remote_allocation_method_bitmap; 738 739 uint8_t allocation_method = AVDTP_SBC_ALLOCATION_METHOD_LOUDNESS; 740 if (allocation_method_bitmap & AVDTP_SBC_ALLOCATION_METHOD_LOUDNESS){ 741 allocation_method = AVDTP_SBC_ALLOCATION_METHOD_LOUDNESS; 742 } else if (allocation_method_bitmap & AVDTP_SBC_ALLOCATION_METHOD_SNR){ 743 allocation_method = AVDTP_SBC_ALLOCATION_METHOD_SNR; 744 } 745 return allocation_method; 746} 747 748uint8_t avdtp_stream_endpoint_seid(avdtp_stream_endpoint_t * stream_endpoint){ 749 if (!stream_endpoint) return 0; 750 return stream_endpoint->sep.seid; 751} 752uint8_t avdtp_choose_sbc_subbands(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_subbands_bitmap){ 753 uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information; 754 uint8_t subbands_bitmap = ((media_codec[1] >> 2) & 0x03) & remote_subbands_bitmap; 755 756 uint8_t subbands = AVDTP_SBC_SUBBANDS_8; 757 if (subbands_bitmap & AVDTP_SBC_SUBBANDS_8){ 758 subbands = AVDTP_SBC_SUBBANDS_8; 759 } else if (subbands_bitmap & AVDTP_SBC_SUBBANDS_4){ 760 subbands = AVDTP_SBC_SUBBANDS_4; 761 } 762 return subbands; 763} 764 765uint8_t avdtp_choose_sbc_block_length(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_block_length_bitmap){ 766 uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information; 767 uint8_t block_length_bitmap = (media_codec[1] >> 4) & remote_block_length_bitmap; 768 769 uint8_t block_length = AVDTP_SBC_BLOCK_LENGTH_16; 770 if (block_length_bitmap & AVDTP_SBC_BLOCK_LENGTH_16){ 771 block_length = AVDTP_SBC_BLOCK_LENGTH_16; 772 } else if (block_length_bitmap & AVDTP_SBC_BLOCK_LENGTH_12){ 773 block_length = AVDTP_SBC_BLOCK_LENGTH_12; 774 } else if (block_length_bitmap & AVDTP_SBC_BLOCK_LENGTH_8){ 775 block_length = AVDTP_SBC_BLOCK_LENGTH_8; 776 } else if (block_length_bitmap & AVDTP_SBC_BLOCK_LENGTH_4){ 777 block_length = AVDTP_SBC_BLOCK_LENGTH_4; 778 } 779 return block_length; 780} 781 782uint8_t avdtp_choose_sbc_sampling_frequency(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_sampling_frequency_bitmap){ 783 uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information; 784 uint8_t sampling_frequency_bitmap = (media_codec[0] >> 4) & remote_sampling_frequency_bitmap; 785 786 uint8_t sampling_frequency = AVDTP_SBC_44100; 787 if (sampling_frequency_bitmap & AVDTP_SBC_48000){ 788 sampling_frequency = AVDTP_SBC_48000; 789 } else if (sampling_frequency_bitmap & AVDTP_SBC_44100){ 790 sampling_frequency = AVDTP_SBC_44100; 791 } else if (sampling_frequency_bitmap & AVDTP_SBC_32000){ 792 sampling_frequency = AVDTP_SBC_32000; 793 } else if (sampling_frequency_bitmap & AVDTP_SBC_16000){ 794 sampling_frequency = AVDTP_SBC_16000; 795 } 796 return sampling_frequency; 797} 798 799uint8_t avdtp_choose_sbc_max_bitpool_value(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_max_bitpool_value){ 800 uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information; 801 return btstack_min(media_codec[3], remote_max_bitpool_value); 802} 803 804uint8_t avdtp_choose_sbc_min_bitpool_value(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_min_bitpool_value){ 805 uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information; 806 return btstack_max(media_codec[2], remote_min_bitpool_value); 807} | |