Autor: Hanns-Jörns Haug

How about encoding the TPEG-SID within the DAB/DMB service-label

22.07.2019 DAB Keine Kommentare

One of the most useful DAB/DMB data-applications is TPEG, the newer and most often much better traffic service compared to TMC.
In-car infotainment systems with TPEG support (for the navigation function) face one problem with the way this data service is signaled by DAB/DMB metadata.
The DAB/DMB meta-data about a service misses the TPEG-SID. There has been a proposal to supply this data within the (normally unused) user-application-data field (of FIG 0/13); unfortunately, no one ever followed this suggestion.
Instead, to know about the TPEG-SID of a DAB/DMB service carrying TPEG, the tuner has to tune to that service and listen to the content for a while, until this TPEG-SID is received.
Why is the TPEG-SID important?
It is not always important. It depends on the way a navigation system decides which TPEG service should be received. If a navigation system has contracts with specific TPEG providers (often paid), they usually select among the receivable TPEG services by means of the TPEG-SID (the navigation system will have built in knowledge about that providers TPEG-SIDs).

Typically, in-car infotainment systems do not have a dedicated DAB tuner device reserved for TPEG. Often, we see a dual tuner setup where one tuner serves the current audio/video source, the other timeslices between band-scan and data service reception (TPEG/EPG).

With the need to tune into each newly receivable DAB/DMB service for TPEG to know about the TPEG-SID, the ‚productive‘ TPEG delivery is interrupted.
Most often the TPEG-SID is found very fast, but often it is not – sometimes providers do not behave well, sometimes reception issues are a cause.

So, the idea is to encode the TPEG-SID within the service-label. This means, the SID can be parsed from DAB metadata directly without the need to tune the ensemble and select the service.

Examples:
Instead of                name it
—————————————————
‚TPEG‘                    ‚TPEG$010203$‘
‚TPEG_MM‘           ‚TPEG_MM$XXXXXX$‘
‚KBS TPEG‘           ‚KBS_TPEG$640301$‘

Everything enclosed by the $ sign is the TPEG-SID encoded as ASCII hex (XXXXXX of course is a placeholder).
It is possible that some dedicated navigation systems use the label to recognize a service.
In that case the DAB provider could signal two DAB services pointing to the very same data source; one service would use the original service-label and DAB service-id, the new one would use the new label. This way we can avoid updating such systems.
This method does not fit directly, should a DAB/DMB service ever carry two or more different TPEG services. However, I have never seen that in the wild.
For such a ‚double service‘ case we could name a service ‚$010203$$010204$‘ to extend this scheme; or we could add additional DAB-services with individual labels, but pointing to the very same data source.
I’m quite sure that this is just another proposal that will never be adopted on a larger scale or even at all by anyone.
However, even a single TPEG provider could introduce this method as an additional way to optimize newer infotainment systems that use its services.
No need to say ‚all or nothing‘.

DAB Slideshow und TID Providerfehler

04.11.2013 Allgemein Keine Kommentare

Der DAB Standard und fast alle unterlagerten oder ergänzenden Standards sind komplex und lassen leider viele Freiräume.
Daher ist die fehlerfreie Implementierung von Software für Empfangs- und Sendeequipment nicht trivial.

Empfangsequipment hat es dabei doppelt schwer, denn zu den korrekten Variationen des Standards kommen hier noch die fehlerbedingten Variationen, die durch die Provider generiert werden, die senderseitig fehlerhafte Software einsetzen oder falsche Konfigurationen verwenden.

Im Premiumbereich ist es nicht genug, wenn der Empfänger Fehlerfälle irgendwie erkennen kann und rechtzeitig Schaden verhindert; das ist lediglich das erwartete Minimum.

Kunden von DAB Empfängern sind häufig Autombilhersteller und die sind erfreulich anspruchsvoll.
Liefert auch nur irgendein Empfänger am Markt oder ein Testgerät in einer bestimmte Fehlersituation eine bessere (oder auch nur besser scheinende) User-Experience, dann wird dieses ‚bessere‘ Verhalten ganz sicher auch am eigenen Gerät gefordert.

