mirror of https://github.com/wb2osz/direwolf.git
1.4 development snapshot C.
IBEACON for IGate statistics. NMEA style waypoints. Clean up compile warnings and header file use for Windows.
This commit is contained in:
parent
48aeb43829
commit
3e9118ba17
18
CHANGES.md
18
CHANGES.md
|
@ -3,15 +3,27 @@
|
|||
|
||||
----------
|
||||
|
||||
## Version 1.4 -- Development snapshot B -- April 2016 ##
|
||||
## Version 1.4 -- Development snapshot C -- June 2016 ##
|
||||
|
||||
This is a snapshot at some semi-stable point in the development of the next version. It is not well tested. New features might be incomplete, poorly documented, and subject to change.
|
||||
|
||||
|
||||
### New Features: ###
|
||||
|
||||
- New beacon type, IBEACON, for sending IGate statistics.
|
||||
|
||||
- 2400 & 4800 bps PSK modems. See ***2400-4800-PSK-for-APRS-Packet-Radio.pdf*** in the doc directory for discussion.
|
||||
|
||||
|
||||
- The top speed of 9600 bps has been increased to 38400. You will need a sound card capable of 96k or 192k samples per second for the higher rates. Radios must also have adequate bandwidth. See ***Going-beyond-9600-baud.pdf*** in the doc directory for more details.
|
||||
|
||||
- Better decoder performance for 9600 and higher especially for low audio sample rate to baud ratios.
|
||||
|
||||
- Generate waypoint sentences for use by AvMap G5 / G6 or other mapping devices or applications. Formats include
|
||||
- $GPWPL - NMEA generic with only location and name.
|
||||
- $PGRMW - Garmin, adds altitude, symbol, and comment to previously named waypoint.
|
||||
- $PMGNWPL - Magellan, more complete for stationary objects.
|
||||
- $PKWDWPL - Kenwood with APRS style symbol but missing comment.
|
||||
|
||||
### Bugs Fixed: ###
|
||||
|
||||
|
@ -31,9 +43,11 @@ received frames are not being printed. After a while this message will appear:
|
|||
another application is not reading the frames from the other side.*
|
||||
|
||||
|
||||
- The Windows version 1.3 would crash when starting to transmit on Windows XP. There have also been some other reports of erratic behavior on Windows. The crashing problem was fixed in in the 1.3.1 patch release. Linux version was not affected.
|
||||
|
||||
----------
|
||||
|
||||
## Version 1.3 -- Beta Test -- March 2016 ##
|
||||
## Version 1.3 -- May 2016 ##
|
||||
|
||||
### New Features: ###
|
||||
|
||||
|
|
|
@ -229,13 +229,13 @@ z := $(notdir ${CURDIR})
|
|||
|
||||
|
||||
direwolf : direwolf.o config.o recv.o demod.o dsp.o demod_afsk.o demod_psk.o demod_9600.o hdlc_rec.o \
|
||||
hdlc_rec2.o multi_modem.o redecode.o rdq.o rrbb.o dlq.o \
|
||||
hdlc_rec2.o multi_modem.o rdq.o rrbb.o dlq.o \
|
||||
fcs_calc.o ax25_pad.o \
|
||||
decode_aprs.o symbols.o server.o kiss.o kissnet.o kiss_frame.o hdlc_send.o fcs_calc.o \
|
||||
gen_tone.o audio.o audio_stats.o digipeater.o pfilter.o dedupe.o tq.o xmit.o morse.o \
|
||||
ptt.o beacon.o encode_aprs.o latlong.o encode_aprs.o latlong.o textcolor.o \
|
||||
dtmf.o aprs_tt.o tt_user.o tt_text.o igate.o waypoint.o serial_port.o log.o telemetry.o \
|
||||
dwgps.o dwgpsnmea.o dwgpsd.o dtime_now.o \
|
||||
dwgps.o dwgpsnmea.o dwgpsd.o dtime_now.o mheard.o \
|
||||
misc.a geotranz.a
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
ifneq ($(enable_gpsd),)
|
||||
|
@ -333,7 +333,7 @@ gen_packets : gen_packets.c ax25_pad.c hdlc_send.c fcs_calc.c gen_tone.c morse.c
|
|||
atest : atest.c demod.o demod_afsk.o demod_psk.o demod_9600.o \
|
||||
dsp.o hdlc_rec.o hdlc_rec2.o multi_modem.o rrbb.o \
|
||||
fcs_calc.o ax25_pad.o decode_aprs.o dwgpsnmea.o \
|
||||
dwgps.o dwgpsd.o serial_port.o telemetry.o latlong.o symbols.o tt_text.o textcolor.o \
|
||||
dwgps.o dwgpsd.o serial_port.o telemetry.o dtime_now.o latlong.o symbols.o tt_text.o textcolor.o \
|
||||
misc.a
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
|
@ -606,14 +606,14 @@ check-modem300 : gen_packets atest
|
|||
|
||||
check-modem9600 : gen_packets atest
|
||||
./gen_packets -B9600 -n 100 -o /tmp/test96.wav
|
||||
./atest -B9600 -F0 -L57 -G61 /tmp/test96.wav
|
||||
./atest -B9600 -F1 -L64 -G67 /tmp/test96.wav
|
||||
./atest -B9600 -F0 -L50 -G54 /tmp/test96.wav
|
||||
./atest -B9600 -F1 -L55 -G59 /tmp/test96.wav
|
||||
rm /tmp/test96.wav
|
||||
|
||||
check-modem19200 : gen_packets atest
|
||||
./gen_packets -r 96000 -B19200 -n 100 -o /tmp/test19.wav
|
||||
./atest -B19200 -F0 -L62 -G64 /tmp/test19.wav
|
||||
./atest -B19200 -F1 -L69 -G71 /tmp/test19.wav
|
||||
./atest -B19200 -F0 -L55 -G59 /tmp/test19.wav
|
||||
./atest -B19200 -F1 -L60 -G64 /tmp/test19.wav
|
||||
rm /tmp/test19.wav
|
||||
|
||||
check-modem2400 : gen_packets atest
|
||||
|
@ -743,11 +743,26 @@ tune.h :
|
|||
|
||||
|
||||
testagc : atest.c demod.c dsp.c demod_afsk.c demod_psk.c demod_9600.c hdlc_rec.o hdlc_rec2.o multi_modem.o rrbb.o \
|
||||
fcs_calc.o ax25_pad.o decode_aprs.o telemetry.o latlong.o symbols.o tune.h textcolor.o misc.a
|
||||
fcs_calc.o ax25_pad.o decode_aprs.o telemetry.o dtime_now.o latlong.o symbols.o tune.h textcolor.o misc.a
|
||||
$(CC) $(CFLAGS) -o atest $^ $(LDFLAGS)
|
||||
./atest 02_Track_2.wav | grep "packets decoded in" > atest.out
|
||||
|
||||
|
||||
testagc96 : atest.c fsk_fast_filter.h tune.h demod.c demod_afsk.c demod_psk.c demod_9600.c \
|
||||
dsp.o hdlc_rec.o hdlc_rec2.o multi_modem.o \
|
||||
rrbb.o fcs_calc.o ax25_pad.o decode_aprs.o \
|
||||
dwgpsnmea.o dwgps.o dwgpsd.o serial_port.o latlong.o \
|
||||
symbols.o tt_text.o textcolor.o telemetry.o dtime_now.o \
|
||||
misc.a
|
||||
rm -f atest96
|
||||
$(CC) $(CFLAGS) -o atest96 $^ $(LDFLAGS)
|
||||
./atest96 -B 9600 ../walkabout9600c.wav | grep "packets decoded in" >atest.out
|
||||
#./atest96 -B 9600 noisy96.wav | grep "packets decoded in" >atest.out
|
||||
#./atest96 -B 9600 19990303_0225_9600_8bis_22kHz.wav | grep "packets decoded in" >atest.out
|
||||
#./atest96 -B 9600 19990303_0225_9600_16bit_22kHz.wav | grep "packets decoded in" >atest.out
|
||||
#./atest96 -B 9600 -P + z8-22k.wav| grep "packets decoded in" >atest.out
|
||||
#./atest96 -B 9600 test9600.wav | grep "packets decoded in" >atest.out
|
||||
echo " " > tune.h
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -227,9 +227,9 @@ direwolf : direwolf.o aprs_tt.o audio_portaudio.o audio_stats.o ax25_pad.o beaco
|
|||
encode_aprs.o encode_aprs.o fcs_calc.o fcs_calc.o gen_tone.o \
|
||||
geotranz.a hdlc_rec.o hdlc_rec2.o hdlc_send.o igate.o kiss_frame.o \
|
||||
kiss.o kissnet.o latlong.o latlong.o log.o morse.o multi_modem.o \
|
||||
waypoint.o serial_port.o pfilter.o ptt.o rdq.o recv.o redecode.o rrbb.o server.o \
|
||||
waypoint.o serial_port.o pfilter.o ptt.o rdq.o recv.o rrbb.o server.o \
|
||||
symbols.o telemetry.o textcolor.o tq.o tt_text.o tt_user.o xmit.o \
|
||||
dwgps.o dwgpsnmea.o
|
||||
dwgps.o dwgpsnmea.o mheard.o
|
||||
$(CC) $(CFLAGS) -o $@ $^ -lpthread $(LDLIBS) -lm
|
||||
|
||||
|
||||
|
@ -453,7 +453,7 @@ tune.h :
|
|||
|
||||
|
||||
testagc : atest.c demod.c dsp.c demod_afsk.c demod_9600.c hdlc_rec.c hdlc_rec2.o multi_modem.o rrbb.o \
|
||||
fcs_calc.c ax25_pad.c decode_aprs.c telemetry.c latlong.c symbols.c tune.h textcolor.c
|
||||
fcs_calc.c ax25_pad.c decode_aprs.c telemetry.c dtime_now.o latlong.c symbols.c tune.h textcolor.c
|
||||
$(CC) $(CFLAGS) -o atest $^ -lm
|
||||
./atest 02_Track_2.wav | grep "packets decoded in" > atest.out
|
||||
|
||||
|
@ -461,7 +461,7 @@ testagc : atest.c demod.c dsp.c demod_afsk.c demod_9600.c hdlc_rec.c hdlc_rec2.o
|
|||
# Unit test for demodulators
|
||||
|
||||
atest : atest.c demod.c dsp.c demod_afsk.c demod_psk.c demod_9600.c hdlc_rec.c hdlc_rec2.o multi_modem.o rrbb.o \
|
||||
fcs_calc.c ax25_pad.c decode_aprs.c dwgpsnmea.o dwgps.o serial_port.o telemetry.c latlong.c symbols.c textcolor.c tt_text.c
|
||||
fcs_calc.c ax25_pad.c decode_aprs.c dwgpsnmea.o dwgps.o serial_port.o telemetry.c dtest_now.o latlong.c symbols.c textcolor.c tt_text.c
|
||||
$(CC) $(CFLAGS) -o $@ $^ -lm
|
||||
#atest : atest.c fsk_fast_filter.h demod.c dsp.c demod_afsk.c demod_psk.c demod_9600.c hdlc_rec.c hdlc_rec2.o multi_modem.o rrbb.o \
|
||||
# fcs_calc.c ax25_pad.c decode_aprs.c dwgpsnmea.o dwgps.o serial_port.o telemetry.c latlong.c symbols.c textcolor.c tt_text.c
|
||||
|
|
121
Makefile.win
121
Makefile.win
|
@ -21,13 +21,24 @@ all : direwolf decode_aprs text2tt tt2text ll2utm utm2ll aclients log2gpx gen_pa
|
|||
|
||||
# People say we need -mthreads option for threads to work properly.
|
||||
# They also say it creates a dependency on mingwm10.dll but I'm not seeing that.
|
||||
# Maybe that is for pthreads. We are using the Windows threads.
|
||||
|
||||
# -Ofast was added in gcc 4.6 which was the MinGW version back in 2012.
|
||||
|
||||
CC := gcc
|
||||
CFLAGS := -Wall -Ofast -march=pentium3 -msse -Iregex -Iutm -Igeotranz -mthreads -DUSE_REGEX_STATIC
|
||||
#CFLAGS := -Wall -march=pentium3 -msse -Iregex -Iutm -Igeotranz -mthreads -DUSE_REGEX_STATIC
|
||||
AR := ar
|
||||
|
||||
CFLAGS += -g
|
||||
|
||||
# For version 1.4, we upgrade from 4.6.2 to 4.9.3.
|
||||
|
||||
# gcc 4.8 adds these. Try them just for fun.
|
||||
# No, it needs libasan which is not on Windows.
|
||||
#CFLAGS += -fsanitize=address -fno-omit-frame-pointer
|
||||
|
||||
|
||||
# TODO: Development in progress. Don't try using yet.
|
||||
#CFLAGS += -DNEW14
|
||||
|
||||
|
@ -78,13 +89,13 @@ demod_psk.o : fsk_demod_state.h
|
|||
# later ax25_link.o
|
||||
|
||||
direwolf : direwolf.o config.o recv.o demod.o dsp.o demod_afsk.o demod_psk.o demod_9600.o hdlc_rec.o \
|
||||
hdlc_rec2.o multi_modem.o redecode.o rdq.o rrbb.o dlq.o \
|
||||
hdlc_rec2.o multi_modem.o rdq.o rrbb.o dlq.o \
|
||||
fcs_calc.o ax25_pad.o ax25_pad2.o \
|
||||
decode_aprs.o symbols.o server.o kiss.o kissnet.o kiss_frame.o hdlc_send.o fcs_calc.o \
|
||||
gen_tone.o morse.o audio_win.o audio_stats.o digipeater.o pfilter.o dedupe.o tq.o xmit.o \
|
||||
ptt.o beacon.o dwgps.o encode_aprs.o latlong.o textcolor.o \
|
||||
dtmf.o aprs_tt.o tt_user.o tt_text.o igate.o waypoint.o serial_port.o log.o telemetry.o \
|
||||
dwgps.o dwgpsnmea.o dtime_now.o \
|
||||
dwgps.o dwgpsnmea.o dtime_now.o mheard.o \
|
||||
dw-icon.o regex.a misc.a geotranz.a
|
||||
$(CC) $(CFLAGS) -o $@ $^ -lwinmm -lws2_32
|
||||
|
||||
|
@ -269,16 +280,16 @@ check-modem300 : gen_packets atest
|
|||
check-modem9600 : gen_packets atest
|
||||
gen_packets -B9600 -n 100 -o test96.wav
|
||||
sleep 1
|
||||
atest -B9600 -F0 -L57 -G62 test96.wav
|
||||
atest -B9600 -F1 -L65 -G67 test96.wav
|
||||
atest -B9600 -F0 -L50 -G54 test96.wav
|
||||
atest -B9600 -F1 -L55 -G59 test96.wav
|
||||
sleep 1
|
||||
rm test96.wav
|
||||
|
||||
check-modem19200 : gen_packets atest
|
||||
gen_packets -r 96000 -B19200 -n 100 -o test19.wav
|
||||
sleep 1
|
||||
atest -B19200 -F0 -L63 -G64 test19.wav
|
||||
atest -B19200 -F1 -L69 -G70 test19.wav
|
||||
atest -B19200 -F0 -L55 -G59 test19.wav
|
||||
atest -B19200 -F1 -L60 -G64 test19.wav
|
||||
sleep 1
|
||||
rm test19.wav
|
||||
|
||||
|
@ -288,7 +299,7 @@ check-modem2400 : gen_packets atest
|
|||
atest -B2400 -F0 -L70 -G78 test24.wav
|
||||
atest -B2400 -F1 -L80 -G87 test24.wav
|
||||
sleep 1
|
||||
#rm test24.wav
|
||||
rm test24.wav
|
||||
|
||||
check-modem4800 : gen_packets atest
|
||||
gen_packets -B4800 -n 100 -o test48.wav
|
||||
|
@ -296,7 +307,7 @@ check-modem4800 : gen_packets atest
|
|||
atest -B4800 -F0 -L70 -G74 test48.wav
|
||||
atest -B4800 -F1 -L79 -G84 test48.wav
|
||||
sleep 1
|
||||
#rm test48.wav
|
||||
rm test48.wav
|
||||
|
||||
|
||||
# Unit test for demodulators
|
||||
|
@ -305,7 +316,7 @@ atest : atest.c fsk_fast_filter.h demod.c demod_afsk.c demod_psk.c demod_9600.c
|
|||
dsp.o hdlc_rec.o hdlc_rec2.o multi_modem.o \
|
||||
rrbb.o fcs_calc.o ax25_pad.o decode_aprs.o \
|
||||
dwgpsnmea.o dwgps.o serial_port.o latlong.c \
|
||||
symbols.c tt_text.c textcolor.c telemetry.c \
|
||||
symbols.c tt_text.c textcolor.c telemetry.c dtime_now.o \
|
||||
misc.a regex.a
|
||||
echo " " > tune.h
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
@ -314,7 +325,7 @@ atest : atest.c fsk_fast_filter.h demod.c demod_afsk.c demod_psk.c demod_9600.c
|
|||
#atest za100.wav
|
||||
|
||||
atest9 : atest.c demod.c dsp.c demod_afsk.c demod_psk.c demod_9600.c hdlc_rec.c hdlc_rec2.c multi_modem.c \
|
||||
rrbb.c fcs_calc.c ax25_pad.c decode_aprs.c latlong.c symbols.c textcolor.c telemetry.c misc.a regex.a \
|
||||
rrbb.c fcs_calc.c ax25_pad.c decode_aprs.c latlong.c symbols.c textcolor.c telemetry.c dtime_now.o misc.a regex.a \
|
||||
fsk_fast_filter.h
|
||||
echo " " > tune.h
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
@ -415,7 +426,7 @@ demod_psk.o : tune.h
|
|||
testagc : atest.c demod.c dsp.c demod_afsk.c demod_psk.c demod_9600.o fsk_demod_agc.h \
|
||||
hdlc_rec.o hdlc_rec2.o multi_modem.o \
|
||||
rrbb.o fcs_calc.o ax25_pad.o decode_aprs.o latlong.o symbols.o textcolor.o telemetry.o \
|
||||
dwgpsnmea.o dwgps.o serial_port.o tt_text.o regex.a misc.a
|
||||
dwgpsnmea.o dwgps.o serial_port.o tt_text.o dtime_now.o regex.a misc.a
|
||||
rm -f atest.exe
|
||||
$(CC) $(CFLAGS) -o atest $^
|
||||
./atest -P GGG- -F 0 ../02_Track_2.wav | grep "packets decoded in" >atest.out
|
||||
|
@ -426,7 +437,7 @@ noisy3.wav : gen_packets
|
|||
./gen_packets -B 300 -n 100 -o noisy3.wav
|
||||
|
||||
testagc3 : atest.c demod.c dsp.c demod_afsk.c demod_psk.c demod_9600.c hdlc_rec.c hdlc_rec2.c multi_modem.c \
|
||||
rrbb.c fcs_calc.c ax25_pad.c decode_aprs.c latlong.c symbols.c textcolor.c telemetry.c regex.a misc.a \
|
||||
rrbb.c fcs_calc.c ax25_pad.c decode_aprs.c latlong.c symbols.c textcolor.c telemetry.c dtime_now.o regex.a misc.a \
|
||||
tune.h
|
||||
rm -f atest3.exe
|
||||
$(CC) $(CFLAGS) -o atest3 $^
|
||||
|
@ -437,20 +448,27 @@ testagc3 : atest.c demod.c dsp.c demod_afsk.c demod_psk.c demod_9600.c hdlc_rec.
|
|||
noisy96.wav : gen_packets
|
||||
./gen_packets -B 9600 -n 100 -o noisy96.wav
|
||||
|
||||
testagc96 : atest.c demod.c dsp.c demod_afsk.c demod_psk.c demod_9600.c hdlc_rec.c hdlc_rec2.c multi_modem.c \
|
||||
rrbb.c fcs_calc.c ax25_pad.c decode_aprs.c latlong.c symbols.c textcolor.c telemetry.c regex.a misc.a \
|
||||
tune.h
|
||||
rm -f atest9.exe
|
||||
$(CC) $(CFLAGS) -o atest9 $^
|
||||
./atest9 -B 9600 ../walkabout9600.wav | grep "packets decoded in" >atest.out
|
||||
#./atest9 -B 9600 noisy96.wav | grep "packets decoded in" >atest.out
|
||||
testagc96 : atest.c fsk_fast_filter.h tune.h demod.c demod_afsk.c demod_psk.c demod_9600.c \
|
||||
dsp.o hdlc_rec.o hdlc_rec2.o multi_modem.o \
|
||||
rrbb.o fcs_calc.o ax25_pad.o decode_aprs.o \
|
||||
dwgpsnmea.o dwgps.o serial_port.o latlong.o \
|
||||
symbols.o tt_text.o textcolor.o telemetry.o dtime_now.o \
|
||||
misc.a regex.a
|
||||
rm -f atest96.exe
|
||||
$(CC) $(CFLAGS) -o atest96 $^
|
||||
./atest96 -B 9600 ../walkabout9600c.wav | grep "packets decoded in" >atest.out
|
||||
#./atest96 -B 9600 noisy96.wav | grep "packets decoded in" >atest.out
|
||||
#./atest96 -B 9600 19990303_0225_9600_8bis_22kHz.wav | grep "packets decoded in" >atest.out
|
||||
#./atest96 -B 9600 19990303_0225_9600_16bit_22kHz.wav | grep "packets decoded in" >atest.out
|
||||
#./atest96 -B 9600 -P + z8-22k.wav| grep "packets decoded in" >atest.out
|
||||
#./atest96 -B 9600 test9600.wav | grep "packets decoded in" >atest.out
|
||||
echo " " > tune.h
|
||||
|
||||
testagc24 : atest.c fsk_fast_filter.h tune.h demod.c demod_afsk.c demod_psk.c demod_9600.c \
|
||||
dsp.o hdlc_rec.o hdlc_rec2.o multi_modem.o \
|
||||
rrbb.o fcs_calc.o ax25_pad.o decode_aprs.o \
|
||||
dwgpsnmea.o dwgps.o serial_port.o latlong.o \
|
||||
symbols.o tt_text.o textcolor.o telemetry.o \
|
||||
symbols.o tt_text.o textcolor.o telemetry.o dtime_now.o \
|
||||
misc.a regex.a
|
||||
rm -f atest24.exe
|
||||
sleep 1
|
||||
|
@ -462,7 +480,7 @@ testagc48 : atest.c fsk_fast_filter.h tune.h demod.c demod_afsk.c demod_psk.c de
|
|||
dsp.o hdlc_rec.o hdlc_rec2.o multi_modem.o \
|
||||
rrbb.o fcs_calc.o ax25_pad.o decode_aprs.o \
|
||||
dwgpsnmea.o dwgps.o serial_port.o latlong.o \
|
||||
symbols.o tt_text.o textcolor.o telemetry.o \
|
||||
symbols.o tt_text.o textcolor.o telemetry.o dtime_now.o \
|
||||
misc.a regex.a
|
||||
rm -f atest48.exe
|
||||
sleep 1
|
||||
|
@ -570,67 +588,6 @@ dist-win : direwolf.exe decode_aprs.exe text2tt.exe tt2text.exe ll2utm.exe utm2l
|
|||
dwespeak.bat \
|
||||
telemetry-toolkit/*
|
||||
|
||||
.PHONY: dist-src
|
||||
dist-src : README.md CHANGES.md \
|
||||
doc/User-Guide.pdf \
|
||||
doc/Raspberry-Pi-APRS.pdf \
|
||||
doc/Raspberry-Pi-APRS-Tracker.pdf \
|
||||
doc/APRStt-Implementation-Notes.pdf \
|
||||
doc/APRS-Telemetry-Toolkit.pdf \
|
||||
dw-start.sh dwespeak.bat dwespeak.sh \
|
||||
tocalls.txt symbols-new.txt symbolsX.txt direwolf.spec
|
||||
rm -f fsk_fast_filter.h
|
||||
echo " " > tune.h
|
||||
rm -f ../$z-src.zip
|
||||
dos2unix generic.conf
|
||||
dos2unix Makefile
|
||||
dos2unix Makefile.linux
|
||||
dos2unix Makefile.macosx
|
||||
dos2unix telemetry-toolkit/telem-balloon.conf
|
||||
dos2unix telemetry-toolkit/telem-balloon.pl
|
||||
dos2unix telemetry-toolkit/telem-bits.pl
|
||||
dos2unix telemetry-toolkit/telem-data.pl
|
||||
dos2unix telemetry-toolkit/telem-data91.pl
|
||||
dos2unix telemetry-toolkit/telem-eqns.pl
|
||||
dos2unix telemetry-toolkit/telem-m0xer-3.txt
|
||||
dos2unix telemetry-toolkit/telem-parm.pl
|
||||
dos2unix telemetry-toolkit/telem-unit.pl
|
||||
dos2unix telemetry-toolkit/telem-volts.py
|
||||
dos2unix telemetry-toolkit/telem-volts.conf
|
||||
(cd .. ; zip $z-src.zip \
|
||||
$z/README.md \
|
||||
$z/CHANGES.md \
|
||||
$z/LICENSE* \
|
||||
$z/doc/User-Guide.pdf \
|
||||
$z/doc/Raspberry-Pi-APRS.pdf \
|
||||
$z/doc/Raspberry-Pi-APRS-Tracker.pdf \
|
||||
$z/doc/APRStt-Implementation-Notes.pdf \
|
||||
$z/doc/APRS-Telemetry-Toolkit.pdf \
|
||||
$z/Makefile.win $z/Makefile.linux $z/Makefile.macosx $z/Makefile \
|
||||
$z/*.c $z/*.h \
|
||||
$z/regex/* $z/misc/* $z/geotranz/* \
|
||||
$z/man1/* \
|
||||
$z/generic.conf \
|
||||
$z/tocalls.txt $z/symbols-new.txt $z/symbolsX.txt \
|
||||
$z/dw-icon.png $z/dw-icon.rc $z/dw-icon.ico \
|
||||
$z/dw-start.sh $z/direwolf.spec \
|
||||
$z/dwespeak.bat $z/dwespeak.sh \
|
||||
$z/telemetry-toolkit/* )
|
||||
unix2dos Makefile
|
||||
unix2dos Makefile.linux
|
||||
unix2dos Makefile.macosx
|
||||
unix2dos telemetry-toolkit/telem-balloon.conf
|
||||
unix2dos telemetry-toolkit/telem-balloon.pl
|
||||
dos2unix telemetry-toolkit/telem-bits.pl
|
||||
unix2dos telemetry-toolkit/telem-data.pl
|
||||
unix2dos telemetry-toolkit/telem-data91.pl
|
||||
unix2dos telemetry-toolkit/telem-eqns.pl
|
||||
unix2dos telemetry-toolkit/telem-m0xer-3.txt
|
||||
unix2dos telemetry-toolkit/telem-parm.pl
|
||||
unix2dos telemetry-toolkit/telem-unit.pl
|
||||
unix2dos telemetry-toolkit/telem-volts.py
|
||||
unix2dos telemetry-toolkit/telem-volts.conf
|
||||
|
||||
|
||||
# Reminders if pdf files are not up to date.
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ Decodes more than 1000 error-free frames from [WA8LMF TNC Test CD](http://wa8lmf
|
|||
|
||||
- Ideal for building a Raspberry Pi digipeater & IGate.
|
||||
|
||||
- 300, 1200, and 9600 baud operation.
|
||||
- Data rates: 300 AFSK, 1200 AFSK, 2400 QPSK, 4800 8PSK, and 9600/19200/38400 K9NG/G3RUH.
|
||||
|
||||
- Interface with applications by
|
||||
- [AGW](http://uz7.ho.ua/includes/agwpeapi.htm) network protocol
|
||||
|
@ -24,6 +24,8 @@ Decodes more than 1000 error-free frames from [WA8LMF TNC Test CD](http://wa8lmf
|
|||
|
||||
- Decoding of received information for troubleshooting.
|
||||
|
||||
- Conversion from APRS to waypoint sentences in popular formats: $GPWPL, $PGRMW, $PMGNWPL, $PKWDWPL.
|
||||
|
||||
- Logging and conversion to GPX file format.
|
||||
|
||||
- Beaconing for yourself or other nearby entities.
|
||||
|
|
|
@ -51,14 +51,13 @@
|
|||
* Linux: Use the BSD socket interface.
|
||||
*/
|
||||
|
||||
#include "direwolf.h" // Sets _WIN32_WINNT for XP API level needed by ws2tcpip.h
|
||||
|
||||
#if __WIN32__
|
||||
|
||||
#include <winsock2.h>
|
||||
// default is 0x0400
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501 /* Minimum OS version is XP. */
|
||||
#include <ws2tcpip.h>
|
||||
#include <ws2tcpip.h> // _WIN32_WINNT must be set to 0x0501 before including this
|
||||
|
||||
#else
|
||||
//#define __USE_XOPEN2KXSI 1
|
||||
//#define __USE_XOPEN 1
|
||||
|
@ -83,7 +82,6 @@
|
|||
#include <time.h>
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
#include "version.h"
|
||||
|
|
11
aprs_tt.c
11
aprs_tt.c
|
@ -39,6 +39,8 @@
|
|||
|
||||
#define APRS_TT_C 1
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
|
||||
// TODO: clean up terminolgy.
|
||||
// "Message" has a specific meaning in APRS and this is not it.
|
||||
|
@ -56,7 +58,6 @@
|
|||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "version.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "hdlc_rec2.h" /* for process_rec_frame */
|
||||
|
@ -105,7 +106,9 @@ static int parse_aprstt3_call (char *e);
|
|||
static int parse_location (char *e);
|
||||
static int parse_comment (char *e);
|
||||
static int expand_macro (char *e);
|
||||
#ifndef TT_MAIN
|
||||
static void raw_tt_data_to_app (int chan, char *msg);
|
||||
#endif
|
||||
static int find_ttloc_match (char *e, char *xstr, char *ystr, char *zstr, char *bstr, char *dstr, size_t valstrsize);
|
||||
|
||||
#if TT_MAIN
|
||||
|
@ -378,6 +381,7 @@ void aprs_tt_sequence (int chan, char *msg)
|
|||
#endif
|
||||
|
||||
#if TT_MAIN
|
||||
(void)err; // suppress variable set but not used warning.
|
||||
check_result (); // for unit testing.
|
||||
#else
|
||||
|
||||
|
@ -1658,6 +1662,7 @@ static int parse_comment (char *e)
|
|||
*
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
#ifndef TT_MAIN
|
||||
|
||||
static void raw_tt_data_to_app (int chan, char *msg)
|
||||
{
|
||||
|
@ -1668,9 +1673,6 @@ static void raw_tt_data_to_app (int chan, char *msg)
|
|||
char src[10], dest[10];
|
||||
char raw_tt_msg[256];
|
||||
packet_t pp;
|
||||
char *c, *s;
|
||||
int i;
|
||||
int err;
|
||||
alevel_t alevel;
|
||||
|
||||
|
||||
|
@ -1716,6 +1718,7 @@ static void raw_tt_data_to_app (int chan, char *msg)
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
|
|
30
atest.c
30
atest.c
|
@ -59,6 +59,7 @@
|
|||
|
||||
// #define X 1
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
@ -79,6 +80,7 @@
|
|||
#include "hdlc_rec2.h"
|
||||
#include "dlq.h"
|
||||
#include "ptt.h"
|
||||
#include "dtime_now.h"
|
||||
|
||||
|
||||
|
||||
|
@ -178,7 +180,10 @@ int main (int argc, char *argv[])
|
|||
int err;
|
||||
int c;
|
||||
int channel;
|
||||
time_t start_time;
|
||||
|
||||
double start_time; // Time when we started so we can measure elapsed time.
|
||||
double duration; // Length of the audio file in seconds.
|
||||
double elapsed; // Time it took us to process it.
|
||||
|
||||
|
||||
#if defined(EXPERIMENT_G) || defined(EXPERIMENT_H)
|
||||
|
@ -430,8 +435,7 @@ int main (int argc, char *argv[])
|
|||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
start_time = time(NULL);
|
||||
|
||||
start_time = dtime_now();
|
||||
|
||||
/*
|
||||
* Read the file header.
|
||||
|
@ -501,13 +505,17 @@ int main (int argc, char *argv[])
|
|||
if (format.nchannels == 2) my_audio_config.achan[1].valid = 1;
|
||||
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf ("%d samples per second\n", my_audio_config.adev[0].samples_per_sec);
|
||||
dw_printf ("%d bits per sample\n", my_audio_config.adev[0].bits_per_sample);
|
||||
dw_printf ("%d audio channels\n", my_audio_config.adev[0].num_channels);
|
||||
dw_printf ("%d audio bytes in file\n", (int)(wav_data.datasize));
|
||||
dw_printf ("%d samples per second. %d bits per sample. %d audio channels.\n",
|
||||
my_audio_config.adev[0].samples_per_sec,
|
||||
my_audio_config.adev[0].bits_per_sample,
|
||||
my_audio_config.adev[0].num_channels);
|
||||
duration = (double) wav_data.datasize /
|
||||
((my_audio_config.adev[0].bits_per_sample / 8) * my_audio_config.adev[0].num_channels * my_audio_config.adev[0].samples_per_sec);
|
||||
dw_printf ("%d audio bytes in file. Duration = %.1f seconds.\n",
|
||||
(int)(wav_data.datasize),
|
||||
duration);
|
||||
dw_printf ("Fix Bits level = %d\n", my_audio_config.achan[0].fix_bits);
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the AFSK demodulator and HDLC decoder.
|
||||
*/
|
||||
|
@ -563,7 +571,11 @@ int main (int argc, char *argv[])
|
|||
dw_printf ("%d\n", count[j]);
|
||||
}
|
||||
#endif
|
||||
dw_printf ("%d packets decoded in %d seconds.\n", packets_decoded, (int)(time(NULL) - start_time));
|
||||
|
||||
|
||||
elapsed = dtime_now() - start_time;
|
||||
|
||||
dw_printf ("%d packets decoded in %.3f seconds. %.1f x realtime\n", packets_decoded, elapsed, duration/elapsed);
|
||||
|
||||
if (error_if_less_than != -1 && packets_decoded < error_if_less_than) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
|
|
2
audio.c
2
audio.c
|
@ -60,6 +60,7 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
@ -88,7 +89,6 @@
|
|||
#endif
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "audio.h"
|
||||
#include "audio_stats.h"
|
||||
#include "textcolor.h"
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
|
||||
#if defined(USE_PORTAUDIO)
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -54,7 +56,6 @@
|
|||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "audio.h"
|
||||
#include "audio_stats.h"
|
||||
#include "textcolor.h"
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
*---------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -57,8 +60,9 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "audio_stats.h"
|
||||
#include "textcolor.h"
|
||||
#include "dtime_now.h"
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
*---------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "direwolf.h" // Sets _WIN32_WINNT for XP API level needed by ws2tcpip.h
|
||||
// Also includes windows.h.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -48,7 +52,6 @@
|
|||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#ifndef WAVE_FORMAT_96M16
|
||||
|
@ -57,11 +60,9 @@
|
|||
#endif
|
||||
|
||||
#include <winsock2.h>
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#include <ws2tcpip.h>
|
||||
#include <ws2tcpip.h> // _WIN32_WINNT must be set to 0x0501 before including this
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "audio.h"
|
||||
#include "audio_stats.h"
|
||||
#include "textcolor.h"
|
||||
|
|
|
@ -146,6 +146,7 @@
|
|||
|
||||
#define AX25_PAD_C /* this will affect behavior of ax25_pad.h */
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -163,7 +164,7 @@
|
|||
char *strtok_r(char *str, const char *delim, char **saveptr);
|
||||
#endif
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
#include "fcs_calc.h"
|
||||
|
|
|
@ -228,7 +228,7 @@ static inline int ax25_get_info_offset (packet_t this_p)
|
|||
return (ax25_get_control_offset (this_p) + ax25_get_num_control(this_p) + ax25_get_num_pid(this_p));
|
||||
}
|
||||
|
||||
static int ax25_get_num_info (packet_t this_p)
|
||||
static inline int ax25_get_num_info (packet_t this_p)
|
||||
{
|
||||
int len;
|
||||
|
||||
|
|
|
@ -136,6 +136,8 @@
|
|||
#define AX25_PAD_C /* this will affect behavior of ax25_pad.h */
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
@ -143,9 +145,7 @@
|
|||
#include <ctype.h>
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "textcolor.h"
|
||||
|
||||
#include "ax25_pad.h"
|
||||
#include "ax25_pad2.h"
|
||||
|
||||
|
|
49
beacon.c
49
beacon.c
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||
//
|
||||
// Copyright (C) 2011, 2013, 2014, 2015 John Langner, WB2OSZ
|
||||
// Copyright (C) 2011, 2013, 2014, 2015, 2016 John Langner, WB2OSZ
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
|
@ -30,6 +30,8 @@
|
|||
|
||||
//#define DEBUG 1
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
@ -40,7 +42,6 @@
|
|||
#include <time.h>
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
#include "audio.h"
|
||||
|
@ -55,6 +56,7 @@
|
|||
#include "log.h"
|
||||
#include "dlq.h"
|
||||
#include "aprs_tt.h" // for dw_run_cmd - should relocate someday.
|
||||
#include "mheard.h"
|
||||
|
||||
|
||||
#if __WIN32__
|
||||
|
@ -83,6 +85,7 @@ struct tm *localtime_r(time_t *clock, struct tm *res)
|
|||
|
||||
static struct audio_s *g_modem_config_p;
|
||||
static struct misc_config_s *g_misc_config_p;
|
||||
static struct igate_config_s *g_igate_config_p;
|
||||
|
||||
|
||||
#if __WIN32__
|
||||
|
@ -118,6 +121,10 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo);
|
|||
* Used only to find valid channels.
|
||||
*
|
||||
* pconfig - misc. configuration from config file.
|
||||
* Beacon stuff ended up here.
|
||||
*
|
||||
* pigate - IGate configuration.
|
||||
* Need this for calculating IGate statistics.
|
||||
*
|
||||
*
|
||||
* Outputs: Remember required information for future use.
|
||||
|
@ -131,7 +138,7 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo);
|
|||
|
||||
|
||||
|
||||
void beacon_init (struct audio_s *pmodem, struct misc_config_s *pconfig)
|
||||
void beacon_init (struct audio_s *pmodem, struct misc_config_s *pconfig, struct igate_config_s *pigate)
|
||||
{
|
||||
time_t now;
|
||||
int j;
|
||||
|
@ -156,6 +163,7 @@ void beacon_init (struct audio_s *pmodem, struct misc_config_s *pconfig)
|
|||
*/
|
||||
g_modem_config_p = pmodem;
|
||||
g_misc_config_p = pconfig;
|
||||
g_igate_config_p = pigate;
|
||||
|
||||
/*
|
||||
* Precompute the packet contents so any errors are
|
||||
|
@ -228,6 +236,22 @@ void beacon_init (struct audio_s *pmodem, struct misc_config_s *pconfig)
|
|||
}
|
||||
break;
|
||||
|
||||
case BEACON_IGATE:
|
||||
|
||||
/* Doesn't make sense if IGate is not configured. */
|
||||
|
||||
if (strlen(g_igate_config_p->t2_server_name) == 0 ||
|
||||
strlen(g_igate_config_p->t2_login) == 0 ||
|
||||
strlen(g_igate_config_p->t2_passcode) == 0) {
|
||||
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Config file, line %d: Doesn't make sense to use IBEACON without IGate Configured.\n", g_misc_config_p->beacon[j].lineno);
|
||||
dw_printf ("IBEACON has been disabled.\n");
|
||||
g_misc_config_p->beacon[j].btype = BEACON_IGNORE;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case BEACON_IGNORE:
|
||||
break;
|
||||
}
|
||||
|
@ -870,6 +894,25 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
|
|||
}
|
||||
break;
|
||||
|
||||
case BEACON_IGATE:
|
||||
|
||||
{
|
||||
int last_minutes = 30;
|
||||
char stuff[256];
|
||||
|
||||
snprintf (stuff, sizeof(stuff), "<IGATE,MSG_CNT=%d,PKT_CNT=%d,DIR_CNT=%d,LOC_CNT=%d,RF_CNT=%d,UPL_CNT=%d,DNL_CNT=%d",
|
||||
igate_get_msg_cnt(),
|
||||
igate_get_pkt_cnt(),
|
||||
mheard_count(0,last_minutes),
|
||||
mheard_count(g_igate_config_p->max_digi_hops,last_minutes),
|
||||
mheard_count(8,last_minutes),
|
||||
igate_get_upl_cnt(),
|
||||
igate_get_dnl_cnt());
|
||||
|
||||
strlcat (beacon_text, stuff, sizeof(beacon_text));
|
||||
}
|
||||
break;
|
||||
|
||||
case BEACON_IGNORE:
|
||||
default:
|
||||
break;
|
||||
|
|
2
beacon.h
2
beacon.h
|
@ -1,6 +1,6 @@
|
|||
|
||||
/* beacon.h */
|
||||
|
||||
void beacon_init (struct audio_s *pmodem, struct misc_config_s *pconfig);
|
||||
void beacon_init (struct audio_s *pmodem, struct misc_config_s *pconfig, struct igate_config_s *pigate);
|
||||
|
||||
void beacon_tracker_set_debug (int level);
|
||||
|
|
158
config.c
158
config.c
|
@ -17,7 +17,7 @@
|
|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#define CONFIG_C 1
|
||||
#define CONFIG_C 1 // influences behavior of aprs_tt.h
|
||||
|
||||
|
||||
// #define DEBUG 1
|
||||
|
@ -34,6 +34,8 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -451,6 +453,110 @@ static int parse_interval (char *str, int line)
|
|||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* Name: check_via_path
|
||||
*
|
||||
* Purpose: Check for valid path in beacons, IGate, and APRStt configuration.
|
||||
*
|
||||
* Inputs: via_path - Zero or more comma separated stations.
|
||||
*
|
||||
* Returns: Maximum number of digipeater hops or -1 for error.
|
||||
*
|
||||
* Description: Beacons and IGate can use via paths such as:
|
||||
*
|
||||
* WIDE1-1,MA3-3
|
||||
* N2GH,RARA-7
|
||||
*
|
||||
* Each part could be a specific station, an alias, or a path
|
||||
* from the "New n-N Paradigm."
|
||||
* In the first example above, the maximum number of digipeater
|
||||
* hops would be 4. In the second example, 2.
|
||||
*
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
// Put something like this in the config file as a quick test.
|
||||
// Not worth adding to "make check" regression tests.
|
||||
//
|
||||
// IBEACON via=
|
||||
// IBEACON via=W2UB
|
||||
// IBEACON via=W2UB-7
|
||||
// IBEACON via=WIDE1-1,WIDE2-2,WIDE3-3
|
||||
// IBEACON via=Lower
|
||||
// IBEACON via=T00LONG
|
||||
// IBEACON via=W2UB-16
|
||||
// IBEACON via=D1,D2,D3,D4,D5,D6,D7,D8
|
||||
// IBEACON via=D1,D2,D3,D4,D5,D6,D7,D8,D9
|
||||
//
|
||||
// Define below and visually check results.
|
||||
|
||||
//#define DEBUG8 1
|
||||
|
||||
|
||||
static int check_via_path (char *via_path)
|
||||
{
|
||||
char stemp[AX25_MAX_REPEATERS * (AX25_MAX_ADDR_LEN + 1)];
|
||||
int num_digi = 0;
|
||||
int max_digi_hops = 0;
|
||||
char *r;
|
||||
char *a;
|
||||
|
||||
#if DEBUG8
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("check_via_path %s\n", via_path);
|
||||
#endif
|
||||
if (strlen(via_path) == 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
strlcpy (stemp, via_path, sizeof(stemp));
|
||||
|
||||
r = stemp;
|
||||
while (( a = strsep(&r,",")) != NULL) {
|
||||
int strict = 1;
|
||||
int ok;
|
||||
char addr[AX25_MAX_ADDR_LEN];
|
||||
int ssid;
|
||||
int heard;
|
||||
|
||||
num_digi++;
|
||||
ok = ax25_parse_addr (AX25_REPEATER_1 - 1 + num_digi, a, strict, addr, &ssid, &heard);
|
||||
if ( ! ok) {
|
||||
#if DEBUG8
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("check_via_path bad address\n");
|
||||
#endif
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Based on assumption that a callsign can't end with a digit. */
|
||||
/* For something of the form xxx9-9, we take the ssid as max hop count. */
|
||||
|
||||
if (ssid > 0 && strlen(addr) >= 2 && isdigit(addr[strlen(addr)-1])) {
|
||||
max_digi_hops += ssid;
|
||||
}
|
||||
else {
|
||||
max_digi_hops++;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_digi > AX25_MAX_REPEATERS) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Maximum of 8 digipeaters has been exceeded.\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if DEBUG8
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("check_via_path %d addresses, %d max digi hops\n", num_digi, max_digi_hops);
|
||||
#endif
|
||||
|
||||
return (max_digi_hops);
|
||||
|
||||
} /* end check_via_path */
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
*
|
||||
* Name: split
|
||||
|
@ -3348,8 +3454,13 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
t = split(NULL,0);
|
||||
if (t != NULL) {
|
||||
|
||||
// TODO: Should do some validity checking on the path.
|
||||
strlcpy (p_tt_config->obj_xmit_via, t, sizeof(p_tt_config->obj_xmit_via));
|
||||
if (check_via_path(t) >= 0) {
|
||||
strlcpy (p_tt_config->obj_xmit_via, t, sizeof(p_tt_config->obj_xmit_via));
|
||||
}
|
||||
else {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Config file, line %d: invalid via path.\n", line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3600,6 +3711,22 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
|
||||
t = split(NULL,0);
|
||||
if (t != NULL) {
|
||||
|
||||
#if 1 // proper checking
|
||||
|
||||
n = check_via_path(t);
|
||||
if (n >= 0) {
|
||||
p_igate_config->max_digi_hops = n;
|
||||
p_igate_config->tx_via[0] = ',';
|
||||
strlcpy (p_igate_config->tx_via + 1, t, sizeof(p_igate_config->tx_via)-1);
|
||||
}
|
||||
else {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Config file, line %d: invalid via path.\n", line);
|
||||
}
|
||||
|
||||
#else // previously
|
||||
|
||||
char *p;
|
||||
p_igate_config->tx_via[0] = ',';
|
||||
strlcpy (p_igate_config->tx_via + 1, t, sizeof(p_igate_config->tx_via)-1);
|
||||
|
@ -3608,6 +3735,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
*p = toupper(*p); /* silently force upper case. */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3841,7 +3969,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
}
|
||||
|
||||
/*
|
||||
* WAYPOINT - Generate WPT NMEA sentences for display on map.
|
||||
* WAYPOINT - Generate WPL NMEA sentences for display on map.
|
||||
*
|
||||
* WAYPOINT serial-device [ formats ]
|
||||
*
|
||||
|
@ -3924,6 +4052,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
* OBEACON keyword=value ...
|
||||
* TBEACON keyword=value ...
|
||||
* CBEACON keyword=value ...
|
||||
* IBEACON keyword=value ...
|
||||
*
|
||||
* New style with keywords for options.
|
||||
*/
|
||||
|
@ -3931,7 +4060,8 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
else if (strcasecmp(t, "PBEACON") == 0 ||
|
||||
strcasecmp(t, "OBEACON") == 0 ||
|
||||
strcasecmp(t, "TBEACON") == 0 ||
|
||||
strcasecmp(t, "CBEACON") == 0) {
|
||||
strcasecmp(t, "CBEACON") == 0 ||
|
||||
strcasecmp(t, "IBEACON") == 0) {
|
||||
|
||||
if (p_misc_config->num_beacons < MAX_BEACONS) {
|
||||
|
||||
|
@ -3945,6 +4075,9 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
else if (strcasecmp(t, "TBEACON") == 0) {
|
||||
p_misc_config->beacon[p_misc_config->num_beacons].btype = BEACON_TRACKER;
|
||||
}
|
||||
else if (strcasecmp(t, "IBEACON") == 0) {
|
||||
p_misc_config->beacon[p_misc_config->num_beacons].btype = BEACON_IGATE;
|
||||
}
|
||||
else {
|
||||
p_misc_config->beacon[p_misc_config->num_beacons].btype = BEACON_CUSTOM;
|
||||
}
|
||||
|
@ -4218,12 +4351,27 @@ static int beacon_options(char *cmd, struct beacon_s *b, int line, struct audio_
|
|||
}
|
||||
}
|
||||
else if (strcasecmp(keyword, "VIA") == 0) {
|
||||
|
||||
#if 1 // proper checking
|
||||
|
||||
if (check_via_path(value) >= 0) {
|
||||
b->via = strdup(value);
|
||||
}
|
||||
else {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Config file, line %d: invalid via path.\n", line);
|
||||
}
|
||||
|
||||
|
||||
#else // previously
|
||||
|
||||
b->via = strdup(value);
|
||||
for (p = b->via; *p != '\0'; p++) {
|
||||
if (islower(*p)) {
|
||||
*p = toupper(*p); /* silently force upper case. */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (strcasecmp(keyword, "INFO") == 0) {
|
||||
b->custom_info = strdup(value);
|
||||
|
|
2
config.h
2
config.h
|
@ -23,7 +23,7 @@
|
|||
* This wasn't thought out. It just happened.
|
||||
*/
|
||||
|
||||
enum beacon_type_e { BEACON_IGNORE, BEACON_POSITION, BEACON_OBJECT, BEACON_TRACKER, BEACON_CUSTOM };
|
||||
enum beacon_type_e { BEACON_IGNORE, BEACON_POSITION, BEACON_OBJECT, BEACON_TRACKER, BEACON_CUSTOM, BEACON_IGATE };
|
||||
|
||||
enum sendto_type_e { SENDTO_XMIT, SENDTO_IGATE, SENDTO_RECV };
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
*
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
@ -48,7 +50,6 @@
|
|||
#endif
|
||||
#include "regex.h"
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
#include "symbols.h"
|
||||
|
|
1
dedupe.c
1
dedupe.c
|
@ -96,6 +96,7 @@
|
|||
|
||||
#define DEDUPE_C
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
100
demod.c
100
demod.c
|
@ -31,6 +31,7 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -41,7 +42,6 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "audio.h"
|
||||
#include "demod.h"
|
||||
#include "tune.h"
|
||||
|
@ -61,13 +61,16 @@
|
|||
static struct audio_s *save_audio_config_p;
|
||||
|
||||
|
||||
// TODO: temp experiment.
|
||||
|
||||
static int upsample = 2; // temp experiment.
|
||||
static int zerostuff = 1; // temp experiment.
|
||||
|
||||
// Current state of all the decoders.
|
||||
|
||||
static struct demodulator_state_s demodulator_state[MAX_CHANS][MAX_SUBCHANS];
|
||||
|
||||
|
||||
#define UPSAMPLE 2
|
||||
|
||||
static int sample_sum[MAX_CHANS][MAX_SUBCHANS];
|
||||
static int sample_count[MAX_CHANS][MAX_SUBCHANS];
|
||||
|
||||
|
@ -641,11 +644,20 @@ int demod_init (struct audio_s *pa)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef TUNE_UPSAMPLE
|
||||
upsample = TUNE_UPSAMPLE;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TUNE_ZEROSTUFF
|
||||
zerostuff = TUNE_ZEROSTUFF;
|
||||
#endif
|
||||
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("Channel %d: %d baud, K9NG/G3RUH, %s, %d sample rate x %d",
|
||||
chan, save_audio_config_p->achan[chan].baud,
|
||||
save_audio_config_p->achan[chan].profiles,
|
||||
save_audio_config_p->adev[ACHAN2ADEV(chan)].samples_per_sec, UPSAMPLE);
|
||||
save_audio_config_p->adev[ACHAN2ADEV(chan)].samples_per_sec, upsample);
|
||||
if (save_audio_config_p->achan[chan].dtmf_decode != DTMF_DECODE_OFF)
|
||||
dw_printf (", DTMF decoder enabled");
|
||||
dw_printf (".\n");
|
||||
|
@ -693,7 +705,7 @@ int demod_init (struct audio_s *pa)
|
|||
dw_printf ("This is a suitable ratio for good performance.\n");
|
||||
}
|
||||
|
||||
demod_9600_init (UPSAMPLE * save_audio_config_p->adev[ACHAN2ADEV(chan)].samples_per_sec, save_audio_config_p->achan[chan].baud, D);
|
||||
demod_9600_init (upsample * save_audio_config_p->adev[ACHAN2ADEV(chan)].samples_per_sec, save_audio_config_p->achan[chan].baud, D);
|
||||
|
||||
if (strchr(save_audio_config_p->achan[chan].profiles, '+') != NULL) {
|
||||
|
||||
|
@ -920,50 +932,50 @@ void demod_process_sample (int chan, int subchan, int sam)
|
|||
case MODEM_SCRAMBLE:
|
||||
default:
|
||||
|
||||
#define ZEROSTUFF 1
|
||||
if (zerostuff) {
|
||||
/* Literature says this is better if followed */
|
||||
/* by appropriate low pass filter. */
|
||||
/* So far, both are same in tests with different */
|
||||
/* optimal low pass filter parameters. */
|
||||
|
||||
|
||||
#if ZEROSTUFF
|
||||
/* Literature says this is better if followed */
|
||||
/* by appropriate low pass filter. */
|
||||
/* So far, both are same in tests with different */
|
||||
/* optimal low pass filter parameters. */
|
||||
|
||||
for (k=1; k<UPSAMPLE; k++) {
|
||||
demod_9600_process_sample (chan, 0, D);
|
||||
for (k=1; k<upsample; k++) {
|
||||
demod_9600_process_sample (chan, 0, D);
|
||||
}
|
||||
demod_9600_process_sample (chan, sam * upsample, D);
|
||||
}
|
||||
demod_9600_process_sample (chan, sam*UPSAMPLE, D);
|
||||
#else
|
||||
/* Linear interpolation. */
|
||||
static int prev_sam;
|
||||
switch (UPSAMPLE) {
|
||||
case 1:
|
||||
demod_9600_process_sample (chan, sam);
|
||||
else {
|
||||
|
||||
break;
|
||||
case 2:
|
||||
demod_9600_process_sample (chan, (prev_sam + sam) / 2, D);
|
||||
demod_9600_process_sample (chan, sam, D);
|
||||
break;
|
||||
case 3:
|
||||
demod_9600_process_sample (chan, (2 * prev_sam + sam) / 3, D);
|
||||
demod_9600_process_sample (chan, (prev_sam + 2 * sam) / 3, D);
|
||||
demod_9600_process_sample (chan, sam, D);
|
||||
break;
|
||||
case 4:
|
||||
demod_9600_process_sample (chan, (3 * prev_sam + sam) / 4, D);
|
||||
demod_9600_process_sample (chan, (prev_sam + sam) / 2, D);
|
||||
demod_9600_process_sample (chan, (prev_sam + 3 * sam) / 4, D);
|
||||
demod_9600_process_sample (chan, sam, D);
|
||||
break;
|
||||
default:
|
||||
assert (0);
|
||||
break;
|
||||
/* Linear interpolation. */
|
||||
static int prev_sam;
|
||||
|
||||
switch (upsample) {
|
||||
case 1:
|
||||
demod_9600_process_sample (chan, sam, D);
|
||||
break;
|
||||
case 2:
|
||||
demod_9600_process_sample (chan, (prev_sam + sam) / 2, D);
|
||||
demod_9600_process_sample (chan, sam, D);
|
||||
break;
|
||||
case 3:
|
||||
demod_9600_process_sample (chan, (2 * prev_sam + sam) / 3, D);
|
||||
demod_9600_process_sample (chan, (prev_sam + 2 * sam) / 3, D);
|
||||
demod_9600_process_sample (chan, sam, D);
|
||||
break;
|
||||
case 4:
|
||||
demod_9600_process_sample (chan, (3 * prev_sam + sam) / 4, D);
|
||||
demod_9600_process_sample (chan, (prev_sam + sam) / 2, D);
|
||||
demod_9600_process_sample (chan, (prev_sam + 3 * sam) / 4, D);
|
||||
demod_9600_process_sample (chan, sam, D);
|
||||
break;
|
||||
default:
|
||||
assert (0);
|
||||
break;
|
||||
}
|
||||
prev_sam = sam;
|
||||
}
|
||||
prev_sam = sam;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
} /* switch modem_type */
|
||||
return;
|
||||
|
||||
} /* end demod_process_sample */
|
||||
|
|
274
demod_9600.c
274
demod_9600.c
|
@ -18,7 +18,7 @@
|
|||
//
|
||||
|
||||
|
||||
// #define DEBUG5 1 /* capture 9600 output to log files */
|
||||
//#define DEBUG4 1 /* capture 9600 output to log files */
|
||||
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
|
@ -33,6 +33,8 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
@ -42,7 +44,6 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "tune.h"
|
||||
#include "fsk_demod_state.h"
|
||||
#include "hdlc_rec.h"
|
||||
|
@ -72,25 +73,10 @@ static inline float convolve (const float *__restrict__ data, const float *__res
|
|||
float sum = 0.0f;
|
||||
int j;
|
||||
|
||||
#if 0
|
||||
// As suggested here, http://locklessinc.com/articles/vectorize/
|
||||
// Unfortunately, older compilers don't recognize it.
|
||||
|
||||
// Get more information by using -ftree-vectorizer-verbose=5
|
||||
|
||||
float *d = __builtin_assume_aligned(data, 16);
|
||||
float *f = __builtin_assume_aligned(filter, 16);
|
||||
|
||||
#pragma GCC ivdep
|
||||
for (j=0; j<filter_size; j++) {
|
||||
sum += f[j] * d[j];
|
||||
}
|
||||
#else
|
||||
#pragma GCC ivdep // ignored until gcc 4.9
|
||||
//#pragma GCC ivdep // ignored until gcc 4.9
|
||||
for (j=0; j<filter_size; j++) {
|
||||
sum += filter[j] * data[j];
|
||||
}
|
||||
#endif
|
||||
return (sum);
|
||||
}
|
||||
|
||||
|
@ -125,11 +111,11 @@ static inline float agc (float in, float fast_attack, float slow_decay, float *p
|
|||
*
|
||||
* Name: demod_9600_init
|
||||
*
|
||||
* Purpose: Initialize the 9600 baud demodulator.
|
||||
* Purpose: Initialize the 9600 (or higher) baud demodulator.
|
||||
*
|
||||
* Inputs: samples_per_sec - Number of samples per second.
|
||||
* Might be upsampled in hopes of
|
||||
* reducing the PLL jitter.
|
||||
* Might be upsampled in hopes of
|
||||
* reducing the PLL jitter.
|
||||
*
|
||||
* baud - Data rate in bits per second.
|
||||
*
|
||||
|
@ -147,22 +133,34 @@ void demod_9600_init (int samples_per_sec, int baud, struct demodulator_state_s
|
|||
memset (D, 0, sizeof(struct demodulator_state_s));
|
||||
D->num_slicers = 1;
|
||||
|
||||
//dw_printf ("demod_9600_init(rate=%d, baud=%d, D ptr)\n", samples_per_sec, baud);
|
||||
// Multiple profiles in future?
|
||||
|
||||
// switch (profile) {
|
||||
|
||||
// case 'J': // upsample x2 with filtering.
|
||||
// case 'K': // upsample x3 with filtering.
|
||||
// case 'L': // upsample x4 with filtering.
|
||||
|
||||
D->lp_filter_len_bits = 76 * 9600.0 / (44100.0 * 2.0);
|
||||
|
||||
// Works best with odd number in some tests. Even is better in others.
|
||||
//D->lp_filter_size = ((int) (0.5 * ( D->lp_filter_len_bits * (float)samples_per_sec / (float)baud ))) * 2 + 1;
|
||||
D->lp_filter_size = (int) (( D->lp_filter_len_bits * (float)samples_per_sec / baud) + 0.5);
|
||||
|
||||
D->lp_window = BP_WINDOW_HAMMING;
|
||||
D->lpf_baud = 0.62;
|
||||
|
||||
D->agc_fast_attack = 0.080;
|
||||
D->agc_slow_decay = 0.00012;
|
||||
|
||||
D->pll_locked_inertia = 0.89;
|
||||
D->pll_searching_inertia = 0.67;
|
||||
// break;
|
||||
// }
|
||||
|
||||
D->pll_step_per_sample =
|
||||
(int) round(TICKS_PER_PLL_CYCLE * (double) baud / (double)samples_per_sec);
|
||||
|
||||
D->lp_filter_len_bits = 72 * 9600.0 / (44100.0 * 2.0);
|
||||
D->lp_filter_size = (int) (( D->lp_filter_len_bits * (float)samples_per_sec / baud) + 0.5);
|
||||
D->lp_window = BP_WINDOW_HAMMING;
|
||||
D->lpf_baud = 0.59;
|
||||
|
||||
D->agc_fast_attack = 0.080;
|
||||
D->agc_slow_decay = 0.00012;
|
||||
|
||||
D->pll_locked_inertia = 0.88;
|
||||
D->pll_searching_inertia = 0.67;
|
||||
|
||||
|
||||
#ifdef TUNE_LP_WINDOW
|
||||
D->lp_window = TUNE_LP_WINDOW;
|
||||
|
@ -184,8 +182,11 @@ void demod_9600_init (int samples_per_sec, int baud, struct demodulator_state_s
|
|||
D->agc_slow_decay = TUNE_AGC_SLOW;
|
||||
#endif
|
||||
|
||||
#if defined(TUNE_PLL_LOCKED) && defined(TUNE_PLL_SEARCHING)
|
||||
#if defined(TUNE_PLL_LOCKED)
|
||||
D->pll_locked_inertia = TUNE_PLL_LOCKED;
|
||||
#endif
|
||||
|
||||
#if defined(TUNE_PLL_SEARCHING)
|
||||
D->pll_searching_inertia = TUNE_PLL_SEARCHING;
|
||||
#endif
|
||||
|
||||
|
@ -260,23 +261,22 @@ void demod_9600_init (int samples_per_sec, int baud, struct demodulator_state_s
|
|||
*
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
static void inline nudge_pll (int chan, int subchan, int slice, int demod_data, struct demodulator_state_s *D);
|
||||
static void inline nudge_pll (int chan, int subchan, int slice, float demod_out, struct demodulator_state_s *D);
|
||||
|
||||
__attribute__((hot))
|
||||
void demod_9600_process_sample (int chan, int sam, struct demodulator_state_s *D)
|
||||
{
|
||||
|
||||
float fsam;
|
||||
//float abs_fsam;
|
||||
float amp;
|
||||
float demod_out;
|
||||
|
||||
#if DEBUG5
|
||||
#if DEBUG4
|
||||
static FILE *demod_log_fp = NULL;
|
||||
static int seq = 0; /* for log file name */
|
||||
static int log_file_seq = 0; /* Part of log file name */
|
||||
#endif
|
||||
|
||||
//int j;
|
||||
|
||||
int subchan = 0;
|
||||
int demod_data; /* Still scrambled. */
|
||||
|
||||
|
@ -306,6 +306,12 @@ void demod_9600_process_sample (int chan, int sam, struct demodulator_state_s *D
|
|||
|
||||
fsam = sam / 16384.0;
|
||||
|
||||
#if defined(TUNE_ZEROSTUFF) && TUNE_ZEROSTUFF == 0
|
||||
// experiment - no filtering.
|
||||
|
||||
amp = fsam;
|
||||
|
||||
#else
|
||||
push_sample (fsam, D->raw_cb, D->lp_filter_size);
|
||||
|
||||
/*
|
||||
|
@ -313,7 +319,7 @@ void demod_9600_process_sample (int chan, int sam, struct demodulator_state_s *D
|
|||
*/
|
||||
|
||||
amp = convolve (D->raw_cb, D->lp_filter, D->lp_filter_size);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Version 1.2: Capture the post-filtering amplitude for display.
|
||||
|
@ -324,6 +330,8 @@ void demod_9600_process_sample (int chan, int sam, struct demodulator_state_s *D
|
|||
* Here we keep + and - peaks because there could be a DC bias.
|
||||
*/
|
||||
|
||||
// TODO: probably no need for this. Just use D->m_peak, D->m_valley
|
||||
|
||||
if (amp >= D->alevel_mark_peak) {
|
||||
D->alevel_mark_peak = amp * D->quick_attack + D->alevel_mark_peak * (1. - D->quick_attack);
|
||||
}
|
||||
|
@ -349,28 +357,10 @@ void demod_9600_process_sample (int chan, int sam, struct demodulator_state_s *D
|
|||
|
||||
demod_out = agc (amp, D->agc_fast_attack, D->agc_slow_decay, &(D->m_peak), &(D->m_valley));
|
||||
|
||||
|
||||
// TODO: There is potential for multiple decoders with one filter.
|
||||
|
||||
//dw_printf ("peak=%.2f valley=%.2f amp=%.2f norm=%.2f\n", D->m_peak, D->m_valley, amp, norm);
|
||||
|
||||
/* Throw in a little Hysteresis??? */
|
||||
/* (Not to be confused with Hysteria.) */
|
||||
/* Doesn't seem to have any value. */
|
||||
/* Using a level of .02 makes things worse. */
|
||||
/* Might want to experiment with this again someday. */
|
||||
|
||||
|
||||
// if (demod_out > 0.03) {
|
||||
// demod_data = 1;
|
||||
// }
|
||||
// else if (demod_out < -0.03) {
|
||||
// demod_data = 0;
|
||||
// }
|
||||
// else {
|
||||
// demod_data = D->slicer[subchan].prev_demod_data;
|
||||
// }
|
||||
|
||||
if (D->num_slicers <= 1) {
|
||||
|
||||
/* Normal case of one demodulator to one HDLC decoder. */
|
||||
|
@ -378,7 +368,7 @@ void demod_9600_process_sample (int chan, int sam, struct demodulator_state_s *D
|
|||
/* AGC should generally keep this around -1 to +1 range. */
|
||||
|
||||
demod_data = demod_out > 0;
|
||||
nudge_pll (chan, subchan, 0, demod_data, D);
|
||||
nudge_pll (chan, subchan, 0, demod_out, D);
|
||||
}
|
||||
else {
|
||||
int slice;
|
||||
|
@ -386,76 +376,147 @@ void demod_9600_process_sample (int chan, int sam, struct demodulator_state_s *D
|
|||
/* Multiple slicers each feeding its own HDLC decoder. */
|
||||
|
||||
for (slice=0; slice<D->num_slicers; slice++) {
|
||||
demod_data = demod_out > slice_point[slice];
|
||||
nudge_pll (chan, subchan, slice, demod_data, D);
|
||||
demod_data = demod_out - slice_point[slice] > 0;
|
||||
nudge_pll (chan, subchan, slice, demod_out - slice_point[slice], D);
|
||||
}
|
||||
}
|
||||
|
||||
// demod_data is used only for debug out.
|
||||
// suppress compiler warning about it not being used.
|
||||
(void) demod_data;
|
||||
|
||||
#if DEBUG4
|
||||
|
||||
if (chan == 0) {
|
||||
|
||||
if (1) {
|
||||
//if (hdlc_rec_gathering (chan, subchan, slice)) {
|
||||
char fname[30];
|
||||
int slice = 0;
|
||||
|
||||
if (demod_log_fp == NULL) {
|
||||
log_file_seq++;
|
||||
snprintf (fname, sizeof(fname), "demod/%04d.csv", log_file_seq);
|
||||
//if (log_file_seq == 1) mkdir ("demod", 0777);
|
||||
if (log_file_seq == 1) mkdir ("demod");
|
||||
|
||||
demod_log_fp = fopen (fname, "w");
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("Starting demodulator log file %s\n", fname);
|
||||
fprintf (demod_log_fp, "Audio, Filtered, Max, Min, Normalized, Sliced, Clock\n");
|
||||
}
|
||||
|
||||
fprintf (demod_log_fp, "%.3f, %.3f, %.3f, %.3f, %.3f, %d, %.2f\n",
|
||||
fsam + 6,
|
||||
amp + 4,
|
||||
D->m_peak + 4,
|
||||
D->m_valley + 4,
|
||||
demod_out + 2,
|
||||
demod_data + 2,
|
||||
(D->slicer[slice].data_clock_pll & 0x80000000) ? .5 : .0);
|
||||
|
||||
fflush (demod_log_fp);
|
||||
}
|
||||
else {
|
||||
if (demod_log_fp != NULL) {
|
||||
fclose (demod_log_fp);
|
||||
demod_log_fp = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* end demod_9600_process_sample */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
*
|
||||
* Name: nudge_pll
|
||||
*
|
||||
* Purpose: Update the PLL state for each audio sample.
|
||||
*
|
||||
* (2) Descramble it.
|
||||
* (2) Recover clock and data.
|
||||
*
|
||||
* Inputs: chan - Audio channel. 0 for left, 1 for right.
|
||||
*
|
||||
* subchan - Which demodulator. We could have several running in parallel.
|
||||
*
|
||||
* slice - Determines which Slicing level & HDLC decoder to use.
|
||||
*
|
||||
* demod_out_f - Demodulator output, possibly shifted by slicing level
|
||||
* It will be compared with 0.0 to bit binary value out.
|
||||
*
|
||||
* D - Demodulator state for this channel / subchannel.
|
||||
*
|
||||
* Returns: None
|
||||
*
|
||||
* Descripton: A PLL is used to sample near the centers of the data bits.
|
||||
*
|
||||
* D->data_clock_pll is a SIGNED 32 bit variable.
|
||||
* When it overflows from a large positive value to a negative value, we
|
||||
* sample a data bit from the demodulated signal.
|
||||
*
|
||||
* Ideally, the the demodulated signal transitions should be near
|
||||
* zero we we sample mid way between the transitions.
|
||||
*
|
||||
* Nudge the PLL by removing some small fraction from the value of
|
||||
* data_clock_pll, pushing it closer to zero.
|
||||
*
|
||||
* This adjustment will never change the sign so it won't cause
|
||||
* any erratic data bit sampling.
|
||||
*
|
||||
* If we adjust it too quickly, the clock will have too much jitter.
|
||||
* If we adjust it too slowly, it will take too long to lock on to a new signal.
|
||||
*
|
||||
* I don't think the optimal value will depend on the audio sample rate
|
||||
* because this happens for each transition from the demodulator.
|
||||
*
|
||||
* Version 1.4: Previously, we would always pull the PLL phase toward 0 after
|
||||
* after a zero crossing was detetected. This adds extra jitter,
|
||||
* especially when the ratio of audio sample rate to baud is low.
|
||||
* Now, we interpolate between the two samples to get an estimate
|
||||
* on when the zero crossing happened. The PLL is pulled toward
|
||||
* this point.
|
||||
*
|
||||
* Results??? TBD
|
||||
*
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
__attribute__((hot))
|
||||
static void inline nudge_pll (int chan, int subchan, int slice, int demod_data, struct demodulator_state_s *D)
|
||||
static void inline nudge_pll (int chan, int subchan, int slice, float demod_out_f, struct demodulator_state_s *D)
|
||||
{
|
||||
|
||||
/*
|
||||
* Next, a PLL is used to sample near the centers of the data bits.
|
||||
*
|
||||
* D->data_clock_pll is a SIGNED 32 bit variable.
|
||||
* When it overflows from a large positive value to a negative value, we
|
||||
* sample a data bit from the demodulated signal.
|
||||
*
|
||||
* Ideally, the the demodulated signal transitions should be near
|
||||
* zero we we sample mid way between the transitions.
|
||||
*
|
||||
* Nudge the PLL by removing some small fraction from the value of
|
||||
* data_clock_pll, pushing it closer to zero.
|
||||
*
|
||||
* This adjustment will never change the sign so it won't cause
|
||||
* any erratic data bit sampling.
|
||||
*
|
||||
* If we adjust it too quickly, the clock will have too much jitter.
|
||||
* If we adjust it too slowly, it will take too long to lock on to a new signal.
|
||||
*
|
||||
* I don't think the optimal value will depend on the audio sample rate
|
||||
* because this happens for each transition from the demodulator.
|
||||
*
|
||||
* This was optimized for 1200 baud AFSK. There might be some opportunity
|
||||
* for improvement here.
|
||||
*/
|
||||
|
||||
D->slicer[slice].prev_d_c_pll = D->slicer[slice].data_clock_pll;
|
||||
D->slicer[slice].data_clock_pll += D->pll_step_per_sample;
|
||||
|
||||
if (D->slicer[slice].data_clock_pll < 0 && D->slicer[slice].prev_d_c_pll > 0) {
|
||||
if ( D->slicer[slice].prev_d_c_pll > 1000000000 && D->slicer[slice].data_clock_pll < -1000000000) {
|
||||
|
||||
/* Overflow. */
|
||||
/* Overflow. Was large positive, wrapped around, now large negative. */
|
||||
|
||||
/*
|
||||
* At this point, we need to descramble the data as
|
||||
* in hardware based designs by G3RUH and K9NG.
|
||||
*
|
||||
* Future Idea: allow unscrambled baseband data.
|
||||
*
|
||||
* http://www.amsat.org/amsat/articles/g3ruh/109/fig03.gif
|
||||
*/
|
||||
// Warning: 'descram' set but not used.
|
||||
// It's used in conditional debug code below.
|
||||
// descram =
|
||||
descramble (demod_data, &(D->slicer[slice].lfsr));
|
||||
|
||||
hdlc_rec_bit (chan, subchan, slice, demod_data, 1, D->slicer[slice].lfsr);
|
||||
hdlc_rec_bit (chan, subchan, slice, demod_out_f > 0, 1, D->slicer[slice].lfsr);
|
||||
}
|
||||
|
||||
if (demod_data != D->slicer[slice].prev_demod_data) {
|
||||
/*
|
||||
* Zero crossing?
|
||||
*/
|
||||
if ((D->slicer[slice].prev_demod_out_f < 0 && demod_out_f > 0) ||
|
||||
(D->slicer[slice].prev_demod_out_f > 0 && demod_out_f < 0)) {
|
||||
|
||||
// Note: Test for this demodulator, not overall for channel.
|
||||
|
||||
float target = 0;
|
||||
|
||||
target = D->pll_step_per_sample * demod_out_f / (demod_out_f - D->slicer[slice].prev_demod_out_f);
|
||||
|
||||
if (hdlc_rec_gathering (chan, subchan, slice)) {
|
||||
D->slicer[slice].data_clock_pll = (int)(D->slicer[slice].data_clock_pll * D->pll_locked_inertia);
|
||||
D->slicer[slice].data_clock_pll = (int)(D->slicer[slice].data_clock_pll * D->pll_locked_inertia + target * (1.0f - D->pll_locked_inertia) );
|
||||
}
|
||||
else {
|
||||
D->slicer[slice].data_clock_pll = (int)(D->slicer[slice].data_clock_pll * D->pll_searching_inertia);
|
||||
D->slicer[slice].data_clock_pll = (int)(D->slicer[slice].data_clock_pll * D->pll_searching_inertia + target * (1.0f - D->pll_searching_inertia) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -506,12 +567,9 @@ static void inline nudge_pll (int chan, int subchan, int slice, int demod_data,
|
|||
* Remember demodulator output (pre-descrambling) so we can compare next time
|
||||
* for the DPLL sync.
|
||||
*/
|
||||
D->slicer[slice].prev_demod_data = demod_data;
|
||||
D->slicer[slice].prev_demod_out_f = demod_out_f;
|
||||
|
||||
} /* end nudge_pll */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* end demod_9600.c */
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -50,9 +50,7 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "audio.h"
|
||||
|
||||
#include "tune.h"
|
||||
#include "fsk_demod_state.h"
|
||||
#include "fsk_gen_filter.h"
|
||||
|
@ -105,7 +103,7 @@ static inline float convolve (const float *__restrict__ data, const float *__res
|
|||
int j;
|
||||
|
||||
|
||||
#pragma GCC ivdep // ignored until gcc 4.9
|
||||
//#pragma GCC ivdep // ignored until gcc 4.9
|
||||
for (j=0; j<filter_size; j++) {
|
||||
sum += filter[j] * data[j];
|
||||
}
|
||||
|
|
13
demod_psk.c
13
demod_psk.c
|
@ -94,7 +94,7 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -105,9 +105,8 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "audio.h"
|
||||
|
||||
#include "audio.h"
|
||||
#include "tune.h"
|
||||
#include "fsk_demod_state.h"
|
||||
#include "fsk_gen_filter.h"
|
||||
|
@ -694,14 +693,14 @@ void demod_psk_process_sample (int chan, int subchan, int sam, struct demodulato
|
|||
#endif
|
||||
}
|
||||
else {
|
||||
float a, delta;
|
||||
int id;
|
||||
float a;
|
||||
int idelta;
|
||||
|
||||
a = my_atan2f(I,Q);
|
||||
id = ((int)((a / (2.f * M_PI) + 1.f) * 256.f)) & 0xff;
|
||||
idelta = ((int)((a / (2.f * M_PI) + 1.f) * 256.f)) & 0xff;
|
||||
// 32 (90 degrees) compensates for 1800 carrier vs. 1800 baud.
|
||||
// 16 is to set threshold between constellation points.
|
||||
demod_phase_shift = ((id - 32 - 16) >> 5) & 0x7;
|
||||
demod_phase_shift = ((idelta - 32 - 16) >> 5) & 0x7;
|
||||
}
|
||||
|
||||
nudge_pll (chan, subchan, slice, demod_phase_shift, D);
|
||||
|
|
84
digipeater.c
84
digipeater.c
|
@ -53,6 +53,7 @@
|
|||
|
||||
#define DIGIPEATER_C
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -62,7 +63,6 @@
|
|||
#include "regex.h"
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "digipeater.h"
|
||||
#include "textcolor.h"
|
||||
|
@ -74,8 +74,6 @@
|
|||
static packet_t digipeat_match (int from_chan, packet_t pp, char *mycall_rec, char *mycall_xmit,
|
||||
regex_t *uidigi, regex_t *uitrace, int to_chan, enum preempt_e preempt, char *type_filter);
|
||||
|
||||
//static int filter_by_type (char *source, char *infop, char *type_filter);
|
||||
|
||||
|
||||
/*
|
||||
* Keep pointer to configuration options.
|
||||
|
@ -87,6 +85,18 @@ static struct audio_s *save_audio_config_p;
|
|||
static struct digi_config_s *save_digi_config_p;
|
||||
|
||||
|
||||
/*
|
||||
* Maintain count of packets digipeated for each combination of from/to channel.
|
||||
*/
|
||||
|
||||
static int digi_count[MAX_CHANS][MAX_CHANS];
|
||||
|
||||
int digipeater_get_count (int from_chan, int to_chan) {
|
||||
return (digi_count[from_chan][to_chan]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
* Name: digipeater_init
|
||||
|
@ -165,6 +175,7 @@ void digipeater (int from_chan, packet_t pp)
|
|||
if (result != NULL) {
|
||||
dedupe_remember (pp, to_chan);
|
||||
tq_append (to_chan, TQ_PRIO_0_HI, result);
|
||||
digi_count[from_chan][to_chan]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -190,6 +201,7 @@ void digipeater (int from_chan, packet_t pp)
|
|||
if (result != NULL) {
|
||||
dedupe_remember (pp, to_chan);
|
||||
tq_append (to_chan, TQ_PRIO_1_LO, result);
|
||||
digi_count[from_chan][to_chan]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -584,13 +596,11 @@ static int failed;
|
|||
|
||||
static enum preempt_e preempt = PREEMPT_OFF;
|
||||
|
||||
static char typefilter[20] = "";
|
||||
|
||||
|
||||
static void test (char *in, char *out)
|
||||
{
|
||||
packet_t pp, result;
|
||||
//int should_repeat;
|
||||
char rec[256];
|
||||
char xmit[256];
|
||||
unsigned char *pinfo;
|
||||
|
@ -610,6 +620,7 @@ static void test (char *in, char *out)
|
|||
|
||||
ax25_format_addrs (pp, rec);
|
||||
info_len = ax25_get_info (pp, &pinfo);
|
||||
(void)info_len;
|
||||
strlcat (rec, (char*)pinfo, sizeof(rec));
|
||||
|
||||
if (strcmp(in, rec) != 0) {
|
||||
|
@ -863,69 +874,6 @@ int main (int argc, char *argv[])
|
|||
"");
|
||||
|
||||
|
||||
#if 0 /* changed strategy */
|
||||
/*
|
||||
* New in version 1.2.
|
||||
*/
|
||||
|
||||
|
||||
// no filter.
|
||||
if (filter_by_type ("CWAPID", ":NWS-TTTTT:DDHHMMz,ADVISETYPE,zcs{seq#", "") != 1)
|
||||
{ text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 1\n"); failed++; }
|
||||
|
||||
// message should not match psqt
|
||||
if (filter_by_type ("CWAPID", ":NWS-TTTTT:DDHHMMz,ADVISETYPE,zcs{seq#", "pqst") != 0)
|
||||
{ text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 2\n"); failed++; }
|
||||
|
||||
// This should match position
|
||||
if (filter_by_type ("N3LEE-7", "`cHDl <0x1c>[/\"5j}", "qstp") != 1)
|
||||
{ text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 3\n"); failed++; }
|
||||
|
||||
// This should match nws
|
||||
if (filter_by_type ("CWAPID", ":NWS-TTTTT:DDHHMMz,ADVISETYPE,zcs{seq#", "n") != 1)
|
||||
{ text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 4\n"); failed++; }
|
||||
|
||||
// But not this.
|
||||
if (filter_by_type ("CWAPID", ":zzz-TTTTT:DDHHMMz,ADVISETYPE,zcs{seq#", "n") != 0)
|
||||
{ text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 5\n"); failed++; }
|
||||
|
||||
// This should match nws
|
||||
if (filter_by_type ("CWAPID", ";CWAttttz *DDHHMMzLATLONICONADVISETYPE{seq#", "n") != 1)
|
||||
{ text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 6\n"); failed++; }
|
||||
|
||||
// But not this due do addressee prefix mismatch
|
||||
if (filter_by_type ("CWAPID", ";NWSttttz *DDHHMMzLATLONICONADVISETYPE{seq#", "n") != 0)
|
||||
{ text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 7\n"); failed++; }
|
||||
|
||||
|
||||
/*
|
||||
* Filtering integrated with rest of process...
|
||||
*/
|
||||
|
||||
strlcpy (typefilter, "w", sizeof(typefilter));
|
||||
|
||||
test ( "N8VIM>APN391,WIDE2-1:$ULTW00000000010E097D2884FFF389DC000102430002033400000000",
|
||||
"N8VIM>APN391,WB2OSZ-9*:$ULTW00000000010E097D2884FFF389DC000102430002033400000000");
|
||||
|
||||
test ( "AB1OC-10>APWW10,WIDE1-1,WIDE2-1:>FN42er/# Hollis, NH iGate Operational",
|
||||
"");
|
||||
|
||||
strlcpy (typefilter, "s", sizeof(typefilter));
|
||||
|
||||
test ( "AB1OC-10>APWW10,WIDE1-1,WIDE2-1:>FN42er/# Hollis, NH iGate Operational",
|
||||
"AB1OC-10>APWW10,WB2OSZ-9*,WIDE2-1:>FN42er/# Hollis, NH iGate Operational");
|
||||
|
||||
test ( "K1ABC-9>TR4R8R,WIDE1-1:`c6LlIb>/`\"4K}_%",
|
||||
"");
|
||||
|
||||
strlcpy (typefilter, "up", sizeof(typefilter));
|
||||
|
||||
test ( "K1ABC-9>TR4R8R,WIDE1-1:`c6LlIb>/`\"4K}_%",
|
||||
"K1ABC-9>TR4R8R,WB2OSZ-9*:`c6LlIb>/`\"4K}_%");
|
||||
|
||||
strlcpy (typefilter, "", sizeof(typefilter));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Did I miss any cases?
|
||||
*/
|
||||
|
|
|
@ -65,6 +65,11 @@ extern void digipeater (int from_chan, packet_t pp);
|
|||
void digi_regen (int from_chan, packet_t pp);
|
||||
|
||||
|
||||
/* Make statistics available. */
|
||||
|
||||
int digipeater_get_count (int from_chan, int to_chan);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* end digipeater.h */
|
||||
|
|
48
direwolf.c
48
direwolf.c
|
@ -35,6 +35,13 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
|
||||
#define DIREWOLF_C 1
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -72,9 +79,7 @@
|
|||
#endif
|
||||
|
||||
|
||||
#define DIREWOLF_C 1
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "version.h"
|
||||
#include "audio.h"
|
||||
#include "config.h"
|
||||
|
@ -96,7 +101,6 @@
|
|||
#include "xmit.h"
|
||||
#include "ptt.h"
|
||||
#include "beacon.h"
|
||||
#include "redecode.h"
|
||||
#include "dtmf.h"
|
||||
#include "aprs_tt.h"
|
||||
#include "tt_user.h"
|
||||
|
@ -107,6 +111,7 @@
|
|||
#include "log.h"
|
||||
#include "recv.h"
|
||||
#include "morse.h"
|
||||
#include "mheard.h"
|
||||
|
||||
|
||||
//static int idx_decoded = 0;
|
||||
|
@ -160,7 +165,7 @@ static int d_u_opt = 0; /* "-d u" command line option to print UTF-8 also in h
|
|||
static int d_p_opt = 0; /* "-d p" option for dumping packets over radio. */
|
||||
|
||||
static int q_h_opt = 0; /* "-q h" Quiet, suppress the "heard" line with audio level. */
|
||||
static int q_d_opt = 0; /* "-q d" Quiet, suppress the decoding of APRS packets. */
|
||||
static int q_d_opt = 0; /* "-q d" Quiet, suppress the printing of decoded of APRS packets. */
|
||||
|
||||
|
||||
|
||||
|
@ -236,10 +241,13 @@ int main (int argc, char *argv[])
|
|||
// TODO: control development/beta/release by version.h instead of changing here.
|
||||
// Print platform. This will provide more information when people send a copy the information displayed.
|
||||
|
||||
// Might want to print OS version here. For Windows, see:
|
||||
// https://msdn.microsoft.com/en-us/library/ms724451(v=VS.85).aspx
|
||||
|
||||
text_color_init(t_opt);
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
//dw_printf ("Dire Wolf version %d.%d (%s) Beta Test\n", MAJOR_VERSION, MINOR_VERSION, __DATE__);
|
||||
dw_printf ("Dire Wolf DEVELOPMENT version %d.%d %s (%s)\n", MAJOR_VERSION, MINOR_VERSION, "B", __DATE__);
|
||||
dw_printf ("Dire Wolf DEVELOPMENT version %d.%d %s (%s)\n", MAJOR_VERSION, MINOR_VERSION, "C", __DATE__);
|
||||
//dw_printf ("Dire Wolf version %d.%d\n", MAJOR_VERSION, MINOR_VERSION);
|
||||
|
||||
#if defined(ENABLE_GPSD) || defined(USE_HAMLIB)
|
||||
|
@ -660,7 +668,7 @@ int main (int argc, char *argv[])
|
|||
* Note: This is not the same as a volume control you would see on the screen.
|
||||
* It is the range of the digital sound representation.
|
||||
*/
|
||||
gen_tone_init (&audio_config, 100);
|
||||
gen_tone_init (&audio_config, 100, 0);
|
||||
morse_init (&audio_config, 100);
|
||||
|
||||
assert (audio_config.adev[0].bits_per_sample == 8 || audio_config.adev[0].bits_per_sample == 16);
|
||||
|
@ -723,11 +731,6 @@ int main (int argc, char *argv[])
|
|||
|
||||
waypoint_init (&misc_config);
|
||||
|
||||
/*
|
||||
* Create thread for trying to salvage frames with bad FCS.
|
||||
*/
|
||||
redecode_init (&audio_config);
|
||||
|
||||
/*
|
||||
* Enable beaconing.
|
||||
* Open log file first because "-dttt" (along with -l...) will
|
||||
|
@ -735,7 +738,8 @@ int main (int argc, char *argv[])
|
|||
*/
|
||||
|
||||
log_init(misc_config.logdir);
|
||||
beacon_init (&audio_config, &misc_config);
|
||||
mheard_init (0); // might add debug option someday.
|
||||
beacon_init (&audio_config, &misc_config, &igate_config);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -916,6 +920,7 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev
|
|||
int ns;
|
||||
|
||||
ftype = ax25_frame_type (pp, &cr, desc, &pf, &nr, &ns);
|
||||
(void)ftype;
|
||||
|
||||
dw_printf ("(%s)", desc);
|
||||
}
|
||||
|
@ -962,15 +967,20 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev
|
|||
/* Decode the contents of APRS frames and display in human-readable form. */
|
||||
/* Suppress decoding if "-q d" option used. */
|
||||
|
||||
if ( ( ! q_d_opt ) && ax25_is_aprs(pp)) {
|
||||
|
||||
if (ax25_is_aprs(pp)) {
|
||||
|
||||
decode_aprs_t A;
|
||||
|
||||
decode_aprs (&A, pp, 0);
|
||||
|
||||
//Print it all out in human readable format.
|
||||
|
||||
decode_aprs_print (&A);
|
||||
if ( ! q_d_opt ) {
|
||||
|
||||
// Print it all out in human readable format unless "-q d" option used.
|
||||
|
||||
decode_aprs_print (&A);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform validity check on each address.
|
||||
|
@ -982,6 +992,11 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev
|
|||
|
||||
log_write (chan, &A, pp, alevel, retries);
|
||||
|
||||
// Add to list of stations heard.
|
||||
|
||||
mheard_save (chan, &A, pp, alevel, retries);
|
||||
|
||||
|
||||
// Convert to NMEA waypoint sentence if we have a location.
|
||||
|
||||
if (A.g_lat != G_UNKNOWN && A.g_lon != G_UNKNOWN) {
|
||||
|
@ -994,7 +1009,7 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev
|
|||
|
||||
|
||||
/* Send to another application if connected. */
|
||||
// TODO1.3: Put a wrapper around this so we only call one function to send by all methods.
|
||||
// TODO: Put a wrapper around this so we only call one function to send by all methods.
|
||||
|
||||
int flen;
|
||||
unsigned char fbuf[AX25_MAX_PACKET_LEN];
|
||||
|
@ -1119,6 +1134,7 @@ static void usage (char **argv)
|
|||
dw_printf (" u u = Display non-ASCII text in hexadecimal.\n");
|
||||
dw_printf (" p p = dump Packets in hexadecimal.\n");
|
||||
dw_printf (" g g = GPS interface.\n");
|
||||
dw_printf (" w w = Waypoints for Position or Object Reports.\n");
|
||||
dw_printf (" t t = Tracker beacon.\n");
|
||||
dw_printf (" o o = output controls such as PTT and DCD.\n");
|
||||
dw_printf (" i i = IGate.\n");
|
||||
|
|
36
direwolf.h
36
direwolf.h
|
@ -1,7 +1,37 @@
|
|||
|
||||
/* direwolf.h - Common stuff used many places. */
|
||||
|
||||
// TODO: include this file first before anything else in each .c file.
|
||||
|
||||
|
||||
#ifndef DIREWOLF_H
|
||||
#define DIREWOLF_H 1
|
||||
|
||||
/*
|
||||
* Support Windows XP and later.
|
||||
*
|
||||
* We need this before "#include <ws2tcpip.h>".
|
||||
*
|
||||
* Don't know what other impact it might have on others.
|
||||
*/
|
||||
|
||||
#if __WIN32__
|
||||
|
||||
#ifdef _WIN32_WINNT
|
||||
#error Include "direwolf.h" before any windows system files.
|
||||
#endif
|
||||
#ifdef WINVER
|
||||
#error Include "direwolf.h" before any windows system files.
|
||||
#endif
|
||||
|
||||
#define _WIN32_WINNT 0x0501 /* Minimum OS version is XP. */
|
||||
#define WINVER 0x0501 /* Minimum OS version is XP. */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Previously, we could handle only a single audio device.
|
||||
|
@ -9,6 +39,8 @@
|
|||
* In version 1.2, we relax this restriction and allow more audio devices.
|
||||
* Three is probably adequate for standard version.
|
||||
* Larger reasonable numbers should also be fine.
|
||||
*
|
||||
* For example, if you wanted to use 4 audio devices at once, change this to 4.
|
||||
*/
|
||||
|
||||
#define MAX_ADEVS 3
|
||||
|
@ -69,7 +101,6 @@
|
|||
|
||||
|
||||
#if __WIN32__
|
||||
#include <windows.h>
|
||||
#define SLEEP_SEC(n) Sleep((n)*1000)
|
||||
#define SLEEP_MS(n) Sleep(n)
|
||||
#else
|
||||
|
@ -191,9 +222,8 @@ char *strsep(char **stringp, const char *delim);
|
|||
char *strtok_r(char *str, const char *delim, char **saveptr);
|
||||
#endif
|
||||
|
||||
//#if __WIN32__
|
||||
// Don't recall why for everyone.
|
||||
char *strcasestr(const char *S, const char *FIND);
|
||||
//#endif
|
||||
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||
|
|
3
dlq.c
3
dlq.c
|
@ -37,6 +37,8 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -47,7 +49,6 @@
|
|||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
#include "audio.h"
|
||||
|
|
Binary file not shown.
Binary file not shown.
5
dsp.c
5
dsp.c
|
@ -26,6 +26,8 @@
|
|||
*
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
@ -34,7 +36,6 @@
|
|||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "audio.h"
|
||||
#include "fsk_demod_state.h"
|
||||
#include "fsk_gen_filter.h"
|
||||
|
@ -51,7 +52,7 @@
|
|||
// Don't remove this. It serves as a reminder that an experiment is underway.
|
||||
|
||||
#if defined(TUNE_MS_FILTER_SIZE) || defined(TUNE_AGC_FAST) || defined(TUNE_LPF_BAUD) || defined(TUNE_PLL_LOCKED) || defined(TUNE_PROFILE)
|
||||
#define DEBUG1 1
|
||||
#define DEBUG1 1 // Don't remove this.
|
||||
#endif
|
||||
|
||||
|
||||
|
|
4
dtmf.c
4
dtmf.c
|
@ -34,13 +34,13 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "dtmf.h"
|
||||
#include "hdlc_rec.h" // for dcd_change
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
|||
|
||||
#if DTMF_TEST
|
||||
#define TIMEOUT_SEC 1 /* short for unit test below. */
|
||||
#define DEBUG 1
|
||||
#define DEBUG 1 // Don't remove this. We want more output for test.
|
||||
#else
|
||||
#define TIMEOUT_SEC 5 /* for normal operation. */
|
||||
#endif
|
||||
|
|
3
dwgps.c
3
dwgps.c
|
@ -48,13 +48,14 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "textcolor.h"
|
||||
#include "dwgps.h"
|
||||
#include "dwgpsnmea.h"
|
||||
|
|
4
dwgpsd.c
4
dwgpsd.c
|
@ -34,6 +34,9 @@
|
|||
*---------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -60,7 +63,6 @@
|
|||
#endif
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "textcolor.h"
|
||||
#include "dwgps.h"
|
||||
#include "dwgpsd.h"
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
*---------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -38,7 +41,6 @@
|
|||
#include <time.h>
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "textcolor.h"
|
||||
#include "dwgps.h"
|
||||
#include "dwgpsnmea.h"
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
@ -42,7 +44,6 @@
|
|||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "encode_aprs.h"
|
||||
#include "latlong.h"
|
||||
#include "textcolor.h"
|
||||
|
@ -692,7 +693,7 @@ int encode_object (char *name, int compressed, time_t thyme, double lat, double
|
|||
|
||||
#define XMIT_UTC 1
|
||||
#if XMIT_UTC
|
||||
gmtime_r (&thyme, &tm);
|
||||
(void)gmtime_r (&thyme, &tm);
|
||||
#else
|
||||
/* Using local time, for this application, would make more sense to me. */
|
||||
/* On Windows, localtime_r produces UTC. */
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
//
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
|
|
|
@ -234,6 +234,7 @@ struct demodulator_state_s
|
|||
|
||||
int prev_demod_data; // Previous data bit detected.
|
||||
// Used to look for transitions.
|
||||
float prev_demod_out_f;
|
||||
|
||||
/* This is used only for "9600" baud data. */
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
*------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -463,7 +463,7 @@ int main(int argc, char **argv)
|
|||
amplitude = 100;
|
||||
}
|
||||
|
||||
gen_tone_init (&modem, amplitude/2);
|
||||
gen_tone_init (&modem, amplitude/2, 1);
|
||||
morse_init (&modem, amplitude/2);
|
||||
|
||||
|
||||
|
@ -635,6 +635,8 @@ int main(int argc, char **argv)
|
|||
else {
|
||||
/* e.g. 9600 */
|
||||
g_noise_level = 0.33 * (amplitude / 200.0) * ((float)i / packet_count);
|
||||
// temp test
|
||||
//g_noise_level = 0.20 * (amplitude / 200.0) * ((float)i / packet_count);
|
||||
}
|
||||
|
||||
snprintf (stemp, sizeof(stemp), "WB2OSZ-15>TEST:,The quick brown fox jumps over the lazy dog! %04d of %04d", i, packet_count);
|
||||
|
@ -677,8 +679,8 @@ static void usage (char **argv)
|
|||
dw_printf (" -r <number> Audio sample Rate. Default is %d.\n", DEFAULT_SAMPLES_PER_SEC);
|
||||
dw_printf (" -n <number> Generate specified number of frames with increasing noise.\n");
|
||||
dw_printf (" -o <file> Send output to .wav file.\n");
|
||||
// dw_printf (" -8 8 bit audio rather than 16.\n");
|
||||
// dw_printf (" -2 2 channels of audio rather than 1.\n");
|
||||
dw_printf (" -8 8 bit audio rather than 16.\n");
|
||||
dw_printf (" -2 2 channels (stereo) audio rather than one channel.\n");
|
||||
// dw_printf (" -z <number> Number of leading zero bits before frame.\n");
|
||||
// dw_printf (" Default is 12 which is .01 seconds at 1200 bits/sec.\n");
|
||||
|
||||
|
|
200
gen_tone.c
200
gen_tone.c
|
@ -1,3 +1,6 @@
|
|||
//#define DEBUG 1
|
||||
//#define DEBUG2 1
|
||||
|
||||
//
|
||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||
//
|
||||
|
@ -28,6 +31,9 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
@ -35,7 +41,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include "audio.h"
|
||||
#include "gen_tone.h"
|
||||
#include "textcolor.h"
|
||||
|
@ -47,7 +53,7 @@
|
|||
|
||||
// Properties of the digitized sound stream & modem.
|
||||
|
||||
static struct audio_s *save_audio_config_p;
|
||||
static struct audio_s *save_audio_config_p = NULL;
|
||||
|
||||
/*
|
||||
* 8 bit samples are unsigned bytes in range of 0 .. 255.
|
||||
|
@ -99,9 +105,6 @@ static int bit_count[MAX_CHANS]; // Counter incremented for each bit transmitted
|
|||
// three for each symbol.
|
||||
static int save_bit[MAX_CHANS];
|
||||
|
||||
static int prev_symbol[MAX_CHANS]; // Data is conveyed by phase relative to the
|
||||
// previous symbol. So we need to keep it.
|
||||
|
||||
|
||||
/*
|
||||
* The K9NG/G3RUH output originally took a very simple and lazy approach.
|
||||
|
@ -177,6 +180,9 @@ static int resample[MAX_CHANS];
|
|||
*
|
||||
* amp - Signal amplitude on scale of 0 .. 100.
|
||||
*
|
||||
* gen_packets - True if being called from "gen_packets" utility
|
||||
* rather than the "direwolf" application.
|
||||
*
|
||||
* Returns: 0 for success.
|
||||
* -1 for failure.
|
||||
*
|
||||
|
@ -188,11 +194,17 @@ static int resample[MAX_CHANS];
|
|||
static int amp16bit; /* for 9600 baud */
|
||||
|
||||
|
||||
int gen_tone_init (struct audio_s *audio_config_p, int amp)
|
||||
int gen_tone_init (struct audio_s *audio_config_p, int amp, int gen_packets)
|
||||
{
|
||||
int j;
|
||||
int chan = 0;
|
||||
|
||||
#if DEBUG
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("gen_tone_init ( audio_config_p=%p, amp=%d, gen_packets=%d )\n",
|
||||
audio_config_p, amp, gen_packets);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Save away modem parameters for later use.
|
||||
*/
|
||||
|
@ -209,6 +221,15 @@ int gen_tone_init (struct audio_s *audio_config_p, int amp)
|
|||
|
||||
int a = ACHAN2ADEV(chan);
|
||||
|
||||
#if DEBUG
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("gen_tone_init: chan=%d, modem_type=%d, bps=%d, samples_per_sec=%d\n",
|
||||
chan,
|
||||
save_audio_config_p->achan[chan].modem_type,
|
||||
audio_config_p->achan[chan].baud,
|
||||
audio_config_p->adev[a].samples_per_sec);
|
||||
#endif
|
||||
|
||||
tone_phase[chan] = 0;
|
||||
bit_len_acc[chan] = 0;
|
||||
lfsr[chan] = 0;
|
||||
|
@ -302,6 +323,20 @@ int gen_tone_init (struct audio_s *audio_config_p, int amp)
|
|||
|
||||
float fc; /* Cutoff frequency as fraction of sampling frequency. */
|
||||
|
||||
/*
|
||||
* Normally, we want to generate the same thing whether sending over the air
|
||||
* or putting it into a file for other testing.
|
||||
* (There is an important exception. gen_packets can introduce random noise.)
|
||||
* In this case, we want more aggressive low pass filtering so it looks more like
|
||||
* what we see coming out of a receiver.
|
||||
* Specifically, single bits of the same state have considerably reduced amplitude
|
||||
* below several same values in a row.
|
||||
*/
|
||||
|
||||
if (gen_packets) {
|
||||
filter_len_bits = 4;
|
||||
lpf_baud = 0.55; /* Lowpass cutoff freq as fraction of baud rate */
|
||||
}
|
||||
|
||||
samples_per_sec = audio_config_p->adev[a].samples_per_sec * UPSAMPLE;
|
||||
baud = audio_config_p->achan[chan].baud;
|
||||
|
@ -339,7 +374,7 @@ int gen_tone_init (struct audio_s *audio_config_p, int amp)
|
|||
|
||||
/*-------------------------------------------------------------------
|
||||
*
|
||||
* Name: gen_tone_put_bit
|
||||
* Name: tone_gen_put_bit
|
||||
*
|
||||
* Purpose: Generate tone of proper duration for one data bit.
|
||||
*
|
||||
|
@ -364,6 +399,7 @@ void tone_gen_put_bit (int chan, int dat)
|
|||
{
|
||||
int a = ACHAN2ADEV(chan); /* device for channel. */
|
||||
|
||||
assert (save_audio_config_p != NULL);
|
||||
assert (save_audio_config_p->achan[chan].valid);
|
||||
|
||||
|
||||
|
@ -385,26 +421,15 @@ void tone_gen_put_bit (int chan, int dat)
|
|||
bit_count[chan]++;
|
||||
return;
|
||||
}
|
||||
#define REV2 1
|
||||
#if REV2
|
||||
#else
|
||||
tone_phase[chan] = PHASE_SHIFT_45;
|
||||
if (bit_count[chan] & 2) {
|
||||
tone_phase[chan] += (unsigned)PHASE_SHIFT_180;
|
||||
}
|
||||
#endif
|
||||
|
||||
// All zero bits should give us steady 1800 Hz.
|
||||
// All one bits should flip phase by 180 degrees each time.
|
||||
|
||||
dibit = (save_bit[chan] << 1) | dat;
|
||||
#if REV2
|
||||
|
||||
symbol = gray2phase_v26[dibit];
|
||||
tone_phase[chan] += symbol * PHASE_SHIFT_90;
|
||||
#else
|
||||
symbol = (prev_symbol[chan] + gray2phase_v26[dibit]) & 0x3;
|
||||
tone_phase[chan] += symbol * PHASE_SHIFT_90;
|
||||
prev_symbol[chan] = symbol;
|
||||
#endif
|
||||
|
||||
bit_count[chan]++;
|
||||
}
|
||||
|
||||
|
@ -425,14 +450,10 @@ void tone_gen_put_bit (int chan, int dat)
|
|||
// All one bits should flip phase by 180 degrees each time.
|
||||
|
||||
tribit = (save_bit[chan] << 1) | dat;
|
||||
#if 1
|
||||
|
||||
symbol = gray2phase_v27[tribit];
|
||||
tone_phase[chan] += symbol * PHASE_SHIFT_45;
|
||||
#else
|
||||
symbol = (prev_symbol[chan] + gray2phase_v27[tribit]) & 0x7;
|
||||
tone_phase[chan] = symbol * PHASE_SHIFT_45;
|
||||
prev_symbol[chan] = symbol;
|
||||
#endif
|
||||
|
||||
save_bit[chan] = 0;
|
||||
bit_count[chan] = 0;
|
||||
}
|
||||
|
@ -445,39 +466,63 @@ void tone_gen_put_bit (int chan, int dat)
|
|||
dat = x;
|
||||
}
|
||||
|
||||
do {
|
||||
do { /* until enough audio samples for this symbol. */
|
||||
|
||||
if (save_audio_config_p->achan[chan].modem_type == MODEM_AFSK) {
|
||||
int sam;
|
||||
int sam;
|
||||
float fsam;
|
||||
|
||||
tone_phase[chan] += dat ? f2_change_per_sample[chan] : f1_change_per_sample[chan];
|
||||
sam = sine_table[(tone_phase[chan] >> 24) & 0xff];
|
||||
gen_tone_put_sample (chan, a, sam);
|
||||
}
|
||||
else if (save_audio_config_p->achan[chan].modem_type == MODEM_QPSK ||
|
||||
save_audio_config_p->achan[chan].modem_type == MODEM_8PSK) {
|
||||
int sam;
|
||||
switch (save_audio_config_p->achan[chan].modem_type) {
|
||||
|
||||
tone_phase[chan] += f1_change_per_sample[chan];
|
||||
sam = sine_table[(tone_phase[chan] >> 24) & 0xff];
|
||||
gen_tone_put_sample (chan, a, sam);
|
||||
}
|
||||
else {
|
||||
case MODEM_AFSK:
|
||||
|
||||
float fsam = dat ? amp16bit : (-amp16bit);
|
||||
|
||||
/* version 1.2 - added a low pass filter instead of square wave out. */
|
||||
|
||||
push_sample (fsam, raw[chan], lp_filter_size[chan]);
|
||||
|
||||
resample[chan]++;
|
||||
if (resample[chan] >= UPSAMPLE) {
|
||||
int sam;
|
||||
|
||||
sam = (int) convolve (raw[chan], lp_filter[chan], lp_filter_size[chan]);
|
||||
resample[chan] = 0;
|
||||
#if DEBUG2
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("tone_gen_put_bit %d AFSK\n", __LINE__);
|
||||
#endif
|
||||
tone_phase[chan] += dat ? f2_change_per_sample[chan] : f1_change_per_sample[chan];
|
||||
sam = sine_table[(tone_phase[chan] >> 24) & 0xff];
|
||||
gen_tone_put_sample (chan, a, sam);
|
||||
}
|
||||
break;
|
||||
|
||||
case MODEM_QPSK:
|
||||
case MODEM_8PSK:
|
||||
|
||||
#if DEBUG2
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("tone_gen_put_bit %d PSK\n", __LINE__);
|
||||
#endif
|
||||
tone_phase[chan] += f1_change_per_sample[chan];
|
||||
sam = sine_table[(tone_phase[chan] >> 24) & 0xff];
|
||||
gen_tone_put_sample (chan, a, sam);
|
||||
break;
|
||||
|
||||
case MODEM_BASEBAND:
|
||||
case MODEM_SCRAMBLE:
|
||||
|
||||
#if DEBUG2
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("tone_gen_put_bit %d SCR\n", __LINE__);
|
||||
#endif
|
||||
fsam = dat ? amp16bit : (-amp16bit);
|
||||
|
||||
/* version 1.2 - added a low pass filter instead of square wave out. */
|
||||
|
||||
push_sample (fsam, raw[chan], lp_filter_size[chan]);
|
||||
|
||||
resample[chan]++;
|
||||
if (resample[chan] >= UPSAMPLE) {
|
||||
|
||||
sam = (int) convolve (raw[chan], lp_filter[chan], lp_filter_size[chan]);
|
||||
resample[chan] = 0;
|
||||
gen_tone_put_sample (chan, a, sam);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("INTERNAL ERROR: %s %d achan[%d].modem_type = %d\n",
|
||||
__FILE__, __LINE__, chan, save_audio_config_p->achan[chan].modem_type);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Enough for the bit time? */
|
||||
|
@ -493,12 +538,14 @@ void tone_gen_put_bit (int chan, int dat)
|
|||
void gen_tone_put_sample (int chan, int a, int sam) {
|
||||
|
||||
/* Ship out an audio sample. */
|
||||
/* 16 bit is signed, little endian, range -32768 .. +32767 */
|
||||
/* 8 bit is unsigned, range 0 .. 255 */
|
||||
|
||||
assert (save_audio_config_p != NULL);
|
||||
|
||||
assert (save_audio_config_p->adev[a].num_channels == 1 || save_audio_config_p->adev[a].num_channels == 2);
|
||||
|
||||
/* Generalize to allow 8 bits someday? */
|
||||
|
||||
assert (save_audio_config_p->adev[a].bits_per_sample == 16);
|
||||
assert (save_audio_config_p->adev[a].bits_per_sample == 16 || save_audio_config_p->adev[a].bits_per_sample == 8);
|
||||
|
||||
// TODO: Should print message telling user to reduce output level.
|
||||
|
||||
|
@ -509,8 +556,13 @@ void gen_tone_put_sample (int chan, int a, int sam) {
|
|||
|
||||
/* Mono */
|
||||
|
||||
audio_put (a, sam & 0xff);
|
||||
audio_put (a, (sam >> 8) & 0xff);
|
||||
if (save_audio_config_p->adev[a].bits_per_sample == 8) {
|
||||
audio_put (a, ((sam+32768) >> 8) & 0xff);
|
||||
}
|
||||
else {
|
||||
audio_put (a, sam & 0xff);
|
||||
audio_put (a, (sam >> 8) & 0xff);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
|
@ -518,21 +570,33 @@ void gen_tone_put_sample (int chan, int a, int sam) {
|
|||
|
||||
/* Stereo, left channel. */
|
||||
|
||||
audio_put (a, sam & 0xff);
|
||||
audio_put (a, (sam >> 8) & 0xff);
|
||||
if (save_audio_config_p->adev[a].bits_per_sample == 8) {
|
||||
audio_put (a, ((sam+32768) >> 8) & 0xff);
|
||||
audio_put (a, 0);
|
||||
}
|
||||
else {
|
||||
audio_put (a, sam & 0xff);
|
||||
audio_put (a, (sam >> 8) & 0xff);
|
||||
|
||||
audio_put (a, 0);
|
||||
audio_put (a, 0);
|
||||
audio_put (a, 0);
|
||||
audio_put (a, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
/* Stereo, right channel. */
|
||||
|
||||
audio_put (a, 0);
|
||||
audio_put (a, 0);
|
||||
if (save_audio_config_p->adev[a].bits_per_sample == 8) {
|
||||
audio_put (a, 0);
|
||||
audio_put (a, ((sam+32768) >> 8) & 0xff);
|
||||
}
|
||||
else {
|
||||
audio_put (a, 0);
|
||||
audio_put (a, 0);
|
||||
|
||||
audio_put (a, sam & 0xff);
|
||||
audio_put (a, (sam >> 8) & 0xff);
|
||||
audio_put (a, sam & 0xff);
|
||||
audio_put (a, (sam >> 8) & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
|
||||
|
||||
int gen_tone_init (struct audio_s *pp, int amp);
|
||||
int gen_tone_init (struct audio_s *pp, int amp, int gen_packets);
|
||||
|
||||
|
||||
//int gen_tone_open (int nchan, int sample_rate, int bit_rate, int f1, int f2, int amp, char *fname);
|
||||
|
|
|
@ -27,11 +27,12 @@
|
|||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "demod.h"
|
||||
#include "hdlc_rec.h"
|
||||
#include "hdlc_rec2.h"
|
||||
|
@ -46,6 +47,7 @@
|
|||
|
||||
//#define TEST 1 /* Define for unit testing. */
|
||||
|
||||
|
||||
//#define DEBUG3 1 /* monitor the data detect signal. */
|
||||
|
||||
|
||||
|
@ -278,6 +280,7 @@ void hdlc_rec_bit (int chan, int subchan, int slice, int raw, int is_scrambled,
|
|||
* when listening to live signals. Let's try 3 and see how that works out.
|
||||
*/
|
||||
|
||||
|
||||
//if (H->flag4_det == 0x7e7e7e7e) {
|
||||
if ((H->flag4_det & 0xffffff00) == 0x7e7e7e00) {
|
||||
//if ((H->flag4_det & 0xffff0000) == 0x7e7e0000) {
|
||||
|
|
20
hdlc_rec2.c
20
hdlc_rec2.c
|
@ -84,13 +84,15 @@
|
|||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
//Optimize processing by accessing directly to decoded bits
|
||||
#define RRBB_C 1
|
||||
#include "direwolf.h"
|
||||
#include "hdlc_rec2.h"
|
||||
#include "fcs_calc.h"
|
||||
#include "textcolor.h"
|
||||
|
@ -242,6 +244,8 @@ void hdlc_rec2_block (rrbb_t block)
|
|||
/* Create an empty retry configuration */
|
||||
retry_conf_t retry_cfg;
|
||||
|
||||
memset (&retry_cfg, 0, sizeof(retry_cfg));
|
||||
|
||||
/*
|
||||
* For our first attempt we don't try to alter any bits.
|
||||
* Still let it thru if passall AND no retries are desired.
|
||||
|
@ -327,7 +331,7 @@ void hdlc_rec2_block (rrbb_t block)
|
|||
static int try_to_fix_quick_now (rrbb_t block, int chan, int subchan, int slice, alevel_t alevel)
|
||||
{
|
||||
int ok;
|
||||
int len, i,j;
|
||||
int len, i;
|
||||
retry_t fix_bits = save_audio_config_p->achan[chan].fix_bits;
|
||||
//int passall = save_audio_config_p->achan[chan].passall;
|
||||
|
||||
|
@ -335,6 +339,9 @@ static int try_to_fix_quick_now (rrbb_t block, int chan, int subchan, int slice,
|
|||
len = rrbb_get_len(block);
|
||||
/* Prepare the retry configuration */
|
||||
retry_conf_t retry_cfg;
|
||||
|
||||
memset (&retry_cfg, 0, sizeof(retry_cfg));
|
||||
|
||||
/* Will modify only contiguous bits*/
|
||||
retry_cfg.mode = RETRY_MODE_CONTIGUOUS;
|
||||
/*
|
||||
|
@ -464,14 +471,17 @@ static int try_to_fix_quick_now (rrbb_t block, int chan, int subchan, int slice,
|
|||
int hdlc_rec2_try_to_fix_later (rrbb_t block, int chan, int subchan, int slice, alevel_t alevel)
|
||||
{
|
||||
int ok;
|
||||
int len, i, j;
|
||||
retry_t fix_bits = save_audio_config_p->achan[chan].fix_bits;
|
||||
//int len;
|
||||
//retry_t fix_bits = save_audio_config_p->achan[chan].fix_bits;
|
||||
int passall = save_audio_config_p->achan[chan].passall;
|
||||
#if DEBUG_LATER
|
||||
double tstart, tend;
|
||||
#endif
|
||||
retry_conf_t retry_cfg;
|
||||
len = rrbb_get_len(block);
|
||||
|
||||
memset (&retry_cfg, 0, sizeof(retry_cfg));
|
||||
|
||||
//len = rrbb_get_len(block);
|
||||
|
||||
|
||||
/*
|
||||
|
|
28
hdlc_send.c
28
hdlc_send.c
|
@ -1,3 +1,4 @@
|
|||
|
||||
//
|
||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||
//
|
||||
|
@ -17,10 +18,10 @@
|
|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "hdlc_send.h"
|
||||
#include "audio.h"
|
||||
#include "gen_tone.h"
|
||||
|
@ -33,7 +34,9 @@ static void send_bit (int, int);
|
|||
|
||||
|
||||
|
||||
static int number_of_bits_sent[MAX_CHANS];
|
||||
static int number_of_bits_sent[MAX_CHANS]; // Count number of bits sent by "hdlc_send_frame" or "hdlc_send_flags"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -162,7 +165,10 @@ int hdlc_send_flags (int chan, int nflags, int finish)
|
|||
|
||||
|
||||
|
||||
static int stuff = 0;
|
||||
static int stuff[MAX_CHANS]; // Count number of "1" bits to keep track of when we
|
||||
// need to break up a long run by "bit stuffing."
|
||||
// Needs to be array because we could be transmitting
|
||||
// on multiple channels at the same time.
|
||||
|
||||
static void send_control (int chan, int x)
|
||||
{
|
||||
|
@ -173,7 +179,7 @@ static void send_control (int chan, int x)
|
|||
x >>= 1;
|
||||
}
|
||||
|
||||
stuff = 0;
|
||||
stuff[chan] = 0;
|
||||
}
|
||||
|
||||
static void send_data (int chan, int x)
|
||||
|
@ -183,13 +189,13 @@ static void send_data (int chan, int x)
|
|||
for (i=0; i<8; i++) {
|
||||
send_bit (chan, x & 1);
|
||||
if (x & 1) {
|
||||
stuff++;
|
||||
if (stuff == 5) {
|
||||
stuff[chan]++;
|
||||
if (stuff[chan] == 5) {
|
||||
send_bit (chan, 0);
|
||||
stuff = 0;
|
||||
stuff[chan] = 0;
|
||||
}
|
||||
} else {
|
||||
stuff = 0;
|
||||
stuff[chan] = 0;
|
||||
}
|
||||
x >>= 1;
|
||||
}
|
||||
|
@ -203,13 +209,13 @@ static void send_data (int chan, int x)
|
|||
|
||||
static void send_bit (int chan, int b)
|
||||
{
|
||||
static int output;
|
||||
static int output[MAX_CHANS];
|
||||
|
||||
if (b == 0) {
|
||||
output = ! output;
|
||||
output[chan] = ! output[chan];
|
||||
}
|
||||
|
||||
tone_gen_put_bit (chan, output);
|
||||
tone_gen_put_bit (chan, output[chan]);
|
||||
|
||||
number_of_bits_sent[chan]++;
|
||||
}
|
||||
|
|
148
igate.c
148
igate.c
|
@ -63,18 +63,15 @@
|
|||
* Cygwin: Can use either one.
|
||||
*/
|
||||
|
||||
#include "direwolf.h" // Sets _WIN32_WINNT for XP API level needed by ws2tcpip.h
|
||||
|
||||
#if __WIN32__
|
||||
|
||||
/* The goal is to support Windows XP and later. */
|
||||
|
||||
#include <winsock2.h>
|
||||
// default is 0x0400
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501 /* Minimum OS version is XP. */
|
||||
//#define _WIN32_WINNT 0x0502 /* Minimum OS version is XP with SP2. */
|
||||
//#define _WIN32_WINNT 0x0600 /* Minimum OS version is Vista. */
|
||||
#include <ws2tcpip.h>
|
||||
#include <ws2tcpip.h> // _WIN32_WINNT must be set to 0x0501 before including this
|
||||
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <netdb.h>
|
||||
|
@ -293,8 +290,10 @@ static int s_debug;
|
|||
|
||||
|
||||
/*
|
||||
* Statistics.
|
||||
* TODO: need print function.
|
||||
* Statistics for IGate function.
|
||||
* Note that the RF related counters are just a subset of what is happening on radio channels.
|
||||
*
|
||||
* TODO: should have debug option to print these occasionally.
|
||||
*/
|
||||
|
||||
static int stats_failed_connect; /* Number of times we tried to connect to */
|
||||
|
@ -312,8 +311,10 @@ static time_t stats_connect_at; /* Most recent time connection was established.
|
|||
/* can be used to determine elapsed connect time. */
|
||||
|
||||
static int stats_rf_recv_packets; /* Number of candidate packets from the radio. */
|
||||
/* This is not the total number of AX.25 frames received */
|
||||
/* over the radio; only APRS packets get this far. */
|
||||
|
||||
static int stats_rx_igate_packets; /* Number of packets passed along to the IGate */
|
||||
static int stats_uplink_packets; /* Number of packets passed along to the IGate */
|
||||
/* server after filtering. */
|
||||
|
||||
static int stats_uplink_bytes; /* Total number of bytes sent to IGate server */
|
||||
|
@ -322,40 +323,44 @@ static int stats_uplink_bytes; /* Total number of bytes sent to IGate server */
|
|||
static int stats_downlink_bytes; /* Total number of bytes from IGate server including */
|
||||
/* packets, heartbeats, other messages. */
|
||||
|
||||
static int stats_tx_igate_packets; /* Number of packets from IGate server. */
|
||||
static int stats_downlink_packets; /* Number of packets from IGate server for possible transmission. */
|
||||
/* Fewer might be transmitted due to filtering or rate limiting. */
|
||||
|
||||
static int stats_rf_xmit_packets; /* Number of packets passed along to radio */
|
||||
/* after rate limiting or other restrictions. */
|
||||
static int stats_rf_xmit_packets; /* Number of packets passed along to radio, for the IGate function, */
|
||||
/* after filtering, rate limiting, or other restrictions. */
|
||||
/* Number of packets transmitted for beacons, digipeating, */
|
||||
/* or client applications are not included here. */
|
||||
|
||||
/* We have some statistics. What do we do with them?
|
||||
static int stats_msg_cnt; /* Number of "messages" transmitted. Subset of above. */
|
||||
/* A "message" has the data type indicator of ":" and it is */
|
||||
/* not the special case of telemetry metadata. */
|
||||
|
||||
|
||||
IGate stations often send packets like this:
|
||||
/*
|
||||
* Make some of these available for IGate statistics beacon like
|
||||
*
|
||||
* WB2OSZ>APDW14,WIDE1-1:<IGATE,MSG_CNT=2,PKT_CNT=0,DIR_CNT=10,LOC_CNT=35,RF_CNT=45
|
||||
*
|
||||
* MSG_CNT is only "messages." From original spec.
|
||||
* PKT_CNT is other (non-message) packets. Followed precedent of APRSISCE32.
|
||||
*/
|
||||
|
||||
<IGATE MSG_CNT=1238 LOC_CNT=0 FILL_CNT=0
|
||||
<IGATE,MSG_CNT=1,LOC_CNT=25
|
||||
<IGATE,MSG_CNT=0,LOC_CNT=46,DIR_CNT=13,RF_CNT=49,RFPORT_ID=0
|
||||
int igate_get_msg_cnt (void) {
|
||||
return (stats_msg_cnt);
|
||||
}
|
||||
|
||||
What does it all mean?
|
||||
Why do some have spaces instead of commas between the capabilities?
|
||||
int igate_get_pkt_cnt (void) {
|
||||
return (stats_rf_xmit_packets - stats_msg_cnt);
|
||||
}
|
||||
|
||||
The APRS Protocol Reference ( http://www.aprs.org/doc/APRS101.PDF ),
|
||||
section 15, briefly discusses station capabilities and gives the example
|
||||
IGATE,MSG_CNT=n,LOC_CNT=n
|
||||
int igate_get_upl_cnt (void) {
|
||||
return (stats_uplink_packets);
|
||||
}
|
||||
|
||||
IGate Design ( http://www.aprs-is.net/IGating.aspx ) barely mentions
|
||||
<IGATE,MSG_CNT=n,LOC_CNT=n
|
||||
int igate_get_dnl_cnt (void) {
|
||||
return (stats_downlink_packets);
|
||||
}
|
||||
|
||||
This leaves many questions. Does "number of messages transmitted" mean only
|
||||
the APRS "Message" (data type indicator ":") or does it mean any type of
|
||||
APRS packet? What are "local" stations? Those we hear directly without
|
||||
going thru a digipeater?
|
||||
|
||||
What are DIR_CNT, RF_CNT, and so on?
|
||||
|
||||
Are the counts since the system started up or are they for some interval?
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
|
@ -424,11 +429,12 @@ void igate_init (struct audio_s *p_audio_config, struct igate_config_s *p_igate_
|
|||
stats_connects = 0;
|
||||
stats_connect_at = 0;
|
||||
stats_rf_recv_packets = 0;
|
||||
stats_rx_igate_packets = 0;
|
||||
stats_uplink_packets = 0;
|
||||
stats_uplink_bytes = 0;
|
||||
stats_downlink_bytes = 0;
|
||||
stats_tx_igate_packets = 0;
|
||||
stats_downlink_packets = 0;
|
||||
stats_rf_xmit_packets = 0;
|
||||
stats_msg_cnt = 0;
|
||||
|
||||
rx_to_ig_init ();
|
||||
ig_to_tx_init ();
|
||||
|
@ -867,6 +873,10 @@ void igate_send_rec_packet (int chan, packet_t recv_pp)
|
|||
return; /* Login not complete. */
|
||||
}
|
||||
|
||||
/* Gather statistics. */
|
||||
|
||||
stats_rf_recv_packets++;
|
||||
|
||||
/*
|
||||
* Check for filtering from specified channel to the IGate server.
|
||||
*/
|
||||
|
@ -875,18 +885,18 @@ void igate_send_rec_packet (int chan, packet_t recv_pp)
|
|||
|
||||
if (pfilter(chan, MAX_CHANS, save_digi_config_p->filter_str[chan][MAX_CHANS], recv_pp) != 1) {
|
||||
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf ("Packet from channel %d to IGate was rejected by filter: %s\n", chan, save_digi_config_p->filter_str[chan][MAX_CHANS]);
|
||||
// Is this useful troubleshooting information or just distracting noise?
|
||||
// Originally this was always printed but there was a request to add a "quiet" option to suppress this.
|
||||
// version 1.4: Instead, make the default off and activate it only with the debug igate option.
|
||||
|
||||
if (s_debug >= 1) {
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf ("Packet from channel %d to IGate was rejected by filter: %s\n", chan, save_digi_config_p->filter_str[chan][MAX_CHANS]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Gather statistics. */
|
||||
|
||||
stats_rf_recv_packets++;
|
||||
|
||||
/*
|
||||
* First make a copy of it because it might be modified in place.
|
||||
*/
|
||||
|
@ -1080,7 +1090,7 @@ static void send_packet_to_server (packet_t pp, int chan)
|
|||
strlcat (msg, (char*)pinfo, sizeof(msg));
|
||||
|
||||
send_msg_to_server (msg);
|
||||
stats_rx_igate_packets++;
|
||||
stats_uplink_packets++;
|
||||
|
||||
/*
|
||||
* Remember what was sent to avoid duplicates in near future.
|
||||
|
@ -1329,6 +1339,8 @@ static void * igate_recv_thread (void *arg)
|
|||
ax25_safe_print ((char *)message, len, 0);
|
||||
dw_printf ("\n");
|
||||
|
||||
stats_downlink_packets++;
|
||||
|
||||
int to_chan = save_igate_config_p->tx_chan;
|
||||
|
||||
if (to_chan >= 0) {
|
||||
|
@ -1532,8 +1544,13 @@ static void xmit_packet (char *message, int to_chan)
|
|||
|
||||
if (pfilter(MAX_CHANS, to_chan, save_digi_config_p->filter_str[MAX_CHANS][to_chan], pp3) != 1) {
|
||||
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf ("Packet from IGate to channel %d was rejected by filter: %s\n", to_chan, save_digi_config_p->filter_str[MAX_CHANS][to_chan]);
|
||||
// Originally this was always printed but it's probably too much noise.
|
||||
// Version 1.4, print only if debug option is specified.
|
||||
|
||||
if (s_debug >= 1) {
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf ("Packet from IGate to channel %d was rejected by filter: %s\n", to_chan, save_digi_config_p->filter_str[MAX_CHANS][to_chan]);
|
||||
}
|
||||
|
||||
ax25_delete (pp3);
|
||||
return;
|
||||
|
@ -1599,8 +1616,6 @@ static void xmit_packet (char *message, int to_chan)
|
|||
|
||||
if (pradio != NULL) {
|
||||
|
||||
stats_tx_igate_packets++;
|
||||
|
||||
#if ITEST
|
||||
text_color_set(DW_COLOR_XMIT);
|
||||
dw_printf ("Xmit: %s\n", radio);
|
||||
|
@ -1609,7 +1624,12 @@ static void xmit_packet (char *message, int to_chan)
|
|||
/* This consumes packet so don't reference it again! */
|
||||
tq_append (to_chan, TQ_PRIO_1_LO, pradio);
|
||||
#endif
|
||||
stats_rf_xmit_packets++;
|
||||
stats_rf_xmit_packets++; // Any type of packet.
|
||||
|
||||
if (*pinfo == ':' && ! is_telem_metadata(pinfo)) {
|
||||
stats_msg_cnt++; // "message" be sure to exclude telemetry metadata.
|
||||
}
|
||||
|
||||
ig_to_tx_remember (pp3, save_igate_config_p->tx_chan, 0); // correct. version before encapsulating it.
|
||||
}
|
||||
else {
|
||||
|
@ -1701,6 +1721,7 @@ static void rx_to_ig_remember (packet_t pp)
|
|||
ax25_get_addr_with_ssid(pp, AX25_SOURCE, src);
|
||||
ax25_get_addr_with_ssid(pp, AX25_DESTINATION, dest);
|
||||
info_len = ax25_get_info (pp, &pinfo);
|
||||
(void)info_len;
|
||||
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("rx_to_ig_remember [%d] = %d %d \"%s>%s:%s\"\n",
|
||||
|
@ -1731,6 +1752,7 @@ static int rx_to_ig_allow (packet_t pp)
|
|||
ax25_get_addr_with_ssid(pp, AX25_SOURCE, src);
|
||||
ax25_get_addr_with_ssid(pp, AX25_DESTINATION, dest);
|
||||
info_len = ax25_get_info (pp, &pinfo);
|
||||
(void)info_len;
|
||||
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("rx_to_ig_allow? %d \"%s>%s:%s\"\n", crc, src, dest, pinfo);
|
||||
|
@ -1986,6 +2008,7 @@ void ig_to_tx_remember (packet_t pp, int chan, int bydigi)
|
|||
ax25_get_addr_with_ssid(pp, AX25_SOURCE, src);
|
||||
ax25_get_addr_with_ssid(pp, AX25_DESTINATION, dest);
|
||||
info_len = ax25_get_info (pp, &pinfo);
|
||||
(void)info_len;
|
||||
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("ig_to_tx_remember [%d] = ch%d d%d %d %d \"%s>%s:%s\"\n",
|
||||
|
@ -2012,16 +2035,20 @@ static int ig_to_tx_allow (packet_t pp, int chan)
|
|||
time_t now = time(NULL);
|
||||
int j;
|
||||
int count_1, count_5;
|
||||
int increase_limit;
|
||||
|
||||
unsigned char *pinfo;
|
||||
int info_len;
|
||||
|
||||
info_len = ax25_get_info (pp, &pinfo);
|
||||
(void)info_len;
|
||||
|
||||
if (s_debug >= 2) {
|
||||
char src[AX25_MAX_ADDR_LEN];
|
||||
char dest[AX25_MAX_ADDR_LEN];
|
||||
unsigned char *pinfo;
|
||||
int info_len;
|
||||
|
||||
ax25_get_addr_with_ssid(pp, AX25_SOURCE, src);
|
||||
ax25_get_addr_with_ssid(pp, AX25_DESTINATION, dest);
|
||||
info_len = ax25_get_info (pp, &pinfo);
|
||||
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("ig_to_tx_allow? ch%d %d \"%s>%s:%s\"\n", chan, crc, src, dest, pinfo);
|
||||
|
@ -2053,12 +2080,25 @@ static int ig_to_tx_allow (packet_t pp, int chan)
|
|||
}
|
||||
}
|
||||
|
||||
if (count_1 >= save_igate_config_p->tx_limit_1) {
|
||||
/* "Messages" (special APRS data type ":") are intentional and more */
|
||||
/* important than all of the other mostly repetitive useless junk */
|
||||
/* flowing thru here. */
|
||||
/* It would be unfortunate to discard a message because we already */
|
||||
/* hit our limit. I don't want to completely eliminate limiting for */
|
||||
/* messages, in case something goes terribly wrong, but we can triple */
|
||||
/* the normal limit for them. */
|
||||
|
||||
increase_limit = 1;
|
||||
if (*pinfo == ':' && ! is_telem_metadata((char*)pinfo)) {
|
||||
increase_limit = 3;
|
||||
}
|
||||
|
||||
if (count_1 >= save_igate_config_p->tx_limit_1 * increase_limit) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Tx IGate: Already transmitted maximum of %d packets in 1 minute.\n", save_igate_config_p->tx_limit_1);
|
||||
return 0;
|
||||
}
|
||||
if (count_5 >= save_igate_config_p->tx_limit_5) {
|
||||
if (count_5 >= save_igate_config_p->tx_limit_5 * increase_limit) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Tx IGate: Already transmitted maximum of %d packets in 5 minutes.\n", save_igate_config_p->tx_limit_5);
|
||||
return 0;
|
||||
|
|
19
igate.h
19
igate.h
|
@ -51,6 +51,11 @@ struct igate_config_s {
|
|||
/* Must start with "," if not empty so it can */
|
||||
/* simply be inserted after the destination address. */
|
||||
|
||||
int max_digi_hops; /* Maximum number of digipeater hops possible for via path. */
|
||||
/* e.g. "WIDE1-1,WDIE2-2" would be 3. */
|
||||
/* This is useful to know so we can determine how many */
|
||||
/* stations we might be able to reach. */
|
||||
|
||||
int tx_limit_1; /* Max. packets to transmit in 1 minute. */
|
||||
|
||||
int tx_limit_5; /* Max. packets to transmit in 5 minutes. */
|
||||
|
@ -84,4 +89,18 @@ void igate_send_rec_packet (int chan, packet_t recv_pp);
|
|||
|
||||
void ig_to_tx_remember (packet_t pp, int chan, int bydigi);
|
||||
|
||||
|
||||
|
||||
/* Get statistics for IGATE status beacon. */
|
||||
|
||||
int igate_get_msg_cnt (void);
|
||||
|
||||
int igate_get_pkt_cnt (void);
|
||||
|
||||
int igate_get_upl_cnt (void);
|
||||
|
||||
int igate_get_dnl_cnt (void);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
15
kiss.c
15
kiss.c
|
@ -112,12 +112,13 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if __WIN32__
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#define __USE_XOPEN2KXSI 1
|
||||
#define __USE_XOPEN 1
|
||||
|
@ -138,7 +139,7 @@
|
|||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include "tq.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
|
@ -241,17 +242,22 @@ void hex_dump (unsigned char *p, int len);
|
|||
*
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
static MYFDTYPE kiss_open_pt (void);
|
||||
#if __WIN32__
|
||||
static MYFDTYPE kiss_open_nullmodem (char *device);
|
||||
#else
|
||||
static MYFDTYPE kiss_open_pt (void);
|
||||
#endif
|
||||
|
||||
|
||||
void kiss_init (struct misc_config_s *mc)
|
||||
{
|
||||
int e;
|
||||
|
||||
#if __WIN32__
|
||||
HANDLE kiss_nullmodem_listen_th;
|
||||
#else
|
||||
pthread_t kiss_pterm_listen_tid;
|
||||
pthread_t kiss_nullmodem_listen_tid;
|
||||
int e;
|
||||
#endif
|
||||
|
||||
memset (&kf, 0, sizeof(kf));
|
||||
|
@ -635,7 +641,6 @@ void kiss_send_rec_packet (int chan, unsigned char *fbuf, int flen)
|
|||
{
|
||||
unsigned char kiss_buff[2 * AX25_MAX_PACKET_LEN + 2];
|
||||
int kiss_len;
|
||||
int j;
|
||||
int err;
|
||||
|
||||
#if ! __WIN32__
|
||||
|
|
19
kiss_frame.c
19
kiss_frame.c
|
@ -68,6 +68,8 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -75,7 +77,6 @@
|
|||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
#include "kiss_frame.h"
|
||||
|
@ -86,7 +87,7 @@
|
|||
void hex_dump (unsigned char *p, int len);
|
||||
|
||||
|
||||
static void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug);
|
||||
|
||||
|
||||
|
||||
#if KISSTEST
|
||||
|
@ -98,6 +99,10 @@ void text_color_set (dw_color_t c)
|
|||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -561,9 +566,15 @@ static void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug)
|
|||
break;
|
||||
|
||||
default:
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("KISS Invalid command %d\n", cmd);
|
||||
kiss_debug_print (FROM_CLIENT, NULL, kiss_msg, kiss_len);
|
||||
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf ("Troubleshooting tip:\n");
|
||||
dw_printf ("Use \"-d kn\" option on direwolf command line to observe\n");
|
||||
dw_printf ("all communication with the client application.\n");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -630,7 +641,7 @@ void kiss_debug_print (fromto_t fromto, char *special, unsigned char *pmsg, int
|
|||
#if KISSTEST
|
||||
|
||||
|
||||
main ()
|
||||
int main ()
|
||||
{
|
||||
unsigned char din[512];
|
||||
unsigned char kissed[520];
|
||||
|
|
55
kissnet.c
55
kissnet.c
|
@ -95,10 +95,12 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "direwolf.h" // Sets _WIN32_WINNT for XP API level needed by ws2tcpip.h
|
||||
|
||||
|
||||
#if __WIN32__
|
||||
#include <winsock2.h>
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#include <ws2tcpip.h>
|
||||
#include <ws2tcpip.h> // _WIN32_WINNT must be set to 0x0501 before including this
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -115,11 +117,9 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "tq.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
|
@ -128,6 +128,8 @@
|
|||
#include "kiss_frame.h"
|
||||
#include "xmit.h"
|
||||
|
||||
void hex_dump (unsigned char *p, int len); // This should be in a .h file.
|
||||
|
||||
|
||||
static kiss_frame_t kf; /* Accumulated KISS frame and state of decoder. */
|
||||
// TODO: multiple instances if multiple KISS network clients!
|
||||
|
@ -139,8 +141,15 @@ static int client_sock; /* File descriptor for socket for */
|
|||
/* (Don't use SOCKET type because it is unsigned.) */
|
||||
|
||||
|
||||
static void * connect_listen_thread (void *arg);
|
||||
static void * kissnet_listen_thread (void *arg);
|
||||
// TODO: define in one place, use everywhere.
|
||||
#if __WIN32__
|
||||
#define THREAD_F unsigned __stdcall
|
||||
#else
|
||||
#define THREAD_F void *
|
||||
#endif
|
||||
|
||||
static THREAD_F connect_listen_thread (void *arg);
|
||||
static THREAD_F kissnet_listen_thread (void *arg);
|
||||
|
||||
|
||||
|
||||
|
@ -184,8 +193,8 @@ void kissnet_init (struct misc_config_s *mc)
|
|||
#else
|
||||
pthread_t connect_listen_tid;
|
||||
pthread_t cmd_listen_tid;
|
||||
#endif
|
||||
int e;
|
||||
#endif
|
||||
int kiss_port = mc->kiss_port;
|
||||
|
||||
|
||||
|
@ -208,7 +217,7 @@ void kissnet_init (struct misc_config_s *mc)
|
|||
* This waits for a client to connect and sets client_sock.
|
||||
*/
|
||||
#if __WIN32__
|
||||
connect_listen_th = _beginthreadex (NULL, 0, connect_listen_thread, (void *)kiss_port, 0, NULL);
|
||||
connect_listen_th = (HANDLE)_beginthreadex (NULL, 0, connect_listen_thread, (void *)kiss_port, 0, NULL);
|
||||
if (connect_listen_th == NULL) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Could not create KISS socket connect listening thread\n");
|
||||
|
@ -227,7 +236,7 @@ void kissnet_init (struct misc_config_s *mc)
|
|||
* This reads messages from client when client_sock is valid.
|
||||
*/
|
||||
#if __WIN32__
|
||||
cmd_listen_th = _beginthreadex (NULL, 0, kissnet_listen_thread, NULL, 0, NULL);
|
||||
cmd_listen_th = (HANDLE)_beginthreadex (NULL, 0, kissnet_listen_thread, NULL, 0, NULL);
|
||||
if (cmd_listen_th == NULL) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Could not create KISS socket command listening thread\n");
|
||||
|
@ -263,7 +272,7 @@ void kissnet_init (struct misc_config_s *mc)
|
|||
*
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
static void * connect_listen_thread (void *arg)
|
||||
static THREAD_F connect_listen_thread (void *arg)
|
||||
{
|
||||
#if __WIN32__
|
||||
|
||||
|
@ -284,7 +293,7 @@ static void * connect_listen_thread (void *arg)
|
|||
if (err != 0) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf("WSAStartup failed: %d\n", err);
|
||||
return (NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wVersion) != 2) {
|
||||
|
@ -292,7 +301,7 @@ static void * connect_listen_thread (void *arg)
|
|||
dw_printf("Could not find a usable version of Winsock.dll\n");
|
||||
WSACleanup();
|
||||
//sleep (1);
|
||||
return (NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
memset (&hints, 0, sizeof(hints));
|
||||
|
@ -307,14 +316,14 @@ static void * connect_listen_thread (void *arg)
|
|||
dw_printf("getaddrinfo failed: %d\n", err);
|
||||
//sleep (1);
|
||||
WSACleanup();
|
||||
return (NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
listen_sock= socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (listen_sock == INVALID_SOCKET) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("connect_listen_thread: Socket creation failed, err=%d", WSAGetLastError());
|
||||
return (NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
@ -331,7 +340,7 @@ static void * connect_listen_thread (void *arg)
|
|||
freeaddrinfo(ai);
|
||||
closesocket(listen_sock);
|
||||
WSACleanup();
|
||||
return (NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
freeaddrinfo(ai);
|
||||
|
@ -353,7 +362,7 @@ static void * connect_listen_thread (void *arg)
|
|||
{
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf("Listen failed with error: %d\n", WSAGetLastError());
|
||||
return (NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
|
@ -366,7 +375,7 @@ static void * connect_listen_thread (void *arg)
|
|||
dw_printf("Accept failed with error: %d\n", WSAGetLastError());
|
||||
closesocket(listen_sock);
|
||||
WSACleanup();
|
||||
return (NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
|
@ -481,7 +490,6 @@ void kissnet_send_rec_packet (int chan, unsigned char *fbuf, int flen)
|
|||
{
|
||||
unsigned char kiss_buff[2 * AX25_MAX_PACKET_LEN];
|
||||
int kiss_len;
|
||||
int j;
|
||||
int err;
|
||||
|
||||
|
||||
|
@ -580,6 +588,7 @@ static int read_from_socket (int fd, char *ptr, int len)
|
|||
#if __WIN32__
|
||||
|
||||
//TODO: any flags for send/recv?
|
||||
//TODO: Would be useful to have more detailed explanation from the error code.
|
||||
|
||||
n = recv (fd, ptr + got_bytes, len - got_bytes, 0);
|
||||
#else
|
||||
|
@ -659,7 +668,7 @@ static int kiss_get (void)
|
|||
}
|
||||
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("\nError reading KISS byte from clent application. Closing connection.\n\n");
|
||||
dw_printf ("\nError reading KISS byte from client application. Closing connection.\n\n");
|
||||
#if __WIN32__
|
||||
closesocket (client_sock);
|
||||
#else
|
||||
|
@ -671,7 +680,7 @@ static int kiss_get (void)
|
|||
|
||||
|
||||
|
||||
static void * kissnet_listen_thread (void *arg)
|
||||
static THREAD_F kissnet_listen_thread (void *arg)
|
||||
{
|
||||
unsigned char ch;
|
||||
|
||||
|
@ -685,7 +694,11 @@ static void * kissnet_listen_thread (void *arg)
|
|||
kiss_rec_byte (&kf, ch, kiss_debug, kissnet_send_rec_packet);
|
||||
}
|
||||
|
||||
return (NULL); /* to suppress compiler warning. */
|
||||
#if __WIN32__
|
||||
return(0);
|
||||
#else
|
||||
return (THREAD_F) 0; /* Unreachable but avoids compiler warning. */
|
||||
#endif
|
||||
|
||||
} /* end kissnet_listen_thread */
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -40,7 +41,6 @@
|
|||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "latlong.h"
|
||||
#include "textcolor.h"
|
||||
|
||||
|
|
2
ll2utm.c
2
ll2utm.c
|
@ -1,5 +1,7 @@
|
|||
/* Latitude / Longitude to UTM conversion */
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
|
4
log.c
4
log.c
|
@ -31,6 +31,8 @@
|
|||
*
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
@ -42,8 +44,6 @@
|
|||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
#include "decode_aprs.h"
|
||||
|
|
|
@ -18,17 +18,12 @@
|
|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if __WIN32__
|
||||
char *strsep(char **stringp, const char *delim);
|
||||
#endif
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
|
||||
/*
|
||||
* Information we gather for each thing.
|
||||
|
|
|
@ -0,0 +1,331 @@
|
|||
//
|
||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||
//
|
||||
// Copyright (C) 2016 John Langner, WB2OSZ
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* File: mheard.c
|
||||
*
|
||||
* Purpose: Maintain a list of all stations heard.
|
||||
*
|
||||
* Description: This was added for IGate statistics but would also be
|
||||
* useful for the AGW network protocol 'H' request.
|
||||
*
|
||||
* This application has no GUI and is not interactive so
|
||||
* I'm not sure what else we might do with the information.
|
||||
*
|
||||
* Future Ideas: Someone suggested using SQLite to store the information
|
||||
* so other applications could access it.
|
||||
*
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "textcolor.h"
|
||||
#include "decode_aprs.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "hdlc_rec2.h" // for retry_t
|
||||
#include "mheard.h"
|
||||
|
||||
|
||||
// I think we can get away without a critical region if we follow certain rules.
|
||||
//
|
||||
// (1) All updates are from a single thread. Although there are multiple receive
|
||||
// threads, all received packets go into a single queue for serial processing.
|
||||
// (2) When adding a new node, make sure it is complete, including next ptr,
|
||||
// before adding it to the list.
|
||||
// (3) Nothing gets deleted.
|
||||
//
|
||||
// It shouldn't be a problem if the data readers are from other threads.
|
||||
|
||||
|
||||
/*
|
||||
* Information for each station heard over the radio.
|
||||
*/
|
||||
|
||||
typedef struct mheard_s {
|
||||
|
||||
struct mheard_s *pnext; // Pointer to next in list.
|
||||
|
||||
char callsign[AX25_MAX_ADDR_LEN]; // Callsign from the AX.25 source field.
|
||||
|
||||
int num_digi_hops; // Number of digipeater hops before we heard it.
|
||||
// Zero when heard directly.
|
||||
|
||||
time_t last_heard; // Timestamp when last heard.
|
||||
|
||||
// What else would be useful?
|
||||
// The AGW protocol is by channel and returns
|
||||
// first heard in addition to last heard.
|
||||
} mheard_t;
|
||||
|
||||
/*
|
||||
* The list could be quite long and we hit this a lot so use a hash table.
|
||||
*/
|
||||
|
||||
#define MHEARD_HASH_SIZE 73 // Best if prime number.
|
||||
|
||||
static mheard_t *mheard_hash[MHEARD_HASH_SIZE];
|
||||
|
||||
static inline int hash_index(char *callsign) {
|
||||
int n = 0;
|
||||
char *p = callsign;
|
||||
|
||||
while (*p != '\0') {
|
||||
n += *p++;
|
||||
}
|
||||
return (n % MHEARD_HASH_SIZE);
|
||||
}
|
||||
|
||||
static mheard_t *mheard_ptr(char *callsign) {
|
||||
int n = hash_index(callsign);
|
||||
mheard_t *p = mheard_hash[n];
|
||||
|
||||
while (p != NULL) {
|
||||
if (strcmp(callsign,p->callsign) == 0) return (p);
|
||||
p = p->pnext;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
static int mheard_debug;
|
||||
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* Function: mheard_init
|
||||
*
|
||||
* Purpose: Initialization at start of application.
|
||||
*
|
||||
* Inputs: debug - Debug level.
|
||||
*
|
||||
* Description: Clear pointer table.
|
||||
* Save debug level for later use.
|
||||
*
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
|
||||
void mheard_init (int debug)
|
||||
{
|
||||
int i;
|
||||
|
||||
mheard_debug = debug;
|
||||
|
||||
for (i = 0; i < MHEARD_HASH_SIZE; i++) {
|
||||
mheard_hash[i] = NULL;
|
||||
}
|
||||
|
||||
} /* end mheard_init */
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* Function: mheard_save
|
||||
*
|
||||
* Purpose: Save information about station heard.
|
||||
*
|
||||
* Inputs: chan - Radio channel where heard.
|
||||
*
|
||||
* A - Exploded information from APRS packet.
|
||||
*
|
||||
* pp - Received packet object.
|
||||
*
|
||||
* alevel - audio level.
|
||||
*
|
||||
* retries - Amount of effort to get a good CRC.
|
||||
*
|
||||
* Description: Calling sequence was copied from "log_write."
|
||||
* It has a lot more than what we currently keep but the
|
||||
* hooks are there so it will be easy to capture additional
|
||||
* information when the need arises.
|
||||
*
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
void mheard_save (int chan, decode_aprs_t *A, packet_t pp, alevel_t alevel, retry_t retries)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
char source[AX25_MAX_ADDR_LEN];
|
||||
int hops;
|
||||
mheard_t *mptr;
|
||||
|
||||
ax25_get_addr_with_ssid (pp, AX25_SOURCE, source);
|
||||
|
||||
/*
|
||||
* How many digipeaters has it gone thru before we hear it?
|
||||
* We can count the number of digi addresses that are marked as "has been used."
|
||||
* This is not always accurate because there is inconsistency in digipeater behavior.
|
||||
* The base AX.25 spec seems clear in this regard. The used digipeaters should
|
||||
* should accurately reflict the path taken by the packet. Sometimes we see excess
|
||||
* stuff in there. Even when you understand what is going on, it is still an ambiguous
|
||||
* situation. Look for my rant in the User Guide.
|
||||
*/
|
||||
|
||||
hops = ax25_get_heard(pp) - AX25_SOURCE;
|
||||
|
||||
mptr = mheard_ptr(source);
|
||||
if (mptr == NULL) {
|
||||
int i;
|
||||
/*
|
||||
* Not heard before. Add it.
|
||||
*/
|
||||
|
||||
if (mheard_debug) {
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("mheard_save: %s %d - added new\n", source, hops);
|
||||
}
|
||||
|
||||
mptr = calloc(sizeof(mheard_t),1);
|
||||
strlcpy (mptr->callsign, source, sizeof(mptr->callsign));
|
||||
mptr->num_digi_hops = hops;
|
||||
mptr->last_heard = now;
|
||||
|
||||
i = hash_index(source);
|
||||
|
||||
mptr->pnext = mheard_hash[i]; // before inserting into list.
|
||||
mheard_hash[i] = mptr;
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
* Update existing entry.
|
||||
* The only tricky part here is that we might hear the same transmission
|
||||
* several times. First direct, then thru various digipeater paths.
|
||||
* We are interested in the shortest path if heard very recently.
|
||||
*/
|
||||
|
||||
if (hops > mptr->num_digi_hops && (int)(now - mptr->last_heard) < 15) {
|
||||
|
||||
if (mheard_debug) {
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("mheard_save: %s %d - skip because hops was %d %d seconds ago.\n", source, hops, mptr->num_digi_hops, (int)(now - mptr->last_heard) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (mheard_debug) {
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("mheard_save: %s %d - update time, was %d hops %d seconds ago.\n", source, hops, mptr->num_digi_hops, (int)(now - mptr->last_heard));
|
||||
}
|
||||
|
||||
mptr->num_digi_hops = hops;
|
||||
mptr->last_heard = now;
|
||||
}
|
||||
}
|
||||
|
||||
if (mheard_debug >= 2) {
|
||||
int limit = 10; // normally 30 or 60
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("mheard debug, %d min, DIR_CNT=%d,LOC_CNT=%d,RF_CNT=%d\n", limit, mheard_count(0,limit), mheard_count(2,limit), mheard_count(8,limit));
|
||||
}
|
||||
|
||||
} /* end mheard_save */
|
||||
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* Function: mheard_count
|
||||
*
|
||||
* Purpose: Count local stations for IGate statistics report like this:
|
||||
*
|
||||
* <IGATE,MSG_CNT=1,LOC_CNT=25
|
||||
*
|
||||
* Inputs: max_hops - Include only stations heard with this number of
|
||||
* digipeater hops or less. For reporting, we might use:
|
||||
*
|
||||
* 0 for DIR_CNT (heard directly)
|
||||
* IGate transmit path for LOC_CNT.
|
||||
* e.g. 3 for WIDE1-1,WIDE2-2
|
||||
* 8 for RF_CNT.
|
||||
*
|
||||
* time_limit - Include only stations heard within this many minutes.
|
||||
* Typically 30 or 60.
|
||||
*
|
||||
* Returns: Number to be used in the statistics report.
|
||||
*
|
||||
* Description: Look for discussion here: http://www.tapr.org/pipermail/aprssig/2016-June/045837.html
|
||||
*
|
||||
* Lynn KJ4ERJ:
|
||||
*
|
||||
* For APRSISCE/32, "Local" is defined as those stations to which messages
|
||||
* would be gated if any are received from the APRS-IS. This currently
|
||||
* means unique stations heard within the past 30 minutes with at most two
|
||||
* used path hops.
|
||||
*
|
||||
* I added DIR_CNT and RF_CNT with comma delimiters to APRSISCE/32's IGate
|
||||
* status. DIR_CNT is the count of unique stations received on RF in the
|
||||
* past 30 minutes with no used hops. RF_CNT is the total count of unique
|
||||
* stations received on RF in the past 30 minutes.
|
||||
*
|
||||
* Steve K4HG:
|
||||
*
|
||||
* The number of hops defining local should match the number of hops of the
|
||||
* outgoing packets from the IGate. So if the path is only WIDE, then local
|
||||
* should only be stations heard direct or through one hop. From the beginning
|
||||
* I was very much against on a standardization of the outgoing IGate path,
|
||||
* hams should be free to manage their local RF network in a way that works
|
||||
* for them. Busy areas one hop may be best, I lived in an area where three was
|
||||
* a much better choice. I avoided as much as possible prescribing anything
|
||||
* that might change between locations.
|
||||
*
|
||||
* The intent was how many stations are there for which messages could be IGated.
|
||||
* IGate software keeps an internal list of the 'local' stations so it knows
|
||||
* when to IGate a message, and this number should be the length of that list.
|
||||
* Some IGates have a parameter for local timeout, 1 hour was the original default,
|
||||
* so if in an hour the IGate has not heard another local packet the station is
|
||||
* dropped from the local list. Messages will no longer be IGated to that station
|
||||
* and the station count would drop by one. The number should not just continue to rise.
|
||||
*
|
||||
*
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
int mheard_count (int max_hops, int time_limit)
|
||||
{
|
||||
time_t since = time(NULL) - time_limit * 60;
|
||||
int count = 0;
|
||||
int i;
|
||||
mheard_t *p;
|
||||
|
||||
for (i = 0; i < MHEARD_HASH_SIZE; i++) {
|
||||
for (p = mheard_hash[i]; p != NULL; p = p->pnext) {
|
||||
if (p->last_heard >= since && p->num_digi_hops <= max_hops) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mheard_debug == 1) {
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("mheard_count(<= %d digi hops, last %d minutes) returns %d\n", max_hops, time_limit, count);
|
||||
}
|
||||
|
||||
return (count);
|
||||
|
||||
} /* end mheard_count */
|
||||
|
||||
|
||||
/* end mheard.c */
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
|
||||
/* mheard.h */
|
||||
|
||||
void mheard_init (int debug);
|
||||
|
||||
void mheard_save (int chan, decode_aprs_t *A, packet_t pp, alevel_t alevel, retry_t retries);
|
||||
|
||||
int mheard_count (int max_hops, int time_limit);
|
4
morse.c
4
morse.c
|
@ -30,6 +30,8 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -39,8 +41,6 @@
|
|||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "textcolor.h"
|
||||
#include "audio.h"
|
||||
#include "ptt.h"
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
//#define DEBUG 1
|
||||
#define DIGIPEATER_C
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -81,7 +82,6 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
#include "multi_modem.h"
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
@ -45,11 +46,6 @@
|
|||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if __WIN32__
|
||||
char *strsep(char **stringp, const char *delim);
|
||||
#endif
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
#include "decode_aprs.h"
|
||||
|
@ -622,7 +618,7 @@ static int filt_bodgu (pfstate_t *pf, char *arg)
|
|||
/* Telemetry metadata is a special case of message. */
|
||||
/* We want to categorize it as telemetry rather than message. */
|
||||
|
||||
static int is_telem_metadata (char *infop)
|
||||
int is_telem_metadata (char *infop)
|
||||
{
|
||||
if (*infop != ':') return (0);
|
||||
if (strlen(infop) < 16) return (0);
|
||||
|
|
|
@ -2,3 +2,5 @@
|
|||
/* pfilter.h */
|
||||
|
||||
int pfilter (int from_chan, int to_chan, char *filter, packet_t pp);
|
||||
|
||||
int is_telem_metadata (char *infop);
|
5
ptt.c
5
ptt.c
|
@ -94,6 +94,9 @@
|
|||
Maybe even for Windows. ;-)
|
||||
*/
|
||||
|
||||
|
||||
#include "direwolf.h" // should be first. This includes windows.h.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -102,7 +105,6 @@
|
|||
#include <time.h>
|
||||
|
||||
#if __WIN32__
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
@ -122,7 +124,6 @@ typedef int HANDLE;
|
|||
|
||||
#endif
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "textcolor.h"
|
||||
#include "audio.h"
|
||||
#include "ptt.h"
|
||||
|
|
3
rdq.c
3
rdq.c
|
@ -29,13 +29,14 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
#include "audio.h"
|
||||
|
|
2
recv.c
2
recv.c
|
@ -82,6 +82,7 @@
|
|||
|
||||
//#define DEBUG 1
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
@ -97,7 +98,6 @@
|
|||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "audio.h"
|
||||
#include "demod.h"
|
||||
#include "multi_modem.h"
|
||||
|
|
255
redecode.c
255
redecode.c
|
@ -1,255 +0,0 @@
|
|||
//
|
||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||
//
|
||||
// Copyright (C) 2011, 2012, 2013, 2015 John Langner, WB2OSZ
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* Module: redecode.c
|
||||
*
|
||||
* Purpose: Retry decoding frames that have a bad FCS.
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
*
|
||||
* Usage: (1) The main application calls redecode_init.
|
||||
*
|
||||
* This will initialize the retry decoding queue
|
||||
* and create a thread to work on contents of the queue.
|
||||
*
|
||||
* (2) The application queues up frames by calling rdq_append.
|
||||
*
|
||||
*
|
||||
* (3) redecode_thread removes raw frames from the queue and
|
||||
* tries to recover from errors.
|
||||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#if __WIN32__
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
#include "audio.h"
|
||||
#include "rdq.h"
|
||||
#include "redecode.h"
|
||||
#include "hdlc_send.h"
|
||||
#include "hdlc_rec2.h"
|
||||
#include "ptt.h"
|
||||
|
||||
|
||||
/* Audio configuration for the fix_bits / passall optiions. */
|
||||
|
||||
static struct audio_s *save_audio_config_p;
|
||||
|
||||
|
||||
|
||||
#if __WIN32__
|
||||
static unsigned redecode_thread (void *arg);
|
||||
#else
|
||||
static void * redecode_thread (void *arg);
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
*
|
||||
* Name: redecode_init
|
||||
*
|
||||
* Purpose: Initialize the process to try fixing bits in frames with bad FCS.
|
||||
*
|
||||
* Inputs: none.
|
||||
*
|
||||
* Outputs: none.
|
||||
*
|
||||
* Description: Initialize the queue to be empty and set up other
|
||||
* mechanisms for sharing it between different threads.
|
||||
*
|
||||
* Start up redecode_thread to actually process the
|
||||
* raw frames from the queue.
|
||||
*
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
|
||||
void redecode_init (struct audio_s *p_audio_config)
|
||||
{
|
||||
|
||||
#if 0
|
||||
|
||||
#if __WIN32__
|
||||
HANDLE redecode_th;
|
||||
#else
|
||||
pthread_t redecode_tid;
|
||||
int e;
|
||||
#endif
|
||||
|
||||
|
||||
#if DEBUG
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("redecode_init ( ... )\n");
|
||||
#endif
|
||||
|
||||
save_audio_config_p = p_audio_config;
|
||||
|
||||
#if DEBUG
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("redecode_init: about to call rdq_init \n");
|
||||
#endif
|
||||
rdq_init ();
|
||||
|
||||
#if DEBUG
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("redecode_init: about to create thread \n");
|
||||
#endif
|
||||
|
||||
|
||||
#if __WIN32__
|
||||
redecode_th = _beginthreadex (NULL, 0, redecode_thread, NULL, 0, NULL);
|
||||
if (redecode_th == NULL) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Could not create redecode thread\n");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
|
||||
//TODO: Give thread lower priority.
|
||||
|
||||
e = pthread_create (&redecode_tid, NULL, redecode_thread, (void *)0);
|
||||
if (e != 0) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
perror("Could not create redecode thread");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if DEBUG
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("redecode_init: finished \n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} /* end redecode_init */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
*
|
||||
* Name: redecode_thread
|
||||
*
|
||||
* Purpose: Try to decode frames with a bad FCS.
|
||||
*
|
||||
* Inputs: None.
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
* Description: Initialize the queue to be empty and set up other
|
||||
* mechanisms for sharing it between different threads.
|
||||
*
|
||||
*
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
#if 0
|
||||
|
||||
#if __WIN32__
|
||||
static unsigned redecode_thread (void *arg)
|
||||
#else
|
||||
static void * redecode_thread (void *arg)
|
||||
#endif
|
||||
{
|
||||
#if __WIN32__
|
||||
HANDLE tid = GetCurrentThread();
|
||||
//int tp;
|
||||
|
||||
//tp = GetThreadPriority (tid);
|
||||
//text_color_set(DW_COLOR_DEBUG);
|
||||
//dw_printf ("Starting redecode thread priority=%d\n", tp);
|
||||
SetThreadPriority (tid, THREAD_PRIORITY_LOWEST);
|
||||
//tp = GetThreadPriority (tid);
|
||||
//dw_printf ("New redecode thread priority=%d\n", tp);
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
rrbb_t block;
|
||||
|
||||
rdq_wait_while_empty ();
|
||||
#if DEBUG
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("redecode_thread: woke up\n");
|
||||
#endif
|
||||
|
||||
block = rdq_remove ();
|
||||
|
||||
#if DEBUG
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("redecode_thread: rdq_remove() returned %p\n", block);
|
||||
#endif
|
||||
|
||||
/* Don't expect null ever but be safe. */
|
||||
|
||||
if (block != NULL) {
|
||||
|
||||
int chan = rrbb_get_chan(block);
|
||||
int subchan = rrbb_get_subchan(block);
|
||||
int blen = rrbb_get_len(block);
|
||||
alevel_t alevel = rrbb_get_audio_level(block);
|
||||
//retry_t fix_bits = save_audio_config_p->achan[chan].fix_bits;
|
||||
//int passall = save_audio_config_p->achan[chan].passall;
|
||||
|
||||
int ok;
|
||||
|
||||
#if DEBUG
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("redecode_thread: begin processing %p, from channel %d, blen=%d\n", block, chan, blen);
|
||||
#endif
|
||||
|
||||
ok = hdlc_rec2_try_to_fix_later (block, chan, subchan, alevel);
|
||||
|
||||
#if DEBUG
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
dw_printf ("redecode_thread: finished processing %p\n", block);
|
||||
#endif
|
||||
rrbb_delete (block);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
} /* end redecode_thread */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* end redecode.c */
|
||||
|
||||
|
||||
|
3
rrbb.c
3
rrbb.c
|
@ -35,12 +35,13 @@
|
|||
|
||||
#define RRBB_C
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "textcolor.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "rrbb.h"
|
||||
|
|
|
@ -34,12 +34,13 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h" // should be first
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if __WIN32__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
|
||||
#else
|
||||
|
||||
|
@ -58,7 +59,7 @@
|
|||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include "textcolor.h"
|
||||
#include "serial_port.h"
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#if __WIN32__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
|
||||
typedef HANDLE MYFDTYPE;
|
||||
#define MYFDERROR INVALID_HANDLE_VALUE
|
||||
|
|
57
server.c
57
server.c
|
@ -121,11 +121,11 @@
|
|||
* Cygwin: Can use either one.
|
||||
*/
|
||||
|
||||
#include "direwolf.h" // Sets _WIN32_WINNT for XP API level needed by ws2tcpip.h
|
||||
|
||||
#if __WIN32__
|
||||
#include <winsock2.h>
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#include <ws2tcpip.h>
|
||||
#include <ws2tcpip.h> // _WIN32_WINNT must be set to 0x0501 before including this
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -146,7 +146,6 @@
|
|||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "tq.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
|
@ -861,6 +860,7 @@ void server_send_rec_packet (int chan, packet_t pp, unsigned char *fbuf, int fl
|
|||
|
||||
time_t clock;
|
||||
struct tm *tm;
|
||||
int num_digi;
|
||||
|
||||
clock = time(NULL);
|
||||
tm = localtime(&clock); // TODO: should use localtime_r
|
||||
|
@ -885,13 +885,46 @@ void server_send_rec_packet (int chan, packet_t pp, unsigned char *fbuf, int fl
|
|||
/* The documentation example includes these 3 extra in the Len= value */
|
||||
/* but actual observed data uses only the packet info length. */
|
||||
|
||||
snprintf (agwpe_msg.data, sizeof(agwpe_msg.data), " %d:Fm %s To %s <UI pid=%02X Len=%d >[%02d:%02d:%02d]\r%s\r\r",
|
||||
// Documentation doesn't mention anything about including the via path.
|
||||
// In version 1.4, we add that to match observed behaviour.
|
||||
|
||||
// This inconsistency was reported:
|
||||
// Direwolf:
|
||||
// [AGWE-IN] 1:Fm ZL4FOX-8 To Q7P2U2 [08:25:07]`I1*l V>/"9<}[:Barts Tracker 3.83V X
|
||||
// AGWPE:
|
||||
// [AGWE-IN] 1:Fm ZL4FOX-8 To Q7P2U2 Via WIDE3-3 [08:32:14]`I0*l V>/"98}[:Barts Tracker 3.83V X
|
||||
|
||||
num_digi = ax25_get_num_repeaters(pp);
|
||||
|
||||
if (num_digi > 0) {
|
||||
|
||||
char via[AX25_MAX_REPEATERS*(AX25_MAX_ADDR_LEN+1)];
|
||||
char stemp[AX25_MAX_ADDR_LEN+1];
|
||||
int j;
|
||||
|
||||
ax25_get_addr_with_ssid (pp, AX25_REPEATER_1, via);
|
||||
for (j = 1; j < num_digi; j++) {
|
||||
ax25_get_addr_with_ssid (pp, AX25_REPEATER_1 + j, stemp);
|
||||
strlcat (via, ",", sizeof(via));
|
||||
strlcat (via, stemp, sizeof(via));
|
||||
}
|
||||
|
||||
snprintf (agwpe_msg.data, sizeof(agwpe_msg.data), " %d:Fm %s To %s Via %s <UI pid=%02X Len=%d >[%02d:%02d:%02d]\r%s\r\r",
|
||||
chan+1, agwpe_msg.hdr.call_from, agwpe_msg.hdr.call_to, via,
|
||||
ax25_get_pid(pp), info_len,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec,
|
||||
pinfo);
|
||||
}
|
||||
else {
|
||||
|
||||
snprintf (agwpe_msg.data, sizeof(agwpe_msg.data), " %d:Fm %s To %s <UI pid=%02X Len=%d >[%02d:%02d:%02d]\r%s\r\r",
|
||||
chan+1, agwpe_msg.hdr.call_from, agwpe_msg.hdr.call_to,
|
||||
ax25_get_pid(pp), info_len,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec,
|
||||
pinfo);
|
||||
}
|
||||
|
||||
agwpe_msg.hdr.data_len_NETLE = host2netle(strlen(agwpe_msg.data) + 1) /* include null */ ;
|
||||
agwpe_msg.hdr.data_len_NETLE = host2netle(strlen(agwpe_msg.data) + 1) /* +1 to include terminating null */ ;
|
||||
|
||||
if (debug_client) {
|
||||
debug_print (TO_CLIENT, client, &agwpe_msg.hdr, sizeof(agwpe_msg.hdr) + netle2host(agwpe_msg.hdr.data_len_NETLE));
|
||||
|
@ -1383,10 +1416,14 @@ static THREAD_F cmd_listen_thread (void *arg)
|
|||
break;
|
||||
|
||||
|
||||
case 'H': /* Ask about recently heard stations. */
|
||||
case 'H': /* Ask about recently heard stations on given port. */
|
||||
|
||||
/* This should send back 20 'H' frames for the most recently heard stations. */
|
||||
/* If there are less available, empty frames are sent to make a total of 20. */
|
||||
/* Each contains the first and last heard times. */
|
||||
|
||||
{
|
||||
#if 0 /* This information is not being collected. */
|
||||
#if 0 /* Currently, this information is not being collected. */
|
||||
struct {
|
||||
struct agwpe_s hdr;
|
||||
char info[100];
|
||||
|
@ -1400,7 +1437,8 @@ static THREAD_F cmd_listen_thread (void *arg)
|
|||
|
||||
reply.hdr.portx = cmd.hdr.portx
|
||||
|
||||
strlcpy (reply.hdr.call_from, "WB2OSZ-15", sizeof(reply.hdr.call_from));
|
||||
strlcpy (reply.hdr.call_from, "WB2OSZ-15 Mon,01Jan2000 01:02:03 Tue,31Dec2099 23:45:56", sizeof(reply.hdr.call_from));
|
||||
// or 00:00:00 00:00:00
|
||||
|
||||
strlcpy (agwpe_msg.data, ..., sizeof(agwpe_msg.data));
|
||||
|
||||
|
@ -1640,6 +1678,7 @@ static THREAD_F cmd_listen_thread (void *arg)
|
|||
#if NEW14
|
||||
dlq_connect_request (callsigns, num_calls, cmd.hdr.portx, client, pid);
|
||||
#else
|
||||
(void)pid; // suppress unused variable message.
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("\n");
|
||||
dw_printf ("Can't process command '%c' from AGW client app %d.\n", cmd.hdr.datakind, client);
|
||||
|
@ -1660,6 +1699,7 @@ static THREAD_F cmd_listen_thread (void *arg)
|
|||
#if NEW14
|
||||
dlq_xmit_data_request (callsigns, num_calls, cmd.hdr.portx, client, cmd.hdr.pid, cmd.data, netle2host(cmd.hdr.data_len_NETLE));
|
||||
#else
|
||||
(void)num_calls; // suppress unused variable warning.
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("\n");
|
||||
dw_printf ("Can't process command '%c' from AGW client app %d.\n", cmd.hdr.datakind, client);
|
||||
|
@ -1679,6 +1719,7 @@ static THREAD_F cmd_listen_thread (void *arg)
|
|||
#if NEW14
|
||||
dlq_disconnect_request (callsigns, num_calls, cmd.hdr.portx, client);
|
||||
#else
|
||||
(void)num_calls; // suppress unused variable warning.
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("\n");
|
||||
dw_printf ("Can't process command '%c' from AGW client app %d.\n", cmd.hdr.datakind, client);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
APRS SYMBOL OVERLAY and EXTENSION TABLES in APRS 1.2 29 Oct 2015
|
||||
APRS SYMBOL OVERLAY and EXTENSION TABLES in APRS 1.2 22 Mar 2016
|
||||
---------------------------------------------------------------------
|
||||
|
||||
BACKGROUND: This file addresses new additions proposals (OVERLAYS)
|
||||
|
@ -7,7 +7,11 @@ document remains on the www.aprs.org/symbols/symbolsX.txt page, but
|
|||
only has one line per symbol character. Since each of the symbols
|
||||
can have up to 36 overlays, this gives us thousands of symbols codes.
|
||||
|
||||
|
||||
22 Mar 2016: Added A0 overlay circle for ALSTAR nodes
|
||||
and V0 for VOIP combined echolink and IRLP
|
||||
and P& for PSKmail node
|
||||
and W& for Wirese-X as opposed to W0 for WiresII
|
||||
and Ya for Yaesu C4FM repeaters
|
||||
Update 29 Oct 2015: Reorgainized list to Alphabetical Order.
|
||||
+ Added many new Balloons (due to lost DoD radar Blimp yesterday)
|
||||
+ Confirmed D^ for Drones was already in there since 2014
|
||||
|
@ -164,6 +168,7 @@ Ga = RSGB Radio Society of Great Brittan
|
|||
Ra = RACES
|
||||
Sa = SATERN Salvation Army
|
||||
Wa = WinLink
|
||||
Ya = C4FM Yaesu repeaters
|
||||
|
||||
BALLOONS and lighter than air #O (All new Oct 2015)
|
||||
/O = Original Balloon (think Ham balloon)
|
||||
|
@ -240,7 +245,9 @@ GATEWAYS: #&
|
|||
/& = HF Gateway <= the original primary table definition
|
||||
I& = Igate Generic (please use more specific overlay)
|
||||
R& = Receive only IGate (do not send msgs back to RF)
|
||||
P& = PSKmail node
|
||||
T& = TX igate with path set to 1 hop only)
|
||||
W& = WIRES-X as opposed to W0 for WiresII
|
||||
2& = TX igate with path set to 2 hops (not generally good idea)
|
||||
|
||||
GPS devices: #\
|
||||
|
@ -287,9 +294,11 @@ P' = Pileup
|
|||
T' = Truck wreck
|
||||
|
||||
NUMBERED CIRCLES: #0
|
||||
A0 = Allstar Node (A0)
|
||||
E0 = Echolink Node (E0)
|
||||
I0 = IRLP repeater (I0)
|
||||
S0 = Staging Area (S0)
|
||||
V0 = Echolink and IRLP (VOIP)
|
||||
W0 = WIRES (Yaesu VOIP)
|
||||
|
||||
NETWORK NODES: #8
|
||||
|
|
|
@ -26,22 +26,19 @@
|
|||
*
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "textcolor.h"
|
||||
#include "symbols.h"
|
||||
#include "tt_text.h"
|
||||
|
||||
|
||||
//#if __WIN32__
|
||||
char *strcasestr(const char *S, const char *FIND);
|
||||
//#endif
|
||||
|
||||
/*
|
||||
* APRS symbol tables.
|
||||
*
|
||||
|
|
11
telemetry.c
11
telemetry.c
|
@ -25,10 +25,10 @@
|
|||
|
||||
#if TEST
|
||||
|
||||
#define DEBUG1 1
|
||||
#define DEBUG2 1
|
||||
#define DEBUG3 1
|
||||
#define DEBUG4 1
|
||||
#define DEBUG1 1 // Activate debug out when testing.
|
||||
#define DEBUG2 1 //
|
||||
#define DEBUG3 1 //
|
||||
#define DEBUG4 1 //
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -49,6 +49,8 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -57,7 +59,6 @@
|
|||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h" // for packet_t, AX25_MAX_ADDR_LEN
|
||||
#include "decode_aprs.h" // for decode_aprs_t, G_UNKNOWN
|
||||
#include "textcolor.h"
|
||||
|
|
|
@ -74,6 +74,8 @@
|
|||
*--------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "direwolf.h" // Should be first. includes windows.h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -81,8 +83,6 @@
|
|||
|
||||
#if __WIN32__
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define BACKGROUND_WHITE (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY)
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
APRS TO-CALL VERSION NUMBERS 21 Jan 2016
|
||||
APRS TO-CALL VERSION NUMBERS 29 Apr 2016
|
||||
-------------------------------------------------------------------
|
||||
WB4APR
|
||||
29 Apr 16 added APFPRS for FreeDV by Jeroen PE1RXQ
|
||||
25 Feb 16 Added APCDS0 for Leon Lessing ZS6LMG's cell tracker
|
||||
21 Jan 16 added APDNOx for APRSduino by DO3SWW
|
||||
18 Nov 15 Added APSTPO for N0AGI
|
||||
03 Nov 15 Updated APAND1 and APDRxx for androids
|
||||
|
@ -76,6 +78,7 @@ a TOCALL number series:
|
|||
APF APFxxx Firenet
|
||||
APFGxx Flood Gage (KP4DJT)
|
||||
APFIxx for APRS.FI OH7LZB, Hessu
|
||||
APFPRS for FreeDV by Jeroen PE1RXQ
|
||||
APG APGxxx Gates, etc
|
||||
APGOxx for AA3NJ PDA application
|
||||
APH APHKxx for LA1BR tracker/digipeater
|
||||
|
|
3
tq.c
3
tq.c
|
@ -35,13 +35,14 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
#include "audio.h"
|
||||
|
|
|
@ -154,6 +154,7 @@ static const char grid[10][10][3] =
|
|||
{ "PH", "QH", "OG", "PG", "QG", "OF", "PF", "QF", "RF", "RE" }, // 8 - Aus / NZ
|
||||
{ "IL", "IK", "IJ", "JJ", "JI", "JH", "JG", "KG", "JF", "KF" } }; // 9 - Africa
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -162,7 +163,6 @@ static const char grid[10][10][3] =
|
|||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "textcolor.h"
|
||||
#include "tt_text.h"
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
@ -42,7 +44,6 @@
|
|||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "version.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
|
|
6
ttcalc.c
6
ttcalc.c
|
@ -45,12 +45,12 @@
|
|||
*---------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "direwolf.h" // Sets _WIN32_WINNT for XP API level needed by ws2tcpip.h
|
||||
|
||||
#if __WIN32__
|
||||
|
||||
#include <winsock2.h>
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501 /* Minimum OS version is XP. */
|
||||
#include <ws2tcpip.h>
|
||||
#include <ws2tcpip.h> // _WIN32_WINNT must be set to 0x0501 before including this
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <netdb.h>
|
||||
|
|
2
utm2ll.c
2
utm2ll.c
|
@ -1,5 +1,6 @@
|
|||
/* UTM to Latitude / Longitude conversion */
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -7,7 +8,6 @@
|
|||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "utm.h"
|
||||
#include "mgrs.h"
|
||||
#include "usng.h"
|
||||
|
|
3
walk96.c
3
walk96.c
|
@ -30,6 +30,8 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -37,7 +39,6 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "config.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "textcolor.h"
|
||||
|
|
11
waypoint.c
11
waypoint.c
|
@ -29,12 +29,15 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "direwolf.h" // should be first
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if __WIN32__
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#define __USE_XOPEN2KXSI 1
|
||||
#define __USE_XOPEN 1
|
||||
|
@ -48,7 +51,7 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "textcolor.h"
|
||||
#include "latlong.h"
|
||||
|
@ -443,7 +446,7 @@ void waypoint_send_sentence (char *name_in, double dlat, double dlong, char symt
|
|||
* GPS Status A = active, V = void.
|
||||
* It looks like this might be modeled after the GPS status values
|
||||
* we see in $GPRMC. i.e. Does the transceiver know its location?
|
||||
* I don’t see how that information would be relevant in this context.
|
||||
* I don't see how that information would be relevant in this context.
|
||||
* I've observed this under various conditions (No GPS, GPS with/without
|
||||
* fix) and it has always been "V."
|
||||
* (There is some information out there indicating this field
|
||||
|
@ -524,7 +527,7 @@ void waypoint_send_sentence (char *name_in, double dlat, double dlong, char symt
|
|||
char ken_sym; /* APRS symbol with , or * substituted. */
|
||||
|
||||
now = time(NULL);
|
||||
gmtime_r (&now, &tm);
|
||||
(void)gmtime_r (&now, &tm);
|
||||
strftime (stime, sizeof(stime), "%H%M%S", &tm);
|
||||
strftime (sdate, sizeof(sdate), "%d%m%y", &tm);
|
||||
|
||||
|
|
2
xid.c
2
xid.c
|
@ -44,12 +44,12 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "direwolf.h"
|
||||
#include "textcolor.h"
|
||||
//#include "xid.h"
|
||||
|
||||
|
|
7
xmit.c
7
xmit.c
|
@ -51,6 +51,8 @@
|
|||
*
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
#include "direwolf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -615,6 +617,7 @@ static void xmit_ax25_frames (int c, int p, packet_t pp)
|
|||
int ns;
|
||||
|
||||
ftype = ax25_frame_type (pp, &cr, desc, &pf, &nr, &ns);
|
||||
(void)ftype;
|
||||
|
||||
dw_printf ("(%s)", desc);
|
||||
}
|
||||
|
@ -821,6 +824,8 @@ static void xmit_speech (int c, packet_t pp)
|
|||
*/
|
||||
|
||||
info_len = ax25_get_info (pp, &pinfo);
|
||||
(void)info_len;
|
||||
|
||||
text_color_set(DW_COLOR_XMIT);
|
||||
dw_printf ("[%d.speech] \"%s\"\n", c, pinfo);
|
||||
|
||||
|
@ -891,6 +896,7 @@ int xmit_speak_it (char *script, int c, char *orig_msg)
|
|||
dw_printf ("Failed to run text-to-speech script, %s\n", script);
|
||||
|
||||
ignore = getcwd (cwd, sizeof(cwd));
|
||||
(void)ignore;
|
||||
strlcpy (path, getenv("PATH"), sizeof(path));
|
||||
|
||||
dw_printf ("CWD = %s\n", cwd);
|
||||
|
@ -933,6 +939,7 @@ static void xmit_morse (int c, packet_t pp, int wpm)
|
|||
|
||||
|
||||
info_len = ax25_get_info (pp, &pinfo);
|
||||
(void)info_len;
|
||||
text_color_set(DW_COLOR_XMIT);
|
||||
dw_printf ("[%d.morse] \"%s\"\n", c, pinfo);
|
||||
|
||||
|
|
Loading…
Reference in New Issue