aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ConfigParser.cpp6
-rw-r--r--src/MuxElements.cpp33
-rw-r--r--src/MuxElements.h37
-rw-r--r--src/fig/FIG0_6.cpp61
-rw-r--r--src/fig/FIG0_6.h19
-rw-r--r--src/utils.cpp16
6 files changed, 121 insertions, 51 deletions
diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp
index 2ca83d3..cb458d7 100644
--- a/src/ConfigParser.cpp
+++ b/src/ConfigParser.cpp
@@ -177,8 +177,8 @@ void parse_linkage(boost::property_tree::ptree& pt,
}
auto linkageset = make_shared<LinkageSet>(setuid, lsn, hard, international);
- linkageset->active = active;
- linkageset->keyservice = service_uid; // TODO check if it exists
+ linkageset->data.active = active;
+ linkageset->data.keyservice = service_uid; // TODO check if it exists
auto pt_list = pt_set.get_child_optional("list");
if (not pt_list) {
@@ -223,7 +223,7 @@ void parse_linkage(boost::property_tree::ptree& pt,
link.ecc = 0;
}
- linkageset->id_list.push_back(link);
+ linkageset->data.id_list.push_back(link);
}
ensemble->linkagesets.push_back(linkageset);
}
diff --git a/src/MuxElements.cpp b/src/MuxElements.cpp
index 656e294..510775e 100644
--- a/src/MuxElements.cpp
+++ b/src/MuxElements.cpp
@@ -663,12 +663,12 @@ unsigned short DabSubchannel::getSizeDWord(void) const
}
LinkageSet::LinkageSet(string name, uint16_t lsn, bool hard, bool international) :
- RemoteControllable(name),
- lsn(lsn),
- active(false),
- hard(hard),
- international(international)
+ RemoteControllable(name)
{
+ data.lsn = lsn;
+ data.active = false;
+ data.hard = hard;
+ data.international = international;
RC_ADD_PARAMETER(active, "Activate this linkage set [0 or 1]");
}
@@ -677,7 +677,7 @@ void LinkageSet::set_parameter(const string& parameter, const string& value)
if (parameter == "active") {
stringstream ss;
ss << value;
- ss >> active;
+ ss >> data.active;
}
else {
stringstream ss;
@@ -691,7 +691,7 @@ const string LinkageSet::get_parameter(const string& parameter) const
{
stringstream ss;
if (parameter == "active") {
- ss << active;
+ ss << data.active;
}
else {
ss << "Parameter '" << parameter <<
@@ -700,3 +700,22 @@ const string LinkageSet::get_parameter(const string& parameter) const
}
return ss.str();
}
+
+LinkageSetData LinkageSetData::filter_type(ServiceLinkType type)
+{
+ LinkageSetData lsd;
+
+ lsd.lsn = lsn;
+ lsd.active = active;
+ lsd.hard = hard;
+ lsd.international = international;
+ lsd.keyservice = keyservice;
+
+ for (const auto& link : id_list) {
+ if (link.type == type) {
+ lsd.id_list.push_back(link);
+ }
+ }
+
+ return lsd;
+}
diff --git a/src/MuxElements.h b/src/MuxElements.h
index 2f602ba..8efc2cb 100644
--- a/src/MuxElements.h
+++ b/src/MuxElements.h
@@ -432,6 +432,28 @@ struct ServiceLink {
uint8_t ecc;
};
+/* Keep the data out of LinkageSet to make it copyable */
+struct LinkageSetData {
+ std::list<ServiceLink> id_list;
+
+ /* Linkage Set Number is a 12-bit number that identifies the linkage
+ * set in a country (requires coordination between multiplex operators
+ * in a country)
+ */
+ uint16_t lsn;
+
+ bool active; // Remote-controllable
+ bool hard;
+ bool international;
+
+ std::string keyservice; // TODO replace by pointer to service
+
+ /* Return a LinkageSetData with id_list filtered to include
+ * only those links of a given type
+ */
+ LinkageSetData filter_type(ServiceLinkType type);
+};
+
/* Represents a linkage set linkage sets according to
* TS 103 176 Clause 5.2.3 "Linkage sets". This information will
* be encoded in FIG 0/6.
@@ -440,20 +462,7 @@ class LinkageSet : public RemoteControllable {
public:
LinkageSet(std::string name, uint16_t lsn, bool hard, bool international);
- std::list<ServiceLink> id_list;
-
- /* Linkage Set Number is a 12-bit number that identifies the linkage
- * set in a country (requires coordination between multiplex operators
- * in a country)
- */
- uint16_t lsn;
-
- bool active; // Remote-controllable
- bool hard;
- bool international;
-
- std::string keyservice; // TODO replace by pointer to service
-
+ LinkageSetData data;
private:
/* Remote control */
virtual void set_parameter(const std::string& parameter,
diff --git a/src/fig/FIG0_6.cpp b/src/fig/FIG0_6.cpp
index f404a47..8c0e53d 100644
--- a/src/fig/FIG0_6.cpp
+++ b/src/fig/FIG0_6.cpp
@@ -40,21 +40,23 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
ssize_t remaining = max_size;
auto ensemble = m_rti->ensemble;
+ update();
+
if (not m_initialised) {
- linkageSetFIG0_6 = m_rti->ensemble->linkagesets.end();
+ linkageSetFIG0_6 = linkageSubsets.begin();
m_initialised = true;
}
FIGtype0* fig0 = NULL;
- for (; linkageSetFIG0_6 != ensemble->linkagesets.end();
+ for (; linkageSetFIG0_6 != linkageSubsets.end();
++linkageSetFIG0_6) {
const bool PD = false;
- const bool ILS = (*linkageSetFIG0_6)->international;
+ 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 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) +
@@ -84,10 +86,10 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
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->LA = linkageSetFIG0_6->active;
+ fig0_6->SH = linkageSetFIG0_6->hard;
fig0_6->ILS = ILS;
- fig0_6->LSN = (*linkageSetFIG0_6)->lsn;
+ fig0_6->LSN = linkageSetFIG0_6->lsn;
fig0->Length += sizeof(struct FIGtype0_6);
buf += sizeof(struct FIGtype0_6);
@@ -98,7 +100,7 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
header->rfu = 0;
if (num_ids > 0x0F) {
etiLog.log(error, "Too large number of links for linkage set 0x%04x",
- (*linkageSetFIG0_6)->lsn);
+ linkageSetFIG0_6->lsn);
throw MuxInitException();
}
@@ -111,7 +113,7 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
remaining -= headersize;
// TODO insert key service first
- const std::string keyserviceuid =(*linkageSetFIG0_6)->keyservice;
+ const std::string keyserviceuid = linkageSetFIG0_6->keyservice;
const auto& keyservice = std::find_if(
ensemble->services.begin(),
ensemble->services.end(),
@@ -121,13 +123,13 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
if (keyservice == ensemble->services.end()) {
etiLog.log(error, "Invalid key service %s in linkage set 0x%04x",
- keyserviceuid.c_str(), (*linkageSetFIG0_6)->lsn);
+ keyserviceuid.c_str(), linkageSetFIG0_6->lsn);
throw MuxInitException();
}
- for (const auto& l : (*linkageSetFIG0_6)->id_list) {
+ 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);
+ linkageSetFIG0_6->lsn);
throw MuxInitException();
}
}
@@ -139,7 +141,7 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
buf += 2;
remaining -= 2;
- for (const auto& l : (*linkageSetFIG0_6)->id_list) {
+ for (const auto& l : linkageSetFIG0_6->id_list) {
buf[0] = l.id >> 8;
buf[1] = l.id & 0xFF;
fig0->Length += 2;
@@ -155,7 +157,7 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
buf += 3;
remaining -= 3;
- for (const auto& l : (*linkageSetFIG0_6)->id_list) {
+ for (const auto& l : linkageSetFIG0_6->id_list) {
buf[0] = l.ecc;
buf[1] = l.id >> 8;
buf[2] = l.id & 0xFF;
@@ -174,7 +176,7 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
buf += 4;
remaining -= 4;
- for (const auto& l : (*linkageSetFIG0_6)->id_list) {
+ for (const auto& l : linkageSetFIG0_6->id_list) {
buf[0] = l.id >> 24;
buf[1] = l.id >> 16;
buf[2] = l.id >> 8;
@@ -191,8 +193,8 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
remaining -= required_size;
}
- if (linkageSetFIG0_6 == ensemble->linkagesets.end()) {
- linkageSetFIG0_6 = ensemble->linkagesets.begin();
+ if (linkageSetFIG0_6 == linkageSubsets.end()) {
+ linkageSetFIG0_6 = linkageSubsets.begin();
fs.complete_fig_transmitted = true;
}
@@ -200,5 +202,30 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
return fs;
}
+void FIG0_6::update()
+{
+ linkageSubsets.clear();
+
+ for (const auto& linkageset : m_rti->ensemble->linkagesets) {
+ const auto lsn = linkageset->data.lsn;
+
+ for (const auto& link : linkageset->data.id_list) {
+ const auto type = link.type;
+
+ const auto subset =
+ std::find_if(linkageSubsets.begin(), linkageSubsets.end(),
+ [&](const LinkageSetData& l) {
+ return not l.id_list.empty() and
+ l.lsn == lsn and l.id_list.front().type == type;
+ });
+
+ if (subset == linkageSubsets.end()) {
+ // A subset with that LSN and type does not exist yet
+ linkageSubsets.push_back( linkageset->data.filter_type(type) );
+ }
+ }
+ }
+}
+
}
diff --git a/src/fig/FIG0_6.h b/src/fig/FIG0_6.h
index db55c06..1af396f 100644
--- a/src/fig/FIG0_6.h
+++ b/src/fig/FIG0_6.h
@@ -26,7 +26,7 @@
#pragma once
#include <cstdint>
-#include <list>
+#include <vector>
#include <memory>
#include "fig/FIG0structs.h"
@@ -58,7 +58,20 @@ class FIG0_6 : public IFIG
private:
FIGRuntimeInformation *m_rti;
bool m_initialised;
- std::list<std::shared_ptr<LinkageSet> >::iterator linkageSetFIG0_6;
+
+ /* Update the linkageSubsets */
+ void update(void);
+
+ /* A LinkageSet can contain links of different types
+ * (DAB, FM, DRM, AMSS), but the FIG needs to send
+ * different FIGs for each of those, because the IdLQ flag
+ * is common to a list.
+ *
+ * We reorganise all LinkageSets into subsets that have
+ * the same type.
+ */
+ std::list<LinkageSetData> linkageSubsets;
+ std::list<LinkageSetData>::iterator linkageSetFIG0_6;
};
// FIG0/6 needs a change indicator, which is a short-form FIG (i.e. without the list)
@@ -79,7 +92,7 @@ class FIG0_6_CEI : public IFIG
private:
FIGRuntimeInformation *m_rti;
bool m_initialised;
- std::list<std::shared_ptr<LinkageSet> >::iterator linkageSetFIG0_6;
+ std::vector<std::shared_ptr<LinkageSet> >::iterator linkageSetFIG0_6;
};
}
diff --git a/src/utils.cpp b/src/utils.cpp
index baf15d5..94268da 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -556,15 +556,17 @@ static void printLinking(const shared_ptr<dabEnsemble> ensemble)
{
etiLog.log(info, " Linkage Sets");
for (const auto& linkageset : ensemble->linkagesets) {
+ const auto& lsd = linkageset->data;
+
etiLog.level(info) << " set " << linkageset->get_rc_name();
- etiLog.log(info, " LSN 0x%04x", linkageset->lsn);
- etiLog.level(info) << " active " << (linkageset->active ? "true" : "false");
- etiLog.level(info) << " " << (linkageset->hard ? "hard" : "soft");
- etiLog.level(info) << " international " << (linkageset->international ? "true" : "false");
- etiLog.level(info) << " key service " << linkageset->keyservice;
+ etiLog.log(info, " LSN 0x%04x", lsd.lsn);
+ etiLog.level(info) << " active " << (lsd.active ? "true" : "false");
+ etiLog.level(info) << " " << (lsd.hard ? "hard" : "soft");
+ etiLog.level(info) << " international " << (lsd.international ? "true" : "false");
+ etiLog.level(info) << " key service " << lsd.keyservice;
etiLog.level(info) << " ID list";
- for (const auto& link : linkageset->id_list) {
+ for (const auto& link : lsd.id_list) {
switch (link.type) {
case ServiceLinkType::DAB:
etiLog.level(info) << " type DAB";
@@ -580,7 +582,7 @@ static void printLinking(const shared_ptr<dabEnsemble> ensemble)
break;
}
etiLog.log(info, " id 0x%04x", link.id);
- if (linkageset->international) {
+ if (lsd.international) {
etiLog.log(info, " ecc 0x%04x", link.ecc);
}
}