.. _ethdata:

====================
BBFRAME Data Service
====================

This section describes how to use the SRX-8 Ethernet interfaces when fine-grained control
of modulation and coding is required.

The BBFRAME data service allows the user to choose the DVB-S2 MODCOD used to emit the given payload.
This gives the user a trade-off between transfer reliability and achievable throughput by varying
the FEC code rate and modulation on a packet-by-packet basis. Refer to [ETSI_EN]_, chapter 6 for
the details of this trade-off.

One IP packet must hold one mode adaptation packet, in its entirety. IP fragmentation is not
supported on the BBFRAME data service, and fragmented packets will be dropped.
This means some combinations of MODCOD and FECFRAME size require the use of jumbo frames.
The maximum mode adaptation packet length is 7276 bytes (excl. UDP/IP headers).

The BBFRAME data service is available on UDP port 12610. The endpoint IP address is
configurable using the ``sys.net.[en|xg].ip`` properties. The packets that can be received or emitted
by this service are:

- Mode adaptation packets
- Flow control requests/replies
- Flow control tokens

These formats are described in the remainder of this section.

Mode Adaptation Packet Format
=============================

The BBFRAME data service UDP payload must hold a DVB-S2 mode adaptation packet according to [ETSI_EN]_, annex I.2:

::

                -- MODE ADAPTATION PACKET --
    ┌──────────┬──────────────┬─────────────────────────┐
    │ TSHEADER │   BBHEADER   │         PAYLOAD         │
    └──────────┴──────────────┴─────────────────────────┘
    ├──────────┼──────────────┼─────────────────────────┤
      2 bytes      10 bytes             N bytes

The contents of the TSHEADER is used to configure the SRX-8 modulator and is not
emitted by the transmitter. The contents of the BBHEADER has no impact on the behavior of the
transmitter. The BBHEADER is usually used and validated by DVB-S2 receiver equipment.

The transmission order throughout this section is from left to right, e.g. starting with the MSB
of the TSHEADER.

TSHEADER
--------

The TSHEADER field holds a sync marker and the ACM command byte:

::

    -- TSHEADER --                   -- ACM --
    ┌──────┬──────┐    ┌────────┬────────┬──────┬──────────┐
    │ 0xB8 │ ACM  │    │ MODCOD │ PILOTS │ SIZE │ RESERVED │
    └──────┴──────┘    └────────┴────────┴──────┴──────────┘
    ├─────────────┤    ├────────┼────────┼──────┼──────────┤
        2 bytes            5b       1b      1b       1b

The ACM command byte fields are given by:

- `MODCOD`: dictates the FEC rate and modulation to use. Valid values are 1 to 28 (inclusive),
  as given by [ETSI_EN]_, section 5.5.2.2, table 12.
- `PILOTS`: 0 to disable pilots, 1 to enable pilots. Usage of pilots may help the receiver
  achieve or stay in lock, but introduces a small overhead.
- `SIZE`: 0 for normal FECFRAMEs (64800 bits), 1 for short FECFRAMEs (16200 bits)

BBHEADER
--------

Unless the PAYLOAD field holds MPEG transport stream packets, the BBHEADER should usually signal
that the payload is a generic continuous single input stream with adaptive coding and modulation.
This is further described in [ETSI_EN]_, section 5.1.6 and summarized below:

::

                                           -- BBHEADER --
    ┌────┬───┬───┬───┬───┬────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐
    │ 01 │ 1 │ 0 │ 0 │ 0 │ RO │   0x00   │  0x0000  │   DFL    │   0xFF   │  0x0000  │   CRC    │
    └────┴───┴───┴───┴───┴────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘
    ├────┼───┼───┼───┼───┼────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
      2b  1b  1b  1b  1b   2b      8b        16b        16b         8b        16b         8b

The variable fields are:

- `RO`: the chosen RRC roll-off factor, ``00`` for 0.35, ``01`` for 0.25 and ``10`` for 0.20.
  This field is not used by the SRX-8, but may be used by some receivers and should be set
  according to the SRX-8 roll-off property ``tx.rolloff``.
- `DFL`: `data field length`, the length of the mode adaptation packet PAYLOAD field in bits,
  most significant byte first.
- `CRC`: a checksum of the preceding 9 BBHEADER bytes, as described in [ETSI_EN]_, section 5.1.6 and 5.1.4.

PAYLOAD
-------

The payload field holds the user data to transfer. The transmitter makes no assumptions on the content,
but DVB-S2 receiver equipment may require the length to match the DFL field of the BBHEADER.

