ESP32-P4 OBC Firmware
ESP-IDF firmware for Plant-B CubeSat OBC
 
Loading...
Searching...
No Matches
Packet Utilities

Data Structures

union  category_t
 Type-safe union for the category field of a packet header. More...
 
union  type_t
 Type-safe union for the type field of a packet header. More...
 
struct  header_t
 Decoded representation of the packet header fields. More...
 

Macros

#define PACKET_BYTES   (111)
 Total packet size in bytes.
 
#define PAYLOAD_BYTES   (48)
 Size of the payload field in bytes.
 
#define PKT_NO_LOCATION   (-1)
 Sentinel value returned by pkt_decode() when no packet was recovered from the decoding pool.
 

Typedefs

typedef struct packet packet_t
 Opaque packet handle.
 
typedef struct pkt_enc_pool pkt_enc_pool_t
 Opaque encoder pool handle.
 
typedef struct pkt_dec_pool pkt_dec_pool_t
 Opaque decoder pool handle.
 

Enumerations

enum  domain_t : uint8_t { DOMAIN_TM = 0x00 , DOMAIN_TC = 0x01 , DOMAIN_TEST = 0x02 }
 Top-level message domain. More...
 
enum  tm_category_t : uint8_t { TM_SDATA = 0x00 , TM_BDATA = 0x01 , TM_EVENT = 0x02 }
 Categories within the Telemetry domain. More...
 
enum  tm_sdata_type_t : uint8_t { TM_SDATA_SENSORS = 0x00 , TM_SDATA_STATUS = 0x01 }
 Types within the Telemetry / Small data category. More...
 
enum  tm_bdata_type_t : uint8_t { TM_BDATA_IMAGE = 0x00 , TM_BDATA_VIDEO = 0x01 }
 Types within the Telemetry / Big data category. More...
 
enum  tm_event_type_t : uint8_t { TM_EVENT_LOG = 0x00 , TM_EVENT_ERROR = 0x01 , TM_EVENT_CRASH = 0x02 }
 Types within the Telemetry / Event category. More...
 
enum  tc_category_t : uint8_t { TC_CTRL = 0x00 , TC_REQ = 0x01 }
 Categories within the Telecommand domain. More...
 
enum  tc_req_type_t : uint8_t {
  TC_REQ_SENSORS = 0x00 , TC_REQ_STATUS = 0x01 , TC_REQ_IMAGE = 0x02 , TC_REQ_VIDEO = 0x03 ,
  TC_REQ_LOG = 0x04 , TC_REQ_ERROR = 0x05 , TC_REQ_CRASH = 0x06
}
 Types within the Telecommand / Request category. More...
 
enum  tc_ctrl_type_t : uint8_t { TC_CTRL_REBOOT = 0x00 }
 Types within the Telecommand / Control category. More...
 
enum  test_category_t : uint8_t { TEST_WIMG = 0x00 , TEST_FRM = 0x01 , TEST_MSG = 0x02 }
 Types within the Test domain. More...
 
enum  pkt_err_t {
  PKT_OK = 0 , PKT_FAIL , PKT_ERR_INVALID_ARG , PKT_ERR_SYNC ,
  PKT_ERR_CRC
}
 Return codes for packet utility functions. More...
 

Functions

packet_tpkt_create (void)
 Allocate and initialize a packet, with each byte set to 0.
 
void pkt_destroy (packet_t *restrict pkt)
 Free a packet allocated by pkt_create().
 
pkt_enc_pool_tenc_pool_create (void)
 Allocate and initialize an encoder pool.
 
void enc_pool_destroy (pkt_enc_pool_t *restrict pool)
 Free an encoder pool allocated by enc_pool_create().
 
pkt_dec_pool_tdec_pool_create (void)
 Allocate and initialize a decoder pool.
 
void dec_pool_destroy (pkt_dec_pool_t *restrict pool)
 Free a decoder pool allocated by dec_pool_create().
 
pkt_err_t pkt_encode (packet_t *restrict pkt, pkt_enc_pool_t *restrict pool)
 Finalize and encode a packet for transmission.
 
pkt_err_t pkt_decode (const packet_t *restrict pkt, pkt_dec_pool_t *restrict pool, int8_t *restrict relative_loc)
 Validate and decode a received packet.
 
pkt_err_t dec_pool_get_pkt_from_relative_loc (const pkt_dec_pool_t *restrict pool, int8_t relative_loc, packet_t *restrict pkt)
 Reconstruct a recovered packet from the decoder pool.
 
