From 25d97e0ac541e699b5477c3f127892f1de4e0544 Mon Sep 17 00:00:00 2001 From: Darjeeling Date: Tue, 30 Aug 2022 16:39:23 -0500 Subject: [PATCH 1/4] Add STS_Q_REQ in prep for logic add Add bit masking --- p25/Control.cpp | 22 ++++++------ p25/P25Defines.h | 16 +++++---- p25/lc/TSBK.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++-- p25/packet/Trunk.cpp | 54 ++++++++++++++++++------------ 4 files changed, 130 insertions(+), 41 deletions(-) diff --git a/p25/Control.cpp b/p25/Control.cpp index 6057b800..f5815e8f 100644 --- a/p25/Control.cpp +++ b/p25/Control.cpp @@ -236,7 +236,7 @@ void Control::setOptions(yaml::Node& conf, const std::string cwCallsign, const s m_trunk->m_noStatusAck = p25Protocol["noStatusAck"].as(false); m_trunk->m_noMessageAck = p25Protocol["noMessageAck"].as(true); m_trunk->m_unitToUnitAvailCheck = p25Protocol["unitToUnitAvailCheck"].as(true); - + m_trunk->m_localEmergAlarm = p25Protocol["localEmergAlarm"].as(false); m_trunk->m_sndcpChGrant = p25Protocol["sndcpGrant"].as(false); @@ -370,15 +370,15 @@ bool Control::processFrame(uint8_t* data, uint32_t len) if (data[0U] == modem::TAG_LOST && m_rfState == RS_RF_AUDIO) { if (m_rssi != 0U) { - ::ActivityLog("P25", true, "transmission lost, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", + ::ActivityLog("P25", true, "transmission lost, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_voice->m_rfFrames) / 5.56F, float(m_voice->m_rfErrs * 100U) / float(m_voice->m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); } else { - ::ActivityLog("P25", true, "transmission lost, %.1f seconds, BER: %.1f%%", + ::ActivityLog("P25", true, "transmission lost, %.1f seconds, BER: %.1f%%", float(m_voice->m_rfFrames) / 5.56F, float(m_voice->m_rfErrs * 100U) / float(m_voice->m_rfBits)); } - LogMessage(LOG_RF, P25_TDU_STR ", total frames: %d, bits: %d, undecodable LC: %d, errors: %d, BER: %.4f%%", + LogMessage(LOG_RF, P25_TDU_STR ", total frames: %d, bits: %d, undecodable LC: %d, errors: %d, BER: %.4f%%", m_voice->m_rfFrames, m_voice->m_rfBits, m_voice->m_rfUndecodableLC, m_voice->m_rfErrs, float(m_voice->m_rfErrs * 100U) / float(m_voice->m_rfBits)); if (m_control) { @@ -580,11 +580,11 @@ bool Control::writeRF_VoiceEnd() bool ret = false; if (m_netState == RS_NET_IDLE && m_rfState == RS_RF_LISTENING) { m_voice->writeRF_EndOfVoice(); - + // this should have been cleared by writeRF_EndOfVoice; but if it hasn't clear it // to prevent badness if (m_voice->m_hadVoice) { - m_voice->m_hadVoice = false; + m_voice->m_hadVoice = false; } m_tailOnIdle = false; @@ -1045,19 +1045,19 @@ bool Control::writeRF_ControlData() return false; } - const uint8_t maxSeq = 8U; + const uint8_t maxSeq = 9U; if (m_ccSeq == maxSeq) { m_ccSeq = 0U; } if (m_netState == RS_NET_IDLE && m_rfState == RS_RF_LISTENING) { m_trunk->writeRF_ControlData(m_ccFrameCnt, m_ccSeq, true); - + m_ccSeq++; if (m_ccSeq == maxSeq) { m_ccFrameCnt++; } - + return true; } @@ -1094,7 +1094,7 @@ bool Control::writeRF_ControlEnd() void Control::writeRF_Nulls() { const uint8_t NULLS_LENGTH_BYTES = 25U; - + // write null bits (0x00) uint8_t data[NULLS_LENGTH_BYTES + 2U]; ::memset(data + 2U, 0x00U, NULLS_LENGTH_BYTES); @@ -1203,7 +1203,7 @@ void Control::addBusyBits(uint8_t* data, uint32_t length, bool b1, bool b2) { assert(data != NULL); - // insert the "10" (Unknown, use for inbound or outbound) status bits + // insert the "10" (Unknown, use for inbound or outbound) status bits for (uint32_t ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += P25_SS_INCREMENT) { uint32_t ss1Pos = ss0Pos + 1U; WRITE_BIT(data, ss0Pos, true); // 1 diff --git a/p25/P25Defines.h b/p25/P25Defines.h index f5e637dc..9cf7217e 100644 --- a/p25/P25Defines.h +++ b/p25/P25Defines.h @@ -213,7 +213,7 @@ namespace p25 const uint8_t PDU_FMT_CONFIRMED = 0x16U; const uint8_t PDU_FMT_AMBT = 0x17U; - // PDU SAP + // PDU SAP const uint8_t PDU_SAP_USER_DATA = 0x00U; const uint8_t PDU_SAP_ENC_USER_DATA = 0x01U; @@ -269,9 +269,9 @@ namespace p25 const uint8_t LC_GROUP = 0x00U; // GRP VCH USER - Group Voice Channel User const uint8_t LC_GROUP_UPDT = 0x02U; // GRP VCH UPDT - Group Voice Channel Update const uint8_t LC_PRIVATE = 0x03U; // UU VCH USER - Unit-to-Unit Voice Channel User - const uint8_t LC_UU_ANS_REQ = 0x05U; // UU ANS REQ - Unit to Unit Answer Request - const uint8_t LC_TEL_INT_VCH_USER = 0x06U; // TEL INT VCH USER - Telephone Interconnect Voice Channel User - const uint8_t LC_TEL_INT_ANS_RQST = 0x07U; // TEL INT ANS RQST - Telephone Interconnect Answer Request + const uint8_t LC_UU_ANS_REQ = 0x05U; // UU ANS REQ - Unit to Unit Answer Request + const uint8_t LC_TEL_INT_VCH_USER = 0x06U; // TEL INT VCH USER - Telephone Interconnect Voice Channel User + const uint8_t LC_TEL_INT_ANS_RQST = 0x07U; // TEL INT ANS RQST - Telephone Interconnect Answer Request const uint8_t LC_CALL_TERM = 0x0FU; // CALL TERM - Call Termination or Cancellation const uint8_t LC_IDEN_UP = 0x18U; // IDEN UP - Channel Identifier Update const uint8_t LC_SYS_SRV_BCAST = 0x20U; // SYS SRV BCAST - System Service Broadcast @@ -304,6 +304,7 @@ namespace p25 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 + const uint8_t TSBK_ISP_STS_Q_REQ = 0x1CU; // STS_Q_REQ - Status Query Request // TSBK Outbound Signalling Packet (OSP) Opcode(s) const uint8_t TSBK_OSP_GRP_VCH_GRANT_UPD = 0x02U; // GRP VCH GRANT UPD - Group Voice Channel Grant Update @@ -311,7 +312,7 @@ namespace p25 const uint8_t TSBK_OSP_SNDCP_CH_GNT = 0x14U; // SNDCP CH GNT - SNDCP Data Channel Grant const uint8_t TSBK_OSP_SNDCP_CH_ANN = 0x16U; // SNDCP CH ANN - SNDCP Data Channel Announcement const uint8_t TSBK_OSP_DENY_RSP = 0x27U; // DENY RSP - Deny Response - const uint8_t TSBK_OSP_SCCB_EXP = 0x29U; // SCCB - Secondary Control Channel Broadcast - Explicit + const uint8_t TSBK_OSP_SCCB_EXP = 0x29U; // SCCB - Secondary Control Channel Broadcast - Explicit const uint8_t TSBK_OSP_GRP_AFF_Q = 0x2AU; // GRP AFF Q - Group Affiliation Query const uint8_t TSBK_OSP_LOC_REG_RSP = 0x2BU; // LOC REG RSP - Location Registration Response const uint8_t TSBK_OSP_U_REG_CMD = 0x2DU; // U REG CMD - Unit Registration Command @@ -324,6 +325,9 @@ namespace p25 const uint8_t TSBK_OSP_NET_STS_BCAST = 0x3BU; // NET STS BCAST - Network Status Broadcast const uint8_t TSBK_OSP_ADJ_STS_BCAST = 0x3CU; // ADJ STS BCAST - Adjacent Site Status Broadcast const uint8_t TSBK_OSP_IDEN_UP = 0x3DU; // IDEN UP - Channel Identifier Update + const uint8_t TSBK_OSP_STS_Q = 0x1AU; // STS_Q - Status Query + const uint8_t TSBK_OSP_TIME_DATE_ANN = 0b110101; // TIME_DATE_ANN - Time and Date Announcement + // TSBK Motorola Outbound Signalling Packet (OSP) Opcode(s) const uint8_t TSBK_OSP_MOT_GRG_ADD = 0x00U; // MOT GRG ADD - Motorola / Group Regroup Add (Patch Supergroup) @@ -342,7 +346,7 @@ namespace p25 const uint8_t P25_DUID_LDU1 = 0x05U; // Logical Link Data Unit 1 const uint8_t P25_DUID_TSDU = 0x07U; // Trunking System Data Unit const uint8_t P25_DUID_LDU2 = 0x0AU; // Logical Link Data Unit 2 - const uint8_t P25_DUID_PDU = 0x0CU; // Packet Data Unit + const uint8_t P25_DUID_PDU = 0x0CU; // Packet Data Unit const uint8_t P25_DUID_TDULC = 0x0FU; // Terminator Data Unit with Link Control } // namespace p25 diff --git a/p25/lc/TSBK.cpp b/p25/lc/TSBK.cpp index a29617ab..066210e5 100644 --- a/p25/lc/TSBK.cpp +++ b/p25/lc/TSBK.cpp @@ -39,6 +39,8 @@ using namespace p25; #include #include #include +#include +#include // --------------------------------------------------------------------------- // Public Class Members @@ -279,7 +281,7 @@ bool TSBK::decode(const uint8_t* data, bool rawTSBK) uint8_t tsbk[P25_TSBK_LENGTH_BYTES + 1U]; if (rawTSBK) { ::memcpy(tsbk, data, P25_TSBK_LENGTH_BYTES); - + bool ret = edac::CRC::checkCCITT162(tsbk, P25_TSBK_LENGTH_BYTES); if (!ret) { if (m_warnCRC) { @@ -323,7 +325,7 @@ bool TSBK::decode(const uint8_t* data, bool rawTSBK) Utils::dump(2U, "P25, decoding excepted with input data", tsbk, P25_TSBK_LENGTH_BYTES); return false; } - } + } if (m_verbose) { Utils::dump(2U, "Decoded TSBK", tsbk, P25_TSBK_LENGTH_BYTES); @@ -666,7 +668,7 @@ void TSBK::encode(uint8_t* data, bool rawTSBK, bool noTrellis) uint32_t rootFreq = rxFrequency - m_siteIdenEntry.baseFrequency(); uint32_t rxChNo = rootFreq / (m_siteIdenEntry.chSpaceKhz() * 1000); - tsbkValue = 0U; // + tsbkValue = 0U; // tsbkValue = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag (m_encrypted ? 0x40U : 0x00U); // Encrypted Flag tsbkValue = (tsbkValue << 8) + @@ -890,6 +892,77 @@ void TSBK::encode(uint8_t* data, bool rawTSBK, bool noTrellis) } } break; + case TSBK_OSP_TIME_DATE_ANN: + { + //Setup + std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); + time_t tt = std::chrono::system_clock::to_time_t( now ); + tm local_tm = *localtime( &tt ); + unsigned long tmM = 0b000;//Month; +1 to account for tm_mon being 0-11 and p25 being 1-12 + unsigned long tmMDAY = 0b00000;//Day of month + unsigned int tmY = 0b0000000000000;//Year + unsigned int tmH = 0b00000;//Hour + unsigned int tmMin = 0b000000;//Min + unsigned int tmS = 0b000000;//Second + + //Assign Values + tmM |= (local_tm.tm_mon + 1);//Month; +1 to account for tm_mon being 0-11 and p25 being 1-12 + tmMDAY |= local_tm.tm_mday;//Day of month + tmY |= local_tm.tm_year;//Year + tmH |= local_tm.tm_hour;//Hour + tmMin |= local_tm.tm_min;//Min + unsigned int i = local_tm.tm_sec; + unsigned long VFLAGS = 0b11000000; // VL,VT,VD, Res(leave 0),LTO direction, LTO + unsigned long VLTO = 0b00000000; // LTO + + //Catch Leap Seconds + if ( i > 59U ) + { + tmS |= 59U; + } else + { + tmS |= i; + } + + //Fix Year from from 1900 to from 2000 + tmY = tmY - 100U; + + //Shift Shift + VFLAGS = VFLAGS << 56 ; + VLTO = VLTO << 48; //LTO + tmM = tmM << 44; //Month + tmMDAY = tmMDAY << 39; //Day of month + tmY = tmY << 26; //Year + tmH = tmH << 19; //Hour + tmMin = tmMin << 13; //Min + tmS = tmS << 7; //Second + + //Build tsbkValue + tsbkValue = 0U; //Zero out tsbkValue + + tsbkValue = tsbkValue + VFLAGS; + tsbkValue = tsbkValue + VLTO; //LTO + //Date + tsbkValue = tsbkValue + tmM; + tsbkValue = tsbkValue + tmMDAY; + tsbkValue = tsbkValue + tmY; + //Time + tsbkValue = tsbkValue + tmH; + tsbkValue = tsbkValue + tmMin; + tsbkValue = tsbkValue + tmS; + + //Debug Stuff, Comment out or put in a #if DEBUG statement before push + LogError( LOG_P25 , "TSBK_OSP_TIME_DATE_ANN (Dump Start)" ); + LogError( LOG_P25 , "tsbkValue RAW= $%p" , tsbkValue ); + LogError( LOG_P25 , "tmM= $%p" , tmM ); + LogError( LOG_P25 , "tmMDAY= $%p" , tmMDAY ); + LogError( LOG_P25 , "tmY= $%p" , tmY ); + LogError( LOG_P25 , "tmH= $%p" , tmH ); + LogError( LOG_P25 , "tmMin= $%p" , tmMin ); + LogError( LOG_P25 , "tmS= $%p" , tmS ); + LogError( LOG_P25 , "TSBK_OSP_TIME_DATE_ANN (Dump End)" ); + + }break; default: if (m_mfId == P25_MFG_STANDARD) { LogError(LOG_P25, "TSBK::encode(), unknown TSBK LCO value, mfId = $%02X, lco = $%02X", m_mfId, m_lco); diff --git a/p25/packet/Trunk.cpp b/p25/packet/Trunk.cpp index a2244263..22cd78c7 100644 --- a/p25/packet/Trunk.cpp +++ b/p25/packet/Trunk.cpp @@ -187,7 +187,7 @@ bool Trunk::process(uint8_t* data, uint32_t len, bool preDecoded) } RPT_RF_STATE prevRfState = m_p25->m_rfState; - + // handle individual DUIDs if (duid == P25_DUID_TSDU) { if (m_p25->m_rfState != RS_RF_DATA) { @@ -199,7 +199,7 @@ bool Trunk::process(uint8_t* data, uint32_t len, bool preDecoded) if (!preDecoded) { resetRF(); resetNet(); - + bool ret = m_rfTSBK.decode(data + 2U); if (!ret) { LogWarning(LOG_RF, P25_TSDU_STR ", undecodable LC"); @@ -270,7 +270,7 @@ bool Trunk::process(uint8_t* data, uint32_t len, bool preDecoded) VALID_DSTID("TSBK_IOSP_UU_ANS (Unit-to-Unit Answer Response)", TSBK_IOSP_UU_ANS, dstId); if (m_verbose) { - LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_UU_ANS (Unit-to-Unit Answer Response), response = $%02X, srcId = %u, dstId = %u", + LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_UU_ANS (Unit-to-Unit Answer Response), response = $%02X, srcId = %u, dstId = %u", m_rfTSBK.getResponse(), srcId, dstId); } @@ -344,7 +344,7 @@ bool Trunk::process(uint8_t* data, uint32_t len, bool preDecoded) RF_TO_WRITE_NET(); if (m_verbose) { - LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_MSG_UPDT (Message Update), message = $%02X, srcId = %u, dstId = %u", + LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_MSG_UPDT (Message Update), message = $%02X, srcId = %u, dstId = %u", m_rfTSBK.getMessage(), srcId, dstId); } @@ -377,7 +377,7 @@ bool Trunk::process(uint8_t* data, uint32_t len, bool preDecoded) VALID_DSTID("TSBK_IOSP_ACK_RSP (Acknowledge Response)", TSBK_IOSP_ACK_RSP, dstId); if (m_verbose) { - LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_ACK_RSP (Acknowledge Response), AIV = %u, serviceType = $%02X, srcId = %u, dstId = %u", + LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_ACK_RSP (Acknowledge Response), AIV = %u, serviceType = $%02X, srcId = %u, dstId = %u", m_rfTSBK.getAIV(), m_rfTSBK.getService(), srcId, dstId); } @@ -405,7 +405,7 @@ bool Trunk::process(uint8_t* data, uint32_t len, bool preDecoded) break; case TSBK_IOSP_EXT_FNCT: if (m_verbose) { - LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_EXT_FNCT (Extended Function), op = $%02X, arg = %u, tgt = %u", + LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_EXT_FNCT (Extended Function), op = $%02X, arg = %u, tgt = %u", m_rfTSBK.getExtendedFunction(), dstId, srcId); } @@ -456,7 +456,7 @@ bool Trunk::process(uint8_t* data, uint32_t len, bool preDecoded) IS_SUPPORT_CONTROL_CHECK("TSBK_IOSP_GRP_AFF (Group Affiliation Query Response)", TSBK_ISP_GRP_AFF_Q_RSP, srcId); if (m_verbose) { - LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_GRP_AFF (Group Affiliation Query Response), srcId = %u, dstId = %u, anncId = %u", srcId, dstId, + LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_GRP_AFF (Group Affiliation Query Response), srcId = %u, dstId = %u, anncId = %u", srcId, dstId, m_rfTSBK.getPatchSuperGroupId()); } @@ -692,7 +692,7 @@ bool Trunk::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L VALID_SRCID_NET("TSBK_IOSP_STS_UPDT (Status Update)", srcId); if (m_verbose) { - LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_IOSP_STS_UPDT (Status Update), status = $%02X, srcId = %u", + LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_IOSP_STS_UPDT (Status Update), status = $%02X, srcId = %u", m_netTSBK.getStatus(), srcId); } @@ -703,7 +703,7 @@ bool Trunk::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L VALID_SRCID_NET("TSBK_IOSP_MSG_UPDT (Message Update)", srcId); if (m_verbose) { - LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_IOSP_MSG_UPDT (Message Update), message = $%02X, srcId = %u, dstId = %u", + LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_IOSP_MSG_UPDT (Message Update), message = $%02X, srcId = %u, dstId = %u", m_netTSBK.getMessage(), srcId, dstId); } @@ -736,7 +736,7 @@ bool Trunk::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L VALID_DSTID_NET("TSBK_IOSP_ACK_RSP (Acknowledge Response)", dstId); if (m_verbose) { - LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_IOSP_ACK_RSP (Acknowledge Response), AIV = %u, serviceType = $%02X, srcId = %u, dstId = %u", + LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_IOSP_ACK_RSP (Acknowledge Response), AIV = %u, serviceType = $%02X, srcId = %u, dstId = %u", m_netTSBK.getAIV(), m_netTSBK.getService(), dstId, srcId); } @@ -747,7 +747,7 @@ bool Trunk::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L VALID_DSTID_NET("TSBK_IOSP_EXT_FNCT (Extended Function)", dstId); if (m_verbose) { - LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_IOSP_EXT_FNCT (Extended Function), serviceType = $%02X, arg = %u, tgt = %u", + LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_IOSP_EXT_FNCT (Extended Function), serviceType = $%02X, arg = %u, tgt = %u", m_netTSBK.getService(), srcId, dstId); } break; @@ -844,7 +844,7 @@ void Trunk::writeAdjSSNetwork() if (m_network != NULL) { if (m_verbose) { - LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_OSP_ADJ_STS_BCAST (Adjacent Site Status Broadcast), network announce, sysId = $%03X, rfss = $%02X, site = $%02X, chId = %u, chNo = %u, svcClass = $%02X", + LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_OSP_ADJ_STS_BCAST (Adjacent Site Status Broadcast), network announce, sysId = $%03X, rfss = $%02X, site = $%02X, chId = %u, chNo = %u, svcClass = $%02X", m_p25->m_siteData.sysId(), m_p25->m_siteData.rfssId(), m_p25->m_siteData.siteId(), m_p25->m_siteData.channelId(), m_p25->m_siteData.channelNo(), m_p25->m_siteData.serviceClass()); } @@ -862,7 +862,7 @@ void Trunk::writeAdjSSNetwork() m_rfTSBK.setAdjSiteChnId(m_p25->m_siteData.channelId()); m_rfTSBK.setAdjSiteChnNo(m_p25->m_siteData.channelNo()); m_rfTSBK.setAdjSiteSvcClass(m_p25->m_siteData.serviceClass()); - + RF_TO_WRITE_NET(); } } @@ -901,12 +901,12 @@ void Trunk::clock(uint32_t ms) // update adjacent site data for (auto it = m_adjSiteUpdateCnt.begin(); it != m_adjSiteUpdateCnt.end(); ++it) { uint8_t siteId = it->first; - + uint8_t updateCnt = it->second; if (updateCnt > 0U) { updateCnt--; } - + if (updateCnt == 0U) { SiteData siteData = m_adjSiteTable[siteId]; LogWarning(LOG_NET, P25_TSDU_STR ", TSBK_OSP_ADJ_STS_BCAST (Adjacent Site Status Broadcast), no data [FAILED], sysId = $%03X, rfss = $%02X, site = $%02X, chId = %u, chNo = %u, svcClass = $%02X", @@ -1169,7 +1169,7 @@ Trunk::Trunk(Control* p25, network::BaseNetwork* network, bool dumpTSBKData, boo { m_rfMBF = new uint8_t[P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U]; ::memset(m_rfMBF, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U); - + m_adjSiteTable.clear(); m_adjSiteUpdateCnt.clear(); @@ -1299,6 +1299,10 @@ void Trunk::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS) break; } break; + case 8: + // write TIME_DATE_ANN + queueRF_TSBK_Ctrl( TSBK_OSP_TIME_DATE_ANN ); + break; } // should we insert the BSI bursts? @@ -1562,7 +1566,7 @@ void Trunk::writeRF_TSDU_MBF(bool clearBeforeWrite) Utils::dump(1U, "!!! *TSDU (MBF) TSBK Block", tsbk, P25_TSBK_FEC_LENGTH_BYTES); } - + // Add TSBK data Utils::setBitRange(tsbk, tsdu, offset, P25_TSBK_FEC_LENGTH_BITS); @@ -1591,7 +1595,7 @@ void Trunk::writeRF_TSDU_MBF(bool clearBeforeWrite) data[0U] = modem::TAG_DATA; data[1U] = 0x00U; - + if (clearBeforeWrite) { m_p25->m_modem->clearP25Data(); m_p25->m_queue.clear(); @@ -1862,6 +1866,14 @@ void Trunk::queueRF_TSBK_Ctrl(uint8_t lco) m_rfTSBK.setLCO(TSBK_OSP_DVM_GIT_HASH); m_rfTSBK.setMFId(P25_MFG_DVM); break; + case TSBK_OSP_TIME_DATE_ANN: + if ( m_debug ) + { + LogMessage( LOG_RF , P25_TSDU_STR ", TSBK_OSP_TIME_DATE_ANN (Time Date Announce)" ); + } + m_rfTSBK.setLCO( TSBK_OSP_TIME_DATE_ANN ); + m_rfTSBK.setMFId( P25_MFG_STANDARD ); + break; } m_rfTSBK.setLastBlock(true); // always set last block @@ -2169,7 +2181,7 @@ void Trunk::writeRF_TSDU_Deny(uint8_t reason, uint8_t service) m_rfTSBK.setResponse(reason); if (m_verbose) { - LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_OSP_DENY_RSP (Deny Response), AIV = %u, reason = $%02X, service = $%02X, srcId = %u, dstId = %u", + LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_OSP_DENY_RSP (Deny Response), AIV = %u, reason = $%02X, service = $%02X, srcId = %u, dstId = %u", m_rfTSBK.getAIV(), reason, service, m_rfTSBK.getSrcId(), m_rfTSBK.getDstId()); } @@ -2332,7 +2344,7 @@ void Trunk::writeRF_TSDU_Queue(uint8_t reason, uint8_t service) m_rfTSBK.setResponse(reason); if (m_verbose) { - LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_OSP_QUE_RSP (Queue Response), AIV = %u, reason = $%02X, srcId = %u, dstId = %u", + LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_OSP_QUE_RSP (Queue Response), AIV = %u, reason = $%02X, srcId = %u, dstId = %u", m_rfTSBK.getAIV(), reason, m_rfTSBK.getSrcId(), m_rfTSBK.getDstId()); } @@ -2475,7 +2487,7 @@ void Trunk::writeNet_TDULC(lc::TDULC lc) } if (m_p25->m_voice->m_netFrames > 0) { - ::ActivityLog("P25", false, "network end of transmission, %.1f seconds, %u%% packet loss", + ::ActivityLog("P25", false, "network end of transmission, %.1f seconds, %u%% packet loss", float(m_p25->m_voice->m_netFrames) / 50.0F, (m_p25->m_voice->m_netLost * 100U) / m_p25->m_voice->m_netFrames); } else { From 8a639610920a140c61633c06f389c835283fae41 Mon Sep 17 00:00:00 2001 From: Darjeeling Date: Tue, 6 Sep 2022 22:56:17 -0500 Subject: [PATCH 2/4] Change from local time to GMT and set LTO to +0 --- p25/lc/TSBK.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/p25/lc/TSBK.cpp b/p25/lc/TSBK.cpp index 066210e5..81665ece 100644 --- a/p25/lc/TSBK.cpp +++ b/p25/lc/TSBK.cpp @@ -897,7 +897,7 @@ void TSBK::encode(uint8_t* data, bool rawTSBK, bool noTrellis) //Setup std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); time_t tt = std::chrono::system_clock::to_time_t( now ); - tm local_tm = *localtime( &tt ); + tm local_tm = *gmtime( &tt ); unsigned long tmM = 0b000;//Month; +1 to account for tm_mon being 0-11 and p25 being 1-12 unsigned long tmMDAY = 0b00000;//Day of month unsigned int tmY = 0b0000000000000;//Year @@ -912,7 +912,7 @@ void TSBK::encode(uint8_t* data, bool rawTSBK, bool noTrellis) tmH |= local_tm.tm_hour;//Hour tmMin |= local_tm.tm_min;//Min unsigned int i = local_tm.tm_sec; - unsigned long VFLAGS = 0b11000000; // VL,VT,VD, Res(leave 0),LTO direction, LTO + unsigned long VFLAGS = 0b11100000; // VL,VT,VD, Res(leave 0),LTO direction, LTO unsigned long VLTO = 0b00000000; // LTO //Catch Leap Seconds From 8d4e98a77db24c2e8dee95bf8583d203d7cf3ff1 Mon Sep 17 00:00:00 2001 From: Darjeeling Date: Wed, 7 Sep 2022 09:25:49 -0500 Subject: [PATCH 3/4] Fixes as requested --- p25/P25Defines.h | 2 +- p25/lc/TSBK.cpp | 49 ++++++++++++++++++++++---------------------- p25/packet/Trunk.cpp | 5 ++--- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/p25/P25Defines.h b/p25/P25Defines.h index 9cf7217e..438425dd 100644 --- a/p25/P25Defines.h +++ b/p25/P25Defines.h @@ -326,7 +326,7 @@ namespace p25 const uint8_t TSBK_OSP_ADJ_STS_BCAST = 0x3CU; // ADJ STS BCAST - Adjacent Site Status Broadcast const uint8_t TSBK_OSP_IDEN_UP = 0x3DU; // IDEN UP - Channel Identifier Update const uint8_t TSBK_OSP_STS_Q = 0x1AU; // STS_Q - Status Query - const uint8_t TSBK_OSP_TIME_DATE_ANN = 0b110101; // TIME_DATE_ANN - Time and Date Announcement + const uint8_t TSBK_OSP_TIME_DATE_ANN = 0x35U; // TIME_DATE_ANN - Time and Date Announcement // TSBK Motorola Outbound Signalling Packet (OSP) Opcode(s) diff --git a/p25/lc/TSBK.cpp b/p25/lc/TSBK.cpp index 81665ece..af3995da 100644 --- a/p25/lc/TSBK.cpp +++ b/p25/lc/TSBK.cpp @@ -898,12 +898,12 @@ void TSBK::encode(uint8_t* data, bool rawTSBK, bool noTrellis) std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); time_t tt = std::chrono::system_clock::to_time_t( now ); tm local_tm = *gmtime( &tt ); - unsigned long tmM = 0b000;//Month; +1 to account for tm_mon being 0-11 and p25 being 1-12 - unsigned long tmMDAY = 0b00000;//Day of month - unsigned int tmY = 0b0000000000000;//Year - unsigned int tmH = 0b00000;//Hour - unsigned int tmMin = 0b000000;//Min - unsigned int tmS = 0b000000;//Second + unsigned long tmM = 0b000; + unsigned long tmMDAY = 0b00000; + uint32_t tmY = 0b0000000000000; + uint32_t tmH = 0b00000; + uint32_t tmMin = 0b000000; + uint32_t tmS = 0b000000; //Assign Values tmM |= (local_tm.tm_mon + 1);//Month; +1 to account for tm_mon being 0-11 and p25 being 1-12 @@ -911,16 +911,14 @@ void TSBK::encode(uint8_t* data, bool rawTSBK, bool noTrellis) tmY |= local_tm.tm_year;//Year tmH |= local_tm.tm_hour;//Hour tmMin |= local_tm.tm_min;//Min - unsigned int i = local_tm.tm_sec; - unsigned long VFLAGS = 0b11100000; // VL,VT,VD, Res(leave 0),LTO direction, LTO + uint32_t i = local_tm.tm_sec; + unsigned long VFLAGS = 0xE0; // VL,VT,VD, Res(leave 0),LTO direction, LTO unsigned long VLTO = 0b00000000; // LTO //Catch Leap Seconds - if ( i > 59U ) - { + if (i > 59U) { tmS |= 59U; - } else - { + } else { tmS |= i; } @@ -928,7 +926,7 @@ void TSBK::encode(uint8_t* data, bool rawTSBK, bool noTrellis) tmY = tmY - 100U; //Shift Shift - VFLAGS = VFLAGS << 56 ; + VFLAGS = VFLAGS << 56 ; //Flags VLTO = VLTO << 48; //LTO tmM = tmM << 44; //Month tmMDAY = tmMDAY << 39; //Day of month @@ -939,9 +937,9 @@ void TSBK::encode(uint8_t* data, bool rawTSBK, bool noTrellis) //Build tsbkValue tsbkValue = 0U; //Zero out tsbkValue - + //Flags tsbkValue = tsbkValue + VFLAGS; - tsbkValue = tsbkValue + VLTO; //LTO + tsbkValue = tsbkValue + VLTO; //Date tsbkValue = tsbkValue + tmM; tsbkValue = tsbkValue + tmMDAY; @@ -951,16 +949,17 @@ void TSBK::encode(uint8_t* data, bool rawTSBK, bool noTrellis) tsbkValue = tsbkValue + tmMin; tsbkValue = tsbkValue + tmS; - //Debug Stuff, Comment out or put in a #if DEBUG statement before push - LogError( LOG_P25 , "TSBK_OSP_TIME_DATE_ANN (Dump Start)" ); - LogError( LOG_P25 , "tsbkValue RAW= $%p" , tsbkValue ); - LogError( LOG_P25 , "tmM= $%p" , tmM ); - LogError( LOG_P25 , "tmMDAY= $%p" , tmMDAY ); - LogError( LOG_P25 , "tmY= $%p" , tmY ); - LogError( LOG_P25 , "tmH= $%p" , tmH ); - LogError( LOG_P25 , "tmMin= $%p" , tmMin ); - LogError( LOG_P25 , "tmS= $%p" , tmS ); - LogError( LOG_P25 , "TSBK_OSP_TIME_DATE_ANN (Dump End)" ); +#if DEBUG_P25_TSBK + LogError(LOG_P25 , "TSBK_OSP_TIME_DATE_ANN (Dump Start)"); + LogError(LOG_P25 , "tsbkValue RAW= $%p" , tsbkValue); + LogError(LOG_P25 , "tmM= $%p" , tmM); + LogError(LOG_P25 , "tmMDAY= $%p" , tmMDAY); + LogError(LOG_P25 , "tmY= $%p" , tmY); + LogError(LOG_P25 , "tmH= $%p" , tmH); + LogError(LOG_P25 , "tmMin= $%p" , tmMin); + LogError(LOG_P25 , "tmS= $%p" , tmS); + LogError(LOG_P25 , "TSBK_OSP_TIME_DATE_ANN (Dump End)"); +#endif }break; default: diff --git a/p25/packet/Trunk.cpp b/p25/packet/Trunk.cpp index 22cd78c7..ad3e0cd3 100644 --- a/p25/packet/Trunk.cpp +++ b/p25/packet/Trunk.cpp @@ -1301,7 +1301,7 @@ void Trunk::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS) break; case 8: // write TIME_DATE_ANN - queueRF_TSBK_Ctrl( TSBK_OSP_TIME_DATE_ANN ); + queueRF_TSBK_Ctrl(TSBK_OSP_TIME_DATE_ANN); break; } @@ -1867,8 +1867,7 @@ void Trunk::queueRF_TSBK_Ctrl(uint8_t lco) m_rfTSBK.setMFId(P25_MFG_DVM); break; case TSBK_OSP_TIME_DATE_ANN: - if ( m_debug ) - { + if ( m_debug ) { LogMessage( LOG_RF , P25_TSDU_STR ", TSBK_OSP_TIME_DATE_ANN (Time Date Announce)" ); } m_rfTSBK.setLCO( TSBK_OSP_TIME_DATE_ANN ); From 7a637bf7c600f8c962b364a0a41ba1a2504a6e58 Mon Sep 17 00:00:00 2001 From: Darjeeling Date: Wed, 7 Sep 2022 09:30:24 -0500 Subject: [PATCH 4/4] For realz this time --- p25/packet/Trunk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/p25/packet/Trunk.cpp b/p25/packet/Trunk.cpp index ad3e0cd3..29e5ec1e 100644 --- a/p25/packet/Trunk.cpp +++ b/p25/packet/Trunk.cpp @@ -1868,7 +1868,7 @@ void Trunk::queueRF_TSBK_Ctrl(uint8_t lco) break; case TSBK_OSP_TIME_DATE_ANN: if ( m_debug ) { - LogMessage( LOG_RF , P25_TSDU_STR ", TSBK_OSP_TIME_DATE_ANN (Time Date Announce)" ); + LogMessage(LOG_RF , P25_TSDU_STR ", TSBK_OSP_TIME_DATE_ANN (Time Date Announce)"); } m_rfTSBK.setLCO( TSBK_OSP_TIME_DATE_ANN ); m_rfTSBK.setMFId( P25_MFG_STANDARD );