aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/MuxElements.h2
-rw-r--r--src/fig/FIG0.cpp121
-rw-r--r--src/fig/FIG0.h22
3 files changed, 136 insertions, 9 deletions
diff --git a/src/MuxElements.h b/src/MuxElements.h
index 8285e61..2f602ba 100644
--- a/src/MuxElements.h
+++ b/src/MuxElements.h
@@ -452,7 +452,7 @@ class LinkageSet : public RemoteControllable {
bool hard;
bool international;
- std::string keyservice;
+ std::string keyservice; // TODO replace by pointer to service
private:
/* Remote control */
diff --git a/src/fig/FIG0.cpp b/src/fig/FIG0.cpp
index b560e4c..1e179cf 100644
--- a/src/fig/FIG0.cpp
+++ b/src/fig/FIG0.cpp
@@ -686,7 +686,17 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
for (; linkageSetFIG0_6 != ensemble->linkagesets.end();
++linkageSetFIG0_6) {
- const int required_size = 2;
+ const bool PD = false;
+ const bool ILS = (*linkageSetFIG0_6)->international;
+
+ // need to add key service to num_ids
+ const size_t num_ids = 1 + (*linkageSetFIG0_6)->id_list.size();
+
+ const size_t headersize = sizeof(struct FIGtype0_6_header);
+ const int required_size = sizeof(struct FIGtype0_6) +
+ (num_ids > 0 ?
+ headersize + (PD == 0 ? (ILS == 0 ? 2*num_ids : 3*num_ids) : 4*num_ids) :
+ 0);
if (fig0 == NULL) {
if (remaining < 2 + required_size) {
@@ -697,7 +707,7 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
fig0->Length = 1;
fig0->CN = 0;
fig0->OE = 0;
- fig0->PD = 0;
+ fig0->PD = PD;
fig0->Extension = 5;
buf += 2;
@@ -709,17 +719,112 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)
FIGtype0_6 *fig0_6 = (FIGtype0_6*)buf;
- fig0_6->IdListFlag = 1;
+ fig0_6->IdListFlag = (num_ids > 0);
fig0_6->LA = (*linkageSetFIG0_6)->active;
fig0_6->SH = (*linkageSetFIG0_6)->hard;
- fig0_6->ILS = (*linkageSetFIG0_6)->international;
+ fig0_6->ILS = ILS;
fig0_6->LSN = (*linkageSetFIG0_6)->lsn;
-#error "handle FIG insertion and CEI properly"
+ fig0->Length += sizeof(struct FIGtype0_6);
+ buf += sizeof(struct FIGtype0_6);
+ remaining -= sizeof(struct FIGtype0_6);
- fig0->Length += 2;
- buf += 2;
- remaining -= 2;
+ if (num_ids > 0) {
+ FIGtype0_6_header *header = (FIGtype0_6_header*)buf;
+ header->rfu = 0;
+ if (num_ids > 0x0F) {
+ etiLog.log(error, "Too large number of links for linkage set 0x%04x",
+ (*linkageSetFIG0_6)->lsn);
+ throw MuxInitException();
+ }
+
+ header->IdLQ = 0; // TODO not only DAB
+ header->rfa = 0;
+ header->num_ids = num_ids;
+
+ fig0->Length += headersize;
+ buf += headersize;
+ remaining -= headersize;
+
+ // TODO insert key service first
+ const std::string keyserviceuid =(*linkageSetFIG0_6)->keyservice;
+ const auto& keyservice = std::find_if(
+ ensemble->services.begin(),
+ ensemble->services.end(),
+ [&](const std::shared_ptr<DabService> srv) {
+ return srv->uid == keyserviceuid;
+ });
+
+ if (keyservice == ensemble->services.end()) {
+ etiLog.log(error, "Invalid key service %s in linkage set 0x%04x",
+ keyserviceuid.c_str(), (*linkageSetFIG0_6)->lsn);
+ throw MuxInitException();
+ }
+ for (const auto& l : (*linkageSetFIG0_6)->id_list) {
+ if (l.type != ServiceLinkType::DAB) {
+ etiLog.log(error, "TODO only DAB links supported. (linkage set 0x%04x)",
+ (*linkageSetFIG0_6)->lsn);
+ throw MuxInitException();
+ }
+ }
+
+ if (not PD and not ILS) {
+ buf[0] = (*keyservice)->id >> 8;
+ buf[1] = (*keyservice)->id & 0xFF;
+ fig0->Length += 2;
+ buf += 2;
+ remaining -= 2;
+
+ for (const auto& l : (*linkageSetFIG0_6)->id_list) {
+ buf[0] = l.id >> 8;
+ buf[1] = l.id & 0xFF;
+ fig0->Length += 2;
+ buf += 2;
+ remaining -= 2;
+ }
+ }
+ if (not PD and ILS) {
+ buf[0] = ensemble->ecc;
+ buf[1] = (*keyservice)->id >> 8;
+ buf[2] = (*keyservice)->id & 0xFF;
+ fig0->Length += 3;
+ buf += 3;
+ remaining -= 3;
+
+ for (const auto& l : (*linkageSetFIG0_6)->id_list) {
+ buf[0] = l.ecc;
+ buf[1] = l.id >> 8;
+ buf[2] = l.id & 0xFF;
+ fig0->Length += 3;
+ buf += 3;
+ remaining -= 3;
+ }
+ }
+ else { // PD == true
+ // TODO if IdLQ is 11, MSB shall be zero
+ buf[0] = (*keyservice)->id >> 24;
+ buf[1] = (*keyservice)->id >> 16;
+ buf[2] = (*keyservice)->id >> 8;
+ buf[3] = (*keyservice)->id & 0xFF;
+ fig0->Length += 4;
+ buf += 4;
+ remaining -= 4;
+
+ for (const auto& l : (*linkageSetFIG0_6)->id_list) {
+ buf[0] = l.id >> 24;
+ buf[1] = l.id >> 16;
+ buf[2] = l.id >> 8;
+ buf[3] = l.id & 0xFF;
+ fig0->Length += 4;
+ buf += 4;
+ remaining -= 4;
+ }
+ }
+ }
+
+ fig0->Length += required_size;
+ buf += required_size;
+ remaining -= required_size;
}
if (linkageSetFIG0_6 == ensemble->linkagesets.end()) {
diff --git a/src/fig/FIG0.h b/src/fig/FIG0.h
index 5a8a69f..0109219 100644
--- a/src/fig/FIG0.h
+++ b/src/fig/FIG0.h
@@ -29,6 +29,7 @@
#include <map>
#include <set>
#include <vector>
+#include <list>
#include "fig/FIG.h"
@@ -163,6 +164,27 @@ class FIG0_6 : public IFIG
std::list<std::shared_ptr<LinkageSet> >::iterator linkageSetFIG0_6;
};
+// FIG0/6 needs a change indicator, which is a short-form FIG (i.e. without the list)
+// and with C/N 1. Since this has another rate, it's implemented in another class.
+//
+// This is signalled once per second for a period of five seconds
+// (TS 103 176 5.2.4.3).
+class FIG0_6_CEI : public IFIG
+{
+ public:
+ FIG0_6_CEI(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 6; }
+
+ private:
+ FIGRuntimeInformation *m_rti;
+ bool m_initialised;
+ std::list<std::shared_ptr<LinkageSet> >::iterator linkageSetFIG0_6;
+};
+
// FIG type 0/8
// The Extension 8 of FIG type 0 (FIG 0/8) provides information to link
// together the service component description that is valid within the ensemble