Als Entwickler befindet man sich hier in dem Dilemma, aus etwas grundsätzlich Falschem noch etwas leidlich Richtiges zu machen; ohne aber, um Himmels willen, etwas Falsches sichtbar werden zu lassen.

Exemplarisch hierfür steht ein noch immer wieder vorkommender Providerfehler bei der DAB Slideshow (SLS).

Die SLS benutzt als Transportschicht MOT (MultiMediaObject-Transfer) im Headermode, dessen Kenntnis hier vorausgesetzt wird, lediglich grob will ich die Grundzüge skizzieren:

Im Headermode wird ein Objekt (Datei) nach dem anderem übertragen, im Falle der SLS also ein Bild nach dem anderen. Es gibt immer ein aktuelles Bild – das zuletzt vollständig übertragene – und es gibt die laufende Übertragung des nachfolgenden Bildes oder der direkten Wiederholung.

Ein Objekt besteht im MOT Protokoll aus einem Body, der den reinen binären Inhalt fasst (also den Dateiinhalt) und einem Header, der die Metadaten zum Body liefert (Bodygröße, Namen,…, Steuerinformationen).

Da ein Body groß sein kann, wird er in nummerierten Segmenten übertragen, die der Empfänger in richtiger Folge zusammenbauen muss.
Der Header kann prinzipiell ebenfalls in Segmenten übertragen werden, was im Falle der SLS aber nicht zu erwarten ist; ein SLS Header ist typisch klein und ich habe bislang nicht gesehen, dass dazu mehr als ein Segment eingesetzt wurde.

Im Strom der empfangenen Segmente werden Segmente für Header oder Body mittels einer Typkennung unterschieden (Datengruppentyp).

Die Gruppierung der Segmente zu einem Objekt und die Zusammengehörigkeit von Header und Body erreicht man mit der 16 Bit breiten Transport-Id (TID), die Teil eines jeden Segments ist.
Die TID kann als eine Art MOT-interner Name für ein Objekt verstanden werden, wobei die Einmaligkeit dieses Namens aber nur in einem begrenzten Zeitraum gewährleistet sein kann; über einen längeren Zeitraum (im Headermode Tage, eher Wochen) werden aber sehr wohl neue Objekte mit einer früher verwendeten TID übertragen.

Daher gilt die MOT-Vorschrift:  Jedes neue Objekt MUSS mit einer unterschiedlichen TID vom zuletzt gesendeten übertragen werden.
Es ist leider nicht festgelegt, dass z.B. die TID ständig inkrementiert werden muss und bei Erreichen des Maximums umläuft.
Es ist lediglich bestimmt, dass eine verwendete TID möglichst spät erneut ins Spiel gebracht werden darf.

Da im Headermode zu einer Zeit immer nur ein Objekt übertragen wird bedeutet diese Regel für den MOT Decoder, dass mit dem Empfang einer neuen TID alle bislang empfangenen Segmente eines unvollständigen Objektes hinfällig sind und gelöscht werden müssen.

Solange die TID unverändert bleibt, handelt es sich um Segmente desselben Objektes.
Auch das kann über lange Zeit ständig wiederholt werden, was durchaus sinnvoll ist.

Soll z.B. für die Dauer der Übertragung von Ravels Bolero das Plattencover zu sehen sein, ist eine Wiederholung geradezu zwingend; ohne Wiederholung müsste man bei leicht verspätetem Einschalten oder dem fehlerhaften Empfang eines einzigen Segmentes für 15 Minuten auf den Genuss des sichtbaren SLS Service verzichten.

Es gibt keine weiteren Regeln für Wiederholungen der Segmente. Man kann alle Segmente der Reihe nach wiederholen, oder jedes Segment mehrfach, Header vielleicht häufiger, frei nach Gusto.
Für den Bolero empfiehlt sich sicher die jeweils komplette Übertragung in Segmentfolge, da so auch der schnellstmögliche Erstempfang des kompletten Bildes bei guten Bedingungen möglich ist.

