no threads in mmdvm service

pull/1/head
Tom Early 8 years ago
parent 53c0596232
commit 398a4fdb87

@ -42,8 +42,8 @@ g2_ircddb : $(IRCOBJS) g2_ircddb.o aprs.o
g2_link : g2_link.o
g++ $(CPPFLAGS) -o g2_link g2_link.o $(LDFLAGS) -pthread
mmdvm_modem : mmdvm_modem.o
g++ $(CPPFLAGS) -o mmdvm_modem mmdvm_modem.o $(LDFLAGS) -pthread
mmdvm_modem : mmdvm_modem.o UDPSocket.o
g++ $(CPPFLAGS) -o mmdvm_modem mmdvm_modem.o UDPSocket.o $(LDFLAGS)
dvap_rptr : dvap_rptr.o DVAPDongle.o $(DSTROBJS)
g++ $(CPPFLAGS) -o dvap_rptr dvap_rptr.o DVAPDongle.o $(DSTROBJS) $(LDFLAGS) -pthread

@ -0,0 +1,172 @@
/*
* Copyright (C) 2006-2016 by Jonathan Naylor G4KLX
* Copyright (c) 2018 by Thomas A. Early N7TAE
*
* 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 "UDPSocket.h"
#include <cassert>
#include <cstdio>
#include <cerrno>
#include <cstring>
CUDPSocket::CUDPSocket(const std::string& address, unsigned int port) :
m_address(address),
m_port(port),
m_fd(-1)
{
}
CUDPSocket::CUDPSocket(unsigned int port) :
m_address(),
m_port(port),
m_fd(-1)
{
}
CUDPSocket::~CUDPSocket()
{
}
in_addr CUDPSocket::lookup(const std::string& hostname)
{
in_addr addr;
in_addr_t address = ::inet_addr(hostname.c_str());
if (address != in_addr_t(-1)) {
addr.s_addr = address;
return addr;
}
struct hostent* hp = ::gethostbyname(hostname.c_str());
if (hp != NULL) {
::memcpy(&addr, hp->h_addr_list[0], sizeof(struct in_addr));
return addr;
}
printf("Cannot find address for host %s", hostname.c_str());
addr.s_addr = INADDR_NONE;
return addr;
}
bool CUDPSocket::open() // returns false on error
{
m_fd = ::socket(PF_INET, SOCK_DGRAM, 0);
if (m_fd < 0) {
printf("Cannot create the UDP socket, err: %d", errno);
return false;
}
if (m_port > 0U) {
sockaddr_in addr;
::memset(&addr, 0x00, sizeof(sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(m_port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (!m_address.empty()) {
addr.sin_addr.s_addr = ::inet_addr(m_address.c_str());
if (addr.sin_addr.s_addr == INADDR_NONE) {
printf("The local address is invalid - %s", m_address.c_str());
return false;
}
}
int reuse = 1;
if (::setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
printf("Cannot set the UDP socket option, err: %d", errno);
return false;
}
if (::bind(m_fd, (sockaddr*)&addr, sizeof(sockaddr_in)) == -1) {
printf("Cannot bind the UDP address, err: %d", errno);
return false;
}
}
return true;
}
int CUDPSocket::read(unsigned char* buffer, unsigned int length, in_addr& address, unsigned int& port)
{
assert(buffer != NULL);
assert(length > 0U);
// Check that the readfrom() won't block
fd_set readFds;
FD_ZERO(&readFds);
FD_SET(m_fd, &readFds);
// Return immediately
timeval tv;
tv.tv_sec = 0L;
tv.tv_usec = 0L;
int ret = ::select(m_fd + 1, &readFds, NULL, NULL, &tv);
if (ret < 0) {
printf("Error returned from UDP select, err: %d", errno);
return -1;
}
if (ret == 0)
return 0;
sockaddr_in addr;
socklen_t size = sizeof(sockaddr_in);
ssize_t len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&addr, &size);
if (len <= 0) {
printf("Error returned from recvfrom, err: %d", errno);
return -1;
}
address = addr.sin_addr;
port = ntohs(addr.sin_port);
return len;
}
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const in_addr& address, unsigned int port)
{
assert(buffer != NULL);
assert(length > 0U);
sockaddr_in addr;
::memset(&addr, 0x00, sizeof(sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr = address;
addr.sin_port = htons(port);
ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&addr, sizeof(sockaddr_in));
if (ret < 0) {
printf("Error returned from sendto, err: %d", errno);
return false;
}
if (ret != ssize_t(length))
return false;
return true;
}
void CUDPSocket::close()
{
::close(m_fd);
}

@ -0,0 +1,53 @@
/*
* Copyright (C) 2009-2011,2013,2015,2016 by Jonathan Naylor G4KLX
* Copyright (c) 2018 by Thomas A. Early N7TAE
*
* 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.
*/
#pragma once
#include <string>
#include <netdb.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
class CUDPSocket {
public:
CUDPSocket(const std::string& address, unsigned int port = 0U);
CUDPSocket(unsigned int port = 0U);
~CUDPSocket();
bool open();
int read(unsigned char* buffer, unsigned int length, in_addr& address, unsigned int& port);
bool write(const unsigned char* buffer, unsigned int length, const in_addr& address, unsigned int port);
void close();
static in_addr lookup(const std::string& hostName);
private:
std::string m_address;
unsigned short m_port;
int m_fd;
};

