From 3633bcc99aedda5d9ea36c143fa339139c763d3e Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 6 Jan 2017 11:35:35 +0100 Subject: Replace EDI-to-ETI converter with a dedicated EDI source --- lib/edi/ETIWriter.cpp | 286 -------------------------------------------------- 1 file changed, 286 deletions(-) delete mode 100644 lib/edi/ETIWriter.cpp (limited to 'lib/edi/ETIWriter.cpp') diff --git a/lib/edi/ETIWriter.cpp b/lib/edi/ETIWriter.cpp deleted file mode 100644 index bd051dd..0000000 --- a/lib/edi/ETIWriter.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* - Copyright (C) 2016 - Matthias P. Braendli, matthias.braendli@mpb.li - - http://opendigitalradio.org - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#include "ETIWriter.hpp" -#include "crc.h" -#include "Log.h" -#include -#include -#include -#include - -namespace EdiDecoder { - -using namespace std; - -void ETIWriter::update_protocol( - const std::string& proto, - uint16_t major, - uint16_t minor) -{ - m_proto_valid = (proto == "DETI" and major == 0 and minor == 0); - - if (not m_proto_valid) { - throw std::invalid_argument("Wrong EDI protocol"); - } -} - -void ETIWriter::reinit() -{ - m_proto_valid = false; - m_fc_valid = false; - m_fic.clear(); - m_etiFrame.clear(); - m_subchannels.clear(); -} - -void ETIWriter::update_err(uint8_t err) -{ - if (not m_proto_valid) { - throw std::logic_error("Cannot update ERR before protocol"); - } - m_err = err; -} - -void ETIWriter::update_fc_data(const eti_fc_data& fc_data) -{ - if (not m_proto_valid) { - throw std::logic_error("Cannot update FC before protocol"); - } - - m_fc_valid = false; - m_fc = fc_data; - - if (not m_fc.ficf) { - throw std::invalid_argument("FIC must be present"); - } - - if (m_fc.mid > 4) { - throw std::invalid_argument("Invalid MID"); - } - - if (m_fc.fp > 7) { - throw std::invalid_argument("Invalid FP"); - } - - m_fc_valid = true; -} - -void ETIWriter::update_fic(const std::vector& fic) -{ - if (not m_proto_valid) { - throw std::logic_error("Cannot update FIC before protocol"); - } - - m_fic = fic; -} - -void ETIWriter::update_edi_time( - uint32_t utco, - uint32_t seconds) -{ - if (not m_proto_valid) { - throw std::logic_error("Cannot update time before protocol"); - } - - m_utco = utco; - m_seconds = seconds; - - // TODO check validity - m_time_valid = true; - -} - -void ETIWriter::update_mnsc(uint16_t mnsc) -{ - if (not m_proto_valid) { - throw std::logic_error("Cannot update MNSC before protocol"); - } - - m_mnsc = mnsc; -} - -void ETIWriter::update_rfu(uint16_t rfu) -{ - if (not m_proto_valid) { - throw std::logic_error("Cannot update RFU before protocol"); - } - - m_rfu = rfu; -} - -void ETIWriter::add_subchannel(const eti_stc_data& stc) -{ - if (not m_proto_valid) { - throw std::logic_error("Cannot add subchannel before protocol"); - } - - m_subchannels.push_back(stc); - - if (m_subchannels.size() > 64) { - throw std::invalid_argument("Too many subchannels"); - } - -} - -void ETIWriter::assemble() -{ - if (not m_proto_valid) { - throw std::logic_error("Cannot assemble ETI before protocol"); - } - - if (not m_fc_valid) { - throw std::logic_error("Cannot assemble ETI without FC"); - } - - if (m_fic.empty()) { - throw std::logic_error("Cannot assemble ETI without FIC data"); - } - - // Accept zero subchannels, because of an edge-case that can happen - // during reconfiguration. See ETS 300 799 Clause 5.3.3 - - // TODO check time validity - - // ETS 300 799 Clause 5.3.2, but we don't support not having - // a FIC - if ( (m_fc.mid == 3 and m_fic.size() != 32 * 4) or - (m_fc.mid != 3 and m_fic.size() != 24 * 4) ) { - stringstream ss; - ss << "Invalid FIC length " << m_fic.size() << - " for MID " << m_fc.mid; - throw std::invalid_argument(ss.str()); - } - - - std::vector eti; - eti.reserve(6144); - - eti.push_back(m_err); - - // FSYNC - if (m_fc.fct() % 2 == 1) { - eti.push_back(0xf8); - eti.push_back(0xc5); - eti.push_back(0x49); - } - else { - eti.push_back(0x07); - eti.push_back(0x3a); - eti.push_back(0xb6); - } - - // LIDATA - // FC - eti.push_back(m_fc.fct()); - - const uint8_t NST = m_subchannels.size(); - - eti.push_back((m_fc.ficf << 7) | NST); - - // We need to pack: - // FP 3 bits - // MID 2 bits - // FL 11 bits - - // FL: EN 300 799 5.3.6 - uint16_t FL = NST + 1 + m_fic.size(); - for (const auto& subch : m_subchannels) { - FL += subch.mst.size(); - } - - const uint16_t fp_mid_fl = (m_fc.fp << 13) | (m_fc.mid << 11) | FL; - - eti.push_back(fp_mid_fl >> 8); - eti.push_back(fp_mid_fl & 0xFF); - - // STC - for (const auto& subch : m_subchannels) { - eti.push_back( (subch.scid << 2) | (subch.sad & 0x300) ); - eti.push_back( subch.sad & 0xff ); - eti.push_back( (subch.tpl << 2) | ((subch.stl() & 0x300) >> 8) ); - eti.push_back( subch.stl() & 0xff ); - } - - // EOH - // MNSC - eti.push_back(m_mnsc >> 8); - eti.push_back(m_mnsc & 0xFF); - - // CRC - // Calculate CRC from eti[4] to current position - uint16_t eti_crc = 0xFFFF; - eti_crc = crc16(eti_crc, &eti[4], eti.size() - 4); - eti_crc ^= 0xffff; - eti.push_back(eti_crc >> 8); - eti.push_back(eti_crc & 0xFF); - - const size_t mst_start = eti.size(); - // MST - // FIC data - copy(m_fic.begin(), m_fic.end(), back_inserter(eti)); - - // Data stream - for (const auto& subch : m_subchannels) { - copy(subch.mst.begin(), subch.mst.end(), back_inserter(eti)); - } - - // EOF - // CRC - uint16_t mst_crc = 0xFFFF; - mst_crc = crc16(mst_crc, &eti[mst_start], eti.size() - mst_start); - mst_crc ^= 0xffff; - eti.push_back(mst_crc >> 8); - eti.push_back(mst_crc & 0xFF); - - // RFU - eti.push_back(m_rfu >> 8); - eti.push_back(m_rfu); - - // TIST - eti.push_back(m_fc.tsta >> 24); - eti.push_back((m_fc.tsta >> 16) & 0xFF); - eti.push_back((m_fc.tsta >> 8) & 0xFF); - eti.push_back(m_fc.tsta & 0xFF); - - if (eti.size() > 6144) { - throw std::logic_error("ETI frame cannot be longer than 6144"); - } - - eti.resize(6144, 0x55); - - m_etiFrame = eti; - -} - -std::vector ETIWriter::getEtiFrame() -{ - if (m_etiFrame.empty()) { - return {}; - } - - vector eti(move(m_etiFrame)); - reinit(); - - return eti; -} - -} - -- cgit v1.2.3