Dem Empfänger ist zunächst nicht bekannt, wie viele Segmente zur Übertragung eines Body benötigt werden. Jedes Segment enthält das Flag ‚LastSegment‘ . Erst wenn das Segment mit gesetztem ‚LastSegment‘ empfangen ist, ist implizit auch die Segmentnummer des letzten Segmentes bekannt und damit die Anzahl der Segmente.
Das kann früh oder spät der Fall sein, da die Segmente in beliebiger Reihenfolge  eintreffen können; bei Wiederholungen oder Empfangsstörungen ist das nicht nur von der Sendefolge abhängig, sondern auch vom Einschaltzeitpunkt und zufälligen Aussetzern.

Wissenswert ist noch, dass alle Segmente einer MOT-Entity (meint Header oder Body) gleich groß sein müssen, mit Ausnahme freilich des letzten Segmentes, das typischerweise kleiner ist.
Das ist eine der Regeln, die ich bislang nie verletzt sah – vermutlich nur deshalb, weil Provider durchgehend eine gleichbleibende Segmentgröße bevorzugen.

Die Integrität von Header und Body kann leider nur über die TID vermutet werden. Die Korrektheit des gesamten Body ist nur bei korrektem Zusammenbau der richtigen Segmente gewährleistet. Es gibt keine Checksumme über den gesamten Body, lediglich die Segmente haben über den Datagroup-CRC einen individuellen optionalen Schutz, der glücklicherweise auch verwendet wird.
Hilfreich wäre die Übertragung eines Body-CRC im Header, weil dies eine zusätzliche Prüfung der Integrität ermöglichte.
Das kann man dem Standard nicht als Mangel anlasten, denn der vorgeschriebene Wechsel der TID bei Objektwechsel wäre vollkommen ausreichend, könnte man sich auf die Provider verlassen.

Und das ist der hier behandelte Providerfehler:

Es kommt immer wieder vor, dass Provider für aufeinander folgende, unterschiedliche Objekte dieselbe TID verwenden.

Es wurde beobachtet, dass eine TID einen ganzen Tag lang verwendet wurde oder, dass eine TID für einen unbestimmten, längeren Zeitraum verwendet wurde. London/Heart benutzte eine Weile systematisch für jeweils zwei aufeinander folgende, aber unterschiedliche Slides eine ID und dann eine neue für zwei weitere.

Für einen mobilen Empfänger in einem Fahrzeug ändern sich die Empfangsbedingungen ständig und Empfangsausfälle sind wahrscheinlich. Hier wird klar, dass auch die zu schnelle Wiederverwendung einer TID (z.B. die Sequenz: 1, 2, 3, 1, 2, 3, 1 …) auf das gleiche hinauslaufen kann.
Fallen einzelne Segmente der TID 1 aus und dann alle Segmente der TID 2 und 3, dann kann der Empfänger die neuen Segmente mit TID 1 dem zuvor empfangenen unvollständigen Objekt zuordnen.

Als Entwickler von Empfängersoftware kann man nicht den Paradigmen folgen, die für Sendeequipment gelten. Dort kann man geplante Sequenzen verbindlich abwickeln, für den Empfänger hingegen herrscht begrenztes Chaos.

Wo liegt  nun das Risiko?

Kommt es unbemerkt zur Mischung von Segmenten verschiedener Objekte, dann wird der MOT Decoder der Slideshow-Applikation ein verstümmeltes Bild abliefern. Die Viewer, die letztlich für die Darstellung auf dem Display sorgen, erkennen diese Fehler meist nicht und es kommt zu unschönen Abbildungen. Abstürze der Viewer habe ich noch nicht beobachtet, aber der deutlich sichtbare Fehler wird zunächst einmal dem Empfänger angelastet.

Oft kann auch noch nachgewiesen werden, dass ein anderer Empfänger in derselben Situation bessere Resultate liefert, womit fast schon der Beweis für einen Empfängerfehler erbracht zu sein scheint.
Das ist für dieses Phänomen jedoch normalerweise nicht so. Vielmehr sind unterschiedliche Samplingstrategien der MOT-Decoder dafür verantwortlich, dass der eine in dieser, der andere in jener Situation auf der glücklicheren Seite steht.

