Hi David and others,
Parrot repeater is working....

On my Intel box (Fedora 23) all seems well with my parrot.c but when Hil VK2AZ 
transmited to me,
to my Banana Pi (Fedora 28), crash:
The Log file shows Hil's transmissions. He is only 5Km away. This end, much 
switch-mode hash.
(Often the Optus HFC cable box)

It's only crashed once though....
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0xb6981f9c in __GI_abort () at abort.c:79
#2  0xb69d179c in __libc_message (action=action@entry=do_abort, fmt=<optimized 
out>) at ../sysdeps/posix/libc_fatal.c:181
#3  0xb69d7f50 in malloc_printerr (str=<optimized out>) at malloc.c:5350
#4  0xb69d824c in malloc_consolidate (av=av@entry=0xb6ab27e4 <main_arena>) at 
malloc.c:4441
#5  0xb69db5a4 in _int_malloc (av=av@entry=0xb6ab27e4 <main_arena>, 
bytes=1763160517, bytes@entry=89600) at malloc.c:3703
#6  0xb69ddd94 in __libc_calloc (n=<optimized out>, elem_size=<optimized out>) 
at malloc.c:3436
#7  0xb6ebbefc in run_ldpc_decoder (ldpc=ldpc@entry=0x1cafe80, out_char=0x70 
<error: Cannot access memory at address 0x70>, 
    out_char@entry=0xbee5a200 
"4\312ڻ\372\236\202\273\217*c\273\235\f\b\273&\017\227;\342\201\065;d\255\374;\361G\230;\324l\335:n݅:oΩ\273\271\365M\273\275\374ڻ\260\070\205\273\016\314\372\272\267\f\231\272SD\266;\333&_;\325ң;?2I;\312#\242\273q\277G\273MB\363\273\202N\226\273\326\315D;\276\365\363:_.\b<\224U\251;\215S\372\071\220\035\234\071\267\253ӻrj\204\273S\232m\273\316\030\025\273\246A\347:ď\221:ʽ\330:S؈:iC\233\272@\251D\272Eμ:\207\341o:\326\357\362;\375̚;\275\223\264;y\325f;\300\271p\273\340T\032\273\324'\371\273O9\240\273"...,
 input=input@entry=0xbee5a2e0, 
parityCheckCount=parityCheckCount@entry=0xbee5e084)
    at 
/home/alanb/Applications/freedv/3757codec2dev/codec2-dev/src/mpdecode_core.c:643
#8  0xb6eb33f0 in freedv_comprx_700d (f=f@entry=0x1cb9fa8, 
demod_in_8kHz=demod_in_8kHz@entry=0xbee5e118, 
    valid=valid@entry=0xbee5e0e4) at 
/home/alanb/Applications/freedv/3757codec2dev/codec2-dev/src/freedv_api.c:1805
#9  0xb6eb518c in freedv_comprx (f=f@entry=0x1cb9fa8, 
speech_out=speech_out@entry=0xbee633d0, demod_in=0xbee5e118)
    at 
/home/alanb/Applications/freedv/3757codec2dev/codec2-dev/src/freedv_api.c:1921
#10 0xb6eb5478 in freedv_rx (f=0x1cb9fa8, speech_out=0xbee633d0, 
demod_in=0xbee63dd0)
    at 
/home/alanb/Applications/freedv/3757codec2dev/codec2-dev/src/freedv_api.c:1241
#11 0x004c209c in main (argc=<optimized out>, argv=<optimized out>) at 
/home/alanb/Applications/freedv/parrot/parrot.c:815
(gdb)

On Sat, 28 Jul 2018 12:52:28 +1000, Alan Beard wrote
> Hi all,
> A few bugs with shutdown and startup cron scripts.
> 
> ie. If I use "pkill -u user parrot" the audio is left in a "bad" state.
> If I then do a "record". it cleans up the audio and "parrot" will
> run and initialise the audio without fault.
> 
> /usr/bin/arecord -D hw:2,0 -d 10 -f S16_LE > /dev/null
> 
> 
> Now running 24x7.
> 
> Trigger with "vk2ziw" or "VK2ZIW" in your text.
> 
> Alan VK2ZIW
> 
>

Alan

Evil flourishes when good men do nothing. 
Consider the Christmas child. 
--------------------------------------------------------------------------- 
Alan Beard               Unix Support Technician from 1984 to today 
70 Wedmore Rd.           Sun Solaris, AIX, HP/UX, Linux, SCO, MIPS 
Emu Heights N.S.W. 2750  Routers, terminal servers, printers, terminals etc.. 
+61 2 47353013 (h)       Support Programming, shell scripting, "C", assembler 
0414 353013 (mobile)     After uni, electronics tech
 
/* 
  parrot.c
  David Rowe  & Alan Beard VK2ZIW
  Created Dec 2015 & 2018

Change tack, use array to store codec2 bits, on Tx play from bits array, not file.

  FreeDV Parrot repeater. Mode 700D
*/

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <ctype.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>

#ifdef _WIN32
#include <windows.h>
#else
#include <termios.h>
#include <sys/ioctl.h>
#endif

#include <samplerate.h>
#include <getopt.h>

#include "sndfile.h"
#include "portaudio.h"

#include "codec2_fifo.h"  // short int fifo
#include "modem_stats.h"
#include "freedv_api.h"

#define MAX_CHAR            80
#define FS8                 8000                // codec audio sample rate fixed at 8 kHz
#define FS48                48000               // 48 kHz sampling rate rec. as we can trust accuracy of sound card
#define SYNC_TIMER          2.0                 // seconds of valid rx sync we need to see to change state
#define UNSYNC_TIMER        2.0                 // seconds of lost sync we need to see to change state
#define COM_HANDLE_INVALID   -1
#define LOG_TIMER           1.0         

/* globals used to communicate with async events and callback functions */

volatile int keepRunning, runListener, recordAny;
char txtMsg[MAX_CHAR], *ptxtMsg, triggerString[20];
int triggered;
float snr_est, snr_sample;
int com_handle, verbose, verbose1;
int	rxqso1, rxqso2;		// Pointers for codec2 bits of Tx QSO

/* state machine defines */

#define SRX_IDLE          0      /* listening but no FreeDV signal                                   */
#define SRX_MAYBE_SYNC    1      /* We have sync but lets see if it goes away                        */
#define SRX_SYNC          2      /* We have sync on a valid FreeDV signal                            */
#define SRX_MAYBE_UNSYNC  3      /* We have lost sync but lets see if it's really gone               */
#define STX               4      /* transmitting reply                                               */

char *state_str[] = {
    "Rx Idle",
    "Rx Maybe Sync",
    "Rx Sync",
    "Rx Maybe UnSync",
    "Tx"
};


int openComPort(const char *name);
void closeComPort(void);
void raiseDTR(void);
void lowerDTR(void);
void raiseRTS(void);
void lowerRTS(void);
pthread_t start_udp_listener_thread(void);


/*--------------------------------------------------------------------------------------------------------*\

                                                  FUNCTIONS

\*--------------------------------------------------------------------------------------------------------*/

/* Called on Ctrl-C */

void intHandler(int dummy) {
    keepRunning = 0;
    fprintf(stderr,"\nShutting Down ......\n");
}

/* returns number of output samples generated by resampling */

int resample(SRC_STATE *src,
            short      output_short[],
            short      input_short[],
            int        output_sample_rate,
            int        input_sample_rate,
            int        length_output_short, // maximum output array length in samples
            int        length_input_short
            )
{
    SRC_DATA src_data;
    float    input[length_input_short];
    float    output[length_output_short];

    assert(src != NULL);

    src_short_to_float_array(input_short, input, length_input_short);

    src_data.data_in = input;
    src_data.data_out = output;
    src_data.input_frames = length_input_short;
    src_data.output_frames = length_output_short;
    src_data.end_of_input = 0;
    src_data.src_ratio = (float)output_sample_rate/input_sample_rate;
    //printf("%d %d src_ratio: %f \n", length_input_short, length_output_short, src_data.src_ratio);

    src_process(src, &src_data);

    assert(src_data.output_frames_gen <= length_output_short);
    src_float_to_short_array(output, output_short, src_data.output_frames_gen);

    return src_data.output_frames_gen;
}


void listAudioDevices(void) {
    const PaDeviceInfo *deviceInfo = NULL;
    int                 numDevices, devn;

    numDevices = Pa_GetDeviceCount();
    printf("Num                                               Name      API   InCh  OutCh  DefFs\n");
    printf("====================================================================================\n");
    for (devn = 0; devn<numDevices; devn++) {
        deviceInfo = Pa_GetDeviceInfo(devn);
        if (deviceInfo == NULL) {
            fprintf(stderr, "Couldn't open devNum: %d\n", devn);
            return;
        }
        printf(" %2d %50s %8s %6d %6d %6d\n", 
               devn, 
               deviceInfo->name,
               Pa_GetHostApiInfo(deviceInfo->hostApi)->name,
               deviceInfo->maxInputChannels,
               deviceInfo->maxOutputChannels,
               (int)deviceInfo->defaultSampleRate);
    }
}