The length of the payload field must be at most K\ :sub:`bch`-80 bits for the MODCOD and FECFRAME
size specified in the ACM command byte. If the length of the payload field is less than
K\ :sub:`bch`-80, it will be zero-padded by the modulator, as described in [ETSI_EN]_, section 5.2.

Refer to [ETSI_EN]_, section 5.3, tables 5a and 5b for a mapping between code rate,
FECFRAME size and K\ :sub:`bch`. Refer to section 5.5.2.2, table 12 for a mapping between
MODCOD and code rate.

Flow Control
============

Depending on configuration, the modulator information rate may be lower than what can be carried
by the Ethernet interface. If this is the case, the user must either

- Throttle the rate at which mode adaptation packets are submitted to the BBFRAME data service,
  such that it never exceeds the modulator input data rate. This requires knowledge of the symbol
  rate and spectral efficiency of the chosen MODCOD. If the input rate is exceeded,
  packets are silently dropped.
- Respect Ethernet pause frames according to [IEEE_802.3]_. Whether pause frames are
  emitted by the SRX-8 depends on the value of the ``sys.net.[en|xg].pause`` properties.
- Use the Satlab UDP flow control protocol.

The Satlab UDP flow control protocol is a simple flow control scheme inspired by
SpaceWire and SpaceFibre. Usage of this protocol introduces three additional packet formats
to the BBFRAME data service:

UDP payload emitted by client, received by SRX-8:

::

    -- Flow control request --
       ┌───────┬───────┐
       │ 0xF1  │ SEQNO │
       └───────┴───────┘
       ├───────┼───────┤
        1 byte  1 byte

UDP payload emitted by SRX-8, received by client:

::

    -- Flow control reply --   -- Flow control token --
    ┌───────┬───────┬───────┐  ┌───────┬───────┬───────┐
    │ 0xF2  │ SEQNO │ NFREE │  │ 0xF3  │ SEQNO │ NCRED │
    └───────┴───────┴───────┘  └───────┴───────┴───────┘
    ├───────┼───────┼───────┤  ├───────┼───────┼───────┤
     1 byte  1 byte  4 bytes    1 byte  1 byte  1 byte

The packets shown above are used to initialize and maintain a connection between a data generating
client and the SRX-8 transmitter as shown below:

::

      ┌─────────┐                 ┌───────┐
      │ Client  │                 │ SRX-8 │
      └────┬────┘                 └───┬───┘
           │                          │
           │ Flow control request     │
           │------------------------->│
           │                          │
           │       Flow control reply │
           │<-------------------------|
    ┌──────┼──────────────────────────┼────┐
    │Loop  │                          │    │
    │      │ Data                     │    │
    │      │------------------------->│    │
    │      │                          │    │
    │      │       Flow control token │    │
    │      │<-------------------------│    │
    │      │                          │    │
    └──────┼──────────────────────────┼────┘

- The client emits a flow control request. `SEQNO` can be chosen freely.
- The target stores the source IP and source port of the request. All flow control packets emitted
  by the target will use that IP and port as destination.
- The target replies with a flow control reply that has the same `SEQNO` and `NFREE` set to the number
  of unused bytes in the BBFRAME data service input buffer.
- From then on, the target will emit a flow control token for each chunk of data that is removed
  from the FIFO. Each token releases a number of credits given by `NCRED`.
- Each credit means the FIFO can accept 1 kiB of data.
- `SEQNO` increments by 1 between each packet emitted by the target, and can be used to detect lost
  flow control tokens. If tokens are lost, the session must be re-established with a new
  flow control request.

Pseudocode of example usage after successful setup:

.. code-block:: c

    nfree = flow_control_reply.nfree;
    seqno = flow_control_reply.seqno;
    mode_adaptation_packet = get_next_mode_adaptation_packet_blocking();

    while (!stop) {
        /* Submit as many packets as we can until remote buffer is full */
        while (nfree >= sizeof(mode_adaptation_packet)) {
            submit(mode_adaptation_packet);
            nfree -= sizeof(mode_adaptation_packet);
            mode_adaptation_packet = get_next_mode_adaptation_packet_blocking();
        }

        /* No more room, get one or more tokens */
        while (flow_control_token_waiting_in_buffer() || nfree < sizeof(mode_adaptation_packet)) {

            fct = next_flow_control_token_blocking();

            if (fct.seqno != (seqno+1) % 256)
                error();

            seqno = fct.seqno;

            nfree += fct.ncred * 1024;
        }
    }
