mirror of
https://github.com/ShaYmez/MMDVM_CM.git
synced 2025-08-13 10:12:26 -04:00
Merge pull request #33 from AndyTaylorTweet/master
This is all based on wok by @nostar and help from @g4klx;
This commit is contained in:
commit
9276cbcc71
@ -43,6 +43,17 @@ m_dstPort(0U),
|
|||||||
m_localAddress(),
|
m_localAddress(),
|
||||||
m_localPort(0U),
|
m_localPort(0U),
|
||||||
m_fcsFile(),
|
m_fcsFile(),
|
||||||
|
m_fichCallSign(2U),
|
||||||
|
m_fichCallMode(0U),
|
||||||
|
m_fichFrameTotal(7U),
|
||||||
|
m_fichMessageRoute(0U),
|
||||||
|
m_fichVOIP(0U),
|
||||||
|
m_fichDataType(2U),
|
||||||
|
m_fichSQLType(0U),
|
||||||
|
m_fichSQLCode(0U),
|
||||||
|
m_ysfDT1(),
|
||||||
|
m_ysfDT2(),
|
||||||
|
m_ysfRadioID("*****"),
|
||||||
m_daemon(false),
|
m_daemon(false),
|
||||||
m_debug(false),
|
m_debug(false),
|
||||||
m_dmrId(0U),
|
m_dmrId(0U),
|
||||||
@ -107,6 +118,7 @@ bool CConf::read()
|
|||||||
|
|
||||||
// Remove quotes from the value
|
// Remove quotes from the value
|
||||||
size_t len = ::strlen(value);
|
size_t len = ::strlen(value);
|
||||||
|
char *t;
|
||||||
if (len > 1U && *value == '"' && value[len - 1U] == '"') {
|
if (len > 1U && *value == '"' && value[len - 1U] == '"') {
|
||||||
value[len - 1U] = '\0';
|
value[len - 1U] = '\0';
|
||||||
value++;
|
value++;
|
||||||
@ -132,6 +144,31 @@ bool CConf::read()
|
|||||||
m_daemon = ::atoi(value) == 1;
|
m_daemon = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
m_debug = ::atoi(value) == 1;
|
m_debug = ::atoi(value) == 1;
|
||||||
|
else if (::strcmp(key, "RadioID") == 0)
|
||||||
|
m_ysfRadioID = value;
|
||||||
|
else if (::strcmp(key, "FICHCallsign") == 0)
|
||||||
|
m_fichCallSign = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHCallMode") == 0)
|
||||||
|
m_fichCallMode = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHFrameTotal") == 0)
|
||||||
|
m_fichFrameTotal = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHMessageRoute") == 0)
|
||||||
|
m_fichMessageRoute = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHVOIP") == 0)
|
||||||
|
m_fichVOIP = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHDataType") == 0)
|
||||||
|
m_fichDataType = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHSQLType") == 0)
|
||||||
|
m_fichSQLType = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHSQLCode") == 0)
|
||||||
|
m_fichSQLCode = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "DT1") == 0){
|
||||||
|
while ((t = strtok_r(value, ",", &value)) != NULL)
|
||||||
|
m_ysfDT1.push_back(::atoi(t));
|
||||||
|
} else if (::strcmp(key, "DT2") == 0){
|
||||||
|
while ((t = strtok_r(value, ",", &value)) != NULL)
|
||||||
|
m_ysfDT2.push_back(::atoi(t));
|
||||||
|
}
|
||||||
} else if (section == SECTION_DMR_NETWORK) {
|
} else if (section == SECTION_DMR_NETWORK) {
|
||||||
if (::strcmp(key, "Id") == 0)
|
if (::strcmp(key, "Id") == 0)
|
||||||
m_dmrId = (unsigned int)::atoi(value);
|
m_dmrId = (unsigned int)::atoi(value);
|
||||||
@ -213,6 +250,61 @@ bool CConf::getDebug() const
|
|||||||
return m_debug;
|
return m_debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHCallSign() const
|
||||||
|
{
|
||||||
|
return m_fichCallSign;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHCallMode() const
|
||||||
|
{
|
||||||
|
return m_fichCallMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHFrameTotal() const
|
||||||
|
{
|
||||||
|
return m_fichFrameTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHMessageRoute() const
|
||||||
|
{
|
||||||
|
return m_fichMessageRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHVOIP() const
|
||||||
|
{
|
||||||
|
return m_fichVOIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHDataType() const
|
||||||
|
{
|
||||||
|
return m_fichDataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHSQLType() const
|
||||||
|
{
|
||||||
|
return m_fichSQLType;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHSQLCode() const
|
||||||
|
{
|
||||||
|
return m_fichSQLCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> CConf::getYsfDT1()
|
||||||
|
{
|
||||||
|
return m_ysfDT1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> CConf::getYsfDT2()
|
||||||
|
{
|
||||||
|
return m_ysfDT2;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getYsfRadioID()
|
||||||
|
{
|
||||||
|
return m_ysfRadioID;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int CConf::getDMRId() const
|
unsigned int CConf::getDMRId() const
|
||||||
{
|
{
|
||||||
return m_dmrId;
|
return m_dmrId;
|
||||||
|
@ -38,6 +38,17 @@ public:
|
|||||||
std::string getLocalAddress() const;
|
std::string getLocalAddress() const;
|
||||||
unsigned int getLocalPort() const;
|
unsigned int getLocalPort() const;
|
||||||
std::string getFCSFile() const;
|
std::string getFCSFile() const;
|
||||||
|
unsigned char getFICHCallSign() const;
|
||||||
|
unsigned char getFICHCallMode() const;
|
||||||
|
unsigned char getFICHFrameTotal() const;
|
||||||
|
unsigned char getFICHMessageRoute() const;
|
||||||
|
unsigned char getFICHVOIP() const;
|
||||||
|
unsigned char getFICHDataType() const;
|
||||||
|
unsigned char getFICHSQLType() const;
|
||||||
|
unsigned char getFICHSQLCode() const;
|
||||||
|
std::vector<unsigned char> getYsfDT1();
|
||||||
|
std::vector<unsigned char> getYsfDT2();
|
||||||
|
std::string getYsfRadioID();
|
||||||
bool getDaemon() const;
|
bool getDaemon() const;
|
||||||
bool getDebug() const;
|
bool getDebug() const;
|
||||||
|
|
||||||
@ -70,6 +81,17 @@ private:
|
|||||||
std::string m_localAddress;
|
std::string m_localAddress;
|
||||||
unsigned int m_localPort;
|
unsigned int m_localPort;
|
||||||
std::string m_fcsFile;
|
std::string m_fcsFile;
|
||||||
|
unsigned char m_fichCallSign;
|
||||||
|
unsigned char m_fichCallMode;
|
||||||
|
unsigned char m_fichFrameTotal;
|
||||||
|
unsigned char m_fichMessageRoute;
|
||||||
|
unsigned char m_fichVOIP;
|
||||||
|
unsigned char m_fichDataType;
|
||||||
|
unsigned char m_fichSQLType;
|
||||||
|
unsigned char m_fichSQLCode;
|
||||||
|
std::vector<unsigned char> m_ysfDT1;
|
||||||
|
std::vector<unsigned char> m_ysfDT2;
|
||||||
|
std::string m_ysfRadioID;
|
||||||
bool m_daemon;
|
bool m_daemon;
|
||||||
bool m_debug;
|
bool m_debug;
|
||||||
|
|
||||||
@ -90,7 +112,6 @@ private:
|
|||||||
unsigned int m_logFileLevel;
|
unsigned int m_logFileLevel;
|
||||||
std::string m_logFilePath;
|
std::string m_logFilePath;
|
||||||
std::string m_logFileRoot;
|
std::string m_logFileRoot;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,9 +33,6 @@
|
|||||||
const unsigned char dt1_temp[] = {0x31, 0x22, 0x62, 0x5F, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00};
|
const unsigned char dt1_temp[] = {0x31, 0x22, 0x62, 0x5F, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
const unsigned char dt2_temp[] = {0x00, 0x00, 0x00, 0x00, 0x6C, 0x20, 0x1C, 0x20, 0x03, 0x08};
|
const unsigned char dt2_temp[] = {0x00, 0x00, 0x00, 0x00, 0x6C, 0x20, 0x1C, 0x20, 0x03, 0x08};
|
||||||
|
|
||||||
// Added by AD8DP for FICH FT=6 transmissions
|
|
||||||
const uint8_t dt1[10] = {0x01, 0x22, 0x61, 0x5f, 0x2b, 0x03, 0x11, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
const unsigned char CONN_RESP[] = {0x5DU, 0x41U, 0x5FU, 0x26U};
|
const unsigned char CONN_RESP[] = {0x5DU, 0x41U, 0x5FU, 0x26U};
|
||||||
|
|
||||||
#define DMR_FRAME_PER 55U
|
#define DMR_FRAME_PER 55U
|
||||||
@ -51,7 +48,6 @@ const char* HEADER1 = "This software is for use on amateur radio networks only,"
|
|||||||
const char* HEADER2 = "it is to be used for educational purposes only. Its use on";
|
const char* HEADER2 = "it is to be used for educational purposes only. Its use on";
|
||||||
const char* HEADER3 = "commercial networks is strictly prohibited.";
|
const char* HEADER3 = "commercial networks is strictly prohibited.";
|
||||||
const char* HEADER4 = "Copyright(C) 2018 by CA6JAU, G4KLX and others";
|
const char* HEADER4 = "Copyright(C) 2018 by CA6JAU, G4KLX and others";
|
||||||
const char ysf_radioid[] = {'H', '5', '0', '0', '0'};
|
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -652,23 +648,24 @@ int CDMR2YSF::run()
|
|||||||
// Set the FICH
|
// Set the FICH
|
||||||
CYSFFICH fich;
|
CYSFFICH fich;
|
||||||
fich.setFI(YSF_FI_HEADER);
|
fich.setFI(YSF_FI_HEADER);
|
||||||
fich.setCS(2U);
|
fich.setCS(m_conf.getFICHCallSign());
|
||||||
fich.setCM(1U);
|
fich.setCM(m_conf.getFICHCallMode());
|
||||||
fich.setBN(0U);
|
fich.setBN(0U);
|
||||||
fich.setBT(0U);
|
fich.setBT(0U);
|
||||||
fich.setFN(0U);
|
fich.setFN(0U);
|
||||||
fich.setFT(6U);
|
fich.setFT(m_conf.getFICHFrameTotal());
|
||||||
fich.setDev(0U);
|
fich.setDev(0U);
|
||||||
fich.setMR(0U);
|
fich.setMR(m_conf.getFICHMessageRoute());
|
||||||
fich.setVoIP(false);
|
fich.setVoIP(m_conf.getFICHVOIP());
|
||||||
fich.setDT(YSF_DT_VD_MODE2);
|
fich.setDT(m_conf.getFICHDataType());
|
||||||
fich.setSQL(0U);
|
fich.setSQL(m_conf.getFICHSQLType());
|
||||||
fich.setSQ(0U);
|
fich.setSQ(m_conf.getFICHSQLCode());
|
||||||
fich.encode(m_ysfFrame + 35U);
|
fich.encode(m_ysfFrame + 35U);
|
||||||
|
|
||||||
unsigned char csd1[20U], csd2[20U];
|
unsigned char csd1[20U], csd2[20U];
|
||||||
|
memset(csd1, '*', YSF_CALLSIGN_LENGTH);
|
||||||
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
||||||
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||||
|
|
||||||
@ -693,23 +690,23 @@ int CDMR2YSF::run()
|
|||||||
// Set the FICH
|
// Set the FICH
|
||||||
CYSFFICH fich;
|
CYSFFICH fich;
|
||||||
fich.setFI(YSF_FI_TERMINATOR);
|
fich.setFI(YSF_FI_TERMINATOR);
|
||||||
fich.setCS(2U);
|
fich.setCS(m_conf.getFICHCallSign());
|
||||||
fich.setCM(1U);
|
fich.setCM(m_conf.getFICHCallMode());
|
||||||
fich.setBN(0U);
|
fich.setBN(0U);
|
||||||
fich.setBT(0U);
|
fich.setBT(0U);
|
||||||
fich.setFN(0U);
|
fich.setFN(0U);
|
||||||
fich.setFT(6U);
|
fich.setFT(m_conf.getFICHFrameTotal());
|
||||||
fich.setDev(0U);
|
fich.setDev(0U);
|
||||||
fich.setMR(0U);
|
fich.setMR(m_conf.getFICHMessageRoute());
|
||||||
fich.setVoIP(false);
|
fich.setVoIP(m_conf.getFICHVOIP());
|
||||||
fich.setDT(YSF_DT_VD_MODE2);
|
fich.setDT(m_conf.getFICHDataType());
|
||||||
fich.setSQL(0U);
|
fich.setSQL(m_conf.getFICHSQLType());
|
||||||
fich.setSQ(0U);
|
fich.setSQ(m_conf.getFICHSQLCode());
|
||||||
fich.encode(m_ysfFrame + 35U);
|
fich.encode(m_ysfFrame + 35U);
|
||||||
|
|
||||||
unsigned char csd1[20U], csd2[20U];
|
unsigned char csd1[20U], csd2[20U];
|
||||||
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
||||||
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||||
|
|
||||||
@ -724,7 +721,7 @@ int CDMR2YSF::run()
|
|||||||
CYSFPayload ysfPayload;
|
CYSFPayload ysfPayload;
|
||||||
unsigned char dch[10U];
|
unsigned char dch[10U];
|
||||||
|
|
||||||
unsigned int fn = (ysf_cnt - 1U) % 7U;
|
unsigned int fn = (ysf_cnt - 1U) % (m_conf.getFICHFrameTotal() + 1);
|
||||||
|
|
||||||
::memcpy(m_ysfFrame + 0U, "YSFD", 4U);
|
::memcpy(m_ysfFrame + 0U, "YSFD", 4U);
|
||||||
::memcpy(m_ysfFrame + 4U, m_ysfNetwork->getCallsign().c_str(), YSF_CALLSIGN_LENGTH);
|
::memcpy(m_ysfFrame + 4U, m_ysfNetwork->getCallsign().c_str(), YSF_CALLSIGN_LENGTH);
|
||||||
@ -737,25 +734,33 @@ int CDMR2YSF::run()
|
|||||||
switch (fn) {
|
switch (fn) {
|
||||||
case 0:
|
case 0:
|
||||||
memset(dch, '*', YSF_CALLSIGN_LENGTH/2);
|
memset(dch, '*', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(dch + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(dch + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dch);
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dch);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)m_netSrc.c_str());
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (unsigned char*)m_netSrc.c_str());
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)m_netDst.c_str());
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (unsigned char*)m_netDst.c_str());
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
memset(dch, ' ', YSF_CALLSIGN_LENGTH/2);
|
memset(dch, ' ', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(dch + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(dch + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dch); // Rem3/4
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dch); // Rem3/4
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6: {
|
||||||
|
unsigned char dt1[10U] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U};
|
||||||
|
for (unsigned int i = 0U; i < m_conf.getYsfDT1().size() && i < 10U; i++)
|
||||||
|
dt1[i] = m_conf.getYsfDT1()[i];
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dt1);
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dt1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7: {
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dt2_temp);
|
unsigned char dt2[10U] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U};
|
||||||
|
for (unsigned int i = 0U; i < m_conf.getYsfDT2().size() && i < 10U; i++)
|
||||||
|
dt2[i] = m_conf.getYsfDT2()[i];
|
||||||
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dt2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)" ");
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)" ");
|
||||||
@ -763,18 +768,18 @@ int CDMR2YSF::run()
|
|||||||
|
|
||||||
// Set the FICH
|
// Set the FICH
|
||||||
fich.setFI(YSF_FI_COMMUNICATIONS);
|
fich.setFI(YSF_FI_COMMUNICATIONS);
|
||||||
fich.setCS(2U);
|
fich.setCS(m_conf.getFICHCallSign());
|
||||||
fich.setCM(1U);
|
fich.setCM(m_conf.getFICHCallMode());
|
||||||
fich.setBN(0U);
|
fich.setBN(0U);
|
||||||
fich.setBT(0U);
|
fich.setBT(0U);
|
||||||
fich.setFN(fn);
|
fich.setFN(fn);
|
||||||
fich.setFT(6U);
|
fich.setFT(m_conf.getFICHFrameTotal());
|
||||||
fich.setDev(0U);
|
fich.setDev(0U);
|
||||||
fich.setMR(0U);
|
fich.setMR(m_conf.getFICHMessageRoute());
|
||||||
fich.setVoIP(false);
|
fich.setVoIP(m_conf.getFICHVOIP());
|
||||||
fich.setDT(YSF_DT_VD_MODE2);
|
fich.setDT(m_conf.getFICHDataType());
|
||||||
fich.setSQL(0U);
|
fich.setSQL(m_conf.getFICHSQLType());
|
||||||
fich.setSQ(0U);
|
fich.setSQ(m_conf.getFICHSQLCode());
|
||||||
fich.encode(m_ysfFrame + 35U);
|
fich.encode(m_ysfFrame + 35U);
|
||||||
|
|
||||||
// Net frame counter
|
// Net frame counter
|
||||||
@ -923,9 +928,9 @@ unsigned int CDMR2YSF::findYSFID(std::string cs, bool showdst)
|
|||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
id = m_defsrcid;
|
id = m_defsrcid;
|
||||||
if (showdst)
|
if (showdst)
|
||||||
LogMessage("Not DMR ID found, using default ID: %u, DstID: %s%u", id, dmrpc ? "" : "TG ", m_dstid);
|
LogMessage("DMR ID not found, using default ID: %u, DstID: %s%u", id, dmrpc ? "" : "TG ", m_dstid);
|
||||||
else
|
else
|
||||||
LogMessage("Not DMR ID found, using default ID: %u", id);
|
LogMessage("DMR ID not found, using default ID: %u", id);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (showdst)
|
if (showdst)
|
||||||
|
@ -5,6 +5,17 @@ GatewayPort=4200
|
|||||||
LocalAddress=127.0.0.1
|
LocalAddress=127.0.0.1
|
||||||
LocalPort=3200
|
LocalPort=3200
|
||||||
FCSRooms=FCSRooms.txt
|
FCSRooms=FCSRooms.txt
|
||||||
|
# RadioID=*****
|
||||||
|
# FICHCallsign=2
|
||||||
|
# FICHCallMode=0
|
||||||
|
# FICHFrameTotal=7
|
||||||
|
# FICHMessageRoute=0
|
||||||
|
# FICHVOIP=0
|
||||||
|
# FICHDataType=2
|
||||||
|
# FICHSQLType=0
|
||||||
|
# FICHSQLCode=0
|
||||||
|
DT1=49,34,98,95,41,0,0,0,0,0
|
||||||
|
DT2=0,0,0,0,108,32,28,32,3,8
|
||||||
Daemon=0
|
Daemon=0
|
||||||
Debug=0
|
Debug=0
|
||||||
|
|
||||||
|
@ -20,6 +20,6 @@
|
|||||||
#if !defined(VERSION_H)
|
#if !defined(VERSION_H)
|
||||||
#define VERSION_H
|
#define VERSION_H
|
||||||
|
|
||||||
const char* VERSION = "20200503";
|
const char* VERSION = "20200605";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -609,7 +609,7 @@ std::string CYSFPayload::getDest()
|
|||||||
std::string tmp;
|
std::string tmp;
|
||||||
|
|
||||||
if (m_dest)
|
if (m_dest)
|
||||||
tmp.assign((const char *)m_dest, YSF_CALLSIGN_LENGTH);
|
tmp.assign((const char *)m_dest, 5);
|
||||||
else
|
else
|
||||||
tmp = "";
|
tmp = "";
|
||||||
|
|
||||||
|
@ -50,6 +50,17 @@ m_enableWiresX(false),
|
|||||||
m_remoteGateway(false),
|
m_remoteGateway(false),
|
||||||
m_hangTime(1000U),
|
m_hangTime(1000U),
|
||||||
m_wiresXMakeUpper(true),
|
m_wiresXMakeUpper(true),
|
||||||
|
m_fichCallSign(2U),
|
||||||
|
m_fichCallMode(0U),
|
||||||
|
m_fichFrameTotal(7U),
|
||||||
|
m_fichMessageRoute(0U),
|
||||||
|
m_fichVOIP(0U),
|
||||||
|
m_fichDataType(2U),
|
||||||
|
m_fichSQLType(0U),
|
||||||
|
m_fichSQLCode(0U),
|
||||||
|
m_ysfDT1(),
|
||||||
|
m_ysfDT2(),
|
||||||
|
m_ysfRadioID("*****"),
|
||||||
m_daemon(false),
|
m_daemon(false),
|
||||||
m_rxFrequency(0U),
|
m_rxFrequency(0U),
|
||||||
m_txFrequency(0U),
|
m_txFrequency(0U),
|
||||||
@ -142,6 +153,7 @@ bool CConf::read()
|
|||||||
|
|
||||||
// Remove quotes from the value
|
// Remove quotes from the value
|
||||||
size_t len = ::strlen(value);
|
size_t len = ::strlen(value);
|
||||||
|
char *t;
|
||||||
if (len > 1U && *value == '"' && value[len - 1U] == '"') {
|
if (len > 1U && *value == '"' && value[len - 1U] == '"') {
|
||||||
value[len - 1U] = '\0';
|
value[len - 1U] = '\0';
|
||||||
value++;
|
value++;
|
||||||
@ -176,6 +188,31 @@ bool CConf::read()
|
|||||||
m_wiresXMakeUpper = ::atoi(value) == 1;
|
m_wiresXMakeUpper = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Daemon") == 0)
|
else if (::strcmp(key, "Daemon") == 0)
|
||||||
m_daemon = ::atoi(value) == 1;
|
m_daemon = ::atoi(value) == 1;
|
||||||
|
else if (::strcmp(key, "RadioID") == 0)
|
||||||
|
m_ysfRadioID = value;
|
||||||
|
else if (::strcmp(key, "FICHCallsign") == 0)
|
||||||
|
m_fichCallSign = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHCallMode") == 0)
|
||||||
|
m_fichCallMode = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHFrameTotal") == 0)
|
||||||
|
m_fichFrameTotal = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHMessageRoute") == 0)
|
||||||
|
m_fichMessageRoute = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHVOIP") == 0)
|
||||||
|
m_fichVOIP = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHDataType") == 0)
|
||||||
|
m_fichDataType = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHSQLType") == 0)
|
||||||
|
m_fichSQLType = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHSQLCode") == 0)
|
||||||
|
m_fichSQLCode = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "DT1") == 0){
|
||||||
|
while ((t = strtok_r(value, ",", &value)) != NULL)
|
||||||
|
m_ysfDT1.push_back(::atoi(t));
|
||||||
|
} else if (::strcmp(key, "DT2") == 0){
|
||||||
|
while ((t = strtok_r(value, ",", &value)) != NULL)
|
||||||
|
m_ysfDT2.push_back(::atoi(t));
|
||||||
|
}
|
||||||
} else if (section == SECTION_INFO) {
|
} else if (section == SECTION_INFO) {
|
||||||
if (::strcmp(key, "TXFrequency") == 0)
|
if (::strcmp(key, "TXFrequency") == 0)
|
||||||
m_txFrequency = (unsigned int)::atoi(value);
|
m_txFrequency = (unsigned int)::atoi(value);
|
||||||
@ -334,6 +371,61 @@ bool CConf::getDaemon() const
|
|||||||
return m_daemon;
|
return m_daemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHCallSign() const
|
||||||
|
{
|
||||||
|
return m_fichCallSign;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHCallMode() const
|
||||||
|
{
|
||||||
|
return m_fichCallMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHFrameTotal() const
|
||||||
|
{
|
||||||
|
return m_fichFrameTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHMessageRoute() const
|
||||||
|
{
|
||||||
|
return m_fichMessageRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHVOIP() const
|
||||||
|
{
|
||||||
|
return m_fichVOIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHDataType() const
|
||||||
|
{
|
||||||
|
return m_fichDataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHSQLType() const
|
||||||
|
{
|
||||||
|
return m_fichSQLType;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHSQLCode() const
|
||||||
|
{
|
||||||
|
return m_fichSQLCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> CConf::getYsfDT1()
|
||||||
|
{
|
||||||
|
return m_ysfDT1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> CConf::getYsfDT2()
|
||||||
|
{
|
||||||
|
return m_ysfDT2;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getYsfRadioID()
|
||||||
|
{
|
||||||
|
return m_ysfRadioID;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int CConf::getRxFrequency() const
|
unsigned int CConf::getRxFrequency() const
|
||||||
{
|
{
|
||||||
return m_rxFrequency;
|
return m_rxFrequency;
|
||||||
|
@ -43,6 +43,20 @@ public:
|
|||||||
bool getRemoteGateway() const;
|
bool getRemoteGateway() const;
|
||||||
unsigned int getHangTime() const;
|
unsigned int getHangTime() const;
|
||||||
bool getWiresXMakeUpper() const;
|
bool getWiresXMakeUpper() const;
|
||||||
|
unsigned char getFICHCallSign() const;
|
||||||
|
unsigned char getFICHCallMode() const;
|
||||||
|
unsigned char getFICHFrameTotal() const;
|
||||||
|
unsigned char getFICHMessageRoute() const;
|
||||||
|
unsigned char getFICHVOIP() const;
|
||||||
|
unsigned char getFICHDataType() const;
|
||||||
|
unsigned char getFICHSQLType() const;
|
||||||
|
unsigned char getFICHSQLCode() const;
|
||||||
|
std::vector<unsigned char> getYsfDT1();
|
||||||
|
std::vector<unsigned char> getYsfDT2();
|
||||||
|
std::string getYsfRadioID();
|
||||||
|
unsigned char* getYsfDT1();
|
||||||
|
unsigned char* getYsfDT2();
|
||||||
|
char* getYsfRadioID();
|
||||||
bool getDaemon() const;
|
bool getDaemon() const;
|
||||||
|
|
||||||
// The Info section
|
// The Info section
|
||||||
@ -109,6 +123,17 @@ private:
|
|||||||
bool m_remoteGateway;
|
bool m_remoteGateway;
|
||||||
unsigned int m_hangTime;
|
unsigned int m_hangTime;
|
||||||
bool m_wiresXMakeUpper;
|
bool m_wiresXMakeUpper;
|
||||||
|
unsigned char m_fichCallSign;
|
||||||
|
unsigned char m_fichCallMode;
|
||||||
|
unsigned char m_fichFrameTotal;
|
||||||
|
unsigned char m_fichMessageRoute;
|
||||||
|
unsigned char m_fichVOIP;
|
||||||
|
unsigned char m_fichDataType;
|
||||||
|
unsigned char m_fichSQLType;
|
||||||
|
unsigned char m_fichSQLCode;
|
||||||
|
std::vector<unsigned char> m_ysfDT1;
|
||||||
|
std::vector<unsigned char> m_ysfDT2;
|
||||||
|
std::string m_ysfRadioID;
|
||||||
bool m_daemon;
|
bool m_daemon;
|
||||||
|
|
||||||
unsigned int m_rxFrequency;
|
unsigned int m_rxFrequency;
|
||||||
@ -157,7 +182,6 @@ private:
|
|||||||
std::string m_aprsAPIKey;
|
std::string m_aprsAPIKey;
|
||||||
unsigned int m_aprsRefresh;
|
unsigned int m_aprsRefresh;
|
||||||
std::string m_aprsDescription;
|
std::string m_aprsDescription;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,6 +20,6 @@
|
|||||||
#if !defined(VERSION_H)
|
#if !defined(VERSION_H)
|
||||||
#define VERSION_H
|
#define VERSION_H
|
||||||
|
|
||||||
const char* VERSION = "20200503";
|
const char* VERSION = "20200605";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
// DT1 and DT2, suggested by Manuel EA7EE
|
// DT1 and DT2, suggested by Manuel EA7EE
|
||||||
const unsigned char dt1_temp[] = {0x31, 0x22, 0x62, 0x5F, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00};
|
const unsigned char dt1_temp[] = {0x31, 0x22, 0x62, 0x5F, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
const unsigned char dt2_temp[] = {0x00, 0x00, 0x00, 0x00, 0x6C, 0x20, 0x1C, 0x20, 0x03, 0x08};
|
const unsigned char dt2_temp[] = {0x00, 0x00, 0x00, 0x00, 0x6C, 0x20, 0x1C, 0x20, 0x03, 0x08};
|
||||||
const uint8_t dt1[10] = {0x01, 0x22, 0x61, 0x5f, 0x2b, 0x03, 0x11, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
#define DMR_FRAME_PER 55U
|
#define DMR_FRAME_PER 55U
|
||||||
#define YSF_FRAME_PER 90U
|
#define YSF_FRAME_PER 90U
|
||||||
@ -51,7 +50,6 @@ const char* HEADER1 = "This software is for use on amateur radio networks only,"
|
|||||||
const char* HEADER2 = "it is to be used for educational purposes only. Its use on";
|
const char* HEADER2 = "it is to be used for educational purposes only. Its use on";
|
||||||
const char* HEADER3 = "commercial networks is strictly prohibited.";
|
const char* HEADER3 = "commercial networks is strictly prohibited.";
|
||||||
const char* HEADER4 = "Copyright(C) 2018,2019 by CA6JAU, EA7EE, G4KLX and others";
|
const char* HEADER4 = "Copyright(C) 2018,2019 by CA6JAU, EA7EE, G4KLX and others";
|
||||||
const char ysf_radioid[] = {'H', '5', '0', '0', '0'};
|
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -943,32 +941,23 @@ int CYSF2DMR::run()
|
|||||||
// Set the FICH
|
// Set the FICH
|
||||||
CYSFFICH fich;
|
CYSFFICH fich;
|
||||||
fich.setFI(YSF_FI_HEADER);
|
fich.setFI(YSF_FI_HEADER);
|
||||||
fich.setCS(2U);
|
fich.setCS(m_conf.getFICHCallSign());
|
||||||
fich.setCM(1U);
|
fich.setCM(m_conf.getFICHCallMode());
|
||||||
fich.setBN(0U);
|
fich.setBN(0U);
|
||||||
fich.setBT(0U);
|
fich.setBT(0U);
|
||||||
fich.setFN(0U);
|
fich.setFN(0U);
|
||||||
fich.setFT(6U);
|
fich.setFT(m_conf.getFICHFrameTotal());
|
||||||
fich.setDev(0U);
|
fich.setDev(0U);
|
||||||
fich.setMR(0U);
|
fich.setMR(m_conf.getFICHMessageRoute());
|
||||||
fich.setVoIP(false);
|
fich.setVoIP(m_conf.getFICHVOIP());
|
||||||
fich.setDT(YSF_DT_VD_MODE2);
|
fich.setDT(m_conf.getFICHDataType());
|
||||||
fich.setSQL(false);
|
fich.setSQL(m_conf.getFICHSQLType());
|
||||||
fich.setSQ(0U);
|
fich.setSQ(m_conf.getFICHSQLCode());
|
||||||
|
|
||||||
if (m_remoteGateway) {
|
|
||||||
fich.setVoIP(false);
|
|
||||||
fich.setMR(YSF_MR_DIRECT);
|
|
||||||
} else {
|
|
||||||
fich.setVoIP(true);
|
|
||||||
fich.setMR(YSF_MR_BUSY);
|
|
||||||
}
|
|
||||||
|
|
||||||
fich.encode(m_ysfFrame + 35U);
|
fich.encode(m_ysfFrame + 35U);
|
||||||
|
|
||||||
unsigned char csd1[20U], csd2[20U];
|
unsigned char csd1[20U], csd2[20U];
|
||||||
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
||||||
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||||
|
|
||||||
@ -992,32 +981,23 @@ int CYSF2DMR::run()
|
|||||||
// Set the FICH
|
// Set the FICH
|
||||||
CYSFFICH fich;
|
CYSFFICH fich;
|
||||||
fich.setFI(YSF_FI_TERMINATOR);
|
fich.setFI(YSF_FI_TERMINATOR);
|
||||||
fich.setCS(2U);
|
fich.setCS(m_conf.getFICHCallSign());
|
||||||
fich.setCM(1U);
|
fich.setCM(m_conf.getFICHCallMode());
|
||||||
fich.setBN(0U);
|
fich.setBN(0U);
|
||||||
fich.setBT(0U);
|
fich.setBT(0U);
|
||||||
fich.setFN(0U);
|
fich.setFN(0U);
|
||||||
fich.setFT(6U);
|
fich.setFT(m_conf.getFICHFrameTotal());
|
||||||
fich.setDev(0U);
|
fich.setDev(0U);
|
||||||
fich.setMR(0U);
|
fich.setMR(m_conf.getFICHMessageRoute());
|
||||||
fich.setVoIP(false);
|
fich.setVoIP(m_conf.getFICHVOIP());
|
||||||
fich.setDT(YSF_DT_VD_MODE2);
|
fich.setDT(m_conf.getFICHDataType());
|
||||||
fich.setSQL(false);
|
fich.setSQL(m_conf.getFICHSQLType());
|
||||||
fich.setSQ(0U);
|
fich.setSQ(m_conf.getFICHSQLCode());
|
||||||
|
|
||||||
if (m_remoteGateway) {
|
|
||||||
fich.setVoIP(false);
|
|
||||||
fich.setMR(YSF_MR_DIRECT);
|
|
||||||
} else {
|
|
||||||
fich.setVoIP(true);
|
|
||||||
fich.setMR(YSF_MR_BUSY);
|
|
||||||
}
|
|
||||||
|
|
||||||
fich.encode(m_ysfFrame + 35U);
|
fich.encode(m_ysfFrame + 35U);
|
||||||
|
|
||||||
unsigned char csd1[20U], csd2[20U];
|
unsigned char csd1[20U], csd2[20U];
|
||||||
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
||||||
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||||
|
|
||||||
@ -1031,7 +1011,7 @@ int CYSF2DMR::run()
|
|||||||
CYSFPayload ysfPayload;
|
CYSFPayload ysfPayload;
|
||||||
unsigned char dch[10U];
|
unsigned char dch[10U];
|
||||||
|
|
||||||
unsigned int fn = (ysf_cnt - 1U) % 7U;
|
unsigned int fn = (ysf_cnt - 1U) % (m_conf.getFICHFrameTotal() + 1);
|
||||||
|
|
||||||
::memcpy(m_ysfFrame + 0U, "YSFD", 4U);
|
::memcpy(m_ysfFrame + 0U, "YSFD", 4U);
|
||||||
::memcpy(m_ysfFrame + 4U, m_ysfNetwork->getCallsign().c_str(), YSF_CALLSIGN_LENGTH);
|
::memcpy(m_ysfFrame + 4U, m_ysfNetwork->getCallsign().c_str(), YSF_CALLSIGN_LENGTH);
|
||||||
@ -1044,25 +1024,33 @@ int CYSF2DMR::run()
|
|||||||
switch (fn) {
|
switch (fn) {
|
||||||
case 0:
|
case 0:
|
||||||
memset(dch, '*', YSF_CALLSIGN_LENGTH/2);
|
memset(dch, '*', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(dch + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(dch + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dch);
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dch);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)m_netSrc.c_str());
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (unsigned char*)m_netSrc.c_str());
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)m_netDst.c_str());
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (unsigned char*)m_netDst.c_str());
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
memset(dch, ' ', YSF_CALLSIGN_LENGTH/2);
|
memset(dch, ' ', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(dch + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(dch + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dch); // Rem3/4
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dch); // Rem3/4
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6: {
|
||||||
|
unsigned char dt1[10U] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U};
|
||||||
|
for (unsigned int i = 0U; i < m_conf.getYsfDT1().size() && i < 10U; i++)
|
||||||
|
dt1[i] = m_conf.getYsfDT1()[i];
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dt1);
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dt1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7: {
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dt2_temp);
|
unsigned char dt2[10U] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U};
|
||||||
|
for (unsigned int i = 0U; i < m_conf.getYsfDT2().size() && i < 10U; i++)
|
||||||
|
dt2[i] = m_conf.getYsfDT2()[i];
|
||||||
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dt2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)" ");
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)" ");
|
||||||
@ -1070,27 +1058,18 @@ int CYSF2DMR::run()
|
|||||||
|
|
||||||
// Set the FICH
|
// Set the FICH
|
||||||
fich.setFI(YSF_FI_COMMUNICATIONS);
|
fich.setFI(YSF_FI_COMMUNICATIONS);
|
||||||
fich.setCS(2U);
|
fich.setCS(m_conf.getFICHCallSign());
|
||||||
fich.setCM(1U);
|
fich.setCM(m_conf.getFICHCallMode());
|
||||||
fich.setBN(0U);
|
fich.setBN(0U);
|
||||||
fich.setBT(0U);
|
fich.setBT(0U);
|
||||||
fich.setFN(fn);
|
fich.setFN(fn);
|
||||||
fich.setFT(6U);
|
fich.setFT(m_conf.getFICHFrameTotal());
|
||||||
fich.setDev(0U);
|
fich.setDev(0U);
|
||||||
fich.setMR(0U);
|
fich.setMR(m_conf.getFICHMessageRoute());
|
||||||
fich.setVoIP(false);
|
fich.setVoIP(m_conf.getFICHVOIP());
|
||||||
fich.setDT(YSF_DT_VD_MODE2);
|
fich.setDT(m_conf.getFICHDataType());
|
||||||
fich.setSQL(false);
|
fich.setSQL(m_conf.getFICHSQLType());
|
||||||
fich.setSQ(0U);
|
fich.setSQ(m_conf.getFICHSQLCode());
|
||||||
|
|
||||||
if (m_remoteGateway) {
|
|
||||||
fich.setVoIP(false);
|
|
||||||
fich.setMR(YSF_MR_DIRECT);
|
|
||||||
} else {
|
|
||||||
fich.setVoIP(true);
|
|
||||||
fich.setMR(YSF_MR_BUSY);
|
|
||||||
}
|
|
||||||
|
|
||||||
fich.encode(m_ysfFrame + 35U);
|
fich.encode(m_ysfFrame + 35U);
|
||||||
|
|
||||||
// Net frame counter
|
// Net frame counter
|
||||||
|
@ -21,6 +21,18 @@ EnableWiresX=1
|
|||||||
RemoteGateway=0
|
RemoteGateway=0
|
||||||
HangTime=1000
|
HangTime=1000
|
||||||
WiresXMakeUpper=1
|
WiresXMakeUpper=1
|
||||||
|
# RadioID=*****
|
||||||
|
# FICHCallsign=2
|
||||||
|
# FICHCallMode=0
|
||||||
|
# FICHBlockTotal=0
|
||||||
|
# FICHFrameTotal=7
|
||||||
|
# FICHMessageRoute=0
|
||||||
|
# FICHVOIP=0
|
||||||
|
# FICHDataType=2
|
||||||
|
# FICHSQLType=0
|
||||||
|
# FICHSQLCode=0
|
||||||
|
DT1=49,34,98,95,41,0,0,0,0,0
|
||||||
|
DT2=0,0,0,0,108,32,28,32,3,8
|
||||||
Daemon=0
|
Daemon=0
|
||||||
|
|
||||||
[DMR Network]
|
[DMR Network]
|
||||||
|
@ -47,6 +47,17 @@ m_localAddress(),
|
|||||||
m_localPort(0U),
|
m_localPort(0U),
|
||||||
m_enableWiresX(false),
|
m_enableWiresX(false),
|
||||||
m_wiresXMakeUpper(true),
|
m_wiresXMakeUpper(true),
|
||||||
|
m_fichCallSign(2U),
|
||||||
|
m_fichCallMode(0U),
|
||||||
|
m_fichFrameTotal(7U),
|
||||||
|
m_fichMessageRoute(0U),
|
||||||
|
m_fichVOIP(0U),
|
||||||
|
m_fichDataType(2U),
|
||||||
|
m_fichSQLType(0U),
|
||||||
|
m_fichSQLCode(0U),
|
||||||
|
m_ysfDT1(),
|
||||||
|
m_ysfDT2(),
|
||||||
|
m_ysfRadioID("*****"),
|
||||||
m_daemon(false),
|
m_daemon(false),
|
||||||
m_rxFrequency(0U),
|
m_rxFrequency(0U),
|
||||||
m_txFrequency(0U),
|
m_txFrequency(0U),
|
||||||
@ -126,6 +137,7 @@ bool CConf::read()
|
|||||||
|
|
||||||
// Remove quotes from the value
|
// Remove quotes from the value
|
||||||
size_t len = ::strlen(value);
|
size_t len = ::strlen(value);
|
||||||
|
char *t;
|
||||||
if (len > 1U && *value == '"' && value[len - 1U] == '"') {
|
if (len > 1U && *value == '"' && value[len - 1U] == '"') {
|
||||||
value[len - 1U] = '\0';
|
value[len - 1U] = '\0';
|
||||||
value++;
|
value++;
|
||||||
@ -167,6 +179,31 @@ bool CConf::read()
|
|||||||
m_enableWiresX = ::atoi(value) == 1;
|
m_enableWiresX = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "WiresXMakeUpper") == 0)
|
else if (::strcmp(key, "WiresXMakeUpper") == 0)
|
||||||
m_wiresXMakeUpper = ::atoi(value) == 1;
|
m_wiresXMakeUpper = ::atoi(value) == 1;
|
||||||
|
else if (::strcmp(key, "RadioID") == 0)
|
||||||
|
m_ysfRadioID = value;
|
||||||
|
else if (::strcmp(key, "FICHCallsign") == 0)
|
||||||
|
m_fichCallSign = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHCallMode") == 0)
|
||||||
|
m_fichCallMode = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHFrameTotal") == 0)
|
||||||
|
m_fichFrameTotal = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHMessageRoute") == 0)
|
||||||
|
m_fichMessageRoute = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHVOIP") == 0)
|
||||||
|
m_fichVOIP = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHDataType") == 0)
|
||||||
|
m_fichDataType = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHSQLType") == 0)
|
||||||
|
m_fichSQLType = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHSQLCode") == 0)
|
||||||
|
m_fichSQLCode = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "DT1") == 0){
|
||||||
|
while ((t = strtok_r(value, ",", &value)) != NULL)
|
||||||
|
m_ysfDT1.push_back(::atoi(t));
|
||||||
|
} else if (::strcmp(key, "DT2") == 0){
|
||||||
|
while ((t = strtok_r(value, ",", &value)) != NULL)
|
||||||
|
m_ysfDT2.push_back(::atoi(t));
|
||||||
|
}
|
||||||
else if (::strcmp(key, "Daemon") == 0)
|
else if (::strcmp(key, "Daemon") == 0)
|
||||||
m_daemon = ::atoi(value) == 1;
|
m_daemon = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_NXDN_NETWORK) {
|
} else if (section == SECTION_NXDN_NETWORK) {
|
||||||
@ -293,6 +330,61 @@ bool CConf::getWiresXMakeUpper() const
|
|||||||
return m_wiresXMakeUpper;
|
return m_wiresXMakeUpper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHCallSign() const
|
||||||
|
{
|
||||||
|
return m_fichCallSign;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHCallMode() const
|
||||||
|
{
|
||||||
|
return m_fichCallMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHFrameTotal() const
|
||||||
|
{
|
||||||
|
return m_fichFrameTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHMessageRoute() const
|
||||||
|
{
|
||||||
|
return m_fichMessageRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHVOIP() const
|
||||||
|
{
|
||||||
|
return m_fichVOIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHDataType() const
|
||||||
|
{
|
||||||
|
return m_fichDataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHSQLType() const
|
||||||
|
{
|
||||||
|
return m_fichSQLType;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHSQLCode() const
|
||||||
|
{
|
||||||
|
return m_fichSQLCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> CConf::getYsfDT1()
|
||||||
|
{
|
||||||
|
return m_ysfDT1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> CConf::getYsfDT2()
|
||||||
|
{
|
||||||
|
return m_ysfDT2;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getYsfRadioID()
|
||||||
|
{
|
||||||
|
return m_ysfRadioID;
|
||||||
|
}
|
||||||
|
|
||||||
bool CConf::getDaemon() const
|
bool CConf::getDaemon() const
|
||||||
{
|
{
|
||||||
return m_daemon;
|
return m_daemon;
|
||||||
|
@ -48,6 +48,17 @@ public:
|
|||||||
unsigned int getLocalPort() const;
|
unsigned int getLocalPort() const;
|
||||||
bool getEnableWiresX() const;
|
bool getEnableWiresX() const;
|
||||||
bool getWiresXMakeUpper() const;
|
bool getWiresXMakeUpper() const;
|
||||||
|
unsigned char getFICHCallSign() const;
|
||||||
|
unsigned char getFICHCallMode() const;
|
||||||
|
unsigned char getFICHFrameTotal() const;
|
||||||
|
unsigned char getFICHMessageRoute() const;
|
||||||
|
unsigned char getFICHVOIP() const;
|
||||||
|
unsigned char getFICHDataType() const;
|
||||||
|
unsigned char getFICHSQLType() const;
|
||||||
|
unsigned char getFICHSQLCode() const;
|
||||||
|
std::vector<unsigned char> getYsfDT1();
|
||||||
|
std::vector<unsigned char> getYsfDT2();
|
||||||
|
std::string getYsfRadioID();
|
||||||
bool getDaemon() const;
|
bool getDaemon() const;
|
||||||
|
|
||||||
// The NXDN Network section
|
// The NXDN Network section
|
||||||
@ -90,6 +101,17 @@ private:
|
|||||||
unsigned int m_localPort;
|
unsigned int m_localPort;
|
||||||
bool m_enableWiresX;
|
bool m_enableWiresX;
|
||||||
bool m_wiresXMakeUpper;
|
bool m_wiresXMakeUpper;
|
||||||
|
unsigned char m_fichCallSign;
|
||||||
|
unsigned char m_fichCallMode;
|
||||||
|
unsigned char m_fichFrameTotal;
|
||||||
|
unsigned char m_fichMessageRoute;
|
||||||
|
unsigned char m_fichVOIP;
|
||||||
|
unsigned char m_fichDataType;
|
||||||
|
unsigned char m_fichSQLType;
|
||||||
|
unsigned char m_fichSQLCode;
|
||||||
|
std::vector<unsigned char> m_ysfDT1;
|
||||||
|
std::vector<unsigned char> m_ysfDT2;
|
||||||
|
std::string m_ysfRadioID;
|
||||||
bool m_daemon;
|
bool m_daemon;
|
||||||
|
|
||||||
unsigned int m_rxFrequency;
|
unsigned int m_rxFrequency;
|
||||||
|
@ -20,6 +20,6 @@
|
|||||||
#if !defined(VERSION_H)
|
#if !defined(VERSION_H)
|
||||||
#define VERSION_H
|
#define VERSION_H
|
||||||
|
|
||||||
const char* VERSION = "20200503";
|
const char* VERSION = "20200605";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
// DT1 and DT2, suggested by Manuel EA7EE
|
// DT1 and DT2, suggested by Manuel EA7EE
|
||||||
const unsigned char dt1_temp[] = {0x31, 0x22, 0x62, 0x5F, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00};
|
const unsigned char dt1_temp[] = {0x31, 0x22, 0x62, 0x5F, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
const unsigned char dt2_temp[] = {0x00, 0x00, 0x00, 0x00, 0x6C, 0x20, 0x1C, 0x20, 0x03, 0x08};
|
const unsigned char dt2_temp[] = {0x00, 0x00, 0x00, 0x00, 0x6C, 0x20, 0x1C, 0x20, 0x03, 0x08};
|
||||||
const uint8_t dt1[10] = {0x01, 0x22, 0x61, 0x5f, 0x2b, 0x03, 0x11, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
#define NXDN_FRAME_PER 75U
|
#define NXDN_FRAME_PER 75U
|
||||||
#define YSF_FRAME_PER 90U
|
#define YSF_FRAME_PER 90U
|
||||||
@ -48,7 +47,6 @@ const char* HEADER1 = "This software is for use on amateur radio networks only,"
|
|||||||
const char* HEADER2 = "it is to be used for educational purposes only. Its use on";
|
const char* HEADER2 = "it is to be used for educational purposes only. Its use on";
|
||||||
const char* HEADER3 = "commercial networks is strictly prohibited.";
|
const char* HEADER3 = "commercial networks is strictly prohibited.";
|
||||||
const char* HEADER4 = "Copyright(C) 2018,2019 by CA6JAU, G4KLX and others";
|
const char* HEADER4 = "Copyright(C) 2018,2019 by CA6JAU, G4KLX and others";
|
||||||
const char ysf_radioid[] = {'H', '5', '0', '0', '0'};
|
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -606,24 +604,23 @@ int CYSF2NXDN::run()
|
|||||||
// Set the FICH
|
// Set the FICH
|
||||||
CYSFFICH fich;
|
CYSFFICH fich;
|
||||||
fich.setFI(YSF_FI_HEADER);
|
fich.setFI(YSF_FI_HEADER);
|
||||||
fich.setCS(2U);
|
fich.setCS(m_conf.getFICHCallSign());
|
||||||
fich.setCM(1U);
|
fich.setCM(m_conf.getFICHCallMode());
|
||||||
fich.setBN(0U);
|
fich.setBN(0U);
|
||||||
fich.setBT(0U);
|
fich.setBT(0U);
|
||||||
fich.setFN(0U);
|
fich.setFN(0U);
|
||||||
fich.setFT(6U);
|
fich.setFT(m_conf.getFICHFrameTotal());
|
||||||
fich.setDev(0U);
|
fich.setDev(0U);
|
||||||
fich.setMR(0U);
|
fich.setMR(m_conf.getFICHMessageRoute());
|
||||||
fich.setVoIP(false);
|
fich.setVoIP(m_conf.getFICHVOIP());
|
||||||
fich.setDT(YSF_DT_VD_MODE2);
|
fich.setDT(m_conf.getFICHDataType());
|
||||||
fich.setSQL(0U);
|
fich.setSQL(m_conf.getFICHSQLType());
|
||||||
fich.setSQ(0U);
|
fich.setSQ(m_conf.getFICHSQLCode());
|
||||||
fich.encode(m_ysfFrame + 35U);
|
fich.encode(m_ysfFrame + 35U);
|
||||||
|
|
||||||
unsigned char csd1[20U], csd2[20U];
|
unsigned char csd1[20U], csd2[20U];
|
||||||
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
//memset(csd1, '*', YSF_CALLSIGN_LENGTH);
|
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
||||||
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||||
|
|
||||||
@ -646,25 +643,24 @@ int CYSF2NXDN::run()
|
|||||||
|
|
||||||
// Set the FICH
|
// Set the FICH
|
||||||
CYSFFICH fich;
|
CYSFFICH fich;
|
||||||
fich.setFI(YSF_FI_TERMINATOR);
|
fich.setFI(YSF_FI_HEADER);
|
||||||
fich.setCS(2U);
|
fich.setCS(m_conf.getFICHCallSign());
|
||||||
fich.setCM(1U);
|
fich.setCM(m_conf.getFICHCallMode());
|
||||||
fich.setBN(0U);
|
fich.setBN(0U);
|
||||||
fich.setBT(0U);
|
fich.setBT(0U);
|
||||||
fich.setFN(0U);
|
fich.setFN(0U);
|
||||||
fich.setFT(6U);
|
fich.setFT(m_conf.getFICHFrameTotal());
|
||||||
fich.setDev(0U);
|
fich.setDev(0U);
|
||||||
fich.setMR(0U);
|
fich.setMR(m_conf.getFICHMessageRoute());
|
||||||
fich.setVoIP(false);
|
fich.setVoIP(m_conf.getFICHVOIP());
|
||||||
fich.setDT(YSF_DT_VD_MODE2);
|
fich.setDT(m_conf.getFICHDataType());
|
||||||
fich.setSQL(0U);
|
fich.setSQL(m_conf.getFICHSQLType());
|
||||||
fich.setSQ(0U);
|
fich.setSQ(m_conf.getFICHSQLCode());
|
||||||
fich.encode(m_ysfFrame + 35U);
|
fich.encode(m_ysfFrame + 35U);
|
||||||
|
|
||||||
unsigned char csd1[20U], csd2[20U];
|
unsigned char csd1[20U], csd2[20U];
|
||||||
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
//memset(csd1, '*', YSF_CALLSIGN_LENGTH);
|
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
||||||
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||||
|
|
||||||
@ -691,26 +687,33 @@ int CYSF2NXDN::run()
|
|||||||
switch (fn) {
|
switch (fn) {
|
||||||
case 0:
|
case 0:
|
||||||
memset(dch, '*', YSF_CALLSIGN_LENGTH/2);
|
memset(dch, '*', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(dch + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(dch + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dch);
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dch);
|
||||||
//ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)"**********");
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)m_netSrc.c_str());
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (unsigned char*)m_netSrc.c_str());
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)m_netDst.c_str());
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (unsigned char*)m_netDst.c_str());
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
memset(dch, ' ', YSF_CALLSIGN_LENGTH/2);
|
memset(dch, ' ', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(dch + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(dch + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dch); // Rem3/4
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dch); // Rem3/4
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6: {
|
||||||
|
unsigned char dt1[10U] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U};
|
||||||
|
for (unsigned int i = 0U; i < m_conf.getYsfDT1().size() && i < 10U; i++)
|
||||||
|
dt1[i] = m_conf.getYsfDT1()[i];
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dt1);
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dt1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7: {
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dt2_temp);
|
unsigned char dt2[10U] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U};
|
||||||
|
for (unsigned int i = 0U; i < m_conf.getYsfDT2().size() && i < 10U; i++)
|
||||||
|
dt2[i] = m_conf.getYsfDT2()[i];
|
||||||
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, dt2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)" ");
|
ysfPayload.writeVDMode2Data(m_ysfFrame + 35U, (const unsigned char*)" ");
|
||||||
@ -718,18 +721,18 @@ int CYSF2NXDN::run()
|
|||||||
|
|
||||||
// Set the FICH
|
// Set the FICH
|
||||||
fich.setFI(YSF_FI_COMMUNICATIONS);
|
fich.setFI(YSF_FI_COMMUNICATIONS);
|
||||||
fich.setCS(2U);
|
fich.setCS(m_conf.getFICHCallSign());
|
||||||
fich.setCM(1U);
|
fich.setCM(m_conf.getFICHCallMode());
|
||||||
fich.setBN(0U);
|
fich.setBN(0U);
|
||||||
fich.setBT(0U);
|
fich.setBT(0U);
|
||||||
fich.setFN(fn);
|
fich.setFN(fn);
|
||||||
fich.setFT(6U);
|
fich.setFT(m_conf.getFICHFrameTotal());
|
||||||
fich.setDev(0U);
|
fich.setDev(0U);
|
||||||
fich.setMR(0U);
|
fich.setMR(m_conf.getFICHMessageRoute());
|
||||||
fich.setVoIP(false);
|
fich.setVoIP(m_conf.getFICHVOIP());
|
||||||
fich.setDT(YSF_DT_VD_MODE2);
|
fich.setDT(m_conf.getFICHDataType());
|
||||||
fich.setSQL(0U);
|
fich.setSQL(m_conf.getFICHSQLType());
|
||||||
fich.setSQ(0U);
|
fich.setSQ(m_conf.getFICHSQLCode());
|
||||||
fich.encode(m_ysfFrame + 35U);
|
fich.encode(m_ysfFrame + 35U);
|
||||||
|
|
||||||
// Net frame counter
|
// Net frame counter
|
||||||
|
@ -16,6 +16,18 @@ LocalAddress=127.0.0.1
|
|||||||
LocalPort=42014
|
LocalPort=42014
|
||||||
EnableWiresX=1
|
EnableWiresX=1
|
||||||
WiresXMakeUpper=1
|
WiresXMakeUpper=1
|
||||||
|
# RadioID=*****
|
||||||
|
# FICHCallsign=2
|
||||||
|
# FICHCallMode=0
|
||||||
|
# FICHBlockTotal=0
|
||||||
|
# FICHFrameTotal=7
|
||||||
|
# FICHMessageRoute=0
|
||||||
|
# FICHVOIP=0
|
||||||
|
# FICHDataType=2
|
||||||
|
# FICHSQLType=0
|
||||||
|
# FICHSQLCode=0
|
||||||
|
DT1=49,34,98,95,41,0,0,0,0,0
|
||||||
|
DT2=0,0,0,0,108,32,28,32,3,8
|
||||||
Daemon=0
|
Daemon=0
|
||||||
|
|
||||||
[NXDN Network]
|
[NXDN Network]
|
||||||
|
@ -46,6 +46,17 @@ m_localAddress(),
|
|||||||
m_localPort(0U),
|
m_localPort(0U),
|
||||||
m_enableWiresX(false),
|
m_enableWiresX(false),
|
||||||
m_wiresXMakeUpper(true),
|
m_wiresXMakeUpper(true),
|
||||||
|
m_fichCallSign(2U),
|
||||||
|
m_fichCallMode(0U),
|
||||||
|
m_fichFrameTotal(7U),
|
||||||
|
m_fichMessageRoute(0U),
|
||||||
|
m_fichVOIP(0U),
|
||||||
|
m_fichDataType(2U),
|
||||||
|
m_fichSQLType(0U),
|
||||||
|
m_fichSQLCode(0U),
|
||||||
|
m_ysfDT1(),
|
||||||
|
m_ysfDT2(),
|
||||||
|
m_ysfRadioID("*****"),
|
||||||
m_daemon(false),
|
m_daemon(false),
|
||||||
m_networkDebug(false),
|
m_networkDebug(false),
|
||||||
m_rxFrequency(0U),
|
m_rxFrequency(0U),
|
||||||
@ -114,6 +125,7 @@ bool CConf::read()
|
|||||||
|
|
||||||
// Remove quotes from the value
|
// Remove quotes from the value
|
||||||
size_t len = ::strlen(value);
|
size_t len = ::strlen(value);
|
||||||
|
char *t;
|
||||||
if (len > 1U && *value == '"' && value[len - 1U] == '"') {
|
if (len > 1U && *value == '"' && value[len - 1U] == '"') {
|
||||||
value[len - 1U] = '\0';
|
value[len - 1U] = '\0';
|
||||||
value++;
|
value++;
|
||||||
@ -149,6 +161,31 @@ bool CConf::read()
|
|||||||
m_enableWiresX = ::atoi(value) == 1;
|
m_enableWiresX = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "WiresXMakeUpper") == 0)
|
else if (::strcmp(key, "WiresXMakeUpper") == 0)
|
||||||
m_wiresXMakeUpper = ::atoi(value) == 1;
|
m_wiresXMakeUpper = ::atoi(value) == 1;
|
||||||
|
else if (::strcmp(key, "RadioID") == 0)
|
||||||
|
m_ysfRadioID = value;
|
||||||
|
else if (::strcmp(key, "FICHCallsign") == 0)
|
||||||
|
m_fichCallSign = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHCallMode") == 0)
|
||||||
|
m_fichCallMode = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHFrameTotal") == 0)
|
||||||
|
m_fichFrameTotal = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHMessageRoute") == 0)
|
||||||
|
m_fichMessageRoute = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHVOIP") == 0)
|
||||||
|
m_fichVOIP = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHDataType") == 0)
|
||||||
|
m_fichDataType = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHSQLType") == 0)
|
||||||
|
m_fichSQLType = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "FICHSQLCode") == 0)
|
||||||
|
m_fichSQLCode = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "DT1") == 0){
|
||||||
|
while ((t = strtok_r(value, ",", &value)) != NULL)
|
||||||
|
m_ysfDT1.push_back(::atoi(t));
|
||||||
|
} else if (::strcmp(key, "DT2") == 0){
|
||||||
|
while ((t = strtok_r(value, ",", &value)) != NULL)
|
||||||
|
m_ysfDT2.push_back(::atoi(t));
|
||||||
|
}
|
||||||
else if (::strcmp(key, "Daemon") == 0)
|
else if (::strcmp(key, "Daemon") == 0)
|
||||||
m_daemon = ::atoi(value) == 1;
|
m_daemon = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
@ -247,6 +284,61 @@ bool CConf::getWiresXMakeUpper() const
|
|||||||
return m_wiresXMakeUpper;
|
return m_wiresXMakeUpper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHCallSign() const
|
||||||
|
{
|
||||||
|
return m_fichCallSign;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHCallMode() const
|
||||||
|
{
|
||||||
|
return m_fichCallMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHFrameTotal() const
|
||||||
|
{
|
||||||
|
return m_fichFrameTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHMessageRoute() const
|
||||||
|
{
|
||||||
|
return m_fichMessageRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHVOIP() const
|
||||||
|
{
|
||||||
|
return m_fichVOIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHDataType() const
|
||||||
|
{
|
||||||
|
return m_fichDataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHSQLType() const
|
||||||
|
{
|
||||||
|
return m_fichSQLType;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CConf::getFICHSQLCode() const
|
||||||
|
{
|
||||||
|
return m_fichSQLCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> CConf::getYsfDT1()
|
||||||
|
{
|
||||||
|
return m_ysfDT1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> CConf::getYsfDT2()
|
||||||
|
{
|
||||||
|
return m_ysfDT2;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getYsfRadioID()
|
||||||
|
{
|
||||||
|
return m_ysfRadioID;
|
||||||
|
}
|
||||||
|
|
||||||
bool CConf::getDaemon() const
|
bool CConf::getDaemon() const
|
||||||
{
|
{
|
||||||
return m_daemon;
|
return m_daemon;
|
||||||
|
@ -45,6 +45,17 @@ public:
|
|||||||
unsigned int getLocalPort() const;
|
unsigned int getLocalPort() const;
|
||||||
bool getEnableWiresX() const;
|
bool getEnableWiresX() const;
|
||||||
bool getWiresXMakeUpper() const;
|
bool getWiresXMakeUpper() const;
|
||||||
|
unsigned char getFICHCallSign() const;
|
||||||
|
unsigned char getFICHCallMode() const;
|
||||||
|
unsigned char getFICHFrameTotal() const;
|
||||||
|
unsigned char getFICHMessageRoute() const;
|
||||||
|
unsigned char getFICHVOIP() const;
|
||||||
|
unsigned char getFICHDataType() const;
|
||||||
|
unsigned char getFICHSQLType() const;
|
||||||
|
unsigned char getFICHSQLCode() const;
|
||||||
|
std::vector<unsigned char> getYsfDT1();
|
||||||
|
std::vector<unsigned char> getYsfDT2();
|
||||||
|
std::string getYsfRadioID();
|
||||||
bool getDaemon() const;
|
bool getDaemon() const;
|
||||||
bool getNetworkDebug() const;
|
bool getNetworkDebug() const;
|
||||||
|
|
||||||
@ -78,6 +89,17 @@ private:
|
|||||||
unsigned int m_localPort;
|
unsigned int m_localPort;
|
||||||
bool m_enableWiresX;
|
bool m_enableWiresX;
|
||||||
bool m_wiresXMakeUpper;
|
bool m_wiresXMakeUpper;
|
||||||
|
unsigned char m_fichCallSign;
|
||||||
|
unsigned char m_fichCallMode;
|
||||||
|
unsigned char m_fichFrameTotal;
|
||||||
|
unsigned char m_fichMessageRoute;
|
||||||
|
unsigned char m_fichVOIP;
|
||||||
|
unsigned char m_fichDataType;
|
||||||
|
unsigned char m_fichSQLType;
|
||||||
|
unsigned char m_fichSQLCode;
|
||||||
|
std::vector<unsigned char> m_ysfDT1;
|
||||||
|
std::vector<unsigned char> m_ysfDT2;
|
||||||
|
std::string m_ysfRadioID;
|
||||||
bool m_daemon;
|
bool m_daemon;
|
||||||
bool m_networkDebug;
|
bool m_networkDebug;
|
||||||
|
|
||||||
|
@ -20,6 +20,6 @@
|
|||||||
#if !defined(VERSION_H)
|
#if !defined(VERSION_H)
|
||||||
#define VERSION_H
|
#define VERSION_H
|
||||||
|
|
||||||
const char* VERSION = "20200503";
|
const char* VERSION = "20200605";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -92,8 +92,6 @@ const unsigned char REC73[] = {
|
|||||||
const unsigned char REC80[] = {
|
const unsigned char REC80[] = {
|
||||||
0x80U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U};
|
0x80U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U};
|
||||||
|
|
||||||
const uint8_t dt1[10] = {0x01, 0x22, 0x61, 0x5f, 0x2b, 0x03, 0x11, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
#define P25_FRAME_PER 15U
|
#define P25_FRAME_PER 15U
|
||||||
#define YSF_FRAME_PER 90U
|
#define YSF_FRAME_PER 90U
|
||||||
|
|
||||||
@ -107,7 +105,6 @@ const char* HEADER1 = "This software is for use on amateur radio networks only,"
|
|||||||
const char* HEADER2 = "it is to be used for educational purposes only. Its use on";
|
const char* HEADER2 = "it is to be used for educational purposes only. Its use on";
|
||||||
const char* HEADER3 = "commercial networks is strictly prohibited.";
|
const char* HEADER3 = "commercial networks is strictly prohibited.";
|
||||||
const char* HEADER4 = "Copyright(C) 2018,2019 by CA6JAU, G4KLX and others";
|
const char* HEADER4 = "Copyright(C) 2018,2019 by CA6JAU, G4KLX and others";
|
||||||
const char ysf_radioid[] = {'H', '5', '0', '0', '0'};
|
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -623,23 +620,23 @@ int CYSF2P25::run()
|
|||||||
// Set the FICH
|
// Set the FICH
|
||||||
CYSFFICH fich;
|
CYSFFICH fich;
|
||||||
fich.setFI(YSF_FI_HEADER);
|
fich.setFI(YSF_FI_HEADER);
|
||||||
fich.setCS(2U);
|
fich.setCS(m_conf.getFICHCallSign());
|
||||||
fich.setCM(1U);
|
fich.setCM(m_conf.getFICHCallMode());
|
||||||
fich.setBN(0U);
|
fich.setBN(0U);
|
||||||
fich.setBT(0U);
|
fich.setBT(0U);
|
||||||
fich.setFN(0U);
|
fich.setFN(0U);
|
||||||
fich.setFT(6U);
|
fich.setFT(m_conf.getFICHFrameTotal());
|
||||||
fich.setDev(0U);
|
fich.setDev(0U);
|
||||||
fich.setMR(0U);
|
fich.setMR(m_conf.getFICHMessageRoute());
|
||||||
fich.setVoIP(false);
|
fich.setVoIP(m_conf.getFICHVOIP());
|
||||||
fich.setDT(YSF_DT_VOICE_FR_MODE);
|
fich.setDT(m_conf.getFICHDataType());
|
||||||
fich.setSQL(0U);
|
fich.setSQL(m_conf.getFICHSQLType());
|
||||||
fich.setSQ(0U);
|
fich.setSQ(m_conf.getFICHSQLCode());
|
||||||
fich.encode(m_ysfFrame + 35U);
|
fich.encode(m_ysfFrame + 35U);
|
||||||
|
|
||||||
unsigned char csd1[20U], csd2[20U];
|
unsigned char csd1[20U], csd2[20U];
|
||||||
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
||||||
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||||
|
|
||||||
@ -663,23 +660,23 @@ int CYSF2P25::run()
|
|||||||
// Set the FICH
|
// Set the FICH
|
||||||
CYSFFICH fich;
|
CYSFFICH fich;
|
||||||
fich.setFI(YSF_FI_TERMINATOR);
|
fich.setFI(YSF_FI_TERMINATOR);
|
||||||
fich.setCS(2U);
|
fich.setCS(m_conf.getFICHCallSign());
|
||||||
fich.setCM(1U);
|
fich.setCM(m_conf.getFICHCallMode());
|
||||||
fich.setBN(0U);
|
fich.setBN(0U);
|
||||||
fich.setBT(0U);
|
fich.setBT(0U);
|
||||||
fich.setFN(0U);
|
fich.setFN(0U);
|
||||||
fich.setFT(6U);
|
fich.setFT(m_conf.getFICHFrameTotal());
|
||||||
fich.setDev(0U);
|
fich.setDev(0U);
|
||||||
fich.setMR(0U);
|
fich.setMR(m_conf.getFICHMessageRoute());
|
||||||
fich.setVoIP(false);
|
fich.setVoIP(m_conf.getFICHVOIP());
|
||||||
fich.setDT(YSF_DT_VOICE_FR_MODE);
|
fich.setDT(m_conf.getFICHDataType());
|
||||||
fich.setSQL(0U);
|
fich.setSQL(m_conf.getFICHSQLType());
|
||||||
fich.setSQ(0U);
|
fich.setSQ(m_conf.getFICHSQLCode());
|
||||||
fich.encode(m_ysfFrame + 35U);
|
fich.encode(m_ysfFrame + 35U);
|
||||||
|
|
||||||
unsigned char csd1[20U], csd2[20U];
|
unsigned char csd1[20U], csd2[20U];
|
||||||
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
memset(csd1, '*', YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, ysf_radioid, YSF_CALLSIGN_LENGTH/2);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH/2, m_conf.getYsfRadioID().c_str(), YSF_CALLSIGN_LENGTH/2);
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_netSrc.c_str(), YSF_CALLSIGN_LENGTH);
|
||||||
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||||
|
|
||||||
@ -705,18 +702,18 @@ int CYSF2P25::run()
|
|||||||
|
|
||||||
// Set the FICH
|
// Set the FICH
|
||||||
fich.setFI(YSF_FI_COMMUNICATIONS);
|
fich.setFI(YSF_FI_COMMUNICATIONS);
|
||||||
fich.setCS(2U);
|
fich.setCS(m_conf.getFICHCallSign());
|
||||||
fich.setCM(1U);
|
fich.setCM(m_conf.getFICHCallMode());
|
||||||
fich.setBN(0U);
|
fich.setBN(0U);
|
||||||
fich.setBT(0U);
|
fich.setBT(0U);
|
||||||
fich.setFN(fn);
|
fich.setFN(fn);
|
||||||
fich.setFT(6U);
|
fich.setFT(m_conf.getFICHFrameTotal());
|
||||||
fich.setDev(0U);
|
fich.setDev(0U);
|
||||||
fich.setMR(0U);
|
fich.setMR(m_conf.getFICHMessageRoute());
|
||||||
fich.setVoIP(false);
|
fich.setVoIP(m_conf.getFICHVOIP());
|
||||||
fich.setDT(YSF_DT_VOICE_FR_MODE);
|
fich.setDT(m_conf.getFICHDataType());
|
||||||
fich.setSQL(0U);
|
fich.setSQL(m_conf.getFICHSQLType());
|
||||||
fich.setSQ(0U);
|
fich.setSQ(m_conf.getFICHSQLCode());
|
||||||
fich.encode(m_ysfFrame + 35U);
|
fich.encode(m_ysfFrame + 35U);
|
||||||
|
|
||||||
// Net frame counter
|
// Net frame counter
|
||||||
|
@ -13,6 +13,18 @@ LocalAddress=127.0.0.1
|
|||||||
LocalPort=42015
|
LocalPort=42015
|
||||||
EnableWiresX=1
|
EnableWiresX=1
|
||||||
WiresXMakeUpper=1
|
WiresXMakeUpper=1
|
||||||
|
# RadioID=*****
|
||||||
|
# FICHCallsign=2
|
||||||
|
# FICHCallMode=0
|
||||||
|
# FICHBlockTotal=0
|
||||||
|
# FICHFrameTotal=7
|
||||||
|
# FICHMessageRoute=0
|
||||||
|
# FICHVOIP=0
|
||||||
|
# FICHDataType=2
|
||||||
|
# FICHSQLType=0
|
||||||
|
# FICHSQLCode=0
|
||||||
|
DT1=49,34,98,95,41,0,0,0,0,0
|
||||||
|
DT2=0,0,0,0,108,32,28,32,3,8
|
||||||
Daemon=0
|
Daemon=0
|
||||||
Debug=0
|
Debug=0
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user