void printHelp(const struct option* long_options, int num_opts, char* argv[])
{
	int i;
	char *option_parameters = NULL;

	fprintf(stderr, "\nFreeBeacon - FreeDV Beacon\n"
		"usage: %s [OPTIONS]\n\n"
                "Options:\n"
                "\t-l --list (audio devices)\n"
                "\t-c        (comm port for Tx PTT)\n"
                "\t-t        (tx on start up, useful for testing)\n"
                "\t-v        (verbose)\n", argv[0]);
        for(i=0; i<num_opts-1; i++) {
		if(long_options[i].has_arg == no_argument) {
			option_parameters="";
		} else if (strcmp("dev", long_options[i].name) == 0) {
			option_parameters = " DeviceNumber (-l --list to list devices)";
                } else if (strcmp("trigger", long_options[i].name) == 0) {
			option_parameters = " textString (used to trigger beacon)";
                } else if (strcmp("callsign", long_options[i].name) == 0) {
			option_parameters = " callsign (returned in text str to tx)";
                } else if (strcmp("txfilename", long_options[i].name) == 0) {
			option_parameters = " wavefile (to use for source audio on tramsmit)";
                } else if (strcmp("samplerate", long_options[i].name) == 0) {
			option_parameters = " sampleRateHz (audio device sample rate)";
                } else if (strcmp("wavefilewritepath", long_options[i].name) == 0) {
			option_parameters = " pathToWaveFiles (path to where wave files are written)";
                } else if (strcmp("rpigpio", long_options[i].name) == 0) {
			option_parameters = " GPIO (BCM GPIO number on Raspberry Pi for Tx PTT)";
                } else if (strcmp("rpigpioalive", long_options[i].name) == 0) {
			option_parameters = " GPIO (BCM GPIO number on Raspberry Pi for alive blinker)";
                } else if (strcmp("statuspagefile", long_options[i].name) == 0) {
			option_parameters = " statusPageFileName (where to write status web page)";
                }
		fprintf(stderr, "\t--%s%s\n", long_options[i].name, option_parameters);
	}

	exit(1);
}


void str2lwr(char * s) {
   int c = 0;
   char ch;
   while (s[c] != '\0') {
      ch = s[c];
      if (ch >= 'A' && ch <= 'Z')
         s[c] = s[c] + 32;
      c++;
   }
}

/* text message callbacks */

void callbackNextRxChar(void *callback_state, char c) {

    /* if we hit end of buffer wrap around to start */

    if ((ptxtMsg - txtMsg) < (MAX_CHAR-1))
        *ptxtMsg++ = c;
    else
        ptxtMsg = txtMsg;

    /* if end of string let see if we have a match for the trigger
       string.  Note tx may send trigger string many times.  We only
       need to receive it once to trigger a beacon tx cycle. */

    if (c == 13) {
        *ptxtMsg++ = c;
        *ptxtMsg = 0;
         ptxtMsg = txtMsg;
         if (verbose1)
             fprintf(stderr, "  RX txtMsg: %s\n", txtMsg);
	 str2lwr(txtMsg);
         if (strstr(txtMsg, triggerString) != NULL) {
             triggered = 1;
             snr_sample = snr_est;
             if (verbose)
                 fprintf(stderr, "  Tx triggered!\n");
         }
    } 
}

char callbackNextTxChar(void *callback_state) {
    if ((*ptxtMsg == 0) || ((ptxtMsg - txtMsg) >= MAX_CHAR))
        ptxtMsg = txtMsg;

    //fprintf(stderr, "TX txtMsg: %d %c\n", (int)*ptxtMsg, *ptxtMsg);
    return *ptxtMsg++;
}


SNDFILE *openPlayFile(char fileName[], int *sfFs)
{
    SF_INFO  sfInfo;
    SNDFILE *sfPlayFile;

    sfInfo.format = 0;

    sfPlayFile = sf_open(fileName, SFM_READ, &sfInfo);
    if(sfPlayFile == NULL) {
        const char *strErr = sf_strerror(NULL);
        fprintf(stderr, " %s Couldn't open: %s\n", strErr, fileName);
    }
    *sfFs = sfInfo.samplerate;

    return sfPlayFile;
}

SNDFILE *openRecFile(char fileName[], int sfFs)
{
    SF_INFO  sfInfo;    // SF_FORMAT_RAW or SF_FORMAT_WAV
    SNDFILE *sfRecFile; // SF_FORMAT_PCM_16 Signed 16 bit data

    sfInfo.format     = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
    sfInfo.channels   = 1;
    sfInfo.samplerate = sfFs;

    sfRecFile = sf_open(fileName, SFM_WRITE, &sfInfo);
    if(sfRecFile == NULL) {
        const char *strErr = sf_strerror(NULL);
        fprintf(stderr, "\nCouldn't open:  %s %s\n", strErr, fileName);
    }

    return sfRecFile;
}

SNDFILE *openPCMfile(char fileName[], int sfFs)
{
    SF_INFO  sfInfo;    // SF_FORMAT_RAW or SF_FORMAT_WAV
    SNDFILE *sfRecFile; // SF_FORMAT_PCM_16 Signed 16 bit data

    sfInfo.format     = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
    sfInfo.channels   = 1;
    sfInfo.samplerate = sfFs;

    sfRecFile = sf_open(fileName, SFM_WRITE, &sfInfo);
    if(sfRecFile == NULL) {
        const char *strErr = sf_strerror(NULL);
        fprintf(stderr, "\nCouldn't open:  %s %s\n", strErr, fileName);
    }

    return sfRecFile;
}


  
SNDFILE *openReadFile(char fileName[], int sfFs)
{
    SF_INFO  sfInfo;
    SNDFILE *sfReadFile;

    sfInfo.format     = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
    sfInfo.channels   = 1;
    sfInfo.samplerate = sfFs;

    sfReadFile = sf_open(fileName, SFM_READ, &sfInfo);
    if(sfReadFile == NULL) {
        const char *strErr = sf_strerror(NULL);
        fprintf(stderr, " Couldn't open: %s %s\n", strErr, fileName);
    }

    return sfReadFile;
}
// Alan0
void flushAudioIn(PaStream* stream)
{
    int n48 = 10240;
    short stereo[2*n48];
    signed long j = Pa_GetStreamReadAvailable( stream );
	while( 2227 + j-- < 0 ) {
            Pa_ReadStream(stream, stereo, n48);
	}
}

/* Use the Linux /sys/class/gpio system to access the RPis GPIOs */

void sys_gpio(char filename[], char s[]) {
    FILE *fgpio = fopen(filename, "wt");
    //fprintf(stderr,"gpio: %s %s\n",filename, s);
    if (fgpio == NULL) {
      fprintf(stderr, "\nProblem opening %s\n", filename);
        exit(1);
    }
    fprintf(fgpio,"%s",s);
    fclose(fgpio);
}


void getTimeStr(char timeStr[]) {
    time_t ltime;     /* calendar time */
    struct tm *loctime;

    ltime=time(NULL); /* get current cal time */
    loctime = localtime (&ltime);
    strftime(timeStr, MAX_CHAR, "%F-%R:%S",loctime);
}

//-------------- bFIFO ------------------
struct bFIFO {
    unsigned char *buf;
    unsigned char *pin;
    unsigned char *pout;
    int    nshort;
};

struct bFIFO *bfifo_create(int nshort) {
    struct bFIFO *bfifo;

    bfifo = (struct bFIFO *)malloc(sizeof(struct bFIFO));
    assert(bfifo != NULL);

    bfifo->buf = (unsigned char*)malloc(sizeof(char)*nshort);
    assert(bfifo->buf != NULL);
    bfifo->pin = bfifo->buf;
    bfifo->pout = bfifo->buf;
    bfifo->nshort = nshort;

    return bfifo;
}

void bfifo_destroy(struct bFIFO *bfifo) {
    assert(bfifo != NULL);
    free(bfifo->buf);
    free(bfifo);
}

int bfifo_used(const struct bFIFO * const bfifo)
{
    unsigned char         *pin = bfifo->pin;
    unsigned char         *pout = bfifo->pout;
    unsigned int   used;

    assert(bfifo != NULL);
    if (pin >= pout)
        used = pin - pout;
    else
        used = bfifo->nshort + (unsigned int)(pin - pout);

    return used;
}

int bfifo_free(const struct bFIFO * const bfifo)
{
    // available storage is one less than nshort as prd == pwr
    // is reserved for empty rather than full

    return bfifo->nshort - bfifo_used(bfifo) - 1;
}

int bfifo_write(struct bFIFO *bfifo, unsigned char data[], int n) {
    int          	  i;
    unsigned char         *pdata;
    unsigned char         *pin = bfifo->pin;

    assert(bfifo != NULL);
    assert(data != NULL);

    if (n > bfifo_free(bfifo)) {
	return -1;
    }
    else {

	/* This could be made more efficient with block copies
	   using memcpy */

	pdata = data;
	for(i=0; i<n; i++) {
	    *pin++ = *pdata++;
	    if (pin == (bfifo->buf + bfifo->nshort))
		pin = bfifo->buf;
	}
	bfifo->pin = pin;
    }

    return 0;
}

