Skip to main content

Public API


The following functions are available for the boards to use outside of the library.

The public API consists of:

  • packet_handler_t
  • packet_handler_config_t
  • PacketDispatcherInit()
  • DispatchPacket()

There are also stack depth macros:

  • PACKET_HANDLER_TASK_STACK_DEPTH_DEFAULT
  • PACKET_DISPATCHER_TASK_STACK_DEPTH

PACKET_DISPATCHER_TASK_STACK_DEPTH is currently defined but not actually used in the provided implementation.


a.

1) packet_handler_t

typedef result_t (*packet_handler_t)(void* buffer);

This type represents the callback function invoked by a handler task when a packet of its type is received.

Parameters

  • buffer

Pointer to the decoded packet payload copied from the queue. The actual type of buffer depends on the registered packet_type.

For example, if a handler is registered for one specific protobuf payload type, the handler should cast buffer to the corresponding generated struct type.

Return value

Returns result_t. The handler task logs a warning if the return value is not RESULT_OK.

Important constraint

The callback receives only a raw void *.

That means type safety is entirely dependent on correct configuration:

  • packet_type must match the actual protobuf payload member
  • item_size must match the size of that decoded payload type
  • handler must cast buffer to the correct struct type

If any of those mismatch, the code may compile while quietly doing something stupid (and it will be your fault :D).



b.

2) packet_handler_config_t

typedef struct {
    packet_handler_t handler;
    const char* task_name;
    pb_size_t packet_type;

    UBaseType_t task_priority;
    configSTACK_DEPTH_TYPE task_stack_depth;

    size_t item_size;
    UBaseType_t queue_length;

    uint8_t* queue_buffer;
    StaticQueue_t queue_struct;
    QueueHandle_t queue;
} packet_handler_config_t;

Purpose

Describes one packet type and the task/queue resources needed to process it. Each entry in the handler config array corresponds to one routed packet type.

Fields

Detailed description of each field
handler

Callback invoked when a packet of this type is received. Must not be NULL.

task_name

Name used when creating the FreeRTOS task. Must not be NULL.

packet_type

The protobuf discriminator value to match against DecodingEnvelopeCurrent.which_payload, which is the routing key.

task_priority

Priority of the FreeRTOS handler task. If set to zero, that is still a valid FreeRTOS priority value. There is no separate “unset” semantic here.

task_stack_depth

Stack depth for the handler task.

If <= 0, the implementation replaces it with: PACKET_HANDLER_TASK_STACK_DEPTH_DEFAULT. Since this type is typically unsigned, the <= 0 check effectively means “zero” in practice.

item_size

Size of one queued item.

This must match the size of the decoded payload type copied into the queue.

queue_length

Number of items the queue can hold.

queue_buffer

Backing storage for static queue data.

Must be large enough for queue_length * item_size

queue_struct

Static queue control structure used internally by xQueueCreateStatic(). Caller provides storage but should not manually initialize runtime content.

queue

Queue handle written internally during initialization.

Caller should not pre-fill it!



c.

3) PacketDispatcherInit()

result_t PacketDispatcherInit(packet_handler_config_t* handlers,
                              size_t handler_count);

Initializes the dispatcher by...

  • storing the handler registry
  • creating one queue and one task per handler entry

Parameters

handlers

Pointer to an array of handler configurations. The implementation stores a global pointer to it and passes individual entries to tasks.

The handlers array must remain valid for the full lifetime of the system. Do NOT allocate this array on a temporary stack frame unless you are into being abused by segfaults :).

handler_count

Number of entries in the array.



d.

4) DispatchPacket()

void DispatchPacket(receive_frame* incoming_packet);

Decodes one incoming raw frame and routes its decoded payload to the appropriate handler queue.

The function:

  1. validates basic frame properties
  2. creates a nanopb input stream from the raw bytes
  3. decodes into the global static DecodingEnvelopeCurrent
  4. scans the registered handler list
  5. finds the first handler whose packet_type matches which_payload
  6. sends DecodingEnvelopeCurrent.payload to that handler’s queue
  7. returns

If no matching handler is found, it logs a warning. If decode fails, it logs an error.

NOTE: This function returns void, so dispatch failure is only observable through logs.

Parameters

incoming_packet

Pointer to a transport frame containing payload, len of the incoming packet.