diff --git a/DMR2YSF/Conf.cpp b/DMR2YSF/Conf.cpp index 03846d6..61f034d 100644 --- a/DMR2YSF/Conf.cpp +++ b/DMR2YSF/Conf.cpp @@ -49,6 +49,8 @@ m_dmrRptPort(0U), m_dmrLocalAddress(), m_dmrLocalPort(0U), m_dmrDefaultDstTG(9U), +m_dmrNetworkTGUnlink(4000U), +m_dmrTGListFile(), m_dmrDebug(false), m_dmrIdLookupFile(), m_dmrIdLookupTime(0U), @@ -137,6 +139,10 @@ bool CConf::read() m_dmrLocalPort = (unsigned int)::atoi(value); else if (::strcmp(key, "DefaultDstTG") == 0) m_dmrDefaultDstTG = (unsigned int)::atoi(value); + else if (::strcmp(key, "TGUnlink") == 0) + m_dmrNetworkTGUnlink = (unsigned int)::atoi(value); + else if (::strcmp(key, "TGListFile") == 0) + m_dmrTGListFile = value; else if (::strcmp(key, "Debug") == 0) m_dmrDebug = ::atoi(value) == 1; } else if (section == SECTION_DMRID_LOOKUP) { @@ -221,6 +227,16 @@ unsigned int CConf::getDMRDefaultDstTG() const return m_dmrDefaultDstTG; } +unsigned int CConf::getDMRNetworkTGUnlink() const +{ + return m_dmrNetworkTGUnlink; +} + +std::string CConf::getDMRTGListFile() const +{ + return m_dmrTGListFile; +} + bool CConf::getDMRDebug() const { return m_dmrDebug; diff --git a/DMR2YSF/Conf.h b/DMR2YSF/Conf.h index 291e111..4baa0f6 100644 --- a/DMR2YSF/Conf.h +++ b/DMR2YSF/Conf.h @@ -46,6 +46,8 @@ public: std::string getDMRLocalAddress() const; unsigned int getDMRLocalPort() const; unsigned int getDMRDefaultDstTG() const; + unsigned int getDMRNetworkTGUnlink() const; + std::string getDMRTGListFile() const; bool getDMRDebug() const; // The DMR Id section @@ -73,6 +75,8 @@ private: std::string m_dmrLocalAddress; unsigned int m_dmrLocalPort; unsigned int m_dmrDefaultDstTG; + unsigned int m_dmrNetworkTGUnlink; + std::string m_dmrTGListFile; bool m_dmrDebug; std::string m_dmrIdLookupFile; diff --git a/DMR2YSF/DMR2YSF.cpp b/DMR2YSF/DMR2YSF.cpp index d3c6dbb..2ddb4ef 100644 --- a/DMR2YSF/DMR2YSF.cpp +++ b/DMR2YSF/DMR2YSF.cpp @@ -108,7 +108,11 @@ m_dmrFrames(0U), m_ysfFrames(0U), m_dmrinfo(false), m_config(NULL), -m_configLen(0U) +m_configLen(0U), +m_command(), +m_tgUnlink(4000U), +m_currTGList(), +m_lastTG(0U) { m_ysfFrame = new unsigned char[200U]; m_dmrFrame = new unsigned char[50U]; @@ -215,6 +219,15 @@ int CDMR2YSF::run() m_callsign = m_conf.getCallsign(); m_defsrcid = m_conf.getDMRId(); m_dstid = m_conf.getDMRDefaultDstTG(); + m_tgUnlink = m_conf.getDMRNetworkTGUnlink(); + std::string tgFile = m_conf.getDMRTGListFile(); + + LogInfo("General Parameters"); + LogInfo(" Default Dst TG: %u", m_dstid); + LogInfo(" Unlink TG: %u", m_tgUnlink); + LogInfo(" TG File: %s", tgFile.c_str()); + + readTGList(tgFile); in_addr dstAddress = CUDPSocket::lookup(m_conf.getDstAddress()); unsigned int dstPort = m_conf.getDstPort(); @@ -524,6 +537,7 @@ int CDMR2YSF::run() m_netDst.resize(YSF_CALLSIGN_LENGTH, ' '); m_dmrFrames = 0U; + connectYSF(m_dstid); } if(DataType == DT_VOICE_SYNC || DataType == DT_VOICE) { @@ -542,6 +556,8 @@ int CDMR2YSF::run() m_netSrc.resize(YSF_CALLSIGN_LENGTH, ' '); m_netDst.resize(YSF_CALLSIGN_LENGTH, ' '); + connectYSF(m_dstid); + m_dmrinfo = true; } @@ -726,6 +742,33 @@ int CDMR2YSF::run() return 0; } +void CDMR2YSF::readTGList(std::string filename) +{ + // Load file with TG List + FILE* fp = ::fopen(filename.c_str(), "rt"); + if (fp != NULL) { + char buffer[100U]; + while (::fgets(buffer, 100U, fp) != NULL) { + if (buffer[0U] == '#') + continue; + + char* p1 = ::strtok(buffer, ";\r\n"); + char* p2 = ::strtok(NULL, ";\r\n"); + + if (p1 != NULL && p2 != NULL) { + CTGReg* tgreg = new CTGReg; + + tgreg->m_tg = atoi(p1); + tgreg->m_ysf = atoi(p2); + + m_currTGList.push_back(tgreg); + } + } + + ::fclose(fp); + } +} + unsigned int CDMR2YSF::findYSFID(std::string cs, bool showdst) { std::string cstrim; @@ -784,6 +827,17 @@ std::string CDMR2YSF::getSrcYSF(const unsigned char* buffer) return trimmed; } +void CDMR2YSF::connectYSF(unsigned int id) +{ + if (id == m_lastTG) + return; + + if (id == m_tgUnlink) + sendYSFDisc(); + + // TODO: connection ID search +} + void CDMR2YSF::sendYSFConn(unsigned int id) { unsigned char data[] = {0x00U, 0x5DU, 0x23U, 0x5FU, 0x24U, 0x20U, 0x20U, 0x20U, 0x20U, @@ -907,6 +961,7 @@ void CDMR2YSF::processWiresX(const unsigned char* data, unsigned char fi, unsign return; if (::memcmp(m_command + 1U, CONN_RESP, 4U) == 0) { + m_lastTG = m_dstid; LogMessage("Reflector connected OK"); return; } diff --git a/DMR2YSF/DMR2YSF.h b/DMR2YSF/DMR2YSF.h index c5b20c0..7724a88 100644 --- a/DMR2YSF/DMR2YSF.h +++ b/DMR2YSF/DMR2YSF.h @@ -44,6 +44,18 @@ #include +class CTGReg { +public: + CTGReg() : + m_tg(), + m_ysf() + { + } + + unsigned int m_tg; + unsigned int m_ysf; +}; + class CDMR2YSF { public: @@ -78,9 +90,14 @@ private: unsigned char* m_config; unsigned int m_configLen; unsigned char* m_command; + unsigned int m_tgUnlink; + std::vector m_currTGList; + unsigned int m_lastTG; + void readTGList(std::string filename); unsigned int findYSFID(std::string cs, bool showdst); std::string getSrcYSF(const unsigned char* source); + void connectYSF(unsigned int id); void sendYSFConn(unsigned int id); void sendYSFDisc(); void processWiresX(const unsigned char* data, unsigned char fi, unsigned char dt, unsigned char fn, unsigned char ft); diff --git a/DMR2YSF/DMR2YSF.ini b/DMR2YSF/DMR2YSF.ini index a8dc6b3..4c99a34 100644 --- a/DMR2YSF/DMR2YSF.ini +++ b/DMR2YSF/DMR2YSF.ini @@ -13,6 +13,8 @@ RptPort=62032 LocalAddress=127.0.0.1 LocalPort=62031 DefaultDstTG=9 +TGUnlink=4000 +TGListFile=TG-YSFList.txt Debug=0 [DMR Id Lookup] diff --git a/DMR2YSF/TG-YSFList.txt b/DMR2YSF/TG-YSFList.txt new file mode 100644 index 0000000..5f01035 --- /dev/null +++ b/DMR2YSF/TG-YSFList.txt @@ -0,0 +1,7 @@ +# This is just an example of DMR TG - YSF ID mapping +# +# DMR TG ID;YSF reflector ID +# +730;72350 +31010;2034 +7227;66099