pkt_err_t pkt_get_id (const packet_t *restrict pkt, uint16_t *id)
 Read the packet identifier.
 
pkt_err_t header_sensor_config (header_t *restrict header)
 Configure a header for a current sensor measurement packet.
 
pkt_err_t header_old_sensor_config (header_t *restrict header, uint16_t old_id)
 Configure a header for a retransmitted (old) sensor measurement packet.
 
pkt_err_t pkt_get_header (const packet_t *restrict pkt, header_t *header)
 Unpack the header fields from a raw packet.
 
pkt_err_t pkt_set_header (packet_t *restrict pkt, const header_t *restrict header)
 Pack header fields into a raw packet.
 
pkt_err_t pkt_get_payload (const packet_t *restrict pkt, uint8_t *payload, size_t len)
 Copy the payload field out of a packet.
 
pkt_err_t pkt_set_payload (packet_t *restrict pkt, const uint8_t *restrict payload, size_t len)
 Copy data into the payload field of a packet.
 
bool pkt_is_chunked (const packet_t *restrict pkt)
 Check whether a packet carries chunked data.
 
pkt_err_t pkt_log (const packet_t *restrict pkt)
 Log a human-readable dump of a packet to the PAL logger.
 
pkt_err_t pkt_test_random_set_sync8 (packet_t *restrict pkt, bool *failed)
 Randomly corrupt the SYNC8 field for testing purposes.
 
pkt_err_t pkt_test_random_set_crc16 (packet_t *restrict pkt)
 Randomly corrupt the CRC16 field for testing purposes.
 

Detailed Description

Implementation of the Plant-B application layer protocol. Provides packet creation, encoding, decoding, header and payload access, CRC16 error detection and XOR-based single-packet error recovery.

A packet is 111 bytes laid out as follows:

Field Size (bytes) Description
SYNC8 1 Synchronization word (0xAA)
ID 2 Globally incrementing packet identifier
DCT 1 Domain (bits 7-6), Category (5-4), Type (3-0)
INDEX 2 Chunk sequence number (0-based)
TOTAL 2 Total chunks minus 1
PAYLOAD 48 Useful data
XOR_PART 53 XOR redundancy over DCT+INDEX+TOTAL+PAYLOAD
CRC16 2 CRC16-CCITT/FALSE over ID through XOR_PART

All multi-byte fields are stored in big-endian byte order.

Todo
Provide an implementation for images, video streams and events.

Data Structure Documentation

◆ category_t

union category_t

Type-safe union for the category field of a packet header.

The active member depends on the domain field of the enclosing header_t. Use u8 for raw byte access when packing/unpacking the DCT byte.

Data Fields
tc_category_t tc Category interpreted as a TC category.
test_category_t test Category interpreted as a Test type.
tm_category_t tm Category interpreted as a TM category.
uint8_t u8 Raw byte value for DCT packing.

◆ type_t

union type_t

Type-safe union for the type field of a packet header.

The active member depends on both the domain and category fields of the enclosing header_t. Use u8 for raw byte access when packing/unpacking the DCT byte.

Data Fields
tm_bdata_type_t bdata Type interpreted as a TM big data type.
tc_ctrl_type_t ctrl Type interpreted as a TC control type.
tm_event_type_t event Type interpreted as a TM event type.
tc_req_type_t req Type interpreted as a TC request type.
tm_sdata_type_t sdata Type interpreted as a TM small data type.
uint8_t u8 Raw byte value for DCT packing.

◆ header_t

struct header_t

Decoded representation of the packet header fields.

Used as an intermediate, human-readable form between raw packet bytes and application logic. The DCT byte is unpacked into its three components; index and total are decoded from big-endian.

Data Fields
category_t category Message category (bits 5–4 of DCT).
domain_t domain Message domain (bits 7–6 of DCT).
uint16_t index Chunk sequence number (0-based).
uint16_t total Total number of chunks minus 1.
type_t type Message type (bits 3–0 of DCT).

Macro Definition Documentation

◆ PACKET_BYTES

#define PACKET_BYTES   (111)

Total packet size in bytes.

◆ PAYLOAD_BYTES

#define PAYLOAD_BYTES   (48)

Size of the payload field in bytes.

◆ PKT_NO_LOCATION

#define PKT_NO_LOCATION   (-1)

Sentinel value returned by pkt_decode() when no packet was recovered from the decoding pool.

Typedef Documentation

◆ packet_t

typedef struct packet packet_t

Opaque packet handle.

