file cleanups; implement BCAST_ANNC_ANN_WD_TSCC; add support for channel identity lookups in DMR; fix a couple of issues with BCAST packet formatting;

pull/1/head
Bryan Biedenkapp 5 years ago
parent cfc8604c8e
commit 6d1644b99e

@ -92,6 +92,7 @@ system:
config:
channelId: 2
channelNo: 1
dmrNetId: 1
voiceChNo:
- 1
colorCode: 5

@ -12,7 +12,7 @@
//
/*
* Copyright (C) 2015,2016,2017 Jonathan Naylor, G4KLX
* Copyright (C) 2017,2020 by Bryan Biedenkapp <gatekeep@jmp.cx>
* Copyright (C) 2017-2021 by Bryan Biedenkapp <gatekeep@jmp.cx>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -53,7 +53,8 @@ using namespace dmr;
/// <param name="duplex">Flag indicating full-duplex operation.</param>
/// <param name="ridLookup">Instance of the RadioIdLookup class.</param>
/// <param name="tidLookup">Instance of the TalkgroupIdLookup class.</param>
/// <param name="rssi">Instance of the CRSSIInterpolator class.</param>
/// <param name="idenTable">Instance of the IdenTableLookup class.</param>
/// <param name="rssiMapper">Instance of the RSSIInterpolator class.</param>
/// <param name="jitter"></param>
/// <param name="dumpDataPacket"></param>
/// <param name="repeatDataPacket"></param>
@ -62,13 +63,14 @@ using namespace dmr;
/// <param name="verbose">Flag indicating whether DMR verbose logging is enabled.</param>
Control::Control(uint32_t colorCode, uint32_t callHang, uint32_t queueSize, bool embeddedLCOnly,
bool dumpTAData, uint32_t timeout, uint32_t tgHang, modem::Modem* modem, network::BaseNetwork* network, bool duplex,
lookups::RadioIdLookup* ridLookup, lookups::TalkgroupIdLookup* tidLookup, lookups::RSSIInterpolator* rssi,
lookups::RadioIdLookup* ridLookup, lookups::TalkgroupIdLookup* tidLookup, lookups::IdenTableLookup* idenTable, lookups::RSSIInterpolator* rssiMapper,
uint32_t jitter, bool dumpDataPacket, bool repeatDataPacket, bool dumpCSBKData, bool debug, bool verbose) :
m_colorCode(colorCode),
m_modem(modem),
m_network(network),
m_slot1(NULL),
m_slot2(NULL),
m_idenTable(idenTable),
m_ridLookup(ridLookup),
m_tidLookup(tidLookup),
m_dumpCSBKData(dumpCSBKData),
@ -78,10 +80,11 @@ Control::Control(uint32_t colorCode, uint32_t callHang, uint32_t queueSize, bool
assert(modem != NULL);
assert(ridLookup != NULL);
assert(tidLookup != NULL);
assert(rssi != NULL);
assert(idenTable != NULL);
assert(rssiMapper != NULL);
acl::AccessControl::init(m_ridLookup, m_tidLookup);
Slot::init(colorCode, SiteData(), embeddedLCOnly, dumpTAData, callHang, modem, network, duplex, m_ridLookup, m_tidLookup, rssi, jitter);
Slot::init(colorCode, SiteData(), embeddedLCOnly, dumpTAData, callHang, modem, network, duplex, m_ridLookup, m_tidLookup, m_idenTable, rssiMapper, jitter);
m_slot1 = new Slot(1U, timeout, tgHang, queueSize, dumpDataPacket, repeatDataPacket, dumpCSBKData, debug, verbose);
m_slot2 = new Slot(2U, timeout, tgHang, queueSize, dumpDataPacket, repeatDataPacket, dumpCSBKData, debug, verbose);
@ -96,6 +99,22 @@ Control::~Control()
delete m_slot1;
}
/// <summary>
/// Helper to set DMR configuration options.
/// </summary>
/// <param name="conf">Instance of the ConfigINI class.</param>
/// <param name="netId"></param>
/// <param name="siteId"></param>
/// <param name="channelId"></param>
/// <param name="channelNo"></param>
void Control::setOptions(yaml::Node& conf, uint32_t netId, uint8_t siteId, uint8_t channelId, uint32_t channelNo)
{
yaml::Node systemConf = conf["system"];
yaml::Node dmrProtocol = conf["protocols"]["dmr"];
Slot::setSiteData(netId, siteId, channelId, channelNo);
}
/// <summary>
/// Helper to process wakeup frames from the RF interface.
/// </summary>

@ -38,8 +38,10 @@
#include "network/BaseNetwork.h"
#include "network/RemoteControl.h"
#include "lookups/RSSIInterpolator.h"
#include "lookups/IdenTableLookup.h"
#include "lookups/RadioIdLookup.h"
#include "lookups/TalkgroupIdLookup.h"
#include "yaml/Yaml.h"
namespace dmr
{
@ -58,11 +60,14 @@ namespace dmr
/// <summary>Initializes a new instance of the Control class.</summary>
Control(uint32_t colorCode, uint32_t callHang, uint32_t queueSize, bool embeddedLCOnly,
bool dumpTAData, uint32_t timeout, uint32_t tgHang, modem::Modem* modem, network::BaseNetwork* network, bool duplex,
lookups::RadioIdLookup* ridLookup, lookups::TalkgroupIdLookup* tidLookup, lookups::RSSIInterpolator* rssi,
lookups::RadioIdLookup* ridLookup, lookups::TalkgroupIdLookup* tidLookup, lookups::IdenTableLookup* idenTable, lookups::RSSIInterpolator* rssi,
uint32_t jitter, bool dumpDataPacket, bool repeatDataPacket, bool dumpCSBKData, bool debug, bool verbose);
/// <summary>Finalizes a instance of the Control class.</summary>
~Control();
/// <summary>Helper to set DMR configuration options.</summary>
void setOptions(yaml::Node& conf, uint32_t netId, uint8_t siteId, uint8_t channelId, uint32_t channelNo);
/// <summary>Helper to process wakeup frames from the RF interface.</summary>
bool processWakeup(const uint8_t* data);
@ -95,6 +100,7 @@ namespace dmr
Slot* m_slot1;
Slot* m_slot2;
lookups::IdenTableLookup* m_idenTable;
lookups::RadioIdLookup* m_ridLookup;
lookups::TalkgroupIdLookup* m_tidLookup;

@ -131,6 +131,7 @@ namespace dmr
const uint32_t DMR_EXT_FNCT_INHIBIT_ACK = 0x00FFU; // Radio Inhibit Ack
const uint8_t DMR_ALOHA_VER_151 = 0x00U;
const uint8_t DMR_CHNULL = 0x00U;
// Data Type(s)
const uint8_t DT_VOICE_PI_HEADER = 0x00U;
@ -163,7 +164,7 @@ namespace dmr
const uint8_t SLCO_TSCC = 0x02U;
// Broadcast Announcement Type(s)
const uint8_t BCAST_ANNC_ANN_WD_TSCC = 0x00U; // Announce/Withdraw TSCC
const uint8_t BCAST_ANNC_ANN_WD_TSCC = 0x00U; // Announce-WD TSCC Channel
const uint8_t BCAST_ANNC_CALL_TIMER_PARMS = 0x01U; // Specify Call Timer Parameters
const uint8_t BCAST_ANNC_VOTE_NOW = 0x02U; // Vote Now Advice
const uint8_t BCAST_ANNC_LOCAL_TIME = 0x03U; // Broadcast Local Time
@ -192,9 +193,9 @@ namespace dmr
const uint8_t CSBKO_ACK_RSP = 0x20U; // ACK RSP - Acknowledge Response
const uint8_t CSBKO_EXT_FNCT = 0x24U; // (DMRA) EXT FNCT - Extended Function
const uint8_t CSBKO_NACK_RSP = 0x26U; // NACK RSP - Negative Acknowledgement Response
const uint8_t CSBKO_BROADCAST = 0x28U; // BCAST - Announcement PDUs
const uint8_t CSBKO_BSDWNACT = 0x38U; // BS DWN ACT - BS Outbound Activation
const uint8_t CSBKO_PRECCSBK = 0x3DU; // PRE CSBK - Preamble CSBK
const uint8_t CSBKO_BROADCAST = 0x40U; // BCAST - Announcement PDUs
const uint8_t TALKER_ID_NONE = 0x00U;
const uint8_t TALKER_ID_HEADER = 0x01U;

@ -43,6 +43,12 @@ using namespace dmr;
#include <algorithm>
#include <cmath>
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
const uint16_t TSCC_MAX_CNT = 511U;
// ---------------------------------------------------------------------------
// Static Class Members
// ---------------------------------------------------------------------------
@ -56,9 +62,15 @@ bool Slot::m_dumpTAData = true;
modem::Modem* Slot::m_modem = NULL;
network::BaseNetwork* Slot::m_network = NULL;
bool Slot::m_duplex = true;
lookups::IdenTableLookup* Slot::m_idenTable = NULL;
lookups::RadioIdLookup* Slot::m_ridLookup = NULL;
lookups::TalkgroupIdLookup* Slot::m_tidLookup = NULL;
lookups::IdenTable Slot::m_idenEntry = lookups::IdenTable();
uint32_t Slot::m_hangCount = 3U * 17U;
lookups::RSSIInterpolator* Slot::m_rssiMapper = NULL;
@ -75,6 +87,8 @@ uint8_t Slot::m_flco2;
uint8_t Slot::m_id2 = 0U;
bool Slot::m_voice2 = true;
uint16_t Slot::m_tsccCnt = 0U;
// ---------------------------------------------------------------------------
// Public Class Members
// ---------------------------------------------------------------------------
@ -321,6 +335,14 @@ void Slot::clock()
uint32_t ms = m_interval.elapsed();
m_interval.start();
// increment the TSCC counter on every slot 1 clock
if (m_slotNo == 1U) {
m_tsccCnt++;
if (m_tsccCnt == TSCC_MAX_CNT) {
m_tsccCnt = 0U;
}
}
m_rfTimeoutTimer.clock(ms);
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired()) {
if (!m_rfTimeout) {
@ -396,26 +418,35 @@ void Slot::clock()
/// <param name="duplex">Flag indicating full-duplex operation.</param>
/// <param name="ridLookup">Instance of the RadioIdLookup class.</param>
/// <param name="tidLookup">Instance of the TalkgroupIdLookup class.</param>
/// <param name="rssi">Instance of the CRSSIInterpolator class.</param>
/// <param name="idenTable">Instance of the IdenTableLookup class.</param>
/// <param name="rssi">Instance of the RSSIInterpolator class.</param>
/// <param name="jitter"></param>
void Slot::init(uint32_t colorCode, SiteData siteData, bool embeddedLCOnly, bool dumpTAData, uint32_t callHang, modem::Modem* modem,
network::BaseNetwork* network, bool duplex, lookups::RadioIdLookup* ridLookup, lookups::TalkgroupIdLookup* tidLookup,
lookups::RSSIInterpolator* rssiMapper, uint32_t jitter)
lookups::IdenTableLookup* idenTable, lookups::RSSIInterpolator* rssiMapper, uint32_t jitter)
{
assert(modem != NULL);
assert(ridLookup != NULL);
assert(tidLookup != NULL);
assert(idenTable != NULL);
assert(rssiMapper != NULL);
m_colorCode = colorCode;
m_siteData = siteData;
m_embeddedLCOnly = embeddedLCOnly;
m_dumpTAData = dumpTAData;
m_modem = modem;
m_network = network;
m_duplex = duplex;
m_idenTable = idenTable;
m_ridLookup = ridLookup;
m_tidLookup = tidLookup;
m_hangCount = callHang * 17U;
m_rssiMapper = rssiMapper;
@ -435,6 +466,28 @@ void Slot::init(uint32_t colorCode, SiteData siteData, bool embeddedLCOnly, bool
slotType.encode(m_idle + 2U);
}
/// <summary>
/// Sets local configured site data.
/// </summary>
/// <param name="netId">DMR Network ID.</param>
/// <param name="siteId">DMR Site ID.</param>
/// <param name="channelId">Channel ID.</param>
/// <param name="channelNo">Channel Number.</param>
void Slot::setSiteData(uint32_t netId, uint8_t siteId, uint8_t channelId, uint32_t channelNo)
{
m_siteData = SiteData(SITE_MODEL_SMALL, netId, siteId, 3U, false);
std::vector<lookups::IdenTable> entries = m_idenTable->list();
uint8_t i = 0U;
for (auto it = entries.begin(); it != entries.end(); ++it) {
lookups::IdenTable entry = *it;
if (entry.channelId == channelId) {
m_idenEntry = entry;
break;
}
}
}
// ---------------------------------------------------------------------------
// Private Class Members
// ---------------------------------------------------------------------------
@ -655,14 +708,84 @@ void Slot::writeRF_Call_Alrt(uint32_t srcId, uint32_t dstId)
}
/// <summary>
/// Helper to write a TSCC broadcast packet on the RF interface.
/// Helper to write a TSCC Ann-Wd broadcast packet on the RF interface.
/// </summary>
/// <param name="channelNo"></param>
/// <param name="annWd"></param>
void Slot::writeRF_TSCC_Bcast_Ann_Wd(uint32_t channelNo, bool annWd)
{
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_BROADCAST (Broadcast), BCAST_ANNC_ANN_WD_TSCC (Announce-WD TSCC Channel), channelNo = %u, annWd = %u",
m_slotNo, channelNo, annWd);
}
m_rfSeqNo = 0U;
SlotType slotType;
slotType.setColorCode(m_colorCode);
slotType.setDataType(DT_CSBK);
lc::CSBK csbk = lc::CSBK();
csbk.setVerbose(m_dumpCSBKData);
csbk.setCSBKO(CSBKO_BROADCAST);
csbk.setFID(FID_ETSI);
csbk.setAnncType(BCAST_ANNC_ANN_WD_TSCC);
csbk.setSiteData(m_siteData);
csbk.setLogicalCh1(channelNo);
csbk.setAnnWdCh1(annWd);
uint8_t data[DMR_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, DMR_FRAME_LENGTH_BYTES);
// MBC frame 1
csbk.setLastBlock(false);
// Regenerate the CSBK data
csbk.encode(data + 2U);
// Regenerate the Slot Type
slotType.encode(data + 2U);
// Convert the Data Sync to be from the BS or MS as needed
Sync::addDMRDataSync(data + 2U, m_duplex);
data[0U] = TAG_DATA;
data[1U] = 0x00U;
if (m_duplex)
writeQueueRF(data);
::memset(data + 2U, 0x00U, DMR_FRAME_LENGTH_BYTES);
// MBC frame 2
csbk.setLastBlock(false);
csbk.setCdef(true);
csbk.setIdenTable(m_idenEntry);
// Regenerate the CSBK data
csbk.encode(data + 2U);
// Regenerate the Slot Type
slotType.encode(data + 2U);
// Convert the Data Sync to be from the BS or MS as needed
Sync::addDMRDataSync(data + 2U, m_duplex);
data[0U] = TAG_DATA;
data[1U] = 0x00U;
if (m_duplex)
writeQueueRF(data);
}
/// <summary>
/// Helper to write a TSCC Sys_Parm broadcast packet on the RF interface.
/// </summary>
/// <param name="anncType">Broadcast announcement type.</param>
void Slot::writeRF_TSCC_Broadcast(uint8_t anncType)
void Slot::writeRF_TSCC_Bcast_Sys_Parm()
{
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_BROADCAST (Broadcast), anncType = %u",
m_slotNo, anncType);
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_BROADCAST (Broadcast), BCAST_ANNC_SITE_PARMS (Announce Site Parms)", m_slotNo);
}
uint8_t data[DMR_FRAME_LENGTH_BYTES + 2U];
@ -677,7 +800,7 @@ void Slot::writeRF_TSCC_Broadcast(uint8_t anncType)
csbk.setCSBKO(CSBKO_BROADCAST);
csbk.setFID(FID_ETSI);
csbk.setAnncType(anncType);
csbk.setAnncType(BCAST_ANNC_SITE_PARMS);
csbk.setSiteData(m_siteData);
// Regenerate the CSBK data

@ -39,6 +39,7 @@
#include "modem/Modem.h"
#include "network/BaseNetwork.h"
#include "lookups/RSSIInterpolator.h"
#include "lookups/IdenTableLookup.h"
#include "lookups/RadioIdLookup.h"
#include "lookups/TalkgroupIdLookup.h"
#include "RingBuffer.h"
@ -83,7 +84,9 @@ namespace dmr
/// <summary>Helper to initialize the slot processor.</summary>
static void init(uint32_t colorCode, SiteData siteData, bool embeddedLCOnly, bool dumpTAData, uint32_t callHang, modem::Modem* modem,
network::BaseNetwork* network, bool duplex, lookups::RadioIdLookup* ridLookup, lookups::TalkgroupIdLookup* tidLookup,
lookups::RSSIInterpolator* rssiMapper, uint32_t jitter);
lookups::IdenTableLookup* idenTable, lookups::RSSIInterpolator* rssiMapper, uint32_t jitter);
/// <summary>Sets local configured site data.</summary>
static void setSiteData(uint32_t netId, uint8_t siteId, uint8_t channelId, uint32_t channelNo);
private:
friend class Control;
@ -147,9 +150,12 @@ namespace dmr
static bool m_duplex;
static lookups::IdenTableLookup* m_idenTable;
static lookups::RadioIdLookup* m_ridLookup;
static lookups::TalkgroupIdLookup* m_tidLookup;
static lookups::IdenTable m_idenEntry;
static uint32_t m_hangCount;
static lookups::RSSIInterpolator* m_rssiMapper;
@ -167,6 +173,8 @@ namespace dmr
static uint8_t m_id2;
static bool m_voice2;
static uint16_t m_tsccCnt;
/// <summary>Helper to change the debug and verbose state.</summary>
void setDebugVerbose(bool debug, bool verbose);
@ -184,8 +192,10 @@ namespace dmr
void writeRF_Ext_Func(uint32_t func, uint32_t arg, uint32_t dstId);
/// <summary>Helper to write a call alert packet on the RF interface.</summary>
void writeRF_Call_Alrt(uint32_t srcId, uint32_t dstId);
/// <summary>Helper to write a TSCC broadcast packet on the RF interface.</summary>
void writeRF_TSCC_Broadcast(uint8_t anncType);
/// <summary>Helper to write a TSCC Ann-Wd broadcast packet on the RF interface.</summary>
void writeRF_TSCC_Bcast_Ann_Wd(uint32_t channelNo, bool annWd);
/// <summary>Helper to write a TSCC Sys_Parm broadcast packet on the RF interface.</summary>
void writeRF_TSCC_Bcast_Sys_Parm();
/// <summary></summary>
static void setShortLC(uint32_t slotNo, uint32_t id, uint8_t flco = FLCO_GROUP, bool voice = true);

@ -54,6 +54,7 @@ CSBK::CSBK() :
m_lastBlock(true),
m_bsId(0U),
m_GI(false),
m_Cdef(false),
m_srcId(0U),
m_dstId(0U),
m_dataContent(false),
@ -209,7 +210,9 @@ void CSBK::encode(uint8_t* bytes)
m_data[0U] = m_CSBKO; // CSBKO
m_data[0U] |= (m_lastBlock) ? 0x80U : 0x00U; // Last Block Marker
m_data[1U] = m_FID; // Feature ID
if (!m_Cdef) {
m_data[1U] = m_FID; // Feature ID
}
switch (m_CSBKO) {
case CSBKO_ACK_RSP:
@ -318,14 +321,75 @@ void CSBK::encode(uint8_t* bytes)
case CSBKO_BROADCAST:
{
ulong64_t csbkValue = 0U;
csbkValue = m_anncType; // Announcement Type
if (!m_Cdef) {
csbkValue = m_anncType; // Announcement Type
}
switch (m_anncType)
{
case BCAST_ANNC_ANN_WD_TSCC:
if (!m_Cdef) {
// Broadcast Parms 1
csbkValue = (csbkValue << 4) + 0U; // Reserved
csbkValue = (csbkValue << 4) + (m_colorCode & 0x0FU); // Color Code 1
csbkValue = (csbkValue << 4) + (m_colorCode & 0x0FU); // Color Code 2
csbkValue = (csbkValue << 1) + ((m_annWdCh1) ? 1U : 0U); // Announce/Withdraw Channel 1
csbkValue = (csbkValue << 1) + ((m_annWdCh2) ? 1U : 0U); // Announce/Withdraw Channel 2
csbkValue = (csbkValue << 1) + ((m_siteData.requireReg()) ? 1U : 0U); // Require Registration
csbkValue = (csbkValue << 4) + (m_backoffNo & 0x0FU); // Backoff Number
csbkValue = (csbkValue << 16) + m_siteData.systemIdentity(); // Site Identity
// Broadcast Parms 2
csbkValue = (csbkValue << 12) + (m_logicalCh1 & 0xFFFU); // Logical Channel 1
csbkValue = (csbkValue << 12) + (m_logicalCh2 & 0xFFFU); // Logical Channel 2
}
else {
uint32_t calcSpace = (uint32_t)(m_siteIdenEntry.chSpaceKhz() / 0.125);
float calcTxOffset = m_siteIdenEntry.txOffsetMhz() * 1000000;
const uint32_t multiple = 100000;
// calculate Rx frequency
uint32_t rxFrequency = (uint32_t)((m_siteIdenEntry.baseFrequency() + ((calcSpace * 125) * m_logicalCh1)) + calcTxOffset);
// generate frequency in mhz
uint32_t rxFreqMhz = rxFrequency + multiple / 2;
rxFreqMhz -= rxFreqMhz % multiple;
rxFreqMhz /= multiple * 10;
// generate khz offset
uint32_t rxFreqKhz = rxFrequency - (rxFreqMhz * 1000000);
// calculate Tx Frequency
uint32_t txFrequency = (uint32_t)((m_siteIdenEntry.baseFrequency() + ((calcSpace * 125) * m_logicalCh1)));
// generate frequency in mhz
uint32_t txFreqMhz = txFrequency + multiple / 2;
txFreqMhz -= txFreqMhz % multiple;
txFreqMhz /= multiple * 10;
// generate khz offset
uint32_t txFreqKhz = txFrequency - (txFreqMhz * 1000000);
csbkValue = (csbkValue << 8) + 0U; // Reserved
csbkValue = (csbkValue << 4) + 0U; // Cdef Type (always 0 for ANN_WD_TSCC)
csbkValue = (csbkValue << 2) + 0U; // Reserved
csbkValue = (csbkValue << 12) + (m_logicalCh1 & 0xFFFU); // Logical Channel
csbkValue = (csbkValue << 10) + txFreqMhz; // Transmit Freq Mhz
csbkValue = (csbkValue << 13) + txFreqKhz; // Transmit Freq Offset Khz
csbkValue = (csbkValue << 10) + rxFreqMhz; // Receive Freq Mhz
csbkValue = (csbkValue << 13) + rxFreqKhz; // Receive Freq Khz
}
break;
case BCAST_ANNC_SITE_PARMS:
// Broadcast Parms 1
csbkValue = (csbkValue << 14) + m_siteData.systemIdentity(true); // Site Identity (Broadcast Parms 1)
csbkValue = (csbkValue << 1) + ((m_siteData.requireReg()) ? 1U : 0U); // Require Registration
csbkValue = (csbkValue << 4) + (m_backoffNo & 0x0FU); // Backoff Number
csbkValue = (csbkValue << 16) + m_siteData.systemIdentity(); // Site Identity
// Broadcast Parms 2
csbkValue = (csbkValue << 1) + 0U; // Roaming TG Subscription/Attach
csbkValue = (csbkValue << 1) + ((m_hibernating) ? 1U : 0U); // TSCC Hibernating
csbkValue = (csbkValue << 22) + 0U; // Broadcast Parms 2 (Reserved)
@ -367,6 +431,8 @@ void CSBK::encode(uint8_t* bytes)
/// </summary>
void CSBK::reset()
{
m_colorCode = 0U;
m_backoffNo = 1U;
m_serviceType = 0U;
m_serviceOptions = 0U;
@ -378,6 +444,11 @@ void CSBK::reset()
m_anncType = BCAST_ANNC_SITE_PARMS;
m_hibernating = false;
m_annWdCh1 = false;
m_logicalCh1 = DMR_CHNULL;
m_annWdCh2 = false;
m_logicalCh2 = DMR_CHNULL;
/* Aloha */
m_siteTSSync = false;
m_siteOffsetTiming = false;
@ -391,6 +462,13 @@ void CSBK::setSiteData(SiteData siteData)
m_siteData = siteData;
}
/// <summary></summary>
/// <param name="entry"></param>
void CSBK::setIdenTable(lookups::IdenTable entry)
{
m_siteIdenEntry = entry;
}
/// <summary>Sets a flag indicating whether or not networking is active.</summary>
/// <param name="netActive"></param>
void CSBK::setNetActive(bool netActive)

