Beispiel #1
0
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
    UNUSED(channel);
    UNUSED(size);

    uint8_t signal_identifier;
    uint8_t status;
    uint8_t local_seid;
    uint8_t remote_seid;
    uint16_t cid;
    bd_addr_t address;
    
    if (packet_type != HCI_EVENT_PACKET) return;
    if (hci_event_packet_get_type(packet) != HCI_EVENT_AVDTP_META) return;
    
    switch (packet[2]){
        case AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
            avdtp_subevent_signaling_connection_established_get_bd_addr(packet, sc.remote_addr);
            cid = avdtp_subevent_signaling_connection_established_get_avdtp_cid(packet);
            status = avdtp_subevent_signaling_connection_established_get_status(packet);
            if (status != 0){
                log_info("AVDTP_SUBEVENT_SIGNALING_CONNECTION failed status %d ---", status);
                a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, cid, sc.remote_addr, 0, 0, status);
                break;
            }
            
            sc.active_remote_sep = NULL;
            next_remote_sep_index_to_query = 0;
            if (!sc.local_stream_endpoint) {
                app_state = A2DP_CONNECTED;
                uint8_t event[11];
                int pos = 0;
                event[pos++] = HCI_EVENT_A2DP_META;
                event[pos++] = sizeof(event) - 2;
                event[pos++] = A2DP_SUBEVENT_INCOMING_CONNECTION_ESTABLISHED;
                little_endian_store_16(event, pos, cid);
                pos += 2;
                reverse_bd_addr(event+pos, sc.remote_addr);
                pos += 6;
                (*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
                return;
            }

            app_state = A2DP_W2_DISCOVER_SEPS;
            avdtp_source_discover_stream_endpoints(cid);
            break;
        
        case AVDTP_SUBEVENT_SIGNALING_SEP_FOUND:
            break;

        case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY:{
            if (!sc.local_stream_endpoint) {
                // printf("local seid %d \n", avdtp_subevent_signaling_media_codec_sbc_capability_get_local_seid(packet));
                return;
            }
            uint8_t sampling_frequency = avdtp_choose_sbc_sampling_frequency(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_sampling_frequency_bitmap(packet));
            uint8_t channel_mode = avdtp_choose_sbc_channel_mode(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_channel_mode_bitmap(packet));
            uint8_t block_length = avdtp_choose_sbc_block_length(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_block_length_bitmap(packet));
            uint8_t subbands = avdtp_choose_sbc_subbands(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_subbands_bitmap(packet));
            
            uint8_t allocation_method = avdtp_choose_sbc_allocation_method(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_allocation_method_bitmap(packet));
            uint8_t max_bitpool_value = avdtp_choose_sbc_max_bitpool_value(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_max_bitpool_value(packet));
            uint8_t min_bitpool_value = avdtp_choose_sbc_min_bitpool_value(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_min_bitpool_value(packet));

            sc.local_stream_endpoint->remote_configuration.media_codec.media_codec_information[0] = (sampling_frequency << 4) | channel_mode;
            sc.local_stream_endpoint->remote_configuration.media_codec.media_codec_information[1] = (block_length << 4) | (subbands << 2) | allocation_method;
            sc.local_stream_endpoint->remote_configuration.media_codec.media_codec_information[2] = min_bitpool_value;
            sc.local_stream_endpoint->remote_configuration.media_codec.media_codec_information[3] = max_bitpool_value;

            sc.local_stream_endpoint->remote_configuration_bitmap = store_bit16(sc.local_stream_endpoint->remote_configuration_bitmap, AVDTP_MEDIA_CODEC, 1);
            sc.local_stream_endpoint->remote_configuration.media_codec.media_type = AVDTP_AUDIO;
            sc.local_stream_endpoint->remote_configuration.media_codec.media_codec_type = AVDTP_CODEC_SBC;

            app_state = A2DP_W2_SET_CONFIGURATION;
            break;
        }
        case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY:
            log_info("received non SBC codec. not implemented");
            break;
        
        case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{
            // TODO check cid
            sc.sampling_frequency = avdtp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet);
            sc.block_length = avdtp_subevent_signaling_media_codec_sbc_configuration_get_block_length(packet);
            sc.subbands = avdtp_subevent_signaling_media_codec_sbc_configuration_get_subbands(packet);
            sc.allocation_method = avdtp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet) - 1;
            sc.max_bitpool_value = avdtp_subevent_signaling_media_codec_sbc_configuration_get_max_bitpool_value(packet);
            sc.channel_mode = avdtp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet);
            // TODO: deal with reconfigure: avdtp_subevent_signaling_media_codec_sbc_configuration_get_reconfigure(packet);
            break;
        }  
        case AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW: 
            cid = avdtp_subevent_streaming_can_send_media_packet_now_get_avdtp_cid(packet);
            a2dp_streaming_emit_can_send_media_packet_now(a2dp_source_context.a2dp_callback, cid, 0);
            break;
        
        case AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED:
            avdtp_subevent_streaming_connection_established_get_bd_addr(packet, address);
            status = avdtp_subevent_streaming_connection_established_get_status(packet);
            cid = avdtp_subevent_streaming_connection_established_get_avdtp_cid(packet);
            remote_seid = avdtp_subevent_streaming_connection_established_get_remote_seid(packet);
            local_seid  = avdtp_subevent_streaming_connection_established_get_local_seid(packet);
            if (status != 0){
                log_info("AVDTP_SUBEVENT_STREAMING_CONNECTION could not be established, status %d ---", status);
                a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, cid, address, local_seid, remote_seid, status);
                break;
            }

            app_state = A2DP_STREAMING_OPENED;
            a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, cid, address, local_seid, remote_seid, 0);
            log_info("AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED --- avdtp_cid 0x%02x, local seid %d, remote seid %d", cid, local_seid, remote_seid);
            break;

        case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
            // TODO check cid
            signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
            cid = avdtp_subevent_signaling_accept_get_avdtp_cid(packet);
            log_info("Accepted %d", signal_identifier);
            
            switch (app_state){
                case A2DP_W2_DISCOVER_SEPS:
                    app_state = A2DP_W2_GET_ALL_CAPABILITIES;
                    
                    sc.active_remote_sep = avdtp_source_remote_sep(cid, next_remote_sep_index_to_query++);
                    if (!sc.active_remote_sep) {
                        app_state = A2DP_IDLE; 
                        a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, cid, sc.remote_addr, 0, 0, AVDTP_SEID_DOES_NOT_EXIST);
                        break;
                    }
                    // printf("Query get caps for seid %d\n", sc.active_remote_sep->seid);
                    avdtp_source_get_capabilities(cid, sc.active_remote_sep->seid);
                    break;
                case A2DP_W2_GET_CAPABILITIES:
                case A2DP_W2_GET_ALL_CAPABILITIES:
                    if (next_remote_sep_index_to_query < avdtp_source_remote_seps_num(cid)){
                        sc.active_remote_sep = avdtp_source_remote_sep(cid, next_remote_sep_index_to_query++);
                        // printf("Query get caps for seid %d\n", sc.active_remote_sep->seid);
                        avdtp_source_get_capabilities(cid, sc.active_remote_sep->seid);
                    } else {
                        // printf("No more remote seps found\n");
                        app_state = A2DP_IDLE;
                        a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, cid, sc.remote_addr, 0, 0, AVDTP_SEID_DOES_NOT_EXIST);
                    }
                    break;
                case A2DP_W2_SET_CONFIGURATION:{
                    if (!sc.local_stream_endpoint) return;
                    app_state = A2DP_W2_GET_CONFIGURATION;
                    avdtp_source_set_configuration(cid, avdtp_stream_endpoint_seid(sc.local_stream_endpoint), sc.active_remote_sep->seid, sc.local_stream_endpoint->remote_configuration_bitmap, sc.local_stream_endpoint->remote_configuration);
                    break;
                }
                case A2DP_W2_GET_CONFIGURATION:
                    app_state = A2DP_W2_OPEN_STREAM_WITH_SEID;
                    avdtp_source_get_configuration(cid, sc.active_remote_sep->seid);
                    break;
                case A2DP_W2_OPEN_STREAM_WITH_SEID:{
                    app_state = A2DP_W4_OPEN_STREAM_WITH_SEID;
                    btstack_sbc_encoder_init(&sc.sbc_encoder_state, SBC_MODE_STANDARD, 
                        sc.block_length, sc.subbands, 
                        sc.allocation_method, sc.sampling_frequency, 
                        sc.max_bitpool_value,
                        sc.channel_mode);
                    avdtp_source_open_stream(cid, avdtp_stream_endpoint_seid(sc.local_stream_endpoint), sc.active_remote_sep->seid);
                    break;
                }
                case A2DP_STREAMING_OPENED:
                    if (!a2dp_source_context.a2dp_callback) return;
                    switch (signal_identifier){
                        case  AVDTP_SI_START:{
                            uint8_t event[6];
                            int pos = 0;
                            event[pos++] = HCI_EVENT_A2DP_META;
                            event[pos++] = sizeof(event) - 2;
                            event[pos++] = A2DP_SUBEVENT_STREAM_STARTED;
                            little_endian_store_16(event, pos, cid);
                            pos += 2;
                            event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
                            (*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
                            break;
                        }
                        case AVDTP_SI_SUSPEND:{
                            uint8_t event[6];
                            int pos = 0;
                            event[pos++] = HCI_EVENT_A2DP_META;
                            event[pos++] = sizeof(event) - 2;
                            event[pos++] = A2DP_SUBEVENT_STREAM_SUSPENDED;
                            little_endian_store_16(event, pos, cid);
                            pos += 2;
                            event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
                            (*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
                            break;
                        }
                        case AVDTP_SI_ABORT:
                        case AVDTP_SI_CLOSE:{
                            uint8_t event[6];
                            int pos = 0;
                            event[pos++] = HCI_EVENT_A2DP_META;
                            event[pos++] = sizeof(event) - 2;
                            event[pos++] = A2DP_SUBEVENT_STREAM_STOPPED;
                            little_endian_store_16(event, pos, cid);
                            pos += 2;
                            log_info("send A2DP_SUBEVENT_STREAM_RELEASED to app");
                            event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
                            (*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
                            break;
                        }
                        default:
                            break;
                    }
                    break;
                default:
                    app_state = A2DP_IDLE;
                    break;
            }
            
            break;
        case AVDTP_SUBEVENT_SIGNALING_REJECT:
            app_state = A2DP_IDLE;
            signal_identifier = avdtp_subevent_signaling_reject_get_signal_identifier(packet);
            log_info("Rejected %d", signal_identifier);
            break;
        case AVDTP_SUBEVENT_SIGNALING_GENERAL_REJECT:
            app_state = A2DP_IDLE;
            signal_identifier = avdtp_subevent_signaling_general_reject_get_signal_identifier(packet);
            log_info("Rejected %d", signal_identifier);
            break;
        case AVDTP_SUBEVENT_SIGNALING_CONNECTION_RELEASED:{
            app_state = A2DP_IDLE;
            uint8_t event[6];
            int pos = 0;
            event[pos++] = HCI_EVENT_A2DP_META;
            event[pos++] = sizeof(event) - 2;
            event[pos++] = A2DP_SUBEVENT_SIGNALING_CONNECTION_RELEASED;
            little_endian_store_16(event, pos, avdtp_subevent_streaming_connection_released_get_avdtp_cid(packet));
            pos += 2;
            event[pos++] = avdtp_subevent_streaming_connection_released_get_local_seid(packet);
            (*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
            break;
        }
        case AVDTP_SUBEVENT_STREAMING_CONNECTION_RELEASED:{
            app_state = A2DP_IDLE;
            uint8_t event[6];
            int pos = 0;
            event[pos++] = HCI_EVENT_A2DP_META;
            event[pos++] = sizeof(event) - 2;
            event[pos++] = A2DP_SUBEVENT_STREAM_RELEASED;
            little_endian_store_16(event, pos, avdtp_subevent_streaming_connection_released_get_avdtp_cid(packet));
            pos += 2;
            event[pos++] = avdtp_subevent_streaming_connection_released_get_local_seid(packet);
            (*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
            break;
        }
        default:
            app_state = A2DP_IDLE;
            log_info("not implemented");
            break; 
    }
}
Beispiel #2
0
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
    if (packet_type != HCI_EVENT_PACKET) return;
    if (hci_event_packet_get_type(packet) != HCI_EVENT_AVDTP_META) return;
    UNUSED(channel);
    UNUSED(size);
    uint8_t signal_identifier;
    uint8_t status;
    avdtp_sep_t sep;
    uint16_t avdtp_cid;

    switch (packet[2]){
        case AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
            avdtp_cid = avdtp_subevent_signaling_connection_established_get_avdtp_cid(packet);
            status = avdtp_subevent_signaling_connection_established_get_status(packet);
            if (status != 0){
                printf("AVDTP source signaling connection failed: status %d\n", status);
                break;
            }
            media_tracker.avdtp_cid = avdtp_subevent_signaling_connection_established_get_avdtp_cid(packet);
            printf("AVDTP source signaling connection established: avdtp_cid 0x%02x\n", avdtp_cid);
            break;
        
        case AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED:
            status = avdtp_subevent_streaming_connection_established_get_status(packet);
            if (status != 0){
                printf("Streaming connection failed: status %d\n", status);
                break;
            }
            avdtp_cid = avdtp_subevent_streaming_connection_established_get_avdtp_cid(packet);
            printf("Streaming connection established, avdtp_cid 0x%02x\n", avdtp_cid);
            break;

        case AVDTP_SUBEVENT_SIGNALING_SEP_FOUND:
            sep.seid = avdtp_subevent_signaling_sep_found_get_remote_seid(packet);;
            sep.in_use = avdtp_subevent_signaling_sep_found_get_in_use(packet);
            sep.media_type = avdtp_subevent_signaling_sep_found_get_media_type(packet);
            sep.type = avdtp_subevent_signaling_sep_found_get_sep_type(packet);
            printf("Found sep: seid %u, in_use %d, media type %d, sep type %d (1-SNK)\n", sep.seid, sep.in_use, sep.media_type, sep.type);
            break;
        
        case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY:{
            printf("CAPABILITY - MEDIA_CODEC_SBC: \n");
            adtvp_media_codec_information_sbc_t   sbc_capability;
            sbc_capability.sampling_frequency_bitmap = avdtp_subevent_signaling_media_codec_sbc_capability_get_sampling_frequency_bitmap(packet);
            sbc_capability.channel_mode_bitmap = avdtp_subevent_signaling_media_codec_sbc_capability_get_channel_mode_bitmap(packet);
            sbc_capability.block_length_bitmap = avdtp_subevent_signaling_media_codec_sbc_capability_get_block_length_bitmap(packet);
            sbc_capability.subbands_bitmap = avdtp_subevent_signaling_media_codec_sbc_capability_get_subbands_bitmap(packet);
            sbc_capability.allocation_method_bitmap = avdtp_subevent_signaling_media_codec_sbc_capability_get_allocation_method_bitmap(packet);
            sbc_capability.min_bitpool_value = avdtp_subevent_signaling_media_codec_sbc_capability_get_min_bitpool_value(packet);
            sbc_capability.max_bitpool_value = avdtp_subevent_signaling_media_codec_sbc_capability_get_max_bitpool_value(packet);
            dump_sbc_capability(sbc_capability);
            break;
        }
        case AVDTP_SUBEVENT_SIGNALING_MEDIA_TRANSPORT_CAPABILITY:
            printf("CAPABILITY - MEDIA_TRANSPORT supported on remote.\n");
            break;
        case AVDTP_SUBEVENT_SIGNALING_REPORTING_CAPABILITY:
            printf("CAPABILITY - REPORTING supported on remote.\n");
            break;
        case AVDTP_SUBEVENT_SIGNALING_RECOVERY_CAPABILITY:
            printf("CAPABILITY - RECOVERY supported on remote: \n");
            printf("    - recovery_type                %d\n", avdtp_subevent_signaling_recovery_capability_get_recovery_type(packet));
            printf("    - maximum_recovery_window_size %d\n", avdtp_subevent_signaling_recovery_capability_get_maximum_recovery_window_size(packet));
            printf("    - maximum_number_media_packets %d\n", avdtp_subevent_signaling_recovery_capability_get_maximum_number_media_packets(packet));
            break;
        case AVDTP_SUBEVENT_SIGNALING_CONTENT_PROTECTION_CAPABILITY:
            printf("CAPABILITY - CONTENT_PROTECTION supported on remote: \n");
            printf("    - cp_type           %d\n", avdtp_subevent_signaling_content_protection_capability_get_cp_type(packet));
            printf("    - cp_type_value_len %d\n", avdtp_subevent_signaling_content_protection_capability_get_cp_type_value_len(packet));
            printf("    - cp_type_value     \'%s\'\n", avdtp_subevent_signaling_content_protection_capability_get_cp_type_value(packet));
            break;
        case AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY:
            printf("CAPABILITY - MULTIPLEXING supported on remote: \n");
            printf("    - fragmentation                  %d\n", avdtp_subevent_signaling_multiplexing_capability_get_fragmentation(packet));
            printf("    - transport_identifiers_num      %d\n", avdtp_subevent_signaling_multiplexing_capability_get_transport_identifiers_num(packet));
            printf("    - transport_session_identifier_1 %d\n", avdtp_subevent_signaling_multiplexing_capability_get_transport_session_identifier_1(packet));
            printf("    - transport_session_identifier_2 %d\n", avdtp_subevent_signaling_multiplexing_capability_get_transport_session_identifier_2(packet));
            printf("    - transport_session_identifier_3 %d\n", avdtp_subevent_signaling_multiplexing_capability_get_transport_session_identifier_3(packet));
            printf("    - tcid_1                         %d\n", avdtp_subevent_signaling_multiplexing_capability_get_tcid_1(packet));
            printf("    - tcid_2                         %d\n", avdtp_subevent_signaling_multiplexing_capability_get_tcid_2(packet));
            printf("    - tcid_3                         %d\n", avdtp_subevent_signaling_multiplexing_capability_get_tcid_3(packet));
            break;
        case AVDTP_SUBEVENT_SIGNALING_DELAY_REPORTING_CAPABILITY:
            printf("CAPABILITY - DELAY_REPORTING supported on remote.\n");
            break;
        case AVDTP_SUBEVENT_SIGNALING_HEADER_COMPRESSION_CAPABILITY:
            printf("CAPABILITY - HEADER_COMPRESSION supported on remote: \n");
            printf("    - back_ch   %d\n", avdtp_subevent_signaling_header_compression_capability_get_back_ch(packet));
            printf("    - media     %d\n", avdtp_subevent_signaling_header_compression_capability_get_media(packet));
            printf("    - recovery  %d\n", avdtp_subevent_signaling_header_compression_capability_get_recovery(packet));
            break;

        case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{
            avdtp_media_codec_configuration_sbc_t sbc_configuration;
            sbc_configuration.reconfigure = avdtp_subevent_signaling_media_codec_sbc_configuration_get_reconfigure(packet);
            sbc_configuration.num_channels = avdtp_subevent_signaling_media_codec_sbc_configuration_get_num_channels(packet);
            sbc_configuration.sampling_frequency = avdtp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet);
            sbc_configuration.channel_mode = avdtp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet);
            sbc_configuration.block_length = avdtp_subevent_signaling_media_codec_sbc_configuration_get_block_length(packet);
            sbc_configuration.subbands = avdtp_subevent_signaling_media_codec_sbc_configuration_get_subbands(packet);
            sbc_configuration.allocation_method = avdtp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet);
            sbc_configuration.min_bitpool_value = avdtp_subevent_signaling_media_codec_sbc_configuration_get_min_bitpool_value(packet);
            sbc_configuration.max_bitpool_value = avdtp_subevent_signaling_media_codec_sbc_configuration_get_max_bitpool_value(packet);
            sbc_configuration.frames_per_buffer = sbc_configuration.subbands * sbc_configuration.block_length;
            dump_sbc_configuration(sbc_configuration);

            sc.block_length = sbc_configuration.block_length;
            sc.subbands     = sbc_configuration.subbands;
            sc.allocation_method = sbc_configuration.allocation_method - 1;
            sc.max_bitpool_value = sbc_configuration.max_bitpool_value;
            sc.sampling_frequency = sbc_configuration.sampling_frequency;
            sc.num_channels = 2;
            switch (sbc_configuration.channel_mode){
                case AVDTP_SBC_JOINT_STEREO:
                    sc.channel_mode = 3;
                    break;
                case AVDTP_SBC_STEREO:
                    sc.channel_mode = 2;
                    break;
                case AVDTP_SBC_DUAL_CHANNEL:
                    sc.channel_mode = 1;
                    break;
                case AVDTP_SBC_MONO:
                    sc.channel_mode = 0;
                    sc.num_channels = 1;
                    break;
            }
            break;
        }  

        case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY:
            printf("Received non SBC codec: not parsed\n");
            break;
        
        case AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW:
            a2dp_demo_send_media_packet();
            break;  


        case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
            // TODO check cid
            signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
            if (is_cmd_triggered_localy){
                is_cmd_triggered_localy = 0;
                printf("AVDTP Source command accepted\n");
            }
            
            switch (signal_identifier){
                case AVDTP_SI_OPEN:
                    initialize_sbc_encoder();  
                    break;
                case AVDTP_SI_SET_CONFIGURATION:
                    break;
                case  AVDTP_SI_START:
                    printf("Stream started.\n");
                    a2dp_demo_timer_start(&media_tracker);
                    break;
                case AVDTP_SI_SUSPEND:
                    printf("Stream paused.\n");
                    a2dp_demo_timer_pause(&media_tracker);
                    break;
                case AVDTP_SI_ABORT:
                case AVDTP_SI_CLOSE:
                    printf("Stream released.\n");
                    a2dp_demo_timer_stop(&media_tracker);
                    break;
                default:
                    break;
            }
            break;

        case AVDTP_SUBEVENT_SIGNALING_REJECT:
            signal_identifier = avdtp_subevent_signaling_reject_get_signal_identifier(packet);
            printf("Rejected %s\n", avdtp_si2str(signal_identifier));
            break;
        case AVDTP_SUBEVENT_SIGNALING_GENERAL_REJECT:
            signal_identifier = avdtp_subevent_signaling_general_reject_get_signal_identifier(packet);
            printf("Rejected %s\n", avdtp_si2str(signal_identifier));
            break;
        case AVDTP_SUBEVENT_STREAMING_CONNECTION_RELEASED:
            a2dp_demo_timer_stop(&media_tracker);
            printf("Streaming connection released.\n");
            break;
        case AVDTP_SUBEVENT_SIGNALING_CONNECTION_RELEASED:
            a2dp_demo_timer_stop(&media_tracker);
            printf("Signaling connection released.\n");
            break;
        default:
            printf("AVDTP Source PTS test: event not parsed 0x%02x\n", packet[2]);
            break; 
    }
}