Was kann man tun?

Auch wenn man nachweisen kann, dass das Problem ursächlich beim Contentprovider oder am Sender liegt – man muss versuchen, eine möglichst gute Figur zu machen.

Freilich gilt es zunächst auszuloten, wie sich Fehlzuordnungen trotz gleicher TID vermeiden lassen.

Ich sehe die folgenden Möglichkeiten und werde sie auch gleich bewerten (freilich nach meinen bisherigen Erfahrungen):

Extension Parameter ‚Content Name‘

Der Header enthält u. A. den ContentName des Objektes, also faktisch den Dateinamen.
Empfangen wir einen neuen Header mit zwar unzulässig gleicher TID aber anderem ContentName, dann muss dieser Header zu einem neuen Objekt gehören und man könnte also alle bislang empfangenen Segmente löschen.

Bewertung:
Leider fast nie hilfreich. Praktisch jeder Provider benutzt stets dauerhaft denselben ContentName (z.B. slide.jpg). Lediglich bei der seltenen Enhanced Slideshow hat der ContentName eine echte Bedeutung.
Selbst wenn das aber vorkommen könnte, so kann man sich nicht sicher sein, ob nicht die bislang empfangenen Segmente zu eben diesem neuen Header gehören. Wie gesagt, die Reihenfolge der Segmente ist beliebig; der Header kann den Bodysegmenten voranstehen, nachfolgen oder beliebig eintreffen. Würde man diese Strategie anwenden und wären die Namen immer andere, aber käme der Header immer zuletzt, dann könnte man niemals ein fertiges Objekt präsentieren.

Header-Core Element ‚BodySize‘

Jeder Header überträgt die Sollgröße des zugeordneten Body. Dieser Wert lässt sich zweifach zur Konsistenzprüfung nutzen.

1. Sind alle Bodysegmente empfangen, so ist auch die tatsächliche Bodygröße bekannt, die kumulierte Größe aller Segmente.
Diese Größe sollte etwa der Angabe im Header entsprechen. Einen geringfügig größeren Wert würde ich nicht zwingend ausschließen wollen, möglicherweise enthält das letzte Segment einige Bytes an Padding, um irgendwelchen Mindestgrößen des Providersytems zu entsprechen (2 Byte, 4 Byte oder Paragraph).
Keinesfalls darf die kumulierte Größe kleiner sein als die ‚BodySize‘ und sie darf auch nicht deutlich größer sein.

Bewertung:
Es kann sein, dass der Body falsch gemixt ist, weil z.B. das korrekte LastSegment nicht empfangen wurde und stattdessen ein früheres mit einer kleineren Segmentnummer verwendet wurde.
Es kann aber auch sein, dass der Body völlig korrekt ist und lediglich der passende, neuere Header nicht empfangen wurde.
Sicher wird man sich entscheiden, das Bild nicht zur Anzeige zu bringen; ein anderer, etwas mutigere oder  leichtfertigere Empfänger kann aber im Einzelfall Glück haben und ein korrektes Bild anzeigen.

2. Ähnlich wie oben beim Extension-Parameter ‚ContentName‘ bedeutet der Empfang eines Headers mit gleicher TID aber anderer BodySize gegenüber dem zuletzt empfangenen Header, dass es sich tatsächlich um ein neues Objekt handeln muss.

Bewertung:
Auch in diesem Fall steht die Verwertbarkeit der bislang empfangenen Segmente zur Disposition. Auch hier ist aber nicht sicher, ob nicht die bereits empfangenen Bodysegmente schon zu diesem neuen Objekt  gehören.

Erneuter Empfang des letzten Segmentes mit anderer Segmentnummer

Das ist freilich ein klares Indiz für unseren Providerfehler und das kann vorkommen, wenn das neue Objekt in der Bodygröße hinreichend abweicht.

