Opendigitalradio / ODR-DabMux

ODR-DabMux is a DAB (Digital Audio Broadcasting) multiplexer, part of the ODR-mmbTools.
https://www.opendigitalradio.org
Other
48 stars 35 forks source link

Add FIC 0/7 #42

Closed mpbraendli closed 4 years ago

mpbraendli commented 4 years ago

The standard EN 300 401 version 2 mandates that FIG 0/7 gets sent right after FIG 0/0.

Anybody interested in tackling this to add complete v2 support to ODR-DabMux?

nickpiggott commented 4 years ago

On the issue of "multiplex configuration" count. In BIND DNS server configurations, it's a requirement for the user to increment a version number in the zone database file to signal to BIND that the database has been changed. Would this be an acceptable solution here?

Essentially, a user-requirement to increment the count, rather than odr-dabmux holding / saving / reading / incrementing state (which infers that odr-dabmux would keep a persistent version of the prior configuration, and deduce if the resulting FIC information is actually different or if someone just changed something non-relevant in the configuration file).

mpbraendli commented 4 years ago

It's one of the options indeed, but it's not something we can easily handle in our production deployment.

The ideal thing would be to have a hash instead of a count, that you derive from the configuration, and that changes if the ensemble composition changes. But that would be bending the spec quite hard, as it unambigiously states

Count: this modulo-1 024 binary counter increments by one for every multiplex reconfiguration.

KuntzeM commented 4 years ago

Hi Matthias, I'm trying to implement this FIG0_7. But I have an problem. Maybe you can help me. Following is my implementation. I checked the incoming FIG0_7 data with DAB Scout (IRT). For testing I hardcoded the service count to 6 and reconfig count to 1.

I get a valid FIG, but with wrong service/reconfig counts. I receive this Hex. 03 07 46 00

The last bits are Service count Reconfig count 010001 1000000000 17 512

But it should be 6 and 1.

Do you see my mistake or can you explain to me where I'm wrong?

Thanks in advanced!

BR Mathias

fig/FIG0_7.cpp

#include "fig/FIG0structs.h"
#include "fig/FIG0_7.h"
#include "utils.h"

namespace FIC {

struct FIGtype0_7 {
    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 Service_count:6;
    uint16_t Reconfig_count:10;
} PACKED;

//=========== FIG 0/0 ===========

FillStatus FIG0_7::fill(uint8_t *buf, size_t max_size)
{
    FillStatus fs;
    FIGtype0_7 *fig0_7;
    fig0_7 = (FIGtype0_7 *)buf;

    fig0_7->FIGtypeNumber = 0;
    fig0_7->Length = 3;
    fig0_7->CN = 0;
    fig0_7->OE = 0;
    fig0_7->PD = 0;
    fig0_7->Extension = 7;

    auto ensemble = m_rti->ensemble;

    fig0_7->Service_count = 6; //ensemble->services.size();
    fig0_7->Reconfig_count = 1; //ensemble->reconfig_counter % 1024;

    fs.complete_fig_transmitted = true;
    fs.num_bytes_written = 4;
    return fs;
}

}
mpbraendli commented 4 years ago

Thanks for tackling this!

Have you considered endianness? In ETI, all the fields are network-endian, which is usually opposite to the system endianness. You'll see calls to htonl() in other parts of ODR-DabMux for that.

And a small nitpick, please be consistent with the naming convention of the fields (ServiceCount not Service_count). I know the mmbTools are not a good example of naming consistency, but that's not an excuse to make it worse :-)

KuntzeM commented 4 years ago

Thank you for your help! I will refactor my code if it's working :) I try to improve my programming skill. This project is perfect for me.

But I still need your help. I read htonl() is using for 32bit to convert from little-endian to big-endian. But I'm using 16 bit INT (10bit) for the ReconfigCounter and 8 bit INT (6bit) for the ServiceCount. I tried with htonl and htons but with both I receive only zero in the FIG0_7 ServiceCount/ReconfigCount.

fig0_7->Service_count = htonl(ensemble->services.size());
fig0_7->Reconfig_count = htonl(ensemble->reconfig_counter % 1024);

Where do I have my mistake?

mpbraendli commented 4 years ago

Yes, you are right that htonl is for 32-bit values and htons for 16-bit values. https://linux.die.net/man/3/htonl

The problem is that you are writing to a bitfield, for which you cannot say how you want it packed. As a consequence, you are forced to only use uint8_t in the bitfield, and you need to rearrange the fields manually. Have a look at struct FIGtype0_1_SubChannel_ShortF in FIG0_1.cpp for an example: the 10-bit StartAddress is split in a 2-bit and an 8-bit.

It's a bit tricky and error-prone, but I hope the example can help you. I also find it useful to write the bit layout on paper to better understand how and where to split the fields.

KuntzeM commented 4 years ago

Thank you very much! Now it is working fine :) I see the correct values in DAB.Scout. I will test it tomorrow and create a pull request. (after a naming convention refactoring) :D

mpbraendli commented 4 years ago

FIG 0/7 support merged.

The question if ODR-DabMux can handle the count field itself or if it is user-configurable is still open. Current implementation sets the value in the config file.

mpbraendli commented 4 years ago

Implemented both configurable Count and automatically calculated using a hash function of ensemble parameters. See 5340215