bool CHBRepeaterProtocolHandler::writeDD(CDDData& data) { unsigned char buffer[2000U]; unsigned int length = data.getHBRepeaterData(buffer, 2000U); #if defined(DUMP_TX) CUtils::dump(wxT("Sending DD Data"), buffer, length); return true; #else return m_socket.write(buffer, length, data.getYourAddress(), data.getYourPort()); #endif }
CDDData* CHBRepeaterProtocolHandler::readDD() { if (m_type != RT_DD) return NULL; CDDData* data = new CDDData; bool res = data->setHBRepeaterData(m_buffer, m_length, m_address, m_port); if (!res) { wxLogError(wxT("Invalid DD data from the repeater")); delete data; return NULL; } return data; }
void CHeaderLogger::write(const wxChar* type, const CDDData& data) { wxASSERT(type != NULL); time_t timeNow = ::time(NULL); struct tm* tm = ::gmtime(&timeNow); wxString text; text.Printf(wxT("%04d-%02d-%02d %02d:%02d:%02d: %s header - My: %s/%s Your: %s Rpt1: %s Rpt2: %s Flags: %02X %02X %02X\n"), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, type, data.getMyCall1().c_str(), data.getMyCall2().c_str(), data.getYourCall().c_str(), data.getRptCall1().c_str(), data.getRptCall2().c_str(), data.getFlag1(), data.getFlag2(), data.getFlag3()); m_file.Write(text); m_file.Flush(); }
CDDData* CDDHandler::read() { // If we're not initialised, return immediately if (m_maxRoutes == 0U) return NULL; #if defined(WIN32) return NULL; #else // Check that the read() won't block fd_set readFds; FD_ZERO(&readFds); #if defined(__WINDOWS__) FD_SET((unsigned int)m_fd, &readFds); #else FD_SET(m_fd, &readFds); #endif // Return immediately timeval tv; tv.tv_sec = 0L; tv.tv_usec = 0L; int ret = ::select(m_fd + 1, &readFds, NULL, NULL, &tv); if (ret < 0) { wxLogError(wxT("Error returned from select()")); return NULL; } #if defined(__WINDOWS__) if (!FD_ISSET((unsigned int)m_fd, &readFds)) return NULL; #else if (!FD_ISSET(m_fd, &readFds)) return NULL; #endif // Ensure that the minimum length is padded with 0x00s ::memset(m_buffer, 0x00U, MINIMUM_DD_FRAME_LENGTH); ssize_t len = ::read(m_fd, (char*)m_buffer, BUFFER_LENGTH); if (len <= 0) { wxLogError(wxT("Error returned from read()")); return NULL; } // There seems to be a minimum size with DD mode, so pad with zeroes if it's not reached if (len < MINIMUM_DD_FRAME_LENGTH) len = MINIMUM_DD_FRAME_LENGTH; // Point to the destination ethernet address unsigned char* address = m_buffer + 0U; // Do destination address to callsign lookup CEthernet* ethernet = NULL; for (unsigned int i = 0U; i < m_maxRoutes; i++) { if (m_list[i] != NULL) { unsigned char* addr = m_list[i]->getAddress(); if (::memcmp(addr, address, ETHERNET_ADDRESS_LENGTH) == 0) { ethernet = m_list[i]; break; } } } if (ethernet == NULL) { wxLogWarning(wxT("Cannot find the ethernet address of %02X:%02X:%02X:%02X:%02X:%02X in the ethernet list"), address[0], address[1], address[2], address[3], address[4], address[5]); return NULL; } CRepeaterHandler* handler = CRepeaterHandler::findDDRepeater(); if (handler == NULL) { wxLogWarning(wxT("Incoming DD data to unknown repeater")); return NULL; } // wxLogMessage(wxT("Mapping ethernet address %02X:%02X:%02X:%02X:%02X:%02X to user %s"), // address[0], address[1], address[2], address[3], address[4], address[5], // ethernet->getCallsign().c_str()); if (m_logEnabled) writeStatus(*ethernet); CDDData* data = new CDDData; data->setEthernetFrame(m_buffer, len); data->setYourCall(ethernet->getCallsign()); handler->process(*data); return data; #endif }
void CDDHandler::process(CDDData& data) { // If we're not initialised, return immediately if (m_maxRoutes == 0U) return; unsigned char flag1 = data.getFlag1(); unsigned char flag2 = data.getFlag2(); unsigned char flag3 = data.getFlag3(); wxString myCall1 = data.getMyCall1(); wxString myCall2 = data.getMyCall2(); wxString yourCall = data.getYourCall(); wxString rptCall1 = data.getRptCall1(); wxString rptCall2 = data.getRptCall2(); if (!m_timer.isRunning() || m_timer.hasExpired()) { // Write to Header.log if it's enabled if (m_headerLogger != NULL) m_headerLogger->write(wxT("Repeater"), data); m_irc->sendHeardWithTXMsg(myCall1, myCall2, yourCall, rptCall1, rptCall2, flag1, flag2, flag3, wxEmptyString, wxT("Digital Data ")); m_irc->sendHeardWithTXStats(myCall1, myCall2, yourCall, rptCall1, rptCall2, flag1, flag2, flag3, 1, 0, -1); m_timer.start(); } // Can we continue? if (m_fd < 0) return; unsigned char* address = data.getSourceAddress(); bool found = false; for (unsigned int i = 0U; i < m_maxRoutes; i++) { if (m_list[i] != NULL) { unsigned char* addr = m_list[i]->getAddress(); if (::memcmp(addr, address, ETHERNET_ADDRESS_LENGTH) == 0) { found = true; break; } } } if (!found) { wxLogMessage(wxT("Adding DD user %s with ethernet address %02X:%02X:%02X:%02X:%02X:%02X"), myCall1.c_str(), address[0], address[1], address[2], address[3], address[4], address[5]); CEthernet* ethernet = new CEthernet(address, myCall1); bool found = false; for (unsigned int i = 0U; i < m_maxRoutes; i++) { if (m_list[i] == NULL) { m_list[i] = ethernet; found = true; break; } } if (!found) { wxLogError(wxT("No space to add new DD ethernet address")); delete ethernet; return; } } unsigned int length = data.getEthernetFrame(m_buffer, BUFFER_LENGTH); #if !defined(WIN32) ssize_t len = ::write(m_fd, (char*)m_buffer, length); if (len != ssize_t(length)) wxLogError(wxT("Error returned from write()")); #endif }
void CIRCDDBGatewayThread::processRepeater(IRepeaterProtocolHandler* handler) { for (;;) { REPEATER_TYPE type = handler->read(); switch (type) { case RT_POLL: { CPollData* poll = handler->readPoll(); if (poll != NULL) { CRepeaterHandler* handler = CRepeaterHandler::findRepeater(*poll); if (handler != NULL) handler->processRepeater(*poll); else CRepeaterHandler::pollAllIcom(*poll); delete poll; } } break; case RT_HEARD: { CHeardData* heard = handler->readHeard(); if (heard != NULL) { wxString user = heard->getUser(); wxString repeater = heard->getRepeater(); // Internal controller heard have identical user and repeater values if (!repeater.IsSameAs(user)) { CRepeaterHandler* handler = CRepeaterHandler::findDVRepeater(repeater); if (handler == NULL) wxLogMessage(wxT("Heard received from unknown repeater, %s"), repeater.c_str()); else handler->processRepeater(*heard); delete heard; } } } break; case RT_HEADER: { CHeaderData* header = handler->readHeader(); if (header != NULL) { // wxLogMessage(wxT("Repeater header - My: %s/%s Your: %s Rpt1: %s Rpt2: %s Flags: %02X %02X %02X"), header->getMyCall1().c_str(), header->getMyCall2().c_str(), header->getYourCall().c_str(), header->getRptCall1().c_str(), header->getRptCall2().c_str(), header->getFlag1(), header->getFlag2(), header->getFlag3()); CRepeaterHandler* repeater = CRepeaterHandler::findDVRepeater(*header); if (repeater == NULL) wxLogMessage(wxT("Header received from unknown repeater, %s"), header->getRptCall1().c_str()); else repeater->processRepeater(*header); delete header; } } break; case RT_AMBE: { CAMBEData* data = handler->readAMBE(); if (data != NULL) { CRepeaterHandler* repeater = CRepeaterHandler::findDVRepeater(*data, false); if (repeater != NULL) repeater->processRepeater(*data); delete data; } } break; case RT_BUSY_HEADER: { CHeaderData* header = handler->readBusyHeader(); if (header != NULL) { // wxLogMessage(wxT("Repeater busy header - My: %s/%s Your: %s Rpt1: %s Rpt2: %s Flags: %02X %02X %02X"), header->getMyCall1().c_str(), header->getMyCall2().c_str(), header->getYourCall().c_str(), header->getRptCall1().c_str(), header->getRptCall2().c_str(), header->getFlag1(), header->getFlag2(), header->getFlag3()); CRepeaterHandler* repeater = CRepeaterHandler::findDVRepeater(*header); if (repeater == NULL) wxLogMessage(wxT("Busy header received from unknown repeater, %s"), header->getRptCall1().c_str()); else repeater->processBusy(*header); delete header; } } break; case RT_BUSY_AMBE: { CAMBEData* data = handler->readBusyAMBE(); if (data != NULL) { CRepeaterHandler* repeater = CRepeaterHandler::findDVRepeater(*data, true); if (repeater != NULL) repeater->processBusy(*data); delete data; } } break; case RT_DD: { CDDData* data = handler->readDD(); if (data != NULL) { // wxLogMessage(wxT("DD header - My: %s/%s Your: %s Rpt1: %s Rpt2: %s Flags: %02X %02X %02X"), data->getMyCall1().c_str(), data->getMyCall2().c_str(), data->getYourCall().c_str(), data->getRptCall1().c_str(), data->getRptCall2().c_str(), data->getFlag1(), data->getFlag2(), data->getFlag3()); CRepeaterHandler* repeater = CRepeaterHandler::findDDRepeater(); if (repeater == NULL) wxLogMessage(wxT("DD data received from unknown DD repeater, %s"), data->getRptCall1().c_str()); else repeater->processRepeater(*data); delete data; } } break; default: return; } } }