diff options
-rw-r--r-- | doc/example.mux | 16 | ||||
-rw-r--r-- | src/ConfigParser.cpp | 15 | ||||
-rw-r--r-- | src/DabMultiplexer.h | 8 | ||||
-rw-r--r-- | src/MuxElements.h | 25 | ||||
-rw-r--r-- | src/dabOutput/dabOutput.h | 3 | ||||
-rw-r--r-- | src/fig/FIG0.cpp | 74 | ||||
-rw-r--r-- | src/fig/FIG0.h | 18 | ||||
-rw-r--r-- | src/fig/FIGCarousel.cpp | 5 | ||||
-rw-r--r-- | src/fig/FIGCarousel.h | 1 | ||||
-rw-r--r-- | src/utils.cpp | 2 |
10 files changed, 162 insertions, 5 deletions
diff --git a/doc/example.mux b/doc/example.mux index 9b43800..1b0059c 100644 --- a/doc/example.mux +++ b/doc/example.mux @@ -86,6 +86,22 @@ services { pty 0 language 0 ; also supports id + + ; List of announcement switching flags signalled in FIG 0/18 + ; This lists all possible announcements. If one is left out, it is disabled. + announcements { + Alarm false + Traffic false + Travel false + Warning false + News false + Weather false + Event false + Special false + ProgrammeInfo false + Sports false + Finance false + } } srv-lu { label "Luschtig" 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; } } |