uses TCP instead of unix sockets

main
Tom Early 2 years ago
parent 02c6396241
commit 842d2e0a59

20
.gitignore vendored

@ -7,24 +7,8 @@
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Files
tcd.*
# Visual Studio
.vscode

@ -21,6 +21,7 @@
#include <fstream>
#include <vector>
#include <sstream>
#include <regex>
#include "Configure.h"
// ini file keywords
@ -30,7 +31,9 @@
#define DMRGAINOUT "DmrYsfGainOut"
#define DSTARGAININ "DStarGainIn"
#define DSTARGAINOUT "DStarGainOut"
#define TRANSCODED "Transcoded"
#define MODULES "Modules"
#define ADDRESS "Address"
#define PORT "Port"
static inline void split(const std::string &s, char delim, std::vector<std::string> &v)
{
@ -63,7 +66,10 @@ static inline void trim(std::string &s) {
bool CConfigure::ReadData(const std::string &path)
// returns true on failure
{
std::string modstmp;
std::regex IPv4RegEx = std::regex("^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3,3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]){1,1}$", std::regex::extended);
std::regex IPv6RegEx = std::regex("^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}(:[0-9a-fA-F]{1,4}){1,1}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|([0-9a-fA-F]{1,4}:){1,1}(:[0-9a-fA-F]{1,4}){1,6}|:((:[0-9a-fA-F]{1,4}){1,7}|:))$", std::regex::extended);
std::string modstmp, porttmp;
std::ifstream cfgfile(path.c_str(), std::ifstream::in);
if (! cfgfile.is_open()) {
@ -104,7 +110,11 @@ bool CConfigure::ReadData(const std::string &path)
std::cout << "WARNING: missing key or value: '" << line << "'" << std::endl;
continue;
}
if (0 == key.compare(TRANSCODED))
if (0 == key.compare(ADDRESS))
address.assign(value);
else if (0 == key.compare(PORT))
porttmp.assign(value);
else if (0 == key.compare(MODULES))
modstmp.assign(value);
else if (0 == key.compare(DSTARGAININ))
dstar_in = getSigned(key, value);
@ -139,7 +149,22 @@ bool CConfigure::ReadData(const std::string &path)
return true;
}
std::cout << TRANSCODED << " = " << tcmods << std::endl;
if (! std::regex_match(address, IPv4RegEx) && ! std::regex_match(address, IPv6RegEx))
{
std::cerr << "ERROR: '" << address << "' is malformed, Halt." << std::endl;
return true;
}
port = std::strtoul(porttmp.c_str(), nullptr, 10);
if (port < 1025 || port > 49000)
{
std::cerr << "ERROR: Port '" << porttmp << "' must be between >1024 and <49000. Halt." << std::endl;
return true;
}
std::cout << MODULES << " = " << tcmods << std::endl;
std::cout << ADDRESS << " = " << address << std::endl;
std::cout << PORT << " = " << port << std::endl;
std::cout << DSTARGAININ << " = " << dstar_in << std::endl;
std::cout << DSTARGAINOUT << " = " << dstar_out << std::endl;
std::cout << DMRGAININ << " = " << dmr_in << std::endl;

@ -32,10 +32,13 @@ public:
bool ReadData(const std::string &path);
int GetGain(EGainType gt) const;
std::string GetTCMods(void) const { return tcmods; }
std::string GetAddress(void) const { return address; }
unsigned GetPort(void) const { return port; }
private:
// CFGDATA data;
std::string tcmods;
std::string tcmods, address;
uint16_t port;
int dstar_in, dstar_out, dmr_in, dmr_out, usrp_tx, usrp_rx;
int getSigned(const std::string &key, const std::string &value) const;

@ -22,6 +22,7 @@
#include <sstream>
#include <fstream>
#include <thread>
#include <queue>
#ifdef USE_SW_AMBE2
#include <md380_vocoder.h>
#endif
@ -46,7 +47,7 @@ bool CController::Start()
usrp_rx_num = calcNumerator(g_Conf.GetGain(EGainType::usrprx));
usrp_tx_num = calcNumerator(g_Conf.GetGain(EGainType::usrptx));
if (InitVocoders() || reader.Open(REF2TC))
if (InitVocoders() || tcClient.Initialize(g_Conf.GetAddress(), g_Conf.GetTCMods(), g_Conf.GetPort()))
{
keep_running = false;
return true;
@ -70,7 +71,7 @@ void CController::Stop()
if (c2Future.valid())
c2Future.get();
reader.Close();
tcClient.Close();
dstar_device->CloseDevice();
dmrsf_device->CloseDevice();
dstar_device.reset();
@ -249,25 +250,27 @@ void CController::ReadReflectorThread()
{
while (keep_running)
{
STCPacket tcpack;
std::queue<std::unique_ptr<STCPacket>> queue;
// wait up to 100 ms to read something on the unix port
if (reader.Receive(&tcpack, 100))
if (tcClient.Receive(queue, 100))
{
while (! queue.empty())
{
// create a shared pointer to a new packet
// there is only one CTranscoderPacket created for each new STCPacket received from the reflector
auto packet = std::make_shared<CTranscoderPacket>(tcpack);
auto packet = std::make_shared<CTranscoderPacket>(*queue.front());
queue.pop();
switch (packet->GetCodecIn())
{
case ECodecType::dstar:
dstar_device->AddPacket(packet);
break;
case ECodecType::dmr:
#ifdef USE_SW_AMBE2
#ifdef USE_SW_AMBE2
swambe2_queue.push(packet);
#else
#else
dmrsf_device->AddPacket(packet);
#endif
#endif
break;
case ECodecType::p25:
imbe_queue.push(packet);
@ -285,6 +288,7 @@ void CController::ReadReflectorThread()
}
}
}
}
}
// This is only called when codec_in was dstar or dmr. Obviously, the incoming
@ -595,14 +599,8 @@ void CController::ProcessUSRPThread()
void CController::SendToReflector(std::shared_ptr<CTranscoderPacket> packet)
{
// open a socket to the reflector channel
CUnixDgramWriter socket;
std::string name(TC2REF);
name.append(1, packet->GetModule());
socket.SetUp(name.c_str());
// send the packet over the socket
socket.Send(packet->GetTCPacket());
// the socket will automatically close after sending
tcClient.Send(packet->GetTCPacket());
packet->Sent();
}

@ -29,7 +29,7 @@
#include "codec2.h"
#include "DV3000.h"
#include "DV3003.h"
#include "UnixDgramSocket.h"
#include "TCSocket.h"
class CController
{
@ -48,8 +48,7 @@ protected:
std::future<void> reflectorFuture, c2Future, imbeFuture, usrpFuture;
std::unordered_map<char, int16_t[160]> audio_store;
std::unordered_map<char, uint8_t[8]> data_store;
CUnixDgramReader reader;
CUnixDgramWriter writer;
CTCClient tcClient;
std::unordered_map<char, std::unique_ptr<CCodec2>> c2_16, c2_32;
std::unique_ptr<CDVDevice> dstar_device, dmrsf_device;

@ -0,0 +1 @@
../urfd/reflector/IP.cpp

@ -0,0 +1 @@
../urfd/reflector/IP.h

@ -5,9 +5,9 @@ include tcd.mk
GCC = g++
ifeq ($(debug), true)
CFLAGS = -ggdb3 -W -Werror -Icodec2 -MMD -MD -std=c++11
CFLAGS = -ggdb3 -W -Werror -Icodec2 -MMD -MD -std=c++17
else
CFLAGS = -W -Werror -Icodec2 -MMD -MD -std=c++11
CFLAGS = -W -Werror -Icodec2 -MMD -MD -std=c++17
endif
ifeq ($(swambe2), true)

@ -20,7 +20,7 @@ Currently, this program must be run locally with its paired URF reflector. Remot
Only systemd-based operating systems are supported. Debian or Ubuntu is recommended. If you want to install this on a non-systemd based OS, you are on your own. Also, by default, *tcd* is built without gdb support.
The P25 IMBE software vocoder library is available [here](https://github.com/nostar/imbe_vocoder). See its README.md file for instructions for compiling and installating this library.
The P25 IMBE software vocoder library is available [here](https://github.com/nostar/imbe_vocoder). See its README.md file for instructions for compiling and installing this library.
If you are running tcd on an ARM-base processor, you can opt to use a software-based vocoder library available [here](https://github.com/nostar/md380_vocoder) for DMR/YSF vocoding. This library is used for the AMBE+2 (DMR/YSF/NXDN) codec. If you are going to use this library, *tcd* must run on an ARM platform like a RPi. Using this software solution means that you only need one DVSI device to handle D-Star vocoding.

@ -0,0 +1 @@
../urfd/reflector/TCSocket.cpp

@ -0,0 +1 @@
../urfd/reflector/TCSocket.h

@ -1 +0,0 @@
../urfd/reflector/UnixDgramSocket.cpp

@ -1 +0,0 @@
../urfd/reflector/UnixDgramSocket.h

@ -2,10 +2,13 @@
#
# this is a comment
# VERY IMPORTANT: This need to be idential to the same line in the urfd ini file!
Port = 10100
ServerAddress = 127.0.0.1
# VERY IMPORTANT: This need to be idential to the same line in [Transcder] section of the urfd ini file!
# This will either be a single module (for DVSI-3000), or
# up to three modules (for DVSI-3003).
Transcoded = A
Modules = A
# All gain values are in dB.
# Gain values are limited to -24 to +24. Typical values will usually be less.

Loading…
Cancel
Save

Powered by TurnKey Linux.