summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2014-02-14 13:07:17 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2014-02-14 13:07:17 +0100
commit4249e4a53950457394395555cd7dcdd6287b499b (patch)
treef24fb7336bc8897e62892da005d0815bef998f31 /src
parent6b9857cb1b2ab6b58e6e42df4b0cce54448b10a0 (diff)
downloaddabmux-4249e4a53950457394395555cd7dcdd6287b499b.tar.gz
dabmux-4249e4a53950457394395555cd7dcdd6287b499b.tar.bz2
dabmux-4249e4a53950457394395555cd7dcdd6287b499b.zip
DabService labels can now be changed through the remote control
Diffstat (limited to 'src')
-rw-r--r--src/DabMux.cpp8
-rw-r--r--src/MuxElements.cpp101
-rw-r--r--src/MuxElements.h32
-rw-r--r--src/ParserCmdline.cpp4
-rw-r--r--src/ParserConfigfile.cpp63
-rw-r--r--src/dabInputZmq.cpp2
-rw-r--r--src/utils.cpp18
-rw-r--r--src/utils.h2
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);