예제 #1
0
void CDPlusHandler::writeAMBEInt(IReflectorCallback* handler, 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 (m_destination == handler) {
				data.setDestination(m_yourAddress, m_yourPort);
				m_handler->writeAMBE(data);
			}
			break;

		case DIR_INCOMING:
			data.setDestination(m_yourAddress, m_yourPort);
			m_handler->writeAMBE(data);
			break;
	}
}
예제 #2
0
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;
	}
}
bool CTimeServerThread::lookup(const wxString &id)
{
	CIndexRecord* info = m_index[id];
	if (info == NULL) {
		// wxLogError(wxT("Cannot find the AMBE index for *%s*"), id.c_str());
		return false;
	}

	unsigned int  start = info->getStart();
	unsigned int length = info->getLength();

	SLOW_DATA slowData = SD_TEXT;

	for (unsigned int i = 0U; i < length; i++) {
		unsigned char* dataIn = m_ambe + (start + i) * VOICE_FRAME_LENGTH_BYTES;

		CAMBEData* dataOut = new CAMBEData;
		dataOut->setDestination(m_address, G2_DV_PORT);
		dataOut->setSeq(m_seqNo);

		unsigned char buffer[DV_FRAME_LENGTH_BYTES];
		::memcpy(buffer + 0U, dataIn, VOICE_FRAME_LENGTH_BYTES);

		// Insert sync bytes when the sequence number is zero, slow data otherwise
		if (m_seqNo == 0U) {
			::memcpy(buffer + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES);
			m_encoder.sync();

			switch (slowData) {
				case SD_HEADER:
					slowData = SD_TEXT;
					break;
				case SD_TEXT:
					slowData = SD_HEADER;
					break;
			}
		} else {
			switch (slowData) {
				case SD_HEADER:
					m_encoder.getHeaderData(buffer + VOICE_FRAME_LENGTH_BYTES);
					break;
				case SD_TEXT:
					m_encoder.getTextData(buffer + VOICE_FRAME_LENGTH_BYTES);
					break;
			}
		}

		dataOut->setData(buffer, DV_FRAME_LENGTH_BYTES);

		m_seqNo++;
		if (m_seqNo == 21U)
			m_seqNo = 0U;

		m_data[m_in] = dataOut;
		m_in++;
	}

	return true;
}
void CTimeServerThread::end()
{
	CAMBEData* dataOut = new CAMBEData;
	dataOut->setData(END_PATTERN_BYTES, DV_FRAME_LENGTH_BYTES);
	dataOut->setDestination(m_address, G2_DV_PORT);
	dataOut->setSeq(m_seqNo);
	dataOut->setEnd(true);

	m_data[m_in] = dataOut;
	m_in++;
}
예제 #5
0
void CXReflectorDPlusHandler::writeAMBEInt(CAMBEData& data)
{
    if (!m_linked)
        return;

    // If there's an incoming data stream, don't send
    if (m_dPlusId != 0x00U)
        return;

    data.setDestination(m_address, m_port);
    m_handler->writeAMBE(data);
}
void CStarNetHandler::sendToRepeaters(CAMBEData& data) const
{
	for (CStarNetRepeatersHashMap::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
		CStarNetRepeater* repeater = it->second;
		if (repeater != NULL) {
			data.setDestination(repeater->m_address, G2_DV_PORT);
			if (repeater->m_local != NULL)
				repeater->m_local->process(data, AS_G2);
			else
				m_g2Handler->writeAMBE(data);
		}
	}
}
void CStarNetHandler::sendAck(const CUserData& user, const wxString& text) const
{
	unsigned int id = CHeaderData::createId();

	CHeaderData header(m_groupCallsign, wxT("    "), user.getUser(), user.getGateway(), user.getRepeater());
	header.setDestination(user.getAddress(), G2_DV_PORT);
	header.setId(id);
	m_g2Handler->writeHeader(header);

	CSlowDataEncoder slowData;
	slowData.setTextData(text);

	CAMBEData data;
	data.setId(id);
	data.setDestination(user.getAddress(), G2_DV_PORT);

	unsigned char buffer[DV_FRAME_MAX_LENGTH_BYTES];
	::memcpy(buffer + 0U, NULL_AMBE_DATA_BYTES, VOICE_FRAME_LENGTH_BYTES);

	for (unsigned int i = 0U; i < 20U; i++) {
		if (i == 0U) {
			// The first AMBE packet is a sync
			::memcpy(buffer + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES);
			data.setData(buffer, DV_FRAME_LENGTH_BYTES);
			data.setSeq(i);
		} else if (i == 19U) {
			// The last packet of the ack
			::memcpy(buffer + VOICE_FRAME_LENGTH_BYTES, END_PATTERN_BYTES, END_PATTERN_LENGTH_BYTES);
			data.setData(buffer, DV_FRAME_MAX_LENGTH_BYTES);
			data.setSeq(i);
			data.setEnd(true);
		} else {
			// The packets containing the text data
			unsigned char slowDataBuffer[DATA_FRAME_LENGTH_BYTES];
			slowData.getTextData(slowDataBuffer);
			::memcpy(buffer + VOICE_FRAME_LENGTH_BYTES, slowDataBuffer, DATA_FRAME_LENGTH_BYTES);
			data.setData(buffer, DV_FRAME_LENGTH_BYTES);
			data.setSeq(i);
		}

		m_g2Handler->writeAMBE(data);
	}
}
예제 #8
0
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;
}
bool CTimeServerThread::send(const wxArrayString &words, unsigned int hour, unsigned int min)
{
	unsigned int idA = CHeaderData::createId();
	unsigned int idB = CHeaderData::createId();
	unsigned int idC = CHeaderData::createId();
	unsigned int idD = CHeaderData::createId();

	CHeaderData header;
	header.setMyCall1(m_callsign);
	header.setRptCall1(m_callsignG);
	header.setRptCall2(m_callsign);		// Just for the slow data header
	header.setYourCall(wxT("CQCQCQ  "));
	header.setDestination(m_address, G2_DV_PORT);

	wxString slowData;
	switch (m_language) {
		case LANG_DEUTSCH_1:
		case LANG_DEUTSCH_2:
			header.setMyCall2(wxT("ZEIT"));
			slowData.Printf(wxT("Es ist %02u:%02u Uhr"), hour, min);
			break;
		case LANG_FRANCAIS:
			header.setMyCall2(wxT("TIME"));
			slowData.Printf(wxT("Il est %02u:%02u"), hour, min);
			break;
		case LANG_NEDERLANDS:
			header.setMyCall2(wxT("TIJD"));
			slowData.Printf(wxT("Het is %02u:%02u"), hour, min);
			break;
		case LANG_SVENSKA:
			header.setMyCall2(wxT("TID "));
			slowData.Printf(wxT("Klockan ar %02u:%02u"), hour, min);
			break;
		case LANG_ENGLISH_US_1:
		case LANG_ENGLISH_UK_1:
			header.setMyCall2(wxT("TIME"));
			if (hour == 0U)
				slowData.Printf(wxT("It is 12:%02u AM"), min);
			else if (hour == 12U)
				slowData.Printf(wxT("It is 12:%02u PM"), min);
			else if (hour > 12U)
				slowData.Printf(wxT("It is %02u:%02u PM"), hour - 12U, min);
			else
				slowData.Printf(wxT("It is %02u:%02u AM"), hour, min);
			break;
		default:
			header.setMyCall2(wxT("TIME"));
			slowData.Printf(wxT("It is %02u:%02u"), hour, min);
			break;
	}

	m_encoder.setHeaderData(header);
	m_encoder.setTextData(slowData);

	m_in = 0U;

	if (m_format != FORMAT_TEXT_TIME) {
		wxString text = words.Item(0U);
		for (unsigned int i = 1U; i < words.GetCount(); i++) {
			text.Append(wxT(" "));
			text.Append(words.Item(i));
		}

		text.Replace(wxT("_"), wxT(" "));
		wxLogMessage(wxT("Sending voice \"%s\", sending text \"%s\""), text.c_str(), slowData.c_str());

		m_seqNo = 0U;

		// Build the audio
		lookup(wxT(" "));
		lookup(wxT(" "));
		lookup(wxT(" "));
		lookup(wxT(" "));

		for (unsigned int i = 0U; i < words.GetCount(); i++)
			lookup(words.Item(i));

		lookup(wxT(" "));
		lookup(wxT(" "));
		lookup(wxT(" "));
		lookup(wxT(" "));

		end();
	} else {
		wxLogMessage(wxT("Sending text \"%s\""), slowData.c_str());

		for (unsigned int i = 0U; i < 21U; i++) {
			CAMBEData* dataOut = new CAMBEData;
			dataOut->setDestination(m_address, G2_DV_PORT);
			dataOut->setSeq(i);

			unsigned char buffer[DV_FRAME_LENGTH_BYTES];
			::memcpy(buffer + 0U, NULL_AMBE_DATA_BYTES, VOICE_FRAME_LENGTH_BYTES);

			// Insert sync bytes when the sequence number is zero, slow data otherwise
			if (i == 0U) {
				::memcpy(buffer + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES);
				m_encoder.sync();
			} else {
				m_encoder.getTextData(buffer + VOICE_FRAME_LENGTH_BYTES);
			}

			dataOut->setData(buffer, DV_FRAME_LENGTH_BYTES);

			m_data[m_in] = dataOut;
			m_in++;
		}

		CAMBEData* dataOut = new CAMBEData;
		dataOut->setData(END_PATTERN_BYTES, DV_FRAME_LENGTH_BYTES);
		dataOut->setDestination(m_address, G2_DV_PORT);
		dataOut->setSeq(0U);
		dataOut->setEnd(true);

		m_data[m_in] = dataOut;
		m_in++;
	}

	if (m_in == 0U) {
		wxLogWarning(wxT("Not sending, no audio files loaded"));
		return false;
	}

	if (!m_callsignA.IsEmpty()) {
		header.setRptCall2(m_callsignA);
		header.setId(idA);
		sendHeader(header);
	}

	if (!m_callsignB.IsEmpty()) {
		header.setRptCall2(m_callsignB);
		header.setId(idB);
		sendHeader(header);
	}

	if (!m_callsignC.IsEmpty()) {
		header.setRptCall2(m_callsignC);
		header.setId(idC);
		sendHeader(header);
	}

	if (!m_callsignD.IsEmpty()) {
		header.setRptCall2(m_callsignD);
		header.setId(idD);
		sendHeader(header);
	}

	unsigned int out = 0U;

	wxStopWatch timer;
	timer.Start();

	for (;;) {
		unsigned int needed = timer.Time() / DSTAR_FRAME_TIME_MS;

		while (out < needed) {
			CAMBEData* data = m_data[out];
			m_data[out] = NULL;
			out++;

			if (!m_callsignA.IsEmpty()) {
				data->setId(idA);
				sendData(*data);
			}

			if (!m_callsignB.IsEmpty()) {
				data->setId(idB);
				sendData(*data);
			}

			if (!m_callsignC.IsEmpty()) {
				data->setId(idC);
				sendData(*data);
			}

			if (!m_callsignD.IsEmpty()) {
				data->setId(idD);
				sendData(*data);
			}

			delete data;

			if (m_in == out)
				return true;
		}

		::wxMilliSleep(10UL);
	}
}
예제 #10
0
bool CAPRSTransmit::run()
{
	//First see if the packet is Icom supported...
	CAPRSPacket aprsPacket;
	if(!CAPRSParser::Parse(m_text, aprsPacket)){
		wxLogWarning(wxT("Unsupported APRS Format, ignoring => ") + m_text.Trim(true));
		return false;
	}

	wxString textWithCRC(aprsPacket.Raw());
	wxLogMessage(wxT("Supported APRS Format => ") + textWithCRC.Trim(true));
	//add nececessary stuff to text, but keep it the original
	textWithCRC.Replace(wxT("\n"), wxEmptyString);
	if(!textWithCRC.EndsWith(wxT("\r"))) textWithCRC.Append(wxT("\r"));
	wxString crc = wxString::Format(wxT("$$CRC%04X,"), calcCRC(textWithCRC));
	textWithCRC.Prepend(crc);

	bool opened = m_socket.open();
	if (!opened)
		return false;

	in_addr address = CUDPReaderWriter::lookup(wxT("127.0.0.1"));

	unsigned int id = CHeaderData::createId();

	wxString callsignG = m_repeaterCallsign.Left(LONG_CALLSIGN_LENGTH - 1U);
	callsignG.Append(wxT("G"));

	CHeaderData header;
	header.setId(id);
	header.setMyCall1(m_APRSCallsign);
	header.setMyCall2(wxT("APRS"));
	header.setRptCall1(callsignG);
	header.setRptCall2(m_repeaterCallsign);
	header.setYourCall(wxT("CQCQCQ  "));
	header.setDestination(address, G2_DV_PORT);

	sendHeader(header);

	CSlowDataEncoder encoder;
	encoder.setHeaderData(header);
	encoder.setGPSData(textWithCRC);
	encoder.setTextData(wxT("APRS to DPRS"));

	CAMBEData data;
	data.setDestination(address, G2_DV_PORT);
	data.setId(id);

	wxStopWatch timer;
	timer.Start();

	unsigned int out = 0U;
        unsigned int dataOut = 0U;
	unsigned int needed = (encoder.getInterleavedDataLength() / (DATA_FRAME_LENGTH_BYTES)) * 2U;

	while (dataOut < needed) {
		data.setSeq(out);

		unsigned char buffer[DV_FRAME_LENGTH_BYTES];
		::memcpy(buffer + 0U, NULL_AMBE_DATA_BYTES, VOICE_FRAME_LENGTH_BYTES);

		// Insert sync bytes when the sequence number is zero, slow data otherwise
		if (out == 0U) {
			::memcpy(buffer + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES);
		} else {
			encoder.getInterleavedData(buffer + VOICE_FRAME_LENGTH_BYTES);		
			dataOut++;
		}

		data.setData(buffer, DV_FRAME_LENGTH_BYTES);

		sendData(data);
		out++;

		if (out == 21U) out = 0U;
	}

	data.setData(END_PATTERN_BYTES, DV_FRAME_LENGTH_BYTES);
	data.setSeq(out >= 21U ? 0U : out);
	data.setEnd(true);

	sendData(data);

	m_socket.close();

	return true;
}