Simple System Fusion bent pipe.
This commit is contained in:
parent
04dddc68a1
commit
647c5d652b
9 changed files with 266 additions and 145 deletions
|
@ -25,7 +25,7 @@
|
||||||
#include "DMRControl.h"
|
#include "DMRControl.h"
|
||||||
#include "TFTSerial.h"
|
#include "TFTSerial.h"
|
||||||
#include "NullDisplay.h"
|
#include "NullDisplay.h"
|
||||||
#include "YSFEcho.h"
|
#include "YSFControl.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
@ -166,9 +166,18 @@ int CMMDVMHost::run()
|
||||||
dmr = new CDMRControl(id, colorCode, timeout, m_modem, m_dmrNetwork, m_display, duplex);
|
dmr = new CDMRControl(id, colorCode, timeout, m_modem, m_dmrNetwork, m_display, duplex);
|
||||||
}
|
}
|
||||||
|
|
||||||
CYSFEcho* ysf = NULL;
|
CYSFControl* ysf = NULL;
|
||||||
if (m_ysfEnabled)
|
if (m_ysfEnabled) {
|
||||||
ysf = new CYSFEcho(2U, 10000U);
|
std::string callsign = m_conf.getCallsign();
|
||||||
|
unsigned int timeout = m_conf.getTimeout();
|
||||||
|
bool duplex = m_conf.getDuplex();
|
||||||
|
|
||||||
|
LogInfo("System Fusion Parameters");
|
||||||
|
LogInfo(" Callsign: %s", callsign.c_str());
|
||||||
|
LogInfo(" Timeout: %us", timeout);
|
||||||
|
|
||||||
|
ysf = new CYSFControl(callsign, m_display, timeout, duplex);
|
||||||
|
}
|
||||||
|
|
||||||
m_modeTimer.setTimeout(m_conf.getModeHang());
|
m_modeTimer.setTimeout(m_conf.getModeHang());
|
||||||
|
|
||||||
|
@ -226,11 +235,11 @@ int CMMDVMHost::run()
|
||||||
len = m_modem->readYSFData(data);
|
len = m_modem->readYSFData(data);
|
||||||
if (ysf != NULL && len > 0U) {
|
if (ysf != NULL && len > 0U) {
|
||||||
if (m_mode == MODE_IDLE) {
|
if (m_mode == MODE_IDLE) {
|
||||||
bool ret = ysf->writeData(data, len);
|
bool ret = ysf->writeModem(data);
|
||||||
if (ret)
|
if (ret)
|
||||||
setMode(MODE_YSF);
|
setMode(MODE_YSF);
|
||||||
} else if (m_mode == MODE_YSF) {
|
} else if (m_mode == MODE_YSF) {
|
||||||
ysf->writeData(data, len);
|
ysf->writeModem(data);
|
||||||
m_modeTimer.start();
|
m_modeTimer.start();
|
||||||
} else {
|
} else {
|
||||||
LogWarning("System Fusion modem data received when in mode %u", m_mode);
|
LogWarning("System Fusion modem data received when in mode %u", m_mode);
|
||||||
|
@ -294,7 +303,7 @@ int CMMDVMHost::run()
|
||||||
if (ysf != NULL) {
|
if (ysf != NULL) {
|
||||||
ret = m_modem->hasYSFSpace();
|
ret = m_modem->hasYSFSpace();
|
||||||
if (ret) {
|
if (ret) {
|
||||||
len = ysf->readData(data);
|
len = ysf->readModem(data);
|
||||||
if (len > 0U) {
|
if (len > 0U) {
|
||||||
if (m_mode == MODE_IDLE) {
|
if (m_mode == MODE_IDLE) {
|
||||||
setMode(MODE_YSF);
|
setMode(MODE_YSF);
|
||||||
|
|
|
@ -189,9 +189,9 @@
|
||||||
<ClInclude Include="UDPSocket.h" />
|
<ClInclude Include="UDPSocket.h" />
|
||||||
<ClInclude Include="Utils.h" />
|
<ClInclude Include="Utils.h" />
|
||||||
<ClInclude Include="Version.h" />
|
<ClInclude Include="Version.h" />
|
||||||
|
<ClInclude Include="YSFControl.h" />
|
||||||
<ClInclude Include="YSFConvolution.h" />
|
<ClInclude Include="YSFConvolution.h" />
|
||||||
<ClInclude Include="YSFDefines.h" />
|
<ClInclude Include="YSFDefines.h" />
|
||||||
<ClInclude Include="YSFEcho.h" />
|
|
||||||
<ClInclude Include="YSFFICH.h" />
|
<ClInclude Include="YSFFICH.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -233,8 +233,8 @@
|
||||||
<ClCompile Include="Timer.cpp" />
|
<ClCompile Include="Timer.cpp" />
|
||||||
<ClCompile Include="UDPSocket.cpp" />
|
<ClCompile Include="UDPSocket.cpp" />
|
||||||
<ClCompile Include="Utils.cpp" />
|
<ClCompile Include="Utils.cpp" />
|
||||||
|
<ClCompile Include="YSFControl.cpp" />
|
||||||
<ClCompile Include="YSFConvolution.cpp" />
|
<ClCompile Include="YSFConvolution.cpp" />
|
||||||
<ClCompile Include="YSFEcho.cpp" />
|
|
||||||
<ClCompile Include="YSFFICH.cpp" />
|
<ClCompile Include="YSFFICH.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|
|
@ -95,9 +95,6 @@
|
||||||
<ClInclude Include="YSFDefines.h">
|
<ClInclude Include="YSFDefines.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="YSFEcho.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Version.h">
|
<ClInclude Include="Version.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -152,6 +149,9 @@
|
||||||
<ClInclude Include="DMRSlotType.h">
|
<ClInclude Include="DMRSlotType.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="YSFControl.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="BPTC19696.cpp">
|
<ClCompile Include="BPTC19696.cpp">
|
||||||
|
@ -223,9 +223,6 @@
|
||||||
<ClCompile Include="Utils.cpp">
|
<ClCompile Include="Utils.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="YSFEcho.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="AMBEFEC.cpp">
|
<ClCompile Include="AMBEFEC.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -277,5 +274,8 @@
|
||||||
<ClCompile Include="DMRSlotType.cpp">
|
<ClCompile Include="DMRSlotType.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="YSFControl.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
2
Makefile
2
Makefile
|
@ -7,7 +7,7 @@ LDFLAGS = -g
|
||||||
OBJECTS = \
|
OBJECTS = \
|
||||||
AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLC.o DMRShortLC.o \
|
AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLC.o DMRShortLC.o \
|
||||||
DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o Log.o MMDVMHost.o Modem.o NullDisplay.o \
|
DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o Log.o MMDVMHost.o Modem.o NullDisplay.o \
|
||||||
QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFConvolution.o YSFEcho.o YSFFICH.o
|
QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o
|
||||||
|
|
||||||
all: MMDVMHost
|
all: MMDVMHost
|
||||||
|
|
||||||
|
|
179
YSFControl.cpp
Normal file
179
YSFControl.cpp
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015,2016 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 "YSFControl.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "Sync.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
// #define DUMP_YSF
|
||||||
|
|
||||||
|
CYSFControl::CYSFControl(const std::string& callsign, IDisplay* display, unsigned int timeout, bool duplex) :
|
||||||
|
m_display(display),
|
||||||
|
m_duplex(duplex),
|
||||||
|
m_queue(1000U, "YSF Control"),
|
||||||
|
m_state(RS_LISTENING),
|
||||||
|
m_timeoutTimer(1000U, timeout),
|
||||||
|
m_frames(0U),
|
||||||
|
m_fp(NULL)
|
||||||
|
{
|
||||||
|
assert(display != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFControl::~CYSFControl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CYSFControl::writeModem(unsigned char *data)
|
||||||
|
{
|
||||||
|
unsigned char type = data[0U];
|
||||||
|
|
||||||
|
if (type == TAG_LOST && m_state == RS_RELAYING_RF_AUDIO) {
|
||||||
|
LogMessage("YSF, transmission lost, %.1f seconds", float(m_frames) / 10.0F);
|
||||||
|
writeEndOfTransmission();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == TAG_LOST)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool valid = (data[1U] & YSF_CKSUM_OK) == YSF_CKSUM_OK;
|
||||||
|
unsigned char fi = data[1U] & YSF_FI_MASK;
|
||||||
|
unsigned char dt = data[1U] & YSF_DT_MASK;
|
||||||
|
|
||||||
|
if (valid && m_state == RS_LISTENING) {
|
||||||
|
m_frames = 0U;
|
||||||
|
m_timeoutTimer.start();
|
||||||
|
m_state = RS_RELAYING_RF_AUDIO;
|
||||||
|
LogMessage("YSF, received RF header");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fi == YSF_DT_TERMINATOR_CHANNEL) {
|
||||||
|
if (m_state == RS_RELAYING_RF_AUDIO) {
|
||||||
|
CSync::addYSFSync(data + 2U);
|
||||||
|
|
||||||
|
m_frames++;
|
||||||
|
|
||||||
|
if (m_duplex) {
|
||||||
|
data[0U] = TAG_DATA;
|
||||||
|
data[1U] = 0x00U;
|
||||||
|
writeQueue(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage("YSF, received RF end of transmission, %.1f seconds", float(m_frames) / 10.0F);
|
||||||
|
|
||||||
|
writeEndOfTransmission();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
CSync::addYSFSync(data + 2U);
|
||||||
|
|
||||||
|
m_frames++;
|
||||||
|
|
||||||
|
if (m_duplex) {
|
||||||
|
data[0U] = TAG_DATA;
|
||||||
|
data[1U] = 0x00U;
|
||||||
|
writeQueue(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CYSFControl::readModem(unsigned char* data)
|
||||||
|
{
|
||||||
|
if (m_queue.isEmpty())
|
||||||
|
return 0U;
|
||||||
|
|
||||||
|
unsigned char len = 0U;
|
||||||
|
m_queue.getData(&len, 1U);
|
||||||
|
|
||||||
|
m_queue.getData(data, len);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFControl::writeEndOfTransmission()
|
||||||
|
{
|
||||||
|
m_state = RS_LISTENING;
|
||||||
|
|
||||||
|
m_timeoutTimer.stop();
|
||||||
|
|
||||||
|
m_display->clearFusion();
|
||||||
|
|
||||||
|
#if defined(DUMP_YSF)
|
||||||
|
closeFile();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFControl::clock(unsigned int ms)
|
||||||
|
{
|
||||||
|
m_timeoutTimer.clock(ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFControl::writeQueue(const unsigned char *data)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired())
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned char len = YSF_FRAME_LENGTH_BYTES + 2U;
|
||||||
|
m_queue.addData(&len, 1U);
|
||||||
|
|
||||||
|
m_queue.addData(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CYSFControl::openFile()
|
||||||
|
{
|
||||||
|
if (m_fp != NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
time_t t;
|
||||||
|
::time(&t);
|
||||||
|
|
||||||
|
struct tm* tm = ::localtime(&t);
|
||||||
|
|
||||||
|
char name[100U];
|
||||||
|
::sprintf(name, "YSF_%04d%02d%02d_%02d%02d%02d.ambe", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||||
|
|
||||||
|
m_fp = ::fopen(name, "wb");
|
||||||
|
if (m_fp == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
::fwrite("YSF", 1U, 3U, m_fp);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CYSFControl::writeFile(const unsigned char* data)
|
||||||
|
{
|
||||||
|
if (m_fp == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
::fwrite(data, 1U, YSF_FRAME_LENGTH_BYTES, m_fp);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFControl::closeFile()
|
||||||
|
{
|
||||||
|
if (m_fp != NULL) {
|
||||||
|
::fclose(m_fp);
|
||||||
|
m_fp = NULL;
|
||||||
|
}
|
||||||
|
}
|
60
YSFControl.h
Normal file
60
YSFControl.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015,2016 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(YSFControl_H)
|
||||||
|
#define YSFControl_H
|
||||||
|
|
||||||
|
#include "YSFDefines.h"
|
||||||
|
#include "RingBuffer.h"
|
||||||
|
#include "Display.h"
|
||||||
|
#include "Defines.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
#include "Modem.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class CYSFControl {
|
||||||
|
public:
|
||||||
|
CYSFControl(const std::string& callsign, IDisplay* display, unsigned int timeout, bool duplex);
|
||||||
|
~CYSFControl();
|
||||||
|
|
||||||
|
bool writeModem(unsigned char* data);
|
||||||
|
|
||||||
|
unsigned int readModem(unsigned char* data);
|
||||||
|
|
||||||
|
void clock(unsigned int ms);
|
||||||
|
|
||||||
|
private:
|
||||||
|
IDisplay* m_display;
|
||||||
|
bool m_duplex;
|
||||||
|
CRingBuffer<unsigned char> m_queue;
|
||||||
|
RPT_STATE m_state;
|
||||||
|
CTimer m_timeoutTimer;
|
||||||
|
unsigned int m_frames;
|
||||||
|
FILE* m_fp;
|
||||||
|
|
||||||
|
void writeQueue(const unsigned char* data);
|
||||||
|
|
||||||
|
void writeEndOfTransmission();
|
||||||
|
|
||||||
|
bool openFile();
|
||||||
|
bool writeFile(const unsigned char* data);
|
||||||
|
void closeFile();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -27,6 +27,7 @@ const unsigned int YSF_SYNC_LENGTH_BYTES = 5U;
|
||||||
const unsigned char YSF_FI_MASK = 0xC0U;
|
const unsigned char YSF_FI_MASK = 0xC0U;
|
||||||
const unsigned char YSF_DT_MASK = 0x30U;
|
const unsigned char YSF_DT_MASK = 0x30U;
|
||||||
|
|
||||||
|
const unsigned char YSF_DT_HEADER_CHANNEL = 0x00U;
|
||||||
const unsigned char YSF_DT_TERMINATOR_CHANNEL = 0x80U;
|
const unsigned char YSF_DT_TERMINATOR_CHANNEL = 0x80U;
|
||||||
|
|
||||||
const unsigned char YSF_CKSUM_OK = 0x01U;
|
const unsigned char YSF_CKSUM_OK = 0x01U;
|
||||||
|
|
85
YSFEcho.cpp
85
YSFEcho.cpp
|
@ -1,85 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2015 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 "YSFEcho.h"
|
|
||||||
|
|
||||||
#include "YSFDefines.h"
|
|
||||||
|
|
||||||
CYSFEcho::CYSFEcho(unsigned int delay, unsigned int space) :
|
|
||||||
m_buffer(space, "YSF Echo"),
|
|
||||||
m_timer(1000U, delay)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CYSFEcho::~CYSFEcho()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int CYSFEcho::readData(unsigned char* data)
|
|
||||||
{
|
|
||||||
if (!hasData())
|
|
||||||
return 0U;
|
|
||||||
|
|
||||||
unsigned char len;
|
|
||||||
m_buffer.getData(&len, 1U);
|
|
||||||
|
|
||||||
m_buffer.getData(data, len);
|
|
||||||
|
|
||||||
// If the FICH is valid, regenerate the sync
|
|
||||||
if ((data[1U] & 0x01U) == 0x01U) {
|
|
||||||
data[2U] = YSF_SYNC_BYTES[0U];
|
|
||||||
data[3U] = YSF_SYNC_BYTES[1U];
|
|
||||||
data[4U] = YSF_SYNC_BYTES[2U];
|
|
||||||
data[5U] = YSF_SYNC_BYTES[3U];
|
|
||||||
data[6U] = YSF_SYNC_BYTES[4U];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasData())
|
|
||||||
m_timer.stop();
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CYSFEcho::writeData(const unsigned char* data, unsigned int length)
|
|
||||||
{
|
|
||||||
bool ret = m_buffer.hasSpace(length + 1U);
|
|
||||||
if (!ret)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
unsigned char len = length;
|
|
||||||
m_buffer.addData(&len, 1U);
|
|
||||||
|
|
||||||
m_buffer.addData(data, length);
|
|
||||||
|
|
||||||
m_timer.start();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CYSFEcho::hasData()
|
|
||||||
{
|
|
||||||
if (m_timer.isRunning() && m_timer.hasExpired())
|
|
||||||
return m_buffer.hasData();
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CYSFEcho::clock(unsigned int ms)
|
|
||||||
{
|
|
||||||
m_timer.clock(ms);
|
|
||||||
}
|
|
43
YSFEcho.h
43
YSFEcho.h
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2015 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(YSFECHO_H)
|
|
||||||
#define YSFECHO_H
|
|
||||||
|
|
||||||
#include "RingBuffer.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
|
|
||||||
class CYSFEcho {
|
|
||||||
public:
|
|
||||||
CYSFEcho(unsigned int delay, unsigned int space);
|
|
||||||
~CYSFEcho();
|
|
||||||
|
|
||||||
unsigned int readData(unsigned char* data);
|
|
||||||
|
|
||||||
bool writeData(const unsigned char* data, unsigned int length);
|
|
||||||
|
|
||||||
bool hasData();
|
|
||||||
|
|
||||||
void clock(unsigned int ms);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CRingBuffer<unsigned char> m_buffer;
|
|
||||||
CTimer m_timer;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in a new issue