int bfifo_read(struct bFIFO *bfifo, unsigned char data[], int n)
{
    int            i;
    unsigned char         *pdata;
    unsigned char         *pout = bfifo->pout;

    assert(bfifo != NULL);
    assert(data != NULL);

    if (n > bfifo_used(bfifo)) {
	return -1;
    }
    else {

	/* This could be made more efficient with block copies
	   using memcpy */

	pdata = data;
	for(i=0; i<n; i++) {
	    *pdata++ = *pout++;
	    if (pout == (bfifo->buf + bfifo->nshort))
		pout = bfifo->buf;
	}
	bfifo->pout = pout;
    }

    return 0;
}

/*--------------------------------------------------------------------------------------------------------*\

                                                  MAIN

\*--------------------------------------------------------------------------------------------------------*/

int main(int argc, char *argv[]) {
    struct freedv      *fdv;
    PaError             err;
    PaStreamParameters  inputParameters, outputParameters;
    const PaDeviceInfo *deviceInfo = NULL;
    PaStream           *stream = NULL;
    int                 j, src_error, inputChannels, nin, devNum;
    int                 outputChannels;
    int                 state, next_state;
    SRC_STATE          *rxsrc, *txsrc;
    SRC_STATE          *playsrc;
    struct FIFO        *rxfifo;
    struct bFIFO       *txfifo;
    char                txFileName[MAX_CHAR];
    SNDFILE            *sfPlayFile, *sfRecFileFromRadio, *sfRecFileDecAudio;
    FILE               *sfRecFileToRadio;
//  SNDFILE	       *sfReadFileToRadio;
    FILE	       *C2FileToRadio;
    int                 sfFs;
    int                 fssc;                 
    int                 triggerf, txfilenamef, callsignf, sampleratef, wavefilepathf, rpigpiof, rpigpioalivef;
    int                 statuspagef;
    int                 sync, haveRecording;
    char                commport[MAX_CHAR];
    char                callsign[20];
    float               syncTimer, logTimer, squelchlvl;
    unsigned int        tnout=0,mnout;
    short               peak = 0;
    char                waveFileWritePath[40];
    char                rpigpio[40], rpigpio_path[MAX_CHAR], rpigpioalive[MAX_CHAR], rpigpioalive_path[MAX_CHAR + 40];
    char                statusPageFileName[MAX_CHAR];
    FILE               *fstatus;
    int                 gpioAliveState = 0;
    int                 tmpf = 1;
    FILE               *ftmp;
// Alan3
    char recFileFromRadioName[500], recFileDecAudioName[500];
    char recFileToRadioName[500], recFileDecDataName[500], recC2ToRadioName[500];
    int			bytes_in_codec2_frame = 1;
    
    /* debug raw file */

    if (tmpf) { ftmp = fopen("t.raw", "wb"); assert(ftmp != NULL); }

    /* Defaults -------------------------------------------------------------------------------*/

    devNum = 0;
    fssc = FS48;
    sprintf(triggerString, "cq");
//  sprintf(triggerString, "FreeBeacon");
    sprintf(txFileName, "txaudio.wav");
    sprintf(callsign, "VK2ZIW cq");  // include rpt to trigger
    squelchlvl = -3.0;
    rxqso1 = rxqso2 = 0;
    verbose = 0;
    verbose1 = 1;
    com_handle = COM_HANDLE_INVALID;
    mnout = 60*FS8;
    state = SRX_IDLE;
    next_state = SRX_IDLE;
    *txtMsg = 0;
    sfRecFileFromRadio = NULL;
    sfRecFileDecAudio = NULL;
    sfRecFileToRadio = NULL; // generated by system cmd
    C2FileToRadio = NULL;
    sfPlayFile = NULL;
    strcpy(waveFileWritePath, ".");
    *rpigpio = 0;
    *rpigpioalive = 0;
    *statusPageFileName = 0;

    if (Pa_Initialize()) {
        fprintf(stderr, "Port Audio failed to initialize");
        exit(1);
    }
 
    /* Process command line options -----------------------------------------------------------*/

    char* opt_string = "hlvc:t";
    struct option long_options[] = {
        { "dev", required_argument, &devNum, 1 },
        { "trigger", required_argument, &triggerf, 1 },
        { "txfilename", required_argument, &txfilenamef, 1 },
        { "callsign", required_argument, &callsignf, 1 },
        { "samplerate", required_argument, &sampleratef, 1 },
        { "wavefilewritepath", required_argument, &wavefilepathf, 1 },
        { "statuspagefile", required_argument, &statuspagef, 1 },
        { "rpigpio", required_argument, &rpigpiof, 1 },
        { "rpigpioalive", required_argument, &rpigpioalivef, 1 },
        { "list", no_argument, NULL, 'l' },
        { "help", no_argument, NULL, 'h' },
        { NULL, no_argument, NULL, 0 }
    };
    int num_opts=sizeof(long_options)/sizeof(struct option);

    while(1) {
        int option_index = 0;
        int opt = getopt_long(argc, argv, opt_string,
                    long_options, &option_index);
        if (opt == -1)
            break;

        switch (opt) {
        case 0:
            if (strcmp(long_options[option_index].name, "dev") == 0) {
                devNum = atoi(optarg);
            } else if(strcmp(long_options[option_index].name, "trigger") == 0) {
                strcpy(triggerString, optarg);
            } else if(strcmp(long_options[option_index].name, "txfilename") == 0) {
                strcpy(txFileName, optarg);
            } else if(strcmp(long_options[option_index].name, "callsign") == 0) {
                strcpy(callsign, optarg);
            } else if (strcmp(long_options[option_index].name, "samplerate") == 0) {
                fssc = atoi(optarg);
            } else if (strcmp(long_options[option_index].name, "wavefilewritepath") == 0) {
                strcpy(waveFileWritePath, optarg);
            } else if (strcmp(long_options[option_index].name, "statuspagefile") == 0) {
                strcpy(statusPageFileName, optarg);
            } else if (strcmp(long_options[option_index].name, "rpigpio") == 0) {
                strcpy(rpigpio, optarg);
                sys_gpio("/sys/class/gpio/unexport", rpigpio);
                sys_gpio("/sys/class/gpio/export", rpigpio);
                usleep(100*1000); /* short delay so OS can create the next device */
                char tmp[MAX_CHAR];
                sprintf(tmp,"/sys/class/gpio/gpio%s/direction", rpigpio);
                sys_gpio(tmp, "out");
                sprintf(rpigpio_path,"/sys/class/gpio/gpio%s/value", rpigpio);
                sys_gpio(rpigpio_path, "0");
            } else if (strcmp(long_options[option_index].name, "rpigpioalive") == 0) {
                strcpy(rpigpioalive, optarg);
                sys_gpio("/sys/class/gpio/unexport", rpigpioalive);
                sys_gpio("/sys/class/gpio/export", rpigpioalive);
                usleep(100*1000); /* short delay so OS can create the next device */
                char tmp[MAX_CHAR + 40];
                sprintf(tmp,"/sys/class/gpio/gpio%s/direction", rpigpioalive);
                sys_gpio(tmp, "out");
                sprintf(rpigpioalive_path,"/sys/class/gpio/gpio%s/value", rpigpioalive);
                sys_gpio(rpigpioalive_path, "0");       
            }
            break;

        case 'c':
            strcpy(commport, optarg);
            if (openComPort(commport) != 0) {
                fprintf(stderr, "Can't open comm port: %s\n",commport);
                exit(1);
            }
            break;

        case 'h':
            printHelp(long_options, num_opts, argv);
            break;

        case 'v':
            verbose = 1;
            break;

        case 't':
            sprintf(txtMsg,"tx Test");
            state = STX;
            break;

        case 'l':
            listAudioDevices();
            exit(0);
            break;

        default:
            /* This will never be reached */
            break;
        }
    }  // End while(1), arg processing

    /* Open Sound Device and start processing --------------------------------------------------------------*/

    fdv = freedv_open(FREEDV_MODE_700D); assert(fdv != NULL);
    freedv_set_squelch_en(fdv, 1);                       // Squelch on
    freedv_set_snr_squelch_thresh(fdv, squelchlvl);

    int   fsm   = freedv_get_modem_sample_rate(fdv);     /* modem sample rate                                   */
    int   n8m   = freedv_get_n_nom_modem_samples(fdv);   /* nominal modem sample buffer size at fsm sample rate */
    int   n48   = n8m*fssc/fsm;                        /* nominal modem sample buffer size at 48kHz           */
    float dT    = (float)n48/fssc;                     /* period of each sound buffer                         */

    if (verbose1)
        fprintf(stderr, "\n========= fsm: %d n8m: %d n48: %d dT: %f =========\n", fsm, n8m, n48, dT);
// ====== fsm: 8000 n8m: 1280 n48: 7680 dT: 0.160000 ====

    short stereo[2*n48];                               /* stereo I/O buffer from port audio                   */
    short rx48k[n48], tx48k[n48];                      /* signals at 48 kHz                                   */
    short rxfsm[n48];                                  /* rx signal at modem sample rate                      */

    freedv_set_callback_txt(fdv, callbackNextRxChar, callbackNextTxChar, NULL);

    rxfifo = fifo_create(4*n8m); assert(rxfifo != NULL);   /* fifo to smooth out variation in demod nin          */
    txfifo = bfifo_create(32768); assert(txfifo != NULL);   /* fifo for tx c2data                                 */

    /* states for sample rate converters */

    rxsrc = src_new(SRC_SINC_FASTEST, 1, &src_error); assert(rxsrc != NULL);
    txsrc = src_new(SRC_SINC_FASTEST, 1, &src_error); assert(txsrc != NULL);
    playsrc = src_new(SRC_SINC_FASTEST, 1, &src_error); assert(playsrc != NULL);

    /* Open Port Audio device and set up config structures -----------------------------------------------------*/

    deviceInfo = Pa_GetDeviceInfo(devNum);
    if (deviceInfo == NULL) {
        fprintf(stderr, "Couldn't get device info from Port Audio for device: %d\n", devNum);
        exit(1);
    }
    if (deviceInfo->maxInputChannels == 1)
        inputChannels = 1;
    else
        inputChannels = 2;

    /* input device */

    inputParameters.device = devNum;
    inputParameters.channelCount = inputChannels;
    inputParameters.sampleFormat = paInt16;
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency;
    inputParameters.hostApiSpecificStreamInfo = NULL;

    /* output device */

    if (deviceInfo->maxOutputChannels == 1)
        outputChannels = 1;
    else
        outputChannels = 2;

    outputParameters.device = devNum;
    outputParameters.channelCount = outputChannels;
    outputParameters.sampleFormat = paInt16;
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;

    /* open port audio for full duplex operation */

    err = Pa_OpenStream(
              &stream,
              &inputParameters,
              &outputParameters,
              fssc,
              n48,         /* changed from 0 to n48 to get Rpi audio to work without clicks */ 
              paClipOff,    
              NULL,        /* no callback, use blocking API */
              NULL ); 

    if (err != paNoError) {
        fprintf(stderr, "Couldn't initialise sound device\n");       
        exit(1);
    }

    err = Pa_StartStream(stream);
    if (err != paNoError) {
        fprintf(stderr, "Couldn't start sound device\n");       
        exit(1);
    }

    /* Start UDP listener thread */

    start_udp_listener_thread();

    /* Init for main loop ----------------------------------------------------------------------------*/

    fprintf(stderr, "\nCtrl-C to exit\n");
    fprintf(stderr, "trigger string: %s\ntxFileName: %s\n", triggerString, txFileName);
    fprintf(stderr, "PortAudio devNum: %d\nsamplerate: %d\n", devNum, fssc);
    fprintf(stderr, "WaveFileWritePath: %s\n", waveFileWritePath);
    fprintf(stderr, "statusPageFile: %s\n", statusPageFileName);
    if (com_handle != COM_HANDLE_INVALID) {
        fprintf(stderr, "Comm Port for PTT: %s\n", commport);
    }
    if (*rpigpio) {
        fprintf(stderr, "Raspberry Pi BCM GPIO for PTT: %s\n", rpigpio);
    }
    if (*rpigpioalive) {
        fprintf(stderr, "Raspberry Pi BCM GPIO for Alive Indicator: %s\n", rpigpioalive);
    }

    signal(SIGINT, intHandler);  /* ctrl-C to exit gracefully */
    keepRunning = 1;
    recordAny = 1;
    ptxtMsg = txtMsg;
    triggered = 0;
    logTimer = 0;
    syncTimer = 0;
    haveRecording = 0;

    if (com_handle != COM_HANDLE_INVALID) {
        lowerRTS(); lowerDTR();
        if (verbose1) fprintf(stderr, "RTS and DTR low \n");
    }

    /* -t flag: we are leaping straight into TX */

    if (state == STX) {
        if (com_handle != COM_HANDLE_INVALID) {
            raiseRTS(); raiseDTR();
            if (verbose1) fprintf(stderr, "RTS and DTR high \n");
        }
        if (*rpigpio) {
            sys_gpio(rpigpio_path, "1");
        }
        sfPlayFile = openPlayFile(txFileName, &sfFs);
    }


    /* Main loop -------------------------------------------------------------------------------------*/

    while(keepRunning) {

        if (state != STX) {
            short demod_in[freedv_get_n_max_modem_samples(fdv)];
            short speech_out[freedv_get_n_speech_samples(fdv)];

            /* Read samples from sound card, resample to modem sample rate */

            Pa_ReadStream(stream, stereo, n48);

            if (inputChannels == 2) {
                for(j=0; j<n48; j++)
                    rx48k[j] = stereo[2*j]; /* left channel only */
            }
            else {
                for(j=0; j<n48; j++)
                    rx48k[j] = stereo[j]; 
            }
            //fwrite(rx48k, sizeof(short), n8m, ftmp);
            int n8m_out = resample(rxsrc, rxfsm, rx48k, fsm, fssc, n8m, n48);
          
            /* crude input signal level meter */
            peak = 0;
            for (j=0; j<n8m_out; j++)
                if (rxfsm[j] > peak)
                    peak = rxfsm[j];

            fifo_write(rxfifo, rxfsm, n8m_out);

            /* demodulate to decoded speech samples */

            nin = freedv_nin(fdv);
            while (fifo_read(rxfifo, demod_in, nin) == 0) {
	        int nout = 0;
	        int nin2 = 0;
                nout = freedv_rx(fdv, speech_out, demod_in);
                freedv_get_modem_stats(fdv, &sync, &snr_est);

                if (sfRecFileFromRadio)
                    sf_write_short(sfRecFileFromRadio, demod_in, nin);
                if (sfRecFileDecAudio)
                    sf_write_short(sfRecFileDecAudio, speech_out, nout);
// Alan4
                unsigned char packed_codec_bitsTX[8000];
//              nin2 = freedv_get_rx_codec_bits700D(fdv, packed_codec_bitsTX);
                nin2 = freedv_get_rx_codec_bits(fdv, packed_codec_bitsTX);
                if (C2FileToRadio != NULL)
                   fwrite(packed_codec_bitsTX, sizeof(char), nin2, C2FileToRadio);
		if (nin2 > 0) {
                    bytes_in_codec2_frame = nin2;
                    bfifo_write(txfifo, packed_codec_bitsTX, nin2);
                    rxqso1 = 1;
	        }
// Alan4
                tnout += nout;
                if (tnout > mnout) {
		    if (verbose) fprintf(stderr, "\n======  Rx done, Close files  ======\n");
                    sf_close(sfRecFileFromRadio);
                    sf_close(sfRecFileDecAudio);
//		    if (C2FileToRadio != NULL) { fclose(C2FileToRadio); C2FileToRadio = NULL; }
		    tnout = 0;
                }
            }
        }  // end state != STX, listening

// Transmitting
        if (state == STX) {
            short mod_out[freedv_get_n_max_modem_samples(fdv)];
            short speech_in[freedv_get_n_speech_samples(fdv)];
            unsigned char mod_out2[freedv_get_n_speech_samples(fdv)*sfFs/FS8];
	    int n48_out = 0;
            
/* Play callsign WAV file 16bit, encoded 700D */
            if (sfPlayFile != NULL) {
                /* resample input sound file as can't guarantee 8KHz sample rate */
		/* read in a small chunk, many times, top level loop */

                unsigned int nsf = freedv_get_n_speech_samples(fdv)*sfFs/FS8;
                short        insf[nsf];
                unsigned int n = sf_read_short(sfPlayFile, insf, nsf);
                resample(playsrc, speech_in, insf, FS8, sfFs, freedv_get_n_speech_samples(fdv), nsf);

                //fwrite(speech_in, sizeof(short), freedv_get_n_nom_modem_samples(fdv), ftmp);

                if (n != nsf) {
                    /* end of file - this signals state machine we've almost finished */
                    sf_close(sfPlayFile);
                    sfPlayFile = NULL;
                    rxqso2 = 1;  // now play Rx
                    if (verbose1) fprintf(stderr, "\n===== Do Rx send! =====\n");
                }

                freedv_tx(fdv, mod_out, speech_in);
                //fwrite(mod_out, sizeof(short), freedv_get_n_nom_modem_samples(f), ftmp);
    
                n48_out = resample(txsrc, tx48k, mod_out, fssc, fsm, n48, n8m);
                //printf("n48_out: %d n48: %d n_nom: %d\n", n48_out, n48, n8m);
                //fwrite(tx48k, sizeof(short), n48_out, ftmp);
                for(j=0; j<n48_out; j++) {
                    if (outputChannels == 2) {
                        stereo[2*j] = tx48k[j];   // left channel
                        stereo[2*j+1] = tx48k[j]; // right channel
                    }
                    else {
                        stereo[j] = tx48k[j];     // mono
                    }
                }
                Pa_WriteStream(stream, stereo, n48_out);
            }  // playfile finished


/* Parrot */

            if (rxqso2 && rxqso1) {
// Alan5
// void freedv_codectx (struct freedv *f, short mod_out[], unsigned char *packed_codec_bits);
	    int nb = freedv_get_n_codec_bits(fdv);
            nin = freedv_nin(fdv);
            if (bfifo_read(txfifo, mod_out2, nb) == 0) {
                 freedv_codectx(fdv, mod_out, mod_out2);
/* resample input sound file from 8KHz to 48k sample rate */
                 if (verbose) fprintf(stderr, "\nResampling mod_out nb %d \n", nb);
                 n48_out =  resample(txsrc, tx48k, mod_out, fssc, fsm, n48, n8m);
                 if (verbose) fprintf(stderr, "n48_out: %d n48: %d n_nom: %d rxqso1: %d\n", n48_out, n48, n8m, rxqso1);
                 for(j=0; j<n48_out; j++) {
                     if (outputChannels == 2) {
                         stereo[2*j] = tx48k[j];   // left channel
                         stereo[2*j+1] = tx48k[j]; // right channel
                     }
                     else {
                         stereo[j] = tx48k[j];     // mono
                     }
                }
                if (verbose) fprintf(stderr, "\n========= Pa_WriteStream TX ========== \n");
                fwrite(stereo, sizeof(short), n48_out, ftmp);
                Pa_WriteStream(stream, stereo, n48_out);

	     } else rxqso1 = rxqso2 = 0;
             if (verbose) fprintf(stderr, "\n========= State TX ========== \n");
// Alan5
 // when both Tx are finished 
            if ( rxqso1 == 0 && rxqso2 == 0) next_state = SRX_IDLE;
            if ( rxqso1 == 0 && rxqso2 == 0 && verbose1) 
               fprintf(stderr, "\n================= Back to SRX_IDLE ================\n");
            }
        }  // state == STX done, callsign WAV file and Parrot done

// Alan6 hopefully flush Rx audio during Tx
	if (state == STX && next_state == SRX_IDLE) {
            if (verbose) fprintf(stderr, "\nFlush Rx audio during transmit\n");
	    Pa_StopStream( stream );
	    Pa_Sleep(1000); // 1000msec
//	    Pa_AbortStream( stream );
	    Pa_StartStream( stream );
	    flushAudioIn( stream );
	}


        /* state machine processing */


        switch(state) {

        case SRX_IDLE:
            if (sync) {
                next_state = SRX_MAYBE_SYNC;
                syncTimer = 0.0;
                *txtMsg = 0;
                ptxtMsg = txtMsg;
                freedv_set_total_bit_errors(fdv, 0);
                freedv_set_total_bits(fdv, 0);
            }
            break;

        case SRX_MAYBE_SYNC:
            if (sync) {
                syncTimer += dT;
                if (syncTimer >= SYNC_TIMER) {

                    /* OK we really are in sync */

                    next_state = SRX_SYNC;
                }
            }
            else {
                next_state = SRX_IDLE;
                triggered = 0;
                haveRecording = 0;
            }
            break;

        case SRX_SYNC:
            syncTimer += dT;
            if (!sync) {
                syncTimer = 0;
                next_state = SRX_MAYBE_UNSYNC;
            }

            /* if triggered kick off recording of two files */

            if ((triggered || recordAny) && !haveRecording) {

                char timeStr[40];
// Alan3

                getTimeStr(timeStr);
                sprintf(recFileFromRadioName,"%s/%s_from_radio.wav", waveFileWritePath, timeStr);
                sprintf(recFileDecAudioName,"%s/%s_decoded_speech.wav", waveFileWritePath, timeStr);
                sprintf(recFileToRadioName,"%s/%s_to_radio.raw", waveFileWritePath, timeStr);
                sprintf(recC2ToRadioName,"%s/%s_to_radio.700C", waveFileWritePath, timeStr);
                sprintf(recFileDecDataName,"%s/%s_decoded_data.c2", waveFileWritePath, timeStr);
                sfRecFileFromRadio = openRecFile(recFileFromRadioName, fsm);
                sfRecFileDecAudio = openRecFile(recFileDecAudioName, FS8);
//		sfReadFileToRadio = openPCMfile(recFileToRadioName, fsm);
		C2FileToRadio = fopen(recC2ToRadioName, "wb");
                haveRecording = 1;
// Alan3        recordAny = 0;
                tnout = 0;
            }

            break;

        case SRX_MAYBE_UNSYNC:
            if (!sync) {
                syncTimer += dT;
                if (syncTimer >= UNSYNC_TIMER) {
                    /* we really are out of sync */

                    /* finish up any open recording files */

                    if (sfRecFileFromRadio)
                        sf_close(sfRecFileFromRadio);
                    if (sfRecFileDecAudio)
                        sf_close(sfRecFileDecAudio);
                    if (C2FileToRadio) {
                        fclose(C2FileToRadio); C2FileToRadio = NULL; }

                    /* kick off a tx if triggered */

                    if (triggered) {
                        float ber = (float)freedv_get_total_bit_errors(fdv)/freedv_get_total_bits(fdv);
                        char tmpStr[MAX_CHAR];

                        sprintf(tmpStr, "SNR: %3.1f BER: %4.3f de %s\r",
                                snr_sample, ber, callsign);
                        strcpy(txtMsg, tmpStr);
                        if (verbose1) fprintf(stderr, "TX txtMsg: %s\n", txtMsg);
                        ptxtMsg = txtMsg;
                        sfPlayFile = openPlayFile(txFileName, &sfFs);

                        if (com_handle != COM_HANDLE_INVALID) {
                            raiseRTS(); raiseDTR();
                        }
                        if (*rpigpio) {
                            sys_gpio(rpigpio_path, "1");
                        }
                        next_state = STX;
                    }
                    else {
                        next_state = SRX_IDLE;
                        triggered = 0;
                        haveRecording = 0;
                    }
                }
            }
            else
                next_state = SRX_SYNC; /* sync is back so false alarm */
            break;

        case STX:
            if (sfPlayFile == NULL && rxqso1 == 0) {

                if (com_handle != COM_HANDLE_INVALID) {
                    lowerRTS(); lowerDTR();
                }
                if (*rpigpio) {
                    sys_gpio(rpigpio_path, "0");
                }
                next_state = SRX_IDLE;
                triggered = 0;
                haveRecording = 0;
            }
            break;
        } /* end switch statement for case statement */
// Alan7

        if (verbose) fprintf(stderr, "\n------ STATE: %d rxqso1: %d rxqso2: %d ------\n", state, rxqso1, rxqso2);

        logTimer += dT;
        if (logTimer >= LOG_TIMER) {
            logTimer = 0;
            if (verbose1 == 1 && sync == 1) {
                fprintf(stderr, "state: %-20s  peak: %6d  sync: %d  SNR: %3.1f  triggered: %d recordany: %d\n", 
                        state_str[state], peak, sync, snr_est, triggered, recordAny);
            }
            if (*statusPageFileName) {
                char timeStr[MAX_CHAR];
                time_t ltime;     /* calendar time */
                ltime=time(NULL); /* get current cal time */

                sprintf(timeStr, "%s",asctime( localtime(&ltime) ) );
                strtok(timeStr, "\n");

                fstatus = fopen(statusPageFileName, "wt");
                if (fstatus != NULL) {
                    fprintf(fstatus, "<html>\n<head>\n<meta http-equiv=\"refresh\" content=\"2\">\n</head>\n<body>\n");
                    fprintf(fstatus, "%s: state: %s peak: %d sync: %d SNR: %3.1f triggered: %d recordany: %d txtMsg: %s\n", 
                            timeStr, state_str[state], peak, sync, snr_est, triggered, recordAny, txtMsg);
                    fprintf(fstatus, "</body>\n</html>\n");
                    fclose(fstatus);
                }
            }

            /* toggle alive GPIO */

            if (*rpigpioalive) {
                if (gpioAliveState) {
                    gpioAliveState = 0;
                    sys_gpio(rpigpioalive_path, "0");           
                } else {
                    gpioAliveState = 1;
                    sys_gpio(rpigpioalive_path, "1");           
                }
            }
        }

        state = next_state;
        usleep(50*1000); /* short delay 50ms */
    } /* end while(keepRunning) loop */


    /* Ctrl-C has been pressed lets shut down gracefully ------------------*/

    /* lower PTT lines, shut down ports */

    if (com_handle != COM_HANDLE_INVALID) {
        lowerRTS(); lowerDTR();
        closeComPort();
    }
    if (*rpigpio) {
        sys_gpio(rpigpio_path, "0");
        sys_gpio("/sys/class/gpio/unexport", rpigpio);
    }
   
    if (*rpigpioalive) {
        sys_gpio(rpigpioalive_path, "0");
        sys_gpio("/sys/class/gpio/unexport", rpigpioalive);
    }
 
    /* Shut down port audio */

    err = Pa_StopStream(stream);
    if (err != paNoError) {
        fprintf(stderr, "Couldn't stop sound device\n");       
        exit(1);
    }
    Pa_CloseStream(stream);
    Pa_Terminate();

    /* clean up states */

    fifo_destroy(rxfifo);
    bfifo_destroy(txfifo);
    src_delete(rxsrc);
    src_delete(txsrc);
    src_delete(playsrc);
    freedv_close(fdv);
    if (tmpf) fclose(ftmp);

    return 0;
}  // end of main() open files will be handled by the shell.


