1f7c85330SMatthias Ringwald /* 2f7c85330SMatthias Ringwald * Copyright (C) 2016 BlueKitchen GmbH 3f7c85330SMatthias Ringwald * 4f7c85330SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5f7c85330SMatthias Ringwald * modification, are permitted provided that the following conditions 6f7c85330SMatthias Ringwald * are met: 7f7c85330SMatthias Ringwald * 8f7c85330SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9f7c85330SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10f7c85330SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11f7c85330SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12f7c85330SMatthias Ringwald * documentation and/or other materials provided with the distribution. 13f7c85330SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14f7c85330SMatthias Ringwald * contributors may be used to endorse or promote products derived 15f7c85330SMatthias Ringwald * from this software without specific prior written permission. 16f7c85330SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17f7c85330SMatthias Ringwald * personal benefit and not for any commercial purpose or for 18f7c85330SMatthias Ringwald * monetary gain. 19f7c85330SMatthias Ringwald * 20f7c85330SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21f7c85330SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22f7c85330SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23f7c85330SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24f7c85330SMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25f7c85330SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26f7c85330SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27f7c85330SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28f7c85330SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29f7c85330SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30f7c85330SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31f7c85330SMatthias Ringwald * SUCH DAMAGE. 32f7c85330SMatthias Ringwald * 33f7c85330SMatthias Ringwald * Please inquire about commercial licensing options at 34f7c85330SMatthias Ringwald * [email protected] 35f7c85330SMatthias Ringwald * 36f7c85330SMatthias Ringwald */ 37f7c85330SMatthias Ringwald 38f7c85330SMatthias Ringwald /* 39f7c85330SMatthias Ringwald * sco_demo_util.c - send/receive test data via SCO, used by hfp_*_demo and hsp_*_demo 40f7c85330SMatthias Ringwald */ 41f7c85330SMatthias Ringwald 422ec72fbbSMilanka Ringwald 432ec72fbbSMilanka Ringwald #include <stdio.h> 442ec72fbbSMilanka Ringwald 45f7c85330SMatthias Ringwald #include "sco_demo_util.h" 46fcb08cdbSMilanka Ringwald #include "btstack_debug.h" 4735fd3fb9SMatthias Ringwald #include "classic/btstack_sbc.h" 4835fd3fb9SMatthias Ringwald #include "classic/btstack_cvsd_plc.h" 4935fd3fb9SMatthias Ringwald #include "classic/hfp_msbc.h" 5035fd3fb9SMatthias Ringwald #include "classic/hfp.h" 51fcb08cdbSMilanka Ringwald 5235fd3fb9SMatthias Ringwald #ifdef HAVE_POSIX_FILE_IO 53fbc7c9f2SMilanka Ringwald #include "wav_util.h" 5435fd3fb9SMatthias Ringwald #endif 55fbc7c9f2SMilanka Ringwald 56f7c85330SMatthias Ringwald // configure test mode 57f7c85330SMatthias Ringwald #define SCO_DEMO_MODE_SINE 0 58f7c85330SMatthias Ringwald #define SCO_DEMO_MODE_ASCII 1 59f7c85330SMatthias Ringwald #define SCO_DEMO_MODE_COUNTER 2 601a919128SMatthias Ringwald #define SCO_DEMO_MODE_55 3 611a919128SMatthias Ringwald #define SCO_DEMO_MODE_00 4 62f7c85330SMatthias Ringwald 638b29cfc6SMatthias Ringwald 64f7c85330SMatthias Ringwald // SCO demo configuration 65fcb08cdbSMilanka Ringwald #define SCO_DEMO_MODE SCO_DEMO_MODE_SINE 66f7c85330SMatthias Ringwald #define SCO_REPORT_PERIOD 100 67f7c85330SMatthias Ringwald 688b29cfc6SMatthias Ringwald #ifdef HAVE_POSIX_FILE_IO 698b29cfc6SMatthias Ringwald #define SCO_WAV_FILENAME "sco_input.wav" 70d5e5f834SMatthias Ringwald #define SCO_MSBC_OUT_FILENAME "sco_output.msbc" 712308e108SMilanka Ringwald #define SCO_MSBC_IN_FILENAME "sco_input.msbc" 72220eb563SMilanka Ringwald 73202da317SMilanka Ringwald #define SCO_WAV_DURATION_IN_SECONDS 15 748b29cfc6SMatthias Ringwald #endif 758b29cfc6SMatthias Ringwald 76f7c85330SMatthias Ringwald 77f7c85330SMatthias Ringwald #if defined(HAVE_PORTAUDIO) && (SCO_DEMO_MODE == SCO_DEMO_MODE_SINE) 78f7c85330SMatthias Ringwald #define USE_PORTAUDIO 79f7c85330SMatthias Ringwald #endif 80f7c85330SMatthias Ringwald 811a919128SMatthias Ringwald 82f7c85330SMatthias Ringwald #ifdef USE_PORTAUDIO 83f7c85330SMatthias Ringwald #include <portaudio.h> 84dbb41bfeSMilanka Ringwald #include "btstack_ring_buffer.h" 85dbb41bfeSMilanka Ringwald 868b29cfc6SMatthias Ringwald // portaudio config 878b29cfc6SMatthias Ringwald #define NUM_CHANNELS 1 88dbb41bfeSMilanka Ringwald 89dbb41bfeSMilanka Ringwald #define CVSD_SAMPLE_RATE 8000 90dbb41bfeSMilanka Ringwald #define CVSD_FRAMES_PER_BUFFER 24 91dbb41bfeSMilanka Ringwald #define CVSD_PA_SAMPLE_TYPE paInt8 92dbb41bfeSMilanka Ringwald #define CVSD_BYTES_PER_FRAME (1*NUM_CHANNELS) 93dbb41bfeSMilanka Ringwald #define CVSD_PREBUFFER_MS 5 94dbb41bfeSMilanka Ringwald #define CVSD_PREBUFFER_BYTES (CVSD_PREBUFFER_MS * CVSD_SAMPLE_RATE/1000 * CVSD_BYTES_PER_FRAME) 95dbb41bfeSMilanka Ringwald 96dbb41bfeSMilanka Ringwald #define MSBC_SAMPLE_RATE 16000 97dbb41bfeSMilanka Ringwald #define MSBC_FRAMES_PER_BUFFER 120 98dbb41bfeSMilanka Ringwald #define MSBC_PA_SAMPLE_TYPE paInt16 99dbb41bfeSMilanka Ringwald #define MSBC_BYTES_PER_FRAME (2*NUM_CHANNELS) 100dbb41bfeSMilanka Ringwald #define MSBC_PREBUFFER_MS 50 101dbb41bfeSMilanka Ringwald #define MSBC_PREBUFFER_BYTES (MSBC_PREBUFFER_MS * MSBC_SAMPLE_RATE/1000 * MSBC_BYTES_PER_FRAME) 102dbb41bfeSMilanka Ringwald 103f7c85330SMatthias Ringwald // portaudio globals 104f7c85330SMatthias Ringwald static PaStream * stream; 105dbb41bfeSMilanka Ringwald static uint8_t pa_stream_started = 0; 106dbb41bfeSMilanka Ringwald 107dbb41bfeSMilanka Ringwald static uint8_t ring_buffer_storage[2*MSBC_PREBUFFER_BYTES]; 108dbb41bfeSMilanka Ringwald static btstack_ring_buffer_t ring_buffer; 109f7c85330SMatthias Ringwald #endif 110f7c85330SMatthias Ringwald 111fcb08cdbSMilanka Ringwald static int dump_data = 1; 112fcb08cdbSMilanka Ringwald static int count_sent = 0; 113fcb08cdbSMilanka Ringwald static int count_received = 0; 114d76591efSMatthias Ringwald static uint8_t negotiated_codec = 0; 1151a919128SMatthias Ringwald #if SCO_DEMO_MODE != SCO_DEMO_MODE_55 1161a919128SMatthias Ringwald static int phase = 0; 1171a919128SMatthias Ringwald #endif 118fcb08cdbSMilanka Ringwald 119d5e5f834SMatthias Ringwald FILE * msbc_file_in; 120d5e5f834SMatthias Ringwald FILE * msbc_file_out; 1217294d009SMatthias Ringwald 122f7c85330SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 123d6a06398SMatthias Ringwald 12435fd3fb9SMatthias Ringwald // input signal: pre-computed sine wave, at 8000 kz 12535fd3fb9SMatthias Ringwald static const uint8_t sine_uint8[] = { 12635fd3fb9SMatthias Ringwald 0, 15, 31, 46, 61, 74, 86, 97, 107, 114, 12735fd3fb9SMatthias Ringwald 120, 124, 126, 126, 124, 120, 114, 107, 97, 86, 12835fd3fb9SMatthias Ringwald 74, 61, 46, 31, 15, 0, 241, 225, 210, 195, 12935fd3fb9SMatthias Ringwald 182, 170, 159, 149, 142, 136, 132, 130, 130, 132, 13035fd3fb9SMatthias Ringwald 136, 142, 149, 159, 170, 182, 195, 210, 225, 241, 13135fd3fb9SMatthias Ringwald }; 13235fd3fb9SMatthias Ringwald 13335fd3fb9SMatthias Ringwald 13435fd3fb9SMatthias Ringwald // input signal: pre-computed sine wave, 160 Hz at 16000 kHz 13535fd3fb9SMatthias Ringwald static const int16_t sine_int16[] = { 13635fd3fb9SMatthias Ringwald 0, 2057, 4107, 6140, 8149, 10126, 12062, 13952, 15786, 17557, 13735fd3fb9SMatthias Ringwald 19260, 20886, 22431, 23886, 25247, 26509, 27666, 28714, 29648, 30466, 13835fd3fb9SMatthias Ringwald 31163, 31738, 32187, 32509, 32702, 32767, 32702, 32509, 32187, 31738, 13935fd3fb9SMatthias Ringwald 31163, 30466, 29648, 28714, 27666, 26509, 25247, 23886, 22431, 20886, 14035fd3fb9SMatthias Ringwald 19260, 17557, 15786, 13952, 12062, 10126, 8149, 6140, 4107, 2057, 14135fd3fb9SMatthias Ringwald 0, -2057, -4107, -6140, -8149, -10126, -12062, -13952, -15786, -17557, 14235fd3fb9SMatthias Ringwald -19260, -20886, -22431, -23886, -25247, -26509, -27666, -28714, -29648, -30466, 14335fd3fb9SMatthias Ringwald -31163, -31738, -32187, -32509, -32702, -32767, -32702, -32509, -32187, -31738, 14435fd3fb9SMatthias Ringwald -31163, -30466, -29648, -28714, -27666, -26509, -25247, -23886, -22431, -20886, 14535fd3fb9SMatthias Ringwald -19260, -17557, -15786, -13952, -12062, -10126, -8149, -6140, -4107, -2057, 14635fd3fb9SMatthias Ringwald }; 14735fd3fb9SMatthias Ringwald 14835fd3fb9SMatthias Ringwald static void sco_demo_sine_wave_int8(int num_samples, int8_t * data){ 14935fd3fb9SMatthias Ringwald int i; 15035fd3fb9SMatthias Ringwald for (i=0; i<num_samples; i++){ 15135fd3fb9SMatthias Ringwald data[i] = (int8_t)sine_uint8[phase]; 15235fd3fb9SMatthias Ringwald phase++; 15335fd3fb9SMatthias Ringwald if (phase >= sizeof(sine_uint8)) phase = 0; 15435fd3fb9SMatthias Ringwald } 15535fd3fb9SMatthias Ringwald } 15635fd3fb9SMatthias Ringwald 15735fd3fb9SMatthias Ringwald static void sco_demo_sine_wave_int16(int num_samples, int16_t * data){ 15835fd3fb9SMatthias Ringwald int i; 15935fd3fb9SMatthias Ringwald for (i=0; i < num_samples; i++){ 16035fd3fb9SMatthias Ringwald data[i] = sine_int16[phase++]; 16135fd3fb9SMatthias Ringwald if (phase >= (sizeof(sine_int16) / sizeof(int16_t))){ 16235fd3fb9SMatthias Ringwald phase = 0; 16335fd3fb9SMatthias Ringwald } 16435fd3fb9SMatthias Ringwald } 16535fd3fb9SMatthias Ringwald } 1661a919128SMatthias Ringwald static int num_audio_frames = 0; 16735fd3fb9SMatthias Ringwald 16835fd3fb9SMatthias Ringwald static void sco_demo_fill_audio_frame(void){ 16935fd3fb9SMatthias Ringwald if (!hfp_msbc_can_encode_audio_frame_now()) return; 17035fd3fb9SMatthias Ringwald int num_samples = hfp_msbc_num_audio_samples_per_frame(); 17135fd3fb9SMatthias Ringwald int16_t sample_buffer[num_samples]; 17235fd3fb9SMatthias Ringwald sco_demo_sine_wave_int16(num_samples, sample_buffer); 17335fd3fb9SMatthias Ringwald hfp_msbc_encode_audio_frame(sample_buffer); 17435fd3fb9SMatthias Ringwald num_audio_frames++; 17535fd3fb9SMatthias Ringwald } 1768b29cfc6SMatthias Ringwald #ifdef SCO_WAV_FILENAME 1772afeea7fSMilanka Ringwald static btstack_sbc_decoder_state_t decoder_state; 17882e01da0SMilanka Ringwald static btstack_cvsd_plc_state_t cvsd_plc_state; 179dbb41bfeSMilanka Ringwald static int num_samples_to_write; 180dbb41bfeSMilanka Ringwald 181dbb41bfeSMilanka Ringwald #ifdef USE_PORTAUDIO 182dbb41bfeSMilanka Ringwald static int patestCallback( const void *inputBuffer, void *outputBuffer, 183dbb41bfeSMilanka Ringwald unsigned long framesPerBuffer, 184dbb41bfeSMilanka Ringwald const PaStreamCallbackTimeInfo* timeInfo, 185dbb41bfeSMilanka Ringwald PaStreamCallbackFlags statusFlags, 186dbb41bfeSMilanka Ringwald void *userData ) { 187dbb41bfeSMilanka Ringwald (void) timeInfo; /* Prevent unused variable warnings. */ 188dbb41bfeSMilanka Ringwald (void) statusFlags; 189dbb41bfeSMilanka Ringwald (void) inputBuffer; 190*3963d036SMatthias Ringwald (void) userData; 191dbb41bfeSMilanka Ringwald 192dbb41bfeSMilanka Ringwald uint32_t bytes_read = 0; 193dbb41bfeSMilanka Ringwald int bytes_per_buffer = framesPerBuffer; 194dbb41bfeSMilanka Ringwald if (negotiated_codec == HFP_CODEC_MSBC){ 195dbb41bfeSMilanka Ringwald bytes_per_buffer *= MSBC_BYTES_PER_FRAME; 196dbb41bfeSMilanka Ringwald } else { 197dbb41bfeSMilanka Ringwald bytes_per_buffer *= CVSD_BYTES_PER_FRAME; 198dbb41bfeSMilanka Ringwald } 199dbb41bfeSMilanka Ringwald 200dbb41bfeSMilanka Ringwald if (btstack_ring_buffer_bytes_available(&ring_buffer) >= bytes_per_buffer){ 201dbb41bfeSMilanka Ringwald btstack_ring_buffer_read(&ring_buffer, outputBuffer, bytes_per_buffer, &bytes_read); 202dbb41bfeSMilanka Ringwald } else { 203dbb41bfeSMilanka Ringwald printf("NOT ENOUGH DATA!\n"); 204dbb41bfeSMilanka Ringwald memset(outputBuffer, 0, bytes_per_buffer); 205dbb41bfeSMilanka Ringwald } 206dbb41bfeSMilanka Ringwald // printf("bytes avail after read: %d\n", btstack_ring_buffer_bytes_available(&ring_buffer)); 207dbb41bfeSMilanka Ringwald return 0; 208dbb41bfeSMilanka Ringwald } 209dbb41bfeSMilanka Ringwald #endif 2108b29cfc6SMatthias Ringwald 211fcb08cdbSMilanka Ringwald static void handle_pcm_data(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context){ 2129ec2630cSMatthias Ringwald UNUSED(context); 2139ec2630cSMatthias Ringwald UNUSED(sample_rate); 2149ec2630cSMatthias Ringwald 215dbb41bfeSMilanka Ringwald // printf("handle_pcm_data num samples %u, sample rate %d\n", num_samples, num_channels); 216dbb41bfeSMilanka Ringwald #ifdef USE_PORTAUDIO 217dbb41bfeSMilanka Ringwald if (!pa_stream_started && btstack_ring_buffer_bytes_available(&ring_buffer) >= MSBC_PREBUFFER_BYTES){ 218dbb41bfeSMilanka Ringwald /* -- start stream -- */ 219dbb41bfeSMilanka Ringwald PaError err = Pa_StartStream(stream); 220dbb41bfeSMilanka Ringwald if (err != paNoError){ 221dbb41bfeSMilanka Ringwald printf("Error starting the stream: \"%s\"\n", Pa_GetErrorText(err)); 222dbb41bfeSMilanka Ringwald return; 223dbb41bfeSMilanka Ringwald } 224dbb41bfeSMilanka Ringwald pa_stream_started = 1; 225dbb41bfeSMilanka Ringwald } 226dbb41bfeSMilanka Ringwald btstack_ring_buffer_write(&ring_buffer, (uint8_t *)data, num_samples*num_channels*2); 227dbb41bfeSMilanka Ringwald // printf("bytes avail after write: %d\n", btstack_ring_buffer_bytes_available(&ring_buffer)); 2289ec2630cSMatthias Ringwald #else 2299ec2630cSMatthias Ringwald UNUSED(num_channels); 230dbb41bfeSMilanka Ringwald #endif 231dbb41bfeSMilanka Ringwald 232fcb08cdbSMilanka Ringwald if (!num_samples_to_write) return; 233fcb08cdbSMilanka Ringwald 234fcb08cdbSMilanka Ringwald num_samples = btstack_min(num_samples, num_samples_to_write); 235fcb08cdbSMilanka Ringwald num_samples_to_write -= num_samples; 236fcb08cdbSMilanka Ringwald 237fbc7c9f2SMilanka Ringwald wav_writer_write_int16(num_samples, data); 238fcb08cdbSMilanka Ringwald 239fcb08cdbSMilanka Ringwald if (num_samples_to_write == 0){ 240fcb08cdbSMilanka Ringwald sco_demo_close(); 241fcb08cdbSMilanka Ringwald } 242fcb08cdbSMilanka Ringwald } 243fcb08cdbSMilanka Ringwald 244fcb08cdbSMilanka Ringwald static void sco_demo_init_mSBC(void){ 245fbc7c9f2SMilanka Ringwald int sample_rate = 16000; 246fbc7c9f2SMilanka Ringwald wav_writer_open(SCO_WAV_FILENAME, 1, sample_rate); 247fbc7c9f2SMilanka Ringwald btstack_sbc_decoder_init(&decoder_state, SBC_MODE_mSBC, &handle_pcm_data, NULL); 248fcb08cdbSMilanka Ringwald 249fbc7c9f2SMilanka Ringwald num_samples_to_write = sample_rate * SCO_WAV_DURATION_IN_SECONDS; 250220eb563SMilanka Ringwald 251220eb563SMilanka Ringwald hfp_msbc_init(); 252220eb563SMilanka Ringwald sco_demo_fill_audio_frame(); 253973d7173SMatthias Ringwald 254d5e5f834SMatthias Ringwald #ifdef SCO_MSBC_IN_FILENAME 255d5e5f834SMatthias Ringwald msbc_file_in = fopen(SCO_MSBC_IN_FILENAME, "wb"); 256d5e5f834SMatthias Ringwald printf("SCO Demo: creating mSBC in file %s, %p\n", SCO_MSBC_IN_FILENAME, msbc_file_in); 257d5e5f834SMatthias Ringwald #endif 2587294d009SMatthias Ringwald #ifdef SCO_MSBC_OUT_FILENAME 259d5e5f834SMatthias Ringwald msbc_file_out = fopen(SCO_MSBC_OUT_FILENAME, "wb"); 260d5e5f834SMatthias Ringwald printf("SCO Demo: creating mSBC out file %s, %p\n", SCO_MSBC_OUT_FILENAME, msbc_file_out); 2617294d009SMatthias Ringwald #endif 262dbb41bfeSMilanka Ringwald 263dbb41bfeSMilanka Ringwald #ifdef USE_PORTAUDIO 264dbb41bfeSMilanka Ringwald PaError err; 265dbb41bfeSMilanka Ringwald PaStreamParameters outputParameters; 266dbb41bfeSMilanka Ringwald 267dbb41bfeSMilanka Ringwald /* -- initialize PortAudio -- */ 268dbb41bfeSMilanka Ringwald err = Pa_Initialize(); 269dbb41bfeSMilanka Ringwald if( err != paNoError ) return; 270dbb41bfeSMilanka Ringwald /* -- setup input and output -- */ 271dbb41bfeSMilanka Ringwald outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ 272dbb41bfeSMilanka Ringwald outputParameters.channelCount = NUM_CHANNELS; 273dbb41bfeSMilanka Ringwald outputParameters.sampleFormat = MSBC_PA_SAMPLE_TYPE; 274dbb41bfeSMilanka Ringwald outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency; 275dbb41bfeSMilanka Ringwald outputParameters.hostApiSpecificStreamInfo = NULL; 276dbb41bfeSMilanka Ringwald /* -- setup stream -- */ 277dbb41bfeSMilanka Ringwald err = Pa_OpenStream( 278dbb41bfeSMilanka Ringwald &stream, 279dbb41bfeSMilanka Ringwald NULL, // &inputParameters, 280dbb41bfeSMilanka Ringwald &outputParameters, 281dbb41bfeSMilanka Ringwald MSBC_SAMPLE_RATE, 282dbb41bfeSMilanka Ringwald MSBC_FRAMES_PER_BUFFER, 283dbb41bfeSMilanka Ringwald paClipOff, /* we won't output out of range samples so don't bother clipping them */ 284dbb41bfeSMilanka Ringwald patestCallback, /* no callback, use blocking API */ 285dbb41bfeSMilanka Ringwald NULL ); /* no callback, so no callback userData */ 286dbb41bfeSMilanka Ringwald if (err != paNoError){ 287dbb41bfeSMilanka Ringwald printf("Error initializing portaudio: \"%s\"\n", Pa_GetErrorText(err)); 288dbb41bfeSMilanka Ringwald return; 289dbb41bfeSMilanka Ringwald } 290dbb41bfeSMilanka Ringwald memset(ring_buffer_storage, 0, sizeof(ring_buffer_storage)); 291dbb41bfeSMilanka Ringwald btstack_ring_buffer_init(&ring_buffer, ring_buffer_storage, sizeof(ring_buffer_storage)); 292dbb41bfeSMilanka Ringwald pa_stream_started = 0; 293dbb41bfeSMilanka Ringwald #endif 294fcb08cdbSMilanka Ringwald } 295fcb08cdbSMilanka Ringwald 296fcb08cdbSMilanka Ringwald static void sco_demo_receive_mSBC(uint8_t * packet, uint16_t size){ 297fcb08cdbSMilanka Ringwald if (num_samples_to_write){ 298d5e5f834SMatthias Ringwald if (msbc_file_in){ 299d5e5f834SMatthias Ringwald // log incoming mSBC data for testing 300d5e5f834SMatthias Ringwald fwrite(packet+3, size-3, 1, msbc_file_in); 301d5e5f834SMatthias Ringwald } 302fcb08cdbSMilanka Ringwald } 303dbb41bfeSMilanka Ringwald btstack_sbc_decoder_process_data(&decoder_state, (packet[1] >> 4) & 3, packet+3, size-3); 304fcb08cdbSMilanka Ringwald } 305fcb08cdbSMilanka Ringwald 306fbc7c9f2SMilanka Ringwald static void sco_demo_init_CVSD(void){ 307fbc7c9f2SMilanka Ringwald int sample_rate = 8000; 308fbc7c9f2SMilanka Ringwald wav_writer_open(SCO_WAV_FILENAME, 1, sample_rate); 309fbc7c9f2SMilanka Ringwald btstack_cvsd_plc_init(&cvsd_plc_state); 310fbc7c9f2SMilanka Ringwald num_samples_to_write = sample_rate * SCO_WAV_DURATION_IN_SECONDS; 311dbb41bfeSMilanka Ringwald 312dbb41bfeSMilanka Ringwald #ifdef USE_PORTAUDIO 313dbb41bfeSMilanka Ringwald PaError err; 314dbb41bfeSMilanka Ringwald PaStreamParameters outputParameters; 315dbb41bfeSMilanka Ringwald 316dbb41bfeSMilanka Ringwald /* -- initialize PortAudio -- */ 317dbb41bfeSMilanka Ringwald err = Pa_Initialize(); 318dbb41bfeSMilanka Ringwald if( err != paNoError ) return; 319dbb41bfeSMilanka Ringwald /* -- setup input and output -- */ 320dbb41bfeSMilanka Ringwald outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ 321dbb41bfeSMilanka Ringwald outputParameters.channelCount = NUM_CHANNELS; 322dbb41bfeSMilanka Ringwald outputParameters.sampleFormat = CVSD_PA_SAMPLE_TYPE; 323dbb41bfeSMilanka Ringwald outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency; 324dbb41bfeSMilanka Ringwald outputParameters.hostApiSpecificStreamInfo = NULL; 325dbb41bfeSMilanka Ringwald /* -- setup stream -- */ 326dbb41bfeSMilanka Ringwald err = Pa_OpenStream( 327dbb41bfeSMilanka Ringwald &stream, 328dbb41bfeSMilanka Ringwald NULL, // &inputParameters, 329dbb41bfeSMilanka Ringwald &outputParameters, 330dbb41bfeSMilanka Ringwald CVSD_SAMPLE_RATE, 331dbb41bfeSMilanka Ringwald CVSD_FRAMES_PER_BUFFER, 332dbb41bfeSMilanka Ringwald paClipOff, /* we won't output out of range samples so don't bother clipping them */ 333dbb41bfeSMilanka Ringwald patestCallback, /* no callback, use blocking API */ 334dbb41bfeSMilanka Ringwald NULL ); /* no callback, so no callback userData */ 335dbb41bfeSMilanka Ringwald if (err != paNoError){ 336dbb41bfeSMilanka Ringwald printf("Error initializing portaudio: \"%s\"\n", Pa_GetErrorText(err)); 337dbb41bfeSMilanka Ringwald return; 338dbb41bfeSMilanka Ringwald } 339dbb41bfeSMilanka Ringwald memset(ring_buffer_storage, 0, sizeof(ring_buffer_storage)); 340dbb41bfeSMilanka Ringwald btstack_ring_buffer_init(&ring_buffer, ring_buffer_storage, sizeof(ring_buffer_storage)); 341dbb41bfeSMilanka Ringwald pa_stream_started = 0; 342dbb41bfeSMilanka Ringwald #endif 343fbc7c9f2SMilanka Ringwald } 344fbc7c9f2SMilanka Ringwald 345fcb08cdbSMilanka Ringwald static void sco_demo_receive_CVSD(uint8_t * packet, uint16_t size){ 346dbb41bfeSMilanka Ringwald if (!num_samples_to_write) return; 347dbb41bfeSMilanka Ringwald 348fcb08cdbSMilanka Ringwald const int num_samples = size - 3; 349fcb08cdbSMilanka Ringwald const int samples_to_write = btstack_min(num_samples, num_samples_to_write); 35082e01da0SMilanka Ringwald int8_t audio_frame_out[24]; 351379d044eSMilanka Ringwald 352dbb41bfeSMilanka Ringwald 353fbc7c9f2SMilanka Ringwald // memcpy(audio_frame_out, (int8_t*)(packet+3), 24); 354fbc7c9f2SMilanka Ringwald btstack_cvsd_plc_process_data(&cvsd_plc_state, (int8_t *)(packet+3), num_samples, audio_frame_out); 3551a919128SMatthias Ringwald // int8_t * audio_frame_out = (int8_t*)&packet[3]; 356379d044eSMilanka Ringwald 357fbc7c9f2SMilanka Ringwald wav_writer_write_int8(samples_to_write, audio_frame_out); 358fcb08cdbSMilanka Ringwald num_samples_to_write -= samples_to_write; 359fcb08cdbSMilanka Ringwald if (num_samples_to_write == 0){ 360fcb08cdbSMilanka Ringwald sco_demo_close(); 361fcb08cdbSMilanka Ringwald } 362dbb41bfeSMilanka Ringwald #ifdef USE_PORTAUDIO 363dbb41bfeSMilanka Ringwald if (!pa_stream_started && btstack_ring_buffer_bytes_available(&ring_buffer) >= CVSD_PREBUFFER_BYTES){ 364dbb41bfeSMilanka Ringwald /* -- start stream -- */ 365dbb41bfeSMilanka Ringwald PaError err = Pa_StartStream(stream); 366dbb41bfeSMilanka Ringwald if (err != paNoError){ 367dbb41bfeSMilanka Ringwald printf("Error starting the stream: \"%s\"\n", Pa_GetErrorText(err)); 368dbb41bfeSMilanka Ringwald return; 369fcb08cdbSMilanka Ringwald } 370dbb41bfeSMilanka Ringwald pa_stream_started = 1; 371dbb41bfeSMilanka Ringwald } 372dbb41bfeSMilanka Ringwald btstack_ring_buffer_write(&ring_buffer, (uint8_t *)audio_frame_out, samples_to_write); 373dbb41bfeSMilanka Ringwald #endif 374fcb08cdbSMilanka Ringwald } 375fcb08cdbSMilanka Ringwald 3768b29cfc6SMatthias Ringwald #endif 3774a96141eSMatthias Ringwald #endif 3788b29cfc6SMatthias Ringwald 379fcb08cdbSMilanka Ringwald void sco_demo_close(void){ 380fcb08cdbSMilanka Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 38126463303SMilanka Ringwald #if defined(SCO_WAV_FILENAME) || defined(SCO_SBC_FILENAME) 382fbc7c9f2SMilanka Ringwald wav_writer_close(); 38326463303SMilanka Ringwald printf("SCO demo statistics: "); 38426463303SMilanka Ringwald if (negotiated_codec == HFP_CODEC_MSBC){ 38526463303SMilanka Ringwald printf("Used mSBC with PLC, number of processed frames: \n - %d good frames, \n - %d zero frames, \n - %d bad frames.", decoder_state.good_frames_nr, decoder_state.zero_frames_nr, decoder_state.bad_frames_nr); 38626463303SMilanka Ringwald } else { 38726463303SMilanka Ringwald printf("Used CVSD with PLC, number of proccesed frames: \n - %d good frames, \n - %d bad frames.", cvsd_plc_state.good_frames_nr, cvsd_plc_state.bad_frames_nr); 38826463303SMilanka Ringwald } 38926463303SMilanka Ringwald #endif 39026463303SMilanka Ringwald #endif 39126463303SMilanka Ringwald 392dbb41bfeSMilanka Ringwald #ifdef HAVE_PORTAUDIO 393dbb41bfeSMilanka Ringwald if (pa_stream_started){ 394dbb41bfeSMilanka Ringwald PaError err = Pa_StopStream(stream); 395dbb41bfeSMilanka Ringwald if (err != paNoError){ 396dbb41bfeSMilanka Ringwald printf("Error stopping the stream: \"%s\"\n", Pa_GetErrorText(err)); 397dbb41bfeSMilanka Ringwald return; 398dbb41bfeSMilanka Ringwald } 399dbb41bfeSMilanka Ringwald pa_stream_started = 0; 400dbb41bfeSMilanka Ringwald err = Pa_CloseStream(stream); 401dbb41bfeSMilanka Ringwald if (err != paNoError){ 402dbb41bfeSMilanka Ringwald printf("Error closing the stream: \"%s\"\n", Pa_GetErrorText(err)); 403dbb41bfeSMilanka Ringwald return; 404dbb41bfeSMilanka Ringwald } 405dbb41bfeSMilanka Ringwald 406dbb41bfeSMilanka Ringwald err = Pa_Terminate(); 407dbb41bfeSMilanka Ringwald if (err != paNoError){ 408dbb41bfeSMilanka Ringwald printf("Error terminating portaudio: \"%s\"\n", Pa_GetErrorText(err)); 409dbb41bfeSMilanka Ringwald return; 410dbb41bfeSMilanka Ringwald } 411dbb41bfeSMilanka Ringwald } 412dbb41bfeSMilanka Ringwald #endif 413dbb41bfeSMilanka Ringwald 41426463303SMilanka Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 415fcb08cdbSMilanka Ringwald #ifdef SCO_WAV_FILENAME 416fcb08cdbSMilanka Ringwald 417613518d1SMilanka Ringwald #if 0 418fcb08cdbSMilanka Ringwald printf("SCO Demo: closing wav file\n"); 419220eb563SMilanka Ringwald if (negotiated_codec == HFP_CODEC_MSBC){ 4206e046a36SMatthias Ringwald wav_writer_state_t * writer_state = &wav_writer_state; 421fcb08cdbSMilanka Ringwald if (!writer_state->wav_file) return; 422fcb08cdbSMilanka Ringwald rewind(writer_state->wav_file); 4232afeea7fSMilanka Ringwald write_wav_header(writer_state->wav_file, writer_state->total_num_samples, btstack_sbc_decoder_num_channels(&decoder_state), btstack_sbc_decoder_sample_rate(&decoder_state),2); 424fcb08cdbSMilanka Ringwald fclose(writer_state->wav_file); 425fcb08cdbSMilanka Ringwald writer_state->wav_file = NULL; 426fcb08cdbSMilanka Ringwald } 427613518d1SMilanka Ringwald #endif 428fcb08cdbSMilanka Ringwald #endif 429fcb08cdbSMilanka Ringwald #endif 430fcb08cdbSMilanka Ringwald } 431fcb08cdbSMilanka Ringwald 432fcb08cdbSMilanka Ringwald void sco_demo_set_codec(uint8_t codec){ 433fcb08cdbSMilanka Ringwald if (negotiated_codec == codec) return; 434fcb08cdbSMilanka Ringwald negotiated_codec = codec; 435fcb08cdbSMilanka Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 43617cd946eSMatthias Ringwald #if defined(SCO_WAV_FILENAME) || defined(SCO_SBC_FILENAME) 437220eb563SMilanka Ringwald if (negotiated_codec == HFP_CODEC_MSBC){ 438fcb08cdbSMilanka Ringwald sco_demo_init_mSBC(); 439fcb08cdbSMilanka Ringwald } else { 440fcb08cdbSMilanka Ringwald sco_demo_init_CVSD(); 441fcb08cdbSMilanka Ringwald } 442fcb08cdbSMilanka Ringwald #endif 443fcb08cdbSMilanka Ringwald #endif 444fcb08cdbSMilanka Ringwald } 445fcb08cdbSMilanka Ringwald 446f7c85330SMatthias Ringwald void sco_demo_init(void){ 447f7c85330SMatthias Ringwald 448f7c85330SMatthias Ringwald // status 449f7c85330SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 450f7c85330SMatthias Ringwald #ifdef HAVE_PORTAUDIO 451f7c85330SMatthias Ringwald printf("SCO Demo: Sending sine wave, audio output via portaudio.\n"); 452f7c85330SMatthias Ringwald #else 453f7c85330SMatthias Ringwald printf("SCO Demo: Sending sine wave, hexdump received data.\n"); 454f7c85330SMatthias Ringwald #endif 455f7c85330SMatthias Ringwald #endif 456f7c85330SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_ASCII 457f7c85330SMatthias Ringwald printf("SCO Demo: Sending ASCII blocks, print received data.\n"); 458f7c85330SMatthias Ringwald #endif 459f7c85330SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_COUNTER 460f7c85330SMatthias Ringwald printf("SCO Demo: Sending counter value, hexdump received data.\n"); 461f7c85330SMatthias Ringwald #endif 462f7c85330SMatthias Ringwald 4637294d009SMatthias Ringwald #if SCO_DEMO_MODE != SCO_DEMO_MODE_SINE 464f7c85330SMatthias Ringwald hci_set_sco_voice_setting(0x03); // linear, unsigned, 8-bit, transparent 4657294d009SMatthias Ringwald #endif 466f7c85330SMatthias Ringwald 467f7c85330SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_ASCII 468f7c85330SMatthias Ringwald phase = 'a'; 469f7c85330SMatthias Ringwald #endif 470f7c85330SMatthias Ringwald } 471f7c85330SMatthias Ringwald 4721a919128SMatthias Ringwald void sco_report(void); 4731a919128SMatthias Ringwald void sco_report(void){ 4744a96141eSMatthias Ringwald printf("SCO: sent %u, received %u\n", count_sent, count_received); 4754a96141eSMatthias Ringwald } 476f7c85330SMatthias Ringwald 477f7c85330SMatthias Ringwald void sco_demo_send(hci_con_handle_t sco_handle){ 478f7c85330SMatthias Ringwald 479f7c85330SMatthias Ringwald if (!sco_handle) return; 480f7c85330SMatthias Ringwald 481f7c85330SMatthias Ringwald const int sco_packet_length = 24 + 3; // hci_get_sco_packet_length(); 482f7c85330SMatthias Ringwald const int sco_payload_length = sco_packet_length - 3; 483f7c85330SMatthias Ringwald 484f7c85330SMatthias Ringwald hci_reserve_packet_buffer(); 485f7c85330SMatthias Ringwald uint8_t * sco_packet = hci_get_outgoing_packet_buffer(); 486f7c85330SMatthias Ringwald // set handle + flags 487f7c85330SMatthias Ringwald little_endian_store_16(sco_packet, 0, sco_handle); 488f7c85330SMatthias Ringwald // set len 489f7c85330SMatthias Ringwald sco_packet[2] = sco_payload_length; 490220eb563SMilanka Ringwald const int audio_samples_per_packet = sco_payload_length; // for 8-bit data. for 16-bit data it's /2 491f7c85330SMatthias Ringwald 492f7c85330SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 493220eb563SMilanka Ringwald if (negotiated_codec == HFP_CODEC_MSBC){ 494220eb563SMilanka Ringwald 495220eb563SMilanka Ringwald if (hfp_msbc_num_bytes_in_stream() < sco_payload_length){ 496220eb563SMilanka Ringwald log_error("mSBC stream is empty."); 497220eb563SMilanka Ringwald } 498220eb563SMilanka Ringwald hfp_msbc_read_from_stream(sco_packet + 3, sco_payload_length); 499d5e5f834SMatthias Ringwald if (msbc_file_out){ 500d76591efSMatthias Ringwald // log outgoing mSBC data for testing 501d5e5f834SMatthias Ringwald fwrite(sco_packet + 3, sco_payload_length, 1, msbc_file_out); 502d76591efSMatthias Ringwald } 5037294d009SMatthias Ringwald 504220eb563SMilanka Ringwald sco_demo_fill_audio_frame(); 505220eb563SMilanka Ringwald } else { 50635fd3fb9SMatthias Ringwald sco_demo_sine_wave_int8(audio_samples_per_packet, (int8_t *) (sco_packet+3)); 507220eb563SMilanka Ringwald } 5081a919128SMatthias Ringwald #endif 509f7c85330SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_ASCII 510220eb563SMilanka Ringwald memset(&sco_packet[3], phase++, audio_samples_per_packet); 511f7c85330SMatthias Ringwald if (phase > 'z') phase = 'a'; 5121a919128SMatthias Ringwald #endif 5131a919128SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_COUNTER 51438b2eaafSMatthias Ringwald int j; 515220eb563SMilanka Ringwald for (j=0;j<audio_samples_per_packet;j++){ 51638b2eaafSMatthias Ringwald sco_packet[3+j] = phase++; 517f7c85330SMatthias Ringwald } 518f7c85330SMatthias Ringwald #endif 5191a919128SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_55 5201a919128SMatthias Ringwald int j; 5211a919128SMatthias Ringwald for (j=0;j<audio_samples_per_packet;j++){ 5221a919128SMatthias Ringwald // sco_packet[3+j] = j & 1 ? 0x35 : 0x53; 5231a919128SMatthias Ringwald sco_packet[3+j] = 0x55; 5241a919128SMatthias Ringwald } 5251a919128SMatthias Ringwald #endif 5261a919128SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_00 5271a919128SMatthias Ringwald int j; 5281a919128SMatthias Ringwald for (j=0;j<audio_samples_per_packet;j++){ 5291a919128SMatthias Ringwald sco_packet[3+j] = 0x00; 5301a919128SMatthias Ringwald } 5311a919128SMatthias Ringwald // additional hack 5321a919128SMatthias Ringwald // big_endian_store_16(sco_packet, 5, phase++); 5331a919128SMatthias Ringwald (void) phase; 534f7c85330SMatthias Ringwald #endif 535220eb563SMilanka Ringwald 536f7c85330SMatthias Ringwald hci_send_sco_packet_buffer(sco_packet_length); 537f7c85330SMatthias Ringwald 538f7c85330SMatthias Ringwald // request another send event 539f7c85330SMatthias Ringwald hci_request_sco_can_send_now_event(); 540f7c85330SMatthias Ringwald 5414a96141eSMatthias Ringwald count_sent++; 5421a919128SMatthias Ringwald #if SCO_DEMO_MODE != SCO_DEMO_MODE_55 5434a96141eSMatthias Ringwald if ((count_sent % SCO_REPORT_PERIOD) == 0) sco_report(); 5441a919128SMatthias Ringwald #endif 545f7c85330SMatthias Ringwald } 546f7c85330SMatthias Ringwald 547f7c85330SMatthias Ringwald /** 548f7c85330SMatthias Ringwald * @brief Process received data 549f7c85330SMatthias Ringwald */ 5501a919128SMatthias Ringwald #define ANSI_COLOR_RED "\x1b[31m" 5511a919128SMatthias Ringwald #define ANSI_COLOR_GREEN "\x1b[32m" 5521a919128SMatthias Ringwald #define ANSI_COLOR_YELLOW "\x1b[33m" 5531a919128SMatthias Ringwald #define ANSI_COLOR_BLUE "\x1b[34m" 5541a919128SMatthias Ringwald #define ANSI_COLOR_MAGENTA "\x1b[35m" 5551a919128SMatthias Ringwald #define ANSI_COLOR_CYAN "\x1b[36m" 5561a919128SMatthias Ringwald #define ANSI_COLOR_RESET "\x1b[0m" 5571a919128SMatthias Ringwald 558f7c85330SMatthias Ringwald void sco_demo_receive(uint8_t * packet, uint16_t size){ 559f7c85330SMatthias Ringwald 560fcb08cdbSMilanka Ringwald dump_data = 1; 5618b29cfc6SMatthias Ringwald 5624a96141eSMatthias Ringwald count_received++; 5631a919128SMatthias Ringwald static uint32_t packets = 0; 5641a919128SMatthias Ringwald static uint32_t crc_errors = 0; 5651a919128SMatthias Ringwald static uint32_t data_received = 0; 5661a919128SMatthias Ringwald static uint32_t byte_errors = 0; 5674a96141eSMatthias Ringwald 5681a919128SMatthias Ringwald data_received += size - 3; 5691a919128SMatthias Ringwald packets++; 5701a919128SMatthias Ringwald if (data_received > 100000){ 5711a919128SMatthias Ringwald printf("Summary: data %07u, packets %04u, packet with crc errors %0u, byte errors %04u\n", data_received, packets, crc_errors, byte_errors); 5721a919128SMatthias Ringwald crc_errors = 0; 5731a919128SMatthias Ringwald byte_errors = 0; 5741a919128SMatthias Ringwald data_received = 0; 5751a919128SMatthias Ringwald packets = 0; 5761a919128SMatthias Ringwald } 5774a96141eSMatthias Ringwald 5784a96141eSMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_SINE 5798b29cfc6SMatthias Ringwald #ifdef SCO_WAV_FILENAME 580220eb563SMilanka Ringwald if (negotiated_codec == HFP_CODEC_MSBC){ 581fcb08cdbSMilanka Ringwald sco_demo_receive_mSBC(packet, size); 582fcb08cdbSMilanka Ringwald } else { 583fcb08cdbSMilanka Ringwald sco_demo_receive_CVSD(packet, size); 5848b29cfc6SMatthias Ringwald } 585dbb41bfeSMilanka Ringwald dump_data = 0; 5868b29cfc6SMatthias Ringwald #endif 5874a96141eSMatthias Ringwald #endif 5888b29cfc6SMatthias Ringwald 589b3f76298SMilanka Ringwald if (packet[1] & 0x30){ 5901a919128SMatthias Ringwald crc_errors++; 5911a919128SMatthias Ringwald // printf("SCO CRC Error: %x - data: ", (packet[1] & 0x30) >> 4); 5921a919128SMatthias Ringwald // printf_hexdump(&packet[3], size-3); 593f7c85330SMatthias Ringwald return; 594f7c85330SMatthias Ringwald } 5958b29cfc6SMatthias Ringwald if (dump_data){ 596f7c85330SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_ASCII 5971a919128SMatthias Ringwald printf("data: "); 598f7c85330SMatthias Ringwald int i; 599f7c85330SMatthias Ringwald for (i=3;i<size;i++){ 600f7c85330SMatthias Ringwald printf("%c", packet[i]); 601f7c85330SMatthias Ringwald } 602f7c85330SMatthias Ringwald printf("\n"); 6038b29cfc6SMatthias Ringwald dump_data = 0; 6041a919128SMatthias Ringwald #endif 6051a919128SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_COUNTER 6061a919128SMatthias Ringwald // colored hexdump with expected 6071a919128SMatthias Ringwald static uint8_t expected_byte = 0; 6081a919128SMatthias Ringwald int i; 6091a919128SMatthias Ringwald printf("data: "); 6101a919128SMatthias Ringwald for (i=3;i<size;i++){ 6111a919128SMatthias Ringwald if (packet[i] != expected_byte){ 6121a919128SMatthias Ringwald printf(ANSI_COLOR_RED "%02x " ANSI_COLOR_RESET, packet[i]); 6131a919128SMatthias Ringwald } else { 6141a919128SMatthias Ringwald printf("%02x ", packet[i]); 6151a919128SMatthias Ringwald } 6161a919128SMatthias Ringwald expected_byte = packet[i]+1; 6171a919128SMatthias Ringwald } 6181a919128SMatthias Ringwald printf("\n"); 6191a919128SMatthias Ringwald #endif 6201a919128SMatthias Ringwald #if SCO_DEMO_MODE == SCO_DEMO_MODE_55 || SCO_DEMO_MODE_00 6211a919128SMatthias Ringwald int i; 6221a919128SMatthias Ringwald int contains_error = 0; 6231a919128SMatthias Ringwald for (i=3;i<size;i++){ 6241a919128SMatthias Ringwald if (packet[i] != 0x00 && packet[i] != 0x35 && packet[i] != 0x53 && packet[i] != 0x55){ 6251a919128SMatthias Ringwald contains_error = 1; 6261a919128SMatthias Ringwald byte_errors++; 6271a919128SMatthias Ringwald } 6281a919128SMatthias Ringwald } 6291a919128SMatthias Ringwald if (contains_error){ 6301a919128SMatthias Ringwald printf("data: "); 6311a919128SMatthias Ringwald for (i=0;i<3;i++){ 6321a919128SMatthias Ringwald printf("%02x ", packet[i]); 6331a919128SMatthias Ringwald } 6341a919128SMatthias Ringwald for (i=3;i<size;i++){ 6351a919128SMatthias Ringwald if (packet[i] != 0x00 && packet[i] != 0x35 && packet[i] != 0x53 && packet[i] != 0x55){ 6361a919128SMatthias Ringwald printf(ANSI_COLOR_RED "%02x " ANSI_COLOR_RESET, packet[i]); 6371a919128SMatthias Ringwald } else { 6381a919128SMatthias Ringwald printf("%02x ", packet[i]); 6391a919128SMatthias Ringwald } 6401a919128SMatthias Ringwald } 6411a919128SMatthias Ringwald printf("\n"); 6421a919128SMatthias Ringwald } 643f7c85330SMatthias Ringwald #endif 6448b29cfc6SMatthias Ringwald } 645f7c85330SMatthias Ringwald } 646