libschc
Functions | Variables
fragmenter.c File Reference
#include <math.h>
#include <string.h>
#include <stdio.h>
#include "schc_config.h"
#include "compressor.h"
#include "fragmenter.h"
#include "schc.h"

Functions

static uint16_t get_fcn_value (uint8_t *fragment, schc_fragmentation_t *conn)
 get the FCN value More...
 
static uint16_t get_max_fcn_value (schc_fragmentation_t *conn)
 get the ALL-1 FCN value More...
 
static uint8_t get_padding_length (uint8_t byte)
 get the number of zero bits added to the end of the buffer More...
 
static uint32_t get_bit_mask (uint8_t len)
 get a bitmap mask for a number of bits More...
 
static void mbuf_print (schc_mbuf_t *head)
 print the complete mbuf chain More...
 
static int8_t mbuf_push (schc_mbuf_t **head, uint8_t *data, uint16_t len)
 add an item to the end of the mbuf list if head is NULL, the first item of the list will be set More...
 
static schc_mbuf_tget_prev_mbuf (schc_mbuf_t *head, schc_mbuf_t *mbuf)
 returns the last chain in the mbuf linked list More...
 
static void mbuf_delete (schc_mbuf_t **head, schc_mbuf_t *mbuf)
 delete a mbuf from the chain More...
 
static uint8_t mbuf_overwrite (schc_mbuf_t **head, uint16_t frag, schc_mbuf_t *mbuf)
 check if an mbuf with the same fragment number already exists and overwrite if so More...
 
uint16_t get_mbuf_len (schc_mbuf_t *head)
 returns the total length of the mbuf More...
 
static schc_mbuf_tget_mbuf_tail (schc_mbuf_t *head)
 returns the last chain in the mbuf linked list More...
 
void mbuf_copy (schc_mbuf_t *head, uint8_t *ptr)
 copy the byte alligned contents of the mbuf chain to the passed pointer More...
 
void mbuf_clean (schc_mbuf_t **head)
 delete all fragments chained in an mbuf More...
 
static void mbuf_sort (schc_mbuf_t **head)
 sort the complete mbuf chain based on fragment counter (fcn) note: some packets will arrive out of order, as they were part of a retransmission, and consequently arrive out of order, but carry the same fcn More...
 
static void mbuf_format (schc_mbuf_t **head, schc_fragmentation_t *conn)
 remove the fragmentation headers and concat the data bits of the complete mbuf chain More...
 
static uint8_t get_header_length (schc_mbuf_t *mbuf, schc_fragmentation_t *conn)
 Returns the number of bits the current header exists off. More...
 
static unsigned int mbuf_compute_mic (schc_fragmentation_t *conn)
 Calculates the Message Integrity Check (MIC) over an unformatted mbuf chain containing the compressed, unfragmented packet which is the 8- 16- or 32- bit Cyclic Redundancy Check (CRC) More...
 
static unsigned int compute_mic (schc_fragmentation_t *conn)
 Calculates the Message Integrity Check (MIC) which is the 8- 16- or 32- bit Cyclic Redundancy Check (CRC) More...
 
static uint8_t get_window_bit (uint8_t *fragment, schc_fragmentation_t *conn)
 get the window bit More...
 
static void get_received_mic (uint8_t *fragment, uint8_t mic[], schc_fragmentation_t *conn)
 get the MIC value More...
 
static void set_conn_frag_cnt (schc_fragmentation_t *conn, uint8_t frag)
 set the fragmentation counter of the current connection which is the inverse of the fcn value More...
 
static int8_t init_tx_connection (schc_fragmentation_t *conn)
 initializes a new tx transmission for a device: set the starting and ending point of the packet calculate the MIC over the complete SCHC packet More...
 
void schc_reset (schc_fragmentation_t *conn)
 reset a connection More...
 
static uint32_t has_no_more_fragments (schc_fragmentation_t *conn)
 check if a connection has more fragments to deliver More...
 
static uint16_t set_fragmentation_header (schc_fragmentation_t *conn, uint8_t *fragmentation_buffer)
 set the fragmentation header More...
 
