Skip to content

Commit 53e9ff7

Browse files
committed
Add IL2P.
1 parent 17b9336 commit 53e9ff7

36 files changed

+6887
-140
lines changed

CHANGES.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
### New Features: ###
99

10+
- Improved Layer 2 Protocol [(IL2P)](https://en.wikipedia.org/wiki/FX.25_Forward_Error_Correction). Use "-I 1" to enable transmit for first channel.
11+
1012
- Limited support for CM109/CM119 GPIO PTT on Windows.
1113

1214
- Dire Wolf now advertises itself using DNS Service Discovery. This allows suitable APRS / Packet Radio applications to find a network KISS TNC without knowing the IP address or TCP port. Thanks to Hessu for providing this. Currently available only for Linux and Mac OSX. [Read all about it here.](https://github.com/hessu/aprs-specs/blob/master/TCP-KISS-DNS-SD.md)

README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ Dire Wolf now includes [FX.25](https://en.wikipedia.org/wiki/FX.25_Forward_Error
1313

1414
![](fx25.png)
1515

16-
Dire Wolf is a modern software replacement for the old 1980's style TNC built with special hardware.
16+
Version 1.7 adds [IL2P](https://en.wikipedia.org/wiki/Improved_Layer_2_Protocol), a different method of FEC with less overhead.
17+
18+
19+
20+
### Dire Wolf is a modern software replacement for the old 1980's style TNC built with special hardware. ###
1721

1822
Without any additional software, it can perform as:
1923

man/direwolf.1

+9-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,15 @@ Divide audio sample by n for first channel.
8787

8888
.TP
8989
.BI "-X " "n"
90-
1 to enable FX.25 transmit.
90+
1 to enable FX.25 transmit. 16, 32, 64 for specific number of check bytes.
91+
92+
.TP
93+
.BI "-I " "n"
94+
Enable IL2P transmit. n=1 is recommended. 0 uses weaker FEC.
95+
96+
.TP
97+
.BI "-i " "n"
98+
Enable IL2P transmit, inverted polarity. n=1 is recommended. 0 uses weaker FEC.
9199

92100
.TP
93101
.BI "-d " "x"

man/gen_packets.1

+12
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ Force G3RUH modem regardless of data rate.
6262
.BI "-J "
6363
2400 bps QPSK compatible with MFJ-2400.
6464

65+
.TP
66+
.BI "-X " "n"
67+
1 to enable FX.25 transmit. 16, 32, 64 for specific number of check bytes.
68+
69+
.TP
70+
.BI "-I " "n"
71+
Enable IL2P transmit. n=1 is recommended. 0 uses weaker FEC.
72+
73+
.TP
74+
.BI "-i " "n"
75+
Enable IL2P transmit, inverted polarity. n=1 is recommended. 0 uses weaker FEC.
76+
6577

6678
.TP
6779
.BI "-m " "n"

src/CMakeLists.txt

+47
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ list(APPEND direwolf_SOURCES
6060
hdlc_rec2.c
6161
hdlc_send.c
6262
igate.c
63+
il2p_codec.c
64+
il2p_scramble.c
65+
il2p_rec.c
66+
il2p_payload.c
67+
il2p_init.c
68+
il2p_header.c
69+
il2p_send.c
6370
kiss_frame.c
6471
kiss.c
6572
kissserial.c
@@ -289,12 +296,20 @@ target_link_libraries(log2gpx
289296
list(APPEND gen_packets_SOURCES
290297
gen_packets.c
291298
ax25_pad.c
299+
ax25_pad2.c
292300
fx25_encode.c
301+
fx25_extract.c
293302
fx25_init.c
294303
fx25_send.c
295304
hdlc_send.c
296305
fcs_calc.c
297306
gen_tone.c
307+
il2p_codec.c
308+
il2p_scramble.c
309+
il2p_payload.c
310+
il2p_init.c
311+
il2p_header.c
312+
il2p_send.c
298313
morse.c
299314
dtmf.c
300315
textcolor.c
@@ -321,14 +336,22 @@ list(APPEND atest_SOURCES
321336
demod_9600.c
322337
dsp.c
323338
fx25_extract.c
339+
fx25_encode.c
324340
fx25_init.c
325341
fx25_rec.c
326342
hdlc_rec.c
327343
hdlc_rec2.c
344+
il2p_codec.c
345+
il2p_scramble.c
346+
il2p_rec.c
347+
il2p_payload.c
348+
il2p_init.c
349+
il2p_header.c
328350
multi_modem.c
329351
rrbb.c
330352
fcs_calc.c
331353
ax25_pad.c
354+
ax25_pad2.c
332355
decode_aprs.c
333356
dwgpsnmea.c
334357
dwgps.c
@@ -421,6 +444,29 @@ if(WIN32 OR CYGWIN)
421444
endif()
422445

423446

447+
# TNC interoperability testing for AX.25 connected mode.
448+
# tnctest
449+
list(APPEND tnctest_SOURCES
450+
tnctest.c
451+
textcolor.c
452+
dtime_now.c
453+
serial_port.c
454+
)
455+
456+
add_executable(tnctest
457+
${tnctest_SOURCES}
458+
)
459+
460+
target_link_libraries(tnctest
461+
${MISC_LIBRARIES}
462+
Threads::Threads
463+
)
464+
465+
if(WIN32 OR CYGWIN)
466+
target_link_libraries(tnctest ws2_32)
467+
endif()
468+
469+
424470
# List USB audio adapters than can use GPIO for PTT.
425471
# Originally for Linux only (using udev).
426472
# Version 1.7 adds it for Windows. Needs hidapi library.
@@ -520,6 +566,7 @@ install(TARGETS gen_packets DESTINATION ${INSTALL_BIN_DIR})
520566
install(TARGETS atest DESTINATION ${INSTALL_BIN_DIR})
521567
install(TARGETS ttcalc DESTINATION ${INSTALL_BIN_DIR})
522568
install(TARGETS kissutil DESTINATION ${INSTALL_BIN_DIR})
569+
install(TARGETS tnctest DESTINATION ${INSTALL_BIN_DIR})
523570
install(TARGETS appserver DESTINATION ${INSTALL_BIN_DIR})
524571
if(UDEV_FOUND OR WIN32 OR CYGWIN)
525572
install(TARGETS cm108 DESTINATION ${INSTALL_BIN_DIR})

src/atest.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This file is part of Dire Wolf, an amateur radio packet TNC.
44
//
5-
// Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2019 John Langner, WB2OSZ
5+
// Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2019, 2021 John Langner, WB2OSZ
66
//
77
// This program is free software: you can redistribute it and/or modify
88
// it under the terms of the GNU General Public License as published by
@@ -82,6 +82,7 @@
8282
#include "ptt.h"
8383
#include "dtime_now.h"
8484
#include "fx25.h"
85+
#include "il2p.h"
8586
#include "hdlc_rec.h"
8687

8788

@@ -189,6 +190,7 @@ static int h_opt = 0; // Hexadecimal display of received packet.
189190
static char P_opt[16] = ""; // Demodulator profiles.
190191
static int d_x_opt = 1; // FX.25 debug.
191192
static int d_o_opt = 0; // "-d o" option for DCD output control. */
193+
static int d_2_opt = 0; // "-d 2" option for IL2P details. */
192194
static int dcd_count = 0;
193195
static int dcd_missing_errors = 0;
194196

@@ -389,6 +391,7 @@ int main (int argc, char *argv[])
389391
switch (*p) {
390392
case 'x': d_x_opt++; break; // FX.25
391393
case 'o': d_o_opt++; break; // DCD output control
394+
case '2': d_2_opt++; break; // IL2P debug out
392395
default: break;
393396
}
394397
}
@@ -539,6 +542,7 @@ int main (int argc, char *argv[])
539542
}
540543

541544
fx25_init (d_x_opt);
545+
il2p_init (d_2_opt);
542546

543547
start_time = dtime_now();
544548

src/audio.h

+19-1
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,11 @@ struct audio_s {
107107
float recv_ber; /* Receive Bit Error Rate (BER). */
108108
/* Probability of inverting a bit coming out of the modem. */
109109

110-
int fx25_xmit_enable; /* Enable transmission of FX.25. */
110+
//int fx25_xmit_enable; /* Enable transmission of FX.25. */
111111
/* See fx25_init.c for explanation of values. */
112112
/* Initially this applies to all channels. */
113113
/* This should probably be per channel. One step at a time. */
114+
/* v1.7 - replaced by layer2_xmit==LAYER2_FX25 */
114115

115116
int fx25_auto_enable; /* Turn on FX.25 for current connected mode session */
116117
/* under poor conditions. */
@@ -156,6 +157,23 @@ struct audio_s {
156157
/* Might try MFJ-2400 / CCITT v.26 / Bell 201 someday. */
157158
/* No modem. Might want this for DTMF only channel. */
158159

160+
enum layer2_t { LAYER2_AX25 = 0, LAYER2_FX25, LAYER2_IL2P } layer2_xmit;
161+
162+
// IL2P - New for version 1.7.
163+
// New layer 2 with FEC. Much less overhead than FX.25 but no longer backward compatible.
164+
// Only applies to transmit.
165+
// Listening for FEC sync word should add negligible overhead so
166+
// we leave reception enabled all the time as we do with FX.25.
167+
// TODO: FX.25 should probably be put here rather than global for all channels.
168+
169+
int fx25_strength; // Strength of FX.25 FEC.
170+
// 16, 23, 64 for specific number of parity symbols.
171+
// 1 for automatic selection based on frame size.
172+
173+
int il2p_max_fec; // 1 for max FEC length, 0 for automatic based on size.
174+
175+
int il2p_invert_polarity; // 1 means invert on transmit. Receive handles either automatically.
176+
159177
enum v26_e { V26_UNSPECIFIED=0, V26_A, V26_B } v26_alternative;
160178

161179
// Original implementation used alternative A for 2400 bbps PSK.

src/ax25_pad.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -2751,6 +2751,7 @@ unsigned short ax25_m_m_crc (packet_t pp)
27512751
unsigned char fbuf[AX25_MAX_PACKET_LEN];
27522752
int flen;
27532753

2754+
// TODO: I think this can be more efficient by getting the packet content pointer instead of copying.
27542755
flen = ax25_pack (pp, fbuf);
27552756

27562757
crc = 0xffff;
@@ -2803,7 +2804,8 @@ unsigned short ax25_m_m_crc (packet_t pp)
28032804
*
28042805
*------------------------------------------------------------------*/
28052806

2806-
#define MAXSAFE 500
2807+
//#define MAXSAFE 500
2808+
#define MAXSAFE AX25_MAX_INFO_LEN
28072809

28082810
void ax25_safe_print (char *pstr, int len, int ascii_only)
28092811
{

src/config.c

+54-6
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ static int check_via_path (char *via_path)
585585
*
586586
*--------------------------------------------------------------------*/
587587

588-
#define MAXCMDLEN 256
588+
#define MAXCMDLEN 1200
589589

590590

591591
static char *split (char *string, int rest_of_line)
@@ -770,6 +770,10 @@ void config_init (char *fname, struct audio_s *p_audio_config,
770770
p_audio_config->achan[channel].num_freq = 1;
771771
p_audio_config->achan[channel].offset = 0;
772772

773+
p_audio_config->achan[channel].layer2_xmit = LAYER2_AX25;
774+
p_audio_config->achan[channel].il2p_max_fec = 1;
775+
p_audio_config->achan[channel].il2p_invert_polarity = 0;
776+
773777
p_audio_config->achan[channel].fix_bits = DEFAULT_FIX_BITS;
774778
p_audio_config->achan[channel].sanity_test = SANITY_APRS;
775779
p_audio_config->achan[channel].passall = 0;
@@ -2252,7 +2256,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
22522256
* 0 = off, 1 = auto mode, others are suggestions for testing
22532257
* or special cases. 16, 32, 64 is number of parity bytes to add.
22542258
* Also set by "-X n" command line option.
2255-
* Current a global setting. Could be per channel someday.
2259+
* V1.7 changed from global to per-channel setting.
22562260
*/
22572261

22582262
else if (strcasecmp(t, "FX25TX") == 0) {
@@ -2265,13 +2269,15 @@ void config_init (char *fname, struct audio_s *p_audio_config,
22652269
}
22662270
n = atoi(t);
22672271
if (n >= 0 && n < 200) {
2268-
p_audio_config->fx25_xmit_enable = n;
2272+
p_audio_config->achan[channel].fx25_strength = n;
2273+
p_audio_config->achan[channel].layer2_xmit = LAYER2_FX25;
22692274
}
22702275
else {
2271-
p_audio_config->fx25_xmit_enable = 1;
2276+
p_audio_config->achan[channel].fx25_strength = 1;
2277+
p_audio_config->achan[channel].layer2_xmit = LAYER2_FX25;
22722278
text_color_set(DW_COLOR_ERROR);
22732279
dw_printf ("Line %d: Unreasonable value for FX.25 transmission mode. Using %d.\n",
2274-
line, p_audio_config->fx25_xmit_enable);
2280+
line, p_audio_config->achan[channel].fx25_strength);
22752281
}
22762282
}
22772283

@@ -2304,6 +2310,48 @@ void config_init (char *fname, struct audio_s *p_audio_config,
23042310
}
23052311
}
23062312

2313+
/*
2314+
* IL2PTX [ + - ] [ 0 1 ] - Enable IL2P transmission. Default off.
2315+
* "+" means normal polarity. Redundant since it is the default.
2316+
* (command line -I for first channel)
2317+
* "-" means inverted polarity. Do not use for 1200 bps.
2318+
* (command line -i for first channel)
2319+
* "0" means weak FEC. Not recommended.
2320+
* "1" means stronger FEC. "Max FEC." Default if not specified.
2321+
*/
2322+
2323+
else if (strcasecmp(t, "IL2PTX") == 0) {
2324+
2325+
p_audio_config->achan[channel].layer2_xmit = LAYER2_IL2P;
2326+
p_audio_config->achan[channel].il2p_max_fec = 1;
2327+
p_audio_config->achan[channel].il2p_invert_polarity = 0;
2328+
2329+
while ((t = split(NULL,0)) != NULL) {
2330+
for (char *c = t; *t != '\0'; c++) {
2331+
switch (*c) {
2332+
case '+':
2333+
p_audio_config->achan[channel].il2p_invert_polarity = 0;
2334+
break;
2335+
case '-':
2336+
p_audio_config->achan[channel].il2p_invert_polarity = 1;
2337+
break;
2338+
case '0':
2339+
p_audio_config->achan[channel].il2p_max_fec = 0;
2340+
break;
2341+
case '1':
2342+
p_audio_config->achan[channel].il2p_max_fec = 1;
2343+
break;
2344+
default:
2345+
text_color_set(DW_COLOR_ERROR);
2346+
dw_printf ("Line %d: Invalid parameter '%c' fol IL2PTX command.\n", line, *c);
2347+
continue;
2348+
break;
2349+
}
2350+
}
2351+
}
2352+
}
2353+
2354+
23072355
/*
23082356
* ==================== APRS Digipeater parameters ====================
23092357
*/
@@ -5399,7 +5447,7 @@ static int beacon_options(char *cmd, struct beacon_s *b, int line, struct audio_
53995447
while ((t = split(NULL,0)) != NULL) {
54005448

54015449
char keyword[20];
5402-
char value[200];
5450+
char value[1000];
54035451
char *e;
54045452
char *p;
54055453

0 commit comments

Comments
 (0)