RDMnet  HEAD (unstable)
Implementation of ANSI E1.33 (RDMnet)
View other versions:
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
Data Ownership Paradigms in the RDMnet Library

RDMnet APIs are non-ownership-transferring; this means that when calling API functions that take pointers to data buffers as arguments, the data buffer memory is owned by the caller, and the caller is responsible for managing that memory both before and after the API function call.

For example, consider sending an RDM command with parameter data using the RDMnet controller API:

#include <stdlib.h>
#include <stdint.h>
uint8_t* device_label_data = (uint8_t*)malloc(32);
strcpy(device_label_data, "New Device Label");
uint32_t cmd_seq_num;
etcpal_error_t result = rdmnet_controller_send_set_command(my_controller_handle, my_scope_handle, &dest,
E120_DEVICE_LABEL, device_label_data,
strlen(device_label_data), &cmd_seq_num);
// The library uses and is finished with the device_label_data buffer by the time
// rdmnet_controller_send_set_command() returns. Now we are responsible for freeing the memory.
free(device_label_data);
// Of course, this would not be necessary if we used a static buffer or a buffer on the stack, e.g.:
uint8_t device_label_data[32];
Definitions for the RDMnet Controller API.
T free(T... args)
etcpal_error_t
#define RDMNET_ADDR_TO_DEFAULT_RESPONDER(manu_id, dev_id)
Initialize an RdmnetDestinationAddr with a default responder address.
Definition: client.h:106
etcpal_error_t rdmnet_controller_send_set_command(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle, const RdmnetDestinationAddr *destination, uint16_t param_id, const uint8_t *data, uint8_t data_len, uint32_t *seq_num)
Send an RDM SET command from a controller on a scope.
Definition: controller.c:713
T malloc(T... args)
T strcpy(T... args)
T strlen(T... args)
A destination address for an RDM command in RDMnet's RPT protocol.
Definition: client.h:84

Callbacks

The same non-ownership-transferring principle applies to callbacks delivered from the RDMnet library. The library retains ownership of any data buffers supplied to a callback; if a library user wants to access that data after the callback returns, it must be saved.

The API provides convenient saving functions to make copies of data buffers present in commands. Of course, data can also be saved manually from the data members.

bool controller_rdm_response_callback(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle,
const RdmnetRdmResponse* resp, void* context)
{
// resp->rdm_data and resp->original_cmd_data are pointers to data buffers owned by the library.
// These buffers will be invalid once this callback finishes.
// You can copy out data manually:
memcpy(my_data_buf, resp->rdm_data, resp->rdm_data_len);
// Or using the save function to create a version with owned data:
rdmnet_save_rdm_response(resp, &saved_resp);
// If you use this method, you must then free the saved_resp data when you're done with it:
return true;
}
etcpal_error_t rdmnet_free_saved_rdm_response(RdmnetSavedRdmResponse *saved_response)
Free the memory owned by a saved RDM response.
Definition: message.c:265
int rdmnet_client_scope_t
Definition: client.h:41
etcpal_error_t rdmnet_save_rdm_response(const RdmnetRdmResponse *response, RdmnetSavedRdmResponse *saved_response)
Save the data in a received RDM response for later use from a different context.
Definition: message.c:102
int rdmnet_controller_t
Definition: controller.h:54
T memcpy(T... args)
Definition: message.h:91
const uint8_t * rdm_data
Definition: message.h:117
size_t rdm_data_len
Definition: message.h:119
An RDM response received over RDMnet and saved for later processing.
Definition: message.h:139