mirror of https://github.com/wb2osz/direwolf.git
Add FEC type to station heard line.
This commit is contained in:
parent
7a8e4320ac
commit
a08d0939b5
42
src/atest.c
42
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<MAX_SUBCHANS; j++) {
|
||||
// if (spectrum[j] == '|') {
|
||||
// count[j]++;
|
||||
// }
|
||||
// }
|
||||
//#endif
|
||||
|
||||
|
||||
// Display non-APRS packets in a different color.
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@
|
|||
#include "il2p.h"
|
||||
#include "dwsock.h"
|
||||
#include "dns_sd_dw.h"
|
||||
#include "dlq.h" // for fec_type_t definition.
|
||||
|
||||
|
||||
//static int idx_decoded = 0;
|
||||
|
@ -300,7 +301,7 @@ int main (int argc, char *argv[])
|
|||
|
||||
text_color_init(t_opt);
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf ("Dire Wolf version %d.%d (%s) BETA TEST 5\n", MAJOR_VERSION, MINOR_VERSION, __DATE__);
|
||||
dw_printf ("Dire Wolf version %d.%d (%s) BETA TEST 7\n", MAJOR_VERSION, MINOR_VERSION, __DATE__);
|
||||
//dw_printf ("Dire Wolf DEVELOPMENT version %d.%d %s (%s)\n", MAJOR_VERSION, MINOR_VERSION, "G", __DATE__);
|
||||
//dw_printf ("Dire Wolf version %d.%d\n", MAJOR_VERSION, MINOR_VERSION);
|
||||
|
||||
|
@ -1179,7 +1180,7 @@ int main (int argc, char *argv[])
|
|||
|
||||
// TODO: Use only one printf per line so output doesn't get jumbled up with stuff from other threads.
|
||||
|
||||
void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, int is_fx25, retry_t retries, char *spectrum)
|
||||
void app_process_rec_packet (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];
|
||||
|
@ -1188,7 +1189,8 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev
|
|||
char heard[AX25_MAX_ADDR_LEN];
|
||||
//int j;
|
||||
int h;
|
||||
char display_retries[32];
|
||||
char display_retries[32]; // Extra stuff before slice indicators.
|
||||
// Can indicate FX.25/IL2P or fix_bits.
|
||||
|
||||
assert (chan >= 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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue