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;
}
Пример #3
0
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();
}
Пример #4
0
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
}
Пример #5
0
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
}
Пример #6
0
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;
		}
	}
}