fix issue where erroneous CALL_TERM would be transmitted; support SCCB_EXP for when there is more then one CC at a site;

pull/1/head
Bryan Biedenkapp 5 years ago
parent 4b3e8de18f
commit 28bb91fbd2

@ -463,7 +463,7 @@ bool Control::writeControlRF()
return false; return false;
} }
if (m_ccSeq == 5U) { if (m_ccSeq == 6U) {
m_ccSeq = 0U; m_ccSeq = 0U;
} }

@ -120,6 +120,7 @@ namespace p25
const uint8_t P25_IDEN_UP_VU_BW_625K = 0x04U; const uint8_t P25_IDEN_UP_VU_BW_625K = 0x04U;
const uint8_t P25_IDEN_UP_VU_BW_125K = 0x05U; const uint8_t P25_IDEN_UP_VU_BW_125K = 0x05U;
const uint8_t P25_SVC_CLS_INVALID = 0x00U;
const uint8_t P25_SVC_CLS_COMPOSITE = 0x01U; const uint8_t P25_SVC_CLS_COMPOSITE = 0x01U;
const uint8_t P25_SVC_CLS_VOICE = 0x10U; const uint8_t P25_SVC_CLS_VOICE = 0x10U;
const uint8_t P25_SVC_CLS_DATA = 0x20U; const uint8_t P25_SVC_CLS_DATA = 0x20U;
@ -275,6 +276,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_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_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_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_GRP_AFF_Q = 0x2AU; // GRP AFF Q - Group Affiliation Query 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_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 const uint8_t TSBK_OSP_U_REG_CMD = 0x2DU; // U REG CMD - Unit Registration Command

@ -682,6 +682,29 @@ bool TrunkPacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
m_adjSiteTable[site.siteId()] = site; m_adjSiteTable[site.siteId()] = site;
m_adjSiteUpdateCnt[site.siteId()] = ADJ_SITE_UPDATE_CNT; m_adjSiteUpdateCnt[site.siteId()] = ADJ_SITE_UPDATE_CNT;
} else {
/*
** treat same site adjacent site broadcast as a SCCB for this site
*/
// update site table data
SiteData site;
try {
site = m_sccbTable.at(m_netTSBK.getAdjSiteRFSSId());
}
catch (...) {
site = SiteData();
}
if (m_verbose) {
LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_OSP_SCCB_EXP (Secondary Control Channel Broadcast), sysId = $%03X, rfss = $%02X, site = $%02X, chId = %u, chNo = %u",
m_netTSBK.getAdjSiteSysId(), m_netTSBK.getAdjSiteRFSSId(), m_netTSBK.getAdjSiteId(), m_netTSBK.getAdjSiteChnId(), m_netTSBK.getAdjSiteChnNo());
}
site.setAdjSite(m_netTSBK.getAdjSiteSysId(), m_netTSBK.getAdjSiteRFSSId(),
m_netTSBK.getAdjSiteId(), m_netTSBK.getAdjSiteChnId(), m_netTSBK.getAdjSiteChnNo());
m_sccbTable[site.rfssId()] = site;
m_sccbUpdateCnt[site.rfssId()] = ADJ_SITE_UPDATE_CNT;
} }
return true; return true;
@ -1065,9 +1088,10 @@ void TrunkPacket::clock(uint32_t ms)
releaseDstIdGrant(*it, false); releaseDstIdGrant(*it, false);
} }
// clock adjacent site update timers // clock adjacent site and SCCB update timers
m_adjSiteUpdateTimer.clock(ms); m_adjSiteUpdateTimer.clock(ms);
if (m_adjSiteUpdateTimer.isRunning() && m_adjSiteUpdateTimer.hasExpired()) { if (m_adjSiteUpdateTimer.isRunning() && m_adjSiteUpdateTimer.hasExpired()) {
// update adjacent site data
for (auto it = m_adjSiteUpdateCnt.begin(); it != m_adjSiteUpdateCnt.end(); ++it) { for (auto it = m_adjSiteUpdateCnt.begin(); it != m_adjSiteUpdateCnt.end(); ++it) {
uint8_t siteId = it->first; uint8_t siteId = it->first;
@ -1085,6 +1109,24 @@ void TrunkPacket::clock(uint32_t ms)
m_adjSiteUpdateCnt[siteId] = updateCnt; m_adjSiteUpdateCnt[siteId] = updateCnt;
} }
// update SCCB data
for (auto it = m_sccbUpdateCnt.begin(); it != m_sccbUpdateCnt.end(); ++it) {
uint8_t rfssId = it->first;
uint8_t updateCnt = it->second;
if (updateCnt > 0U) {
updateCnt--;
}
if (updateCnt == 0U) {
SiteData siteData = m_sccbTable[rfssId];
LogWarning(LOG_NET, P25_TSDU_STR ", TSBK_OSP_SCCB (Secondary Control Channel Broadcast), no data [FAILED], sysId = $%03X, rfss = $%02X, site = $%02X, chId = %u, chNo = %u",
siteData.sysId(), siteData.rfssId(), siteData.siteId(), siteData.channelId(), siteData.channelNo());
}
m_sccbUpdateCnt[rfssId] = updateCnt;
}
m_adjSiteUpdateTimer.setTimeout(m_adjSiteUpdateInterval); m_adjSiteUpdateTimer.setTimeout(m_adjSiteUpdateInterval);
m_adjSiteUpdateTimer.start(); m_adjSiteUpdateTimer.start();
} }
@ -1236,11 +1278,14 @@ TrunkPacket::TrunkPacket(Control* p25, network::BaseNetwork* network, bool dumpT
m_mbfCnt(0U), m_mbfCnt(0U),
m_mbfIdenCnt(0U), m_mbfIdenCnt(0U),
m_mbfAdjSSCnt(0U), m_mbfAdjSSCnt(0U),
m_mbfSCCBCnt(0U),
m_rfTDULC(), m_rfTDULC(),
m_netTDULC(), m_netTDULC(),
m_voiceChTable(), m_voiceChTable(),
m_adjSiteTable(), m_adjSiteTable(),
m_adjSiteUpdateCnt(), m_adjSiteUpdateCnt(),
m_sccbTable(),
m_sccbUpdateCnt(),
m_unitRegTable(), m_unitRegTable(),
m_grpAffTable(), m_grpAffTable(),
m_grantChTable(), m_grantChTable(),
@ -1284,6 +1329,9 @@ TrunkPacket::TrunkPacket(Control* p25, network::BaseNetwork* network, bool dumpT
m_adjSiteTable.clear(); m_adjSiteTable.clear();
m_adjSiteUpdateCnt.clear(); m_adjSiteUpdateCnt.clear();
m_sccbTable.clear();
m_sccbUpdateCnt.clear();
m_unitRegTable.clear(); m_unitRegTable.clear();
m_grpAffTable.clear(); m_grpAffTable.clear();
@ -1352,9 +1400,6 @@ void TrunkPacket::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS)
switch (n) switch (n)
{ {
case 0:
queueRF_TSBK_Ctrl_MBF(TSBK_OSP_IDEN_UP);
break;
case 1: case 1:
queueRF_TSBK_Ctrl_MBF(TSBK_OSP_RFSS_STS_BCAST); queueRF_TSBK_Ctrl_MBF(TSBK_OSP_RFSS_STS_BCAST);
break; break;
@ -1368,7 +1413,17 @@ void TrunkPacket::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS)
// write ADJSS // write ADJSS
if (adjSS) { if (adjSS) {
queueRF_TSBK_Ctrl_MBF(TSBK_OSP_ADJ_STS_BCAST); queueRF_TSBK_Ctrl_MBF(TSBK_OSP_ADJ_STS_BCAST);
break;
}
case 5:
// write SCCB
if (adjSS) {
queueRF_TSBK_Ctrl_MBF(TSBK_OSP_SCCB_EXP);
break;
} }
case 0:
default:
queueRF_TSBK_Ctrl_MBF(TSBK_OSP_IDEN_UP);
break; break;
} }
@ -1803,6 +1858,40 @@ void TrunkPacket::queueRF_TSBK_Ctrl_MBF(uint8_t lco)
return; // don't create anything return; // don't create anything
} }
break; break;
case TSBK_OSP_SCCB_EXP:
// write SCCB
if (m_sccbTable.size() > 0) {
if (m_mbfSCCBCnt >= m_sccbTable.size())
m_mbfSCCBCnt = 0U;
if (m_debug) {
LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_OSP_SCCB_EXP (Secondary Control Channel Broadcast)");
}
uint8_t i = 0U;
for (auto it = m_sccbTable.begin(); it != m_sccbTable.end(); ++it) {
// no good very bad way of skipping entries...
if (i != m_mbfSCCBCnt) {
i++;
continue;
}
else {
SiteData site = it->second;
// transmit SCCB broadcast
m_rfTSBK.setLCO(TSBK_OSP_SCCB_EXP);
m_rfTSBK.setSCCBChnId1(site.channelId());
m_rfTSBK.setSCCBChnNo(site.channelNo());
m_mbfSCCBCnt++;
break;
}
}
}
else {
return; // don't create anything
}
break;
case TSBK_OSP_SNDCP_CH_ANN: case TSBK_OSP_SNDCP_CH_ANN:
if (m_debug) { if (m_debug) {
LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_OSP_SNDCP_CH_ANN (SNDCP Channel Announcement)"); LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_OSP_SNDCP_CH_ANN (SNDCP Channel Announcement)");

@ -143,6 +143,7 @@ namespace p25
uint8_t m_mbfIdenCnt; uint8_t m_mbfIdenCnt;
uint8_t m_mbfAdjSSCnt; uint8_t m_mbfAdjSSCnt;
uint8_t m_mbfSCCBCnt;
lc::TDULC m_rfTDULC; lc::TDULC m_rfTDULC;
lc::TDULC m_netTDULC; lc::TDULC m_netTDULC;
@ -152,6 +153,9 @@ namespace p25
std::unordered_map<uint8_t, SiteData> m_adjSiteTable; std::unordered_map<uint8_t, SiteData> m_adjSiteTable;
std::unordered_map<uint8_t, uint8_t> m_adjSiteUpdateCnt; std::unordered_map<uint8_t, uint8_t> m_adjSiteUpdateCnt;
std::unordered_map<uint8_t, SiteData> m_sccbTable;
std::unordered_map<uint8_t, uint8_t> m_sccbUpdateCnt;
std::vector<uint32_t> m_unitRegTable; std::vector<uint32_t> m_unitRegTable;
std::unordered_map<uint32_t, uint32_t> m_grpAffTable; std::unordered_map<uint32_t, uint32_t> m_grpAffTable;

@ -319,6 +319,8 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
} }
} }
m_hadVoice = true;
m_p25->writeRF_Preamble(); m_p25->writeRF_Preamble();
m_p25->m_rfState = RS_RF_AUDIO; m_p25->m_rfState = RS_RF_AUDIO;
@ -785,6 +787,12 @@ bool VoicePacket::writeEndRF()
if (m_p25->m_netState == RS_NET_IDLE && m_p25->m_rfState == RS_RF_LISTENING) { if (m_p25->m_netState == RS_NET_IDLE && m_p25->m_rfState == RS_RF_LISTENING) {
writeRF_EndOfVoice(); writeRF_EndOfVoice();
// this should have been cleared by writeRF_EndOfVoice; but if it hasn't clear it
// to prevent badness
if (m_hadVoice) {
m_hadVoice = false;
}
if (!m_p25->m_ccRunning) { if (!m_p25->m_ccRunning) {
m_p25->m_trunk->writeRF_ControlData(255U, 0U, false); m_p25->m_trunk->writeRF_ControlData(255U, 0U, false);
m_p25->writeControlEndRF(); m_p25->writeControlEndRF();
@ -833,6 +841,7 @@ VoicePacket::VoicePacket(Control* p25, network::BaseNetwork* network, bool debug
m_netLDU2(NULL), m_netLDU2(NULL),
m_lastDUID(P25_DUID_TDU), m_lastDUID(P25_DUID_TDU),
m_lastIMBE(NULL), m_lastIMBE(NULL),
m_hadVoice(false),
m_lastPatchGroup(0U), m_lastPatchGroup(0U),
m_silenceThreshold(124U), m_silenceThreshold(124U),
m_verbose(verbose), m_verbose(verbose),
@ -899,6 +908,10 @@ void VoicePacket::writeNetworkRF(const uint8_t *data, uint8_t duid)
/// <returns></returns> /// <returns></returns>
void VoicePacket::writeRF_EndOfVoice() void VoicePacket::writeRF_EndOfVoice()
{ {
if (!m_hadVoice) {
return;
}
bool grp = m_rfLC.getGroup(); bool grp = m_rfLC.getGroup();
uint32_t srcId = m_rfLC.getSrcId(); uint32_t srcId = m_rfLC.getSrcId();
uint32_t dstId = m_rfLC.getDstId(); uint32_t dstId = m_rfLC.getDstId();
@ -1089,6 +1102,7 @@ void VoicePacket::writeNet_HDU(const lc::LC& control, const data::LowSpeedData&
LogMessage(LOG_NET, P25_HDU_STR ", dstId = %u, algo = $%02X, kid = $%04X", m_netLC.getDstId(), m_netLC.getAlgId(), m_netLC.getKId()); LogMessage(LOG_NET, P25_HDU_STR ", dstId = %u, algo = $%02X, kid = $%04X", m_netLC.getDstId(), m_netLC.getAlgId(), m_netLC.getKId());
} }
m_hadVoice = true;
m_p25->m_netState = RS_NET_AUDIO; m_p25->m_netState = RS_NET_AUDIO;
m_p25->m_netLastDstId = dstId; m_p25->m_netLastDstId = dstId;
m_p25->m_netTimeout.start(); m_p25->m_netTimeout.start();

@ -96,6 +96,7 @@ namespace p25
uint8_t* m_netLDU2; uint8_t* m_netLDU2;
uint8_t m_lastDUID; uint8_t m_lastDUID;
uint8_t* m_lastIMBE; uint8_t* m_lastIMBE;
bool m_hadVoice;
uint32_t m_lastPatchGroup; uint32_t m_lastPatchGroup;

@ -434,6 +434,24 @@ void TSBK::encode(uint8_t * data, bool singleBlock)
} }
} }
break; break;
case TSBK_OSP_SCCB_EXP:
tsbkValue = m_siteData.rfssId(); // RF Sub-System ID
tsbkValue = (tsbkValue << 8) + m_siteData.siteId(); // Site ID
tsbkValue = (tsbkValue << 4) + m_sccbChannelId1; // Channel (T) ID
tsbkValue = (tsbkValue << 12) + m_sccbChannelNo; // Channel (T) Number
tsbkValue = (tsbkValue << 12) + m_sccbChannelId1; // Channel (R) ID
tsbkValue = (tsbkValue << 12) + m_sccbChannelNo; // Channel (R) Number
if (m_sccbChannelId1 > 0) {
tsbkValue = (tsbkValue << 8) + // System Service Class
(P25_SVC_CLS_COMPOSITE | P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA | P25_SVC_CLS_REG);
}
else {
tsbkValue = (tsbkValue << 8) + // System Service Class
(P25_SVC_CLS_INVALID);
}
break;
case TSBK_OSP_GRP_AFF_Q: case TSBK_OSP_GRP_AFF_Q:
tsbkValue = 0U; tsbkValue = 0U;
tsbkValue = (tsbkValue << 24) + m_dstId; // Target Radio Address tsbkValue = (tsbkValue << 24) + m_dstId; // Target Radio Address
@ -489,6 +507,28 @@ void TSBK::encode(uint8_t * data, bool singleBlock)
tsbkValue = (tsbkValue << 16) + services; // System Services Available tsbkValue = (tsbkValue << 16) + services; // System Services Available
tsbkValue = (tsbkValue << 24) + services; // System Services Supported tsbkValue = (tsbkValue << 24) + services; // System Services Supported
break; break;
case TSBK_OSP_SCCB:
tsbkValue = m_siteData.rfssId(); // RF Sub-System ID
tsbkValue = (tsbkValue << 8) + m_siteData.siteId(); // Site ID
tsbkValue = (tsbkValue << 16) + m_sccbChannelId1; // SCCB Channel ID 1
if (m_sccbChannelId1 > 0) {
tsbkValue = (tsbkValue << 8) + // System Service Class
(P25_SVC_CLS_COMPOSITE | P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA | P25_SVC_CLS_REG);
}
else {
tsbkValue = (tsbkValue << 8) + // System Service Class
(P25_SVC_CLS_INVALID);
}
tsbkValue = (tsbkValue << 16) + m_sccbChannelId2; // SCCB Channel ID 2
if (m_sccbChannelId2 > 0) {
tsbkValue = (tsbkValue << 8) + // System Service Class
(P25_SVC_CLS_COMPOSITE | P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA | P25_SVC_CLS_REG);
}
else {
tsbkValue = (tsbkValue << 8) + // System Service Class
(P25_SVC_CLS_INVALID);
}
break;
case TSBK_OSP_RFSS_STS_BCAST: case TSBK_OSP_RFSS_STS_BCAST:
tsbkValue = m_siteData.lra(); // Location Registration Area tsbkValue = m_siteData.lra(); // Location Registration Area
tsbkValue = (tsbkValue << 4) + tsbkValue = (tsbkValue << 4) +

@ -146,6 +146,14 @@ namespace p25
/// <summary>Adjacent site channel number.</summary> /// <summary>Adjacent site channel number.</summary>
__PROPERTY(uint32_t, adjChannelNo, AdjSiteChnNo); __PROPERTY(uint32_t, adjChannelNo, AdjSiteChnNo);
/** SCCB Data */
/// <summary>SCCB channel ID 1.</summary>
__PROPERTY(uint8_t, sccbChannelId1, SCCBChnId1);
/// <summary>SCCB channel ID 2.</summary>
__PROPERTY(uint8_t, sccbChannelId2, SCCBChnId2);
/// <summary>Explicit SCCB channel number.</summary>
__PROPERTY(uint32_t, sccbChannelNo, SCCBChnNo);
/** Patch Group data */ /** Patch Group data */
/// <summary>Patch super group ID.</summary> /// <summary>Patch super group ID.</summary>
__PROPERTY(uint32_t, patchSuperGroupId, PatchSuperGroupId); __PROPERTY(uint32_t, patchSuperGroupId, PatchSuperGroupId);

Loading…
Cancel
Save

Powered by TurnKey Linux.