Bewertung:
Sicher ist, dass alle empfangenen Segmente mit nun zu großer Segmentnummer falsch sein müssen, mehr aber auch nicht. Sollte das neue Last-Segment eine größere Segmentnummer haben, als das vorangegangene,  kann man kein Segment ausschließen, außer eben dem zuerst empfangenen LastSegment.
Wenn man bei der Speicherung der empfangenen Segmente etwas mehr Aufwand treibt und zusätzlich die Reihenfolge des Empfangs vermerkt, dann kann man sicher alle Segmente löschen, die bis einschließlich des zuerst empfangenen Last-Segment eintrafen. Damit ist zwar sicher, dass diese Segmente falsch sind, nicht aber, dass die danach empfangenen richtig sind.

Wechsel der Segmentgröße

Vorschrift ist, dass alle Segmente einer Entity (für uns hier eines Body) die gleiche Segmentgröße haben müssen, mit Ausnahme freilich des letzten.
Wechselt also bei gleicher TID plötzlich die Segmentgröße, so kann auch das als versteckter Objektwechsel gesehen werden.

Bewertung:
Keinerlei praktische Bedeutung, weil alle mir bekannten Services durchgängig dieselbe Segmentgröße für alle non-last Segmente aller Entities verwenden. Ein Wechsel kommt allenfalls bei grundlegender Änderung der Serverkonfiguration vor, nicht aber objektabhängig.
Eher kann man bei einer wechselnde Segmentgröße innerhalb einer Entity auf einen Übertragungsfehler schließen, falls die Datengruppe, die das Segment transportiert ohne CRC gesendet wurde, was aber ebenfalls unwahrscheinlich ist.

Segment-Sampling Strategie

Warum kommen nun verschiedene Empfänger bei diesem TID-Providerfehler zu unterschiedlich guten Ergebnissen. Die oben beschriebenen Erkennungsstrategien greifen nur bedingt und eine zu enge Auslegung kann auch die Anzeige korrekter Slides verhindern.

Im Wesentlichen ist es die Strategie nach der empfangene Segmente aufgesammelt werden, bis alle Segmente vorliegen.

Grundsätzlich gibt es zwei Möglichkeiten:

1.
Man optimiert im Hinblick auf geringstmögliche Dynamik und Rechenlast.
In diesem Fall sieht man jedes Segment mit TID t und Segmentnummer n als schlichte Wiederholung, wenn man bereits ein Segment mit diesen Werten gespeichert hat. Man wird dieses neue Segment also schnellstmöglich verwerfen und nichts weiter unternehmen.

2.
Man optimiert einfach nicht, speichert jedes empfangene Segment ab, wobei ggf. ein bereits empfangenes überschrieben oder gelöscht wird, je nach Art des Repository.

Damit lassen sich die unterschiedlichen Ergebnisse leicht erklären. Tests mit beiden Varianten, angewandt auf ETI-Files (Ensemble-Aufzeichnungen) von fehlerhaften Ausstrahlungen, belegen dies auch.

Eigentlich sollte die zweite, schlichtere Variante grundsätzlich leistungsfähiger sein, im Hinblick auf die Anwendererfahrung. Schließlich kommen Segmente des neuen Objektes nach einem Objektwechsel grundsätzlich zeitlich nach denen des alten Objektes. Es gibt jedoch Fälle, in denen das verwässert wird.
Häufig werden Bilder im Wechsel mit anderen Wiederholt, z.B. wechselt ein Stationslogo mit dem aktuellen Plattencover. So kann es durchaus geschehen, dass bei schlechtem Empfang ein Teil der Logo-Segmente abgespeichert wird, die zwischenzeitlich einkommenden Segmente eines Cover werden als Wiederholung verworfen und schließlich empfängt man glücklich das letzte Segment des erneut ausgestrahlten Logo.
Ziemlich unwahrscheinlich?
Stimmt, kommt aber vor und normalerweise wird eine Erklärung erwartet.

Generell aber bleibt es dabei, die Übernahme des jeweils zuletzt empfangenen Segmentes bringt statistisch die besseren Ergebnisse, weshalb sie bevorzugt werden sollte.

Signalisierung neuer Objekte

Ein Problem bleibt noch im Zusammenhang mit diesem TID-Providerfehler.