@ -25,6 +25,7 @@
#include "versions.h"
#include "mmdvm_modem.h"
#include "UDPSocket.h"
std::atomic<bool> CMMDVMModem::keep_running(true);
@ -57,25 +58,48 @@ bool CMMDVMModem::Initialize(const char *cfgfile)
return true;
}
// dstar_dv_init();
return false;
}
try {
mmdvm_future = std::async(std::launch::async, &CMMDVMModem::ProcessMMDVM, this);
} catch (const std::exception &e) {
printf("Unable to start ReadDVAPThread(). Exception: %s\n", e.what());
keep_running = false;
void CMMDVMModem::Run(const char *cfgfile)
{
if (Initialize(cfgfile))
return;
CUDPSocket GatewaySock(G2_INTERNAL_IP, G2_PORT);
if (GatewaySock.open())
return;
CUDPSocket MMDVMSock(MMDVM_IP, MMDVM_PORT);
if (MMDVMSock.open()) {
GatewaySock.close();
return;
}
printf("Started ProcessMMDVM() thread\n");
return false;
keep_running = true;
while (keep_running) {
ProcessMMDVM();
ProcessGateway();
}
MMDVMSock.close();
GatewaySock.close();
}
void CMMDVMModem::ProcessGateway()
{
// read from gateway
// if there is data, translate it and send it to the MMDVM Modem
}
void CMMDVMModem::ProcessMMDVM()
{
// read from the MMDVM modem
// if there is data, translate it and send it to the Gateway
}
bool CMMDVMModem::GetValue(const Config &cfg, const char *path, int &value, const int min, const int max, const int default_value)
@ -195,15 +219,15 @@ bool CMMDVMModem::ReadConfig(const char *cfgFile)
}
if (GetValue(cfg, std::string(mmdvm_path+".internal_ip").c_str(), value, 7, IP_SIZE, "0.0.0.0"))
strcpy(RPTR_VIRTUAL_IP, value.c_str());
MMDVM_IP = value;
else
return true;
GetValue(cfg, std::string(mmdvm_path+".port").c_str(), i, 10000, 65535, 20010);
RPTR_PORT = (unsigned short)i;
MMDVM_PORT = (unsigned short)i;
if (GetValue(cfg, "gateway.ip", value, 7, IP_SIZE, "127.0.0.1"))
strcpy(G2_INTERNAL_IP, value.c_str());
G2_INTERNAL_IP = value;
else
return true;
@ -246,17 +270,9 @@ int main(int argc, const char **argv)
CMMDVMModem mmdvm;
if (mmdvm.Initialize(argv[1])) {
printf("ERROR: Failed to process %s\n", argv[0]);
return 1;
}
while (mmdvm.keep_running) {
mmdvm.ProcessGateway();
}
mmdvm.Run(argv[1]);
mmdvm.mmdvm_future.get();
printf("%s is closed.\n", argv[0]);
printf("%s is closing.\n", argv[0]);
return 0;
}

@ -20,8 +20,6 @@
#include <atomic>
#include <string>
#include <future>
#include <libconfig.h++>
using namespace libconfig;
@ -35,17 +33,17 @@ public:
// functions
CMMDVMModem();
~CMMDVMModem();
bool Initialize(const char *cfgfile);
void ProcessGateway();
void Run(const char *cfgfile);
// data
static std::atomic<bool> keep_running;
std::future<void> mmdvm_future;
private:
// functions
void ProcessMMDVM();
bool Initialize(const char *cfgfile);
static void SignalCatch(int signum);
void ProcessGateway();
void ProcessMMDVM();
// read configuration file
bool ReadConfig(const char *);
@ -58,11 +56,11 @@ private:
char RPTR_MOD;
char RPTR[CALL_SIZE + 1];
char OWNER[CALL_SIZE + 1];
char RPTR_VIRTUAL_IP[IP_SIZE + 1];
char G2_INTERNAL_IP[IP_SIZE + 1];
unsigned short RPTR_PORT, G2_PORT;
std::string MMDVM_IP, G2_INTERNAL_IP;
unsigned short MMDVM_PORT, G2_PORT;
int WAIT_FOR_PACKETS, DELAY_BEFORE, DELAY_BETWEEN;
bool RPTR_ACK;
// parameters
int gateway_sock, mmdvm_sock;
};

Loading…
Cancel
Save

Powered by TurnKey Linux.