@ -34,6 +34,7 @@
#include "Defines.h"
#include "dmr/DMRDefines.h"
#include "dmr/SiteData.h"
#include "lookups/IdenTableLookup.h"
namespace dmr
{
@ -62,6 +63,8 @@ namespace dmr
/** Local Site data */
/// <summary>Sets local configured site data.</summary>
void setSiteData(SiteData siteData);
/// <summary></summary>
void setIdenTable(lookups::IdenTable entry);
/// <summary>Sets a flag indicating whether or not networking is active.</summary>
void setNetActive(bool netActive);
@ -85,6 +88,10 @@ namespace dmr
/// <summary>Flag indicating whether the CSBK is group or individual.</summary>
__PROPERTY(bool, GI, GI);
// For Cdef blocks
/// <summary>Flag indicating whether the CSBK is a Cdef block.</summary>
__PROPERTY(bool, Cdef, Cdef);
/// <summary>Source ID.</summary>
__PROPERTY(uint32_t, srcId, SrcId);
/// <summary>Destination ID.</summary>
@ -96,6 +103,9 @@ namespace dmr
/// <summary>Sets the number of blocks to follow.</summary>
__PROPERTY(uint8_t, CBF, CBF);
/// <summary>DMR access color code.</summary>
__PROPERTY(uint8_t, colorCode, ColorCode);
// Tier III
/// <summary>Backoff Number.</summary>
__PROPERTY(uint8_t, backoffNo, BackoffNo);
@ -115,6 +125,15 @@ namespace dmr
/// <summary>Broadcast Hibernation Flag.</summary>
__PROPERTY(bool, hibernating, Hibernating);
/// <summary>Broadcast Announce/Withdraw Channel 1 Flag.</summary>
__PROPERTY(bool, annWdCh1, AnnWdCh1);
/// <summary>Broadcast Logical Channel ID 1.</summary>
__PROPERTY(uint16_t, logicalCh1, LogicalCh1);
/// <summary>Broadcast Announce/Withdraw Channel 2 Flag.</summary>
__PROPERTY(bool, annWdCh2, AnnWdCh2);
/// <summary>Broadcast Logical Channel ID 2.</summary>
__PROPERTY(uint16_t, logicalCh2, LogicalCh2);
/// <summary>Aloha Site Time Slot Synchronization.</summary>
__PROPERTY(bool, siteTSSync, SiteTSSync);
/// <summary>Aloha site users offset timing.</summary>
@ -127,6 +146,7 @@ namespace dmr
/** Local Site data */
SiteData m_siteData;
lookups::IdenTable m_siteIdenEntry;
bool m_siteNetActive;
};
} // namespace lc

