You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
7.8 KiB

/*
* Copyright (C) 2009,2010,2012 by Jonathan Naylor, G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "CCITTChecksumReverse.h"
#include "SlowDataEncoder.h"
#include "DStarDefines.h"
const unsigned char SCRAMBLER_BYTE1 = 0x70;
const unsigned char SCRAMBLER_BYTE2 = 0x4F;
const unsigned char SCRAMBLER_BYTE3 = 0x93;
CSlowDataEncoder::CSlowDataEncoder() :
m_initial(),
m_body(),
m_it(),
m_end(),
m_header(),
m_message(),
// m_gpsMessage(),
m_codeSquelch()
{
}
CSlowDataEncoder::~CSlowDataEncoder()
{
}
void CSlowDataEncoder::getData(unsigned char* data)
{
wxASSERT(data != NULL);
// First time, we need to build the output data
if (m_body.empty()) {
buildData();
// Do we have any initial data to send?
if (m_initial.empty()) {
m_it = m_body.begin();
m_end = m_body.end();
} else {
m_it = m_initial.begin();
m_end = m_initial.end();
}
}
// Create the sequence: initial, body, body, body, ...
if (m_it == m_end) {
m_it = m_body.begin();
m_end = m_body.end();
}
// This assumes that the data is in three byte blocks and won't end half-way through
// the loop.
unsigned char buffer[DATA_FRAME_LENGTH_BYTES];
for (unsigned int n = 0U; m_it != m_end && n < DATA_FRAME_LENGTH_BYTES; ++m_it, n++)
buffer[n] = *m_it;
data[0U] = buffer[0U] ^ SCRAMBLER_BYTE1;
data[1U] = buffer[1U] ^ SCRAMBLER_BYTE2;
data[2U] = buffer[2U] ^ SCRAMBLER_BYTE3;
}
void CSlowDataEncoder::reset()
{
m_initial.clear();
m_body.clear();
m_header.clear();
m_message.clear();
// m_gpsMessage.clear();
m_codeSquelch.clear();
}
void CSlowDataEncoder::setHeaderData(const CHeaderData& header)
{
CCCITTChecksumReverse cksum;
unsigned char buffer[5U];
m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U);
m_header.push_back(buffer[0] = header.getFlag1());
m_header.push_back(buffer[1] = header.getFlag2());
m_header.push_back(buffer[2] = header.getFlag3());
m_header.push_back(buffer[3] = header.getRptCall1().GetChar(0));
m_header.push_back(buffer[4] = header.getRptCall1().GetChar(1));
cksum.update(buffer, 5U);
m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U);
m_header.push_back(buffer[0] = header.getRptCall1().GetChar(2));
m_header.push_back(buffer[1] = header.getRptCall1().GetChar(3));
m_header.push_back(buffer[2] = header.getRptCall1().GetChar(4));
m_header.push_back(buffer[3] = header.getRptCall1().GetChar(5));
m_header.push_back(buffer[4] = header.getRptCall1().GetChar(6));
cksum.update(buffer, 5U);
m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U);
m_header.push_back(buffer[0] = header.getRptCall1().GetChar(7));
m_header.push_back(buffer[1] = header.getRptCall2().GetChar(0));
m_header.push_back(buffer[2] = header.getRptCall2().GetChar(1));
m_header.push_back(buffer[3] = header.getRptCall2().GetChar(2));
m_header.push_back(buffer[4] = header.getRptCall2().GetChar(3));
cksum.update(buffer, 5U);
m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U);
m_header.push_back(buffer[0] = header.getRptCall2().GetChar(4));
m_header.push_back(buffer[1] = header.getRptCall2().GetChar(5));
m_header.push_back(buffer[2] = header.getRptCall2().GetChar(6));
m_header.push_back(buffer[3] = header.getRptCall2().GetChar(7));
m_header.push_back(buffer[4] = header.getYourCall().GetChar(0));
cksum.update(buffer, 5U);
m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U);
m_header.push_back(buffer[0] = header.getYourCall().GetChar(1));
m_header.push_back(buffer[1] = header.getYourCall().GetChar(2));
m_header.push_back(buffer[2] = header.getYourCall().GetChar(3));
m_header.push_back(buffer[3] = header.getYourCall().GetChar(4));
m_header.push_back(buffer[4] = header.getYourCall().GetChar(5));
cksum.update(buffer, 5U);
m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U);
m_header.push_back(buffer[0] = header.getYourCall().GetChar(6));
m_header.push_back(buffer[1] = header.getYourCall().GetChar(7));
m_header.push_back(buffer[2] = header.getMyCall1().GetChar(0));
m_header.push_back(buffer[3] = header.getMyCall1().GetChar(1));
m_header.push_back(buffer[4] = header.getMyCall1().GetChar(2));
cksum.update(buffer, 5U);
m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U);
m_header.push_back(buffer[0] = header.getMyCall1().GetChar(3));
m_header.push_back(buffer[1] = header.getMyCall1().GetChar(4));
m_header.push_back(buffer[2] = header.getMyCall1().GetChar(5));
m_header.push_back(buffer[3] = header.getMyCall1().GetChar(6));
m_header.push_back(buffer[4] = header.getMyCall1().GetChar(7));
cksum.update(buffer, 5U);
m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U);
m_header.push_back(buffer[0] = header.getMyCall2().GetChar(0));
m_header.push_back(buffer[1] = header.getMyCall2().GetChar(1));
m_header.push_back(buffer[2] = header.getMyCall2().GetChar(2));
m_header.push_back(buffer[3] = header.getMyCall2().GetChar(3));
cksum.update(buffer, 4U);
cksum.result(buffer);
m_header.push_back(buffer[0]);
m_header.push_back(SLOW_DATA_TYPE_HEADER | 1U);
m_header.push_back(buffer[1]);
m_header.push_back('f');
m_header.push_back('f');
m_header.push_back('f');
m_header.push_back('f');
}
void CSlowDataEncoder::setMessageData(const wxString& message)
{
if (message.IsEmpty())
return;
wxString text = message;
text.Append(wxT(" "));
text.Truncate(MESSAGE_LENGTH);
unsigned int n = 0U;
for (unsigned int i = 0U; i < MESSAGE_LENGTH; i++) {
if ((i % 5U) == 0U) {
m_message.push_back(SLOW_DATA_TYPE_MESSAGE | n);
n++;
}
m_message.push_back(text.GetChar(i));
}
}
/*
void CSlowDataEncoder::setGPSMessageData(const CGPSMessageData& message)
{
if (message.getGPSMsgText().IsEmpty())
return;
unsigned int n = 0U;
unsigned int length = message.getGPSMsgText().Len();
for (unsigned int i = 0U; i < length; i++) {
if ((i % 5U) == 0U) {
m_gpsMessage.push_back(SLOW_DATA_TYPE_GPSDATA | n);
n++;
}
m_gpsMessage.push_back(message.getGPSMsgText().GetChar(i));
}
length %= 5U;
for (unsigned int i = 0U; i < length; i++)
m_gpsMessage.push_back('f');
}
*/
void CSlowDataEncoder::setCodeSquelch(unsigned char value)
{
// Convert decimal to hex, i.e. 99 = 0x99
unsigned char hexValue = (value / 10U) * 16U + (value % 10U);
m_codeSquelch.push_back(SLOW_DATA_TYPE_SQUELCH | 2U);
m_codeSquelch.push_back(hexValue);
m_codeSquelch.push_back(hexValue);
m_codeSquelch.push_back('f');
m_codeSquelch.push_back('f');
m_codeSquelch.push_back('f');
}
void CSlowDataEncoder::buildData()
{
// Create the initial section, if needed
if (!m_message.empty()) {
if (m_codeSquelch.empty()) {
// T T T T F F F F F F
m_initial.insert(m_initial.begin(), m_message.begin(), m_message.end());
m_initial.insert(m_initial.end(), 12U * DATA_FRAME_LENGTH_BYTES, 'f');
} else {
// C T T T T F F F F F
m_initial.insert(m_initial.begin(), m_codeSquelch.begin(), m_codeSquelch.end());
m_initial.insert(m_initial.end(), m_message.begin(), m_message.end());
m_initial.insert(m_initial.end(), 10U * DATA_FRAME_LENGTH_BYTES, 'f');
}
}
// Create the body section
if (!m_codeSquelch.empty()) {
// C H H H H H H H H H
m_body.insert(m_body.begin(), m_codeSquelch.begin(), m_codeSquelch.end());
m_body.insert(m_body.end(), m_header.begin(), m_header.end());
} else {
// H H H H H H H H H F
m_body.insert(m_body.begin(), m_header.begin(), m_header.end());
m_body.insert(m_body.end(), 2U * DATA_FRAME_LENGTH_BYTES, 'f');
}
}

Powered by TurnKey Linux.