Start the voice transmission module.

This commit is contained in:
Jonathan Naylor
2017-05-01 14:46:43 +01:00
parent 55cb6beaf2
commit b9ebdee601
9 changed files with 228 additions and 15 deletions

View File

@@ -30,6 +30,7 @@ enum SECTION {
SECTION_NONE, SECTION_NONE,
SECTION_GENERAL, SECTION_GENERAL,
SECTION_LOG, SECTION_LOG,
SECTION_VOICE,
SECTION_DMR_NETWORK, SECTION_DMR_NETWORK,
SECTION_XLX_NETWORK SECTION_XLX_NETWORK
}; };
@@ -49,6 +50,8 @@ m_logDisplayLevel(0U),
m_logFileLevel(0U), m_logFileLevel(0U),
m_logFilePath(), m_logFilePath(),
m_logFileRoot(), m_logFileRoot(),
m_voiceEnabled(true),
m_voiceLanguage("en_GB"),
m_dmrNetworkAddress(), m_dmrNetworkAddress(),
m_dmrNetworkPort(0U), m_dmrNetworkPort(0U),
m_dmrNetworkLocal(0U), m_dmrNetworkLocal(0U),
@@ -82,20 +85,22 @@ bool CConf::read()
if (buffer[0U] == '#') if (buffer[0U] == '#')
continue; continue;
if (buffer[0U] == '[') { if (buffer[0U] == '[') {
if (::strncmp(buffer, "[General]", 9U) == 0) if (::strncmp(buffer, "[General]", 9U) == 0)
section = SECTION_GENERAL; section = SECTION_GENERAL;
else if (::strncmp(buffer, "[Log]", 5U) == 0) else if (::strncmp(buffer, "[Log]", 5U) == 0)
section = SECTION_LOG; section = SECTION_LOG;
else if (::strncmp(buffer, "[XLX Network]", 13U) == 0) else if (::strncmp(buffer, "[Voice]", 7U) == 0)
section = SECTION_XLX_NETWORK; section = SECTION_VOICE;
else if (::strncmp(buffer, "[DMR Network]", 13U) == 0) else if (::strncmp(buffer, "[XLX Network]", 13U) == 0)
section = SECTION_DMR_NETWORK; section = SECTION_XLX_NETWORK;
else else if (::strncmp(buffer, "[DMR Network]", 13U) == 0)
section = SECTION_NONE; section = SECTION_DMR_NETWORK;
else
section = SECTION_NONE;
continue; continue;
} }
char* key = ::strtok(buffer, " \t=\r\n"); char* key = ::strtok(buffer, " \t=\r\n");
if (key == NULL) if (key == NULL)
@@ -133,6 +138,11 @@ bool CConf::read()
m_logFileLevel = (unsigned int)::atoi(value); m_logFileLevel = (unsigned int)::atoi(value);
else if (::strcmp(key, "DisplayLevel") == 0) else if (::strcmp(key, "DisplayLevel") == 0)
m_logDisplayLevel = (unsigned int)::atoi(value); m_logDisplayLevel = (unsigned int)::atoi(value);
} else if (section == SECTION_VOICE) {
if (::strcmp(key, "Enabled") == 0)
m_voiceEnabled = ::atoi(value) == 1;
else if (::strcmp(key, "Language") == 0)
m_voiceLanguage = value;
} else if (section == SECTION_XLX_NETWORK) { } else if (section == SECTION_XLX_NETWORK) {
if (::strcmp(key, "Address") == 0) if (::strcmp(key, "Address") == 0)
m_xlxNetworkAddress = value; m_xlxNetworkAddress = value;
@@ -230,6 +240,16 @@ std::string CConf::getLogFileRoot() const
return m_logFileRoot; return m_logFileRoot;
} }
bool CConf::getVoiceEnabled() const
{
return m_voiceEnabled;
}
std::string CConf::getVoiceLanguage() const
{
return m_voiceLanguage;
}
std::string CConf::getXLXNetworkAddress() const std::string CConf::getXLXNetworkAddress() const
{ {
return m_xlxNetworkAddress; return m_xlxNetworkAddress;

7
Conf.h
View File

@@ -47,6 +47,10 @@ public:
std::string getLogFilePath() const; std::string getLogFilePath() const;
std::string getLogFileRoot() const; std::string getLogFileRoot() const;
// The Voice section
bool getVoiceEnabled() const;
std::string getVoiceLanguage() const;
// The DMR Network section // The DMR Network section
std::string getDMRNetworkAddress() const; std::string getDMRNetworkAddress() const;
unsigned int getDMRNetworkPort() const; unsigned int getDMRNetworkPort() const;
@@ -74,6 +78,9 @@ private:
unsigned int m_timeout; unsigned int m_timeout;
bool m_debug; bool m_debug;
bool m_voiceEnabled;
std::string m_voiceLanguage;
unsigned int m_logDisplayLevel; unsigned int m_logDisplayLevel;
unsigned int m_logFileLevel; unsigned int m_logFileLevel;
std::string m_logFilePath; std::string m_logFilePath;

View File

@@ -21,6 +21,7 @@
#include "StopWatch.h" #include "StopWatch.h"
#include "Rewrite.h" #include "Rewrite.h"
#include "Thread.h" #include "Thread.h"
#include "Voice.h"
#include "Log.h" #include "Log.h"
#include <cstdio> #include <cstdio>
@@ -63,7 +64,7 @@ enum DMRGW_STATUS {
const char* HEADER1 = "This software is for use on amateur radio networks only,"; const char* HEADER1 = "This software is for use on amateur radio networks only,";
const char* HEADER2 = "it is to be used for educational purposes only. Its use on"; const char* HEADER2 = "it is to be used for educational purposes only. Its use on";
const char* HEADER3 = "commercial networks is strictly prohibited."; const char* HEADER3 = "commercial networks is strictly prohibited.";
const char* HEADER4 = "Copyright(C) 2015-2017 by Jonathan Naylor, G4KLX and others"; const char* HEADER4 = "Copyright(C) 2017 by Jonathan Naylor, G4KLX and others";
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
@@ -247,6 +248,23 @@ int CDMRGateway::run()
if (!ret) if (!ret)
return 1; return 1;
CVoice* voice = NULL;
if (m_conf.getVoiceEnabled()) {
std::string language = m_conf.getVoiceLanguage();
LogInfo("Voice Parameters");
LogInfo(" Enabled: yes");
LogInfo(" Language: %s", language.c_str());
voice = new CVoice(language, xlxSlot, xlxTG);
bool ret = voice->open();
if (!ret) {
delete voice;
voice = NULL;
}
}
DMRGW_STATUS status = DMRGWS_NONE; DMRGW_STATUS status = DMRGWS_NONE;
CTimer timer(1000U, timeout); CTimer timer(1000U, timeout);
@@ -256,6 +274,8 @@ int CDMRGateway::run()
LogMessage("DMRGateway-%s is running", VERSION); LogMessage("DMRGateway-%s is running", VERSION);
bool changed = false;
while (!m_killed) { while (!m_killed) {
CDMRData data; CDMRData data;
@@ -281,12 +301,26 @@ int CDMRGateway::run()
LogMessage("Unlinking"); LogMessage("Unlinking");
m_reflector = id; m_reflector = id;
changed = true;
} }
xlxRewrite.process(data); xlxRewrite.process(data);
m_xlxNetwork->write(data); m_xlxNetwork->write(data);
status = DMRGWS_REFLECTOR; status = DMRGWS_REFLECTOR;
timer.start(); timer.start();
if (voice != NULL) {
unsigned char type = data.getDataType();
if (type == DT_TERMINATOR_WITH_LC) {
if (changed) {
if (m_reflector == 4000U)
voice->unlinked();
else
voice->linkedTo(m_reflector);
changed = false;
}
}
}
} else { } else {
m_dmrNetwork->write(data); m_dmrNetwork->write(data);
status = DMRGWS_NETWORK; status = DMRGWS_NETWORK;
@@ -334,6 +368,15 @@ int CDMRGateway::run()
} }
} }
if (voice != NULL) {
ret = voice->read(data);
if (ret) {
m_repeater->write(data);
status = DMRGWS_REFLECTOR;
timer.start();
}
}
unsigned int ms = stopWatch.elapsed(); unsigned int ms = stopWatch.elapsed();
stopWatch.start(); stopWatch.start();
@@ -341,6 +384,9 @@ int CDMRGateway::run()
m_dmrNetwork->clock(ms); m_dmrNetwork->clock(ms);
m_xlxNetwork->clock(ms); m_xlxNetwork->clock(ms);
if (voice != NULL)
voice->clock(ms);
timer.clock(ms); timer.clock(ms);
if (timer.isRunning() && timer.hasExpired()) { if (timer.isRunning() && timer.hasExpired()) {
status = DMRGWS_NONE; status = DMRGWS_NONE;
@@ -353,6 +399,8 @@ int CDMRGateway::run()
LogMessage("DMRGateway-%s is exiting on receipt of SIGHUP1", VERSION); LogMessage("DMRGateway-%s is exiting on receipt of SIGHUP1", VERSION);
delete voice;
m_repeater->close(); m_repeater->close();
delete m_repeater; delete m_repeater;

View File

@@ -16,6 +16,10 @@ FileLevel=1
FilePath=. FilePath=.
FileRoot=DMRGateway FileRoot=DMRGateway
[Voice]
Enabled=1
Language=en_GB
[XLX Network] [XLX Network]
Address=xlx950.epf.lu Address=xlx950.epf.lu
Port=55555 Port=55555

View File

@@ -175,6 +175,7 @@
<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="Voice.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="BPTC19696.cpp" /> <ClCompile Include="BPTC19696.cpp" />
@@ -203,6 +204,7 @@
<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="Voice.cpp" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@@ -98,6 +98,9 @@
<ClInclude Include="QR1676.h"> <ClInclude Include="QR1676.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Voice.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Conf.cpp"> <ClCompile Include="Conf.cpp">
@@ -178,5 +181,8 @@
<ClCompile Include="QR1676.cpp"> <ClCompile Include="QR1676.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Voice.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -5,7 +5,7 @@ LIBS = -lpthread
LDFLAGS = -g LDFLAGS = -g
OBJECTS = BPTC19696.o Conf.o CRC.o DMRData.o DMREmbeddedData.o DMREMB.o DMRFullLC.o DMRGateway.o DMRLC.o DMRNetwork.o DMRSlotType.o Golay2087.o Hamming.o Log.o \ OBJECTS = BPTC19696.o Conf.o CRC.o DMRData.o DMREmbeddedData.o DMREMB.o DMRFullLC.o DMRGateway.o DMRLC.o DMRNetwork.o DMRSlotType.o Golay2087.o Hamming.o Log.o \
MMDVMNetwork.o QR1676.o RepeaterProtocol.o Rewrite.o RS129.o SHA256.o StopWatch.o Sync.o Thread.o Timer.o UDPSocket.o Utils.o MMDVMNetwork.o QR1676.o RepeaterProtocol.o Rewrite.o RS129.o SHA256.o StopWatch.o Sync.o Thread.o Timer.o UDPSocket.o Utils.o Voice.o
all: DMRGateway all: DMRGateway

69
Voice.cpp Normal file
View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2017 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 "Voice.h"
CVoice::CVoice(const std::string& language, unsigned int slot, unsigned int tg) :
m_language(language),
m_slot(slot),
m_tg(tg),
m_status(VS_NONE),
m_timer(1000U, 1U),
m_stopWatch()
{
}
CVoice::~CVoice()
{
}
bool CVoice::open()
{
return true;
}
void CVoice::linkedTo(unsigned int id)
{
m_status = VS_WAITING;
m_timer.start();
}
void CVoice::unlinked()
{
m_status = VS_WAITING;
m_timer.start();
}
bool CVoice::read(CDMRData& data)
{
if (m_status != VS_SENDING)
return false;
return false;
}
void CVoice::clock(unsigned int ms)
{
m_timer.clock(ms);
if (m_timer.isRunning() && m_timer.hasExpired()) {
if (m_status == VS_WAITING) {
m_stopWatch.start();
m_status = VS_SENDING;
}
}
}

57
Voice.h Normal file
View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2017 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(Voice_H)
#define Voice_H
#include "StopWatch.h"
#include "DMRData.h"
#include "Timer.h"
#include <string>
enum VOICE_STATUS {
VS_NONE,
VS_WAITING,
VS_SENDING
};
class CVoice {
public:
CVoice(const std::string& language, unsigned int slot, unsigned int tg);
~CVoice();
bool open();
void linkedTo(unsigned int id);
void unlinked();
bool read(CDMRData& data);
void clock(unsigned int ms);
private:
std::string m_language;
unsigned int m_slot;
unsigned int m_tg;
VOICE_STATUS m_status;
CTimer m_timer;
CStopWatch m_stopWatch;
};
#endif