/** * 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 * */ // // Based on code from the MMDVMHost project. (https://github.com/g4klx/MMDVMHost) // Licensed under the GPLv2 License (https://opensource.org/licenses/GPL-2.0) // /* * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX * * 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/LC.h" #include "Utils.h" using namespace dmr::lc; using namespace dmr; #include #include // --------------------------------------------------------------------------- // Public Class Members // --------------------------------------------------------------------------- /// /// Initializes a new instance of the LC class. /// /// Full-link Control Opcode. /// Source ID. /// Destination ID. LC::LC(uint8_t flco, uint32_t srcId, uint32_t dstId) : m_PF(false), m_FLCO(flco), m_FID(0U), m_srcId(srcId), m_dstId(dstId), m_R(false), m_options(0U) { /* stub */ } /// /// Initializes a new instance of the LC class. /// /// LC::LC(const uint8_t* bytes) : m_PF(false), m_FLCO(FLCO_GROUP), m_FID(0U), m_srcId(0U), m_dstId(0U), m_R(false), m_options(0U) { assert(bytes != NULL); m_PF = (bytes[0U] & 0x80U) == 0x80U; m_R = (bytes[0U] & 0x40U) == 0x40U; m_FLCO = bytes[0U] & 0x3FU; m_FID = bytes[1U]; m_options = bytes[2U]; m_dstId = bytes[3U] << 16 | bytes[4U] << 8 | bytes[5U]; m_srcId = bytes[6U] << 16 | bytes[7U] << 8 | bytes[8U]; } /// /// Initializes a new instance of the LC class. /// /// LC::LC(const bool* bits) : m_PF(false), m_FLCO(FLCO_GROUP), m_FID(0U), m_srcId(0U), m_dstId(0U), m_R(false), m_options(0U) { assert(bits != NULL); m_PF = bits[0U]; m_R = bits[1U]; uint8_t temp1, temp2, temp3; Utils::bitsToByteBE(bits + 0U, temp1); m_FLCO = temp1 & 0x3FU; Utils::bitsToByteBE(bits + 8U, temp2); m_FID = temp2; Utils::bitsToByteBE(bits + 16U, temp3); m_options = temp3; uint8_t d1, d2, d3; Utils::bitsToByteBE(bits + 24U, d1); Utils::bitsToByteBE(bits + 32U, d2); Utils::bitsToByteBE(bits + 40U, d3); uint8_t s1, s2, s3; Utils::bitsToByteBE(bits + 48U, s1); Utils::bitsToByteBE(bits + 56U, s2); Utils::bitsToByteBE(bits + 64U, s3); m_srcId = s1 << 16 | s2 << 8 | s3; m_dstId = d1 << 16 | d2 << 8 | d3; } /// /// Initializes a new instance of the LC class. /// LC::LC() : m_PF(false), m_FLCO(FLCO_GROUP), m_FID(0U), m_srcId(0U), m_dstId(0U), m_R(false), m_options(0U) { /* stub */ } /// /// Finalizes a instance of the LC class. /// LC::~LC() { /* stub */ } /// /// /// /// void LC::getData(uint8_t* bytes) const { assert(bytes != NULL); bytes[0U] = (uint8_t)m_FLCO; if (m_PF) bytes[0U] |= 0x80U; if (m_R) bytes[0U] |= 0x40U; bytes[1U] = m_FID; bytes[2U] = m_options; bytes[3U] = m_dstId >> 16; bytes[4U] = m_dstId >> 8; bytes[5U] = m_dstId >> 0; bytes[6U] = m_srcId >> 16; bytes[7U] = m_srcId >> 8; bytes[8U] = m_srcId >> 0; } /// /// /// /// void LC::getData(bool* bits) const { assert(bits != NULL); uint8_t bytes[9U]; getData(bytes); Utils::byteToBitsBE(bytes[0U], bits + 0U); Utils::byteToBitsBE(bytes[1U], bits + 8U); Utils::byteToBitsBE(bytes[2U], bits + 16U); Utils::byteToBitsBE(bytes[3U], bits + 24U); Utils::byteToBitsBE(bytes[4U], bits + 32U); Utils::byteToBitsBE(bytes[5U], bits + 40U); Utils::byteToBitsBE(bytes[6U], bits + 48U); Utils::byteToBitsBE(bytes[7U], bits + 56U); Utils::byteToBitsBE(bytes[8U], bits + 64U); } /// /// /// /// bool LC::getOVCM() const { return (m_options & 0x04U) == 0x04U; } /// /// /// /// void LC::setOVCM(bool ovcm) { if (ovcm) m_options |= 0x04U; else m_options &= 0xFBU; }