summaryrefslogtreecommitdiffstats
path: root/src/fig
diff options
context:
space:
mode:
Diffstat (limited to 'src/fig')
-rw-r--r--src/fig/FIG0.h1
-rw-r--r--src/fig/FIG0_24.cpp184
-rw-r--r--src/fig/FIG0_24.h53
-rw-r--r--src/fig/FIGCarousel.cpp6
-rw-r--r--src/fig/FIGCarousel.h3
5 files changed, 244 insertions, 3 deletions
diff --git a/src/fig/FIG0.h b/src/fig/FIG0.h
index d8de751..856b5ee 100644
--- a/src/fig/FIG0.h
+++ b/src/fig/FIG0.h
@@ -40,4 +40,5 @@
#include "fig/FIG0_18.h"
#include "fig/FIG0_19.h"
#include "fig/FIG0_21.h"
+#include "fig/FIG0_24.h"
diff --git a/src/fig/FIG0_24.cpp b/src/fig/FIG0_24.cpp
new file mode 100644
index 0000000..a790440
--- /dev/null
+++ b/src/fig/FIG0_24.cpp
@@ -0,0 +1,184 @@
+/*
+ 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) 2017
+ 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/FIG0structs.h"
+#include "fig/FIG0_24.h"
+#include "utils.h"
+
+/* FIG0/24 allows us to announce if a service is available in another ensemble.
+ * Things we do not support:
+ *
+ * - The CEI using length=0, because this information is not available in the
+ * remote control, and there is no runtime changes.
+ * - Announcing information about other ensembles (OE=1)
+ */
+
+namespace FIC {
+
+struct FIGtype0_24_audioservice {
+ uint16_t SId;
+ uint8_t Length:4;
+ uint8_t CAId:3;
+ uint8_t rfa:1;
+} PACKED;
+
+struct FIGtype0_24_dataservice {
+ uint32_t SId;
+ uint8_t Length:4;
+ uint8_t CAId:3;
+ uint8_t rfa:1;
+} PACKED;
+
+
+FIG0_24::FIG0_24(FIGRuntimeInformation *rti) :
+ m_rti(rti),
+ m_initialised(false),
+ m_inserting_audio_not_data(false)
+{
+}
+
+FillStatus FIG0_24::fill(uint8_t *buf, size_t max_size)
+{
+#define FIG0_24_TRACE discard
+ using namespace std;
+
+ FillStatus fs;
+ FIGtype0* fig0 = nullptr;
+ ssize_t remaining = max_size;
+
+ const auto ensemble = m_rti->ensemble;
+
+ etiLog.level(FIG0_24_TRACE) << "FIG0_24::fill init " << (m_initialised ? 1 : 0) <<
+ " ********************************";
+
+ if (not m_initialised) {
+ serviceFIG0_24 = ensemble->services.begin();
+ m_initialised = true;
+ }
+
+ const auto last_service = ensemble->services.end();
+
+ // Rotate through the subchannels until there is no more
+ // space
+ for (; serviceFIG0_24 != last_service; ++serviceFIG0_24) {
+ const auto type = (*serviceFIG0_24)->getType(ensemble);
+ const auto isProgramme = (*serviceFIG0_24)->isProgramme(ensemble);
+
+ etiLog.log(FIG0_24_TRACE, "FIG0_24::fill loop SId=%04x %s/%s",
+ (*serviceFIG0_24)->id,
+ m_inserting_audio_not_data ? "AUDIO" : "DATA",
+ type == subchannel_type_t::Audio ? "Audio" :
+ type == subchannel_type_t::Packet ? "Packet" :
+ type == subchannel_type_t::DataDmb ? "DataDmb" :
+ type == subchannel_type_t::Fidc ? "Fidc" : "?");
+
+ // Skip services that are not in other ensembles
+ if ((*serviceFIG0_24)->other_ensembles.empty()) {
+ continue;
+ }
+
+ const ssize_t required_size =
+ (isProgramme ? 2 : 4) + 1 +
+ (*serviceFIG0_24)->other_ensembles.size() * 2;
+
+
+ if (fig0 == nullptr) {
+ etiLog.level(FIG0_24_TRACE) << "FIG0_24::fill header";
+ if (remaining < 2 + required_size) {
+ etiLog.level(FIG0_24_TRACE) << "FIG0_24::fill header no place" <<
+ " rem=" << remaining << " req=" << 2 + required_size;
+ break;
+ }
+ fig0 = (FIGtype0*)buf;
+
+ fig0->FIGtypeNumber = 0;
+ fig0->Length = 1;
+ // CN according to ETSI TS 103 176, Clause 5.3.4.1
+ fig0->CN = (serviceFIG0_24 == ensemble->services.begin() ? 0 : 1);
+ fig0->OE = 0;
+ fig0->PD = isProgramme ? 0 : 1;
+ fig0->Extension = 24;
+ buf += 2;
+ remaining -= 2;
+ }
+ else if (remaining < required_size) {
+ etiLog.level(FIG0_24_TRACE) << "FIG0_24::fill no place" <<
+ " rem=" << remaining << " req=" << required_size;
+ break;
+ }
+
+ if (type == subchannel_type_t::Audio) {
+ auto fig0_2serviceAudio = (FIGtype0_24_audioservice*)buf;
+
+ fig0_2serviceAudio->SId = htons((*serviceFIG0_24)->id);
+ fig0_2serviceAudio->rfa = 0;
+ fig0_2serviceAudio->CAId = 0;
+ fig0_2serviceAudio->Length = (*serviceFIG0_24)->other_ensembles.size();
+ buf += 3;
+ fig0->Length += 3;
+ remaining -= 3;
+
+ etiLog.log(FIG0_24_TRACE, "FIG0_24::fill audio SId=%04x",
+ (*serviceFIG0_24)->id);
+ }
+ else {
+ auto fig0_2serviceData = (FIGtype0_24_dataservice*)buf;
+
+ fig0_2serviceData->SId = htonl((*serviceFIG0_24)->id);
+ fig0_2serviceData->rfa = 0;
+ fig0_2serviceData->CAId = 0;
+ fig0_2serviceData->Length = (*serviceFIG0_24)->other_ensembles.size();
+ buf += 4;
+ fig0->Length += 4;
+ remaining -= 4;
+
+ etiLog.log(FIG0_24_TRACE, "FIG0_24::fill data SId=%04x",
+ (*serviceFIG0_24)->id);
+ }
+
+ for (const uint16_t oe : (*serviceFIG0_24)->other_ensembles) {
+ buf[0] = oe >> 8;
+ buf[1] = oe & 0xFF;
+
+ buf += 2;
+ fig0->Length += 2;
+ remaining -= 2;
+ }
+ }
+
+ if (serviceFIG0_24 == last_service) {
+ etiLog.log(FIG0_24_TRACE, "FIG0_24::loop reached last");
+ fs.complete_fig_transmitted = true;
+ m_initialised = false;
+ }
+
+ etiLog.log(FIG0_24_TRACE, "FIG0_24::loop end complete=%d",
+ fs.complete_fig_transmitted ? 1 : 0);
+
+ fs.num_bytes_written = max_size - remaining;
+ return fs;
+}
+
+}
diff --git a/src/fig/FIG0_24.h b/src/fig/FIG0_24.h
new file mode 100644
index 0000000..4ccbd0c
--- /dev/null
+++ b/src/fig/FIG0_24.h
@@ -0,0 +1,53 @@
+/*
+ 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) 2017
+ 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/>.
+*/
+
+#pragma once
+
+#include <cstdint>
+#include <vector>
+#include "FIG.h"
+
+namespace FIC {
+/* The OE Services feature is used to identify the services currently carried
+ * in other DAB ensembles.
+ */
+class FIG0_24 : public IFIG
+{
+ public:
+ FIG0_24(FIGRuntimeInformation* rti);
+ virtual FillStatus fill(uint8_t *buf, size_t max_size);
+ virtual FIG_rate repetition_rate(void) { return FIG_rate::E; }
+
+ virtual const int figtype(void) const { return 0; }
+ virtual const int figextension(void) const { return 24; }
+
+ private:
+ FIGRuntimeInformation *m_rti;
+ bool m_initialised;
+ bool m_inserting_audio_not_data;
+ std::vector<std::shared_ptr<DabService> >::iterator serviceFIG0_24;
+};
+
+}
diff --git a/src/fig/FIGCarousel.cpp b/src/fig/FIGCarousel.cpp
index 6d89ad8..e32ea39 100644
--- a/src/fig/FIGCarousel.cpp
+++ b/src/fig/FIGCarousel.cpp
@@ -3,7 +3,7 @@
2011, 2012 Her Majesty the Queen in Right of Canada (Communications
Research Center Canada)
- Copyright (C) 2016
+ Copyright (C) 2017
Matthias P. Braendli, matthias.braendli@mpb.li
Implementation of the FIG carousel to schedule the FIGs into the
@@ -76,7 +76,8 @@ FIGCarousel::FIGCarousel(std::shared_ptr<dabEnsemble> ensemble) :
m_fig1_5(&m_rti),
m_fig0_18(&m_rti),
m_fig0_19(&m_rti),
- m_fig0_21(&m_rti)
+ m_fig0_21(&m_rti),
+ m_fig0_24(&m_rti)
{
/* Complete MCI except FIG0/8 should be in FIB0.
* EN 300 401 V1.4.1 Clause 6.1
@@ -111,6 +112,7 @@ FIGCarousel::FIGCarousel(std::shared_ptr<dabEnsemble> ensemble) :
load_and_allocate(m_fig0_18, FIBAllocation::FIB_ANY);
load_and_allocate(m_fig0_19, FIBAllocation::FIB_ANY);
load_and_allocate(m_fig0_21, FIBAllocation::FIB_ANY);
+ load_and_allocate(m_fig0_24, FIBAllocation::FIB_ANY);
}
void FIGCarousel::load_and_allocate(IFIG& fig, FIBAllocation fib)
diff --git a/src/fig/FIGCarousel.h b/src/fig/FIGCarousel.h
index ec1611d..5e102ad 100644
--- a/src/fig/FIGCarousel.h
+++ b/src/fig/FIGCarousel.h
@@ -3,7 +3,7 @@
2011, 2012 Her Majesty the Queen in Right of Canada (Communications
Research Center Canada)
- Copyright (C) 2016
+ Copyright (C) 2017
Matthias P. Braendli, matthias.braendli@mpb.li
Implementation of the FIG carousel to schedule the FIGs into the
@@ -102,6 +102,7 @@ class FIGCarousel {
FIG0_18 m_fig0_18;
FIG0_19 m_fig0_19;
FIG0_21 m_fig0_21;
+ FIG0_24 m_fig0_24;
};
} // namespace FIC