svpcom / wfb-ng

WFB-NG - the next generation of long-range packet radio link based on raw WiFi radio
https://docs.px4.io/main/en/tutorials/video_streaming_wifi_broadcast.html
GNU General Public License v3.0
1.01k stars 240 forks source link

how to distinguish fec packet and media packet #2

Closed openserli closed 7 years ago

openserli commented 7 years ago

hi, can i tell me how to distinguish which is fec packet(redundant) and which is media packet in wifibroadcast? redundant packet should not push to deocder from what i know.

svpcom commented 7 years ago

Data packets have fragment_idx < fec_k. FEC packets - from fec_k to fec_n

openserli commented 7 years ago
can you tell me what this code mean ? why need alloc more then one blocks for one block_id ?

int ring_idx = -1; for(int i = 0; i < new_blocks; i++) { ring_idx = rx_ring_push(); rx_ring[ring_idx].block_idx = modN(block_idx - new_blocks + i + 1, 256); rx_ring[ring_idx].send_fragment_idx = 0; rx_ring[ring_idx].has_fragments = 0; memset(rx_ring[ring_idx].fragment_map, '\0', fec_n * sizeof(uint8_t)); } return ring_idx;

svpcom commented 7 years ago

rx_ring is a circular buffer, where we store packets, grouped by FEC blocks. It has two variables: rx_ring_front (index of the first allocated FEC block) and alloc_size -- number of allocated blocks.

When we receive a new packet it can belongs to:

  1. New fec block - we need to allocate it in RX ring (do nothing if block was already processed)
  2. Already existing fec block - we need to add it to them (do nothing if packet already processed)

When we allocate a new block we have following choices:

  1. Add a new block to rx ring tail.
  2. Override a block at rx ring head if rx ring is full.

block idx is rounded by modulo 256 - i.e. 0, 1, 2, ... 255, 0, 1 ... For example:

  1. rx_ring_front == 5 and alloc_size == 2 and last last allocated block has block_idx == 132
  2. We got a packet with block_idx == 141. We need to allocate a (141 - 132) mod 256 = 9 new blocks. Such packet reordering can happens due to different latency in WiFi adapters if we use multiple adapters/antennas or packet reordering in adapter's internal queue.
  3. This code allocates new_blocks in rx ring. It clears rx ring slots from previous data and write indexes of new blocks to rx ring slots.
svpcom commented 7 years ago

added to wiki

openserli commented 7 years ago

you say that , block idx is rounded by modulo 256 - i.e. 0, 1, 2, ... 255, 0, 1 ... but int the sender part, the block is will larger then 255, and the receiver side block will not right.

svpcom commented 7 years ago

Receiver only use last 8 bits from tx block index:

block_hdr->nonce = ((block_idx & BLOCK_IDX_MASK) << 8) + fragment_idx;
...
uint8_t block_idx = (uint8_t)((block_hdr->nonce >> 8) & 0xff);