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 Kbch-80 bits for the MODCOD and FECFRAME size specified in the ACM command byte. If the length of the payload field is less than Kbch-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 Kbch. 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:

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;
    }
}