From c97b43fc819e1e0e963183579d1b50f26f8c6f7f Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 2 Oct 2016 15:36:21 +0200 Subject: Regroup linkagesets into subsets of same type --- src/ConfigParser.cpp | 6 +++--- src/MuxElements.cpp | 33 ++++++++++++++++++++++------ src/MuxElements.h | 37 +++++++++++++++++++------------ src/fig/FIG0_6.cpp | 61 +++++++++++++++++++++++++++++++++++++--------------- src/fig/FIG0_6.h | 19 +++++++++++++--- src/utils.cpp | 16 ++++++++------ 6 files changed, 121 insertions(+), 51 deletions(-) (limited to 'src') 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(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 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 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 -#include +#include #include #include "fig/FIG0structs.h" @@ -58,7 +58,20 @@ class FIG0_6 : public IFIG private: FIGRuntimeInformation *m_rti; bool m_initialised; - std::list >::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 linkageSubsets; + std::list::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 >::iterator linkageSetFIG0_6; + std::vector >::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 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 ensemble) break; } etiLog.log(info, " id 0x%04x", link.id); - if (linkageset->international) { + if (lsd.international) { etiLog.log(info, " ecc 0x%04x", link.ecc); } } -- cgit v1.2.3