mirror of https://github.com/g4klx/DMRGateway
Improve the ability of the logging in to the DMR Master when the
connection is lost.
This commit is contained in:
parent
d4f7d11bdd
commit
9725179f85
163
DMRNetwork.cpp
163
DMRNetwork.cpp
|
|
@ -31,6 +31,8 @@ const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U;
|
||||||
|
|
||||||
|
|
||||||
CDMRNetwork::CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, const std::string& name, bool location, bool debug) :
|
CDMRNetwork::CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, const std::string& name, bool location, bool debug) :
|
||||||
|
m_address(address),
|
||||||
|
m_port(port),
|
||||||
m_addr(),
|
m_addr(),
|
||||||
m_addrLen(0U),
|
m_addrLen(0U),
|
||||||
m_id(NULL),
|
m_id(NULL),
|
||||||
|
|
@ -55,9 +57,6 @@ m_beacon(false)
|
||||||
assert(id > 1000U);
|
assert(id > 1000U);
|
||||||
assert(!password.empty());
|
assert(!password.empty());
|
||||||
|
|
||||||
if (CUDPSocket::lookup(address, port, m_addr, m_addrLen) != 0)
|
|
||||||
m_addrLen = 0U;
|
|
||||||
|
|
||||||
m_buffer = new unsigned char[BUFFER_LENGTH];
|
m_buffer = new unsigned char[BUFFER_LENGTH];
|
||||||
m_salt = new unsigned char[sizeof(uint32_t)];
|
m_salt = new unsigned char[sizeof(uint32_t)];
|
||||||
m_id = new uint8_t[4U];
|
m_id = new uint8_t[4U];
|
||||||
|
|
@ -90,7 +89,7 @@ void CDMRNetwork::setConfig(const unsigned char* data, unsigned int len)
|
||||||
|
|
||||||
bool CDMRNetwork::open()
|
bool CDMRNetwork::open()
|
||||||
{
|
{
|
||||||
if (m_addrLen == 0U) {
|
if (CUDPSocket::lookup(m_address, m_port, m_addr, m_addrLen) != 0) {
|
||||||
LogError("%s, Could not lookup the address of the master", m_name.c_str());
|
LogError("%s, Could not lookup the address of the master", m_name.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -304,23 +303,36 @@ void CDMRNetwork::close()
|
||||||
|
|
||||||
void CDMRNetwork::clock(unsigned int ms)
|
void CDMRNetwork::clock(unsigned int ms)
|
||||||
{
|
{
|
||||||
if (m_status == WAITING_CONNECT) {
|
m_retryTimer.clock(ms);
|
||||||
m_retryTimer.clock(ms);
|
if (m_retryTimer.isRunning() && m_retryTimer.hasExpired()) {
|
||||||
if (m_retryTimer.isRunning() && m_retryTimer.hasExpired()) {
|
switch (m_status) {
|
||||||
bool ret = m_socket.open(m_addr);
|
case WAITING_CONNECT:
|
||||||
if (ret) {
|
if (m_socket.open(m_addr.ss_family)) {
|
||||||
ret = writeLogin();
|
if (writeLogin()) {
|
||||||
if (!ret)
|
m_status = WAITING_LOGIN;
|
||||||
return;
|
}
|
||||||
|
|
||||||
m_status = WAITING_LOGIN;
|
|
||||||
m_timeoutTimer.start();
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
m_retryTimer.start();
|
case WAITING_LOGIN:
|
||||||
|
writeLogin();
|
||||||
|
break;
|
||||||
|
case WAITING_AUTHORISATION:
|
||||||
|
writeAuthorisation();
|
||||||
|
break;
|
||||||
|
case WAITING_OPTIONS:
|
||||||
|
writeOptions();
|
||||||
|
break;
|
||||||
|
case WAITING_CONFIG:
|
||||||
|
writeConfig();
|
||||||
|
break;
|
||||||
|
case RUNNING:
|
||||||
|
writePing();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
m_retryTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
sockaddr_storage address;
|
sockaddr_storage address;
|
||||||
|
|
@ -333,18 +345,23 @@ void CDMRNetwork::clock(unsigned int ms)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_debug && length > 0)
|
if (length > 0) {
|
||||||
CUtils::dump(1U, "Network Received", m_buffer, length);
|
if (!CUDPSocket::match(m_addr, address)) {
|
||||||
|
LogMessage("%s, packet received from an invalid source", m_name.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_debug) {
|
||||||
|
char buffer[100U];
|
||||||
|
::sprintf(buffer, "%s, Network Received", m_name.c_str());
|
||||||
|
CUtils::dump(1U, buffer, m_buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
if (length > 0 && CUDPSocket::match(m_addr, address)) {
|
|
||||||
if (::memcmp(m_buffer, "DMRD", 4U) == 0) {
|
if (::memcmp(m_buffer, "DMRD", 4U) == 0) {
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "Network Received", m_buffer, length);
|
|
||||||
|
|
||||||
unsigned char len = length;
|
unsigned char len = length;
|
||||||
m_rxData.addData(&len, 1U);
|
m_rxData.addData(&len, 1U);
|
||||||
m_rxData.addData(m_buffer, len);
|
m_rxData.addData(m_buffer, len);
|
||||||
} else if (::memcmp(m_buffer, "MSTNAK", 6U) == 0) {
|
} else if (::memcmp(m_buffer, "MSTNAK", 6U) == 0) {
|
||||||
if (m_status == RUNNING) {
|
if (m_status == RUNNING) {
|
||||||
LogWarning("%s, Login to the master has failed, retrying login ...", m_name.c_str());
|
LogWarning("%s, Login to the master has failed, retrying login ...", m_name.c_str());
|
||||||
m_status = WAITING_LOGIN;
|
m_status = WAITING_LOGIN;
|
||||||
|
|
@ -359,45 +376,46 @@ void CDMRNetwork::clock(unsigned int ms)
|
||||||
open();
|
open();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (::memcmp(m_buffer, "RPTACK", 6U) == 0) {
|
} else if (::memcmp(m_buffer, "RPTACK", 6U) == 0) {
|
||||||
switch (m_status) {
|
switch (m_status) {
|
||||||
case WAITING_LOGIN:
|
case WAITING_LOGIN:
|
||||||
LogDebug("%s, Sending authorisation", m_name.c_str());
|
LogDebug("%s, Sending authorisation", m_name.c_str());
|
||||||
::memcpy(m_salt, m_buffer + 6U, sizeof(uint32_t));
|
::memcpy(m_salt, m_buffer + 6U, sizeof(uint32_t));
|
||||||
writeAuthorisation();
|
writeAuthorisation();
|
||||||
m_status = WAITING_AUTHORISATION;
|
m_status = WAITING_AUTHORISATION;
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_retryTimer.start();
|
m_retryTimer.start();
|
||||||
break;
|
break;
|
||||||
case WAITING_AUTHORISATION:
|
case WAITING_AUTHORISATION:
|
||||||
LogDebug("%s, Sending configuration", m_name.c_str());
|
LogDebug("%s, Sending configuration", m_name.c_str());
|
||||||
writeConfig();
|
writeConfig();
|
||||||
m_status = WAITING_CONFIG;
|
m_status = WAITING_CONFIG;
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_retryTimer.start();
|
m_retryTimer.start();
|
||||||
break;
|
break;
|
||||||
case WAITING_CONFIG:
|
case WAITING_CONFIG:
|
||||||
if (m_options.empty()) {
|
if (m_options.empty()) {
|
||||||
LogMessage("%s, Logged into the master successfully", m_name.c_str());
|
|
||||||
m_status = RUNNING;
|
|
||||||
} else {
|
|
||||||
LogDebug("%s, Sending options", m_name.c_str());
|
|
||||||
writeOptions();
|
|
||||||
m_status = WAITING_OPTIONS;
|
|
||||||
}
|
|
||||||
m_timeoutTimer.start();
|
|
||||||
m_retryTimer.start();
|
|
||||||
break;
|
|
||||||
case WAITING_OPTIONS:
|
|
||||||
LogMessage("%s, Logged into the master successfully", m_name.c_str());
|
LogMessage("%s, Logged into the master successfully", m_name.c_str());
|
||||||
m_status = RUNNING;
|
m_status = RUNNING;
|
||||||
m_timeoutTimer.start();
|
}
|
||||||
m_retryTimer.start();
|
else {
|
||||||
break;
|
LogDebug("%s, Sending options", m_name.c_str());
|
||||||
default:
|
writeOptions();
|
||||||
break;
|
m_status = WAITING_OPTIONS;
|
||||||
|
}
|
||||||
|
m_timeoutTimer.start();
|
||||||
|
m_retryTimer.start();
|
||||||
|
break;
|
||||||
|
case WAITING_OPTIONS:
|
||||||
|
LogMessage("%s, Logged into the master successfully", m_name.c_str());
|
||||||
|
m_status = RUNNING;
|
||||||
|
m_timeoutTimer.start();
|
||||||
|
m_retryTimer.start();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (::memcmp(m_buffer, "MSTCL", 5U) == 0) {
|
} else if (::memcmp(m_buffer, "MSTCL", 5U) == 0) {
|
||||||
LogError("%s, Master is closing down", m_name.c_str());
|
LogError("%s, Master is closing down", m_name.c_str());
|
||||||
close();
|
close();
|
||||||
open();
|
open();
|
||||||
|
|
@ -412,31 +430,6 @@ void CDMRNetwork::clock(unsigned int ms)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_retryTimer.clock(ms);
|
|
||||||
if (m_retryTimer.isRunning() && m_retryTimer.hasExpired()) {
|
|
||||||
switch (m_status) {
|
|
||||||
case WAITING_LOGIN:
|
|
||||||
writeLogin();
|
|
||||||
break;
|
|
||||||
case WAITING_AUTHORISATION:
|
|
||||||
writeAuthorisation();
|
|
||||||
break;
|
|
||||||
case WAITING_OPTIONS:
|
|
||||||
writeOptions();
|
|
||||||
break;
|
|
||||||
case WAITING_CONFIG:
|
|
||||||
writeConfig();
|
|
||||||
break;
|
|
||||||
case RUNNING:
|
|
||||||
writePing();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_retryTimer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_timeoutTimer.clock(ms);
|
m_timeoutTimer.clock(ms);
|
||||||
if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) {
|
if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) {
|
||||||
LogError("%s, Connection to the master has timed out, retrying connection", m_name.c_str());
|
LogError("%s, Connection to the master has timed out, retrying connection", m_name.c_str());
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018,2020,2021 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
|
||||||
|
|
@ -58,6 +58,8 @@ public:
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::string m_address;
|
||||||
|
unsigned int m_port;
|
||||||
sockaddr_storage m_addr;
|
sockaddr_storage m_addr;
|
||||||
unsigned int m_addrLen;
|
unsigned int m_addrLen;
|
||||||
uint8_t* m_id;
|
uint8_t* m_id;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue