add support to send service class across the network when adj site broadcasts occur;

pull/1/head
Bryan Biedenkapp 5 years ago
parent a66f91fe2f
commit 0c8f2583bc

@ -181,7 +181,6 @@ void Control::setOptions(yaml::Node& conf, const std::string cwCallsign, const s
m_tduPreambleCount = p25Protocol["tduPreambleCount"].as<uint32_t>(8U);
m_trunk->m_patchSuperGroup = pSuperGroup;
m_trunk->setSiteData(netId, sysId, rfssId, siteId, 0U, channelId, channelNo);
m_inhibitIllegal = p25Protocol["inhibitIllegal"].as<bool>(false);
m_legacyGroupGrnt = p25Protocol["legacyGroupGrnt"].as<bool>(true);
@ -218,6 +217,8 @@ void Control::setOptions(yaml::Node& conf, const std::string cwCallsign, const s
m_disableNetworkHDU = p25Protocol["disableNetworkHDU"].as<bool>(false);
m_trunk->setSiteData(netId, sysId, rfssId, siteId, 0U, channelId, channelNo);
std::vector<uint32_t> availCh = voiceChNo;
m_trunk->m_voiceChCnt = (uint8_t)availCh.size();
m_trunk->setSiteChCnt((uint8_t)availCh.size());

@ -51,6 +51,7 @@ namespace p25
m_siteId(1U),
m_channelId(1U),
m_channelNo(1U),
m_serviceClass(P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA),
m_isAdjSite(false)
{
/* stub */
@ -63,7 +64,8 @@ namespace p25
/// <param name="lra">P25 Location Resource Area.</param>
/// <param name="channelId">Channel ID.</param>
/// <param name="channelNo">Channel Number.</param>
SiteData(uint32_t netId, uint32_t sysId, uint8_t rfssId, uint8_t siteId, uint8_t lra, uint8_t channelId, uint32_t channelNo) :
/// <param name="serviceClass">Service class.</param>
SiteData(uint32_t netId, uint32_t sysId, uint8_t rfssId, uint8_t siteId, uint8_t lra, uint8_t channelId, uint32_t channelNo, uint8_t serviceClass) :
m_lra(0U),
m_netId(P25_WACN_STD_DEFAULT),
m_sysId(P25_SID_STD_DEFAULT),
@ -71,6 +73,7 @@ namespace p25
m_siteId(1U),
m_channelId(1U),
m_channelNo(1U),
m_serviceClass(P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA),
m_isAdjSite(false)
{
// lra clamping
@ -121,6 +124,8 @@ namespace p25
m_channelId = channelId;
m_channelNo = channelNo;
m_serviceClass = serviceClass;
}
/// <summary>Helper to set adjacent site data.</summary>
@ -129,7 +134,8 @@ namespace p25
/// <param name="siteId">P25 Site ID.</param>
/// <param name="channelId">Channel ID.</param>
/// <param name="channelNo">Channel Number.</param>
void setAdjSite(uint32_t sysId, uint8_t rfssId, uint8_t siteId, uint8_t channelId, uint32_t channelNo)
/// <param name="serviceClass">Service class.</param>
void setAdjSite(uint32_t sysId, uint8_t rfssId, uint8_t siteId, uint8_t channelId, uint32_t channelNo, uint8_t serviceClass)
{
// sysId clamping
if (sysId == 0U) // clamp to 1
@ -170,6 +176,8 @@ namespace p25
m_channelId = channelId;
m_channelNo = channelNo;
m_serviceClass = serviceClass;
m_isAdjSite = true;
}
@ -190,6 +198,8 @@ namespace p25
m_channelId = data.m_channelId;
m_channelNo = data.m_channelNo;
m_serviceClass = data.m_serviceClass;
m_isAdjSite = data.m_isAdjSite;
}
@ -211,6 +221,8 @@ namespace p25
__READONLY_PROPERTY_PLAIN(uint8_t, channelId, channelId);
/// <summary>Channel number.</summary>
__READONLY_PROPERTY_PLAIN(uint32_t, channelNo, channelNo);
/// <summary>Channel number.</summary>
__READONLY_PROPERTY_PLAIN(uint8_t, serviceClass, serviceClass);
/// <summary>Flag indicating whether this site data is for an adjacent site.</summary>
__READONLY_PROPERTY_PLAIN(bool, isAdjSite, isAdjSite);
};

@ -151,7 +151,8 @@ const uint32_t GRANT_TIMER_TIMEOUT = 15U;
void TrunkPacket::setSiteData(uint32_t netId, uint32_t sysId, uint8_t rfssId, uint8_t siteId, uint8_t lra,
uint8_t channelId, uint32_t channelNo)
{
m_siteData = SiteData(netId, sysId, rfssId, siteId, lra, channelId, channelNo);
uint8_t serviceClass = m_rfTSBK.getServiceClass();
m_siteData = SiteData(netId, sysId, rfssId, siteId, lra, channelId, channelNo, serviceClass);
m_rfTSBK.setSiteData(m_siteData);
m_rfTDULC.setSiteData(m_siteData);
@ -692,12 +693,12 @@ bool TrunkPacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
}
if (m_verbose) {
LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_OSP_ADJ_STS_BCAST (Adjacent Site Status 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());
LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_OSP_ADJ_STS_BCAST (Adjacent Site Status Broadcast), sysId = $%03X, rfss = $%02X, site = $%02X, chId = %u, chNo = %u, svcClass = $%02X",
m_netTSBK.getAdjSiteSysId(), m_netTSBK.getAdjSiteRFSSId(), m_netTSBK.getAdjSiteId(), m_netTSBK.getAdjSiteChnId(), m_netTSBK.getAdjSiteChnNo(), m_netTSBK.getAdjSiteSvcClass());
}
site.setAdjSite(m_netTSBK.getAdjSiteSysId(), m_netTSBK.getAdjSiteRFSSId(),
m_netTSBK.getAdjSiteId(), m_netTSBK.getAdjSiteChnId(), m_netTSBK.getAdjSiteChnNo());
m_netTSBK.getAdjSiteId(), m_netTSBK.getAdjSiteChnId(), m_netTSBK.getAdjSiteChnNo(), m_netTSBK.getAdjSiteSvcClass());
m_adjSiteTable[site.siteId()] = site;
m_adjSiteUpdateCnt[site.siteId()] = ADJ_SITE_UPDATE_CNT;
@ -715,12 +716,12 @@ bool TrunkPacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
}
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());
LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_OSP_SCCB_EXP (Secondary Control Channel Broadcast), sysId = $%03X, rfss = $%02X, site = $%02X, chId = %u, chNo = %u, svcClass = $%02X",
m_netTSBK.getAdjSiteSysId(), m_netTSBK.getAdjSiteRFSSId(), m_netTSBK.getAdjSiteId(), m_netTSBK.getAdjSiteChnId(), m_netTSBK.getAdjSiteChnNo(), m_netTSBK.getAdjSiteSvcClass());
}
site.setAdjSite(m_netTSBK.getAdjSiteSysId(), m_netTSBK.getAdjSiteRFSSId(),
m_netTSBK.getAdjSiteId(), m_netTSBK.getAdjSiteChnId(), m_netTSBK.getAdjSiteChnNo());
m_netTSBK.getAdjSiteId(), m_netTSBK.getAdjSiteChnId(), m_netTSBK.getAdjSiteChnNo(), m_netTSBK.getAdjSiteSvcClass());
m_sccbTable[site.rfssId()] = site;
m_sccbUpdateCnt[site.rfssId()] = ADJ_SITE_UPDATE_CNT;
@ -863,19 +864,27 @@ void TrunkPacket::writeAdjSSNetwork()
m_netTSBK.reset();
if (m_network != NULL) {
uint8_t serviceClass = m_rfTSBK.getServiceClass();
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",
m_siteData.sysId(), m_siteData.rfssId(), m_siteData.siteId(), m_siteData.channelId(), m_siteData.channelNo());
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_siteData.sysId(), m_siteData.rfssId(), m_siteData.siteId(), m_siteData.channelId(), m_siteData.channelNo(), serviceClass);
}
uint8_t cfva = P25_CFVA_VALID;
if (m_p25->m_control && m_p25->m_voiceOnControl) {
cfva |= P25_CFVA_CONV;
}
// transmit adjacent site broadcast
m_rfTSBK.setLCO(TSBK_OSP_ADJ_STS_BCAST);
m_rfTSBK.setAdjSiteCFVA(P25_CFVA_CONV | P25_CFVA_VALID);
m_rfTSBK.setAdjSiteCFVA(cfva);
m_rfTSBK.setAdjSiteSysId(m_siteData.sysId());
m_rfTSBK.setAdjSiteRFSSId(m_siteData.rfssId());
m_rfTSBK.setAdjSiteId(m_siteData.siteId());
m_rfTSBK.setAdjSiteChnId(m_siteData.channelId());
m_rfTSBK.setAdjSiteChnNo(m_siteData.channelNo());
m_rfTSBK.setAdjSiteSvcClass(serviceClass);
RF_TO_WRITE_NET();
}
@ -1124,8 +1133,8 @@ void TrunkPacket::clock(uint32_t ms)
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",
siteData.sysId(), siteData.rfssId(), siteData.siteId(), siteData.channelId(), siteData.channelNo());
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",
siteData.sysId(), siteData.rfssId(), siteData.siteId(), siteData.channelId(), siteData.channelNo(), siteData.serviceClass());
}
m_adjSiteUpdateCnt[siteId] = updateCnt;
@ -1142,8 +1151,8 @@ void TrunkPacket::clock(uint32_t ms)
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());
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, svcClass = $%02X",
siteData.sysId(), siteData.rfssId(), siteData.siteId(), siteData.channelId(), siteData.channelNo(), siteData.serviceClass());
}
m_sccbUpdateCnt[rfssId] = updateCnt;
@ -1854,6 +1863,7 @@ void TrunkPacket::queueRF_TSBK_Ctrl_MBF(uint8_t lco)
m_rfTSBK.setAdjSiteId(site.siteId());
m_rfTSBK.setAdjSiteChnId(site.channelId());
m_rfTSBK.setAdjSiteChnNo(site.channelNo());
m_rfTSBK.setAdjSiteSvcClass(site.serviceClass());
m_mbfAdjSSCnt++;
break;