static void set_local_bitmap (schc_fragmentation_t *conn)
 sets the local bitmap at the current fragment offset without encoding the bitmap More...
 
static void clear_bitmap (schc_fragmentation_t *conn)
 clear the received and local bitmap More...
 
static void encode_bitmap (schc_fragmentation_t *conn)
 encode the bitmap by removing all the right most contiguous BYTES in the non-encoded bitmap More...
 
static void decode_bitmap (schc_fragmentation_t *conn)
 reconstruct an encoded bitmap More...
 
static uint8_t is_bitmap_full (schc_fragmentation_t *conn, uint8_t len)
 loop over a bitmap to check if all bits are set to 1, starting from MAX_WIND_FCN More...
 
static uint16_t get_next_fragment_from_bitmap (schc_fragmentation_t *conn)
 get the next fragment to retransmit according the fragmentation counter More...
 
static void discard_fragment (schc_fragmentation_t *conn)
 discard a fragment More...
 
static void abort_connection (schc_fragmentation_t *conn)
 abort an ongoing transmission because the inactivity timer has expired More...
 
static void set_retrans_timer (schc_fragmentation_t *conn)
 sets the retransmission timer to re-enter the fragmentation loop and changes the retransmission_timer flag More...
 
static void set_dc_timer (schc_fragmentation_t *conn)
 sets the duty cycle timer to re-enter the fragmentation loop More...
 
static void set_inactivity_timer (schc_fragmentation_t *conn)
 sets the inactivity timer to re-enter the fragmentation loop and changes the retransmission_timer flag More...
 
static uint8_t empty_all_0 (schc_mbuf_t *mbuf, schc_fragmentation_t *conn)
 checks if the fragment inside the mbuf is an all-0 empty More...
 
static uint8_t empty_all_1 (schc_mbuf_t *mbuf, schc_fragmentation_t *conn)
 checks if the fragment inside the mbuf is an all-1 empty More...
 
static uint8_t send_fragment (schc_fragmentation_t *conn)
 composes a packet based on the type of the packet and calls the callback function to transmit the packet More...
 
static uint8_t send_ack (schc_fragmentation_t *conn)
 composes an ack based on the parameters found in the connection and calls the callback function to transmit the packet More...
 
static uint8_t send_empty (schc_fragmentation_t *conn)
 composes an all-empty fragment based on the parameters found in the connection and calls the callback function to transmit the packet More...
 
static uint8_t send_tx_empty (schc_fragmentation_t *conn)
 composes an all-empty fragment based on the parameters found in the connection and calls the callback function to transmit the packet More...
 
schc_fragmentation_tschc_get_connection (uint32_t device_id)
 find a connection based on a device id or open a new connection if there was no connection for this device yet More...
 
static int8_t mic_correct (schc_fragmentation_t *rx_conn)
 sort the mbuf chain, find the MIC inside the last received fragment and compare with the calculated one More...
 
static uint8_t wait_end (schc_fragmentation_t *rx_conn, schc_mbuf_t *tail)
 the function to call when the state machine is in WAIT END state More...
 
int8_t schc_reassemble (schc_fragmentation_t *rx_conn)
 the receiver state machine More...
 
int8_t schc_fragmenter_init (schc_fragmentation_t *tx_conn, uint8_t(*send)(uint8_t *data, uint16_t length, uint32_t device_id), void(*end_rx)(schc_fragmentation_t *conn), void(*remove_timer_entry)(uint32_t device_id))
 Initializes the SCHC fragmenter. More...
 
static void tx_fragment_send (schc_fragmentation_t *tx_conn)
 the function to call when the state machine is in SEND state More...
 
static void tx_fragment_resend (schc_fragmentation_t *tx_conn)
 the function to call when the state machine is in RESEND state More...
 
static void no_missing_fragments_more_to_come (schc_fragmentation_t *tx_conn)
 the function to call when the state machine has to continue transmission More...
 
int8_t schc_fragment (schc_fragmentation_t *tx_conn)
 the sender state machine More...
 
schc_fragmentation_tschc_input (uint8_t *data, uint16_t len, schc_fragmentation_t *tx_conn, uint32_t device_id)
 This function should be called whenever a packet is received. More...
 
