mirror of
https://github.com/oe7drt/YSFClients.git
synced 2025-12-06 05:32:02 +01:00
Fix YSFGateway Crash on searching for a reflector with an ID that doesn't exist, code cleanup around the WiresX protocol
This commit is contained in:
parent
702d9e1312
commit
d583357cab
|
|
@ -239,7 +239,7 @@ WX_STATUS CWiresX::process(const unsigned char* data, const unsigned char* sourc
|
|||
|
||||
CUtils::dump(1U, "Received Wires-X command", m_command, cmd_len);
|
||||
|
||||
// If we are using WiresX Passthrough (we already know we are on a YSF2xxx room from YSFGateway
|
||||
// YSFGateway.cpp is telling us to pass the command to the network, so do not process locally unless it's a disconnect
|
||||
if (wiresXCommandPassthrough) {
|
||||
if (::memcmp(m_command + 1U, DX_REQ, 3U) == 0) {
|
||||
return WX_STATUS::NONE;
|
||||
|
|
@ -375,8 +375,10 @@ WX_STATUS CWiresX::processConnect(const unsigned char* source, const unsigned ch
|
|||
std::string id = std::string((char*)data, 5U);
|
||||
|
||||
m_reflector = m_reflectors.findById(id);
|
||||
if (m_reflector == nullptr)
|
||||
if (m_reflector == nullptr) {
|
||||
sendConnectFailedReply();
|
||||
return WX_STATUS::NONE;
|
||||
}
|
||||
|
||||
m_status = WXSI_STATUS::CONNECT;
|
||||
m_timer.start();
|
||||
|
|
@ -472,11 +474,11 @@ void CWiresX::createReply(const unsigned char* data, unsigned int length, CYSFNe
|
|||
assert(data != nullptr);
|
||||
assert(length > 0U);
|
||||
|
||||
bool isYSF2XX = true;
|
||||
bool sendWiresXtoNetwork = true;
|
||||
|
||||
// If we don't explicitly pass a network, use the default one.
|
||||
if (network == nullptr) {
|
||||
isYSF2XX = false;
|
||||
sendWiresXtoNetwork = false;
|
||||
network = m_network;
|
||||
}
|
||||
|
||||
|
|
@ -521,7 +523,7 @@ void CWiresX::createReply(const unsigned char* data, unsigned int length, CYSFNe
|
|||
buffer[34U] = seqNo;
|
||||
seqNo += 2U;
|
||||
|
||||
writeData(buffer, network, isYSF2XX);
|
||||
writeData(buffer, network, sendWiresXtoNetwork);
|
||||
|
||||
fich.setFI(YSF_FI_COMMUNICATIONS);
|
||||
|
||||
|
|
@ -568,7 +570,7 @@ void CWiresX::createReply(const unsigned char* data, unsigned int length, CYSFNe
|
|||
buffer[34U] = seqNo;
|
||||
seqNo += 2U;
|
||||
|
||||
writeData(buffer, network, isYSF2XX);
|
||||
writeData(buffer, network, sendWiresXtoNetwork);
|
||||
|
||||
fn++;
|
||||
if (fn >= 8U) {
|
||||
|
|
@ -588,13 +590,13 @@ void CWiresX::createReply(const unsigned char* data, unsigned int length, CYSFNe
|
|||
|
||||
buffer[34U] = seqNo | 0x01U;
|
||||
|
||||
writeData(buffer, network, isYSF2XX);
|
||||
writeData(buffer, network, sendWiresXtoNetwork);
|
||||
}
|
||||
|
||||
void CWiresX::writeData(const unsigned char* buffer, CYSFNetwork* network, bool isYSF2XX)
|
||||
void CWiresX::writeData(const unsigned char* buffer, CYSFNetwork* network, bool sendWiresXtoNetwork)
|
||||
{
|
||||
if (isYSF2XX) {
|
||||
// Send YSF2XXX Wires-X reply directly to the network
|
||||
if (sendWiresXtoNetwork) {
|
||||
// Send WiresX directly to the network
|
||||
network->write(buffer);
|
||||
} else {
|
||||
// Send host Wires-X reply using ring buffer
|
||||
|
|
@ -644,15 +646,15 @@ void CWiresX::sendDXReply()
|
|||
data[i + 20U] = m_name.at(i);
|
||||
|
||||
if (m_reflector == nullptr) {
|
||||
data[34U] = '1';
|
||||
data[35U] = '2';
|
||||
data[34U] = '1'; // 0,1,2 seem Valid
|
||||
data[35U] = '2'; // 0 = Offline 1 = Busy 2 = Disconnect 3 = Normal
|
||||
|
||||
data[57U] = '0';
|
||||
data[58U] = '0';
|
||||
data[59U] = '0';
|
||||
} else {
|
||||
data[34U] = '1';
|
||||
data[35U] = '5';
|
||||
data[34U] = '1'; // 0,1,2 seem Valid
|
||||
data[35U] = '3'; // 0 = Offline 1 = Busy 2 = Disconnect 3 = Normal
|
||||
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
data[i + 36U] = m_reflector->m_id.at(i);
|
||||
|
|
@ -739,8 +741,8 @@ void CWiresX::sendConnectReply()
|
|||
for (unsigned int i = 0U; i < 14U; i++)
|
||||
data[i + 20U] = m_name.at(i);
|
||||
|
||||
data[34U] = '1';
|
||||
data[35U] = '5';
|
||||
data[34U] = '1'; // 0,1,2 seem Valid
|
||||
data[35U] = '3'; // 0 = Offline 1 = Busy 2 = Disconnect 3 = Normal
|
||||
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
data[i + 36U] = m_reflector->m_id.at(i);
|
||||
|
|
@ -770,6 +772,43 @@ void CWiresX::sendConnectReply()
|
|||
m_seqNo++;
|
||||
}
|
||||
|
||||
void CWiresX::sendConnectFailedReply()
|
||||
{
|
||||
unsigned char data[110U];
|
||||
::memset(data, 0x00U, 110U);
|
||||
::memset(data, ' ', 90U);
|
||||
|
||||
data[0U] = m_seqNo;
|
||||
|
||||
for (unsigned int i = 0U; i < 4U; i++)
|
||||
data[i + 1U] = CONN_RESP[i];
|
||||
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
data[i + 5U] = m_id.at(i);
|
||||
|
||||
for (unsigned int i = 0U; i < 10U; i++)
|
||||
data[i + 10U] = m_node.at(i);
|
||||
|
||||
for (unsigned int i = 0U; i < 14U; i++)
|
||||
data[i + 20U] = m_name.at(i);
|
||||
|
||||
data[34U] = '1'; // 0,1,2 seem Valid
|
||||
data[35U] = '0'; // 0 = Offline 1 = Busy 2 = Disconnect 3 = Normal
|
||||
|
||||
data[57U] = '0';
|
||||
data[58U] = '0';
|
||||
data[59U] = '0';
|
||||
|
||||
data[89U] = 0x03U; // End of data marker
|
||||
data[90U] = CCRC::addCRC(data, 90U);
|
||||
|
||||
CUtils::dump(1U, "Connect Failed Reply", data, 91U);
|
||||
|
||||
createReply(data, 91U);
|
||||
|
||||
m_seqNo++;
|
||||
}
|
||||
|
||||
void CWiresX::sendDisconnectReply()
|
||||
{
|
||||
unsigned char data[110U];
|
||||
|
|
@ -790,8 +829,8 @@ void CWiresX::sendDisconnectReply()
|
|||
for (unsigned int i = 0U; i < 14U; i++)
|
||||
data[i + 20U] = m_name.at(i);
|
||||
|
||||
data[34U] = '1';
|
||||
data[35U] = '2';
|
||||
data[34U] = '1'; // 0,1,2 seem Valid
|
||||
data[35U] = '2'; // 0 = Offline 1 = Busy 2 = Disconnect 3 = Normal
|
||||
|
||||
data[57U] = '0';
|
||||
data[58U] = '0';
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ private:
|
|||
|
||||
void sendDXReply();
|
||||
void sendConnectReply();
|
||||
void sendConnectFailedReply();
|
||||
void sendDisconnectReply();
|
||||
void sendAllReply();
|
||||
void sendSearchReply();
|
||||
|
|
@ -113,7 +114,7 @@ private:
|
|||
void sendCategoryReply();
|
||||
|
||||
void createReply(const unsigned char* data, unsigned int length, CYSFNetwork* network = nullptr);
|
||||
void writeData(const unsigned char* data, CYSFNetwork* network, bool isYSF2XX);
|
||||
void writeData(const unsigned char* data, CYSFNetwork* network, bool sendWiresXtoNetwork);
|
||||
unsigned char calculateFT(unsigned int length, unsigned int offset) const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -323,14 +323,14 @@ int CYSFGateway::run()
|
|||
unsigned char dt = fich.getDT();
|
||||
|
||||
CYSFReflector* reflector = m_wiresX->getReflector();
|
||||
if (m_ysfNetwork != nullptr && m_linkType == LINK_TYPE::YSF && wiresXCommandPassthrough && reflector->m_wiresX) {
|
||||
if (m_ysfNetwork != nullptr && m_linkType == LINK_TYPE::YSF && wiresXCommandPassthrough && reflector != nullptr && reflector->m_wiresX) {
|
||||
processDTMF(buffer, dt);
|
||||
processWiresX(buffer, fich, true, wiresXCommandPassthrough);
|
||||
processWiresX(buffer, fich, reflector->m_wiresX, wiresXCommandPassthrough); // Honour reflector->m_wiresX status
|
||||
} else {
|
||||
processDTMF(buffer, dt);
|
||||
processWiresX(buffer, fich, false, wiresXCommandPassthrough);
|
||||
reflector = m_wiresX->getReflector(); //reflector may have changed
|
||||
if (m_ysfNetwork != nullptr && m_linkType == LINK_TYPE::YSF && reflector->m_wiresX)
|
||||
processWiresX(buffer, fich, false, wiresXCommandPassthrough); // Remove the assumption that wiresXCommandPassthrough is set
|
||||
reflector = m_wiresX->getReflector(); // reflector may have changed
|
||||
if (m_ysfNetwork != nullptr && m_linkType == LINK_TYPE::YSF && reflector != nullptr && reflector->m_wiresX)
|
||||
m_exclude = (dt == YSF_DT_DATA_FR_MODE);
|
||||
}
|
||||
|
||||
|
|
@ -560,11 +560,17 @@ void CYSFGateway::createWiresX(CYSFNetwork* rptNetwork)
|
|||
m_wiresX->start();
|
||||
}
|
||||
|
||||
void CYSFGateway::processWiresX(const unsigned char* buffer, const CYSFFICH& fich, bool dontProcessWiresXLocal, bool wiresXCommandPassthrough)
|
||||
void CYSFGateway::processWiresX(const unsigned char* buffer, const CYSFFICH& fich, bool wiresXEnabledReflector, bool wiresXCommandPassthrough)
|
||||
{
|
||||
assert(buffer != nullptr);
|
||||
|
||||
WX_STATUS status = m_wiresX->process(buffer + 35U, buffer + 14U, fich, dontProcessWiresXLocal);
|
||||
WX_STATUS status;
|
||||
if (wiresXEnabledReflector && wiresXCommandPassthrough) { // If these are BOTH true, then we ignore anything but a WiresX disconnect
|
||||
status = m_wiresX->process(buffer + 35U, buffer + 14U, fich, true);
|
||||
} else { // Otherwise process all WiresX commands locally
|
||||
status = m_wiresX->process(buffer + 35U, buffer + 14U, fich, false);
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case WX_STATUS::CONNECT_YSF: {
|
||||
if (m_linkType == LINK_TYPE::YSF)
|
||||
|
|
@ -626,8 +632,9 @@ void CYSFGateway::processWiresX(const unsigned char* buffer, const CYSFFICH& fic
|
|||
case WX_STATUS::DISCONNECT:
|
||||
if (m_linkType == LINK_TYPE::YSF) {
|
||||
LogMessage("Disconnect has been requested by %10.10s", buffer + 14U);
|
||||
if ( (wiresXCommandPassthrough) && (::memcmp(buffer + 0U, "YSFD", 4U) == 0) ) {
|
||||
if ( (wiresXEnabledReflector && wiresXCommandPassthrough) && (::memcmp(buffer + 0U, "YSFD", 4U) == 0) ) {
|
||||
// Send the disconnect to the YSF2xxx gateway too
|
||||
LogMessage("Forward WiresX Disconnect to Network");
|
||||
m_ysfNetwork->write(buffer);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ private:
|
|||
void reconnectReflector(const std::string& nameOrId);
|
||||
void disconnectCurrentReflector();
|
||||
std::string calculateLocator();
|
||||
void processWiresX(const unsigned char* buffer, const CYSFFICH& fich, bool dontProcessWiresXLocal, bool wiresXCommandPassthrough);
|
||||
void processWiresX(const unsigned char* buffer, const CYSFFICH& fich, bool wiresXEnabledReflector, bool wiresXCommandPassthrough);
|
||||
void processDTMF(unsigned char* buffer, unsigned char dt);
|
||||
void createWiresX(CYSFNetwork* rptNetwork);
|
||||
void createGPS();
|
||||
|
|
|
|||
|
|
@ -142,8 +142,7 @@ bool CYSFReflectors::load()
|
|||
refl->m_addrLen = addrLen;
|
||||
refl->m_count = std::string(p6);
|
||||
refl->m_type = YSF_TYPE::YSF;
|
||||
refl->m_wiresX = (refl->m_name.compare(0, 3, "XLX") == 0);
|
||||
|
||||
refl->m_wiresX = ( refl->m_name.compare(0, 3, "XLX") == 0 || refl->m_name.compare(2, 4, "-XLX") == 0 );
|
||||
refl->m_name.resize(16U, ' ');
|
||||
refl->m_desc.resize(14U, ' ');
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue