Skip to main content

Recommended Usage Pattern

More information on the mentioned steps can be found in Functions of the Packet Dispatcher



7)Typical RecommendedUsage usage patternModel

A

Intended clean pattern is:setup

  1. defineDefine one handler callbacksfunction per packet type
  2. define one configpacket_handler_config_t objectentry per packet type (using the macros)
  3. placeprovide allqueue configstorage objectsbuffers
    (When inusing anthe arraymacros, you do not need to do this manually)
  4. passcall thatPacketDispatcherInit(...)
  5. whenever arraya toframe arrives, call DispatchPacket()

Flow after setup

  1. Ethernet/UDP receives raw frame
  2. networking code builds PacketDispatcherInit(receive_frame
  3. DispatchPacket() decodes it
  4. payload type is matched
  5. decoded payload is copied into target queue
  6. matching handler task wakes
  7. the callback processes typed payload

Example



Examples

1) Using macros

//Imports
#include "packet_dispatcher.h"
#include "packet_dispatcher_macros.h"

/*Define handler callbacks*/
//(such that: typedef result_t (*packet_handler_t)(void* buffer) )
static result_t handle_drive_msg(void* buffer) {
    PBDriveMsg* msg = (PBDriveMsg*)buffer;
    return process_drive_msg(msg);
}

static result_t handle_sensor_diag(void* buffer) {
    PBSensorDiag* msg = (PBSensorDiag*)buffer;
    return process_sensor_diag(msg);
}

PACKET_HANDLER_CONFIG_STATIC(drive_handler_cfg,
                             PBEnvelope_drive_msg_tag,
                             drive_msg,
                             handle_drive_msg);

PACKET_HANDLER_CONFIG_STATIC_QUEUE(sensor_diag_handler_cfg,
                                   PBEnvelope_sensor_diag_tag,
                                   sensor_diag,
                                   handle_sensor_diag,
                                   10U);

static packet_handler_config_t* handlers[] = {
    drive_handler_cfg,
    sensor_diag_handler_cfg,
};


2) Manual configuration

//Imports
#include "packet_dispatcher.h"

static result_t handle_drive_cmd(void* buffer) {
    PBDriveCommand* msg = (PBDriveCommand*)buffer;
    return drive_process(msg);
}

static result_t handle_arm_cmd(void* buffer) {
    PBArmCommand* msg = (PBArmCommand*)buffer;
    return arm_process(msg);
}

static uint8_t drive_queue_storage[8 * sizeof(PBDriveCommand)];
static uint8_t arm_queue_storage[4 * sizeof(PBArmCommand)];

static packet_handler_config_t handlers[] = {
    {
        .handler = handle_drive_cmd,
        .task_name = "drive_pkt",
        .packet_type = PBEnvelope_drive_cmd_tag,
        .task_priority = 3,
        .task_stack_depth = 512,
        .item_size = sizeof(PBDriveCommand),
        .queue_length = 8,
        .queue_buffer = drive_queue_storage,
    },
    {
        .handler = handle_arm_cmd,
        .task_name = "arm_pkt",
        .packet_type = PBEnvelope_arm_cmd_tag,
        .task_priority = 3,
        .task_stack_depth = 512,
        .item_size = sizeof(PBArmCommand),
        .queue_length = 4,
        .queue_buffer = arm_queue_storage,
    },
};

Then during startup:

result_t res = PacketDispatcherInit(handlers, ARRAY_LEN(handlers));

And during frame reception:

DispatchPacket(&rx_frame);


Important note about array type

The current PacketDispatcherInit() API expects:

packet_handler_config_t* handlers

meaning a contiguous array of structs, not an array of pointers.

So with the current implementation, the final array should actually be:

static packet_handler_config_t handlers[] = {
    drive_handler_cfg,
    sensor_diag_handler_cfg,
};

not an array of pointers.

That distinction matters. The macros define actual config objects, not pointers.