void schc_ack_input (uint8_t *data, uint16_t len, schc_fragmentation_t *tx_conn, uint32_t device_id)
 This function should be called whenever an ack is received. More...
 
schc_fragmentation_tschc_fragment_input (uint8_t *data, uint16_t len, uint32_t device_id)
 This function should be called whenever a fragment is received an open connection is picked for the device out of a pool of connections to keep track of the packet. More...
 

Variables

uint8_t ATTEMPTS = 0
 
struct schc_fragmentation_t schc_rx_conns [SCHC_CONF_RX_CONNS]
 
static uint8_t fragmentation_buffer [MAX_MTU_LENGTH]
 
static uint32_t MBUF_PTR
 
static struct schc_mbuf_t MBUF_POOL [SCHC_CONF_MBUF_POOL_LEN]
 
static uint8_t buf_ptr = 0
 
uint8_t schc_buf [SCHC_BUFSIZE] = { 0 }
 

Function Documentation

◆ abort_connection()

static void abort_connection ( schc_fragmentation_t conn)
static

abort an ongoing transmission because the inactivity timer has expired

Parameters
conna pointer to the connection

◆ clear_bitmap()

static void clear_bitmap ( schc_fragmentation_t conn)
static

clear the received and local bitmap

Parameters
conna pointer to the connection

◆ compute_mic()

static unsigned int compute_mic ( schc_fragmentation_t conn)
static

Calculates the Message Integrity Check (MIC) which is the 8- 16- or 32- bit Cyclic Redundancy Check (CRC)

Parameters
connpointer to the connection
Returns
checksum the computed checksum

◆ decode_bitmap()

static void decode_bitmap ( schc_fragmentation_t conn)
static

reconstruct an encoded bitmap

Parameters
conna pointer to the connection

◆ discard_fragment()

static void discard_fragment ( schc_fragmentation_t conn)
static

discard a fragment

Parameters
conna pointer to the connection

◆ empty_all_0()

static uint8_t empty_all_0 ( schc_mbuf_t mbuf,
schc_fragmentation_t conn 
)
static

checks if the fragment inside the mbuf is an all-0 empty

Parameters
mbufa pointer to the mbuf
Returns
0 this is not an empty all-0 1 this is an empty all-0

◆ empty_all_1()

static uint8_t empty_all_1 ( schc_mbuf_t mbuf,
schc_fragmentation_t conn 
)
static

checks if the fragment inside the mbuf is an all-1 empty

Parameters
mbufa pointer to the mbuf
Returns
0 this is not an empty all-1 1 this is an empty all-1

◆ encode_bitmap()

static void encode_bitmap ( schc_fragmentation_t conn)
static

encode the bitmap by removing all the right most contiguous BYTES in the non-encoded bitmap

Parameters
conna pointer to the connection

◆ get_bit_mask()

static uint32_t get_bit_mask ( uint8_t  len)
static

get a bitmap mask for a number of bits

Parameters
lenthe number of bits to set
Returns
padding the bitmask

◆ get_fcn_value()

static uint16_t get_fcn_value ( uint8_t *  fragment,
schc_fragmentation_t conn 
)
static

get the FCN value

Parameters
fragmenta pointer to the fragment to retrieve the FCN from
Returns
FCN the FCN as indicated by the fragment
Note
only FCN values up to 16 bits are currently supported

◆ get_header_length()

static uint8_t get_header_length ( schc_mbuf_t mbuf,
schc_fragmentation_t conn 
)
static

Returns the number of bits the current header exists off.

Parameters
mbufthe mbuf to find th offset for
Returns
length the length of the header

◆ get_max_fcn_value()

static uint16_t get_max_fcn_value ( schc_fragmentation_t conn)
static

get the ALL-1 FCN value

Returns
FCN the all-1 fcn value
Note
only FCN values up to 16 bits are currently supported

◆ get_mbuf_len()

uint16_t get_mbuf_len ( schc_mbuf_t head)

returns the total length of the mbuf

Parameters
headthe head of the list
Returns
len the total length of the fragment

◆ get_mbuf_tail()

