summaryrefslogtreecommitdiffstats
path: root/src/fig/FIG0_6.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/fig/FIG0_6.cpp')
-rw-r--r--src/fig/FIG0_6.cpp204
1 files changed, 204 insertions, 0 deletions
diff --git a/src/fig/FIG0_6.cpp b/src/fig/FIG0_6.cpp
new file mode 100644
index 0000000..f404a47
--- /dev/null
+++ b/src/fig/FIG0_6.cpp
@@ -0,0 +1,204 @@
+/*
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2011, 2012 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+
+ Copyright (C) 2016
+ Matthias P. Braendli, matthias.braendli@mpb.li
+ */
+/*
+ This file is part of ODR-DabMux.
+
+ ODR-DabMux 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 3 of the
+ License, or (at your option) any later version.
+
+ ODR-DabMux 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 ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "fig/FIG0_6.h"
+#include "utils.h"
+
+namespace FIC {
+
+FIG0_6::FIG0_6(FIGRuntimeInformation *rti) :
+ m_rti(rti),
+ m_initialised(false)
+{
+}
+
+FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
+{
+ FillStatus fs;
+ ssize_t remaining = max_size;
+ auto ensemble = m_rti->ensemble;
+
+ if (not m_initialised) {
+ linkageSetFIG0_6 = m_rti->ensemble->linkagesets.end();
+ m_initialised = true;
+ }
+
+ FIGtype0* fig0 = NULL;
+
+ for (; linkageSetFIG0_6 != ensemble->linkagesets.end();
+ ++linkageSetFIG0_6) {
+
+ const bool PD = false;
+ const bool ILS = (*linkageSetFIG0_6)->international;
+
+ // need to add key service to num_ids
+ const size_t num_ids = 1 + (*linkageSetFIG0_6)->id_list.size();
+
+ const size_t headersize = sizeof(struct FIGtype0_6_header);
+ const int required_size = sizeof(struct FIGtype0_6) +
+ (num_ids > 0 ?
+ headersize + (PD == 0 ? (ILS == 0 ? 2*num_ids : 3*num_ids) : 4*num_ids) :
+ 0);
+
+ if (fig0 == NULL) {
+ if (remaining < 2 + required_size) {
+ break;
+ }
+ fig0 = (FIGtype0*)buf;
+ fig0->FIGtypeNumber = 0;
+ fig0->Length = 1;
+ fig0->CN = 0;
+ fig0->OE = 0;
+ fig0->PD = PD;
+ fig0->Extension = 5;
+
+ buf += 2;
+ remaining -= 2;
+ }
+ else if (remaining < required_size) {
+ break;
+ }
+
+ FIGtype0_6 *fig0_6 = (FIGtype0_6*)buf;
+
+ fig0_6->IdListFlag = (num_ids > 0);
+ fig0_6->LA = (*linkageSetFIG0_6)->active;
+ fig0_6->SH = (*linkageSetFIG0_6)->hard;
+ fig0_6->ILS = ILS;
+ fig0_6->LSN = (*linkageSetFIG0_6)->lsn;
+
+ fig0->Length += sizeof(struct FIGtype0_6);
+ buf += sizeof(struct FIGtype0_6);
+ remaining -= sizeof(struct FIGtype0_6);
+
+ if (num_ids > 0) {
+ FIGtype0_6_header *header = (FIGtype0_6_header*)buf;
+ header->rfu = 0;
+ if (num_ids > 0x0F) {
+ etiLog.log(error, "Too large number of links for linkage set 0x%04x",
+ (*linkageSetFIG0_6)->lsn);
+ throw MuxInitException();
+ }
+
+ header->IdLQ = 0; // TODO not only DAB
+ header->rfa = 0;
+ header->num_ids = num_ids;
+
+ fig0->Length += headersize;
+ buf += headersize;
+ remaining -= headersize;
+
+ // TODO insert key service first
+ const std::string keyserviceuid =(*linkageSetFIG0_6)->keyservice;
+ const auto& keyservice = std::find_if(
+ ensemble->services.begin(),
+ ensemble->services.end(),
+ [&](const std::shared_ptr<DabService> srv) {
+ return srv->uid == keyserviceuid;
+ });
+
+ if (keyservice == ensemble->services.end()) {
+ etiLog.log(error, "Invalid key service %s in linkage set 0x%04x",
+ keyserviceuid.c_str(), (*linkageSetFIG0_6)->lsn);
+ throw MuxInitException();
+ }
+ for (const auto& l : (*linkageSetFIG0_6)->id_list) {
+ if (l.type != ServiceLinkType::DAB) {
+ etiLog.log(error, "TODO only DAB links supported. (linkage set 0x%04x)",
+ (*linkageSetFIG0_6)->lsn);
+ throw MuxInitException();
+ }
+ }
+
+ if (not PD and not ILS) {
+ buf[0] = (*keyservice)->id >> 8;
+ buf[1] = (*keyservice)->id & 0xFF;
+ fig0->Length += 2;
+ buf += 2;
+ remaining -= 2;
+
+ for (const auto& l : (*linkageSetFIG0_6)->id_list) {
+ buf[0] = l.id >> 8;
+ buf[1] = l.id & 0xFF;
+ fig0->Length += 2;
+ buf += 2;
+ remaining -= 2;
+ }
+ }
+ if (not PD and ILS) {
+ buf[0] = ensemble->ecc;
+ buf[1] = (*keyservice)->id >> 8;
+ buf[2] = (*keyservice)->id & 0xFF;
+ fig0->Length += 3;
+ buf += 3;
+ remaining -= 3;
+
+ for (const auto& l : (*linkageSetFIG0_6)->id_list) {
+ buf[0] = l.ecc;
+ buf[1] = l.id >> 8;
+ buf[2] = l.id & 0xFF;
+ fig0->Length += 3;
+ buf += 3;
+ remaining -= 3;
+ }
+ }
+ else { // PD == true
+ // TODO if IdLQ is 11, MSB shall be zero
+ buf[0] = (*keyservice)->id >> 24;
+ buf[1] = (*keyservice)->id >> 16;
+ buf[2] = (*keyservice)->id >> 8;
+ buf[3] = (*keyservice)->id & 0xFF;
+ fig0->Length += 4;
+ buf += 4;
+ remaining -= 4;
+
+ for (const auto& l : (*linkageSetFIG0_6)->id_list) {
+ buf[0] = l.id >> 24;
+ buf[1] = l.id >> 16;
+ buf[2] = l.id >> 8;
+ buf[3] = l.id & 0xFF;
+ fig0->Length += 4;
+ buf += 4;
+ remaining -= 4;
+ }
+ }
+ }
+
+ fig0->Length += required_size;
+ buf += required_size;
+ remaining -= required_size;
+ }
+
+ if (linkageSetFIG0_6 == ensemble->linkagesets.end()) {
+ linkageSetFIG0_6 = ensemble->linkagesets.begin();
+ fs.complete_fig_transmitted = true;
+ }
+
+ fs.num_bytes_written = max_size - remaining;
+ return fs;
+}
+
+}
+