diff --git a/src/dmr/Control.cpp b/src/dmr/Control.cpp
index 1ac1d5a2..57e39023 100644
--- a/src/dmr/Control.cpp
+++ b/src/dmr/Control.cpp
@@ -413,6 +413,26 @@ void Control::permittedTG(uint32_t dstId, uint8_t slot)
}
}
+///
+/// Grants a TGID on a non-authoritative host.
+///
+///
+///
+void Control::grantTG(uint32_t srcId, uint32_t dstId, uint8_t slot, bool grp)
+{
+ switch (slot) {
+ case 1U:
+ m_slot1->grantTG(srcId, dstId, grp);
+ break;
+ case 2U:
+ m_slot2->grantTG(srcId, dstId, grp);
+ break;
+ default:
+ LogError(LOG_DMR, "DMR, invalid slot, slotNo = %u", slot);
+ break;
+ }
+}
+
///
/// Releases a granted TG.
///
diff --git a/src/dmr/Control.h b/src/dmr/Control.h
index 063d5ff3..f9e6a417 100644
--- a/src/dmr/Control.h
+++ b/src/dmr/Control.h
@@ -95,7 +95,8 @@ namespace dmr
void setSupervisor(bool supervisor);
/// Permits a TGID on a non-authoritative host.
void permittedTG(uint32_t dstId, uint8_t slot);
-
+ /// Grants a TGID on a non-authoritative host.
+ void grantTG(uint32_t srcId, uint32_t dstId, uint8_t slot, bool grp);
/// Releases a granted TG.
void releaseGrantTG(uint32_t dstId, uint8_t slot);
/// Touchs a granted TG to keep a channel grant alive.
diff --git a/src/dmr/Slot.cpp b/src/dmr/Slot.cpp
index fc03ba65..55c3c1f9 100644
--- a/src/dmr/Slot.cpp
+++ b/src/dmr/Slot.cpp
@@ -627,6 +627,25 @@ void Slot::permittedTG(uint32_t dstId)
m_permittedDstId = dstId;
}
+///
+/// Grants a TGID on a non-authoritative host.
+///
+///
+///
+///
+void Slot::grantTG(uint32_t srcId, uint32_t dstId, bool grp)
+{
+ if (!m_control) {
+ return;
+ }
+
+ if (m_verbose) {
+ LogMessage(LOG_DMR, "DMR Slot %u, network TG grant demand, srcId = %u, dstId = %u", m_slotNo, srcId, dstId);
+ }
+
+ m_control->writeRF_CSBK_Grant(srcId, dstId, 4U, grp);
+}
+
///
/// Releases a granted TG.
///
diff --git a/src/dmr/Slot.h b/src/dmr/Slot.h
index 4d980f1e..1cf2e825 100644
--- a/src/dmr/Slot.h
+++ b/src/dmr/Slot.h
@@ -96,7 +96,8 @@ namespace dmr
/// Permits a TGID on a non-authoritative host.
void permittedTG(uint32_t dstId);
-
+ /// Grants a TGID on a non-authoritative host.
+ void grantTG(uint32_t srcId, uint32_t dstId, bool grp);
/// Releases a granted TG.
void releaseGrantTG(uint32_t dstId);
/// Touchs a granted TG to keep a channel grant alive.
diff --git a/src/network/RESTAPI.cpp b/src/network/RESTAPI.cpp
index 268f046f..a4117773 100644
--- a/src/network/RESTAPI.cpp
+++ b/src/network/RESTAPI.cpp
@@ -1045,13 +1045,24 @@ void RESTAPI::restAPI_PutGrantTG(const HTTPPayload& request, HTTPPayload& reply,
return;
}
- // validate unit-to-unit is a integer within the JSON blob
- if (!req["unitToUnit"].is()) {
- errorPayload(reply, "unit-to-unit was not a valid boolean");
+ // validate source ID is a integer within the JSON blob
+ if (!req["srcId"].is()) {
+ errorPayload(reply, "source ID was not a valid integer");
return;
}
- //bool unitToUnit = req["unitToUnit"].get();
+ uint32_t srcId = req["srcId"].get();
+
+ if (srcId == 0U) {
+ errorPayload(reply, "soruce ID is an illegal TGID");
+ return;
+ }
+
+ // validate unit-to-unit is a integer within the JSON blob
+ bool unitToUnit = false;
+ if (req["unitToUnit"].is()) {
+ unitToUnit = req["unitToUnit"].get();
+ }
switch (state) {
case STATE_DMR:
@@ -1071,8 +1082,7 @@ void RESTAPI::restAPI_PutGrantTG(const HTTPPayload& request, HTTPPayload& reply,
}
if (m_dmr != nullptr) {
- // TODO TODO
- //m_dmr->grantTG(dstId, slot, unitToUnit);
+ m_dmr->grantTG(srcId, dstId, slot, !unitToUnit);
}
else {
errorPayload(reply, "DMR mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
@@ -1088,8 +1098,7 @@ void RESTAPI::restAPI_PutGrantTG(const HTTPPayload& request, HTTPPayload& reply,
#if defined(ENABLE_P25)
{
if (m_p25 != nullptr) {
- // TODO TODO
- //m_p25->grantTG(dstId, unitToUnit);
+ m_p25->grantTG(srcId, dstId, !unitToUnit);
}
else {
errorPayload(reply, "P25 mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
@@ -1105,8 +1114,7 @@ void RESTAPI::restAPI_PutGrantTG(const HTTPPayload& request, HTTPPayload& reply,
#if defined(ENABLE_NXDN)
{
if (m_nxdn != nullptr) {
- // TODO TODO
- //m_nxdn->grantTG(dstId, unitToUnit);
+ m_nxdn->grantTG(srcId, dstId, !unitToUnit);
}
else {
errorPayload(reply, "NXDN mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
diff --git a/src/nxdn/Control.cpp b/src/nxdn/Control.cpp
index d08a3ee6..a83756fa 100644
--- a/src/nxdn/Control.cpp
+++ b/src/nxdn/Control.cpp
@@ -691,12 +691,31 @@ void Control::permittedTG(uint32_t dstId)
}
if (m_verbose) {
- LogMessage(LOG_P25, "non-authoritative TG permit, dstId = %u", dstId);
+ LogMessage(LOG_NXDN, "non-authoritative TG permit, dstId = %u", dstId);
}
m_permittedDstId = dstId;
}
+///
+/// Grants a TGID on a non-authoritative host.
+///
+///
+///
+///
+void Control::grantTG(uint32_t srcId, uint32_t dstId, bool grp)
+{
+ if (!m_control) {
+ return;
+ }
+
+ if (m_verbose) {
+ LogMessage(LOG_NXDN, "network TG grant demand, srcId = %u, dstId = %u", srcId, dstId);
+ }
+
+ m_trunk->writeRF_Message_Grant(srcId, dstId, 4U, grp);
+}
+
///
/// Releases a granted TG.
///
diff --git a/src/nxdn/Control.h b/src/nxdn/Control.h
index 33f4196d..5277da3b 100644
--- a/src/nxdn/Control.h
+++ b/src/nxdn/Control.h
@@ -107,7 +107,8 @@ namespace nxdn
void setSupervisor(bool supervisor) { m_supervisor = supervisor; }
/// Permits a TGID on a non-authoritative host.
void permittedTG(uint32_t dstId);
-
+ /// Grants a TGID on a non-authoritative host.
+ void grantTG(uint32_t srcId, uint32_t dstId, bool grp);
/// Releases a granted TG.
void releaseGrantTG(uint32_t dstId);
/// Touchs a granted TG to keep a channel grant alive.
diff --git a/src/p25/Control.cpp b/src/p25/Control.cpp
index 5467b7c9..8aa96369 100644
--- a/src/p25/Control.cpp
+++ b/src/p25/Control.cpp
@@ -862,6 +862,25 @@ void Control::permittedTG(uint32_t dstId)
m_permittedDstId = dstId;
}
+///
+/// Grants a TGID on a non-authoritative host.
+///
+///
+///
+///
+void Control::grantTG(uint32_t srcId, uint32_t dstId, bool grp)
+{
+ if (!m_control) {
+ return;
+ }
+
+ if (m_verbose) {
+ LogMessage(LOG_P25, "network TG grant demand, srcId = %u, dstId = %u", srcId, dstId);
+ }
+
+ m_trunk->writeRF_TSDU_Grant(srcId, dstId, 4U, grp);
+}
+
///
/// Releases a granted TG.
///
diff --git a/src/p25/Control.h b/src/p25/Control.h
index 4c73ef68..7ce4a724 100644
--- a/src/p25/Control.h
+++ b/src/p25/Control.h
@@ -115,7 +115,8 @@ namespace p25
void setSupervisor(bool supervisor) { m_supervisor = supervisor; }
/// Permits a TGID on a non-authoritative host.
void permittedTG(uint32_t dstId);
-
+ /// Grants a TGID on a non-authoritative host.
+ void grantTG(uint32_t srcId, uint32_t dstId, bool grp);
/// Releases a granted TG.
void releaseGrantTG(uint32_t dstId);
/// Touchs a granted TG to keep a channel grant alive.