From a08d0939b5427d868d48e5f2c810510b16b3f16f Mon Sep 17 00:00:00 2001 From: wb2osz Date: Mon, 11 Sep 2023 00:07:36 +0100 Subject: [PATCH] Add FEC type to station heard line. --- src/atest.c | 42 ++++++++++++++++++++++-------------------- src/direwolf.c | 35 +++++++++++++++++++++++------------ src/dlq.c | 8 ++++---- src/dlq.h | 7 +++++-- src/hdlc_rec2.h | 3 ++- src/igate.c | 4 ++-- src/il2p_test.c | 2 +- src/multi_modem.c | 32 ++++++++++++++++++-------------- src/multi_modem.h | 4 ++-- src/recv.c | 2 +- 10 files changed, 80 insertions(+), 59 deletions(-) diff --git a/src/atest.c b/src/atest.c index 733e8c4..c5f4ec5 100644 --- a/src/atest.c +++ b/src/atest.c @@ -757,7 +757,7 @@ int audio_get (int a) * This is called when we have a good frame. */ -void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, int is_fx25, retry_t retries, char *spectrum) +void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, fec_type_t fec_type, retry_t retries, char *spectrum) { char stemp[500]; @@ -826,29 +826,31 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev strlcat (heard, ")", sizeof(heard)); } - if (my_audio_config.achan[chan].fix_bits == RETRY_NONE && my_audio_config.achan[chan].passall == 0) { - dw_printf ("%s audio level = %s %s\n", heard, alevel_text, spectrum); - } - else if (is_fx25) { - dw_printf ("%s audio level = %s %s\n", heard, alevel_text, spectrum); - } - else { - assert (retries >= RETRY_NONE && retries <= RETRY_MAX); - dw_printf ("%s audio level = %s [%s] %s\n", heard, alevel_text, retry_text[(int)retries], spectrum); + switch (fec_type) { + + case fec_type_fx25: + dw_printf ("%s audio level = %s FX.25 %s\n", heard, alevel_text, spectrum); + break; + + case fec_type_il2p: + dw_printf ("%s audio level = %s IL2P %s\n", heard, alevel_text, spectrum); + break; + + case fec_type_none: + default: + if (my_audio_config.achan[chan].fix_bits == RETRY_NONE && my_audio_config.achan[chan].passall == 0) { + // No fix_bits or passall specified. + dw_printf ("%s audio level = %s %s\n", heard, alevel_text, spectrum); + } + else { + assert (retries >= RETRY_NONE && retries <= RETRY_MAX); // validate array index. + dw_printf ("%s audio level = %s [%s] %s\n", heard, alevel_text, retry_text[(int)retries], spectrum); + } + break; } #endif -//#if defined(EXPERIMENT_G) || defined(EXPERIMENT_H) -// int j; -// -// for (j=0; j= 0 && chan < MAX_TOTAL_CHANS); // TOTAL for virtual channels assert (subchan >= -2 && subchan < MAX_SUBCHANS); @@ -1197,12 +1199,21 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev strlcpy (display_retries, "", sizeof(display_retries)); - if (is_fx25) { - ; - } - else if (audio_config.achan[chan].fix_bits != RETRY_NONE || audio_config.achan[chan].passall) { - assert (retries >= RETRY_NONE && retries <= RETRY_MAX); - snprintf (display_retries, sizeof(display_retries), " [%s] ", retry_text[(int)retries]); + switch (fec_type) { + case fec_type_fx25: + strlcpy (display_retries, " FX.25 ", sizeof(display_retries)); + break; + case fec_type_il2p: + strlcpy (display_retries, " IL2P ", sizeof(display_retries)); + break; + case fec_type_none: + default: + // Possible fix_bits indication. + if (audio_config.achan[chan].fix_bits != RETRY_NONE || audio_config.achan[chan].passall) { + assert (retries >= RETRY_NONE && retries <= RETRY_MAX); + snprintf (display_retries, sizeof(display_retries), " [%s] ", retry_text[(int)retries]); + } + break; } ax25_format_addrs (pp, stemp); @@ -1567,7 +1578,7 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev * However, if it used FEC mode (FX.25. IL2P), we have much higher level of * confidence that it is correct. */ - if (ax25_is_aprs(pp) && ( retries == RETRY_NONE || is_fx25) ) { + if (ax25_is_aprs(pp) && ( retries == RETRY_NONE || fec_type == fec_type_fx25 || fec_type == fec_type_il2p) ) { igate_send_rec_packet (chan, pp); } @@ -1588,7 +1599,7 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev * However, if it used FEC mode (FX.25. IL2P), we have much higher level of * confidence that it is correct. */ - if (ax25_is_aprs(pp) && ( retries == RETRY_NONE || is_fx25) ) { + if (ax25_is_aprs(pp) && ( retries == RETRY_NONE || fec_type == fec_type_fx25 || fec_type == fec_type_il2p) ) { digipeater (chan, pp); } @@ -1598,7 +1609,7 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev * Use only those with correct CRC (or using FEC.) */ - if (retries == RETRY_NONE || is_fx25) { + if (retries == RETRY_NONE || fec_type == fec_type_fx25 || fec_type == fec_type_il2p) { cdigipeater (chan, pp); } diff --git a/src/dlq.c b/src/dlq.c index 698df5a..f56b864 100644 --- a/src/dlq.c +++ b/src/dlq.c @@ -215,10 +215,10 @@ void dlq_init (void) * display of audio level line. * Use -2 to indicate DTMF message.) * - * is_fx25 - Was it from FX.25? Need to know because + * fec_type - Was it from FX.25 or IL2P? Need to know because * meaning of retries is different. * - * retries - Level of bit correction used. + * retries - Level of correction used. * * spectrum - Display of how well multiple decoders did. * @@ -228,7 +228,7 @@ void dlq_init (void) * *--------------------------------------------------------------------*/ -void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, int is_fx25, retry_t retries, char *spectrum) +void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, fec_type_t fec_type, retry_t retries, char *spectrum) { struct dlq_item_s *pnew; @@ -278,7 +278,7 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev pnew->subchan = subchan; pnew->pp = pp; pnew->alevel = alevel; - pnew->is_fx25 = is_fx25; + pnew->fec_type = fec_type; pnew->retries = retries; if (spectrum == NULL) strlcpy(pnew->spectrum, "", sizeof(pnew->spectrum)); diff --git a/src/dlq.h b/src/dlq.h index f07d330..fdac1c0 100644 --- a/src/dlq.h +++ b/src/dlq.h @@ -33,10 +33,13 @@ typedef struct cdata_s { + /* Types of things that can be in queue. */ typedef enum dlq_type_e {DLQ_REC_FRAME, DLQ_CONNECT_REQUEST, DLQ_DISCONNECT_REQUEST, DLQ_XMIT_DATA_REQUEST, DLQ_REGISTER_CALLSIGN, DLQ_UNREGISTER_CALLSIGN, DLQ_OUTSTANDING_FRAMES_REQUEST, DLQ_CHANNEL_BUSY, DLQ_SEIZE_CONFIRM, DLQ_CLIENT_CLEANUP} dlq_type_t; +typedef enum fec_type_e {fec_type_none=0, fec_type_fx25=1, fec_type_il2p=2} fec_type_t; + /* A queue item. */ @@ -68,7 +71,7 @@ typedef struct dlq_item_s { alevel_t alevel; /* Audio level. */ - int is_fx25; /* Was it from FX.25? */ + fec_type_t fec_type; // Type of FEC for received signal: none, FX.25, or IL2P. retry_t retries; /* Effort expended to get a valid CRC. */ /* Bits changed for regular AX.25. */ @@ -106,7 +109,7 @@ void dlq_init (void); -void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, int is_fx25, retry_t retries, char *spectrum); +void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, fec_type_t fec_type, retry_t retries, char *spectrum); void dlq_connect_request (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, int chan, int client, int pid); diff --git a/src/hdlc_rec2.h b/src/hdlc_rec2.h index 5141f3a..01ef323 100644 --- a/src/hdlc_rec2.h +++ b/src/hdlc_rec2.h @@ -6,6 +6,7 @@ #include "ax25_pad.h" /* for packet_t, alevel_t */ #include "rrbb.h" #include "audio.h" /* for struct audio_s */ +#include "dlq.h" // for fec_type_t definition. @@ -62,6 +63,6 @@ int hdlc_rec2_try_to_fix_later (rrbb_t block, int chan, int subchan, int slice, /* Provided by the top level application to process a complete frame. */ -void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alevel_t level, int is_fx25, retry_t retries, char *spectrum); +void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alevel_t level, fec_type_t fec_type, retry_t retries, char *spectrum); #endif diff --git a/src/igate.c b/src/igate.c index d77d78c..7f84228 100644 --- a/src/igate.c +++ b/src/igate.c @@ -1564,9 +1564,9 @@ static void * igate_recv_thread (void *arg) // See what happens with -2 and follow up on this. // Do we need something else here? int slice = 0; - int is_fx25 = 0; + fec_type_t fec_type = fec_type_none; char spectrum[] = "APRS-IS"; - dlq_rec_frame (ichan, subchan, slice, pp3, alevel, is_fx25, RETRY_NONE, spectrum); + dlq_rec_frame (ichan, subchan, slice, pp3, alevel, fec_type, RETRY_NONE, spectrum); } else { text_color_set(DW_COLOR_ERROR); diff --git a/src/il2p_test.c b/src/il2p_test.c index c983daf..1799525 100644 --- a/src/il2p_test.c +++ b/src/il2p_test.c @@ -943,7 +943,7 @@ void tone_gen_put_bit (int chan, int data) // This is called when a complete frame has been deserialized. -void multi_modem_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, retry_t retries, int is_fx25) +void multi_modem_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, retry_t retries, fec_type_t fec_type) { if (rec_count < 0) return; // Skip check before serdes test. diff --git a/src/multi_modem.c b/src/multi_modem.c index d02b8c2..d2382f1 100644 --- a/src/multi_modem.c +++ b/src/multi_modem.c @@ -116,7 +116,8 @@ static struct audio_s *save_audio_config_p; static struct { packet_t packet_p; alevel_t alevel; - int is_fx25; // 1 for FX.25, 0 for regular AX.25. + float speed_error; + fec_type_t fec_type; // Type of FEC: none(0), fx25, il2p retry_t retries; // For the old "fix bits" strategy, this is the // number of bits that were modified to get a good CRC. // It would be 0 to something around 4. @@ -306,14 +307,14 @@ void multi_modem_process_sample (int chan, int audio_sample) * display of audio level line. * Use -2 to indicate DTMF message.) * retries - Level of correction used. - * is_fx25 - 1 for FX.25, 0 for normal AX.25. + * fec_type - none(0), fx25, il2p * * Description: Add to list of candidates. Best one will be picked later. * *--------------------------------------------------------------------*/ -void multi_modem_process_rec_frame (int chan, int subchan, int slice, unsigned char *fbuf, int flen, alevel_t alevel, retry_t retries, int is_fx25) +void multi_modem_process_rec_frame (int chan, int subchan, int slice, unsigned char *fbuf, int flen, alevel_t alevel, retry_t retries, fec_type_t fec_type) { packet_t pp; @@ -346,12 +347,12 @@ void multi_modem_process_rec_frame (int chan, int subchan, int slice, unsigned c pp = ax25_from_frame (fbuf, flen, alevel); } - multi_modem_process_rec_packet (chan, subchan, slice, pp, alevel, retries, is_fx25); + multi_modem_process_rec_packet (chan, subchan, slice, pp, alevel, retries, fec_type); } // TODO: Eliminate function above and move code elsewhere? -void multi_modem_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, retry_t retries, int is_fx25) +void multi_modem_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, retry_t retries, fec_type_t fec_type) { if (pp == NULL) { text_color_set(DW_COLOR_ERROR); @@ -386,7 +387,7 @@ void multi_modem_process_rec_packet (int chan, int subchan, int slice, packet_t ax25_delete (pp); } else { - dlq_rec_frame (chan, subchan, slice, pp, alevel, is_fx25, retries, ""); + dlq_rec_frame (chan, subchan, slice, pp, alevel, fec_type, retries, ""); } return; } @@ -406,7 +407,7 @@ void multi_modem_process_rec_packet (int chan, int subchan, int slice, packet_t candidate[chan][subchan][slice].packet_p = pp; candidate[chan][subchan][slice].alevel = alevel; - candidate[chan][subchan][slice].is_fx25 = is_fx25; + candidate[chan][subchan][slice].fec_type = fec_type; candidate[chan][subchan][slice].retries = retries; candidate[chan][subchan][slice].age = 0; candidate[chan][subchan][slice].crc = ax25_m_m_crc(pp); @@ -443,6 +444,9 @@ static void pick_best_candidate (int chan) int best_n, best_score; char spectrum[MAX_SUBCHANS*MAX_SLICERS+1]; int n, j, k; + if (save_audio_config_p->achan[chan].num_slicers < 1) { + save_audio_config_p->achan[chan].num_slicers = 1; + } int num_bars = save_audio_config_p->achan[chan].num_slicers * save_audio_config_p->achan[chan].num_subchan; memset (spectrum, 0, sizeof(spectrum)); @@ -456,7 +460,7 @@ static void pick_best_candidate (int chan) if (candidate[chan][j][k].packet_p == NULL) { spectrum[n] = '_'; } - else if (candidate[chan][j][k].is_fx25) { + else if (candidate[chan][j][k].fec_type != fec_type_none) { // FX.25 or IL2P // FIXME: using retries both as an enum and later int too. if ((int)(candidate[chan][j][k].retries) <= 9) { spectrum[n] = '0' + candidate[chan][j][k].retries; @@ -464,7 +468,7 @@ static void pick_best_candidate (int chan) else { spectrum[n] = '+'; } - } + } // AX.25 below else if (candidate[chan][j][k].retries == RETRY_NONE) { spectrum[n] = '|'; } @@ -481,8 +485,8 @@ static void pick_best_candidate (int chan) candidate[chan][j][k].score = 0; } else { - if (candidate[chan][j][k].is_fx25) { - candidate[chan][j][k].score = 9000 - 100 * candidate[chan][j][k].retries; + if (candidate[chan][j][k].fec_type != fec_type_none) { + candidate[chan][j][k].score = 9000 - 100 * candidate[chan][j][k].retries; // has FEC } else { /* Originally, this produced 0 for the PASSALL case. */ @@ -550,9 +554,9 @@ static void pick_best_candidate (int chan) candidate[chan][j][k].packet_p); } else { - dw_printf ("%d.%d.%d: ptr=%p, is_fx25=%d, retry=%d, age=%3d, crc=%04x, score=%d %s\n", chan, j, k, + dw_printf ("%d.%d.%d: ptr=%p, fec_type=%d, retry=%d, age=%3d, crc=%04x, score=%d %s\n", chan, j, k, candidate[chan][j][k].packet_p, - candidate[chan][j][k].is_fx25, + (int)(candidate[chan][j][k].fec_type), (int)(candidate[chan][j][k].retries), candidate[chan][j][k].age, candidate[chan][j][k].crc, @@ -611,7 +615,7 @@ static void pick_best_candidate (int chan) dlq_rec_frame (chan, j, k, candidate[chan][j][k].packet_p, candidate[chan][j][k].alevel, - candidate[chan][j][k].is_fx25, + candidate[chan][j][k].fec_type, (int)(candidate[chan][j][k].retries), spectrum); diff --git a/src/multi_modem.h b/src/multi_modem.h index de3061e..51c3cde 100644 --- a/src/multi_modem.h +++ b/src/multi_modem.h @@ -17,8 +17,8 @@ void multi_modem_process_sample (int c, int audio_sample); int multi_modem_get_dc_average (int chan); // Deprecated. Replace with ...packet -void multi_modem_process_rec_frame (int chan, int subchan, int slice, unsigned char *fbuf, int flen, alevel_t alevel, retry_t retries, int is_fx25); +void multi_modem_process_rec_frame (int chan, int subchan, int slice, unsigned char *fbuf, int flen, alevel_t alevel, retry_t retries, fec_type_t fec_type); -void multi_modem_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, retry_t retries, int is_fx25); +void multi_modem_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, retry_t retries, fec_type_t fec_type); #endif diff --git a/src/recv.c b/src/recv.c index a6b4afb..49040e5 100644 --- a/src/recv.c +++ b/src/recv.c @@ -339,7 +339,7 @@ void recv_process (void) * - Digipeater. */ - app_process_rec_packet (pitem->chan, pitem->subchan, pitem->slice, pitem->pp, pitem->alevel, pitem->is_fx25, pitem->retries, pitem->spectrum); + app_process_rec_packet (pitem->chan, pitem->subchan, pitem->slice, pitem->pp, pitem->alevel, pitem->fec_type, pitem->retries, pitem->spectrum); /*