diff --git a/DGIdGateway/Conf.cpp b/DGIdGateway/Conf.cpp index 6ababbb..0a30e8c 100644 --- a/DGIdGateway/Conf.cpp +++ b/DGIdGateway/Conf.cpp @@ -250,6 +250,10 @@ bool CConf::read() dgIdData->m_rfHangTime = m_fcsRFHangTime; dgIdData->m_netHangTime = m_fcsNetHangTime; dgIdData->m_debug = m_fcsNetDebug; + } else if (::strcmp(value, "YCS") == 0) { + dgIdData->m_rfHangTime = m_ysfRFHangTime; + dgIdData->m_netHangTime = m_ysfNetHangTime; + dgIdData->m_debug = m_ysfNetDebug; } else { dgIdData->m_rfHangTime = m_rfHangTime; dgIdData->m_netHangTime = m_netHangTime; @@ -261,8 +265,6 @@ bool CConf::read() dgIdData->m_netHangTime = (unsigned int)::atoi(value); else if (::strcmp(key, "Static") == 0) dgIdData->m_static = ::atoi(value) == 1; - else if (::strcmp(key, "Options") == 0) - dgIdData->m_options = value; else if (::strcmp(key, "Address") == 0) dgIdData->m_address = value; else if (::strcmp(key, "Name") == 0) @@ -271,6 +273,8 @@ bool CConf::read() dgIdData->m_port = (unsigned int)::atoi(value); else if (::strcmp(key, "Local") == 0) dgIdData->m_local = (unsigned int)::atoi(value); + else if (::strcmp(key, "DGId") == 0) + dgIdData->m_netDGId = (unsigned int)::atoi(value); else if (::strcmp(key, "Destination") == 0) { char* p1 = ::strtok(value, ","); char* p2 = ::strtok(NULL, "\r\n"); diff --git a/DGIdGateway/Conf.h b/DGIdGateway/Conf.h index 755727b..d29c5ab 100644 --- a/DGIdGateway/Conf.h +++ b/DGIdGateway/Conf.h @@ -31,11 +31,11 @@ struct DGIdData { unsigned int m_dgId; std::string m_type; bool m_static; - std::string m_options; std::string m_name; std::string m_address; unsigned int m_port; unsigned int m_local; + unsigned int m_netDGId; std::vector m_destinations; unsigned int m_rfHangTime; unsigned int m_netHangTime; diff --git a/DGIdGateway/DGIdGateway.cpp b/DGIdGateway/DGIdGateway.cpp index c6ad905..2f33979 100644 --- a/DGIdGateway/DGIdGateway.cpp +++ b/DGIdGateway/DGIdGateway.cpp @@ -236,9 +236,8 @@ int CDGIdGateway::run() unsigned int rxFrequency = m_conf.getRxFrequency(); std::string locator = calculateLocator(); unsigned int id = m_conf.getId(); - std::string options = (*it)->m_options; - dgIdNetwork[dgid] = new CFCSNetwork(name, local, m_callsign, rxFrequency, txFrequency, locator, id, options, debug); + dgIdNetwork[dgid] = new CFCSNetwork(name, local, m_callsign, rxFrequency, txFrequency, locator, id, debug); dgIdNetwork[dgid]->m_modes = DT_VD_MODE1 | DT_VD_MODE2 | DT_VOICE_FR_MODE | DT_DATA_FR_MODE; dgIdNetwork[dgid]->m_static = statc; dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; @@ -248,11 +247,10 @@ int CDGIdGateway::run() } else if (type == "YSF") { std::string name = (*it)->m_name; unsigned int local = (*it)->m_local; - std::string options = (*it)->m_options; CYSFReflector* reflector = reflectors->findByName(name); if (reflector != NULL) { - dgIdNetwork[dgid] = new CYSFNetwork(local, reflector->m_name, reflector->m_addr, reflector->m_addrLen, m_callsign, options, debug); + dgIdNetwork[dgid] = new CYSFNetwork(local, reflector->m_name, reflector->m_addr, reflector->m_addrLen, m_callsign, debug); dgIdNetwork[dgid]->m_modes = DT_VD_MODE1 | DT_VD_MODE2 | DT_VOICE_FR_MODE | DT_DATA_FR_MODE; dgIdNetwork[dgid]->m_static = statc; dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; @@ -262,6 +260,23 @@ int CDGIdGateway::run() } else { LogWarning("Unknown YSF reflector: %s", name.c_str()); } + } else if (type == "YCS") { + std::string name = (*it)->m_name; + unsigned int local = (*it)->m_local; + + CYSFReflector* reflector = reflectors->findByName(name); + if (reflector != NULL) { + dgIdNetwork[dgid] = new CYSFNetwork(local, reflector->m_name, reflector->m_addr, reflector->m_addrLen, m_callsign, (*it)->m_netDGId, debug); + dgIdNetwork[dgid]->m_modes = DT_VD_MODE1 | DT_VD_MODE2 | DT_VOICE_FR_MODE | DT_DATA_FR_MODE; + dgIdNetwork[dgid]->m_static = statc; + dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; + dgIdNetwork[dgid]->m_netHangTime = netHangTime; + + LogMessage("Added YCS:%s:%u to DG-ID %u", name.c_str(), (*it)->m_netDGId, dgid); + } + else { + LogWarning("Unknown YCS reflector: %s", name.c_str()); + } } else if (type == "IMRS") { if (imrs != NULL) { std::vector destinations = (*it)->m_destinations; @@ -298,7 +313,7 @@ int CDGIdGateway::run() sockaddr_storage addr; unsigned int addrLen; if (CUDPSocket::lookup((*it)->m_address, (*it)->m_port, addr, addrLen) == 0) { - dgIdNetwork[dgid] = new CYSFNetwork(local, "PARROT", addr, addrLen, m_callsign, "", debug); + dgIdNetwork[dgid] = new CYSFNetwork(local, "PARROT", addr, addrLen, m_callsign, debug); dgIdNetwork[dgid]->m_modes = DT_VD_MODE1 | DT_VD_MODE2 | DT_VOICE_FR_MODE | DT_DATA_FR_MODE; dgIdNetwork[dgid]->m_static = statc; dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; @@ -314,7 +329,7 @@ int CDGIdGateway::run() sockaddr_storage addr; unsigned int addrLen; if (CUDPSocket::lookup((*it)->m_address, (*it)->m_port, addr, addrLen) == 0) { - dgIdNetwork[dgid] = new CYSFNetwork(local, "YSF2DMR", addr, addrLen, m_callsign, "", debug); + dgIdNetwork[dgid] = new CYSFNetwork(local, "YSF2DMR", addr, addrLen, m_callsign, debug); dgIdNetwork[dgid]->m_modes = DT_VD_MODE1 | DT_VD_MODE2; dgIdNetwork[dgid]->m_static = statc; dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; @@ -330,7 +345,7 @@ int CDGIdGateway::run() sockaddr_storage addr; unsigned int addrLen; if (CUDPSocket::lookup((*it)->m_address, (*it)->m_port, addr, addrLen) == 0) { - dgIdNetwork[dgid] = new CYSFNetwork(local, "YSF2NXDN", addr, addrLen, m_callsign, "", debug); + dgIdNetwork[dgid] = new CYSFNetwork(local, "YSF2NXDN", addr, addrLen, m_callsign, debug); dgIdNetwork[dgid]->m_modes = DT_VD_MODE1 | DT_VD_MODE2; dgIdNetwork[dgid]->m_static = statc; dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; @@ -346,7 +361,7 @@ int CDGIdGateway::run() sockaddr_storage addr; unsigned int addrLen; if (CUDPSocket::lookup((*it)->m_address, (*it)->m_port, addr, addrLen) == 0) { - dgIdNetwork[dgid] = new CYSFNetwork(local, "YSF2P25", addr, addrLen, m_callsign, "", debug); + dgIdNetwork[dgid] = new CYSFNetwork(local, "YSF2P25", addr, addrLen, m_callsign, debug); dgIdNetwork[dgid]->m_modes = DT_VOICE_FR_MODE; dgIdNetwork[dgid]->m_static = statc; dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; @@ -428,8 +443,8 @@ int CDGIdGateway::run() (dt == YSF_DT_DATA_FR_MODE && (dgIdNetwork[currentDGId]->m_modes & DT_DATA_FR_MODE) != 0U) || (dt == YSF_DT_VD_MODE2 && (dgIdNetwork[currentDGId]->m_modes & DT_VD_MODE2) != 0U) || (dt == YSF_DT_VOICE_FR_MODE && (dgIdNetwork[currentDGId]->m_modes & DT_VOICE_FR_MODE) != 0U)) { - // Set the DG-ID to zero for compatibility - fich.setDGId(0U); + unsigned int dgId = dgIdNetwork[currentDGId]->getDGId(); + fich.setDGId(dgId); fich.encode(buffer + 35U); dgIdNetwork[currentDGId]->write(currentDGId, buffer); @@ -644,5 +659,5 @@ std::string CDGIdGateway::calculateLocator() void CDGIdGateway::sendPips(unsigned int n) { - + LogMessage("*** %u bleep!", n); } diff --git a/DGIdGateway/DGIdNetwork.h b/DGIdGateway/DGIdNetwork.h index 922da0d..ce962ec 100644 --- a/DGIdGateway/DGIdNetwork.h +++ b/DGIdGateway/DGIdNetwork.h @@ -34,6 +34,8 @@ public: virtual std::string getDesc(unsigned int dgId) = 0; + virtual unsigned int getDGId() = 0; + virtual bool open() = 0; virtual void link() = 0; diff --git a/DGIdGateway/FCSNetwork.cpp b/DGIdGateway/FCSNetwork.cpp index b8be3f7..0baa477 100644 --- a/DGIdGateway/FCSNetwork.cpp +++ b/DGIdGateway/FCSNetwork.cpp @@ -29,14 +29,12 @@ const char* FCS_VERSION = "MMDVM"; const unsigned int BUFFER_LENGTH = 200U; -CFCSNetwork::CFCSNetwork(const std::string& reflector, unsigned int port, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, unsigned int id, const std::string& options, bool debug) : +CFCSNetwork::CFCSNetwork(const std::string& reflector, unsigned int port, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, unsigned int id, bool debug) : m_socket(port), m_debug(debug), m_addr(), m_addrLen(0U), m_ping(NULL), -m_options(NULL), -m_opt(options), m_info(NULL), m_reflector(reflector), m_print(), @@ -59,11 +57,6 @@ m_state(DS_NOTOPEN) m_print = reflector.substr(0U, 6U) + "-" + reflector.substr(6U); - m_options = new unsigned char[50U]; - ::memcpy(m_options + 0U, "FCSO", 4U); - ::memset(m_options + 4U, ' ', 46U); - ::memcpy(m_options + 4U, callsign.c_str(), callsign.size()); - char url[50U]; ::sprintf(url, "%s.xreflector.net", reflector.c_str()); if (CUDPSocket::lookup(std::string(url), FCS_PORT, m_addr, m_addrLen) != 0) @@ -74,7 +67,6 @@ CFCSNetwork::~CFCSNetwork() { delete[] m_info; delete[] m_ping; - delete[] m_options; } std::string CFCSNetwork::getDesc(unsigned int dgId) @@ -82,6 +74,11 @@ std::string CFCSNetwork::getDesc(unsigned int dgId) return "FCS: " + m_reflector; } +unsigned int CFCSNetwork::getDGId() +{ + return 0U; +} + bool CFCSNetwork::open() { if (m_addrLen == 0U) { @@ -177,6 +174,8 @@ void CFCSNetwork::clock(unsigned int ms) if (length <= 0) return; + CUtils::dump(1U, "FCS Network Data Received", buffer, length); + if (m_state == DS_NOTLINKED) return; @@ -191,14 +190,12 @@ void CFCSNetwork::clock(unsigned int ms) LogMessage("Linked to %s", m_print.c_str()); m_state = DS_LINKED; writeInfo(); - writeOptions(m_print); } if (length == 10 && m_state == DS_LINKING) { LogMessage("Linked to %s", m_print.c_str()); m_state = DS_LINKED; writeInfo(); - writeOptions(m_print); } if (length == 7 || length == 10 || length == 130) { @@ -276,21 +273,3 @@ void CFCSNetwork::writePing() m_socket.write(m_ping, 25U, m_addr, m_addrLen); } - -void CFCSNetwork::writeOptions(const std::string& reflector) -{ - if (m_state != DS_LINKED) - return; - - if (m_opt.size() < 1) - return; - - ::memset(m_options + 14U, 0x20U, 36U); - ::memcpy(m_options + 4U, (reflector.substr(0, 6) + reflector.substr(7, 2)).c_str(), 8U); - ::memcpy(m_options + 12U, m_opt.c_str(), m_opt.size()); - - if (m_debug) - CUtils::dump(1U, "FCS Network Options Sent", m_options, 50U); - - m_socket.write(m_options, 50U, m_addr, m_addrLen); -} diff --git a/DGIdGateway/FCSNetwork.h b/DGIdGateway/FCSNetwork.h index 845787e..5c22635 100644 --- a/DGIdGateway/FCSNetwork.h +++ b/DGIdGateway/FCSNetwork.h @@ -30,11 +30,13 @@ class CFCSNetwork : public CDGIdNetwork { public: - CFCSNetwork(const std::string& reflector, unsigned int port, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, unsigned int id, const std::string& options, bool debug); + CFCSNetwork(const std::string& reflector, unsigned int port, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, unsigned int id, bool debug); virtual ~CFCSNetwork(); virtual std::string getDesc(unsigned int dgId); + virtual unsigned int getDGId(); + virtual bool open(); virtual DGID_STATUS getStatus(); @@ -57,8 +59,6 @@ private: sockaddr_storage m_addr; unsigned int m_addrLen; unsigned char* m_ping; - unsigned char* m_options; - std::string m_opt; unsigned char* m_info; std::string m_reflector; std::string m_print; @@ -68,7 +68,6 @@ private: CTimer m_resetTimer; DGID_STATUS m_state; - void writeOptions(const std::string& reflector); void writeInfo(); void writePing(); }; diff --git a/DGIdGateway/IMRSNetwork.cpp b/DGIdGateway/IMRSNetwork.cpp index f354b5e..08ad667 100644 --- a/DGIdGateway/IMRSNetwork.cpp +++ b/DGIdGateway/IMRSNetwork.cpp @@ -58,6 +58,11 @@ std::string CIMRSNetwork::getDesc(unsigned int dgId) return "IMRS: " + ptr->m_name; } +unsigned int CIMRSNetwork::getDGId() +{ + return 0U; +} + bool CIMRSNetwork::open() { LogMessage("Opening IMRS network connection"); diff --git a/DGIdGateway/IMRSNetwork.h b/DGIdGateway/IMRSNetwork.h index 46b69e9..e7be4f5 100644 --- a/DGIdGateway/IMRSNetwork.h +++ b/DGIdGateway/IMRSNetwork.h @@ -59,6 +59,8 @@ public: virtual std::string getDesc(unsigned int dgId); + virtual unsigned int getDGId(); + virtual bool open(); virtual DGID_STATUS getStatus(); diff --git a/DGIdGateway/Version.h b/DGIdGateway/Version.h index 3e08686..d41dcb0 100644 --- a/DGIdGateway/Version.h +++ b/DGIdGateway/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200920"; +const char* VERSION = "20200922"; #endif diff --git a/DGIdGateway/YSFNetwork.cpp b/DGIdGateway/YSFNetwork.cpp index 9c1cd37..bddae8d 100644 --- a/DGIdGateway/YSFNetwork.cpp +++ b/DGIdGateway/YSFNetwork.cpp @@ -38,7 +38,10 @@ m_unlink(NULL), m_buffer(1000U, "YSF Network Buffer"), m_pollTimer(1000U, 5U), m_name(name), -m_state(DS_NOTOPEN) +m_state(DS_NOTOPEN), +m_pollCount(0U), +m_ycs(false), +m_dgId(0U) { m_poll = new unsigned char[14U]; ::memcpy(m_poll + 0U, "YSFP", 4U); @@ -46,16 +49,20 @@ m_state(DS_NOTOPEN) m_unlink = new unsigned char[14U]; ::memcpy(m_unlink + 0U, "YSFU", 4U); + m_options = new unsigned char[50U]; + ::memcpy(m_options + 0U, "YSFO", 4U); + std::string node = callsign; node.resize(YSF_CALLSIGN_LENGTH, ' '); for (unsigned int i = 0U; i < YSF_CALLSIGN_LENGTH; i++) { m_poll[i + 4U] = node.at(i); m_unlink[i + 4U] = node.at(i); + m_options[i + 4U] = node.at(i); } } -CYSFNetwork::CYSFNetwork(unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, const std::string& options, bool debug) : +CYSFNetwork::CYSFNetwork(unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, bool debug) : m_socket(localPort), m_debug(debug), m_addr(addr), @@ -66,7 +73,10 @@ m_unlink(NULL), m_buffer(1000U, "YSF Network Buffer"), m_pollTimer(1000U, 5U), m_name(name), -m_state(DS_NOTOPEN) +m_state(DS_NOTOPEN), +m_pollCount(0U), +m_ycs(false), +m_dgId(0U) { m_poll = new unsigned char[14U]; ::memcpy(m_poll + 0U, "YSFP", 4U); @@ -74,27 +84,58 @@ m_state(DS_NOTOPEN) m_unlink = new unsigned char[14U]; ::memcpy(m_unlink + 0U, "YSFU", 4U); + m_options = new unsigned char[50U]; + ::memcpy(m_options + 0U, "YSFO", 4U); + std::string node = callsign; node.resize(YSF_CALLSIGN_LENGTH, ' '); for (unsigned int i = 0U; i < YSF_CALLSIGN_LENGTH; i++) { m_poll[i + 4U] = node.at(i); m_unlink[i + 4U] = node.at(i); + m_options[i + 4U] = node.at(i); } +} - std::string opt = options; - if (!opt.empty()) { - m_options = new unsigned char[50U]; - ::memcpy(m_options + 0U, "YSFO", 4U); +CYSFNetwork::CYSFNetwork(unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, unsigned int dgId, bool debug) : +m_socket(localPort), +m_debug(debug), +m_addr(addr), +m_addrLen(addrLen), +m_poll(NULL), +m_options(NULL), +m_unlink(NULL), +m_buffer(1000U, "YCS Network Buffer"), +m_pollTimer(1000U, 5U), +m_name(name), +m_state(DS_NOTOPEN), +m_pollCount(0U), +m_ycs(true), +m_dgId(dgId) +{ + m_poll = new unsigned char[14U]; + ::memcpy(m_poll + 0U, "YSFP", 4U); - for (unsigned int i = 0U; i < YSF_CALLSIGN_LENGTH; i++) - m_options[i + 4U] = node.at(i); + m_unlink = new unsigned char[14U]; + ::memcpy(m_unlink + 0U, "YSFU", 4U); - opt.resize(50, ' '); + m_options = new unsigned char[50U]; + ::memcpy(m_options + 0U, "YSFO", 4U); - for (unsigned int i = 0U; i < (50U - 4U - YSF_CALLSIGN_LENGTH); i++) - m_options[i + 4U + YSF_CALLSIGN_LENGTH] = opt.at(i); + std::string node = callsign; + node.resize(YSF_CALLSIGN_LENGTH, ' '); + + for (unsigned int i = 0U; i < YSF_CALLSIGN_LENGTH; i++) { + m_poll[i + 4U] = node.at(i); + m_unlink[i + 4U] = node.at(i); + m_options[i + 4U] = node.at(i); } + + char text[101U]; + ::sprintf(text, "Options=%u ", dgId); + + for (unsigned int i = 0U; i < (50U - 4U - YSF_CALLSIGN_LENGTH); i++) + m_options[i + 4U + YSF_CALLSIGN_LENGTH] = text[i]; } CYSFNetwork::~CYSFNetwork() @@ -106,18 +147,26 @@ CYSFNetwork::~CYSFNetwork() std::string CYSFNetwork::getDesc(unsigned int dgId) { - return "YSF: " + m_name; + if (m_ycs) + return "YCS: " + m_name; + else + return "YSF: " + m_name; +} + +unsigned int CYSFNetwork::getDGId() +{ + return m_dgId; } bool CYSFNetwork::open() { if (m_addrLen == 0U) { - LogError("Unable to resolve the address of the YSF network"); + LogError("Unable to resolve the address of the YSF/YCS network"); m_state = DS_NOTOPEN; return false; } - LogMessage("Opening YSF network connection"); + LogMessage("Opening YSF/YCS network connection"); bool ret = m_socket.open(m_addr); if (!ret) { @@ -169,12 +218,16 @@ void CYSFNetwork::writePoll() m_socket.write(m_poll, 14U, m_addr, m_addrLen); - if (m_options != NULL) { + if (m_ycs && m_state == DS_LINKED && m_pollCount == 0U) { if (m_debug) CUtils::dump(1U, "YSF Network Data Sent", m_options, 50U); m_socket.write(m_options, 50U, m_addr, m_addrLen); } + + m_pollCount++; + if (m_pollCount == 100U) + m_pollCount = 0U; } void CYSFNetwork::unlink() @@ -229,7 +282,8 @@ void CYSFNetwork::clock(unsigned int ms) else LogMessage("Linked to %s", m_name.c_str()); - m_state = DS_LINKED; + m_state = DS_LINKED; + m_pollCount = 0U; if (m_options != NULL) m_socket.write(m_options, 50U, m_addr, m_addrLen); @@ -260,7 +314,7 @@ void CYSFNetwork::close() { m_socket.close(); - LogMessage("Closing YSF network connection"); + LogMessage("Closing YSF/YCS network connection"); m_state = DS_NOTOPEN; } diff --git a/DGIdGateway/YSFNetwork.h b/DGIdGateway/YSFNetwork.h index 7c7586d..b3bcefb 100644 --- a/DGIdGateway/YSFNetwork.h +++ b/DGIdGateway/YSFNetwork.h @@ -31,13 +31,14 @@ class CYSFNetwork : public CDGIdNetwork { public: CYSFNetwork(const std::string& localAddress, unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, bool debug); - CYSFNetwork(unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, const std::string& options, bool debug); + CYSFNetwork(unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, unsigned int dgId, bool debug); + CYSFNetwork(unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, bool debug); virtual ~CYSFNetwork(); - void setOptions(const std::string& options); - virtual std::string getDesc(unsigned int dgId); + virtual unsigned int getDGId(); + virtual bool open(); virtual DGID_STATUS getStatus(); @@ -66,6 +67,9 @@ private: CTimer m_pollTimer; std::string m_name; DGID_STATUS m_state; + unsigned int m_pollCount; + bool m_ycs; + unsigned int m_dgId; void writePoll(); };