The internal layout of a packet is not exposed. Use the provided API functions to create, populate, encode, decode and destroy packets.

◆ pkt_dec_pool_t

typedef struct pkt_dec_pool pkt_dec_pool_t

Opaque decoder pool handle.

Holds the receiver circular buffer of exactly 32 slots storing incoming packets, the XOR_PART redundancy data, and the reception bitmap used to track received and lost packets and to drive recovery attempts.

◆ pkt_enc_pool_t

typedef struct pkt_enc_pool pkt_enc_pool_t

Opaque encoder pool handle.

Holds the transmitter circular buffer of exactly 32 slots used to compute the XOR_PART field of each outgoing packet.

Enumeration Type Documentation

◆ domain_t

enum domain_t : uint8_t

Top-level message domain.

Encoded in bits 7–6 of the DCT byte.

Enumerator
DOMAIN_TM 

Telemetry domain (CubeSat to Ground).

DOMAIN_TC 

Telecommand domain (Ground to CubeSat).

DOMAIN_TEST 

Test domain (Ground to CubeSat, for tests only).

◆ pkt_err_t

enum pkt_err_t

Return codes for packet utility functions.

Enumerator
PKT_OK 

Operation completed successfully.

PKT_FAIL 

Generic failure.

PKT_ERR_INVALID_ARG 

One or more arguments are invalid or NULL.

PKT_ERR_SYNC 

SYNC8 word mismatch: packet boundary error.

PKT_ERR_CRC 

CRC16 mismatch: packet is corrupted.

◆ tc_category_t

enum tc_category_t : uint8_t

Categories within the Telecommand domain.

Encoded in bits 5–4 of the DCT byte when domain is DOMAIN_TC.

Enumerator
TC_CTRL 

Control commands (e.g. reboot).

TC_REQ 

Data or status requests.

◆ tc_ctrl_type_t

enum tc_ctrl_type_t : uint8_t

Types within the Telecommand / Control category.

Encoded in bits 3–0 of the DCT byte.

Todo
Add other useful control sequences.
Enumerator
TC_CTRL_REBOOT 

Force a system reboot.

◆ tc_req_type_t

enum tc_req_type_t : uint8_t

Types within the Telecommand / Request category.

Encoded in bits 3–0 of the DCT byte.

Enumerator
TC_REQ_SENSORS 

Request current sensor measurements.

TC_REQ_STATUS 

Request current system status.

TC_REQ_IMAGE 

Request image transmission.

TC_REQ_VIDEO 

Request video transmission.

TC_REQ_LOG 

Request log retrieval.

TC_REQ_ERROR 

Request error list.

TC_REQ_CRASH 

Request last crash information.

◆ test_category_t

enum test_category_t : uint8_t

Types within the Test domain.

The Test domain has no category level; this enum encodes the type directly. Encoded in bits 3–0 of the DCT byte when domain is DOMAIN_TEST.

Enumerator
TEST_WIMG 

Write an image to OBC memory.

TEST_FRM 

Remove a file from OBC file system.

TEST_MSG 

Send a text message.

◆ tm_bdata_type_t

enum tm_bdata_type_t : uint8_t

Types within the Telemetry / Big data category.

Encoded in bits 3–0 of the DCT byte.

Note
Reserved for future use.
Enumerator
TM_BDATA_IMAGE 

Image data (JPEG).

TM_BDATA_VIDEO 

Video stream (H.264).

◆ tm_category_t

enum tm_category_t : uint8_t

Categories within the Telemetry domain.

Encoded in bits 5–4 of the DCT byte when domain is DOMAIN_TM.

Enumerator
TM_SDATA 

Small data (sensor measurements, system status).

TM_BDATA 

Big data (images, video streams).

TM_EVENT 

Events (logs, errors, crashes).

◆ tm_event_type_t

enum tm_event_type_t : uint8_t

Types within the Telemetry / Event category.

Encoded in bits 3–0 of the DCT byte.

Note
Reserved for future use.
Enumerator
TM_EVENT_LOG 

Normal event log.

TM_EVENT_ERROR 

Non-critical error.

TM_EVENT_CRASH 

Critical failure / crash report.

◆ tm_sdata_type_t

enum tm_sdata_type_t : uint8_t

Types within the Telemetry / Small data category.

Encoded in bits 3–0 of the DCT byte.

Enumerator
TM_SDATA_SENSORS 

Sensor measurements payload.

TM_SDATA_STATUS 

System status payload.

Function Documentation

◆ dec_pool_create()