Gehen wir von einer naheliegenden Architektur aus:
Ein MOT Headermode-Decoder  (nicht SLS spezifisch) wickelt das MOT Empfangsprotokoll ab und puffert das zuletzt fertig empfangene Bild.
Eine Slideshow Applikation benutzt den MOT Decoder, kann dessen Status erfragen und lässt sich ereignisgesteuert über relevante Statusänderungen informieren.

Das wichtigste Ereignis ist sicher der vollendete Empfang eines neuen Bildes (Header-Updates betrachten wir hier nicht). Meist soll ein neu empfangenes Bild unverzüglich zur Anzeige gebracht werden.
Dieses Ereignis nennen wir onNewObject(…).

Ausdrücklich heißt es hier ‚New‘, denn Objektwiederholungen sind normalerweise nicht relevant; es gibt keinen Grund, das bereits angezeigte Bild erneut durch alle Schichten zu reichen und am Display ggf. ein Flackern zu verursachen. Schließlich sollten Wiederholungen normalerweise vorkommen dürfen, denkt man an den Bolero.
Also werden Wiederholungen nicht signalisiert, sie sind lediglich ein Phänomen der Übertragungsschicht und kein Anwendungsereignis.

Verwendet ein Provider nun aber immer die gleiche TID, dann funktioniert die normale Erkennung auf ‚Neuheit‘ eben nicht.

Der MOT Decoder sollte also über eine Option verfügen, auch Wiederholungen zu signalisieren.
Dasselbe kann eine Art Reset des Decoders bewirken, unmittelbar ausgelöst nach Auslesen des gerade empfangenen Objekts; ohne Gedächtnis ist für den Decoder das nächste Objekt auf jeden Fall wieder ‚neu‘.

Es bleibt dann der Client-Applikation überlassen was zu tun ist. Sie kann jedes Bild zur Anzeige bringen oder versuchen mittels der Metadaten oder gar durch binären Contentvergleich die Neuheit abzusichern.

 

DAB: Double-byte contents indicators in variable-size X-PAD

02.11.2012 Allgemein Keine Kommentare

This short article presumes serious understanding of the DAB protocol.

This very special DAB topic is a little older. Double-byte contents indicators do not appear in newer versions of any DAB spec. If you are involved in the development of provider equipment that encodes data via X-PAD you can safely ignore all this entirely.
If you work on receiver decoders however, there is a very small risk that your software will be fed with X-PAD data sometimes that uses double byte indicators; simply because there are documents around that do describe them.

Many PAD parsers do not care about double-byte contents indicators for a simple reason:
Double-byte contents indicators are not even mentioned in EN 300 401 –  and TR 101 496-2 is not widely known amongst developers.

Is it important?
– Yes and no:
I never have seen double-byte indicators in real life and I’m not sure if anyone does use them. I’m very sure that a normal radio equipment need not be able to understand the services that someone indicates by double-byte indicators.

However, if a parser is not prepared for double-byte indicators it may interpret the second byte of the first double-byte indicator as a normal indicator itself and this might cause big trouble.

What are double-byte contents indicators?

A normal contents indicator is one byte in size and carries 5 bits for the XpadApplicationType and 3 bits as the length indicator. A double-byte contents indicator has a value of 31 in the XpadApplicationType bit-field of the first byte and is immediately followed by a second byte that extends the XpadApplicationType; so the resulting XpadApplicationType value is 31 plus the value of the second byte.

According to EN 300 401 an XpadApplicationType  value of 31 is simply ‘not used’, according to TR 101 496-2 however, a value of 31 indicates the first byte of a double-byte indicator.

A simple solution:

If a parser shall not care about the applications indicated by double-byte contents indicators but shall work correctly for all other applications in all situations it may follow this simple procedure:

  • If the XpadApplicationType of the first byte in the contents indicator list is 31:
    -> forget the entire X-PAD field!
  • If the contents indicator list starts with two normal single byte contents indicators and the XpadApplicationType of the third byte is 31:
    -> assume the contents indicator list is 4 byte long (this is the offset of the first subfield) and consume only the subfields for the first two applications.
  • If an XpadApplicationType of 31 should appear in the second byte after one normal single-byte contents indicator or in the fourth byte after three normal single-byte contents indicators:
    -> this is illegal and I suggest to discard the entire X-PAD field!

