From 18f5392707dce34207ca272152a9021c45b13f99 Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Tue, 21 Mar 2023 11:44:49 -0400 Subject: [PATCH] complete remaining REST API implementations; --- network/RESTAPI.cpp | 123 +++++++++++++++++++++++++++++++++++++- network/RESTDefines.h | 1 + remote/RESTClientMain.cpp | 8 +++ 3 files changed, 131 insertions(+), 1 deletion(-) diff --git a/network/RESTAPI.cpp b/network/RESTAPI.cpp index 9158e107..b626f07f 100644 --- a/network/RESTAPI.cpp +++ b/network/RESTAPI.cpp @@ -644,7 +644,7 @@ void RESTAPI::restAPI_PutModemMode(const HTTPPayload& request, HTTPPayload& repl return; } - std::string mode = req["mode"].get(); + std::string mode = ::strtolower(req["mode"].get()); if (mode == MODE_OPT_IDLE) { m_host->m_fixedMode = false; @@ -1246,8 +1246,64 @@ void RESTAPI::restAPI_PutDMRRID(const HTTPPayload& request, HTTPPayload& reply, if (!parseRequestBody(request, reply, req)) { return; } +#if defined(ENABLE_DMR) + if (m_dmr == nullptr) { + errorPayload(reply, "DMR mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE); + return; + } + + // validate state is a string within the JSON blob + if (!req["command"].is()) { + errorPayload(reply, "command was not valid"); + return; + } + + // validate destination ID is a integer within the JSON blob + if (!req["dstId"].is()) { + errorPayload(reply, "destination ID was not valid"); + return; + } + + // validate destination ID is a integer within the JSON blob + if (!req["slot"].is()) { + errorPayload(reply, "slot was not valid"); + return; + } + + uint32_t dstId = req["dstId"].get(); + uint8_t slot = req["slot"].get(); + + if (dstId == 0U) { + errorPayload(reply, "destination ID was not valid"); + return; + } + + if (slot == 0U && slot >= 3U) { + errorPayload(reply, "invalid DMR slot number (slot == 0 or slot > 3)"); + return; + } errorPayload(reply, "OK", HTTPPayload::OK); + std::string command = req["command"].get(); + if (::strtolower(command) == RID_CMD_PAGE) { + m_dmr->writeRF_Call_Alrt(slot, p25::P25_WUID_FNE, dstId); + } + else if (::strtolower(command) == RID_CMD_CHECK) { + m_dmr->writeRF_Ext_Func(slot, dmr::DMR_EXT_FNCT_CHECK, p25::P25_WUID_FNE, dstId); + } + else if (::strtolower(command) == RID_CMD_INHIBIT) { + m_dmr->writeRF_Ext_Func(slot, dmr::DMR_EXT_FNCT_INHIBIT, p25::P25_WUID_FNE, dstId); + } + else if (::strtolower(command) == RID_CMD_UNINHIBIT) { + m_dmr->writeRF_Ext_Func(slot, dmr::DMR_EXT_FNCT_UNINHIBIT, p25::P25_WUID_FNE, dstId); + } + else { + errorPayload(reply, "invalid command"); + return; + } +#else + errorPayload(reply, "DMR operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE); +#endif // defined(ENABLE_DMR) } /// @@ -1453,8 +1509,73 @@ void RESTAPI::restAPI_PutP25RID(const HTTPPayload& request, HTTPPayload& reply, if (!parseRequestBody(request, reply, req)) { return; } +#if defined(ENABLE_P25) + if (m_p25 == nullptr) { + errorPayload(reply, "P25 mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE); + return; + } + + // validate state is a string within the JSON blob + if (!req["command"].is()) { + errorPayload(reply, "command was not valid"); + return; + } + + std::string command = req["command"].get(); + uint32_t dstId = 0; + + if (::strtolower(command) != RID_CMD_P25_SET_MFID) { + // validate destination ID is a integer within the JSON blob + if (!req["dstId"].is()) { + errorPayload(reply, "destination ID was not valid"); + return; + } + + dstId = req["dstId"].get(); + + if (dstId == 0U) { + errorPayload(reply, "destination ID was not valid"); + return; + } + } + errorPayload(reply, "OK", HTTPPayload::OK); + if (::strtolower(command) == RID_CMD_P25_SET_MFID) { + // validate destination ID is a integer within the JSON blob + if (!req["mfId"].is()) { + errorPayload(reply, "MFID was not valid"); + return; + } + + uint8_t mfId = req["mfId"].get(); + m_p25->trunk()->setLastMFId(mfId); + } + else if (::strtolower(command) == RID_CMD_PAGE) { + m_p25->trunk()->writeRF_TSDU_Call_Alrt(p25::P25_WUID_FNE, dstId); + } + else if (::strtolower(command) == RID_CMD_CHECK) { + m_p25->trunk()->writeRF_TSDU_Ext_Func(p25::P25_EXT_FNCT_CHECK, p25::P25_WUID_FNE, dstId); + } + else if (::strtolower(command) == RID_CMD_INHIBIT) { + m_p25->trunk()->writeRF_TSDU_Ext_Func(p25::P25_EXT_FNCT_INHIBIT, p25::P25_WUID_FNE, dstId); + } + else if (::strtolower(command) == RID_CMD_UNINHIBIT) { + m_p25->trunk()->writeRF_TSDU_Ext_Func(p25::P25_EXT_FNCT_UNINHIBIT, p25::P25_WUID_FNE, dstId); + } + else if (::strtolower(command) == RID_CMD_GAQ) { + m_p25->trunk()->writeRF_TSDU_Grp_Aff_Q(dstId); + } + else if (::strtolower(command) == RID_CMD_UREG) { + m_p25->trunk()->writeRF_TSDU_U_Reg_Cmd(dstId); + } + else { + errorPayload(reply, "invalid command"); + return; + } +#else + errorPayload(reply, "P25 operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE); +#endif // defined(ENABLE_P25) } /// diff --git a/network/RESTDefines.h b/network/RESTDefines.h index a0266d62..b85c5434 100644 --- a/network/RESTDefines.h +++ b/network/RESTDefines.h @@ -47,6 +47,7 @@ #define MODE_OPT_FP25 "p25" #define MODE_OPT_FNXDN "nxdn" +#define RID_CMD_P25_SET_MFID "p25-setmfid" #define RID_CMD_PAGE "page" #define RID_CMD_CHECK "check" #define RID_CMD_INHIBIT "inhibit" diff --git a/remote/RESTClientMain.cpp b/remote/RESTClientMain.cpp index 705b755f..1dade8af 100644 --- a/remote/RESTClientMain.cpp +++ b/remote/RESTClientMain.cpp @@ -588,6 +588,14 @@ int main(int argc, char** argv) retCode = client->send(HTTP_GET, GET_P25_DUMP_TSBK_BASE + std::to_string(verbose), json::object()); } } + else if (rcom == RCD_P25_SET_MFID && argCnt >= 2U) { + json::object req = json::object(); + req["command"].set(std::string(RID_CMD_P25_SET_MFID)); + uint8_t mfId = getArgUInt8(args, 0U); + req["mfId"].set(mfId); + + retCode = client->send(HTTP_PUT, PUT_P25_RID, req); + } else if (rcom == RCD_P25_RID_PAGE && argCnt >= 2U) { json::object req = json::object(); req["command"].set(std::string(RID_CMD_PAGE));