/*--------------------------------------------------------------------------------------------------------*\

                                      Comm port fuctions lifted from FreeDV

\*--------------------------------------------------------------------------------------------------------*/

//----------------------------------------------------------------
// openComPort() opens the com port specified by the string
// ie: "/dev/ttyUSB0" 
//----------------------------------------------------------------

int openComPort(const char *name)
{
    if(com_handle != COM_HANDLE_INVALID)
        closeComPort();

#ifdef _WIN32
	{
		COMMCONFIG CC;
		DWORD CCsize=sizeof(CC);
		COMMTIMEOUTS timeouts;
		DCB	dcb;

		if(GetDefaultCommConfigA(name, &CC, &CCsize)) {
			CC.dcb.fOutxCtsFlow		= FALSE;
			CC.dcb.fOutxDsrFlow		= FALSE;
			CC.dcb.fDtrControl		= DTR_CONTROL_DISABLE;
			CC.dcb.fDsrSensitivity	= FALSE;
			CC.dcb.fRtsControl		= RTS_CONTROL_DISABLE;
			SetDefaultCommConfigA(name, &CC, CCsize);
		}

		if((com_handle=CreateFileA(name
			,GENERIC_READ|GENERIC_WRITE 	/* Access */
			,0								/* Share mode */
			,NULL							/* Security attributes */
			,OPEN_EXISTING					/* Create access */
			,FILE_ATTRIBUTE_NORMAL			/* File attributes */
			,NULL							/* Template */
			))==INVALID_HANDLE_VALUE)
			return false;

		if(GetCommTimeouts(com_handle, &timeouts)) {
			timeouts.ReadIntervalTimeout=MAXDWORD;
			timeouts.ReadTotalTimeoutMultiplier=0;
			timeouts.ReadTotalTimeoutConstant=0;		// No-wait read timeout
			timeouts.WriteTotalTimeoutMultiplier=0;
			timeouts.WriteTotalTimeoutConstant=5000;	// 5 seconds
			SetCommTimeouts(com_handle,&timeouts);
		}

		/* Force N-8-1 mode: */
		if(GetCommState(com_handle, &dcb)==TRUE) {
			dcb.ByteSize		= 8;
			dcb.Parity			= NOPARITY;
			dcb.StopBits		= ONESTOPBIT;
			dcb.DCBlength		= sizeof(DCB);
			dcb.fBinary			= TRUE;
			dcb.fOutxCtsFlow	= FALSE;
			dcb.fOutxDsrFlow	= FALSE;
			dcb.fDtrControl		= DTR_CONTROL_DISABLE;
			dcb.fDsrSensitivity	= FALSE;
			dcb.fTXContinueOnXoff= TRUE;
			dcb.fOutX			= FALSE;
			dcb.fInX			= FALSE;
			dcb.fRtsControl		= RTS_CONTROL_DISABLE;
			dcb.fAbortOnError	= FALSE;
			SetCommState(com_handle, &dcb);
		}
	}
#else
    {
        struct termios t;

        if((com_handle=open(name, O_NONBLOCK|O_RDWR))==COM_HANDLE_INVALID)
            return -1;

        if(tcgetattr(com_handle, &t)==-1) {
            close(com_handle);
            com_handle = COM_HANDLE_INVALID;
            return -1;
        }

        t.c_iflag = (
                     IGNBRK   /* ignore BREAK condition */
                     | IGNPAR   /* ignore (discard) parity errors */
                     );
        t.c_oflag = 0;	/* No output processing */
        t.c_cflag = (
                     CS8         /* 8 bits */
                     | CREAD       /* enable receiver */
                     /*
                       Fun snippet from the FreeBSD manpage:

                       If CREAD is set, the receiver is enabled.  Otherwise, no character is
                       received.  Not all hardware supports this bit.  In fact, this flag is
                       pretty silly and if it were not part of the termios specification it
                       would be omitted.
                     */
                     | CLOCAL      /* ignore modem status lines */
                     );
        t.c_lflag = 0;	/* No local modes */
        if(tcsetattr(com_handle, TCSANOW, &t)==-1) {
            close(com_handle);
            com_handle = COM_HANDLE_INVALID;
            return -1;
        }
		
    }
#endif

    return 0;
}

