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.

98 lines
2.2 KiB

/*
* Copyright (C) 2014 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "DStarDefines.h"
#include "Modem.h"
// Internal scratch buffer used by read() to hold one decoded message payload.
// 200 bytes is large enough for RADIO_HEADER_LENGTH_BYTES (41) and a max DV frame.
const unsigned int BUFFER_LENGTH = 200U;
CModem::CModem() :
m_rxData(1000U),
m_mutex(),
m_tx(false),
m_stopped(false),
m_thread(),
m_readType(DSMTT_NONE),
m_readLength(0U),
m_readBuffer(nullptr)
{
m_readBuffer = new unsigned char[BUFFER_LENGTH];
}
CModem::~CModem()
{
delete[] m_readBuffer;
}
bool CModem::isTX()
{
return m_tx;
}
DSMT_TYPE CModem::read()
{
m_readLength = 0U;
if (m_rxData.isEmpty())
return DSMTT_NONE;
std::lock_guard<std::mutex> lock(m_mutex);
// Each ring-buffer message is framed as [type:1][length:1][payload:length].
unsigned char hdr[2U];
m_rxData.getData(hdr, 2U);
m_readType = DSMT_TYPE(hdr[0U]);
m_readLength = hdr[1U];
m_rxData.getData(m_readBuffer, m_readLength);
return m_readType;
}
CHeaderData* CModem::readHeader()
{
if (m_readType != DSMTT_HEADER)
return nullptr;
return new CHeaderData(m_readBuffer, RADIO_HEADER_LENGTH_BYTES, false);
}
unsigned int CModem::readData(unsigned char* data, unsigned int length)
{
if (m_readType != DSMTT_DATA)
return 0U;
if (length < m_readLength) {
::memcpy(data, m_readBuffer, length);
return length;
} else {
::memcpy(data, m_readBuffer, m_readLength);
return m_readLength;
}
}
void CModem::stop()
{
m_stopped = true;
if (m_thread.joinable())
m_thread.join();
}

Powered by TurnKey Linux.