pkt_dec_pool_t * dec_pool_create ( void )

Allocate and initialize a decoder pool.

The decoder pool holds exactly 32 slots storing incoming packets and their XOR_PART redundancy data, along with a reception bitmap. Pass it to pkt_decode() to enable automatic single-packet error recovery.

Returns
Pointer to the new pkt_dec_pool_t, NULL on allocation failure.

◆ dec_pool_destroy()

void dec_pool_destroy ( pkt_dec_pool_t *restrict pool)

Free a decoder pool allocated by dec_pool_create().

Parameters
[in,out]poolPool to destroy. Logs a warning if the pool is NULL.

◆ dec_pool_get_pkt_from_relative_loc()

pkt_err_t dec_pool_get_pkt_from_relative_loc ( const pkt_dec_pool_t *restrict pool,
int8_t relative_loc,
packet_t *restrict pkt )

Reconstruct a recovered packet from the decoder pool.

After pkt_decode() reports a recovered packet via relative_loc, call this function to copy that slot back into a packet_t for application-level processing.

Parameters
[in]poolDecoder pool.
[in]relative_locRelative index returned by pkt_decode(). Must be in the range (PKT_NO_LOCATION, POOL_DEPTH).
[out]pktPacket to fill with the recovered data.
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGAny pointer is NULL, relative_loc equals PKT_NO_LOCATION or relative_loc exceeds the pool depth.

◆ enc_pool_create()

pkt_enc_pool_t * enc_pool_create ( void )

Allocate and initialize an encoder pool.

The encoder pool holds exactly 32 slots used to compute the XOR_PART field of each outgoing packet. Pass it to pkt_encode() to enable XOR-based error recovery on the receiver side.

Returns
Pointer to the new pkt_enc_pool_t, NULL on allocation failure.

◆ enc_pool_destroy()

void enc_pool_destroy ( pkt_enc_pool_t *restrict pool)

Free an encoder pool allocated by enc_pool_create().

Parameters
[in,out]poolPool to destroy. Logs a warning if the pool is NULL.

◆ header_old_sensor_config()

pkt_err_t header_old_sensor_config ( header_t *restrict header,
uint16_t old_id )

Configure a header for a retransmitted (old) sensor measurement packet.

Sets domain to DOMAIN_TM, category to TM_SDATA, type to TM_SDATA_SENSORS. The index field carries the original packet ID and total is set to 0xFFFF to signal a retransmission.

Parameters
[out]headerHeader to configure.
[in]old_idOriginal packet ID being retransmitted.
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGheader is NULL.
Warning
This behaviour is specific to this implementation and is not part of the Plant-B application layer protocol. It highlights a limitation of the current sensor payload format, which carries no timestamp or any other field that would allow tracking when measurements were taken.

◆ header_sensor_config()

pkt_err_t header_sensor_config ( header_t *restrict header)

Configure a header for a current sensor measurement packet.

Sets domain to DOMAIN_TM, category to TM_SDATA, type to TM_SDATA_SENSORS, and clears index and total (non-chunked).

Parameters
[out]headerHeader to configure.
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGheader is NULL.

◆ pkt_create()

packet_t * pkt_create ( void )

Allocate and initialize a packet, with each byte set to 0.

Returns
Pointer to the new packet_t, NULL on allocation failure.

◆ pkt_decode()

pkt_err_t pkt_decode ( const packet_t *restrict pkt,
pkt_dec_pool_t *restrict pool,
int8_t *restrict relative_loc )

Validate and decode a received packet.

Checks the SYNC8 word and the CRC16. If both pass, the packet is stored in the decoder pool (if provided), the reception bitmap is updated, and a single-packet XOR recovery is attempted if any slot in the pool is unknown. The relative location of a successfully recovered packet is written to relative_loc.

Parameters
[out]pktPacket to decode.
[in,out]poolDecoder pool. If NULL, no recovery is attempted and a warning is logged.
[out]relative_locRelative index (from the current pool head) of the recovered packet or PKT_NO_LOCATION if none was recovered. May be NULL if not needed.
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGpkt is NULL.
PKT_ERR_SYNCSYNC8 mismatch.
PKT_ERR_CRCCRC16 mismatch.

◆ pkt_destroy()

void pkt_destroy ( packet_t *restrict pkt)

Free a packet allocated by pkt_create().

Parameters
[in,out]pktPacket to destroy. Logs a warning if the packet is NULL.

◆ pkt_encode()

pkt_err_t pkt_encode ( packet_t *restrict pkt,
pkt_enc_pool_t *restrict pool )