void closeComPort(void)
{
#ifdef _WIN32
	CloseHandle(com_handle);
#else
    close(com_handle);
#endif
    com_handle = COM_HANDLE_INVALID;
}

//----------------------------------------------------------------
// (raise|lower)(RTS|DTR)()
//
// Raises/lowers the specified signal
//----------------------------------------------------------------

void raiseDTR(void)
{
    if(com_handle == COM_HANDLE_INVALID)
        return;
#ifdef _WIN32
	EscapeCommFunction(com_handle, SETDTR);
#else
    {	// For C89 happiness
        int flags = TIOCM_DTR;
        ioctl(com_handle, TIOCMBIS, &flags);
    }
#endif
}


void raiseRTS(void)
{
    if(com_handle == COM_HANDLE_INVALID)
        return;
#ifdef _WIN32
	EscapeCommFunction(com_handle, SETRTS);
#else
    {	// For C89 happiness
        int flags = TIOCM_RTS;
        ioctl(com_handle, TIOCMBIS, &flags);
    }
#endif
}

void lowerDTR(void)
{
    if(com_handle == COM_HANDLE_INVALID)
        return;

#ifdef _WIN32
	EscapeCommFunction(com_handle, CLRDTR);
#else
    {	// For C89 happiness
        int flags = TIOCM_DTR;
        ioctl(com_handle, TIOCMBIC, &flags);
    }
#endif
}

