void CDPlusHandler::writeAMBEInt(CAMBEData& data, DIRECTION direction)
{
	if (m_linkState != DPLUS_LINKED)
		return;

	if (direction != m_direction)
		return;

	// Already in use?
	if (m_dPlusId != 0x00U)
		return;

	switch (m_direction) {
		case DIR_OUTGOING:
			if (data.getId() == m_rptrId) {
				data.setDestination(m_yourAddress, m_yourPort);
				m_handler->writeAMBE(data);

				if (data.isEnd())
					m_rptrId = 0x00U;
			}
			break;

		case DIR_INCOMING:
			data.setDestination(m_yourAddress, m_yourPort);
			m_handler->writeAMBE(data);
			break;
	}
}
Example #2
0
void CG2Handler::process(CAMBEData& data)
{
	// Check to see if this is for StarNet
	CStarNetHandler* handler = CStarNetHandler::findStarNet(data);
	if (handler != NULL) {
		handler->process(data);
		return;
	}

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

	unsigned int id = data.getId();

	for (unsigned int i = 0U; i < m_maxRoutes; i++) {
		CG2Handler* route = m_routes[i];
		if (route != NULL) {
			if (route->m_id == id) {
				route->m_inactivityTimer.reset();
				route->m_repeater->process(data, DIR_INCOMING, AS_G2);

				if (data.isEnd()) {
					delete route;
					m_routes[i] = NULL;
				}

				return;
			}
		}
	}	
}
void CDPlusHandler::processInt(CAMBEData& data)
{
	unsigned int id = data.getId();

	if (m_dPlusId != id)
		return;

	m_dPlusSeq = data.getSeq();

	// Send the header every 21 frames
	if (m_dPlusSeq == 0U)
		m_destination->process(*m_header, AS_DUP);

	m_inactivityTimer.reset();
	m_pollInactivityTimer.reset();

	m_destination->process(data, AS_DPLUS);

	if (data.isEnd()) {
		m_dPlusId  = 0x00U;
		m_dPlusSeq = 0x00U;

		delete m_header;
		m_header = NULL;

		m_inactivityTimer.stop();
	}
}
void CXReflectorDPlusHandler::processInt(CAMBEData& data)
{
    unsigned int id = data.getId();

    if (m_dPlusId == id) {
        m_inactivityTimer.reset();
        m_pollInactivityTimer.reset();
        m_destination->process(m_dPlusId, data);

        if (data.isEnd()) {
            m_dPlusId = 0x00;
            m_inactivityTimer.stop();
        }
    }
}
Example #5
0
void CEchoUnit::writeData(const CAMBEData& data)
{
    if (m_status != ES_RECEIVE)
        return;

    if (m_in < MAX_FRAMES) {
        m_data[m_in] = new CAMBEData(data);
        m_in++;
    }

    if (data.isEnd()) {
        wxLogMessage(wxT("Received %.1f secs of audio from %s for echoing"), float(m_in) / float(DSTAR_FRAMES_PER_SEC), m_header->getMyCall1().c_str());

        m_timer.start();
        m_status = ES_WAIT;
    }
}
bool CStarNetHandler::process(CAMBEData &data, AUDIO_SOURCE source)
{
	unsigned int id = data.getId();
	if (id != m_id)
		return false;

	m_linkTimer.reset();

	sendToRepeaters(data);

	if (data.isEnd()) {
		m_linkTimer.stop();
		m_id = 0x00U;

		// Clear the repeater list
		for (CStarNetRepeatersHashMap::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it)
			delete it->second;
		m_repeaters.clear();
	}

	return true;
}
void CDExtraHandler::writeAMBEInt(CAMBEData& data, DIRECTION direction)
{
	if (m_linkState != DEXTRA_LINKED)
		return;

	// Is it link in the right direction
	if (m_direction != direction)
		return;

	// If the ids don't match, reject
	if (data.getId() != m_rptrId)
		return;

	// Already in use?
	if (m_dExtraId != 0x00)
		return;

	data.setDestination(m_address, m_port);
	m_handler->writeAMBE(data);

	if (data.isEnd())
		m_rptrId = 0x00;
}
void CAPRSWriter::writeData(const wxString& callsign, const CAMBEData& data)
{
	if (data.isEnd())
		return;

	CAPRSEntry* entry = m_array[callsign];
	if (entry == NULL) {
		wxLogError(wxT("Cannot find the callsign \"%s\" in the APRS array"), callsign.c_str());
		return;
	}

	CAPRSCollector* collector = entry->getCollector();

	if (data.isSync()) {
		collector->sync();
		return;
	}

	unsigned char buffer[400U];
	data.getData(buffer, DV_FRAME_MAX_LENGTH_BYTES);

	bool complete = collector->writeData(buffer + VOICE_FRAME_LENGTH_BYTES);
	if (!complete)
		return;

	if (!m_enabled) {
		collector->reset();
		return;
	}

	if (!m_thread->isConnected()) {
		collector->reset();
		return;
	}

	// Check the transmission timer
	bool ok = entry->isOK();
	if (!ok) {
		collector->reset();
		return;
	}

	unsigned int length = collector->getData(buffer, 400U);
	wxString text((char*)buffer, wxConvLocal, length);

	int n = text.Find(wxT(':'));
	if (n == wxNOT_FOUND) {
		collector->reset();
		return;
	}

	wxString header = text.Left(n);
	wxString body   = text.Mid(n + 1U);

	// If we already have a q-construct, don't send it on
	n = header.Find(wxT('q'));
	if (n != wxNOT_FOUND)
		return;

	// Remove the trailing \r
	n = body.Find(wxT('\r'));
	if (n != wxNOT_FOUND)
		body = body.Left(n);

	wxString output;
	output.Printf(wxT("%s,qAR,%s-%s:%s"), header.c_str(), entry->getCallsign().c_str(), entry->getBand().c_str(), body.c_str());

	char ascii[500U];
	::memset(ascii, 0x00, 500U);
	for (unsigned int i = 0U; i < output.Len(); i++)
		ascii[i] = output.GetChar(i);

	m_thread->write(ascii);

	collector->reset();
}
void CStarNetHandler::process(CAMBEData &data)
{
	unsigned int id = data.getId();

	CStarNetId* tx = m_ids[id];
	if (tx == NULL)
		return;

	tx->reset();

	CStarNetUser* user = tx->getUser();
	user->reset();

	m_groupTimer.reset();

	// If we've just logged in, the LOGOFF and INFO commands are disabled
	if (!tx->isLogin()) {
		// If we've already found some slow data, then don't look again
		if (!tx->isLogoff() && !tx->isInfo()) {
			tx->getTextCollector().writeData(data);
			bool hasText = tx->getTextCollector().hasData();
			if (hasText) {
				wxString text = tx->getTextCollector().getData();

				if (text.Left(6U).IsSameAs(wxT("LOGOFF"), false)) {
					if (m_logFile != NULL) {
						time_t timeNow = ::time(NULL);
						struct tm* tm = ::gmtime(&timeNow);

						wxString text;
						text.Printf(wxT("%04d-%02d-%02d %02d:%02d:%02d: Removing %s from StarNet group %s, logged off\n"),
							tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
							user->getCallsign().c_str(), m_groupCallsign.c_str());

						m_logFile->Write(text);
						m_logFile->Flush();
					}

					tx->setLogoff();

					// Ensure that this user is in the cache in time for the logoff ack
					CUserData* cacheUser = m_cache->findUser(user->getCallsign());
					if (cacheUser == NULL)
						m_irc->findUser(user->getCallsign());

					delete cacheUser;
					cacheUser = NULL;
				}

				if (text.Left(4U).IsSameAs(wxT("INFO"), false)) {
					tx->setInfo();

					// Ensure that this user is in the cache in time for the info text
					CUserData* cacheUser = m_cache->findUser(user->getCallsign());
					if (cacheUser == NULL)
						m_irc->findUser(user->getCallsign());

					delete cacheUser;
					cacheUser = NULL;
				}
			}
		}
	}

	if (id == m_id) {
#if defined(DEXTRA_LINK)
		CDExtraHandler::writeAMBE(this, data, DIR_OUTGOING);
#endif
#if defined(DCS_LINK)
		CDCSHandler::writeAMBE(this, data, DIR_OUTGOING);
#endif
		sendToRepeaters(data);
	}

	if (data.isEnd()) {
		if (id == m_id) {
			// Clear the repeater list if we're the relayed id
			for (CStarNetRepeatersHashMap::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it)
				delete it->second;
			m_repeaters.clear();
			m_id = 0x00U;
		}

		if (tx->isLogin()) {
			tx->reset();
			tx->setEnd();
		} else if (tx->isLogoff()) {
			m_users.erase(user->getCallsign());
			tx->reset();
			tx->setEnd();
		} else if (tx->isInfo()) {
			tx->reset();
			tx->setEnd();
		} else {
			m_ids.erase(tx->getId());
			delete tx;
		}
	}
}
Example #10
0
void CDRATSServer::writeData(const CAMBEData& data)
{
	// Sync data isn't sent on
	if (data.isSync()) {
		m_writeState = SS_FIRST;
		return;
	}

	if (data.isEnd()) {
		if (m_writeLength > 0U && m_socket != NULL) {
			// CUtils::dump(wxT("From RF"), m_writeBuffer, m_writeLength);
			m_socket->write(m_writeBuffer, m_writeLength);
		}

		m_writeLength = 0U;
		return;
	}

	unsigned char buffer[DV_FRAME_MAX_LENGTH_BYTES];
	unsigned int length = data.getData(buffer, DV_FRAME_MAX_LENGTH_BYTES);

	if (length != DV_FRAME_LENGTH_BYTES)
		return;

	unsigned char byte1 = buffer[VOICE_FRAME_LENGTH_BYTES + 0U] ^ SCRAMBLER_BYTE1;
	unsigned char byte2 = buffer[VOICE_FRAME_LENGTH_BYTES + 1U] ^ SCRAMBLER_BYTE2;
	unsigned char byte3 = buffer[VOICE_FRAME_LENGTH_BYTES + 2U] ^ SCRAMBLER_BYTE3;

	switch (m_writeState) {
		case SS_FIRST:
			m_writeText[0U] = byte1;
			m_writeText[1U] = byte2;
			m_writeText[2U] = byte3;
			m_writeState = SS_SECOND;
			return;

		case SS_SECOND:
			m_writeText[3U] = byte1;
			m_writeText[4U] = byte2;
			m_writeText[5U] = byte3;
			m_writeState = SS_FIRST;
			break;
	}

	if ((m_writeText[0U] & SLOW_DATA_TYPE_MASK) != SLOW_DATA_TYPE_GPS)
		return;

	length = m_writeText[0U] & 0x07;	// Maximum value of 5
	if (length > 5U)
		length = 5U;

	for (unsigned int i = 0U; i < length; i++) {
		m_writeBuffer[m_writeLength++] = m_writeText[i + 1U];

		// Check for [EOB] in the buffer to signal the end of the D-RATS data.
		// To allow strstr() to run correctly
		m_writeBuffer[m_writeLength] = 0x00U;

		if (::strstr((char*)m_writeBuffer, "[EOB]") != NULL) {
			if (m_socket != NULL) {
				// CUtils::dump(wxT("From RF"), m_writeBuffer, m_writeLength);
				m_socket->write(m_writeBuffer, m_writeLength);
			}

			m_writeLength = 0U;
		}
	}
}