diff options
| -rw-r--r-- | src/ConfigParser.cpp | 36 | ||||
| -rw-r--r-- | src/ConfigParser.h | 6 | ||||
| -rw-r--r-- | src/DabMultiplexer.cpp | 53 | ||||
| -rw-r--r-- | src/DabMultiplexer.h | 2 | ||||
| -rw-r--r-- | src/MuxElements.cpp | 28 | ||||
| -rw-r--r-- | src/MuxElements.h | 18 | ||||
| -rw-r--r-- | src/fig/FIG0_21.cpp | 67 | ||||
| -rw-r--r-- | src/fig/FIG0_21.h | 6 | ||||
| -rw-r--r-- | src/fig/FIG0_6.cpp | 2 | ||||
| -rw-r--r-- | src/utils.cpp | 17 | 
10 files changed, 154 insertions, 81 deletions
| diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 2d500b3..efc010f 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -112,7 +112,7 @@ static void parse_fig2_label(ptree& pt, DabLabel& label) {  // Parse the linkage section  void parse_linkage(          const boost::optional<boost::property_tree::ptree&> pt_linking, -        std::vector<std::shared_ptr<LinkageSet> >& linkageSets) +        std::vector<std::shared_ptr<LinkageSet> >& linkage_sets)  {      if (pt_linking) {          for (const auto& it : *pt_linking) { @@ -189,17 +189,17 @@ void parse_linkage(                      linkageset->id_list.push_back(link);                  }              } -            linkageSets.push_back(linkageset); +            linkage_sets.push_back(linkageset);          }      }  }  // Parse the FI section -static void parse_freq_info(ptree& pt, std::shared_ptr<dabEnsemble> ensemble) +void parse_freq_info( +        const boost::optional<boost::property_tree::ptree&> pt_frequency_information, +        std::vector<FrequencyInformation>& frequency_information)  { -    auto pt_frequency_information = pt.get_child_optional("frequency_information"); -    if (pt_frequency_information) -    { +    if (pt_frequency_information) {          for (const auto& it_fi : *pt_frequency_information) {              const string fi_uid = it_fi.first;              const ptree pt_fi = it_fi.second; @@ -312,14 +312,14 @@ static void parse_freq_info(ptree& pt, std::shared_ptr<dabEnsemble> ensemble)                  throw runtime_error("invalid configuration for FI " + fi_uid);              } -            ensemble->frequency_information.emplace_back(move(fi)); +            frequency_information.emplace_back(std::move(fi));          } // for over fi          /* We sort all FI to have the OE=0 first and the OE=1 afterwards, to           * avoid having to send FIG0 headers every time it switches.  */          std::sort( -                ensemble->frequency_information.begin(), -                ensemble->frequency_information.end(), +                frequency_information.begin(), +                frequency_information.end(),                  [](const FrequencyInformation& first,                     const FrequencyInformation& second) {                      const int oe_first = first.other_ensemble ? 1 : 0; @@ -332,9 +332,8 @@ static void parse_freq_info(ptree& pt, std::shared_ptr<dabEnsemble> ensemble)  static void parse_other_service_linking(ptree& pt,          std::shared_ptr<dabEnsemble> ensemble)  { -    auto pt_other_services = pt.get_child_optional("other-services"); -    if (pt_other_services) -    { +    const auto pt_other_services = pt.get_child_optional("other-services"); +    if (pt_other_services) {          for (const auto& it_service : *pt_other_services) {              const string srv_uid = it_service.first;              const ptree pt_srv = it_service.second; @@ -363,7 +362,7 @@ static void parse_other_service_linking(ptree& pt,                          }                      } -                    ensemble->service_other_ensemble.push_back(move(info)); +                    ensemble->service_other_ensemble.push_back(std::move(info));                  }              }              catch (const std::exception &e) { @@ -911,8 +910,15 @@ void parse_ptree(      }      const auto pt_linking = pt.get_child_optional("linking"); -    parse_linkage(pt_linking, ensemble->linkagesets); -    parse_freq_info(pt, ensemble); +    std::vector<std::shared_ptr<LinkageSet> > linkagesets; +    parse_linkage(pt_linking, linkagesets); + +    const auto pt_frequency_information = pt.get_child_optional("frequency_information"); +    std::vector<FrequencyInformation> frequency_information; +    parse_freq_info(pt_frequency_information, frequency_information); + +    ensemble->set_linking_config(linkagesets, frequency_information); +      parse_other_service_linking(pt, ensemble);  } diff --git a/src/ConfigParser.h b/src/ConfigParser.h index 038247b..dc7c256 100644 --- a/src/ConfigParser.h +++ b/src/ConfigParser.h @@ -40,4 +40,8 @@ void parse_ptree(  void parse_linkage(          const boost::optional<boost::property_tree::ptree&> pt_linking, -        std::vector<std::shared_ptr<LinkageSet> >& linkageSets); +        std::vector<std::shared_ptr<LinkageSet> >& linkage_sets); + +void parse_freq_info( +        const boost::optional<boost::property_tree::ptree&> pt_frequency_information, +        std::vector<FrequencyInformation>& frequency_information); diff --git a/src/DabMultiplexer.cpp b/src/DabMultiplexer.cpp index 7a8ac97..d107b9a 100644 --- a/src/DabMultiplexer.cpp +++ b/src/DabMultiplexer.cpp @@ -163,7 +163,7 @@ DabMultiplexer::DabMultiplexer(DabMultiplexerConfig& config) :  {      RC_ADD_PARAMETER(frames, "Show number of frames generated [read-only]");      RC_ADD_PARAMETER(tist_offset, "Configured tist-offset"); -    RC_ADD_PARAMETER(reload_linkagesets, "Write 1 to this parameter to trigger a reload of the linkage sets from the config [write-only]"); +    RC_ADD_PARAMETER(reload_linking, "Write 1 to this parameter to trigger a reload of the linkage sets, frequency info and other-services from the config [write-only]");      rcs.enrol(&m_clock_tai);  } @@ -462,24 +462,51 @@ void DabMultiplexer::prepare_data_inputs()      }  } -void DabMultiplexer::reload_linkagesets() +void DabMultiplexer::reload_linking()  {      try {          DabMultiplexerConfig new_conf;          new_conf.read(m_config.config_file());          if (new_conf.valid()) { -            const auto pt_linking = new_conf.pt.get_child_optional("linking"); + +            bool linkage_sets_valid = false;              std::vector<std::shared_ptr<LinkageSet> > linkagesets; -            parse_linkage(pt_linking, linkagesets); -            etiLog.level(info) << "Validating " << linkagesets.size() << " new linkage sets."; +            try { +                const auto pt_linking = new_conf.pt.get_child_optional("linking"); +                parse_linkage(pt_linking, linkagesets); + +                etiLog.level(info) << "Validating " << linkagesets.size() << " new linkage sets."; + +                linkage_sets_valid = ensemble->validate_linkage_sets( +                        ensemble->services, linkagesets); +                if (not linkage_sets_valid) { +                    etiLog.level(warn) << "New linkage set validation failed"; +                } +            } +            catch (const std::runtime_error& e) +            { +                etiLog.level(warn) << "Failed to validate new linkage sets: " << e.what(); +            } + + +            bool freq_info_valid = false; +            std::vector<FrequencyInformation> frequency_information; -            if (ensemble->validate_linkage_sets(ensemble->services, linkagesets)) { -                ensemble->linkagesets = linkagesets; -                etiLog.level(info) << "Loaded new linkage sets."; +            try { +                const auto pt_frequency_information = new_conf.pt.get_child_optional( +                        "frequency_information"); +                parse_freq_info(pt_frequency_information, frequency_information); +                freq_info_valid = true;              } -            else { -                etiLog.level(warn) << "New linkage set validation failed"; +            catch (const std::runtime_error& e) +            { +                etiLog.level(warn) << "Failed to validate new frequency info: " << e.what(); +            } + +            if (linkage_sets_valid and freq_info_valid) { +                ensemble->set_linking_config(linkagesets, frequency_information); +                etiLog.level(info) << "Loaded new linkage sets and frequency info.";              }          }      } @@ -897,8 +924,8 @@ void DabMultiplexer::set_parameter(const std::string& parameter,      else if (parameter == "tist_offset") {          m_time.set_tist_offset(std::stod(value));      } -    else if (parameter == "reload_linkagesets") { -        reload_linkagesets(); +    else if (parameter == "reload_linking") { +        reload_linking();      }      else {          stringstream ss; @@ -918,7 +945,7 @@ const std::string DabMultiplexer::get_parameter(const std::string& parameter) co      else if (parameter == "tist_offset") {          ss << m_time.tist_offset();      } -    else if (parameter == "reload_linkagesets") { +    else if (parameter == "reload_linking") {          ss << "Parameter '" << parameter <<              "' is not write-only in controllable " << get_rc_name();          throw ParameterError(ss.str()); diff --git a/src/DabMultiplexer.h b/src/DabMultiplexer.h index 620e65d..0d95c11 100644 --- a/src/DabMultiplexer.h +++ b/src/DabMultiplexer.h @@ -115,7 +115,7 @@ class DabMultiplexer : public RemoteControllable {          void prepare_services_components();          void prepare_data_inputs(); -        void reload_linkagesets(); +        void reload_linking();          DabMultiplexerConfig& m_config; diff --git a/src/MuxElements.cpp b/src/MuxElements.cpp index 1f02a6d..d39c874 100644 --- a/src/MuxElements.cpp +++ b/src/MuxElements.cpp @@ -745,7 +745,8 @@ const json::map_t dabEnsemble::get_all_values() const  bool dabEnsemble::validate_linkage_sets() const  { -    return validate_linkage_sets(services, linkagesets); +    unique_lock<mutex> lock(m_mutex); +    return validate_linkage_sets(services, m_linkagesets);  }  bool dabEnsemble::validate_linkage_sets( @@ -789,6 +790,31 @@ bool dabEnsemble::validate_linkage_sets(      return true;  } +std::vector<FrequencyInformation> dabEnsemble::get_frequency_information() const +{ +    unique_lock<mutex> lock(m_mutex); +    auto fi = m_frequency_information; +    lock.unlock(); +    return fi; +} + +std::vector<std::shared_ptr<LinkageSet> > dabEnsemble::get_linkagesets() const +{ +    unique_lock<mutex> lock(m_mutex); +    auto ls = m_linkagesets; +    lock.unlock(); +    return ls; +} + +void dabEnsemble::set_linking_config( +        std::vector<std::shared_ptr<LinkageSet> >& new_linkage_sets, +        std::vector<FrequencyInformation>& new_frequency_information) +{ +    unique_lock<mutex> lock(m_mutex); +    m_frequency_information = new_frequency_information; +    m_linkagesets = new_linkage_sets; +} +  unsigned short DabSubchannel::getSizeCu() const  {      if (protection.form == UEP) { diff --git a/src/MuxElements.h b/src/MuxElements.h index dfc4380..51445a9 100644 --- a/src/MuxElements.h +++ b/src/MuxElements.h @@ -350,9 +350,23 @@ class dabEnsemble : public RemoteControllable {          vec_sp_subchannel subchannels;          std::vector<std::shared_ptr<AnnouncementCluster> > clusters; -        std::vector<std::shared_ptr<LinkageSet> > linkagesets; -        std::vector<FrequencyInformation> frequency_information; +          std::vector<ServiceOtherEnsembleInfo> service_other_ensemble; + +        std::vector<FrequencyInformation> get_frequency_information() const; +        std::vector<std::shared_ptr<LinkageSet> > get_linkagesets() const; + +        void set_linking_config( +                std::vector<std::shared_ptr<LinkageSet> >& new_linkage_sets, +                std::vector<FrequencyInformation>& new_frequency_information); + +    private: +        // The following can be updated by the RC while being read by the main +        // thread, and need to be protected +        std::vector<std::shared_ptr<LinkageSet> > m_linkagesets; +        std::vector<FrequencyInformation> m_frequency_information; + +        mutable std::mutex m_mutex;  }; diff --git a/src/fig/FIG0_21.cpp b/src/fig/FIG0_21.cpp index 5855fb1..ea6ebfe 100644 --- a/src/fig/FIG0_21.cpp +++ b/src/fig/FIG0_21.cpp @@ -3,7 +3,7 @@     2011, 2012 Her Majesty the Queen in Right of Canada (Communications     Research Center Canada) -   Copyright (C) 2018 +   Copyright (C) 2025     Matthias P. Braendli, matthias.braendli@mpb.li     */  /* @@ -119,11 +119,12 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)      auto ensemble = m_rti->ensemble;      if (not m_initialised) { -        freqInfoFIG0_21 = ensemble->frequency_information.begin(); +        m_freq_info = ensemble->get_frequency_information(); +        m_freq_info_it = m_freq_info.begin();          fi_frequency_index = 0; -        if (freqInfoFIG0_21 != ensemble->frequency_information.end()) { -            m_last_oe = freqInfoFIG0_21->other_ensemble; +        if (m_freq_info_it != m_freq_info.end()) { +            m_last_oe = m_freq_info_it->other_ensemble;          }          m_initialised = true;      } @@ -131,13 +132,13 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)      FIGtype0* fig0 = nullptr;      auto advance_loop = [&](void){ -            if (fi_frequency_index == get_num_frequencies(freqInfoFIG0_21)) { -                ++freqInfoFIG0_21; +            if (fi_frequency_index == get_num_frequencies(m_freq_info_it)) { +                ++m_freq_info_it;                  fi_frequency_index = 0;              }          }; -    for (; freqInfoFIG0_21 != ensemble->frequency_information.end(); +    for (; m_freq_info_it != m_freq_info.end();              advance_loop()) {          /* For better usage of FIC capacity, we want to transmit           * frequency lists with @@ -149,7 +150,7 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)          // Check we have space for one frequency          size_t required_fi_size = 2; // RegionId + length of FI list          size_t list_entry_size = sizeof(struct FIGtype0_21_fi_list_header); -        switch (freqInfoFIG0_21->rm) { +        switch (m_freq_info_it->rm) {              case RangeModulation::dab_ensemble:                  list_entry_size += 3;                  break; @@ -170,12 +171,12 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)          const size_t required_size =              sizeof(struct FIGtype0_21_header) + required_fi_size; -        if (m_last_oe != freqInfoFIG0_21->other_ensemble) { +        if (m_last_oe != m_freq_info_it->other_ensemble) {              // Trigger resend of FIG0 when OE changes              fig0 = nullptr; -            m_last_oe = freqInfoFIG0_21->other_ensemble; +            m_last_oe = m_freq_info_it->other_ensemble;              etiLog.level(FIG0_21_TRACE) << "FIG0_21::switch OE to " << -                freqInfoFIG0_21->other_ensemble; +                m_freq_info_it->other_ensemble;          }          if (fig0 == nullptr) { @@ -188,7 +189,7 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)              // Database start or continuation flag, EN 300 401 Clause 5.2.2.1 part b)              fig0->CN = (fi_frequency_index == 0 ? 0 : 1); -            fig0->OE = freqInfoFIG0_21->other_ensemble ? 1 : 0; +            fig0->OE = m_freq_info_it->other_ensemble ? 1 : 0;              fig0->PD = false;              fig0->Extension = 21; @@ -199,8 +200,8 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)              break;          } -        etiLog.level(FIG0_21_TRACE) << "FIG0_21::loop " << freqInfoFIG0_21->uid << " " << -            std::distance(ensemble->frequency_information.begin(), freqInfoFIG0_21) << +        etiLog.level(FIG0_21_TRACE) << "FIG0_21::loop " << m_freq_info_it->uid << " " << +            std::distance(m_freq_info.begin(), m_freq_info_it) <<              " freq entry " << fi_frequency_index;          auto *fig0_21_header = (FIGtype0_21_header*)buf; @@ -217,26 +218,26 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)          buf          += sizeof(FIGtype0_21_fi_list_header);          remaining    -= sizeof(FIGtype0_21_fi_list_header); -        fi_list_header->continuity = freqInfoFIG0_21->continuity; +        fi_list_header->continuity = m_freq_info_it->continuity;          fi_list_header->length_freq_list = 0; -        fi_list_header->range_modulation = static_cast<uint8_t>(freqInfoFIG0_21->rm); +        fi_list_header->range_modulation = static_cast<uint8_t>(m_freq_info_it->rm);          bool continue_loop = true; -        switch (freqInfoFIG0_21->rm) { +        switch (m_freq_info_it->rm) {              case RangeModulation::dab_ensemble: -                fi_list_header->setId(freqInfoFIG0_21->fi_dab.eid); +                fi_list_header->setId(m_freq_info_it->fi_dab.eid);                  for (size_t num_inserted = 0, i = fi_frequency_index;                          num_inserted < 2 and -                        i < freqInfoFIG0_21->fi_dab.frequencies.size(); +                        i < m_freq_info_it->fi_dab.frequencies.size();                          num_inserted++, i++) {                      if (remaining < 3) {                          continue_loop = false;                          break;                      } -                    const auto& freq = freqInfoFIG0_21->fi_dab.frequencies.at(i); +                    const auto& freq = m_freq_info_it->fi_dab.frequencies.at(i);                      auto *field = (FIGtype0_21_fi_dab_entry*)buf;                      field->control_field = static_cast<uint8_t>(freq.control_field); @@ -254,18 +255,18 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)                  }                  break;              case RangeModulation::fm_with_rds: -                fi_list_header->setId(freqInfoFIG0_21->fi_fm.pi_code); +                fi_list_header->setId(m_freq_info_it->fi_fm.pi_code);                  for (size_t num_inserted = 0, i = fi_frequency_index;                          num_inserted < 7 and -                        i < freqInfoFIG0_21->fi_fm.frequencies.size(); +                        i < m_freq_info_it->fi_fm.frequencies.size();                          num_inserted++, i++) {                      if (remaining < 1) {                          continue_loop = false;                          break;                      } -                    const auto& freq = freqInfoFIG0_21->fi_fm.frequencies.at(i); +                    const auto& freq = m_freq_info_it->fi_fm.frequencies.at(i);                      // RealFreq = 87.5 MHz + (F * 100kHz)                      // => F = (RealFreq - 87.5 MHz) / 100kHz                      // Do the whole calculation in kHz: @@ -280,14 +281,14 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)                  }                  break;              case RangeModulation::drm: -                fi_list_header->setId((freqInfoFIG0_21->fi_drm.drm_service_id) & 0xFFFF); +                fi_list_header->setId((m_freq_info_it->fi_drm.drm_service_id) & 0xFFFF);                  if (remaining < 3) {                      throw logic_error("Incorrect DRM FI size calculation");                  }                  // Id field 2 -                *buf = (freqInfoFIG0_21->fi_drm.drm_service_id >> 16) & 0xFF; +                *buf = (m_freq_info_it->fi_drm.drm_service_id >> 16) & 0xFF;                  fig0_21_header->length_fi += 1;                  fi_list_header->addToLength(1); @@ -297,14 +298,14 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)                  for (size_t num_inserted = 0, i = fi_frequency_index;                          num_inserted < 3 and -                        i < freqInfoFIG0_21->fi_drm.frequencies.size(); +                        i < m_freq_info_it->fi_drm.frequencies.size();                          num_inserted++, i++) {                      if (remaining < 2) {                          continue_loop = false;                          break;                      } -                    const auto& freq = freqInfoFIG0_21->fi_drm.frequencies.at(i); +                    const auto& freq = m_freq_info_it->fi_drm.frequencies.at(i);                      uint16_t freq_field = static_cast<uint16_t>(freq * 1000.0f);                      buf[0] = freq_field >> 8;                      buf[1] = freq_field & 0xFF; @@ -318,14 +319,14 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)                  }                  break;              case RangeModulation::amss: -                fi_list_header->setId((freqInfoFIG0_21->fi_amss.amss_service_id) & 0xFFFF); +                fi_list_header->setId((m_freq_info_it->fi_amss.amss_service_id) & 0xFFFF);                  if (remaining < 3) {                      throw logic_error("Incorrect AMSS FI size calculation");                  }                  // Id field 2 -                *buf = (freqInfoFIG0_21->fi_amss.amss_service_id >> 16) & 0xFF; +                *buf = (m_freq_info_it->fi_amss.amss_service_id >> 16) & 0xFF;                  fig0_21_header->length_fi += 1;                  fi_list_header->addToLength(1); @@ -335,14 +336,14 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)                  for (size_t num_inserted = 0, i = fi_frequency_index;                          num_inserted < 3 and -                        i < freqInfoFIG0_21->fi_amss.frequencies.size(); +                        i < m_freq_info_it->fi_amss.frequencies.size();                          num_inserted++, i++) {                      if (remaining < 2) {                          continue_loop = false;                          break;                      } -                    const auto& freq = freqInfoFIG0_21->fi_amss.frequencies.at(i); +                    const auto& freq = m_freq_info_it->fi_amss.frequencies.at(i);                      uint16_t freq_field = static_cast<uint16_t>(freq * 1000.0f);                      buf[0] = freq_field >> 8;                      buf[1] = freq_field & 0xFF; @@ -370,10 +371,10 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)          }      } // for over FI -    if (freqInfoFIG0_21 == ensemble->frequency_information.end()) { +    if (m_freq_info_it == m_freq_info.end()) {          fs.complete_fig_transmitted = true; -        freqInfoFIG0_21 = ensemble->frequency_information.begin(); +        m_freq_info_it = m_freq_info.begin();          fi_frequency_index = 0;      } diff --git a/src/fig/FIG0_21.h b/src/fig/FIG0_21.h index 706dead..4e56c8c 100644 --- a/src/fig/FIG0_21.h +++ b/src/fig/FIG0_21.h @@ -3,7 +3,7 @@     2011, 2012 Her Majesty the Queen in Right of Canada (Communications     Research Center Canada) -   Copyright (C) 2018 +   Copyright (C) 2025     Matthias P. Braendli, matthias.braendli@mpb.li     */  /* @@ -27,7 +27,6 @@  #include <cstdint>  #include <vector> -#include <memory>  namespace FIC { @@ -49,7 +48,8 @@ class FIG0_21 : public IFIG          bool m_initialised = false;          bool m_last_oe = false; -        std::vector<FrequencyInformation>::iterator freqInfoFIG0_21; +        std::vector<FrequencyInformation> m_freq_info; +        std::vector<FrequencyInformation>::iterator m_freq_info_it;          size_t fi_frequency_index = 0;  }; diff --git a/src/fig/FIG0_6.cpp b/src/fig/FIG0_6.cpp index 61d950d..e9e6220 100644 --- a/src/fig/FIG0_6.cpp +++ b/src/fig/FIG0_6.cpp @@ -256,7 +256,7 @@ void FIG0_6::update()      // TODO check if AMSS and DRM have to be put into a single subset -    for (const auto& linkageset : m_rti->ensemble->linkagesets) { +    for (const auto& linkageset : m_rti->ensemble->get_linkagesets()) {          const auto lsn = linkageset->lsn;          if (linkageset->keyservice.empty()) { diff --git a/src/utils.cpp b/src/utils.cpp index 7ea6293..fc4c864 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -171,8 +171,6 @@ void printOutputs(const vector<shared_ptr<DabOutput> >& outputs)  void printServices(const vector<shared_ptr<DabService> >& services)  { -    int index = 0; -      etiLog.log(info, "--- Services list ---");      for (auto service : services) { @@ -200,7 +198,6 @@ void printServices(const vector<shared_ptr<DabService> >& services)              clusters_s.push_back(std::to_string(cluster));          }          etiLog.level(info) << " clusters: " << boost::join(clusters_s, ","); -        ++index;      }  } @@ -279,8 +276,6 @@ void printComponent(const shared_ptr<DabComponent>& component, const std::shared  void printSubchannels(const vec_sp_subchannel& subchannels)  { -    int index = 0; -      int total_num_cu = 0;      etiLog.log(info, "--- Subchannels list ---"); @@ -330,7 +325,6 @@ void printSubchannels(const vec_sp_subchannel& subchannels)          etiLog.log(info, " size (CU):  %i",                  subchannel->getSizeCu());          total_num_cu += subchannel->getSizeCu(); -        ++index;      }      etiLog.log(info, "Total ensemble size (CU):  %i", total_num_cu); @@ -338,12 +332,12 @@ void printSubchannels(const vec_sp_subchannel& subchannels)  static void printLinking(const shared_ptr<dabEnsemble>& ensemble)  { +    const auto linkagesets = ensemble->get_linkagesets();      etiLog.log(info, " Linkage Sets"); -    if (ensemble->linkagesets.empty()) { +    if (linkagesets.empty()) {          etiLog.level(info) << "  None ";      } -    for (const auto& ls : ensemble->linkagesets) { - +    for (const auto& ls : linkagesets) {          etiLog.level(info) << "  set " << ls->get_name();          etiLog.log(info,      "   LSN 0x%04x", ls->lsn);          etiLog.level(info) << "   active " << (ls->active ? "true" : "false"); @@ -399,11 +393,12 @@ static void printLinking(const shared_ptr<dabEnsemble>& ensemble)  static void printFrequencyInformation(const shared_ptr<dabEnsemble>& ensemble)  { +    const auto frequency_information = ensemble->get_frequency_information();      etiLog.log(info, " Frequency Information"); -    if (ensemble->frequency_information.empty()) { +    if (frequency_information.empty()) {          etiLog.level(info) << "  None ";      } -    for (const auto& fi : ensemble->frequency_information) { +    for (const auto& fi : frequency_information) {          etiLog.level(info) << "  FI " << fi.uid;          etiLog.level(info) << "   OE=" << (fi.other_ensemble ? 1 : 0);          switch (fi.rm) { | 