void lowerRTS(void)
{
    if(com_handle == COM_HANDLE_INVALID)
        return;
#ifdef _WIN32
	EscapeCommFunction(com_handle, CLRRTS);
#else
    {	// For C89 happiness
        int flags = TIOCM_RTS;
        ioctl(com_handle, TIOCMBIC, &flags);
    }
#endif
}

#define BUFSIZE          2048
#define SERVICE_PORT	21234

void *udp_listener_thread(void* p) {
    struct sockaddr_in myaddr;	/* our address */
    struct sockaddr_in remaddr;	/* remote address */
    socklen_t addrlen = sizeof(remaddr);		/* length of addresses */
    int recvlen;			/* # bytes received */
    int fd;				/* our socket */
    char txt[BUFSIZE];	/* receive buffer */

    /* create a UDP socket */

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        fprintf(stderr, "cannot create socket\n");
        return 0;
    }

    /* bind the socket to any valid IP address and a specific port */

    memset((char *)&myaddr, 0, sizeof(myaddr));
    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    myaddr.sin_port = htons(SERVICE_PORT);

    if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
        fprintf(stderr, "bind failed");
        return 0;
    }

    /* now loop, receiving data and printing what we received */

    while (runListener) {
        fprintf(stderr, "udp listener waiting on port %d - send me a command!\n", SERVICE_PORT);
        recvlen = recvfrom(fd, txt, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);
        fprintf(stderr, "received %d bytes\n", recvlen);
        if (recvlen > 0) {
            txt[recvlen] = 0;
            fprintf(stderr, "txt: %s\n", txt);
            if (strcmp(txt, "recordany") == 0) {
                recordAny = 1;
                fprintf(stderr, "Next signal to sync will be recorded regardless of txt msg\n");
            }
        }
    }

    return NULL;
}


pthread_t start_udp_listener_thread(void) {
    pthread_t athread;

    runListener = 1;

    if (!pthread_create(&athread, NULL, udp_listener_thread, NULL) != 0)
        fprintf(stderr, "Can't create UDP listener thread\n");

    return athread;
}
// The End
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 
'cards.Loopback.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:4555:(_snd_config_evaluate) function snd_func_refer returned 
error: No such file or directory
ALSA lib conf.c:5034:(snd_config_expand) Evaluate error: No such file or 
directory
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM iec958
ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 
'cards.Loopback.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:4555:(_snd_config_evaluate) function snd_func_refer returned 
error: No such file or directory
ALSA lib conf.c:5034:(snd_config_expand) Evaluate error: No such file or 
directory
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM spdif
ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 
'cards.Loopback.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:4555:(_snd_config_evaluate) function snd_func_refer returned 
error: No such file or directory
ALSA lib conf.c:5034:(snd_config_expand) Evaluate error: No such file or 
directory
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM spdif
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
Expression 'alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, 
&alsaPeriodFrames, &dir )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 
923
ALSA lib pcm_hw.c:1820:(_snd_pcm_hw_open) Invalid value for card
ALSA lib pcm_hw.c:1820:(_snd_pcm_hw_open) Invalid value for card
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping 
unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping 
unlock

========= fsm: 8000 n8m: 1280 n48: 7680 dT: 0.160000 =========
Can't create UDP listener thread

Ctrl-C to exit
trigger string: 2ziw
txFileName: txaudio.wav
PortAudio devNum: 3
samplerate: 48000
WaveFileWritePath: .
statusPageFile: 
Comm Port for PTT: /dev/ttyUSB0
udp listener waiting on port 21234 - send me a command!
RTS and DTR low 
state: Rx Maybe Sync         peak:   2537  sync: 1  SNR: -2.7  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2121  sync: 1  SNR: -4.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2671  sync: 1  SNR: -4.9  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2584  sync: 1  SNR: -5.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2740  sync: 1  SNR: -4.8  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2426  sync: 1  SNR: -5.4  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2817  sync: 1  SNR: -5.8  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2785  sync: 1  SNR: -7.0  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2631  sync: 1  SNR: -7.2  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2612  sync: 1  SNR: -6.5  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2397  sync: 1  SNR: -7.1  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2823  sync: 1  SNR: -7.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2529  sync: 1  SNR: -6.2  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2581  sync: 1  SNR: -5.4  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2618  sync: 1  SNR: -5.3  triggered: 0 
recordany: 1
  RX txtMsg: 

