diff --git a/src/common/lookups/RadioIdLookup.cpp b/src/common/lookups/RadioIdLookup.cpp
index 672373b7..ba0fb379 100644
--- a/src/common/lookups/RadioIdLookup.cpp
+++ b/src/common/lookups/RadioIdLookup.cpp
@@ -131,7 +131,6 @@ RadioId RadioIdLookup::find(uint32_t id)
///
void RadioIdLookup::commit()
{
- // bryanb: TODO TODO TODO
save();
}
diff --git a/src/common/network/BaseNetwork.h b/src/common/network/BaseNetwork.h
index c4f2969d..b0a60f90 100644
--- a/src/common/network/BaseNetwork.h
+++ b/src/common/network/BaseNetwork.h
@@ -50,6 +50,7 @@
#define TAG_REPEATER_PING "RPTP"
#define TAG_REPEATER_GRANT "RPTG"
+#define TAG_TRANSFER "TRNS"
#define TAG_TRANSFER_ACT_LOG "TRNSLOG"
#define TAG_TRANSFER_DIAG_LOG "TRNSDIAG"
@@ -137,6 +138,9 @@ namespace network
enum NET_CONN_NAK_REASON {
NET_CONN_NAK_GENERAL_FAILURE,
+ NET_CONN_NAK_MODE_NOT_ENABLED,
+ NET_CONN_NAK_ILLEGAL_PACKET,
+
NET_CONN_NAK_FNE_UNAUTHORIZED,
NET_CONN_NAK_BAD_CONN_STATE,
NET_CONN_NAK_INVALID_CONFIG_DATA,
diff --git a/src/fne/network/FNENetwork.cpp b/src/fne/network/FNENetwork.cpp
index 2cfb4fe6..eaba1a4d 100644
--- a/src/fne/network/FNENetwork.cpp
+++ b/src/fne/network/FNENetwork.cpp
@@ -387,6 +387,8 @@ void* FNENetwork::threadedNetworkRx(void* arg)
if (network->m_tagDMR != nullptr) {
network->m_tagDMR->processFrame(req->buffer, req->length, peerId, req->rtpHeader.getSequence(), streamId);
}
+ } else {
+ network->writePeerNAK(peerId, TAG_DMR_DATA, NET_CONN_NAK_MODE_NOT_ENABLED);
}
}
}
@@ -408,6 +410,8 @@ void* FNENetwork::threadedNetworkRx(void* arg)
if (network->m_tagP25 != nullptr) {
network->m_tagP25->processFrame(req->buffer, req->length, peerId, req->rtpHeader.getSequence(), streamId);
}
+ } else {
+ network->writePeerNAK(peerId, TAG_P25_DATA, NET_CONN_NAK_MODE_NOT_ENABLED);
}
}
}
@@ -429,6 +433,8 @@ void* FNENetwork::threadedNetworkRx(void* arg)
if (network->m_tagNXDN != nullptr) {
network->m_tagNXDN->processFrame(req->buffer, req->length, peerId, req->rtpHeader.getSequence(), streamId);
}
+ } else {
+ network->writePeerNAK(peerId, TAG_NXDN_DATA, NET_CONN_NAK_MODE_NOT_ENABLED);
}
}
}
@@ -708,7 +714,47 @@ void* FNENetwork::threadedNetworkRx(void* arg)
// validate peer (simple validation really)
if (connection->connected() && connection->address() == ip) {
- /* ignored */
+ uint32_t srcId = __GET_UINT16(req->buffer, 11U); // Source Address
+ uint32_t dstId = __GET_UINT16(req->buffer, 15U); // Destination Address
+
+ uint8_t slot = req->buffer[19U];
+
+ bool unitToUnit = (req->buffer[19U] & 0x80U) == 0x80U;
+
+ DVM_STATE state = (DVM_STATE)req->buffer[20U]; // DVM Mode State
+ switch (state) {
+ case STATE_DMR:
+ if (network->m_dmrEnabled) {
+ if (network->m_tagDMR != nullptr) {
+ network->m_tagDMR->processGrantReq(srcId, dstId, slot, unitToUnit, peerId, req->rtpHeader.getSequence(), streamId);
+ } else {
+ network->writePeerNAK(peerId, TAG_DMR_DATA, NET_CONN_NAK_MODE_NOT_ENABLED);
+ }
+ }
+ break;
+ case STATE_P25:
+ if (network->m_p25Enabled) {
+ if (network->m_tagP25 != nullptr) {
+ network->m_tagP25->processGrantReq(srcId, dstId, unitToUnit, peerId, req->rtpHeader.getSequence(), streamId);
+ } else {
+ network->writePeerNAK(peerId, TAG_P25_DATA, NET_CONN_NAK_MODE_NOT_ENABLED);
+ }
+ }
+ break;
+ case STATE_NXDN:
+ if (network->m_nxdnEnabled) {
+ if (network->m_tagNXDN != nullptr) {
+ network->m_tagNXDN->processGrantReq(srcId, dstId, unitToUnit, peerId, req->rtpHeader.getSequence(), streamId);
+ } else {
+ network->writePeerNAK(peerId, TAG_NXDN_DATA, NET_CONN_NAK_MODE_NOT_ENABLED);
+ }
+ }
+ break;
+ default:
+ network->writePeerNAK(peerId, TAG_REPEATER_GRANT, NET_CONN_NAK_ILLEGAL_PACKET);
+ Utils::dump("unknown state for grant request from the peer", req->buffer, req->length);
+ break;
+ }
}
else {
network->writePeerNAK(peerId, TAG_REPEATER_GRANT, NET_CONN_NAK_FNE_UNAUTHORIZED);
@@ -770,6 +816,7 @@ void* FNENetwork::threadedNetworkRx(void* arg)
}
}
else {
+ network->writePeerNAK(peerId, TAG_TRANSFER, NET_CONN_NAK_ILLEGAL_PACKET);
Utils::dump("unknown transfer opcode from the peer", req->buffer, req->length);
}
}
@@ -786,8 +833,8 @@ void* FNENetwork::threadedNetworkRx(void* arg)
// validate peer (simple validation really)
if (connection->connected() && connection->address() == ip) {
- uint32_t srcId = __GET_UINT16(req->buffer, 0U);
- uint32_t dstId = __GET_UINT16(req->buffer, 3U);
+ uint32_t srcId = __GET_UINT16(req->buffer, 0U); // Source Address
+ uint32_t dstId = __GET_UINT16(req->buffer, 3U); // Destination Address
aff->groupUnaff(srcId);
aff->groupAff(srcId, dstId);
}
@@ -806,7 +853,7 @@ void* FNENetwork::threadedNetworkRx(void* arg)
// validate peer (simple validation really)
if (connection->connected() && connection->address() == ip) {
- uint32_t srcId = __GET_UINT16(req->buffer, 0U);
+ uint32_t srcId = __GET_UINT16(req->buffer, 0U); // Source Address
aff->unitReg(srcId);
}
else {
@@ -824,7 +871,7 @@ void* FNENetwork::threadedNetworkRx(void* arg)
// validate peer (simple validation really)
if (connection->connected() && connection->address() == ip) {
- uint32_t srcId = __GET_UINT16(req->buffer, 0U);
+ uint32_t srcId = __GET_UINT16(req->buffer, 0U); // Source Address
aff->unitDereg(srcId);
}
else {
@@ -863,6 +910,7 @@ void* FNENetwork::threadedNetworkRx(void* arg)
}
}
else {
+ network->writePeerNAK(peerId, TAG_ANNOUNCE, NET_CONN_NAK_ILLEGAL_PACKET);
Utils::dump("unknown announcement opcode from the peer", req->buffer, req->length);
}
}
diff --git a/src/fne/network/FNENetwork.h b/src/fne/network/FNENetwork.h
index 2e692e57..32869fae 100644
--- a/src/fne/network/FNENetwork.h
+++ b/src/fne/network/FNENetwork.h
@@ -40,6 +40,20 @@ namespace network { namespace fne { class HOST_SW_API TagNXDNData; } }
namespace network
{
+ // ---------------------------------------------------------------------------
+ // Constants
+ // ---------------------------------------------------------------------------
+
+ enum DVM_STATE {
+ STATE_IDLE = 0U,
+ // DMR
+ STATE_DMR = 1U,
+ // Project 25
+ STATE_P25 = 2U,
+ // NXDN
+ STATE_NXDN = 3U,
+ };
+
// ---------------------------------------------------------------------------
// Class Prototypes
// ---------------------------------------------------------------------------
diff --git a/src/fne/network/fne/TagDMRData.cpp b/src/fne/network/fne/TagDMRData.cpp
index 2c6cd261..9cc9ffed 100644
--- a/src/fne/network/fne/TagDMRData.cpp
+++ b/src/fne/network/fne/TagDMRData.cpp
@@ -289,6 +289,23 @@ bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId
return false;
}
+///
+/// Process a grant request frame from the network.
+///
+///
+///
+///
+///
+/// Peer ID
+///
+/// Stream ID
+///
+bool TagDMRData::processGrantReq(uint32_t srcId, uint32_t dstId, uint8_t slot, bool unitToUnit, uint32_t peerId, uint16_t pktSeq, uint32_t streamId)
+{
+ // bryanb: TODO TODO TODO
+ return false;
+}
+
///
/// Helper to playback a parrot frame to the network.
///
diff --git a/src/fne/network/fne/TagDMRData.h b/src/fne/network/fne/TagDMRData.h
index 94a17d85..8502c2b8 100644
--- a/src/fne/network/fne/TagDMRData.h
+++ b/src/fne/network/fne/TagDMRData.h
@@ -39,6 +39,8 @@ namespace network
/// Process a data frame from the network.
bool processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId, bool external = false);
+ /// Process a grant request frame from the network.
+ bool processGrantReq(uint32_t srcId, uint32_t dstId, uint8_t slot, bool unitToUnit, uint32_t peerId, uint16_t pktSeq, uint32_t streamId);
/// Helper to playback a parrot frame to the network.
void playbackParrot();
diff --git a/src/fne/network/fne/TagNXDNData.cpp b/src/fne/network/fne/TagNXDNData.cpp
index fde01e24..4fcf8fd4 100644
--- a/src/fne/network/fne/TagNXDNData.cpp
+++ b/src/fne/network/fne/TagNXDNData.cpp
@@ -259,6 +259,22 @@ bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerI
return false;
}
+///
+/// Process a grant request frame from the network.
+///
+///
+///
+///
+/// Peer ID
+///
+/// Stream ID
+///
+bool TagNXDNData::processGrantReq(uint32_t srcId, uint32_t dstId, bool unitToUnit, uint32_t peerId, uint16_t pktSeq, uint32_t streamId)
+{
+ // bryanb: TODO TODO TODO
+ return false;
+}
+
///
/// Helper to playback a parrot frame to the network.
///
diff --git a/src/fne/network/fne/TagNXDNData.h b/src/fne/network/fne/TagNXDNData.h
index e678c945..0bd15fd7 100644
--- a/src/fne/network/fne/TagNXDNData.h
+++ b/src/fne/network/fne/TagNXDNData.h
@@ -39,6 +39,8 @@ namespace network
/// Process a data frame from the network.
bool processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId, bool external = false);
+ /// Process a grant request frame from the network.
+ bool processGrantReq(uint32_t srcId, uint32_t dstId, bool unitToUnit, uint32_t peerId, uint16_t pktSeq, uint32_t streamId);
/// Helper to playback a parrot frame to the network.
void playbackParrot();
diff --git a/src/fne/network/fne/TagP25Data.cpp b/src/fne/network/fne/TagP25Data.cpp
index 41213224..dc8c6cc1 100644
--- a/src/fne/network/fne/TagP25Data.cpp
+++ b/src/fne/network/fne/TagP25Data.cpp
@@ -326,6 +326,22 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId
return false;
}
+///
+/// Process a grant request frame from the network.
+///
+///
+///
+///
+/// Peer ID
+///
+/// Stream ID
+///
+bool TagP25Data::processGrantReq(uint32_t srcId, uint32_t dstId, bool unitToUnit, uint32_t peerId, uint16_t pktSeq, uint32_t streamId)
+{
+ // bryanb: TODO TODO TODO
+ return false;
+}
+
///
/// Helper to playback a parrot frame to the network.
///
diff --git a/src/fne/network/fne/TagP25Data.h b/src/fne/network/fne/TagP25Data.h
index c951bf82..c76adc78 100644
--- a/src/fne/network/fne/TagP25Data.h
+++ b/src/fne/network/fne/TagP25Data.h
@@ -45,6 +45,8 @@ namespace network
/// Process a data frame from the network.
bool processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId, bool external = false);
+ /// Process a grant request frame from the network.
+ bool processGrantReq(uint32_t srcId, uint32_t dstId, bool unitToUnit, uint32_t peerId, uint16_t pktSeq, uint32_t streamId);
/// Helper to playback a parrot frame to the network.
void playbackParrot();
diff --git a/src/host/network/Network.cpp b/src/host/network/Network.cpp
index 27bc1ed5..a8b2b135 100644
--- a/src/host/network/Network.cpp
+++ b/src/host/network/Network.cpp
@@ -486,6 +486,12 @@ void Network::clock(uint32_t ms)
if (length > 10) {
reason = __GET_UINT16B(buffer, 10U);
switch (reason) {
+ case NET_CONN_NAK_MODE_NOT_ENABLED:
+ LogWarning(LOG_NET, "PEER %u master NAK; digital mode not enabled on FNE, remotePeerId = %u", m_peerId, rtpHeader.getSSRC());
+ break;
+ case NET_CONN_NAK_ILLEGAL_PACKET:
+ LogWarning(LOG_NET, "PEER %u master NAK; illegal/unknown packet, remotePeerId = %u", m_peerId, rtpHeader.getSSRC());
+ break;
case NET_CONN_NAK_FNE_UNAUTHORIZED:
LogWarning(LOG_NET, "PEER %u master NAK; unauthorized, remotePeerId = %u", m_peerId, rtpHeader.getSSRC());
break;