Since it is not allowed to let a single-byte indicator follow a double-byte indicator, this solution should be safe and complete.

It is not too hard to parse even double-byte indicators correctly but this recipe can quickly fix older parsers.

understanding the CRC flag of MSC datagroups in DAB

26.10.2012 DAB Keine Kommentare

If you work on DAB data services like EPG, SLS (slideshow), BWS (broadcast website), Journaline or TPEG, this article might be worth reading.

As a programmer of software for the DAB radio standard you surely have often faced problems that have their roots in the lots of options the standard leaves open.
One of those problems is the proper handling of the CRC-flag that is broadcast within the MSC data group header. I will cover that in this short article.

If you concentrate on stationary radios this considerations may not be much important, but mobile receivers (think of automotive) may benefit a lot from a little deeper understanding.

In short, an MSC data group is a standard structure to carry data chunks of up to 8191 bytes within DAB ensembles. Different transport mechanisms are used to carry such datagroups.
An MSC datagroup consists of one mandatory header, some optional headers, a data field and an optional CRC placed behind the data field.
! Worth to note: an entire data group with all headers, data field and CRC may be a little larger than 8 KB (i.e. larger than 8192 bytes), which can easily be overseen when defining static buffers !!

Unfortunately the CRC is optional.
Even worse, the information whether there is a CRC or not is transmitted within the data group itself; it is the second bit within the mandatory MSC data group header.

What is the problem with that definition?
Since the CRC-flag is part of the data to be protected it may (in principal) as easily be corrupted as any other bit of the data group.
If the flag happens to switch from a transmitted ‘1’ to a received ‘0’ the receiver has to assume that there is no CRC placed behind the data field.
The receiver has to accept the data with all risks.

Of course the best would have been to simply make the CRC mandatory. At least the CRC-flag should be meta-data transmitted elsewhere at a high protection level (e.g. in FIG0/13 for all data groups of a data application) instead of being part of the data transmission itself.
But useless to complain about, we have to find ways to accept as much data groups as possible while discovering as many transmission errors as possible.

Obviously there is no problem if the CRC flag switches from ‘0’ to ‘1’. In that case the receiver would do a CRC check against a non existing CRC and that would most likely fail; good so far because the data group is corrupted, at least in one bit.

To be as smart as possible with the other case we have to examine the lower level transport mechanisms.

An MSC data group may be broadcast within the X-PAD channel of an audio stream sub-channel or within a data sub-channel using packets. Let’s look at each in detail.

X-PAD

In X-PAD an MSC datagroup is concatenated from a series of subfields. The X-PAD application-type transmitted within the content-indicator-list of an X-PAD field (kind of a content description) tells whether a subfield belongs to a specific application (means  here: to a specific datagroup series) and whether it is the first subfield of a datagroup or a continuation.
An additional length-indicator immediately precedes the first subfield and tells the overall length of the datagroup to come.

In case of UEP four bytes of the entire X-PAD field within an audio frame belong to the better protected part of the frame. If the first byte of the first subfield of a datagroup happens to be part of this better protected area, then the CRC flag will most likely be valid (if the current receiving quality is measured to be reasonably good).
This will always be the case if short X-PAD is used, with variable size X-PAD however it may or may not be so.

There is no additional protection for an X-PAD subfield!

DAB+ specific:
if you know whether the X-PAD data comes from an AAC audio stream (DAB+) instead of normal DAB when you do the CRC check, you could be more optimistic about the reliability of the CRC flag, because X-PAD in AAC is generally better protected.

Packet mode

In packet mode an MSC data group is concatenated from a series of packets within a data sub-channel. The packet-address tells whether a packet belongs to a specific application (means here: to a specific series of datagroups).

There is no extra length indicator, so the overall size of the data group simply is the sum of the ‘ useful data ’ of all packets.