state: Rx Maybe Sync         peak:   2628  sync: 1  SNR: 1.6  triggered: 0 
recordany: 1
  RX txtMsg: iIW

state: Rx Maybe Sync         peak:   2588  sync: 1  SNR: 3.8  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2508  sync: 1  SNR: 6.9  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2706  sync: 1  SNR: 8.8  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2329  sync: 1  SNR: 0.9  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2693  sync: 1  SNR: -3.3  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2814  sync: 1  SNR: -5.2  triggered: 0 
recordany: 1
  RX txtMsg: VK2AZ - ths  u nj

  RX txtMsg: 

state: Rx Maybe Sync         peak:   2927  sync: 1  SNR: -6.6  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2545  sync: 1  SNR: -6.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2677  sync: 1  SNR: -5.7  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2553  sync: 1  SNR: -5.3  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2311  sync: 1  SNR: -5.6  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2550  sync: 1  SNR: -6.7  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2593  sync: 1  SNR: -1.7  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2740  sync: 1  SNR: 3.4  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2755  sync: 1  SNR: 5.9  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2782  sync: 1  SNR: 7.8  triggered: 0 
recordany: 1
  RX txtMsg:  ry to VK2ZIW

state: Rx Sync               peak:   2677  sync: 1  SNR: 9.5  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2894  sync: 1  SNR: 10.4  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2190  sync: 1  SNR: 7.3  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2747  sync: 1  SNR: -2.6  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2722  sync: 1  SNR: -5.7  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2290  sync: 1  SNR: -5.4  triggered: 1 
recordany: 1
state: Rx Maybe UnSync       peak:   2442  sync: 1  SNR: -7.2  triggered: 1 
recordany: 1
TX txtMsg: SNR: 8.7 BER: 0.197 de VK2ZIW cq

===== Do Rx send! =====

================= Back to SRX_IDLE ================
state: Rx Maybe Sync         peak:   2470  sync: 1  SNR: -7.3  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2888  sync: 1  SNR: -7.4  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2449  sync: 1  SNR: -7.4  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2514  sync: 1  SNR: -7.4  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2759  sync: 1  SNR: 3.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2652  sync: 1  SNR: 5.3  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2798  sync: 1  SNR: 6.9  triggered: 0 
recordany: 1
  RX txtMsg: to VK2ZIW

state: Rx Sync               peak:   2774  sync: 1  SNR: -1.3  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2693  sync: 1  SNR: -5.2  triggered: 1 
recordany: 1
state: Rx Maybe UnSync       peak:   2508  sync: 1  SNR: -5.8  triggered: 1 
recordany: 1
TX txtMsg: SNR: 6.9 BER: 0.292 de VK2ZIW cq

===== Do Rx send! =====

