aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ConfigParser.cpp15
-rw-r--r--src/DabMultiplexer.h8
-rw-r--r--src/MuxElements.h25
-rw-r--r--src/dabOutput/dabOutput.h3
-rw-r--r--src/fig/FIG0.cpp74
-rw-r--r--src/fig/FIG0.h18
-rw-r--r--src/fig/FIGCarousel.cpp5
-rw-r--r--src/fig/FIGCarousel.h1
-rw-r--r--src/utils.cpp2
9 files changed, 146 insertions, 5 deletions
diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp
index 1ad9249..5290b0f 100644
--- a/src/ConfigParser.cpp
+++ b/src/ConfigParser.cpp
@@ -235,8 +235,7 @@ void parse_ptree(boost::property_tree::ptree& pt,
bool service_already_existing = false;
- for (auto srv : ensemble->services)
- {
+ for (auto srv : ensemble->services) {
if (srv->uid == serviceuid) {
service = srv;
service_already_existing = true;
@@ -250,6 +249,18 @@ void parse_ptree(boost::property_tree::ptree& pt,
service = new_srv;
}
+ /* Parse ASu */
+ service->ASu = 0;
+ for (size_t flag = 0; flag < 16; flag++) {
+ std::string announcement_name(annoucement_flags_names[flag]);
+ bool flag_set =
+ pt_service.get<bool>("announcements." + announcement_name, false);
+
+ if (flag_set) {
+ service->ASu |= (1 << flag);
+ }
+ }
+
int success = -5;
string servicelabel = pt_service.get<string>("label");
diff --git a/src/DabMultiplexer.h b/src/DabMultiplexer.h
index ef637e5..0458969 100644
--- a/src/DabMultiplexer.h
+++ b/src/DabMultiplexer.h
@@ -387,6 +387,14 @@ struct FIGtype0_17_programme {
uint8_t SD:1;
} PACKED;
+struct FIGtype0_18 {
+ uint16_t SId;
+ uint16_t ASu;
+ uint8_t NumClusters:5;
+ uint8_t Rfa:3;
+ /* Followed by uint8_t Cluster IDs */
+} PACKED;
+
struct FIGtype0_1 {
uint8_t Length:5;
diff --git a/src/MuxElements.h b/src/MuxElements.h
index 4d770e9..5eeac51 100644
--- a/src/MuxElements.h
+++ b/src/MuxElements.h
@@ -47,6 +47,24 @@ enum class subchannel_type_t {
};
+/* Announcement switching flags,
+ * define in ETSI TS 101 756 Table 15 */
+const char * const annoucement_flags_names[] = {
+ "Alarm",
+ "Traffic",
+ "Travel",
+ "Warning",
+ "News",
+ "Weather",
+ "Event",
+ "Special",
+ "ProgrammeInfo",
+ "Sports",
+ "Finance",
+ "tba1", "tba2", "tba3", "tba4", "tba5"
+};
+
+
struct dabOutput {
dabOutput(const char* proto, const char* name) :
outputProto(proto), outputName(name), output(NULL) { }
@@ -299,6 +317,13 @@ class DabService : public RemoteControllable
unsigned char language;
bool program;
+ /* ASu (Announcement support) flags: this 16-bit flag field shall
+ * specify the type(s) of announcements by which it is possible to
+ * interrupt the reception of the service. The interpretation of this
+ * field shall be as defined in TS 101 756, table 14.
+ */
+ uint16_t ASu;
+
subchannel_type_t getType(boost::shared_ptr<dabEnsemble> ensemble);
unsigned char nbComponent(std::vector<DabComponent*>& components);
diff --git a/src/dabOutput/dabOutput.h b/src/dabOutput/dabOutput.h
index cd48790..0ced9d3 100644
--- a/src/dabOutput/dabOutput.h
+++ b/src/dabOutput/dabOutput.h
@@ -55,6 +55,9 @@
// Configuration for EDI output
struct edi_configuration_t {
+ edi_configuration_t() :
+ enabled(false),
+ verbose(false) {}
unsigned chunk_len; // RSk, data length of each chunk
unsigned fec; // number of fragments that can be recovered
bool enabled;
diff --git a/src/fig/FIG0.cpp b/src/fig/FIG0.cpp
index b424fe3..7cb3dde 100644
--- a/src/fig/FIG0.cpp
+++ b/src/fig/FIG0.cpp
@@ -919,5 +919,79 @@ FillStatus FIG0_17::fill(uint8_t *buf, size_t max_size)
return fs;
}
+//=========== FIG 0/18 ===========
+
+FIG0_18::FIG0_18(FIGRuntimeInformation *rti) :
+ m_rti(rti),
+ m_initialised(false)
+{
+}
+
+FillStatus FIG0_18::fill(uint8_t *buf, size_t max_size)
+{
+ FillStatus fs;
+ ssize_t remaining = max_size;
+
+ if (not m_initialised) {
+ service = m_rti->ensemble->services.end();
+ m_initialised = true;
+ }
+
+ auto ensemble = m_rti->ensemble;
+
+ FIGtype0* fig0 = NULL;
+
+ if (service == ensemble->services.end()) {
+ service = ensemble->services.begin();
+ fs.complete_fig_transmitted = true;
+ }
+
+ for (; service != ensemble->services.end();
+ ++service) {
+
+ if ( (*service)->ASu == 0 ) {
+ continue;
+ }
+
+ // TODO support more than one cluster
+ const int numclusters = 1;
+
+ if (remaining < (int)sizeof(FIGtype0_18) + numclusters) {
+ break;
+ }
+
+ if (fig0 == NULL) {
+ if (remaining < 2 + (int)sizeof(FIGtype0_18) + numclusters) {
+ break;
+ }
+
+ fig0 = (FIGtype0*)buf;
+ fig0->FIGtypeNumber = 0;
+ fig0->Length = 1;
+ fig0->CN = 0;
+ fig0->OE = 0;
+ fig0->PD = 0;
+ fig0->Extension = 18;
+ buf += 2;
+ remaining -= 2;
+ }
+
+ auto programme = (FIGtype0_18*)buf;
+ programme->SId = htons((*service)->id);
+ programme->ASu = htons((*service)->ASu);
+ programme->Rfa = 0;
+ programme->NumClusters = numclusters;
+ buf += sizeof(FIGtype0_18);
+ buf[0] = 0x1; // TODO support not only cluster 1
+ buf += numclusters;
+
+ fig0->Length += sizeof(FIGtype0_18) + numclusters;
+ remaining -= sizeof(FIGtype0_18) + numclusters;
+ }
+
+ fs.num_bytes_written = max_size - remaining;
+ return fs;
+}
+
} // namespace FIC
diff --git a/src/fig/FIG0.h b/src/fig/FIG0.h
index 14b658f..0c11ced 100644
--- a/src/fig/FIG0.h
+++ b/src/fig/FIG0.h
@@ -180,7 +180,6 @@ class FIG0_13 : public IFIG
std::vector<DabComponent*>::iterator componentFIG0_13;
};
-
// FIG type 0/17
class FIG0_17 : public IFIG
{
@@ -198,6 +197,23 @@ class FIG0_17 : public IFIG
std::vector<std::shared_ptr<DabService> >::iterator serviceFIG0_17;
};
+// FIG type 0/18
+class FIG0_18 : public IFIG
+{
+ public:
+ FIG0_18(FIGRuntimeInformation* rti);
+ virtual FillStatus fill(uint8_t *buf, size_t max_size);
+ virtual FIG_rate repetition_rate(void) { return FIG_rate::B; }
+
+ virtual const int figtype(void) const { return 0; }
+ virtual const int figextension(void) const { return 18; }
+
+ private:
+ FIGRuntimeInformation *m_rti;
+ bool m_initialised;
+ std::vector<std::shared_ptr<DabService> >::iterator service;
+};
+
} // namespace FIC
#endif // __FIG0_H_
diff --git a/src/fig/FIGCarousel.cpp b/src/fig/FIGCarousel.cpp
index cfe5c38..8eedd6e 100644
--- a/src/fig/FIGCarousel.cpp
+++ b/src/fig/FIGCarousel.cpp
@@ -67,7 +67,8 @@ FIGCarousel::FIGCarousel(boost::shared_ptr<dabEnsemble> ensemble) :
m_fig0_9(&m_rti),
m_fig1_1(&m_rti),
m_fig1_4(&m_rti),
- m_fig1_5(&m_rti)
+ m_fig1_5(&m_rti),
+ m_fig0_18(&m_rti)
{
load_and_allocate(m_fig0_0, 0);
load_and_allocate(m_fig0_1, 0);
@@ -83,7 +84,7 @@ FIGCarousel::FIGCarousel(boost::shared_ptr<dabEnsemble> ensemble) :
load_and_allocate(m_fig1_1, 2);
load_and_allocate(m_fig1_5, 2);
- load_and_allocate(m_fig1_4, 2);
+ load_and_allocate(m_fig0_18, 2);
}
void FIGCarousel::load_and_allocate(IFIG& fig, int fib)
diff --git a/src/fig/FIGCarousel.h b/src/fig/FIGCarousel.h
index 2fa0335..170ffdd 100644
--- a/src/fig/FIGCarousel.h
+++ b/src/fig/FIGCarousel.h
@@ -85,6 +85,7 @@ class FIGCarousel {
FIG1_1 m_fig1_1;
FIG1_4 m_fig1_4;
FIG1_5 m_fig1_5;
+ FIG0_18 m_fig0_18;
};
} // namespace FIC
diff --git a/src/utils.cpp b/src/utils.cpp
index e79d023..2559cb0 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -387,6 +387,8 @@ void printServices(const vector<shared_ptr<DabService> >& services)
etiLog.log(info, " language: 0x%x (%u)",
service->language, service->language);
+ etiLog.log(info, " announcements: 0x%x",
+ service->ASu);
++index;
}
}