1
0
Fork 0

Improve the network state machines.

ycs232-kbc
Jonathan Naylor 4 years ago
parent 364c496507
commit ce8e34959f

@ -363,6 +363,8 @@ int CDGIdGateway::run()
LogMessage("Starting DGIdGateway-%s", VERSION); LogMessage("Starting DGIdGateway-%s", VERSION);
DGID_STATUS state = DS_NOTLINKED;
for (;;) { for (;;) {
unsigned char buffer[200U]; unsigned char buffer[200U];
memset(buffer, 0U, 200U); memset(buffer, 0U, 200U);
@ -394,6 +396,7 @@ int CDGIdGateway::run()
std::string desc = dgIdNetwork[dgId]->getDesc(dgId); std::string desc = dgIdNetwork[dgId]->getDesc(dgId);
LogDebug("DG-ID set to %u (%s) via RF", dgId, desc.c_str()); LogDebug("DG-ID set to %u (%s) via RF", dgId, desc.c_str());
currentDGId = dgId; currentDGId = dgId;
state = DS_NOTLINKED;
} }
if (m_gps != NULL) if (m_gps != NULL)
@ -444,6 +447,7 @@ int CDGIdGateway::run()
std::string desc = dgIdNetwork[i]->getDesc(i); std::string desc = dgIdNetwork[i]->getDesc(i);
LogDebug("DG-ID set to %u (%s) via Network", i, desc.c_str()); LogDebug("DG-ID set to %u (%s) via Network", i, desc.c_str());
currentDGId = i; currentDGId = i;
state = DS_LINKED;
} }
} }
} }
@ -474,8 +478,19 @@ int CDGIdGateway::run()
LogDebug("DG-ID set to 0 (None) via timeout"); LogDebug("DG-ID set to 0 (None) via timeout");
state = DS_NOTLINKED;
currentDGId = 0U; currentDGId = 0U;
inactivityTimer.stop(); inactivityTimer.stop();
sendPips(2U);
}
if (dgIdNetwork[currentDGId] != NULL) {
DGID_STATUS netState = dgIdNetwork[currentDGId]->getStatus();
if (state != DS_LINKED && netState == DS_LINKED)
sendPips(1U);
else if (state == DS_LINKED && netState != DS_LINKED)
sendPips(3U);
state = netState;
} }
if (ms < 5U) if (ms < 5U)
@ -602,3 +617,7 @@ std::string CDGIdGateway::calculateLocator()
return locator; return locator;
} }
void CDGIdGateway::sendPips(unsigned int n)
{
}

@ -42,6 +42,7 @@ private:
std::string calculateLocator(); std::string calculateLocator();
void createGPS(); void createGPS();
void sendPips(unsigned int n);
}; };
#endif #endif