A first-flag, a last-flag and a continuity-index help in starting a concatenation, continue a concatenation and finish a concatenation.
The continuity index (modulo 4) allows to discover a packet disruption in most cases.

Each packet has it’s own (mandatory!) CRC that protects each single packet.

What does this mean

In packet mode we can rely on the CRC-flag, since the start of a data group is safely identified by the first-flag and all packets are CRC protected.

So if there should be a data group with a CRC flag = ‘0’ that comes from packet mode, the data group should be accepted.

Delaying checks to higher protocol layers

In general it is good practice to handle each protocol layer independently and thus replaceable. That means, a layer should work the same way regardless how a lower level or any upper level is implemented.

But datagroup concatenation is somewhat different for X-PAD or packet mode as lower levels anyway. Further we mentioned above that we could benefit from some knowledge about lower level specifics with respect to the reliability of the CRC flag.
Possibly some upper level extensions could help too?

The MSC datagroup is one layer in a protocol stack that is normally followed by higher layers. Datagroups are directly used by Journaline for example or are fed into MOT decoders in case of Slideshow , EPG, BWS  and TPEG in some areas.

The MOT protocol defines an additional segmentation header containing two fields and one of these is the SegmentSize field. The segment size is the size of the usable data chunk within a datagroup that will be part of an MOT entity (normally a file). So we could suppose, that the datagroup should have a size of SegmentSize + all headers + CRC (if it exists).
So one could easily check if the datagroup is big enough to carry the CRC or not. However, nobody tells that a datagroup must not be bigger as needed.
I found one sentence in the spec.:
Note that some MOT decoders may ignore both parameters of the Segmentation header
– if so, those decoders could only function properly if the datagroup size matches exactly.
I would never trust such vague statements when it’s about DAB.

So I think we could not be sure that additional data (more as needed to carry a chunk of SegmentSize ) is a safe indication that there is a CRC. However if there are less than two additional bytes it is a safe indication that there is no CRC or a transmission error (e.g. a wrong SegmentSize ); an MOT decoder would accept that datagroup only if the CRC flag is set to 0.

Of course we should never implement any MOT specific knowledge into the datagroup concatenation. We could however delegate the CRC checking to upper layers, in this example to the MOT decoder.
I do not think it’s worth it, but I did not try.
The disadvantages are that the datagroup concatenation is not complete, that the CRC check has to be implemented at several places, and that erroneous data is moved in the system further than needed.

With a little help from statistics

It may also help to do some statistics and keep the results for one liefecycle or even persistent (persistent information has to be verified as soon as possible).
If we receive all (or most) datagroups of a service with a CRC, then we may assume that each single datagroup has one. The same should be true for the opposite.

When we start with no statistics available and receive the first datagroup with a valid CRC, then we may assume this service to be one with a CRC. If we receive one with a CRC-flag = 0 later, we consequently treat it as corrupted.

When we receive the first datagroupt with a CRC-flag = 0, we should wait for some more datagroups to verify this.
If there is enough memory, we should not drop the first datagroups but keep them for consumption after this verification.
This may, unfortunately, produce annoying delays since we do never know when the next datagroup will be broadcast.

Although there is no such rule, a providers datagroup generator will most likely not optimize in a way that it uses CRC if it fits into a frame and none if not.

However, the standard explicitly assigns the CRC-flag to each individual datagroup, not to a service, so we can never be sure.

Experiences

I have definitely seen CRC-flag corruptions in car radios when transmitted in X-PAD and those corruptions were not rare.

Ignoring them can confuse upper layers very seriously. On the other hand, dropping too many datagroups will result in a bad user experience; it’s annoying, for example, if a cheap receiver shows a more fluid slideshow performance as yours does. Robustness and performance are somewhat contradictionary in this case.

I spent a lot of time in making my MOT or TPEG decoders smart enough to keep out any kind of malicious input. I had to develop generators that produce datagroups with all kinds of risky data and metadata to verify that.
On the contrary, obeying the standard too strict here (with all thousand legal possibilities) could easily cause the rejection of datagroups that other receivers don’t drop.