================= Back to SRX_IDLE ================
state: Rx Idle               peak:   2686  sync: 1  SNR: -5.8  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2610  sync: 1  SNR: -6.0  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2885  sync: 1  SNR: -6.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2735  sync: 1  SNR: -6.7  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2754  sync: 1  SNR: 1.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2762  sync: 1  SNR: 3.8  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2982  sync: 1  SNR: -3.6  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2809  sync: 1  SNR: -6.4  triggered: 0 
recordany: 1
state: Rx Maybe UnSync       peak:   2541  sync: 1  SNR: -6.8  triggered: 0 
recordany: 1
state: Rx Maybe UnSync       peak:   2625  sync: 1  SNR: -7.2  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2961  sync: 1  SNR: -6.6  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2350  sync: 1  SNR: -6.6  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2572  sync: 1  SNR: -6.9  triggered: 0 
recordany: 1
state: Rx Maybe UnSync       peak:   2545  sync: 1  SNR: -6.2  triggered: 0 
recordany: 1
state: Rx Maybe UnSync       peak:   2548  sync: 1  SNR: -6.0  triggered: 0 
recordany: 1
state: Rx Maybe UnSync       peak:   3421  sync: 1  SNR: -6.3  triggered: 0 
recordany: 1
state: Rx Maybe UnSync       peak:   2667  sync: 1  SNR: -1.6  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2748  sync: 1  SNR: 3.1  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2823  sync: 1  SNR: 6.5  triggered: 0 
recordany: 1
  RX txtMsg: yZ - eo oedfho s rJo9 9  (`nie
  l K2ZIW

state: Rx Sync               peak:   2285  sync: 1  SNR: 0.1  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2959  sync: 1  SNR: -4.6  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2874  sync: 1  SNR: -6.2  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2626  sync: 1  SNR: -7.4  triggered: 1 
recordany: 1
state: Rx Maybe UnSync       peak:   2356  sync: 1  SNR: -7.7  triggered: 1 
recordany: 1
state: Rx Maybe UnSync       peak:   2751  sync: 1  SNR: -6.4  triggered: 1 
recordany: 1
TX txtMsg: SNR: 7.0 BER: 0.412 de VK2ZIW cq

===== Do Rx send! =====

================= Back to SRX_IDLE ================
state: Rx Idle               peak:   2740  sync: 1  SNR: -6.3  triggered: 0 
recordany: 1
  RX txtMsg: 

state: Rx Idle               peak:   2789  sync: 1  SNR: -7.4  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2938  sync: 1  SNR: -5.2  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2476  sync: 1  SNR: -7.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   3023  sync: 1  SNR: -5.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2455  sync: 1  SNR: -6.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2403  sync: 1  SNR: -6.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2533  sync: 1  SNR: -6.5  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2624  sync: 1  SNR: -5.5  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2695  sync: 1  SNR: -5.5  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2633  sync: 1  SNR: 1.9  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2760  sync: 1  SNR: 6.3  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2660  sync: 1  SNR: 9.1  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2675  sync: 1  SNR: 11.0  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2209  sync: 1  SNR: 1.6  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2357  sync: 1  SNR: -4.7  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2904  sync: 1  SNR: -6.1  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2230  sync: 1  SNR: -6.5  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2877  sync: 1  SNR: -8.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2823  sync: 1  SNR: -6.4  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2677  sync: 1  SNR: -6.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2695  sync: 1  SNR: -4.4  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2880  sync: 1  SNR: -4.1  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2690  sync: 1  SNR: 2.4  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2364  sync: 1  SNR: -1.6  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2330  sync: 1  SNR: -3.6  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2537  sync: 1  SNR: -5.6  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2332  sync: 1  SNR: -3.6  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2109  sync: 1  SNR: -2.8  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2701  sync: 1  SNR: -6.9  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2364  sync: 1  SNR: -4.8  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2438  sync: 1  SNR: -4.6  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2885  sync: 1  SNR: -5.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2342  sync: 1  SNR: -4.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2542  sync: 1  SNR: -2.8  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2425  sync: 1  SNR: -5.1  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2802  sync: 1  SNR: -5.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2545  sync: 1  SNR: -4.4  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2711  sync: 1  SNR: -5.0  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2256  sync: 1  SNR: -3.4  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2477  sync: 1  SNR: -2.0  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2734  sync: 1  SNR: -4.5  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2719  sync: 1  SNR: -2.8  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2526  sync: 1  SNR: -4.6  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   3363  sync: 1  SNR: -6.0  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2702  sync: 1  SNR: -5.7  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2737  sync: 1  SNR: -4.6  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2559  sync: 1  SNR: -3.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2262  sync: 1  SNR: -4.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2248  sync: 1  SNR: -4.6  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2389  sync: 1  SNR: -6.0  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2605  sync: 1  SNR: -5.1  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2870  sync: 1  SNR: 0.2  triggered: 0 
recordany: 1
  RX txtMsg: 

state: Rx Maybe Sync         peak:   2304  sync: 1  SNR: -4.5  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2503  sync: 1  SNR: -4.2  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2999  sync: 1  SNR: -5.3  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2871  sync: 1  SNR: -4.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2659  sync: 1  SNR: -5.0  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2778  sync: 1  SNR: -4.3  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2582  sync: 1  SNR: -5.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2613  sync: 1  SNR: -3.3  triggered: 0 
recordany: 1
  RX txtMsg: 

state: Rx Maybe Sync         peak:   2402  sync: 1  SNR: -3.9  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2743  sync: 1  SNR: -6.4  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2420  sync: 1  SNR: -5.4  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2602  sync: 1  SNR: -4.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2384  sync: 1  SNR: -5.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   3154  sync: 1  SNR: -6.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2601  sync: 1  SNR: -2.6  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2553  sync: 1  SNR: -4.8  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2363  sync: 1  SNR: -5.7  triggered: 0 
recordany: 1
  RX txtMsg: 

state: Rx Idle               peak:   2737  sync: 1  SNR: -4.9  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2827  sync: 1  SNR: -4.8  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2668  sync: 1  SNR: -5.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2685  sync: 1  SNR: -3.6  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2776  sync: 1  SNR: -5.1  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2193  sync: 1  SNR: -4.3  triggered: 0 
recordany: 1
  RX txtMsg: 

state: Rx Idle               peak:   2735  sync: 1  SNR: -4.7  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2968  sync: 1  SNR: -3.8  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2536  sync: 1  SNR: -3.5  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2471  sync: 1  SNR: -4.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2477  sync: 1  SNR: -5.2  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2674  sync: 1  SNR: -5.0  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   3081  sync: 1  SNR: -5.8  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2782  sync: 1  SNR: -3.5  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2761  sync: 1  SNR: -4.5  triggered: 0 
recordany: 1
state: Rx Idle               peak:   3089  sync: 1  SNR: -6.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2676  sync: 1  SNR: -5.0  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2668  sync: 1  SNR: -3.9  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2391  sync: 1  SNR: -4.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2630  sync: 1  SNR: -5.2  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2368  sync: 1  SNR: -4.6  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2793  sync: 1  SNR: -4.0  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2444  sync: 1  SNR: -3.3  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2135  sync: 1  SNR: -4.2  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2174  sync: 1  SNR: -6.0  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2966  sync: 1  SNR: -5.9  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2481  sync: 1  SNR: -3.0  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2890  sync: 1  SNR: -4.2  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2427  sync: 1  SNR: -3.0  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2517  sync: 1  SNR: -5.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2703  sync: 1  SNR: -4.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   3109  sync: 1  SNR: -2.1  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2253  sync: 1  SNR: -3.8  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2461  sync: 1  SNR: -4.9  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2836  sync: 1  SNR: -3.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2569  sync: 1  SNR: -5.8  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2457  sync: 1  SNR: -5.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2643  sync: 1  SNR: -3.1  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2442  sync: 1  SNR: -5.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   1962  sync: 1  SNR: -3.6  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2419  sync: 1  SNR: -5.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2798  sync: 1  SNR: -4.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2575  sync: 1  SNR: -3.4  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2917  sync: 1  SNR: -4.0  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2777  sync: 1  SNR: -4.9  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2662  sync: 1  SNR: 3.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2540  sync: 1  SNR: 6.6  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2735  sync: 1  SNR: 8.1  triggered: 0 
recordany: 1
state: Rx Sync               peak:    548  sync: 1  SNR: 8.5  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2878  sync: 1  SNR: -1.4  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2575  sync: 1  SNR: -5.4  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2655  sync: 1  SNR: -5.0  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2856  sync: 1  SNR: -1.7  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2749  sync: 1  SNR: 3.1  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2683  sync: 1  SNR: 5.4  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2764  sync: 1  SNR: 7.3  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2678  sync: 1  SNR: 9.0  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2817  sync: 1  SNR: 10.0  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2654  sync: 1  SNR: 12.1  triggered: 0 
recordany: 1
  RX txtMsg: 2AZ - Hilary to VK2ZIW

state: Rx Sync               peak:   2948  sync: 1  SNR: 12.0  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2463  sync: 1  SNR: 3.5  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2944  sync: 1  SNR: -2.8  triggered: 1 
recordany: 1
TX txtMsg: SNR: 12.0 BER: 0.089 de VK2ZIW cq

===== Do Rx send! =====

================= Back to SRX_IDLE ================
state: Rx Idle               peak:   2841  sync: 1  SNR: -3.7  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2741  sync: 1  SNR: 4.7  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2714  sync: 1  SNR: 9.0  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2782  sync: 1  SNR: 10.4  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2667  sync: 1  SNR: 11.7  triggered: 0 
recordany: 1
state: Rx Sync               peak:   1544  sync: 1  SNR: 4.6  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2910  sync: 1  SNR: -2.0  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   3023  sync: 1  SNR: -4.7  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2757  sync: 1  SNR: 2.8  triggered: 0 
recordany: 1
  RX txtMsg: nW

state: Rx Maybe Sync         peak:   2858  sync: 1  SNR: 11.1  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2825  sync: 1  SNR: 12.8  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2746  sync: 1  SNR: 12.7  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2715  sync: 1  SNR: 13.1  triggered: 0 
recordany: 1
state: Rx Sync               peak:    821  sync: 1  SNR: 9.4  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2502  sync: 1  SNR: -1.6  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2754  sync: 1  SNR: -4.9  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2826  sync: 1  SNR: 0.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2734  sync: 1  SNR: 5.3  triggered: 0 
recordany: 1
  RX txtMsg: K2ZIW

state: Rx Sync               peak:   2723  sync: 1  SNR: 8.5  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2765  sync: 1  SNR: 10.5  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2833  sync: 1  SNR: 12.0  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2813  sync: 1  SNR: 12.1  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2382  sync: 1  SNR: 3.8  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2672  sync: 1  SNR: -2.5  triggered: 1 
recordany: 1
TX txtMsg: SNR: 7.7 BER: 0.119 de VK2ZIW cq

===== Do Rx send! =====

================= Back to SRX_IDLE ================
state: Rx Idle               peak:   2804  sync: 1  SNR: -4.6  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2747  sync: 1  SNR: -0.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2735  sync: 1  SNR: 4.7  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2672  sync: 1  SNR: 7.1  triggered: 0 
recordany: 1
  RX txtMsg: VK2ZIW

state: Rx Sync               peak:   2624  sync: 1  SNR: 9.5  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2682  sync: 1  SNR: 11.1  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2617  sync: 1  SNR: 12.3  triggered: 1 
recordany: 1
state: Rx Sync               peak:   1049  sync: 1  SNR: 6.3  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2780  sync: 1  SNR: -2.3  triggered: 1 
recordany: 1
TX txtMsg: SNR: 7.1 BER: 0.140 de VK2ZIW cq

===== Do Rx send! =====

================= Back to SRX_IDLE ================
  RX txtMsg: 

state: Rx Idle               peak:   2468  sync: 1  SNR: -4.4  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2594  sync: 1  SNR: 1.1  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2958  sync: 1  SNR: 4.6  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2749  sync: 1  SNR: 7.1  triggered: 0 
recordany: 1
  RX txtMsg: ro VK2ZIW

state: Rx Sync               peak:   2671  sync: 1  SNR: 9.3  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2722  sync: 1  SNR: 11.6  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2617  sync: 1  SNR: 12.1  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2735  sync: 1  SNR: 12.9  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2852  sync: 1  SNR: 13.0  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2693  sync: 1  SNR: 13.0  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2442  sync: 1  SNR: 2.1  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2644  sync: 1  SNR: -2.9  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2372  sync: 1  SNR: -3.9  triggered: 1 
recordany: 1
state: Rx Sync               peak:   2756  sync: 1  SNR: -4.2  triggered: 1 
recordany: 1
TX txtMsg: SNR: 7.8 BER: 0.159 de VK2ZIW cq

===== Do Rx send! =====

================= Back to SRX_IDLE ================
state: Rx Idle               peak:   2796  sync: 1  SNR: -2.8  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2653  sync: 1  SNR: 2.1  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2686  sync: 1  SNR: 5.1  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2710  sync: 1  SNR: 7.8  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2743  sync: 1  SNR: 8.5  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2708  sync: 1  SNR: 10.3  triggered: 0 
recordany: 1
state: Rx Sync               peak:   1722  sync: 1  SNR: 7.4  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2755  sync: 1  SNR: -2.5  triggered: 0 
recordany: 1
  RX txtMsg: -K2AZ - Hilary to Vl@ fA  

state: Rx Sync               peak:   2690  sync: 1  SNR: -3.4  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2520  sync: 1  SNR: -6.2  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2730  sync: 1  SNR: -5.4  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2698  sync: 1  SNR: -6.9  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2556  sync: 1  SNR: -4.8  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2697  sync: 1  SNR: -3.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2716  sync: 1  SNR: 3.2  triggered: 0 
recordany: 1
  RX txtMsg: ZIW

state: Rx Sync               peak:   2836  sync: 1  SNR: 6.6  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2739  sync: 1  SNR: 9.8  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2849  sync: 1  SNR: 11.0  triggered: 0 
recordany: 1
state: Rx Sync               peak:   1500  sync: 1  SNR: 5.0  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2848  sync: 1  SNR: -2.2  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2782  sync: 1  SNR: -4.3  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2474  sync: 1  SNR: -3.8  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2826  sync: 1  SNR: -4.5  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2699  sync: 1  SNR: -2.2  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2905  sync: 1  SNR: -4.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2627  sync: 1  SNR: -6.3  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2441  sync: 1  SNR: -5.0  triggered: 0 
recordany: 1
  RX txtMsg: 

state: Rx Maybe Sync         peak:   2810  sync: 1  SNR: 0.7  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2769  sync: 1  SNR: -0.8  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2619  sync: 1  SNR: 3.3  triggered: 0 
recordany: 1
  RX txtMsg: iIW

state: Rx Sync               peak:   2757  sync: 1  SNR: 5.4  triggered: 0 
recordany: 1
state: Rx Sync               peak:    762  sync: 1  SNR: 4.5  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2884  sync: 1  SNR: -2.7  triggered: 0 
recordany: 1
state: Rx Sync               peak:   2248  sync: 1  SNR: -4.1  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2947  sync: 1  SNR: -5.0  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2466  sync: 1  SNR: -4.2  triggered: 0 
recordany: 1
state: Rx Idle               peak:   2466  sync: 1  SNR: -4.4  triggered: 0 
recordany: 1
state: Rx Maybe Sync         peak:   2798  sync: 1  SNR: -4.9  triggered: 0 
recordany: 1
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Freetel-codec2 mailing list
Freetel-codec2@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freetel-codec2

Reply via email to