Finalize and encode a packet for transmission.

Sets the SYNC8 word, assigns a globally unique ID (atomically incremented, thread safe), computes the XOR_PART field if a pool is provided and appends the CRC16. The header and payload must have been set beforehand via pkt_set_header() and pkt_set_payload().

Parameters
[out]pktPacket to encode.
[in,out]poolEncoder pool used to compute XOR_PART. If NULL, the XOR_PART field is left as is and a warning is logged.
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGpkt is NULL.

◆ pkt_get_header()

pkt_err_t pkt_get_header ( const packet_t *restrict pkt,
header_t * header )

Unpack the header fields from a raw packet.

Decodes the DCT byte into domain, category and type then converts INDEX and TOTAL from big-endian to host byte order.

Parameters
[in]pktPacket to read from.
[out]headerDecoded header.
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGAny pointer is NULL.

◆ pkt_get_id()

pkt_err_t pkt_get_id ( const packet_t *restrict pkt,
uint16_t * id )

Read the packet identifier.

Parameters
[in]pktPacket to read from.
[out]idDecoded 16-bit packet ID.
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGAny pointer is NULL.

◆ pkt_get_payload()

pkt_err_t pkt_get_payload ( const packet_t *restrict pkt,
uint8_t * payload,
size_t len )

Copy the payload field out of a packet.

Always copies exactly PAYLOAD_BYTES bytes into payload.

Parameters
[in]pktPacket to read from.
[out]payloadDestination buffer.
[in]lenSize of payload in bytes. Must be >= PAYLOAD_BYTES.
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGAny pointer is NULL or len < PAYLOAD_BYTES.

◆ pkt_is_chunked()

bool pkt_is_chunked ( const packet_t *restrict pkt)
inline

Check whether a packet carries chunked data.

A packet is considered chunked if its TOTAL field is non-zero, meaning it is one of several chunks making up a larger payload.

Parameters
[in]pktPacket to check.
Return values
trueThe packet is part of a chunked sequence.
falseThe packet carries a self-contained payload.

◆ pkt_log()

pkt_err_t pkt_log ( const packet_t *restrict pkt)

Log a human-readable dump of a packet to the PAL logger.

Prints the packet ID, domain, category, type, index, total, payload bytes and XOR_PART bytes at INFO level.

Parameters
[in]pktPacket to log.
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGpkt is NULL.

◆ pkt_set_header()

pkt_err_t pkt_set_header ( packet_t *restrict pkt,
const header_t *restrict header )

Pack header fields into a raw packet.

Encodes domain (bits 7–6), category (bits 5–4), and type (bits 3–0) into the DCT byte, and stores INDEX and TOTAL in big-endian byte order.

Parameters
[in,out]pktPacket to write to.
[in]headerHeader to pack.
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGAny pointer is NULL.

◆ pkt_set_payload()

pkt_err_t pkt_set_payload ( packet_t *restrict pkt,
const uint8_t *restrict payload,
size_t len )

Copy data into the payload field of a packet.

Copies len bytes from payload into the packet. If len is smaller than PAYLOAD_BYTES, the remainder of the field is zero-padded.

Parameters
[in,out]pktPacket to write to.
[in]payloadSource data buffer.
[in]lenNumber of bytes to copy. Must be in (0, PAYLOAD_BYTES].
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGAny pointer is NULL or len is out of bounds.

◆ pkt_test_random_set_crc16()

pkt_err_t pkt_test_random_set_crc16 ( packet_t *restrict pkt)

Randomly corrupt the CRC16 field for testing purposes.

With a probability of 1/RAND_THRESHOLD, replaces CRC16 with a random 16-bit value. Uses the ESP32 hardware RNG.

Parameters
[in,out]pktPacket whose CRC16 may be corrupted.
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGpkt is NULL.
Note
For tests only.

◆ pkt_test_random_set_sync8()

pkt_err_t pkt_test_random_set_sync8 ( packet_t *restrict pkt,
bool * failed )

Randomly corrupt the SYNC8 field for testing purposes.

With a probability of 1/RAND_THRESHOLD, sets SYNC8 to 0x00 and writes true to failed. Uses the ESP32 hardware RNG.

Parameters
[in,out]pktPacket whose SYNC8 may be corrupted.
[out]failedSet to true if the field was corrupted, false otherwise.
Return values
PKT_OKOn success.
PKT_ERR_INVALID_ARGpkt is NULL.
Note
For tests only.