aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2017-06-05 17:51:47 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2017-06-05 17:51:47 +0200
commitf1832dd977078a60b343673c60092d3d5d030398 (patch)
treec1d585a637a24732507b0b6f94ebe5151fb493c2
parent7378fc903a26f779c48114e6305a89e59a3285d6 (diff)
downloaddabmux-f1832dd977078a60b343673c60092d3d5d030398.tar.gz
dabmux-f1832dd977078a60b343673c60092d3d5d030398.tar.bz2
dabmux-f1832dd977078a60b343673c60092d3d5d030398.zip
Add initial implementation for FIG0/24
-rw-r--r--doc/servicelinking.mux5
-rw-r--r--src/ConfigParser.cpp24
-rw-r--r--src/Makefile.am1
-rw-r--r--src/MuxElements.h3
-rw-r--r--src/fig/FIG0.h1
-rw-r--r--src/fig/FIG0_24.cpp177
-rw-r--r--src/fig/FIG0_24.h53
-rw-r--r--src/fig/FIGCarousel.cpp6
-rw-r--r--src/fig/FIGCarousel.h3
9 files changed, 270 insertions, 3 deletions
diff --git a/doc/servicelinking.mux b/doc/servicelinking.mux
index 6c491c8..03c842a 100644
--- a/doc/servicelinking.mux
+++ b/doc/servicelinking.mux
@@ -160,6 +160,11 @@ services {
srv-fu {
id 0x8daa
label "Funk"
+
+ ; If this service is present in other ensembles, it can be announced
+ ; through FIG0/24. other_ensembles is a comma separated list of
+ ; ensemble IDs (decimal or hexadecimal with 0x prefix)
+ other_ensembles "0x4ffe,0x4ffd"
}
srv-ri {
id 0x8dab
diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp
index 8c7e6b4..3f977ad 100644
--- a/src/ConfigParser.cpp
+++ b/src/ConfigParser.cpp
@@ -511,6 +511,30 @@ void parse_ptree(
serviceuid;
}
+ try {
+ auto oelist = pt_service.get<std::string>("other_ensembles", "");
+ vector<string> oe_string_list;
+ boost::split(oe_string_list, oelist, boost::is_any_of(","));
+
+ for (const auto& oe_string : oe_string_list) {
+ if (oe_string == "") {
+ continue;
+ }
+ try {
+ service->other_ensembles.push_back(hexparse(oe_string));
+ }
+ catch (std::logic_error& e) {
+ etiLog.level(warn) << "Cannot parse '" << oelist <<
+ "' announcement clusters for service " << serviceuid <<
+ ": " << e.what();
+ }
+ }
+ }
+ catch (ptree_error& e) {
+ etiLog.level(info) << "No other_sensmbles information for Service " <<
+ serviceuid;
+ }
+
int success = -5;
string servicelabel = pt_service.get<string>("label");
diff --git a/src/Makefile.am b/src/Makefile.am
index 4ee8792..12934f0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -96,6 +96,7 @@ odr_dabmux_SOURCES =DabMux.cpp DabMux.h \
fig/FIG0_18.cpp fig/FIG0_18.h \
fig/FIG0_19.cpp fig/FIG0_19.h \
fig/FIG0_21.cpp fig/FIG0_21.h \
+ fig/FIG0_24.cpp fig/FIG0_24.h \
fig/FIG1.cpp fig/FIG1.h \
fig/FIGCarousel.cpp fig/FIGCarousel.h \
fig/TransitionHandler.h \
diff --git a/src/MuxElements.h b/src/MuxElements.h
index 7f1b828..6a1ca74 100644
--- a/src/MuxElements.h
+++ b/src/MuxElements.h
@@ -406,6 +406,9 @@ class DabService : public RemoteControllable
uint16_t ASu = 0;
std::vector<uint8_t> clusters;
+ // Ensembles in which this service is also available, used for FIG0/24
+ std::vector<uint16_t> other_ensembles;
+
subchannel_type_t getType(const std::shared_ptr<dabEnsemble> ensemble) const;
bool isProgramme(const std::shared_ptr<dabEnsemble>& ensemble) const;
unsigned char nbComponent(const std::vector<DabComponent*>& components) const;
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..af3f043
--- /dev/null
+++ b/src/fig/FIG0_24.cpp
@@ -0,0 +1,177 @@
+/*
+ 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"
+
+#warning "fig0/24 rate"
+
+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 debug
+ 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;
+ fig0->CN = 0;
+ fig0->OE = 0;
+ fig0->PD = isProgramme ? 0 : 1;
+ fig0->Extension = 2;
+ 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..0faa3b9
--- /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::A; }
+
+ 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