@ -319,8 +319,10 @@ int Host::run()
}
dmr = new dmr::Control(m_dmrColorCode, callHang, dmrQueueSize, embeddedLCOnly, dumpTAData, m_timeout, m_rfTalkgroupHang,
m_modem, m_network, m_duplex, m_ridLookup, m_tidLookup, rssi, jitter, dmrDumpDataPacket, dmrRepeatDataPacket,
m_modem, m_network, m_duplex, m_ridLookup, m_tidLookup, m_idenTable, rssi, jitter, dmrDumpDataPacket, dmrRepeatDataPacket,
dmrDumpCsbkData, dmrDebug, dmrVerbose);
dmr->setOptions(m_conf, m_dmrNetId, m_siteId, m_channelId, m_channelNo);
m_dmrTXTimer.setTimeout(txHang);
if (dmrVerbose) {
@ -396,7 +398,7 @@ int Host::run()
p25ControlBcstInterval, m_duplex, m_ridLookup, m_tidLookup, m_idenTable, rssi, p25DumpDataPacket, p25RepeatDataPacket,
p25DumpTsbkData, p25Debug, p25Verbose);
p25->setOptions(m_conf, m_cwCallsign, m_voiceChNo, m_p25PatchSuperGroup, m_p25NetId, m_p25SysId, m_p25RfssId,
m_p25SiteId, m_channelId, m_channelNo, true);
m_siteId, m_channelId, m_channelNo, true);
if (p25Verbose) {
LogInfo(" Verbose: yes");
@ -1186,7 +1188,22 @@ bool Host::readParams()
}
strVoiceChNo.erase(strVoiceChNo.find_last_of(","));
m_siteId = (uint8_t)::strtoul(rfssConfig["siteId"].as<std::string>("1").c_str(), NULL, 16);
if (m_siteId == 0U) { // clamp to 1
m_siteId = 1U;
}
if (m_siteId > 0xFEU) { // clamp to $FE
m_siteId = 0xFEU;
}
m_dmrColorCode = rfssConfig["colorCode"].as<uint32_t>(2U);
m_dmrNetId = (uint32_t)::strtoul(rfssConfig["dmrNetId"].as<std::string>("1").c_str(), NULL, 16);
if (m_dmrNetId == 0U) { // clamp to 1
m_dmrNetId = 1U;
}
if (m_dmrNetId > 0x1FFU) { // clamp to $1FF
m_dmrNetId = 0x1FFU;
}
m_p25NAC = (uint32_t)::strtoul(rfssConfig["nac"].as<std::string>("293").c_str(), NULL, 16);
m_p25PatchSuperGroup = (uint32_t)::strtoul(rfssConfig["pSuperGroup"].as<std::string>("FFFF").c_str(), NULL, 16);
@ -1211,13 +1228,6 @@ bool Host::readParams()
if (m_p25RfssId > 0xFEU) { // clamp to $FE
m_p25RfssId = 0xFEU;
}
m_p25SiteId = (uint8_t)::strtoul(rfssConfig["siteId"].as<std::string>("1").c_str(), NULL, 16);
if (m_p25SiteId == 0U) { // clamp to 1
m_p25SiteId = 1U;
}
if (m_p25SiteId > 0xFEU) { // clamp to $FE
m_p25SiteId = 0xFEU;
}
LogInfo("System Config Parameters");
LogInfo(" RX Frequency: %uHz", m_rxFrequency);
@ -1229,13 +1239,14 @@ bool Host::readParams()
LogInfo(" Channel Id: %u", m_channelId);
LogInfo(" Channel No.: $%04X", m_channelNo);
LogInfo(" Voice Channel No(s).: %s", strVoiceChNo.c_str());
LogInfo(" Site Id: $%02X", m_siteId);
LogInfo(" DMR Color Code: %u", m_dmrColorCode);
LogInfo(" DMR Network Id: $%05X", m_dmrNetId);
LogInfo(" P25 NAC: $%03X", m_p25NAC);
LogInfo(" P25 Patch Super Group: $%04X", m_p25PatchSuperGroup);
LogInfo(" P25 Network Id: $%05X", m_p25NetId);
LogInfo(" P25 System Id: $%03X", m_p25SysId);
LogInfo(" P25 RFSS Id: $%02X", m_p25RfssId);
LogInfo(" P25 Site Id: $%02X", m_p25SiteId);
return true;
}

