You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
6.7 KiB
175 lines
6.7 KiB
/**
|
|
* Digital Voice Modem - Host Software
|
|
* GPLv2 Open Source. Use is subject to license terms.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* @package DVM / Host Software
|
|
*
|
|
*/
|
|
/*
|
|
* Copyright (C) 2022 by Bryan Biedenkapp N2PLL
|
|
*
|
|
* 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
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
#include "Defines.h"
|
|
#include "dmr/lc/csbk/CSBK_BROADCAST.h"
|
|
#include "Log.h"
|
|
#include "Utils.h"
|
|
|
|
using namespace dmr::lc::csbk;
|
|
using namespace dmr::lc;
|
|
using namespace dmr;
|
|
|
|
#include <cassert>
|
|
#include <cmath>
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Public Class Members
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the CSBK_BROADCAST class.
|
|
/// </summary>
|
|
CSBK_BROADCAST::CSBK_BROADCAST() : CSBK(),
|
|
m_anncType(BCAST_ANNC_SITE_PARMS),
|
|
m_hibernating(false),
|
|
m_annWdCh1(false),
|
|
m_annWdCh2(false),
|
|
m_backoffNo(1U)
|
|
{
|
|
m_CSBKO = CSBKO_BROADCAST;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Decode a control signalling block.
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
/// <returns>True, if CSBK was decoded, otherwise false.</returns>
|
|
bool CSBK_BROADCAST::decode(const uint8_t* data)
|
|
{
|
|
assert(data != NULL);
|
|
|
|
/* stub */
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Encode a control signalling block.
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
void CSBK_BROADCAST::encode(uint8_t* data)
|
|
{
|
|
assert(data != NULL);
|
|
|
|
ulong64_t csbkValue = 0U;
|
|
|
|
if (!m_Cdef) {
|
|
csbkValue = m_anncType; // Announcement Type
|
|
}
|
|
|
|
switch (m_anncType)
|
|
{
|
|
case BCAST_ANNC_ANN_WD_TSCC:
|
|
// 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
|
|
break;
|
|
case BCAST_ANNC_CHAN_FREQ:
|
|
{
|
|
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 = 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 & 0x7FFU); // Transmit Freq Mhz
|
|
csbkValue = (csbkValue << 13) + (txFreqKhz & 0x3FFFU); // Transmit Freq Offset Khz
|
|
csbkValue = (csbkValue << 10) + (rxFreqMhz & 0x7FFU); // Receive Freq Mhz
|
|
csbkValue = (csbkValue << 13) + (rxFreqKhz & 0x3FFFU); // 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)
|
|
break;
|
|
}
|
|
|
|
std::unique_ptr<uint8_t[]> csbk = CSBK::fromValue(csbkValue);
|
|
CSBK::encode(data, csbk.get());
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Private Class Members
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Internal helper to copy the the class.
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
void CSBK_BROADCAST::copy(const CSBK_BROADCAST& data)
|
|
{
|
|
CSBK::copy(data);
|
|
|
|
m_anncType = data.m_anncType;
|
|
m_hibernating = data.m_hibernating;
|
|
|
|
m_annWdCh1 = data.m_annWdCh1;
|
|
m_annWdCh2 = data.m_annWdCh2;
|
|
}
|