diff --git a/p25/P25Defines.h b/p25/P25Defines.h index 08d97b9b..7940848c 100644 --- a/p25/P25Defines.h +++ b/p25/P25Defines.h @@ -285,9 +285,10 @@ namespace p25 // TSBK Inbound Signalling Packet (ISP) Opcode(s) const uint8_t TSBK_ISP_TELE_INT_PSTN_REQ = 0x09U; // TELE INT PSTN REQ - Telephone Interconnect Request - Implicit - const uint8_t TSBK_ISP_SNDCP_CH_REQ = 0x13U; // SNDCP CH REQ - SNDCP Data Channel Request + const uint8_t TSBK_ISP_SNDCP_CH_REQ = 0x12U; // SNDCP CH REQ - SNDCP Data Channel Request const uint8_t TSBK_ISP_STS_Q_RSP = 0x19U; // STS Q RSP - Status Query Response const uint8_t TSBK_ISP_CAN_SRV_REQ = 0x23U; // CAN SRV REQ - Cancel Service Request + const uint8_t TSBK_ISP_EMERG_ALRM_REQ = 0x27U; // EMERG ALRM REQ - Emergency Alarm Request const uint8_t TSBK_ISP_GRP_AFF_Q_RSP = 0x29U; // GRP AFF Q RSP - Group Affiliation Query Response const uint8_t TSBK_ISP_U_DEREG_REQ = 0x2BU; // U DE REG REQ - Unit De-Registration Request const uint8_t TSBK_ISP_LOC_REG_REQ = 0x2DU; // LOC REG REQ - Location Registration Request diff --git a/p25/TrunkPacket.cpp b/p25/TrunkPacket.cpp index ed0fcaa5..6c2eb862 100644 --- a/p25/TrunkPacket.cpp +++ b/p25/TrunkPacket.cpp @@ -294,6 +294,22 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len) writeRF_TSDU_Queue(P25_QUE_RSN_TGT_UNIT_QUEUED, TSBK_IOSP_TELE_INT_ANS); } break; + case TSBK_ISP_SNDCP_CH_REQ: + // make sure control data is supported + IS_SUPPORT_CONTROL_CHECK("TSBK_ISP_SNDCP_CH_REQ (SNDCP Channel Request)", TSBK_ISP_SNDCP_CH_REQ, srcId); + + // validate the source RID + VALID_SRCID("TSBK_ISP_SNDCP_CH_REQ (SNDCP Channel Request)", TSBK_ISP_SNDCP_CH_REQ, srcId); + + if (m_verbose) { + LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_ISP_SNDCP_CH_REQ (SNDCP Channel Request), dataServiceOptions = $%02X, dataAccessControl = %u, srcId = %u", + m_rfTSBK.getDataServiceOptions(), m_rfTSBK.getDataAccessControl(), srcId); + } + + // SNDCP data channel requests are currently unsupported -- maybe in the future? + + writeRF_TSDU_Deny(P25_DENY_RSN_SYS_UNSUPPORTED_SVC, TSBK_ISP_SNDCP_CH_REQ); + break; case TSBK_IOSP_STS_UPDT: // validate the source RID VALID_SRCID("TSBK_IOSP_STS_UPDT (Status Update)", TSBK_IOSP_STS_UPDT, srcId); @@ -395,6 +411,18 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len) writeRF_TSDU_SBF(true); break; + case TSBK_ISP_EMERG_ALRM_REQ: + if (m_rfTSBK.getEmergency()) { + if (m_verbose) { + LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_ISP_EMERG_ALRM_REQ (Emergency Alarm Request), srcId = %u, dstId = %u", + srcId, dstId); + } + + ::ActivityLog("P25", true, "emergency alarm request request from %u", srcId); + + writeRF_TSDU_SBF(); + } + break; case TSBK_IOSP_GRP_AFF: // make sure control data is supported IS_SUPPORT_CONTROL_CHECK("TSBK_IOSP_GRP_AFF (Group Affiliation Request)", TSBK_IOSP_GRP_AFF, srcId); @@ -680,6 +708,20 @@ bool TrunkPacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d m_netTSBK.getService(), srcId, dstId); } break; + case TSBK_ISP_EMERG_ALRM_REQ: + // non-emergency mode is a TSBK_OSP_DENY_RSP + if (!m_netTSBK.getEmergency()) { + if (m_verbose) { + LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_OSP_DENY_RSP (Deny Response), AIV = %u, reason = $%02X, srcId = %u, dstId = %u", + m_netTSBK.getAIV(), m_netTSBK.getResponse(), m_netTSBK.getSrcId(), m_netTSBK.getDstId()); + } + } else { + if (m_verbose) { + LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_ISP_EMERG_ALRM_REQ (Emergency Alarm Request), srcId = %u, dstId = %u", + srcId, dstId); + } + } + break; case TSBK_IOSP_GRP_AFF: // ignore a network group affiliation command return true; // don't allow this to write to the air @@ -689,12 +731,6 @@ bool TrunkPacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d case TSBK_OSP_LOC_REG_RSP: // ignore a network location registration command return true; // don't allow this to write to the air - case TSBK_OSP_DENY_RSP: - if (m_verbose) { - LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_OSP_DENY_RSP (Deny Response), AIV = %u, reason = $%02X, srcId = %u, dstId = %u", - m_netTSBK.getAIV(), m_netTSBK.getResponse(), m_netTSBK.getSrcId(), m_netTSBK.getDstId()); - } - break; case TSBK_OSP_QUE_RSP: if (m_verbose) { LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_OSP_QUE_RSP (Queue Response), AIV = %u, reason = $%02X, srcId = %u, dstId = %u", diff --git a/p25/lc/TSBK.cpp b/p25/lc/TSBK.cpp index 619e9863..93d7f73f 100644 --- a/p25/lc/TSBK.cpp +++ b/p25/lc/TSBK.cpp @@ -334,6 +334,11 @@ bool TSBK::decode(const uint8_t* data) m_response = (uint8_t)((tsbkValue >> 48) & 0xFFU); // Answer Response m_srcId = (uint32_t)(tsbkValue & 0xFFFFFFU); // Source Radio Address break; + case TSBK_ISP_SNDCP_CH_REQ: + m_dataServiceOptions = (uint8_t)((tsbkValue >> 56) & 0xFFU); // Data Service Options + m_dataAccessControl = (uint32_t)((tsbkValue >> 40) & 0xFFFFFFFFU); // Data Access Control + m_srcId = (uint32_t)(tsbkValue & 0xFFFFFFU); // Source Radio Address + break; case TSBK_IOSP_STS_UPDT: m_statusValue = (uint8_t)((tsbkValue >> 56) & 0xFFU); // Status Value m_dstId = (uint32_t)((tsbkValue >> 24) & 0xFFFFFFU); // Target Radio Address @@ -354,6 +359,23 @@ bool TSBK::decode(const uint8_t* data) m_dstId = (uint32_t)((tsbkValue >> 24) & 0xFFFFFFU); // Target Radio Address m_srcId = (uint32_t)(tsbkValue & 0xFFFFFFU); // Source Radio Address break; + case TSBK_ISP_EMERG_ALRM_REQ: // TSBK_OSP_DENY_RSP + /* + ** these are used by TSBK_OSP_DENY_RSP; best way to check is for m_response > 0 + */ + m_aivFlag = (((tsbkValue >> 56) & 0xFFU) & 0x80U) == 0x80U; // Additional Info. Flag + m_service = (uint8_t)((tsbkValue >> 56) & 0x3FU); // Service Type + m_response = (uint8_t)((tsbkValue >> 48) & 0xFFU); // Reason + + if (m_response > 0U) { + m_emergency = true; + } else { + m_emergency = false; + } + + m_dstId = (uint32_t)((tsbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_srcId = (uint32_t)(tsbkValue & 0xFFFFFFU); // Source Radio Address + break; case TSBK_IOSP_EXT_FNCT: m_extendedFunction = (uint32_t)((tsbkValue >> 48) & 0xFFFFU); // Extended Function m_dstId = (uint32_t)((tsbkValue >> 24) & 0xFFFFFFU); // Argument @@ -381,7 +403,6 @@ bool TSBK::decode(const uint8_t* data) m_dstId = (uint32_t)((tsbkValue >> 24) & 0xFFFFU); // Talkgroup Address m_srcId = (uint32_t)(tsbkValue & 0xFFFFFFU); // Source Radio Address break; - case TSBK_OSP_DENY_RSP: case TSBK_OSP_QUE_RSP: m_aivFlag = (((tsbkValue >> 56) & 0xFFU) & 0x80U) == 0x80U; // Additional Info. Flag m_service = (uint8_t)((tsbkValue >> 56) & 0x3FU); // Service Type diff --git a/p25/lc/TSBK.h b/p25/lc/TSBK.h index 2ea47769..420f8a8f 100644 --- a/p25/lc/TSBK.h +++ b/p25/lc/TSBK.h @@ -132,6 +132,12 @@ namespace p25 /// Extended function opcode. __PROPERTY(uint32_t, extendedFunction, ExtendedFunction); + /** SNDCP Channel Request */ + /// SNDCP Data Service Options + __PROPERTY(uint8_t, dataServiceOptions, DataServiceOptions); + /// SNDCP Data Access Control + __PROPERTY(uint32_t, dataAccessControl, DataAccessControl); + /** Adjacent Site Data */ /// Adjacent site CFVA flags. __PROPERTY(uint8_t, adjCFVA, AdjSiteCFVA);