diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/DabMux.cpp | 8 | ||||
| -rw-r--r-- | src/MuxElements.cpp | 101 | ||||
| -rw-r--r-- | src/MuxElements.h | 32 | ||||
| -rw-r--r-- | src/ParserCmdline.cpp | 4 | ||||
| -rw-r--r-- | src/ParserConfigfile.cpp | 63 | ||||
| -rw-r--r-- | src/dabInputZmq.cpp | 2 | ||||
| -rw-r--r-- | src/utils.cpp | 18 | ||||
| -rw-r--r-- | src/utils.h | 2 | 
8 files changed, 178 insertions, 52 deletions
| diff --git a/src/DabMux.cpp b/src/DabMux.cpp index b7095c6..7bb44ba 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -275,10 +275,10 @@ int main(int argc, char *argv[])      ensemble->ecc = DEFAULT_ENSEMBLE_ECC;      vector<dabOutput*> outputs; -    vector<dabService*>::iterator service = ensemble->services.end(); -    vector<dabService*>::iterator serviceProgramInd; -    vector<dabService*>::iterator serviceDataInd; -    vector<dabService*>::iterator servicePty; +    vector<DabService*>::iterator service = ensemble->services.end(); +    vector<DabService*>::iterator serviceProgramInd; +    vector<DabService*>::iterator serviceDataInd; +    vector<DabService*>::iterator servicePty;      vector<dabComponent*>::iterator component = ensemble->components.end();      vector<dabComponent*>::iterator componentIndicatorProgram;      vector<dabComponent*>::iterator componentIndicatorData; diff --git a/src/MuxElements.cpp b/src/MuxElements.cpp index 3ac63e3..13ce096 100644 --- a/src/MuxElements.cpp +++ b/src/MuxElements.cpp @@ -3,8 +3,8 @@     2011, 2012 Her Majesty the Queen in Right of Canada (Communications     Research Center Canada) -   Includes modifications -   2012, Matthias P. Braendli, matthias.braendli@mpb.li +   Copyright (C) 2014 +   Matthias P. Braendli, matthias.braendli@mpb.li     */  /*     This file is part of ODR-DabMux. @@ -26,6 +26,7 @@  #include <vector>  #include "MuxElements.h" +#include <boost/algorithm/string.hpp>  const unsigned short Sub_Channel_SizeTable[64] = {      16, 21, 24, 29, 35, 24, 29, 35, @@ -48,9 +49,11 @@ int DabLabel::setLabel(const std::string& text)      if (len > 16)          return -3; -    memset(m_text, 0, 16); +    memset(m_text, 0, 17);      memcpy(m_text, text.c_str(), len); +    m_flag = 0xFF00; // truncate the label to the eight first characters +      return 0;  } @@ -58,7 +61,7 @@ int DabLabel::setLabel(const std::string& text, const std::string& short_label)  {      DabLabel newlabel; -    memset(newlabel.m_text, 0, 16); +    memset(newlabel.m_text, 0, 17);      int len = text.length();      if (len > 16)          return -3; @@ -70,7 +73,7 @@ int DabLabel::setLabel(const std::string& text, const std::string& short_label)          return flag;      // short label is valid. -    memcpy(this->m_text, newlabel.m_text, len); +    memcpy(this->m_text, newlabel.m_text, 17);      this->m_flag = flag & 0xFFFF;      return 0; @@ -127,6 +130,18 @@ int DabLabel::setShortLabel(const std::string& slabel)      return flag;  } +const string DabLabel::short_label() const +{ +    stringstream shortlabel; +    for (int i = 0; i < 32; ++i) { +        if (m_flag & 0x8000 >> i) { +            shortlabel << m_text[i]; +        } +    } + +    return shortlabel.str(); +} +  vector<dabSubchannel*>::iterator getSubchannel(          vector<dabSubchannel*>& subchannels, int id) @@ -166,11 +181,11 @@ vector<dabComponent*>::iterator getComponent(      return getComponent(components, serviceId, components.end());  } -vector<dabService*>::iterator getService( +vector<DabService*>::iterator getService(          dabComponent* component, -        vector<dabService*>& services) +        vector<DabService*>& services)  { -    vector<dabService*>::iterator service; +    vector<DabService*>::iterator service;      for (service = services.begin(); service != services.end(); ++service) {          if ((*service)->id == component->serviceId) { @@ -204,7 +219,7 @@ bool dabComponent::isPacketComponent(vector<dabSubchannel*>& subchannels)  } -unsigned char dabService::getType(dabEnsemble* ensemble) +unsigned char DabService::getType(dabEnsemble* ensemble)  {      vector<dabSubchannel*>::iterator subchannel;      vector<dabComponent*>::iterator component = @@ -220,7 +235,7 @@ unsigned char dabService::getType(dabEnsemble* ensemble)      return (*subchannel)->type;  } -unsigned char dabService::nbComponent(vector<dabComponent*>& components) +unsigned char DabService::nbComponent(vector<dabComponent*>& components)  {      int nb = 0;      vector<dabComponent*>::iterator current; @@ -234,6 +249,72 @@ unsigned char dabService::nbComponent(vector<dabComponent*>& components)      return nb;  } +void DabService::set_parameter(string parameter, string value) +{ +    stringstream ss(value); +    ss.exceptions ( stringstream::failbit | stringstream::badbit ); + +    if (parameter == "label") { +        vector<string> fields; +        boost::split(fields, value, boost::is_any_of(",")); +        if (fields.size() != 2) { +            throw ParameterError("Parameter 'label' must have format" +                   " 'label,shortlabel'"); +        } +        int success = this->label.setLabel(fields[0], fields[1]); +        stringstream ss; +        switch (success) +        { +            case 0: +                break; +            case -1: +                ss << "Ensemble short label " << +                    fields[1] << " is not subset of label '" << +                    fields[0] << "'"; +                etiLog.level(warn) << ss.str(); +                throw ParameterError(ss.str()); +            case -2: +                ss << "Ensemble short label " << +                    fields[1] << " is too long (max 8 characters)"; +                etiLog.level(warn) << ss.str(); +                throw ParameterError(ss.str()); +            case -3: +                ss << "Ensemble label " << +                    fields[0] << " is too long (max 16 characters)"; +                etiLog.level(warn) << ss.str(); +                throw ParameterError(ss.str()); +            default: +                ss << "Ensemble short label definition: program error !"; +                etiLog.level(emerg) << ss.str(); +                throw ParameterError(ss.str()); +        } +    } +    else { +        stringstream ss; +        ss << "Parameter '" << parameter << +            "' is not exported by controllable " << get_rc_name(); +        throw ParameterError(ss.str()); +    } +} + +string DabService::get_parameter(string parameter) +{ +    stringstream ss; +    if (parameter == "label") { +        char l[17]; +        l[16] = '\0'; +        memcpy(l, label.text(), 16); +        ss << l << "," << label.short_label(); +    } +    else { +        ss << "Parameter '" << parameter << +            "' is not exported by controllable " << get_rc_name(); +        throw ParameterError(ss.str()); +    } +    return ss.str(); + +} +  unsigned short getSizeCu(dabSubchannel* subchannel)  {      if (subchannel->protection.form == 0) { diff --git a/src/MuxElements.h b/src/MuxElements.h index 9658fb2..a0ee23a 100644 --- a/src/MuxElements.h +++ b/src/MuxElements.h @@ -35,6 +35,7 @@  #include <stdint.h>  #include "dabOutput/dabOutput.h"  #include "dabInput.h" +#include "RemoteControl.h"  #include "Eti.h"  using namespace std; @@ -74,15 +75,18 @@ class DabLabel          const char* text() const { return m_text; }          uint16_t flag() const { return m_flag; } +        const string short_label() const;      private: -        char m_text[16]; +        // In the DAB standard, the label is 16 chars. +        // We keep it here zero-terminated +        char m_text[17];          uint16_t m_flag;          int setShortLabel(const std::string& slabel);  }; -struct dabService; +struct DabService;  struct dabComponent;  struct dabSubchannel;  struct dabEnsemble { @@ -90,7 +94,7 @@ struct dabEnsemble {      uint8_t ecc;      DabLabel label;      uint8_t mode; -    vector<dabService*> services; +    vector<DabService*> services;      vector<dabComponent*> components;      vector<dabSubchannel*> subchannels;  }; @@ -177,8 +181,14 @@ struct dabComponent { -struct dabService +class DabService : public RemoteControllable  { +    public: +        DabService(std::string uid) : RemoteControllable(uid) +        { +            RC_ADD_PARAMETER(label, "Label and shortlabel [label,short]"); +        } +          uint32_t id;          unsigned char pty;          unsigned char language; @@ -188,6 +198,16 @@ struct dabService          unsigned char nbComponent(vector<dabComponent*>& components);          DabLabel label; + +        /* Remote control */ +        virtual void set_parameter(string parameter, string value); + +        /* Getting a parameter always returns a string. */ +        virtual string get_parameter(string parameter); + +    private: +        const DabService& operator=(const DabService& other); +        DabService(const DabService& other);  };  vector<dabSubchannel*>::iterator getSubchannel( @@ -202,9 +222,9 @@ vector<dabComponent*>::iterator getComponent(          vector<dabComponent*>& components,          uint32_t serviceId); -vector<dabService*>::iterator getService( +vector<DabService*>::iterator getService(          dabComponent* component, -        vector<dabService*>& services); +        vector<DabService*>& services);  unsigned short getSizeCu(dabSubchannel* subchannel); diff --git a/src/ParserCmdline.cpp b/src/ParserCmdline.cpp index 9985d9a..2027bff 100644 --- a/src/ParserCmdline.cpp +++ b/src/ParserCmdline.cpp @@ -104,7 +104,7 @@ bool parse_cmdline(char **argv,      vector<dabOutput*>::iterator output;      vector<dabSubchannel*>::iterator subchannel = ensemble->subchannels.end();      vector<dabComponent*>::iterator component = ensemble->components.end(); -    vector<dabService*>::iterator service = ensemble->services.end(); +    vector<DabService*>::iterator service = ensemble->services.end();      dabProtection* protection = NULL;      dabInputOperations operations; @@ -148,7 +148,7 @@ bool parse_cmdline(char **argv,              service = ensemble->services.end();              break;          case 'S': -            ensemble->services.push_back(new dabService); +            ensemble->services.push_back(new DabService("?"));              subchannel = ensemble->subchannels.end();              protection = NULL; diff --git a/src/ParserConfigfile.cpp b/src/ParserConfigfile.cpp index 9262ed3..a6bbe63 100644 --- a/src/ParserConfigfile.cpp +++ b/src/ParserConfigfile.cpp @@ -105,7 +105,6 @@ using namespace std;  int hexparse(std::string input)  {      int value; -    fprintf(stderr, "**************************** %s\n", input.c_str());      if (input.find("0x") == 0) {          value = strtoll(input.c_str() + 2, NULL, 16);      } @@ -190,25 +189,35 @@ void parse_configfile(string configuration_file,      /* Extended Country Code */      ensemble->ecc = hexparse(pt_ensemble.get("ecc", "0")); -    string label = pt_ensemble.get<string>("label"); -    string short_label = pt_ensemble.get<string>("shortlabel"); -    int success = ensemble->label.setLabel(label, short_label); +    int success = -5; +    string ensemble_label = pt_ensemble.get<string>("label"); +    string ensemble_short_label(ensemble_label); +    try { +        ensemble_short_label = pt_ensemble.get<string>("shortlabel"); +        success = ensemble->label.setLabel(ensemble_label, ensemble_short_label); +    } +    catch (ptree_error &e) { +        etiLog.level(warn) << "Ensemble short label undefined, " +            "truncating label " << ensemble_label; + +        success = ensemble->label.setLabel(ensemble_label); +    }      switch (success)      {          case 0:              break;          case -1:              etiLog.level(error) << "Ensemble short label " << -                short_label << " is not subset of label '" << -                label << "'"; +                ensemble_short_label << " is not subset of label '" << +                ensemble_label << "'";              throw runtime_error("ensemble label definition error");          case -2:              etiLog.level(error) << "Ensemble short label " << -                short_label << " is too long (max 8 characters)"; +                ensemble_short_label << " is too long (max 8 characters)";              throw runtime_error("ensemble label definition error");          case -3:              etiLog.level(error) << "Ensemble label " << -                label << " is too long (max 16 characters)"; +                ensemble_label << " is too long (max 16 characters)";              throw runtime_error("ensemble label definition error");          default:              etiLog.level(error) << @@ -219,22 +228,34 @@ void parse_configfile(string configuration_file,      /******************** READ SERVICES PARAMETERS *************/ -    map<string, dabService*> allservices; +    map<string, DabService*> allservices;      /* For each service, we keep a separate SCIdS counter */ -    map<dabService*, int> SCIdS_per_service; +    map<DabService*, int> SCIdS_per_service;      ptree pt_services = pt.get_child("services");      for (ptree::iterator it = pt_services.begin();              it != pt_services.end(); ++it) {          string serviceuid = it->first;          ptree pt_service = it->second; -        dabService* service = new dabService(); +        DabService* service = new DabService(serviceuid);          ensemble->services.push_back(service); +        service->enrol_at(*rc); + +        int success = -5;          string servicelabel = pt_service.get<string>("label"); -        string serviceshortlabel = pt_service.get<string>("shortlabel"); -        int success = service->label.setLabel(label, short_label); +        string serviceshortlabel(servicelabel); +        try { +            serviceshortlabel = pt_service.get<string>("shortlabel"); +            success = service->label.setLabel(servicelabel, serviceshortlabel); +        } +        catch (ptree_error &e) { +            etiLog.level(warn) << "Service short label undefined, " +                "truncating label " << servicelabel; + +            success = service->label.setLabel(servicelabel); +        }          switch (success)          {              case 0: @@ -318,7 +339,7 @@ void parse_configfile(string configuration_file,          string componentuid = it->first;          ptree pt_comp = it->second; -        dabService* service; +        DabService* service;          try {              // Those two uids serve as foreign keys to select the service+subchannel              string service_uid = pt_comp.get<string>("service"); @@ -365,9 +386,19 @@ void parse_configfile(string configuration_file,          component->SCIdS = SCIdS_per_service[service]++;          component->type = component_type; +        int success = -5;          string componentlabel = pt_comp.get<string>("label"); -        string componentshortlabel = pt_comp.get<string>("shortlabel"); -        int success = component->label.setLabel(label, short_label); +        string componentshortlabel(componentlabel); +        try { +            componentshortlabel = pt_comp.get<string>("shortlabel"); +            success = component->label.setLabel(componentlabel, componentshortlabel); +        } +        catch (ptree_error &e) { +            etiLog.level(warn) << "Component short label undefined, " +                "truncating label " << componentlabel; + +            success = component->label.setLabel(componentlabel); +        }          switch (success)          {              case 0: diff --git a/src/dabInputZmq.cpp b/src/dabInputZmq.cpp index ab1aca1..c883f35 100644 --- a/src/dabInputZmq.cpp +++ b/src/dabInputZmq.cpp @@ -309,7 +309,7 @@ void DabInputZmqBase::set_parameter(string parameter, string value)      ss.exceptions ( stringstream::failbit | stringstream::badbit );      if (parameter == "buffer") { -        throw ParameterError("Parameter 'ntaps' is read-only"); +        throw ParameterError("Parameter 'buffer' is read-only");      }      else {          stringstream ss; diff --git a/src/utils.cpp b/src/utils.cpp index b837009..157c3a7 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -296,9 +296,9 @@ void printOutputs(vector<dabOutput*>& outputs)      }  } -void printServices(vector<dabService*>& services) +void printServices(vector<DabService*>& services)  { -    vector<dabService*>::const_iterator current; +    vector<DabService*>::const_iterator current;      int index = 0;      for (current = services.begin(); current != services.end(); ++current) { @@ -307,16 +307,10 @@ void printServices(vector<dabService*>& services)          label[16] = 0;          etiLog.log(info, "Service       %i\n", index); -        etiLog.log(info, " label:       %s\n", label); -        etiLog.log(info, " short label: "); -        { -            LogLine line = etiLog.level(info); -            for (int i = 0; i < 32; ++i) { -                if ((*current)->label.flag() & 0x8000 >> i) { -                    line << label[i]; -                } -            } -        } +        etiLog.log(info, " label:       %s\n", +                (*current)->label.text()); +        etiLog.log(info, " short label: %s\n", +                (*current)->label.short_label().c_str());          etiLog.log(info, " (0x%x)\n", (*current)->label.flag());          etiLog.log(info, " id:          0x%lx (%lu)\n",                  (*current)->id, (*current)->id); diff --git a/src/utils.h b/src/utils.h index 75d1b6e..8a9e264 100644 --- a/src/utils.h +++ b/src/utils.h @@ -51,7 +51,7 @@ void printUsageConfigfile(char *name, FILE* out = stderr);   * resp. subchannels*/  void printOutputs(vector<dabOutput*>& outputs); -void printServices(vector<dabService*>& services); +void printServices(vector<DabService*>& services);  void printComponents(vector<dabComponent*>& components); | 
