diff --git a/YSFGateway/Reflectors.cpp b/YSFGateway/Reflectors.cpp index 87b969e..2d8c0b9 100644 --- a/YSFGateway/Reflectors.cpp +++ b/YSFGateway/Reflectors.cpp @@ -86,7 +86,7 @@ CYSFReflector* CReflectors::find(const std::string& id) return NULL; } -static int refComparison(const CYSFReflector* r1, const CYSFReflector* r2) +static bool refComparison(const CYSFReflector* r1, const CYSFReflector* r2) { assert(r1 != NULL); assert(r2 != NULL); @@ -94,13 +94,13 @@ static int refComparison(const CYSFReflector* r1, const CYSFReflector* r2) std::string name1 = r1->m_name; std::string name2 = r2->m_name; - for (unsigned int i = 0U; i < name1.size() && i < name2.size(); i++) { + for (unsigned int i = 0U; i < 16U; i++) { int c = ::toupper(name1.at(i)) - ::toupper(name2.at(i)); if (c != 0) - return c; + return c < 0; } - return int(name1.size()) - int(name2.size()); + return false; } std::vector& CReflectors::current() @@ -112,13 +112,17 @@ std::vector& CReflectors::current() m_current.push_back(*it); } - std::sort(m_current.begin(), m_current.end(), ::refComparison); + std::sort(m_current.begin(), m_current.end(), refComparison); return m_current; } void CReflectors::clock(unsigned int ms) { + // Nothing to do, avoid crashes + if (m_reflectors.size() == 0U) + return; + m_timer.clock(ms); if (m_timer.isRunning() && m_timer.hasExpired()) { m_socket.write((unsigned char*)"YSFS", 4U, (*m_it)->m_address, (*m_it)->m_port); diff --git a/YSFGateway/WiresX.cpp b/YSFGateway/WiresX.cpp index 318c118..1f6c6a5 100644 --- a/YSFGateway/WiresX.cpp +++ b/YSFGateway/WiresX.cpp @@ -26,6 +26,7 @@ #include #include +#include const unsigned char DX_REQ[] = {0x5DU, 0x71U, 0x5FU}; const unsigned char CONN_REQ[] = {0x5DU, 0x23U, 0x5FU}; @@ -57,7 +58,9 @@ m_source(NULL), m_csd1(NULL), m_csd2(NULL), m_csd3(NULL), -m_status(WXSI_NONE) +m_status(WXSI_NONE), +m_start(0U), +m_search() { assert(network != NULL); assert(statusPort > 0U); @@ -169,7 +172,7 @@ WX_STATUS CWiresX::process(const unsigned char* data, unsigned char fi, unsigned processDX(); return WXS_NONE; } else if (::memcmp(buffer + 1U, ALL_REQ, 3U) == 0) { - processAll(); + processAll(buffer + 5U); return WXS_NONE; } else if (::memcmp(buffer + 1U, CONN_REQ, 3U) == 0) { return processConnect(buffer + 5U); @@ -198,12 +201,31 @@ void CWiresX::processDX() m_timer.start(); } -void CWiresX::processAll() +void CWiresX::processAll(const unsigned char* data) { - ::LogDebug("Received ALL from %10.10s", m_source + 10U); + if (data[0U] == '0' && data[1] == '1') { + ::LogDebug("Received ALL for \"%3.3s\" from %10.10s", data + 2U, m_source + 10U); - m_status = WXSI_ALL; - m_timer.start(); + char buffer[4U]; + ::memcpy(buffer, data + 2U, 3U); + buffer[3U] = 0x00U; + + m_start = ::atoi(buffer); + if (m_start > 0U) + m_start--; + + m_status = WXSI_ALL; + + m_timer.start(); + } else if (data[0U] == '1' && data[1U] == '1') { + ::LogDebug("Received SEARCH for \"%16.16s\" from %10.10s", data + 5U, m_source + 10U); + + m_search = std::string((char*)(data + 5U), 16U); + + m_status = WXSI_SEARCH; + + m_timer.start(); + } } WX_STATUS CWiresX::processConnect(const unsigned char* data) @@ -243,6 +265,9 @@ void CWiresX::clock(unsigned int ms) case WXSI_ALL: sendAllReply(); break; + case WXSI_SEARCH: + sendSearchReply(); + break; case WXSI_CONNECT: sendConnectReply(); break; @@ -308,13 +333,13 @@ void CWiresX::createReply(const unsigned char* data, unsigned int length) offset += 20U; } else { // All subsequent entries start with 0x00U - unsigned char buffer[20U]; - ::memcpy(buffer + 1U, data + offset, 19U); - buffer[0U] = 0x00U; - payload.writeDataFRModeData2(buffer, buffer + 35U); + unsigned char temp[20U]; + ::memcpy(temp + 1U, data + offset, 19U); + temp[0U] = 0x00U; + payload.writeDataFRModeData2(temp, buffer + 35U); offset += 19U; } - break ; + break; default: payload.writeDataFRModeData1(data + offset, buffer + 35U); offset += 20U; @@ -536,7 +561,7 @@ void CWiresX::sendAllReply() unsigned int total = curr.size(); if (total > 999U) total = 999U; - unsigned int n = curr.size(); + unsigned int n = curr.size() - m_start; if (n > 20U) n = 20U; ::sprintf((char*)(data + 22U), "%03u%03u", n, total); @@ -545,7 +570,7 @@ void CWiresX::sendAllReply() unsigned int offset = 29U; for (unsigned int j = 0U; j < n; j++, offset += 50U) { - CYSFReflector* refl = curr.at(j); + CYSFReflector* refl = curr.at(j + m_start); data[offset + 0U] = '5'; @@ -579,3 +604,72 @@ void CWiresX::sendAllReply() m_seqNo++; } + +// XXX This is wrong +void CWiresX::sendSearchReply() +{ + std::vector& curr = m_reflectors.current(); + + unsigned char data[1100U]; + ::memset(data, 0x00U, 1100U); + + data[0U] = m_seqNo; + + for (unsigned int i = 0U; i < 4U; i++) + data[i + 1U] = ALL_RESP[i]; + + data[5U] = '1'; + data[6U] = '1'; + + for (unsigned int i = 0U; i < 5U; i++) + data[i + 7U] = m_id.at(i); + + for (unsigned int i = 0U; i < 10U; i++) + data[i + 12U] = m_callsign.at(i); + + unsigned int total = curr.size(); + if (total > 999U) total = 999U; + + unsigned int n = curr.size() - m_start; + if (n > 20U) n = 20U; + + ::sprintf((char*)(data + 22U), "%03u%03u", n, total); + + data[28U] = 0x0DU; + + unsigned int offset = 29U; + for (unsigned int j = 0U; j < n; j++, offset += 50U) { + CYSFReflector* refl = curr.at(j + m_start); + + data[offset + 0U] = '5'; + + for (unsigned int i = 0U; i < 5U; i++) + data[i + offset + 1U] = refl->m_id.at(i); + + for (unsigned int i = 0U; i < 16U; i++) + data[i + offset + 6U] = refl->m_name.at(i); + + for (unsigned int i = 0U; i < 3U; i++) + data[i + offset + 22U] = refl->m_count.at(i); + + for (unsigned int i = 0U; i < 10U; i++) + data[i + offset + 25U] = ' '; + + for (unsigned int i = 0U; i < 14U; i++) + data[i + offset + 35U] = refl->m_desc.at(i); + + data[offset + 49U] = 0x0DU; + } + + data[offset + 0U] = 0x03U; // End of data marker + data[offset + 1U] = CCRC::addCRC(data, offset + 1U); + + unsigned int blocks = (offset + 1U) / 20U; + if ((blocks % 20U) > 0U) blocks++; + + CUtils::dump(1U, "SEARCH Reply", data, blocks * 20U); + + createReply(data, blocks * 20U); + + m_seqNo++; +} diff --git a/YSFGateway/WiresX.h b/YSFGateway/WiresX.h index 9b40ee1..79ee8b3 100644 --- a/YSFGateway/WiresX.h +++ b/YSFGateway/WiresX.h @@ -36,7 +36,8 @@ enum WXSI_STATUS { WXSI_DX, WXSI_CONNECT, WXSI_DISCONNECT, - WXSI_ALL + WXSI_ALL, + WXSI_SEARCH }; class CWiresX { @@ -71,16 +72,19 @@ private: unsigned char* m_csd2; unsigned char* m_csd3; WXSI_STATUS m_status; + unsigned int m_start; + std::string m_search; WX_STATUS processConnect(const unsigned char* data); void processDisconnect(); void processDX(); - void processAll(); + void processAll(const unsigned char* data); void sendDXReply(); void sendConnectReply(); void sendDisconnectReply(); void sendAllReply(); + void sendSearchReply(); void createReply(const unsigned char* data, unsigned int length); unsigned char calculateFT(unsigned int length) const;