From 0360110bfb7320f3310737b6b75da5f8cd96edb9 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 30 Sep 2016 16:13:12 +0200 Subject: Move FIG0 structures to separate file --- src/fig/FIG0structs.h | 347 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 347 insertions(+) create mode 100644 src/fig/FIG0structs.h (limited to 'src/fig/FIG0structs.h') diff --git a/src/fig/FIG0structs.h b/src/fig/FIG0structs.h new file mode 100644 index 0000000..a1e79d3 --- /dev/null +++ b/src/fig/FIG0structs.h @@ -0,0 +1,347 @@ +/* + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + 2011, 2012 Her Majesty the Queen in Right of Canada (Communications + Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + */ +/* + This file is part of ODR-DabMux. + + ODR-DabMux is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + ODR-DabMux is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ODR-DabMux. If not, see . +*/ + +#pragma once + +#include +#include +#include + +#include "fig/FIG.h" + +#ifdef _WIN32 +# pragma pack(push) +#endif + +struct FIGtype0 { + uint8_t Length:5; + uint8_t FIGtypeNumber:3; + uint8_t Extension:5; + uint8_t PD:1; + uint8_t OE:1; + uint8_t CN:1; +} PACKED; + + +struct FIGtype0_0 { + uint8_t Length:5; + uint8_t FIGtypeNumber:3; + uint8_t Extension:5; + uint8_t PD:1; + uint8_t OE:1; + uint8_t CN:1; + + uint16_t EId; + uint8_t CIFcnt_hight:5; + uint8_t Al:1; + uint8_t Change:2; + uint8_t CIFcnt_low:8; +} PACKED; + + +struct FIGtype0_2 { + uint8_t Length:5; + uint8_t FIGtypeNumber:3; + uint8_t Extension:5; + uint8_t PD:1; + uint8_t OE:1; + uint8_t CN:1; +} PACKED; + + +struct FIGtype0_2_Service { + uint16_t SId; + uint8_t NbServiceComp:4; + uint8_t CAId:3; + uint8_t Local_flag:1; +} PACKED; + + +struct FIGtype0_2_Service_data { + uint32_t SId; + uint8_t NbServiceComp:4; + uint8_t CAId:3; + uint8_t Local_flag:1; +} PACKED; + + +struct FIGtype0_2_audio_component { + uint8_t ASCTy:6; + uint8_t TMid:2; + uint8_t CA_flag:1; + uint8_t PS:1; + uint8_t SubChId:6; +} PACKED; + + +struct FIGtype0_2_data_component { + uint8_t DSCTy:6; + uint8_t TMid:2; + uint8_t CA_flag:1; + uint8_t PS:1; + uint8_t SubChId:6; +} PACKED; + + +struct FIGtype0_2_packet_component { + uint8_t SCId_high:6; + uint8_t TMid:2; + uint8_t CA_flag:1; + uint8_t PS:1; + uint8_t SCId_low:6; + void setSCId(uint16_t SCId) { + SCId_high = SCId >> 6; + SCId_low = SCId & 0x3f; + } +} PACKED; + + +/* Warning: When bit SCCA_flag is unset(0), the multiplexer R&S does not send + * the SCCA field. But, in the Factum ETI analyzer, if this field is not there, + * it is an error. + */ +struct FIGtype0_3 { + uint8_t SCId_high; + uint8_t SCCA_flag:1; + uint8_t rfa:3; + uint8_t SCId_low:4; + uint8_t DSCTy:6; + uint8_t rfu:1; + uint8_t DG_flag:1; + uint8_t Packet_address_high:2; + uint8_t SubChId:6; + uint8_t Packet_address_low; + uint16_t SCCA; + void setSCId(uint16_t SCId) { + SCId_high = SCId >> 4; + SCId_low = SCId & 0xf; + } + void setPacketAddress(uint16_t address) { + Packet_address_high = address >> 8; + Packet_address_low = address & 0xff; + } +} PACKED; + +struct FIGtype0_5_short { + uint8_t SubChId:6; + uint8_t rfu:1; + uint8_t LS:1; + + uint8_t language; +} PACKED; + +struct FIGtype0_8_short { + uint8_t SCIdS:4; + uint8_t rfa_1:3; + uint8_t ext:1; + uint8_t Id:6; + uint8_t MscFic:1; + uint8_t LS:1; + uint8_t rfa_2; +} PACKED; + + +struct FIGtype0_8_long { + uint8_t SCIdS:4; + uint8_t rfa_1:3; + uint8_t ext:1; + uint8_t SCId_high:4; + uint8_t rfa:3; + uint8_t LS:1; + uint8_t SCId_low; + uint8_t rfa_2; + void setSCId(uint16_t id) { + SCId_high = id >> 8; + SCId_low = id & 0xff; + } + uint16_t getSCid() { + return (SCId_high << 8) | SCId_low; + } +} PACKED; + + +struct FIGtype0_9 { + uint8_t Length:5; + uint8_t FIGtypeNumber:3; + uint8_t Extension:5; + uint8_t PD:1; + uint8_t OE:1; + uint8_t CN:1; + + uint8_t ensembleLto:6; + uint8_t rfa1:1; + uint8_t ext:1; + uint8_t ensembleEcc; + uint8_t tableId; +} PACKED; + + +struct FIGtype0_10_LongForm { + uint8_t Length:5; + uint8_t FIGtypeNumber:3; + + uint8_t Extension:5; + uint8_t PD:1; + uint8_t OE:1; + uint8_t CN:1; + + uint8_t MJD_high:7; + uint8_t RFU:1; + + uint8_t MJD_med; + + uint8_t Hours_high:3; + uint8_t UTC:1; + uint8_t ConfInd:1; + uint8_t LSI:1; + uint8_t MJD_low:2; + + uint8_t Minutes:6; + uint8_t Hours_low:2; + + uint8_t Milliseconds_high:2; + uint8_t Seconds:6; + + uint8_t Milliseconds_low; + + void setMJD(uint32_t date) { + MJD_high = (date >> 10) & 0x7f; + MJD_med = (date >> 2) & 0xff; + MJD_low = date & 0x03; + } + void setHours(uint16_t hours) { + Hours_high = (hours >> 2) & 0x07; + Hours_low = hours & 0x03; + } + + void setMilliseconds(uint16_t ms) { + Milliseconds_high = (ms >> 8) & 0x03; + Milliseconds_low = ms & 0xFF; + } +} PACKED; + + +struct FIGtype0_17 { + uint16_t SId; + + uint8_t rfa2_high:4; + uint8_t rfu1:2; + uint8_t rfa1:1; + uint8_t SD:1; // Static/Dynamic + + uint8_t IntCode:5; + uint8_t rfu2:1; + uint8_t rfa2_low:2; +} 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_19 { + uint8_t ClusterId; + uint16_t ASw; + uint8_t SubChId:6; + uint8_t RegionFlag:1; // shall be zero + uint8_t NewFlag:1; + // Region and RFa not supported +} PACKED; + +struct FIGtype0_1 { + uint8_t Length:5; + uint8_t FIGtypeNumber:3; + uint8_t Extension:5; + uint8_t PD:1; + uint8_t OE:1; + uint8_t CN:1; +} PACKED; + + +struct FIG_01_SubChannel_ShortF { + uint8_t StartAdress_high:2; + uint8_t SubChId:6; + uint8_t StartAdress_low:8; + uint8_t TableIndex:6; + uint8_t TableSwitch:1; + uint8_t Short_Long_form:1; +} PACKED; + + +struct FIG_01_SubChannel_LongF { + uint8_t StartAdress_high:2; + uint8_t SubChId:6; + uint8_t StartAdress_low:8; + uint8_t Sub_ChannelSize_high:2; + uint8_t ProtectionLevel:2; + uint8_t Option:3; + uint8_t Short_Long_form:1; + uint8_t Sub_ChannelSize_low:8; +} PACKED; + + +// See EN 300 401, Clause 8.1.20 for the FIG0_13 description +struct FIG0_13_shortAppInfo { + uint16_t SId; + uint8_t No:4; + uint8_t SCIdS:4; +} PACKED; + + +struct FIG0_13_longAppInfo { + uint32_t SId; + uint8_t No:4; + uint8_t SCIdS:4; +} PACKED; + + +struct FIG0_13_app { + uint8_t typeHigh; + uint8_t length:5; + uint8_t typeLow:3; + void setType(uint16_t type) { + typeHigh = type >> 3; + typeLow = type & 0x1f; + } + uint16_t xpad; +} PACKED; + +#define FIG0_13_APPTYPE_SLIDESHOW 0x2 +#define FIG0_13_APPTYPE_WEBSITE 0x3 +#define FIG0_13_APPTYPE_TPEG 0x4 +#define FIG0_13_APPTYPE_DGPS 0x5 +#define FIG0_13_APPTYPE_TMC 0x6 +#define FIG0_13_APPTYPE_EPG 0x7 +#define FIG0_13_APPTYPE_DABJAVA 0x8 +#define FIG0_13_APPTYPE_JOURNALINE 0x441 + + +#ifdef _WIN32 +# pragma pack(pop) +#endif + -- cgit v1.2.3 From f198d1a2c799c97fe1e4e92e110cc0782f6f7880 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 30 Sep 2016 17:10:43 +0200 Subject: Add some FIG0/6 structures and skeleton --- src/fig/FIG0.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/fig/FIG0.h | 28 +++++++++++++++++++++ src/fig/FIG0structs.h | 19 ++++++++++++++ 3 files changed, 116 insertions(+) (limited to 'src/fig/FIG0structs.h') diff --git a/src/fig/FIG0.cpp b/src/fig/FIG0.cpp index bb08fac..b560e4c 100644 --- a/src/fig/FIG0.cpp +++ b/src/fig/FIG0.cpp @@ -662,6 +662,75 @@ FillStatus FIG0_5::fill(uint8_t *buf, size_t max_size) return fs; } +//=========== FIG 0/6 =========== + +FIG0_6::FIG0_6(FIGRuntimeInformation *rti) : + m_rti(rti), + m_initialised(false) +{ +} + +FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size) +{ + FillStatus fs; + ssize_t remaining = max_size; + auto ensemble = m_rti->ensemble; + + if (not m_initialised) { + linkageSetFIG0_6 = m_rti->ensemble->linkagesets.end(); + m_initialised = true; + } + + FIGtype0* fig0 = NULL; + + for (; linkageSetFIG0_6 != ensemble->linkagesets.end(); + ++linkageSetFIG0_6) { + + const int required_size = 2; + + if (fig0 == NULL) { + if (remaining < 2 + required_size) { + break; + } + fig0 = (FIGtype0*)buf; + fig0->FIGtypeNumber = 0; + fig0->Length = 1; + fig0->CN = 0; + fig0->OE = 0; + fig0->PD = 0; + fig0->Extension = 5; + + buf += 2; + remaining -= 2; + } + else if (remaining < required_size) { + break; + } + + FIGtype0_6 *fig0_6 = (FIGtype0_6*)buf; + + fig0_6->IdListFlag = 1; + fig0_6->LA = (*linkageSetFIG0_6)->active; + fig0_6->SH = (*linkageSetFIG0_6)->hard; + fig0_6->ILS = (*linkageSetFIG0_6)->international; + fig0_6->LSN = (*linkageSetFIG0_6)->lsn; + +#error "handle FIG insertion and CEI properly" + + fig0->Length += 2; + buf += 2; + remaining -= 2; + } + + if (linkageSetFIG0_6 == ensemble->linkagesets.end()) { + linkageSetFIG0_6 = ensemble->linkagesets.begin(); + fs.complete_fig_transmitted = true; + } + + fs.num_bytes_written = max_size - remaining; + return fs; +} + //=========== FIG 0/8 =========== FIG0_8::FIG0_8(FIGRuntimeInformation *rti) : diff --git a/src/fig/FIG0.h b/src/fig/FIG0.h index 25aea15..5a8a69f 100644 --- a/src/fig/FIG0.h +++ b/src/fig/FIG0.h @@ -28,6 +28,7 @@ #include #include #include +#include #include "fig/FIG.h" @@ -135,6 +136,33 @@ class FIG0_5 : public IFIG std::vector::iterator componentFIG0_5; }; +// FIG type 0/6 +// Service Linking +// +// This feature shall use the SIV signalling (see clause 5.2.2.1). The database +// shall be divided by use of a database key. Changes to the database shall be +// signalled using the CEI. The first service in the list of services in each +// part of the database, as divided by the database key, shall be a service +// carried in the ensemble. This service is called the key service. +// +// The database key comprises the OE and P/D flags and the S/H, ILS, and LSN +// fields. +class FIG0_6 : public IFIG +{ + public: + FIG0_6(FIGRuntimeInformation* rti); + virtual FillStatus fill(uint8_t *buf, size_t max_size); + virtual FIG_rate repetition_rate(void) { return FIG_rate::E; } + + 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 >::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 diff --git a/src/fig/FIG0structs.h b/src/fig/FIG0structs.h index a1e79d3..4b9b7e0 100644 --- a/src/fig/FIG0structs.h +++ b/src/fig/FIG0structs.h @@ -152,6 +152,25 @@ struct FIGtype0_5_short { uint8_t language; } PACKED; +struct FIGtype0_6 { + uint16_t IdListFlag:1; + uint16_t LA:1; // Linkage actuator + uint16_t SH:1; // 0=Soft link / 1=Hard link + uint16_t ILS:1; // 0=national / 1=international + uint16_t LSN:12; // Linkage Set Number +} PACKED; + +#define FIG0_6_IDLQ_DAB 0x0 +#define FIG0_6_IDLQ_RDS 0x1 +#define FIG0_6_IDLQ_DRM_AMSS 0x3 + +struct FIGtype0_6_header { + uint8_t rfu:1; // must be 0 + uint8_t IdLQ:2; // Identifier List Qualifier, see above defines + uint8_t rfa:1; // must be 0 + uint8_t num_ids:4; // number of Ids to follow in the list +} PACKED; + struct FIGtype0_8_short { uint8_t SCIdS:4; uint8_t rfa_1:3; -- cgit v1.2.3 From 3342f01f9a0e6f1effc7a698208a072d4a120ff8 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 3 Oct 2016 21:29:29 +0200 Subject: Fix byte order in FIG0/6 structures --- src/fig/FIG0_6.cpp | 5 +++-- src/fig/FIG0structs.h | 23 +++++++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) (limited to 'src/fig/FIG0structs.h') diff --git a/src/fig/FIG0_6.cpp b/src/fig/FIG0_6.cpp index 20fe78b..7c09078 100644 --- a/src/fig/FIG0_6.cpp +++ b/src/fig/FIG0_6.cpp @@ -87,7 +87,7 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size) fig0_6->LA = linkageSetFIG0_6->active; fig0_6->SH = linkageSetFIG0_6->hard; fig0_6->ILS = ILS; - fig0_6->LSN = linkageSetFIG0_6->lsn; + fig0_6->setLSN(linkageSetFIG0_6->lsn); fig0->Length += sizeof(struct FIGtype0_6); buf += sizeof(struct FIGtype0_6); @@ -125,7 +125,6 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size) 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(), @@ -208,6 +207,8 @@ void FIG0_6::update() { linkageSubsets.clear(); + // TODO check if AMSS and DRM have to be put into a single subset + for (const auto& linkageset : m_rti->ensemble->linkagesets) { const auto lsn = linkageset->data.lsn; diff --git a/src/fig/FIG0structs.h b/src/fig/FIG0structs.h index 4b9b7e0..3b9bfbf 100644 --- a/src/fig/FIG0structs.h +++ b/src/fig/FIG0structs.h @@ -153,11 +153,18 @@ struct FIGtype0_5_short { } PACKED; struct FIGtype0_6 { - uint16_t IdListFlag:1; - uint16_t LA:1; // Linkage actuator - uint16_t SH:1; // 0=Soft link / 1=Hard link - uint16_t ILS:1; // 0=national / 1=international - uint16_t LSN:12; // Linkage Set Number + uint8_t LSN_high:4; // Linkage Set Number + uint8_t ILS:1; // 0=national / 1=international + uint8_t SH:1; // 0=Soft link / 1=Hard link + uint8_t LA:1; // Linkage actuator + uint8_t IdListFlag:1; // Marks the presence of the list + + uint8_t LSN_low; // Linkage Set Number + + void setLSN(uint16_t LSN) { + LSN_high = LSN >> 8; + LSN_low = LSN & 0xff; + } } PACKED; #define FIG0_6_IDLQ_DAB 0x0 @@ -165,10 +172,10 @@ struct FIGtype0_6 { #define FIG0_6_IDLQ_DRM_AMSS 0x3 struct FIGtype0_6_header { - uint8_t rfu:1; // must be 0 - uint8_t IdLQ:2; // Identifier List Qualifier, see above defines - uint8_t rfa:1; // must be 0 uint8_t num_ids:4; // number of Ids to follow in the list + uint8_t rfa:1; // must be 0 + uint8_t IdLQ:2; // Identifier List Qualifier, see above defines + uint8_t rfu:1; // must be 0 } PACKED; struct FIGtype0_8_short { -- cgit v1.2.3