mirror of
https://github.com/g8bpq/QtSoundModem.git
synced 2025-04-06 06:51:29 +02:00
0.0.0.71
This commit is contained in:
parent
5f5d989a5c
commit
e6a7ab8152
13 changed files with 330 additions and 261 deletions
|
@ -116,6 +116,7 @@ void GetPortSettings(int Chan)
|
|||
|
||||
fx25_mode[Chan] = getAX25Param("FX25", FX25_MODE_RX).toInt();
|
||||
il2p_mode[Chan] = getAX25Param("IL2P", IL2P_MODE_NONE).toInt();
|
||||
il2p_crc[Chan] = getAX25Param("IL2PCRC", 0).toInt();
|
||||
RSID_UI[Chan] = getAX25Param("RSID_UI", 0).toInt();
|
||||
RSID_SABM[Chan] = getAX25Param("RSID_SABM", 0).toInt();
|
||||
RSID_SetModem[Chan] = getAX25Param("RSID_SetModem", 0).toInt();
|
||||
|
@ -350,6 +351,7 @@ void SavePortSettings(int Chan)
|
|||
saveAX25Param("MyDigiCall", MyDigiCall[Chan]);
|
||||
saveAX25Param("FX25", fx25_mode[Chan]);
|
||||
saveAX25Param("IL2P", il2p_mode[Chan]);
|
||||
saveAX25Param("IL2PCRC", il2p_crc[Chan]);
|
||||
saveAX25Param("RSID_UI", RSID_UI[Chan]);
|
||||
saveAX25Param("RSID_SABM", RSID_SABM[Chan]);
|
||||
saveAX25Param("RSID_SetModem", RSID_SetModem[Chan]);
|
||||
|
|
|
@ -737,6 +737,19 @@
|
|||
<string>Retries</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="CRC_A">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>280</y>
|
||||
<width>53</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CRC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -1445,6 +1458,19 @@
|
|||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="CRC_B">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>280</y>
|
||||
<width>53</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CRC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_88">
|
||||
<property name="geometry">
|
||||
|
@ -2202,6 +2228,19 @@
|
|||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="CRC_C">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>280</y>
|
||||
<width>53</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CRC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="IL2PModeC">
|
||||
<property name="geometry">
|
||||
|
@ -2956,6 +2995,19 @@
|
|||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="CRC_D">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>280</y>
|
||||
<width>53</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CRC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="IL2PModeD">
|
||||
<property name="geometry">
|
||||
|
|
|
@ -160,6 +160,7 @@ int WaterfallMax = 6000;
|
|||
|
||||
int Configuring = 0;
|
||||
bool lockWaterfall = false;
|
||||
bool inWaterfall = false;
|
||||
|
||||
extern "C" int NeedWaterfallHeaders;
|
||||
extern "C" float BinSize;
|
||||
|
@ -498,7 +499,7 @@ void DoPSKWindows()
|
|||
constellationDialog->resize(NextX, 140);
|
||||
}
|
||||
|
||||
|
||||
QTimer *wftimer;
|
||||
|
||||
QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
|
||||
{
|
||||
|
@ -763,7 +764,7 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
|
|||
connect(timer, SIGNAL(timeout()), this, SLOT(MyTimerSlot()));
|
||||
timer->start(100);
|
||||
|
||||
QTimer *wftimer = new QTimer(this);
|
||||
wftimer = new QTimer(this);
|
||||
connect(wftimer, SIGNAL(timeout()), this, SLOT(doRestartWF()));
|
||||
wftimer->start(1000 * 300);
|
||||
|
||||
|
@ -884,9 +885,12 @@ void QtSoundModem::MyTimerSlot()
|
|||
{
|
||||
NeedWaterfallHeaders = 0;
|
||||
|
||||
Waterfall->fill(black);
|
||||
DrawModemFreqRange();
|
||||
DrawFreqTicks();
|
||||
if (Waterfall)
|
||||
{
|
||||
Waterfall->fill(black);
|
||||
DrawModemFreqRange();
|
||||
DrawFreqTicks();
|
||||
}
|
||||
}
|
||||
|
||||
show_grid();
|
||||
|
@ -1443,6 +1447,11 @@ void QtSoundModem::doModems()
|
|||
Dlg->IL2PModeC->setCurrentIndex(il2p_mode[2]);
|
||||
Dlg->IL2PModeD->setCurrentIndex(il2p_mode[3]);
|
||||
|
||||
Dlg->CRC_A->setChecked(il2p_crc[0]);
|
||||
Dlg->CRC_B->setChecked(il2p_crc[1]);
|
||||
Dlg->CRC_C->setChecked(il2p_crc[2]);
|
||||
Dlg->CRC_D->setChecked(il2p_crc[3]);
|
||||
|
||||
Dlg->CWIDCall->setText(CWIDCall);
|
||||
Dlg->CWIDInterval->setText(QString::number(CWIDInterval));
|
||||
Dlg->CWIDMark->setText(CWIDMark);
|
||||
|
@ -1532,6 +1541,12 @@ extern "C" void get_exclude_list(char * line, TStringList * list);
|
|||
void QtSoundModem::modemaccept()
|
||||
{
|
||||
modemSave();
|
||||
|
||||
AGW_Report_Modem_Change(0);
|
||||
AGW_Report_Modem_Change(1);
|
||||
AGW_Report_Modem_Change(2);
|
||||
AGW_Report_Modem_Change(3);
|
||||
|
||||
delete(Dlg);
|
||||
saveSettings();
|
||||
|
||||
|
@ -1661,6 +1676,11 @@ void QtSoundModem::modemSave()
|
|||
il2p_mode[2] = Dlg->IL2PModeC->currentIndex();
|
||||
il2p_mode[3] = Dlg->IL2PModeD->currentIndex();
|
||||
|
||||
il2p_crc[0] = Dlg->CRC_A->isChecked();
|
||||
il2p_crc[1] = Dlg->CRC_B->isChecked();
|
||||
il2p_crc[2] = Dlg->CRC_C->isChecked();
|
||||
il2p_crc[3] = Dlg->CRC_D->isChecked();
|
||||
|
||||
recovery[0] = Dlg->recoverBitA->currentIndex();
|
||||
recovery[1] = Dlg->recoverBitB->currentIndex();
|
||||
recovery[2] = Dlg->recoverBitC->currentIndex();
|
||||
|
@ -1712,7 +1732,6 @@ void QtSoundModem::modemSave()
|
|||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
initTStringList(&list_digi_callsigns[i]);
|
||||
|
||||
get_exclude_list(MyDigiCall[i], &list_digi_callsigns[i]);
|
||||
}
|
||||
|
||||
|
@ -1729,6 +1748,7 @@ void QtSoundModem::modemSave()
|
|||
Q = Dlg->LPFWidthD->text();
|
||||
lpf[3] = Q.toInt();
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void QtSoundModem::modemreject()
|
||||
|
@ -2401,6 +2421,14 @@ void QtSoundModem::handleButton(int Port, int Type)
|
|||
|
||||
void QtSoundModem::doRestartWF()
|
||||
{
|
||||
if (inWaterfall)
|
||||
{
|
||||
// in waterfall update thread
|
||||
|
||||
wftimer->start(5000);
|
||||
return;
|
||||
}
|
||||
|
||||
lockWaterfall = true;
|
||||
|
||||
if (Firstwaterfall | Secondwaterfall)
|
||||
|
@ -2849,6 +2877,11 @@ void doWaterfallThread(void * param)
|
|||
if (lockWaterfall)
|
||||
return;
|
||||
|
||||
if (Configuring)
|
||||
return;
|
||||
|
||||
inWaterfall = true; // don't allow restart waterfall
|
||||
|
||||
if (snd_ch == 1 && UsingLeft == 0) // Only using right
|
||||
snd_ch = 0; // Samples are in first buffer
|
||||
|
||||
|
@ -2865,8 +2898,6 @@ void doWaterfallThread(void * param)
|
|||
float RealOut[8192] = { 0 };
|
||||
float ImagOut[8192];
|
||||
|
||||
if (Configuring)
|
||||
return;
|
||||
|
||||
RefreshLevel(CurrentLevel); // Signal Level
|
||||
|
||||
|
@ -2954,10 +2985,15 @@ void doWaterfallThread(void * param)
|
|||
// we always do fft so we can get centre freq and do busy detect. But only upodate waterfall if on display
|
||||
|
||||
if (bm == 0)
|
||||
{
|
||||
inWaterfall = false;
|
||||
return;
|
||||
|
||||
}
|
||||
if ((Firstwaterfall == 0 && snd_ch == 0) || (Secondwaterfall == 0 && snd_ch == 1))
|
||||
{
|
||||
inWaterfall = false;
|
||||
return;
|
||||
}
|
||||
|
||||
p = Line;
|
||||
lineLen = 4096;
|
||||
|
@ -3005,6 +3041,8 @@ void doWaterfallThread(void * param)
|
|||
if (TopLine > 79)
|
||||
TopLine = 0;
|
||||
}
|
||||
|
||||
inWaterfall = false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,15 +20,15 @@
|
|||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<QtLastBackgroundBuild>2023-10-13T13:21:39.9400374Z</QtLastBackgroundBuild>
|
||||
<QtLastBackgroundBuild>2023-10-15T11:35:54.9027336Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="QtSettings">
|
||||
<QtLastBackgroundBuild>2023-10-13T13:21:40.0558471Z</QtLastBackgroundBuild>
|
||||
<QtLastBackgroundBuild>2023-10-15T11:35:55.0741785Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<QtLastBackgroundBuild>2023-10-13T13:21:40.2121547Z</QtLastBackgroundBuild>
|
||||
<QtLastBackgroundBuild>2023-10-15T11:35:55.2661628Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="QtSettings">
|
||||
<QtLastBackgroundBuild>2023-10-13T13:21:40.4722944Z</QtLastBackgroundBuild>
|
||||
<QtLastBackgroundBuild>2023-10-15T11:35:55.4659021Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
</Project>
|
15
UZ7HOStuff.h
15
UZ7HOStuff.h
|
@ -4,8 +4,8 @@
|
|||
// My port of UZ7HO's Soundmodem
|
||||
//
|
||||
|
||||
#define VersionString "0.0.0.70"
|
||||
#define VersionBytes {0, 0, 0, 70}
|
||||
#define VersionString "0.0.0.71"
|
||||
#define VersionBytes {0, 0, 0, 71}
|
||||
|
||||
// Added FX25. 4x100 FEC and V27 not Working and disabled
|
||||
|
||||
|
@ -174,6 +174,11 @@
|
|||
|
||||
// .70 Restructure Waterfall area to be a single image
|
||||
|
||||
// .71 Add IL2P CRC Mode
|
||||
// Improve reliability of waterfall update
|
||||
// Report and set fx.25 and il2p flags to/from BPQ
|
||||
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
@ -1004,6 +1009,7 @@ extern TAX25Port AX25Port[4][port_num];
|
|||
|
||||
extern int fx25_mode[4];
|
||||
extern int il2p_mode[4];
|
||||
extern int il2p_crc[4];
|
||||
|
||||
extern int tx_fx25_size[4];
|
||||
extern int tx_fx25_size_cnt[4];
|
||||
|
@ -1105,7 +1111,7 @@ int Add(TStringList * Q, string * Entry);
|
|||
|
||||
struct il2p_context_s {
|
||||
|
||||
enum { IL2P_SEARCHING = 0, IL2P_HEADER, IL2P_PAYLOAD, IL2P_DECODE } state;
|
||||
enum { IL2P_SEARCHING = 0, IL2P_HEADER, IL2P_PAYLOAD, IL2P_CRC, IL2P_DECODE } state;
|
||||
|
||||
unsigned int acc; // Accumulate most recent 24 bits for sync word matching.
|
||||
// Lower 8 bits are also used for accumulating bytes for
|
||||
|
@ -1129,6 +1135,9 @@ struct il2p_context_s {
|
|||
int pc; // Number of bytes placed in above.
|
||||
|
||||
int corrected; // Number of symbols corrected by RS FEC.
|
||||
|
||||
int crccount; // fec chars collected
|
||||
unsigned char crc[4]; // the 4 fec chars
|
||||
};
|
||||
|
||||
extern int NeedWaterfallHeaders;
|
||||
|
|
49
ax25_agw.c
49
ax25_agw.c
|
@ -515,13 +515,15 @@ void on_AGW_Gs_frame(AGWUser * AGW, struct AGWHeader * Frame, Byte * Data)
|
|||
{
|
||||
// QTSM with a data field is used by QtSM to set/read Modem Params
|
||||
|
||||
Byte info[44] = { 0, 255, 24, 3, 100, 15, 6, 0, 1, 0, 0, 0 }; //QTSM Signature
|
||||
Byte info[48] = { 0, 255, 24, 3, 100, 15, 6, 0, 1, 0, 0, 0 }; //QTSM Signature
|
||||
int Len = 12;
|
||||
|
||||
if (Frame->DataLength == 32)
|
||||
{
|
||||
// BPQ to QTSM private Format.
|
||||
|
||||
// First 4 Freq, 4 to 24 Modem, rest was spare. Use 27-31 for modem control flags (fx.25 il2p etc)
|
||||
|
||||
int Freq;
|
||||
Byte versionBytes[4] = VersionBytes;
|
||||
|
||||
|
@ -542,7 +544,7 @@ void on_AGW_Gs_frame(AGWUser * AGW, struct AGWHeader * Frame, Byte * Data)
|
|||
// New Modem Name. Need to convert to index unless numeric
|
||||
|
||||
int n;
|
||||
|
||||
|
||||
if (strlen(&Data[4]) < 3)
|
||||
{
|
||||
n = atoi(&Data[4]);
|
||||
|
@ -569,6 +571,13 @@ void on_AGW_Gs_frame(AGWUser * AGW, struct AGWHeader * Frame, Byte * Data)
|
|||
}
|
||||
}
|
||||
|
||||
if (Data[27] == 2)
|
||||
{
|
||||
fx25_mode[Frame->Port] = Data[28];
|
||||
il2p_mode[Frame->Port] = Data[29];
|
||||
il2p_crc[Frame->Port] = Data[30];
|
||||
}
|
||||
|
||||
// Return Freq and Modem
|
||||
|
||||
memcpy(&info[12], &rx_freq[Frame->Port], 2);
|
||||
|
@ -577,6 +586,22 @@ void on_AGW_Gs_frame(AGWUser * AGW, struct AGWHeader * Frame, Byte * Data)
|
|||
memcpy(&info[38], versionBytes, 4);
|
||||
|
||||
Len = 44;
|
||||
|
||||
if (Data[27])
|
||||
{
|
||||
// BPQ understands fx25 and il2p fields
|
||||
|
||||
AGW->reportFreqAndModem = 2; // Can report frequency Modem and flags
|
||||
|
||||
|
||||
Len = 48;
|
||||
|
||||
info[44] = 1; // Show includes Modem Flags
|
||||
info[45] = fx25_mode[Frame->Port];
|
||||
info[46] = il2p_mode[Frame->Port];
|
||||
info[47] = il2p_crc[Frame->Port];
|
||||
}
|
||||
|
||||
AGW_send_to_app(AGW->socket, AGW_Gs_Frame(Frame->Port, info, Len));
|
||||
return;
|
||||
}
|
||||
|
@ -1337,6 +1362,9 @@ void AGW_Report_Modem_Change(int port)
|
|||
AGWUser * AGW;
|
||||
string * pkt;
|
||||
|
||||
if (soundChannel[port] == 0) // Not in use
|
||||
return;
|
||||
|
||||
// I think we send to all AGW sockets
|
||||
|
||||
for (i = 0; i < AGWConCount; i++)
|
||||
|
@ -1345,16 +1373,27 @@ void AGW_Report_Modem_Change(int port)
|
|||
|
||||
if (AGW->reportFreqAndModem)
|
||||
{
|
||||
// QTSM 's' Message with a data field is used by QtSM to set/read Modem Params
|
||||
// QTSM 'g' Message with a data field is used by QtSM to set/read Modem Params
|
||||
|
||||
Byte info[44] = { 0, 255, 24, 3, 100, 15, 6, 0, 1, 0, 0, 0 }; //QTSM Signature
|
||||
Byte info[48] = { 0, 255, 24, 3, 100, 15, 6, 0, 1, 0, 0, 0 }; //QTSM Signature
|
||||
int Len = 44;
|
||||
|
||||
// Return Freq and Modem
|
||||
|
||||
memcpy(&info[12], &rx_freq[port], 2);
|
||||
memcpy(&info[16], modes_name[speed[port]], 20);
|
||||
info[37] = speed[port]; // Index
|
||||
AGW_send_to_app(AGW->socket, AGW_Gs_Frame(port, info, 44));
|
||||
|
||||
if (AGW->reportFreqAndModem == 2)
|
||||
{
|
||||
Len = 48;
|
||||
|
||||
info[44] = 1; // Show includes Modem Flags
|
||||
info[45] = fx25_mode[port];
|
||||
info[46] = il2p_mode[port];
|
||||
info[47] = il2p_crc[port];
|
||||
}
|
||||
AGW_send_to_app(AGW->socket, AGW_Gs_Frame(port, info, Len));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,6 +142,7 @@ short active_rx_freq[5] = { 1700, 1700,1700,1700,1700 };
|
|||
|
||||
int fx25_mode[4] = { 0, 0, 0, 0 };
|
||||
int il2p_mode[4] = { 0, 0, 0, 0 };
|
||||
int il2p_crc[4] = { 0, 0, 0, 0 };
|
||||
|
||||
int pnt_change[5] = { 0 };
|
||||
float src_buf[5][2048];
|
||||
|
|
|
@ -1,201 +0,0 @@
|
|||
[General]
|
||||
geometry="@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0z\0\0\0\t\0\0\x4=\0\0\x2\xf9\0\0\0{\0\0\0(\0\0\x4<\0\0\x2\xf8\0\0\0\0\0\0\0\0\x5\0\0\0\0{\0\0\0(\0\0\x4<\0\0\x2\xf8)"
|
||||
windowState=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\x3\xc2\0\0\x2\xb9\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\0)
|
||||
PSKWindow=@Rect(46 499 366 140)
|
||||
FontFamily=Courier New
|
||||
PointSize=12
|
||||
Weight=50
|
||||
|
||||
[AX25_A]
|
||||
Retries=15
|
||||
HiToneRaise=0
|
||||
Maxframe=3
|
||||
FrackTime=5
|
||||
IdleTime=180
|
||||
SlotTime=100
|
||||
Persist=128
|
||||
RespTime=1500
|
||||
TXFrmMode=1
|
||||
FrameCollector=6
|
||||
ExcludeCallsigns=
|
||||
ExcludeAPRSFrmType=
|
||||
KISSOptimization=0
|
||||
DynamicFrack=0
|
||||
BitRecovery=0
|
||||
NonAX25Frm=0
|
||||
MEMRecovery=200
|
||||
IPOLL=80
|
||||
MyDigiCall=
|
||||
FX25=1
|
||||
IL2P=2
|
||||
RSID_UI=0
|
||||
RSID_SABM=0
|
||||
RSID_SetModem=0
|
||||
|
||||
[Init]
|
||||
SoundMode=0
|
||||
UDPClientPort=8888
|
||||
UDPServerPort=8884
|
||||
TXPort=8884
|
||||
UDPServer=0
|
||||
UDPHost=192.168.1.255
|
||||
TXSampleRate=12000
|
||||
RXSampleRate=12000
|
||||
SndRXDeviceName="CABLE-B OUTPUT (VB-AUDIO CABLE "
|
||||
SndTXDeviceName=CABLE-B INPUT (VB-AUDIO CABLE B
|
||||
SCO=0
|
||||
DualPTT=1
|
||||
TXRotate=0
|
||||
DispMode=1
|
||||
PTT=
|
||||
PTTBAUD=19200
|
||||
PTTMode=1
|
||||
PTTOffString=
|
||||
PTTOnString=
|
||||
pttGPIOPin=17
|
||||
pttGPIOPinR=17
|
||||
CM108Addr=0xD8C:0x08
|
||||
HamLibPort=4532
|
||||
HamLibHost=127.0.0.1
|
||||
MinimizetoTray=1
|
||||
multiCore=1
|
||||
Wisdom=(fftw-3.3.5 fftwf_wisdom #x9e7d4dee #xdb14fed1 #x34bf76a4 #xeb6e8fdf\n (fftwf_codelet_n2fv_12_avx 0 #x10048 #x10048 #x0 #xb0767e46 #x8d41dd22 #x439264a0 #x18435a99)\n (fftwf_rdft_rank0_register 0 #x11048 #x11048 #x0 #xff75c762 #x3a0ee093 #x5b78d592 #x6b6be60e)\n (fftwf_codelet_t2fv_2_avx 0 #x11048 #x11048 #x0 #x34057a74 #x664db78f #xa9524ebc #x606afd88)\n (fftwf_dft_nop_register 0 #x11048 #x11048 #x0 #x4a593e24 #xb5f06ddf #xf11fe7f2 #xc010b545)\n (fftwf_dft_bluestein_register 0 #x11048 #x11048 #x0 #x5e17c068 #x1682c5d6 #x89dd79be #x9b951c0f)\n (fftwf_dft_vrank_geq1_register 0 #x10048 #x10048 #x0 #x2fce15e1 #x178d4f4d #x1e956a41 #xf3fd6b80)\n (fftwf_codelet_t1fuv_4_sse2 0 #x11048 #x11048 #x0 #x2fb84bc5 #x2792028e #x8ec66ed5 #x47b5f7dc)\n (fftwf_dft_buffered_register 0 #x11048 #x11048 #x0 #x4f8e87b4 #xec4f2fa0 #x79fe76a1 #xa16e32a5)\n (fftwf_dft_vrank_geq1_register 0 #x11048 #x11048 #x0 #x8a9c355b #xb6dbadad #xbac1daac #xa866ceb3)\n (fftwf_dft_r2hc_register 0 #x11048 #x11048 #x0 #x576d5db6 #xa6a15f8a #x875d87d5 #x7561a866)\n (fftwf_codelet_t1fv_6_avx 0 #x10048 #x10048 #x0 #xd9db29d8 #x3302fcf3 #x19ce6e5d #x869fc341)\n (fftwf_dft_vrank_geq1_register 0 #x11048 #x11048 #x0 #xf7abab03 #x5f0e79b1 #x1b8367ad #xe5028f2c)\n (fftwf_codelet_t1fv_12_avx 0 #x10048 #x10048 #x0 #x0b0d3933 #x08267d12 #x45613873 #xde496efe)\n)\n
|
||||
WaterfallMin=0
|
||||
WaterfallMax=3300
|
||||
|
||||
[AX25_B]
|
||||
Retries=15
|
||||
HiToneRaise=0
|
||||
Maxframe=3
|
||||
FrackTime=5
|
||||
IdleTime=180
|
||||
SlotTime=100
|
||||
Persist=128
|
||||
RespTime=1500
|
||||
TXFrmMode=1
|
||||
FrameCollector=6
|
||||
ExcludeCallsigns=
|
||||
ExcludeAPRSFrmType=
|
||||
KISSOptimization=0
|
||||
DynamicFrack=0
|
||||
BitRecovery=0
|
||||
NonAX25Frm=0
|
||||
MEMRecovery=200
|
||||
IPOLL=80
|
||||
MyDigiCall=
|
||||
FX25=1
|
||||
IL2P=2
|
||||
RSID_UI=0
|
||||
RSID_SABM=0
|
||||
RSID_SetModem=0
|
||||
|
||||
[Modem]
|
||||
NRRcvrPairs1=2
|
||||
NRRcvrPairs2=2
|
||||
NRRcvrPairs3=0
|
||||
NRRcvrPairs4=2
|
||||
RcvrShift1=50
|
||||
RcvrShift2=30
|
||||
RcvrShift3=30
|
||||
RcvrShift4=30
|
||||
ModemType1=4
|
||||
ModemType2=14
|
||||
ModemType3=0
|
||||
ModemType4=14
|
||||
soundChannel1=1
|
||||
soundChannel2=1
|
||||
soundChannel3=0
|
||||
soundChannel4=0
|
||||
DCDThreshold=40
|
||||
rxOffset=-100
|
||||
PreEmphasisAll1=0
|
||||
PreEmphasisAll2=0
|
||||
PreEmphasisAll3=0
|
||||
PreEmphasisAll4=0
|
||||
PreEmphasisDB1=0
|
||||
PreEmphasisDB2=0
|
||||
PreEmphasisDB3=0
|
||||
PreEmphasisDB4=0
|
||||
TxDelay1=250
|
||||
TxDelay2=250
|
||||
TxDelay3=250
|
||||
TxDelay4=250
|
||||
TxTail1=50
|
||||
TxTail2=50
|
||||
TxTail3=50
|
||||
TxTail4=50
|
||||
CWIDCall=
|
||||
CWIDInterval=0
|
||||
CWIDLeft=0
|
||||
CWIDRight=0
|
||||
CWIDType=1
|
||||
RXFreq1=1700
|
||||
RXFreq2=1700
|
||||
RXFreq3=500
|
||||
RXFreq4=1700
|
||||
CWIDMark=
|
||||
afterTraffic=false
|
||||
|
||||
[AGWHost]
|
||||
Server=1
|
||||
Port=8000
|
||||
|
||||
[KISS]
|
||||
Server=0
|
||||
Port=8105
|
||||
|
||||
[AX25_C]
|
||||
Retries=15
|
||||
HiToneRaise=0
|
||||
Maxframe=3
|
||||
FrackTime=5
|
||||
IdleTime=180
|
||||
SlotTime=100
|
||||
Persist=128
|
||||
RespTime=1500
|
||||
TXFrmMode=1
|
||||
FrameCollector=6
|
||||
ExcludeCallsigns=
|
||||
ExcludeAPRSFrmType=
|
||||
KISSOptimization=0
|
||||
DynamicFrack=0
|
||||
BitRecovery=0
|
||||
NonAX25Frm=0
|
||||
MEMRecovery=200
|
||||
IPOLL=80
|
||||
MyDigiCall=
|
||||
FX25=1
|
||||
IL2P=0
|
||||
RSID_UI=0
|
||||
RSID_SABM=0
|
||||
RSID_SetModem=0
|
||||
|
||||
[Window]
|
||||
Waterfall1=1
|
||||
Waterfall2=1
|
||||
|
||||
[AX25_D]
|
||||
Retries=15
|
||||
HiToneRaise=0
|
||||
Maxframe=3
|
||||
FrackTime=5
|
||||
IdleTime=180
|
||||
SlotTime=100
|
||||
Persist=128
|
||||
RespTime=1500
|
||||
TXFrmMode=1
|
||||
FrameCollector=6
|
||||
ExcludeCallsigns=
|
||||
ExcludeAPRSFrmType=
|
||||
KISSOptimization=0
|
||||
DynamicFrack=0
|
||||
BitRecovery=0
|
||||
NonAX25Frm=0
|
||||
MEMRecovery=200
|
||||
IPOLL=80
|
||||
MyDigiCall=
|
||||
FX25=1
|
||||
IL2P=0
|
||||
RSID_UI=0
|
||||
RSID_SABM=0
|
||||
RSID_SetModem=0
|
|
@ -1,12 +0,0 @@
|
|||
#define _MSC_EXTENSIONS
|
||||
#define _INTEGRAL_MAX_BITS 64
|
||||
#define _MSC_VER 1916
|
||||
#define _MSC_FULL_VER 191627050
|
||||
#define _MSC_BUILD 0
|
||||
#define _WIN32
|
||||
#define _M_IX86 600
|
||||
#define _M_IX86_FP 2
|
||||
#define _CPPRTTI
|
||||
#define _DEBUG
|
||||
#define _MT
|
||||
#define _DLL
|
1
dw9600.c
1
dw9600.c
|
@ -25,6 +25,7 @@ typedef struct TStringList_T
|
|||
|
||||
extern int fx25_mode[4];
|
||||
extern int il2p_mode[4];
|
||||
extern int il2p_crc[4];
|
||||
extern short rx_baudrate[5];
|
||||
|
||||
#define FX25_MODE_NONE 0
|
||||
|
|
182
il2p.c
182
il2p.c
|
@ -42,11 +42,44 @@ along with QtSoundModem. If not, see http://www.gnu.org/licenses
|
|||
|
||||
// IP2P receive code (il2p_rec_bit) is called from the bit receiving code in ax25_demod.c, so includes parallel decoders
|
||||
|
||||
|
||||
|
||||
|
||||
#include "UZ7HOStuff.h"
|
||||
|
||||
#include <stdint.h> // for uint64_t
|
||||
|
||||
// Oct 2023 Nino has added an optional crc
|
||||
|
||||
// Hamming(7,4) Encoding Table
|
||||
// Enter this table with the 4-bit value to be encoded.
|
||||
// Returns 7-bit encoded value, with high bit zero'd.
|
||||
|
||||
uint8_t Hamming74EncodeTable[16] = { 0x0, 0x71, 0x62, 0x13, 0x54, 0x25, 0x36, 0x47, 0x38, 0x49, 0x5a, 0x2b, 0x6c, 0x1d, 0xe, 0x7f };
|
||||
|
||||
// Hamming(7,4) Decoding Table
|
||||
// Enter this table with 7-bit encoded value, high bit masked.
|
||||
// Returns 4-bit decoded value.
|
||||
|
||||
uint16_t Hamming74DecodeTable[128] = { \
|
||||
0x0, 0x0, 0x0, 0x3, 0x0, 0x5, 0xe, 0x7, \
|
||||
0x0, 0x9, 0xe, 0xb, 0xe, 0xd, 0xe, 0xe, \
|
||||
0x0, 0x3, 0x3, 0x3, 0x4, 0xd, 0x6, 0x3, \
|
||||
0x8, 0xd, 0xa, 0x3, 0xd, 0xd, 0xe, 0xd, \
|
||||
0x0, 0x5, 0x2, 0xb, 0x5, 0x5, 0x6, 0x5, \
|
||||
0x8, 0xb, 0xb, 0xb, 0xc, 0x5, 0xe, 0xb, \
|
||||
0x8, 0x1, 0x6, 0x3, 0x6, 0x5, 0x6, 0x6, \
|
||||
0x8, 0x8, 0x8, 0xb, 0x8, 0xd, 0x6, 0xf, \
|
||||
0x0, 0x9, 0x2, 0x7, 0x4, 0x7, 0x7, 0x7, \
|
||||
0x9, 0x9, 0xa, 0x9, 0xc, 0x9, 0xe, 0x7, \
|
||||
0x4, 0x1, 0xa, 0x3, 0x4, 0x4, 0x4, 0x7, \
|
||||
0xa, 0x9, 0xa, 0xa, 0x4, 0xd, 0xa, 0xf, \
|
||||
0x2, 0x1, 0x2, 0x2, 0xc, 0x5, 0x2, 0x7, \
|
||||
0xc, 0x9, 0x2, 0xb, 0xc, 0xc, 0xc, 0xf, \
|
||||
0x1, 0x1, 0x2, 0x1, 0x4, 0x1, 0x6, 0xf, \
|
||||
0x8, 0x1, 0xa, 0xf, 0xc, 0xf, 0xf, 0xf };
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void Debugprintf(const char * format, ...);
|
||||
int SMUpdatePhaseConstellation(int chan, float * Phases, float * Mags, int intPSKPhase, int Count);
|
||||
|
||||
|
@ -109,7 +142,6 @@ int MaxMagIndex = 0;
|
|||
#ifndef FX25_H
|
||||
#define FX25_H
|
||||
|
||||
#include <stdint.h> // for uint64_t
|
||||
|
||||
extern unsigned int pskStates[4];
|
||||
|
||||
|
@ -343,6 +375,7 @@ struct packet_s {
|
|||
unsigned char frame_data[AX25_MAX_PACKET_LEN + 1];
|
||||
/* Raw frame contents, without the CRC. */
|
||||
|
||||
unsigned char crc[4]; // received crc
|
||||
|
||||
int magic2; /* Will get stomped on if above overflows. */
|
||||
};
|
||||
|
@ -1015,6 +1048,39 @@ void multi_modem_process_rec_packet(int snd_ch, int subchan, int slice, packet_t
|
|||
|
||||
sprintf(Mode, "IL2P %d", centreFreq);
|
||||
|
||||
// check crc if enabled
|
||||
|
||||
if (il2p_crc[snd_ch])
|
||||
{
|
||||
unsigned short CRCMSG;
|
||||
unsigned short CRCCALC;
|
||||
uint8_t crc[4];
|
||||
|
||||
// check crc if enabled
|
||||
|
||||
// The four encoded CRC bytes are arranged :
|
||||
// | CRC3 | CRC2 | CRC1 | CRC0 | but we store as received, so F->crc[0] is CRC3
|
||||
// CRC3 encoded from high nibble of 16 - bit CRC value (from crc2)
|
||||
// CRC0 encoded from low nibble of 16 - bit CRC value (from crc1)
|
||||
|
||||
crc[0] = Hamming74DecodeTable[(pp->crc[0] & 0x7f)];
|
||||
crc[1] = Hamming74DecodeTable[(pp->crc[1] & 0x7f)];
|
||||
crc[2] = Hamming74DecodeTable[(pp->crc[2] & 0x7f)];
|
||||
crc[3] = Hamming74DecodeTable[(pp->crc[3] & 0x7f)];
|
||||
|
||||
CRCMSG = crc[0] << 12 | crc[1] << 8 | crc[2] << 4 | crc[3];
|
||||
|
||||
CRCCALC = get_fcs(pp->frame_data, pp->frame_len);
|
||||
|
||||
if (CRCCALC != CRCMSG)
|
||||
{
|
||||
Debugprintf("CRC Error Decoder %d Received %x Sent %x", subchan, CRCCALC, CRCMSG);
|
||||
// freeString(data);
|
||||
// ax25_delete(pp);
|
||||
// return;
|
||||
}
|
||||
}
|
||||
|
||||
stringAdd(data, pp->frame_data, pp->frame_len + 2); // QTSM assumes a CRC
|
||||
|
||||
ax25_delete(pp);
|
||||
|
@ -3151,6 +3217,13 @@ int il2p_type_1_header(packet_t pp, int max_fec, unsigned char *hdr)
|
|||
ax25_get_addr_no_ssid(pp, AX25_SOURCE, src_addr);
|
||||
int src_ssid = ax25_get_ssid(pp, AX25_SOURCE);
|
||||
|
||||
if ((pp->frame_data[6] & 0x80) == (pp->frame_data[13] & 0x80))
|
||||
{
|
||||
// Both C bits are the same (ax.25 v1) so can't be sent as type 1 as will be changed
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned char *a = (unsigned char *)dst_addr;
|
||||
for (int i = 0; *a != '\0'; i++, a++) {
|
||||
if (*a < ' ' || *a > '_') {
|
||||
|
@ -3919,7 +3992,7 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit)
|
|||
//assert(slice >= 0 && slice < MAX_SLICERS);
|
||||
F = il2p_context[chan][subchan][slice] = (struct il2p_context_s *)malloc(sizeof(struct il2p_context_s));
|
||||
//assert(F != NULL);
|
||||
memset(F, 0, sizeof(struct il2p_context_s));
|
||||
memset(F, 0, sizeof(struct il2p_context_s));
|
||||
}
|
||||
|
||||
// Accumulate most recent 24 bits received. Most recent is LSB.
|
||||
|
@ -3942,7 +4015,7 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit)
|
|||
nPhases[chan][subchan][slice] = 0;
|
||||
|
||||
// Determine Centre Freq
|
||||
|
||||
|
||||
centreFreq[chan] = GuessCentreFreq(chan);
|
||||
}
|
||||
else if (__builtin_popcount((~F->acc & 0x00ffffff) ^ IL2P_SYNC_WORD) <= 1) {
|
||||
|
@ -3956,7 +4029,7 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit)
|
|||
centreFreq[chan] = GuessCentreFreq(chan);
|
||||
nPhases[chan][subchan][slice] = 0;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case IL2P_HEADER: // Gathering the header.
|
||||
|
@ -3990,7 +4063,7 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit)
|
|||
F->eplen = il2p_payload_compute(&plprop, len, max_fec);
|
||||
|
||||
if (il2p_get_debug() >= 1)
|
||||
{
|
||||
{
|
||||
Debugprintf("Header type %d, max fec = %d", hdr_type, max_fec);
|
||||
Debugprintf("Need to collect %d encoded bytes for %d byte payload.", F->eplen, len);
|
||||
Debugprintf("%d small blocks of %d and %d large blocks of %d. %d parity symbols per block",
|
||||
|
@ -4008,9 +4081,21 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit)
|
|||
F->pc = 0;
|
||||
F->state = IL2P_PAYLOAD;
|
||||
}
|
||||
else if (F->eplen == 0) { // No payload.
|
||||
else if (F->eplen == 0)
|
||||
{
|
||||
// No payload.
|
||||
|
||||
F->pc = 0;
|
||||
F->state = IL2P_DECODE;
|
||||
|
||||
if (il2p_crc[chan])
|
||||
{
|
||||
// enter collect crc state
|
||||
|
||||
F->crccount = 0;
|
||||
F->state = IL2P_CRC;
|
||||
}
|
||||
else
|
||||
F->state = IL2P_DECODE;
|
||||
}
|
||||
else { // Error.
|
||||
|
||||
|
@ -4039,16 +4124,47 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit)
|
|||
else {
|
||||
F->spayload[F->pc++] = (~F->acc) & 0xff;
|
||||
}
|
||||
if (F->pc == F->eplen) {
|
||||
if (F->pc == F->eplen)
|
||||
{
|
||||
// got frame. See if need crc
|
||||
|
||||
// TODO?: for symmetry it seems like we should clarify the payload before combining.
|
||||
if (il2p_crc[chan])
|
||||
{
|
||||
// enter collect crc state
|
||||
|
||||
F->state = IL2P_DECODE;
|
||||
F->crccount = 0;
|
||||
F->state = IL2P_CRC;
|
||||
}
|
||||
else
|
||||
F->state = IL2P_DECODE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IL2P_CRC:
|
||||
|
||||
F->bc++;
|
||||
if (F->bc == 8)
|
||||
{
|
||||
// full byte has been collected.
|
||||
F->bc = 0;
|
||||
if (!F->polarity)
|
||||
F->crc[F->crccount++] = F->acc & 0xff;
|
||||
else
|
||||
F->crc[F->crccount++] = (~F->acc) & 0xff;
|
||||
|
||||
if (F->crccount == 4)
|
||||
{
|
||||
// have all crc bytes. enter DECODE
|
||||
|
||||
F->state = IL2P_DECODE;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case IL2P_DECODE:
|
||||
|
||||
// We get here after a good header and any payload has been collected.
|
||||
// Processing is delayed by one bit but I think it makes the logic cleaner.
|
||||
// During unit testing be sure to send an extra bit to flush it out at the end.
|
||||
|
@ -4077,6 +4193,18 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit)
|
|||
|
||||
// TODO: Could we put last 3 arguments in packet object rather than passing around separately?
|
||||
|
||||
// if using crc pass received crc to packet object
|
||||
|
||||
if (il2p_crc[chan])
|
||||
{
|
||||
//copy crc bytes to packet object
|
||||
|
||||
pp->crc[0] = F->crc[0];
|
||||
pp->crc[1] = F->crc[1];
|
||||
pp->crc[2] = F->crc[2];
|
||||
pp->crc[3] = F->crc[3];
|
||||
}
|
||||
|
||||
multi_modem_process_rec_packet(chan, subchan, slice, pp, alevel, retries, is_fx25, slice, centreFreq[chan]);
|
||||
}
|
||||
} // end block for local variables.
|
||||
|
@ -4269,13 +4397,19 @@ static void send_bit(int chan, int b, int polarity);
|
|||
*
|
||||
*--------------------------------------------------------------*/
|
||||
|
||||
|
||||
string * il2p_send_frame(int chan, packet_t pp, int max_fec, int polarity)
|
||||
{
|
||||
unsigned char encoded[IL2P_MAX_PACKET_SIZE];
|
||||
unsigned char encoded[IL2P_MAX_PACKET_SIZE] = "";
|
||||
string * packet = newString();
|
||||
int preamblecount;
|
||||
unsigned char preamble[1024];
|
||||
|
||||
// The data includes the 2 byte crc but length doesn't
|
||||
|
||||
uint8_t crc1 = pp->frame_data[pp->frame_len]; // Low 8 bits
|
||||
uint8_t crc2 = pp->frame_data[pp->frame_len + 1]; // High 8 bits
|
||||
|
||||
encoded[0] = (IL2P_SYNC_WORD >> 16) & 0xff;
|
||||
encoded[1] = (IL2P_SYNC_WORD >> 8) & 0xff;
|
||||
encoded[2] = (IL2P_SYNC_WORD) & 0xff;
|
||||
|
@ -4289,6 +4423,24 @@ string * il2p_send_frame(int chan, packet_t pp, int max_fec, int polarity)
|
|||
|
||||
elen += IL2P_SYNC_WORD_SIZE;
|
||||
|
||||
// if we are using crc add it now. elen should point to end of data
|
||||
// crc should be at pp->frame_data[pp->frame_len]
|
||||
|
||||
if (il2p_crc[chan])
|
||||
{
|
||||
// The four encoded CRC bytes are arranged :
|
||||
// | CRC3 | CRC2 | CRC1 | CRC0 |
|
||||
|
||||
// CRC3 encoded from high nibble of 16 - bit CRC value (from crc2)
|
||||
// CRC0 encoded from low nibble of 16 - bit CRC value (from crc1)
|
||||
|
||||
encoded[elen++] = Hamming74EncodeTable[crc2 >> 4];
|
||||
encoded[elen++] = Hamming74EncodeTable[crc2 & 0xf];
|
||||
encoded[elen++] = Hamming74EncodeTable[crc1 >> 4];
|
||||
encoded[elen++] = Hamming74EncodeTable[crc1 &0xf];
|
||||
}
|
||||
|
||||
|
||||
number_of_bits_sent[chan] = 0;
|
||||
|
||||
if (il2p_get_debug() >= 1) {
|
||||
|
@ -4366,7 +4518,7 @@ string * fill_il2p_data(int snd_ch, string * data)
|
|||
// Call il2p_send_frame to build the bit stream
|
||||
|
||||
pp->frame_len = data->Length - 2; // Included CRC
|
||||
memcpy(pp->frame_data, data->Data, data->Length);
|
||||
memcpy(pp->frame_data, data->Data, data->Length); // Copy the crc in case we are going to send it
|
||||
|
||||
result = il2p_send_frame(snd_ch, pp, 1, 0);
|
||||
|
||||
|
|
|
@ -245,7 +245,6 @@ void ProcessKISSFrame(void * socket, UCHAR * Msg, int Len)
|
|||
Add(&KISS.buffer[Chan], TXMSG);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
|
||||
case KISS_DATA:
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#define _MSC_EXTENSIONS
|
||||
#define _INTEGRAL_MAX_BITS 64
|
||||
#define _MSC_VER 1916
|
||||
#define _MSC_FULL_VER 191627043
|
||||
#define _MSC_BUILD 0
|
||||
#define _WIN32
|
||||
#define _M_IX86 600
|
||||
#define _M_IX86_FP 2
|
||||
#define _CPPRTTI
|
||||
#define _MT
|
||||
#define _DLL
|
Loading…
Add table
Reference in a new issue