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);
	}
}
示例#2
0
CVersionUnit::CVersionUnit(IRepeaterCallback* handler, const wxString& callsign) :
m_handler(handler),
m_callsign(callsign),
m_status(VS_IDLE),
m_timer(1000U, 2U),			// 2 seconds
m_data(NULL),
m_id(0U),
m_out(0U),
m_time()
{
	wxASSERT(handler != NULL);

	m_data = new CAMBEData*[NUM_FRAMES];

	wxString versionText;
	versionText.Printf(wxT("ircDDB GW - %s"), VERSION.Left(8U).c_str());

	wxLogMessage(wxT("Version text set to \"%s\""), versionText.c_str());

	CSlowDataEncoder encoder;
	encoder.setTextData(versionText);

	// Seq No and end
	for (unsigned int i = 0U; i < NUM_FRAMES; 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);
			encoder.sync();
		} else {
			encoder.getTextData(buffer + VOICE_FRAME_LENGTH_BYTES);
		}

		m_data[i] = new CAMBEData;
		m_data[i]->setData(buffer, DV_FRAME_LENGTH_BYTES);
		m_data[i]->setSeq(i);

		if (i == (NUM_FRAMES - 1U))
			m_data[i]->setEnd(true);
	}
}
void CStarNetHandler::sendFromText(const wxString& my) const
{
	wxString text;
	switch (m_callsignSwitch) {
		case SCS_GROUP_CALLSIGN:
			text.Printf(wxT("FROM %s"), my.c_str());
			break;
		case SCS_USER_CALLSIGN:
			text.Printf(wxT("VIA STARnet %s"), m_groupCallsign.c_str());
			break;
		default:
			break;
	}

	CSlowDataEncoder slowData;
	slowData.setTextData(text);

	CAMBEData data;
	data.setId(m_id);

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

	for (unsigned int i = 0U; i < 21U; 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 {
			// 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);
		}

		sendToRepeaters(data);
	}
}
示例#4
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;
}