@ -283,7 +283,8 @@ bool TSBK::decode(const uint8_t* data)
m_adjRfssId = (uint8_t)((tsbkValue >> 32) & 0xFFU); // Site RFSS ID
m_adjSiteId = (uint8_t)((tsbkValue >> 24) & 0xFFU); // Site ID
m_adjChannelId = (uint8_t)((tsbkValue >> 20) & 0xFU); // Site Channel ID
m_adjChannelNo = (uint32_t)((tsbkValue >> 8) & 0xFFFU); // Site Channel ID
m_adjChannelNo = (uint32_t)((tsbkValue >> 8) & 0xFFFU); // Site Channel Number
m_adjServiceClass = (uint8_t)(tsbkValue & 0xFFU); // Site Service Class
break;
default:
LogError(LOG_P25, "unknown TSBK LCO value, mfId = $%02X, lco = $%02X", m_mfId, m_lco);
@ -558,11 +559,11 @@ void TSBK::encode(uint8_t * data, bool singleBlock)
tsbkValue = (tsbkValue << 8) + m_adjSiteId; // Site ID
tsbkValue = (tsbkValue << 4) + m_adjChannelId; // Channel ID
tsbkValue = (tsbkValue << 12) + m_adjChannelNo; // Channel Number
tsbkValue = (tsbkValue << 8) + m_serviceClass; // System Service Class
tsbkValue = (tsbkValue << 8) + m_adjServiceClass; // System Service Class
}
else {
LogError(LOG_P25, "invalid values for OSP_ADJ_STS_BCAST, adjRfssId = $%02X, adjSiteId = $%02X, adjChannelId = %u, adjChannelNo = $%02X",
m_adjRfssId, m_adjSiteId, m_adjChannelId, m_adjChannelNo);
LogError(LOG_P25, "invalid values for OSP_ADJ_STS_BCAST, adjRfssId = $%02X, adjSiteId = $%02X, adjChannelId = %u, adjChannelNo = $%02X, adjSvcClass = $%02X",
m_adjRfssId, m_adjSiteId, m_adjChannelId, m_adjChannelNo, m_adjServiceClass);
return; // blatently ignore creating this TSBK
}
}
@ -785,11 +786,12 @@ void TSBK::reset()
m_extendedFunction = P25_EXT_FNCT_CHECK;
m_adjCFVA = P25_CFVA_CONV | P25_CFVA_FAILURE;
m_adjCFVA = P25_CFVA_FAILURE;
m_adjRfssId = 0U;
m_adjSiteId = 0U;
m_adjChannelId = 0U;
m_adjChannelNo = 0U;
m_adjServiceClass = P25_SVC_CLS_INVALID;
/* TSBK Patch Group data */
m_patchSuperGroupId = 0U;

@ -148,6 +148,8 @@ namespace p25
__PROPERTY(uint8_t, adjChannelId, AdjSiteChnId);
/// <summary>Adjacent site channel number.</summary>
__PROPERTY(uint32_t, adjChannelNo, AdjSiteChnNo);
/// <summary>Adjacent site channel number.</summary>
__PROPERTY(uint8_t, adjServiceClass, AdjSiteSvcClass);
/** SCCB Data */
/// <summary>SCCB channel ID 1.</summary>

Loading…
Cancel
Save

Powered by TurnKey Linux.