@ -113,13 +113,14 @@ private:
bool m_dmrBeacons;
bool m_controlData;
uint8_t m_siteId;
uint32_t m_dmrNetId;
uint32_t m_dmrColorCode;
uint32_t m_p25NAC;
uint32_t m_p25PatchSuperGroup;
uint32_t m_p25NetId;
uint32_t m_p25SysId;
uint8_t m_p25RfssId;
uint8_t m_p25SiteId;
friend class RemoteControl;
RemoteControl* m_remoteControl;

@ -72,7 +72,7 @@ const uint32_t MAX_PREAMBLE_TDU_CNT = 64U;
/// <param name="ridLookup">Instance of the RadioIdLookup class.</param>
/// <param name="tidLookup">Instance of the TalkgroupIdLookup class.</param>
/// <param name="idenTable">Instance of the IdenTableLookup class.</param>
/// <param name="rssi">Instance of the CRSSIInterpolator class.</param>
/// <param name="rssi">Instance of the RSSIInterpolator class.</param>
/// <param name="dumpPDUData"></param>
/// <param name="repeatPDU"></param>
/// <param name="dumpTSBKData"></param>
@ -169,7 +169,16 @@ void Control::reset()
/// Helper to set P25 configuration options.
/// </summary>
/// <param name="conf">Instance of the ConfigINI class.</param>
/// <param name="netOnly">Flag indicating this instance should operate in network only mode.</param>
/// <param name="cwCallsign"></param>
/// <param name="voiceChNo"></param>
/// <param name="pSuperGroup"></param>
/// <param name="netId"></param>
/// <param name="sysId"></param>
/// <param name="rfssId"></param>
/// <param name="siteId"></param>
/// <param name="channelId"></param>
/// <param name="channelNo"></param>
/// <param name="printOptions"></param>
void Control::setOptions(yaml::Node& conf, const std::string cwCallsign, const std::vector<uint32_t> voiceChNo,
uint32_t pSuperGroup, uint32_t netId, uint32_t sysId, uint8_t rfssId, uint8_t siteId, uint8_t channelId,
uint32_t channelNo, bool printOptions)

Loading…
Cancel
Save

Powered by TurnKey Linux.