static schc_mbuf_t* get_mbuf_tail ( schc_mbuf_t head)
static

returns the last chain in the mbuf linked list

Parameters
headthe head of the list
Returns
tail the last mbuf in the linked list

◆ get_next_fragment_from_bitmap()

static uint16_t get_next_fragment_from_bitmap ( schc_fragmentation_t conn)
static

get the next fragment to retransmit according the fragmentation counter

Parameters
conna pointer to the connection
Returns
frag the next fragment to retransmit 0 no more fragments to retransmit

◆ get_padding_length()

static uint8_t get_padding_length ( uint8_t  byte)
static

get the number of zero bits added to the end of the buffer

Parameters
bytethe byte to investigate
Returns
padding the length of the padding

◆ get_prev_mbuf()

static schc_mbuf_t* get_prev_mbuf ( schc_mbuf_t head,
schc_mbuf_t mbuf 
)
static

returns the last chain in the mbuf linked list

Parameters
headthe head of the list
mbufthe mbuf to find the previous mbuf for
Returns
prev the previous mbuf

◆ get_received_mic()

static void get_received_mic ( uint8_t *  fragment,
uint8_t  mic[],
schc_fragmentation_t conn 
)
static

get the MIC value

Parameters
fragmenta pointer to the fragment to retrieve the MIC from
mic

◆ get_window_bit()

static uint8_t get_window_bit ( uint8_t *  fragment,
schc_fragmentation_t conn 
)
static

get the window bit

Parameters
fragmenta pointer to the fragment to retrieve the window number from
Returns
window the window number as indicated by the fragment

◆ has_no_more_fragments()

static uint32_t has_no_more_fragments ( schc_fragmentation_t conn)
static

check if a connection has more fragments to deliver

Parameters
conna pointer to the connection
Returns
0 the connection still has fragments to send total_bit_offset the total bit offset inside the packet

◆ init_tx_connection()

static int8_t init_tx_connection ( schc_fragmentation_t conn)
static

initializes a new tx transmission for a device: set the starting and ending point of the packet calculate the MIC over the complete SCHC packet

Parameters
conna pointer to the connection to initialize
Returns
1 on success 0 on error -1 if no fragmentation is needed

◆ is_bitmap_full()

static uint8_t is_bitmap_full ( schc_fragmentation_t conn,
uint8_t  len 
)
static

loop over a bitmap to check if all bits are set to 1, starting from MAX_WIND_FCN

Parameters
conna pointer to the connection
lenthe length of the bitmap

◆ mbuf_clean()

void mbuf_clean ( schc_mbuf_t **  head)

delete all fragments chained in an mbuf

Parameters
headthe head of the list

◆ mbuf_compute_mic()

static unsigned int mbuf_compute_mic ( schc_fragmentation_t conn)
static

Calculates the Message Integrity Check (MIC) over an unformatted mbuf chain containing the compressed, unfragmented packet which is the 8- 16- or 32- bit Cyclic Redundancy Check (CRC)

Parameters
headthe head of the list
Returns
checksum the computed checksum

◆ mbuf_copy()

void mbuf_copy ( schc_mbuf_t head,
uint8_t *  ptr 
)

copy the byte alligned contents of the mbuf chain to the passed pointer

Parameters
headthe head of the list
ptrthe pointer to copy the contents to

◆ mbuf_delete()

static void mbuf_delete ( schc_mbuf_t **  head,
schc_mbuf_t mbuf 
)
static

delete a mbuf from the chain

Parameters
headthe head of the list
mbufthe mbuf to delete

◆ mbuf_format()

static void mbuf_format ( schc_mbuf_t **  head,
schc_fragmentation_t conn 
)
static

remove the fragmentation headers and concat the data bits of the complete mbuf chain

+-—+---------—+ +-—+---------—+ | FH | DATA | <— ... <— | FH | DATA | +-—+---------—+ +-—+---------—+

  1. remove the fragmentation header (FH), but keep the rule id
  2. shift the DATA bits to the left, to overwrite the FH bits 3.
Parameters
headdouble pointer to the head of the list

◆ mbuf_overwrite()

