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
}
Exemple #2
0
void CG2Handler::process(CHeaderData& header)
{
	// Is this a busy reply?
	unsigned char flag1 = header.getFlag1();
	if (flag1 == 0x01) {
		// Don't check the incoming stream
		// wxLogMessage(wxT("G2 busy message received"));
		return;
	}

	// Check to see if this is for StarNet
	CStarNetHandler* handler = CStarNetHandler::findStarNet(header);
	if (handler != NULL) {
		// Write to Header.log if it's enabled
		if (m_headerLogger != NULL)
			m_headerLogger->write(wxT("StarNet"), header);

		handler->process(header);
		return;
	}

	// No need to go any further
	if (m_maxRoutes == 0U)
		return;

	in_addr address = header.getYourAddress();
	unsigned int id = header.getId();

	for (unsigned int i = 0U; i < m_maxRoutes; i++) {
		CG2Handler* route = m_routes[i];
		if (route != NULL) {
			// Is this a duplicate header, ignore it
			if (route->m_id == id)
				return;
		}
	}	

	// Find the destination repeater
	CRepeaterHandler* repeater = CRepeaterHandler::findDVRepeater(header.getRptCall2());
	if (repeater == NULL) {
		wxLogMessage(wxT("Incoming G2 header from %s to unknown repeater - %s"), header.getMyCall1().c_str(), header.getRptCall2().c_str());
		return;		// Not found, ignore
	}

	CG2Handler* route = new CG2Handler(repeater, address, id);

	for (unsigned int i = 0U; i < m_maxRoutes; i++) {
		if (m_routes[i] == NULL) {
			m_routes[i] = route;

			// Write to Header.log if it's enabled
			if (m_headerLogger != NULL)
				m_headerLogger->write(wxT("G2"), header);

			repeater->process(header, DIR_INCOMING, AS_G2);
			return;
		}
	}

	wxLogMessage(wxT("No space to add new G2 route, ignoring"));

	delete route;
}