diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2014-02-14 13:07:17 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2014-02-14 13:07:17 +0100 |
commit | 4249e4a53950457394395555cd7dcdd6287b499b (patch) | |
tree | f24fb7336bc8897e62892da005d0815bef998f31 | |
parent | 6b9857cb1b2ab6b58e6e42df4b0cce54448b10a0 (diff) | |
download | dabmux-4249e4a53950457394395555cd7dcdd6287b499b.tar.gz dabmux-4249e4a53950457394395555cd7dcdd6287b499b.tar.bz2 dabmux-4249e4a53950457394395555cd7dcdd6287b499b.zip |
DabService labels can now be changed through the remote control
-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); |