@ -21,6 +21,13 @@
#include <string> #include <string>
enum DGID_STATUS {
DS_NOTOPEN,
DS_NOTLINKED,
DS_LINKING,
DS_LINKED
};
class CDGIdNetwork { class CDGIdNetwork {
public: public:
virtual ~CDGIdNetwork() = 0; virtual ~CDGIdNetwork() = 0;
@ -31,6 +38,8 @@ public:
virtual void link() = 0; virtual void link() = 0;
virtual DGID_STATUS getStatus() = 0;
virtual void write(unsigned int dgId, const unsigned char* data) = 0; virtual void write(unsigned int dgId, const unsigned char* data) = 0;
virtual unsigned int read(unsigned int dgid, unsigned char* data) = 0; virtual unsigned int read(unsigned int dgid, unsigned char* data) = 0;

@ -44,7 +44,7 @@ m_buffer(1000U, "FCS Network Buffer"),
m_n(0U), m_n(0U),
m_pingTimer(1000U, 0U, 800U), m_pingTimer(1000U, 0U, 800U),
m_resetTimer(1000U, 1U), m_resetTimer(1000U, 1U),
m_state(FCS_UNLINKED) m_state(DS_NOTOPEN)
{ {
m_info = new unsigned char[100U]; m_info = new unsigned char[100U];
::sprintf((char*)m_info, "%9u%9u%-6.6s%-12.12s%7u", rxFrequency, txFrequency, locator.c_str(), FCS_VERSION, id); ::sprintf((char*)m_info, "%9u%9u%-6.6s%-12.12s%7u", rxFrequency, txFrequency, locator.c_str(), FCS_VERSION, id);
@ -86,19 +86,32 @@ bool CFCSNetwork::open()
{ {
if (m_addrLen == 0U) { if (m_addrLen == 0U) {
LogError("Unable to resolve the address of %s", m_reflector.c_str()); LogError("Unable to resolve the address of %s", m_reflector.c_str());
m_state = DS_NOTOPEN;
return false; return false;
} }
LogMessage("Opening FCS network connection"); LogMessage("Opening FCS network connection");
return m_socket.open(m_addr); bool ret = m_socket.open(m_addr);
if (!ret) {
m_state = DS_NOTOPEN;
return false;
} else {
m_state = DS_NOTLINKED;
return true;
}
}
DGID_STATUS CFCSNetwork::getStatus()
{
return m_state;
} }
void CFCSNetwork::write(unsigned int dgid, const unsigned char* data) void CFCSNetwork::write(unsigned int dgid, const unsigned char* data)
{ {
assert(data != NULL); assert(data != NULL);
if (m_state != FCS_LINKED) if (m_state != DS_LINKED)
return; return;
unsigned char buffer[130U]; unsigned char buffer[130U];
@ -115,10 +128,10 @@ void CFCSNetwork::write(unsigned int dgid, const unsigned char* data)
void CFCSNetwork::link() void CFCSNetwork::link()
{ {
if (m_state == FCS_LINKING || m_state == FCS_LINKED) if (m_state != DS_NOTLINKED)
return; return;
m_state = FCS_LINKING; m_state = DS_LINKING;
m_pingTimer.start(); m_pingTimer.start();
@ -127,14 +140,21 @@ void CFCSNetwork::link()
void CFCSNetwork::unlink() void CFCSNetwork::unlink()
{ {
if (m_state != FCS_LINKED) if (m_state != DS_LINKED)
return; return;
m_socket.write((unsigned char*)"CLOSE ", 11U, m_addr, m_addrLen); m_socket.write((unsigned char*)"CLOSE ", 11U, m_addr, m_addrLen);
m_pingTimer.stop();
m_state = DS_NOTLINKED;
} }
void CFCSNetwork::clock(unsigned int ms) void CFCSNetwork::clock(unsigned int ms)
{ {
if (m_state == DS_NOTOPEN)
return;
m_pingTimer.clock(ms); m_pingTimer.clock(ms);
if (m_pingTimer.isRunning() && m_pingTimer.hasExpired()) { if (m_pingTimer.isRunning() && m_pingTimer.hasExpired()) {
writePing(); writePing();
@ -155,7 +175,7 @@ void CFCSNetwork::clock(unsigned int ms)
if (length <= 0) if (length <= 0)
return; return;
if (m_state == FCS_UNLINKED) if (m_state == DS_NOTLINKED)
return; return;
if (!CUDPSocket::match(addr, m_addr)) if (!CUDPSocket::match(addr, m_addr))
@ -165,16 +185,16 @@ void CFCSNetwork::clock(unsigned int ms)
CUtils::dump(1U, "FCS Network Data Received", buffer, length); CUtils::dump(1U, "FCS Network Data Received", buffer, length);
if (length == 7) { if (length == 7) {
if (m_state == FCS_LINKING) if (m_state == DS_LINKING)
LogMessage("Linked to %s", m_print.c_str()); LogMessage("Linked to %s", m_print.c_str());
m_state = FCS_LINKED; m_state = DS_LINKED;
writeInfo(); writeInfo();
writeOptions(m_print); writeOptions(m_print);
} }
if (length == 10 && m_state == FCS_LINKING) { if (length == 10 && m_state == DS_LINKING) {
LogMessage("Linked to %s", m_print.c_str()); LogMessage("Linked to %s", m_print.c_str());
m_state = FCS_LINKED; m_state = DS_LINKED;
writeInfo(); writeInfo();
writeOptions(m_print); writeOptions(m_print);
} }
@ -229,11 +249,13 @@ void CFCSNetwork::close()
m_socket.close(); m_socket.close();
LogMessage("Closing FCS network connection"); LogMessage("Closing FCS network connection");
m_state = DS_NOTOPEN;
} }
void CFCSNetwork::writeInfo() void CFCSNetwork::writeInfo()
{ {
if (m_state != FCS_LINKED) if (m_state != DS_LINKED)
return; return;
if (m_debug) if (m_debug)
@ -244,7 +266,7 @@ void CFCSNetwork::writeInfo()
void CFCSNetwork::writePing() void CFCSNetwork::writePing()
{ {
if (m_state == FCS_UNLINKED) if (m_state != DS_LINKING && m_state != DS_LINKED)
return; return;
if (m_debug) if (m_debug)
@ -255,7 +277,7 @@ void CFCSNetwork::writePing()
void CFCSNetwork::writeOptions(const std::string& reflector) void CFCSNetwork::writeOptions(const std::string& reflector)
{ {
if (m_state != FCS_LINKED) if (m_state != DS_LINKED)
return; return;
if (m_opt.size() < 1) if (m_opt.size() < 1)
@ -270,4 +292,3 @@ void CFCSNetwork::writeOptions(const std::string& reflector)
m_socket.write(m_options, 50U, m_addr, m_addrLen); m_socket.write(m_options, 50U, m_addr, m_addrLen);
} }

@ -28,12 +28,6 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
enum FCS_STATE {
FCS_UNLINKED,
FCS_LINKING,
FCS_LINKED
};
class CFCSNetwork : public CDGIdNetwork { class CFCSNetwork : public CDGIdNetwork {
public: public:
CFCSNetwork(const std::string& reflector, unsigned int port, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, unsigned int id, const std::string& options, bool debug); CFCSNetwork(const std::string& reflector, unsigned int port, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, unsigned int id, const std::string& options, bool debug);
@ -43,6 +37,8 @@ public:
virtual bool open(); virtual bool open();
virtual DGID_STATUS getStatus();
virtual void link(); virtual void link();
virtual void write(unsigned int dgId, const unsigned char* data); virtual void write(unsigned int dgId, const unsigned char* data);
@ -70,7 +66,7 @@ private:
unsigned char m_n; unsigned char m_n;
CTimer m_pingTimer; CTimer m_pingTimer;
CTimer m_resetTimer; CTimer m_resetTimer;
FCS_STATE m_state; DGID_STATUS m_state;
void writeOptions(const std::string& reflector); void writeOptions(const std::string& reflector);
void writeInfo(); void writeInfo();

@ -29,7 +29,8 @@
CIMRSNetwork::CIMRSNetwork() : CIMRSNetwork::CIMRSNetwork() :
m_socket(IMRS_PORT), m_socket(IMRS_PORT),
m_dgIds() m_dgIds(),
m_state(DS_NOTOPEN)
{ {
} }
@ -61,7 +62,19 @@ bool CIMRSNetwork::open()
{ {
LogMessage("Opening IMRS network connection"); LogMessage("Opening IMRS network connection");
return m_socket.open(); bool ret = m_socket.open();
if (!ret) {
m_state = DS_NOTOPEN;
return false;
} else {
m_state = DS_NOTLINKED;
return true;
}
}
DGID_STATUS CIMRSNetwork::getStatus()
{
return m_state;
} }
void CIMRSNetwork::write(unsigned int dgId, const unsigned char* data) void CIMRSNetwork::write(unsigned int dgId, const unsigned char* data)
@ -196,6 +209,8 @@ void CIMRSNetwork::close()
LogMessage("Closing IMRS network connection"); LogMessage("Closing IMRS network connection");
m_socket.close(); m_socket.close();
m_state = DS_NOTOPEN;
} }
IMRSDGId* CIMRSNetwork::find(const sockaddr_storage& addr) const IMRSDGId* CIMRSNetwork::find(const sockaddr_storage& addr) const

@ -61,6 +61,8 @@ public:
virtual bool open(); virtual bool open();
virtual DGID_STATUS getStatus();
virtual void link(); virtual void link();
virtual void write(unsigned int dgId, const unsigned char* data); virtual void write(unsigned int dgId, const unsigned char* data);
@ -76,6 +78,7 @@ public:
private: private:
CUDPSocket m_socket; CUDPSocket m_socket;
std::vector<IMRSDGId*> m_dgIds; std::vector<IMRSDGId*> m_dgIds;
DGID_STATUS m_state;
IMRSDGId* find(const sockaddr_storage& address) const; IMRSDGId* find(const sockaddr_storage& address) const;
IMRSDGId* find(unsigned int dgId) const; IMRSDGId* find(unsigned int dgId) const;

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2009-2014,2016,2017,2018 by Jonathan Naylor G4KLX * Copyright (C) 2009-2014,2016,2017,2018,2020 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
@ -38,7 +38,7 @@ m_unlink(NULL),
m_buffer(1000U, "YSF Network Buffer"), m_buffer(1000U, "YSF Network Buffer"),
m_pollTimer(1000U, 5U), m_pollTimer(1000U, 5U),
m_name(name), m_name(name),
m_linked(true) m_state(DS_NOTOPEN)
{ {
m_poll = new unsigned char[14U]; m_poll = new unsigned char[14U];
::memcpy(m_poll + 0U, "YSFP", 4U); ::memcpy(m_poll + 0U, "YSFP", 4U);
@ -66,7 +66,7 @@ m_unlink(NULL),
m_buffer(1000U, "YSF Network Buffer"), m_buffer(1000U, "YSF Network Buffer"),
m_pollTimer(1000U, 5U), m_pollTimer(1000U, 5U),
m_name(name), m_name(name),
m_linked(false) m_state(DS_NOTOPEN)
{ {
m_poll = new unsigned char[14U]; m_poll = new unsigned char[14U];
::memcpy(m_poll + 0U, "YSFP", 4U); ::memcpy(m_poll + 0U, "YSFP", 4U);
@ -113,19 +113,32 @@ bool CYSFNetwork::open()
{ {
if (m_addrLen == 0U) { if (m_addrLen == 0U) {
LogError("Unable to resolve the address of the YSF network"); LogError("Unable to resolve the address of the YSF network");
m_state = DS_NOTOPEN;
return false; return false;
} }
LogMessage("Opening YSF network connection"); LogMessage("Opening YSF network connection");
return m_socket.open(m_addr); bool ret = m_socket.open(m_addr);
if (!ret) {
m_state = DS_NOTOPEN;
return false;
} else {
m_state = DS_NOTLINKED;
return true;
}
}
DGID_STATUS CYSFNetwork::getStatus()
{
return m_state;
} }
void CYSFNetwork::write(unsigned int dgid, const unsigned char* data) void CYSFNetwork::write(unsigned int dgid, const unsigned char* data)
{ {
assert(data != NULL); assert(data != NULL);
if (!m_linked) if (m_state != DS_LINKED)
return; return;
if (m_debug) if (m_debug)
@ -136,11 +149,19 @@ void CYSFNetwork::write(unsigned int dgid, const unsigned char* data)
void CYSFNetwork::link() void CYSFNetwork::link()
{ {
if (m_state != DS_NOTLINKED)
return;
writePoll(); writePoll();
m_state = DS_LINKING;
} }
void CYSFNetwork::writePoll() void CYSFNetwork::writePoll()
{ {
if (m_state != DS_LINKING && m_state != DS_LINKED)
return;
m_pollTimer.start(); m_pollTimer.start();
m_socket.write(m_poll, 14U, m_addr, m_addrLen); m_socket.write(m_poll, 14U, m_addr, m_addrLen);
@ -151,15 +172,21 @@ void CYSFNetwork::writePoll()
void CYSFNetwork::unlink() void CYSFNetwork::unlink()
{ {
if (m_state != DS_LINKED)
return;
m_pollTimer.stop(); m_pollTimer.stop();
m_socket.write(m_unlink, 14U, m_addr, m_addrLen); m_socket.write(m_unlink, 14U, m_addr, m_addrLen);
m_linked = false; m_state = DS_NOTLINKED;
} }
void CYSFNetwork::clock(unsigned int ms) void CYSFNetwork::clock(unsigned int ms)
{ {
if (m_state == DS_NOTOPEN)
return;
m_pollTimer.clock(ms); m_pollTimer.clock(ms);
if (m_pollTimer.isRunning() && m_pollTimer.hasExpired()) if (m_pollTimer.isRunning() && m_pollTimer.hasExpired())
writePoll(); writePoll();
@ -184,13 +211,13 @@ void CYSFNetwork::clock(unsigned int ms)
if (::memcmp(buffer, "YSFO", 4U) == 0) if (::memcmp(buffer, "YSFO", 4U) == 0)
return; return;
if (::memcmp(buffer, "YSFP", 4U) == 0 && !m_linked) { if (::memcmp(buffer, "YSFP", 4U) == 0 && m_state == DS_LINKING) {
if (strcmp(m_name.c_str(),"MMDVM")== 0) if (strcmp(m_name.c_str(),"MMDVM")== 0)
LogMessage("Link successful to %s", m_name.c_str()); LogMessage("Link successful to %s", m_name.c_str());
else else
LogMessage("Linked to %s", m_name.c_str()); LogMessage("Linked to %s", m_name.c_str());
m_linked = true; m_state = DS_LINKED;
if (m_options != NULL) if (m_options != NULL)
m_socket.write(m_options, 50U, m_addr, m_addrLen); m_socket.write(m_options, 50U, m_addr, m_addrLen);
@ -222,4 +249,6 @@ void CYSFNetwork::close()
m_socket.close(); m_socket.close();
LogMessage("Closing YSF network connection"); LogMessage("Closing YSF network connection");
m_state = DS_NOTOPEN;
} }

@ -40,6 +40,8 @@ public:
virtual bool open(); virtual bool open();
virtual DGID_STATUS getStatus();
virtual void link(); virtual void link();
virtual void write(unsigned int dgId, const unsigned char* data); virtual void write(unsigned int dgId, const unsigned char* data);
@ -63,7 +65,7 @@ private:
CRingBuffer<unsigned char> m_buffer; CRingBuffer<unsigned char> m_buffer;
CTimer m_pollTimer; CTimer m_pollTimer;
std::string m_name; std::string m_name;
bool m_linked; DGID_STATUS m_state;
void writePoll(); void writePoll();
}; };

Loading…
Cancel
Save