static uint8_t mbuf_overwrite ( schc_mbuf_t **  head,
uint16_t  frag,
schc_mbuf_t mbuf 
)
static

check if an mbuf with the same fragment number already exists and overwrite if so

Parameters
headthe head of the list
fragthe fragment number to overwrite
mbufthe fragment to overwrite with
Returns
0 no matching fragment found 1 overwrote a matching packet

◆ mbuf_print()

static void mbuf_print ( schc_mbuf_t head)
static

print the complete mbuf chain

Parameters
headthe head of the list

◆ mbuf_push()

static int8_t mbuf_push ( schc_mbuf_t **  head,
uint8_t *  data,
uint16_t  len 
)
static

add an item to the end of the mbuf list if head is NULL, the first item of the list will be set

Parameters
headthe head of the list
dataa pointer to the data pointer
lenthe length of the data
Returns
-1 no free mbuf slot was found 0 ok

◆ mbuf_sort()

static void mbuf_sort ( schc_mbuf_t **  head)
static

sort the complete mbuf chain based on fragment counter (fcn) note: some packets will arrive out of order, as they were part of a retransmission, and consequently arrive out of order, but carry the same fcn

Parameters
headdouble pointer to the head of the list

◆ mic_correct()

static int8_t mic_correct ( schc_fragmentation_t rx_conn)
static

sort the mbuf chain, find the MIC inside the last received fragment and compare with the calculated one

Parameters
rx_conna pointer to the rx connection structure

◆ no_missing_fragments_more_to_come()

static void no_missing_fragments_more_to_come ( schc_fragmentation_t tx_conn)
static

the function to call when the state machine has to continue transmission

Parameters
tx_conna pointer to the tx connection structure

◆ schc_ack_input()

void schc_ack_input ( uint8_t *  data,
uint16_t  len,
schc_fragmentation_t tx_conn,
uint32_t  device_id 
)

This function should be called whenever an ack is received.

Parameters
dataa pointer to the received data
lenthe length of the received packet
tx_conna pointer to the tx initialization structure
device_idthe device id from the rx source

◆ schc_fragment()

int8_t schc_fragment ( schc_fragmentation_t tx_conn)

the sender state machine

Parameters
tx_conna pointer to the tx connection structure
Returns
0 TBD -1 failed to initialize the connection -2 no fragmentation was needed for this packet

◆ schc_fragment_input()

schc_fragmentation_t* schc_fragment_input ( uint8_t *  data,
uint16_t  len,
uint32_t  device_id 
)

This function should be called whenever a fragment is received an open connection is picked for the device out of a pool of connections to keep track of the packet.

Parameters
dataa pointer to the data packet
lenthe length of the received packet
device_idthe device id from the rx source
Returns
conn the connection

◆ schc_fragmenter_init()

int8_t schc_fragmenter_init ( schc_fragmentation_t tx_conn,
uint8_t(*)(uint8_t *data, uint16_t length, uint32_t device_id)  send,
void(*)(schc_fragmentation_t *conn)  end_rx,
void(*)(uint32_t device_id)  remove_timer_entry 
)

Initializes the SCHC fragmenter.

Parameters
tx_conna pointer to the tx initialization structure
senda pointer to the send callback
end_rxthis function is called to indicate that the last rx timer has expired
remove_timer_entrysome scheduler implementations need a callback to remove a timer entry for a certain device
Returns
error codes on error

◆ schc_get_connection()

schc_fragmentation_t* schc_get_connection ( uint32_t  device_id)

find a connection based on a device id or open a new connection if there was no connection for this device yet

Parameters
device_idthe id of the device to open a connection for
Returns
conn a pointer to the selected connection 0 if no free connections are available

◆ schc_input()

schc_fragmentation_t* schc_input ( uint8_t *  data,
uint16_t  len,
schc_fragmentation_t tx_conn,
uint32_t  device_id 
)

This function should be called whenever a packet is received.

Parameters
dataa pointer to the received data
lenthe length of the received packet
tx_conna pointer to the tx initialization structure
device_idthe device id from the rx source

◆ schc_reassemble()

int8_t schc_reassemble ( schc_fragmentation_t rx_conn)

the receiver state machine

Parameters
conna pointer to the connection
Returns
0 TBD

◆ schc_reset()

void schc_reset ( schc_fragmentation_t conn)

reset a connection

Parameters
conna pointer to the connection to reset

◆ send_ack()

static uint8_t send_ack ( schc_fragmentation_t conn)
static

composes an ack based on the parameters found in the connection and calls the callback function to transmit the packet

Parameters
conna pointer to the connection

@ret 0 the packet was not sent 1 the packet was transmitted

◆ send_empty()

static uint8_t send_empty ( schc_fragmentation_t conn)
static

composes an all-empty fragment based on the parameters found in the connection and calls the callback function to transmit the packet

Parameters
conna pointer to the connection

@ret 0 the packet was not sent 1 the packet was transmitted

◆ send_fragment()

static uint8_t send_fragment ( schc_fragmentation_t conn)
static

composes a packet based on the type of the packet and calls the callback function to transmit the packet

Parameters
conna pointer to the connection

@ret 0 the packet was not sent 1 the packet was transmitted

◆ send_tx_empty()

static uint8_t send_tx_empty ( schc_fragmentation_t conn)
static

composes an all-empty fragment based on the parameters found in the connection and calls the callback function to transmit the packet

Parameters
conna pointer to the connection

@ret 0 the packet was not sent 1 the packet was transmitted

◆ set_conn_frag_cnt()

static void set_conn_frag_cnt ( schc_fragmentation_t conn,
uint8_t  frag 
)
static

set the fragmentation counter of the current connection which is the inverse of the fcn value

Parameters
conna pointer to the connection
fragthe fcn value

◆ set_dc_timer()

static void set_dc_timer ( schc_fragmentation_t conn)
static

sets the duty cycle timer to re-enter the fragmentation loop

Parameters
conna pointer to the connection

◆ set_fragmentation_header()

static uint16_t set_fragmentation_header ( schc_fragmentation_t conn,
uint8_t *  fragmentation_buffer 
)
static

set the fragmentation header

Parameters
conna pointer to the connection
buffera pointer to the buffer to set the header
Returns
bit_offset the number of bits added to the front of the fragment

◆ set_inactivity_timer()

static void set_inactivity_timer ( schc_fragmentation_t conn)
static

sets the inactivity timer to re-enter the fragmentation loop and changes the retransmission_timer flag

Parameters
conna pointer to the connection

◆ set_local_bitmap()

static void set_local_bitmap ( schc_fragmentation_t conn)
static

sets the local bitmap at the current fragment offset without encoding the bitmap

Parameters
conna pointer to the connection

◆ set_retrans_timer()

static void set_retrans_timer ( schc_fragmentation_t conn)
static

sets the retransmission timer to re-enter the fragmentation loop and changes the retransmission_timer flag

Parameters
conna pointer to the connection

◆ tx_fragment_resend()

static void tx_fragment_resend ( schc_fragmentation_t tx_conn)
static

the function to call when the state machine is in RESEND state

Parameters
tx_conna pointer to the tx connection structure

◆ tx_fragment_send()

static void tx_fragment_send ( schc_fragmentation_t tx_conn)
static

the function to call when the state machine is in SEND state

Parameters
tx_conna pointer to the tx connection structure

◆ wait_end()

static uint8_t wait_end ( schc_fragmentation_t rx_conn,
schc_mbuf_t tail 
)
static

the function to call when the state machine is in WAIT END state

Parameters
rx_conna pointer to the rx connection structure

Variable Documentation

◆ ATTEMPTS

uint8_t ATTEMPTS = 0

◆ buf_ptr

uint8_t buf_ptr = 0
static

◆ fragmentation_buffer

uint8_t fragmentation_buffer[MAX_MTU_LENGTH]
static

◆ MBUF_POOL

struct schc_mbuf_t MBUF_POOL[SCHC_CONF_MBUF_POOL_LEN]
static

◆ MBUF_PTR

uint32_t MBUF_PTR
static

◆ schc_buf

uint8_t schc_buf[SCHC_BUFSIZE] = { 0 }

◆ schc_rx_conns