To create a device instance, use the rdmnet_device_create() function in C, or instantiate an rdmnet::Device and call its Startup() function in C++.
The RDMnet device API is an asynchronous, callback-oriented API. Part of the initial configuration for a device instance is a set of function pointers (or abstract interface) for the library to use as callbacks. Callbacks are dispatched from the background thread that is started when the RDMnet library is initialized.
A set of configuration settings that a device needs to initialize.
Definition: device.h:378
Deinitialization
The device should be shut down and destroyed gracefully before program termination. This will send a graceful disconnect message to any connected broker and deallocate the device's resources.
Devices operate on a single RDMnet scope at a time, which is set at initial configuration time when the device instance is created, and can be changed using rdmnet_device_change_scope(). See the "Scopes" section in How RDMnet Works for more information on scopes.
On startup, a device will immediately begin the scope connection state machine from the RDMnet tick thread. If a static configuration is not provided (using the RDMNET_CLIENT_SET_SCOPE() macro to initialize the device's RdmnetScopeConfig, or calling rdmnet::Device::Startup() without a static_broker_addr argument), the first action will be to attempt to discover brokers for this scope via DNS-SD. Once a broker is found, connection will be initiated automatically, and the result will be delivered via either the connected or connect_failed callback.
If a broker for a given scope has been configured with a static IP address and port, you can skip DNS-SD discovery by providing this address to the relevant functions/macros.
You can change the initial scope configuration before the device is started:
The library will dispatch callback notifications from the background thread which is started when rdmnet_init() is called. It is safe to call any RDMnet API function from any callback.
Generally the first callback a device gets will be when it has connected to a broker:
A handle type used by the RDMnet library to identify device instances.
Definition: device.h:318
Connection Failure
It's worth noting connection failure as a special case here. RDMnet connections can fail for many reasons, including user misconfiguration, network misconfiguration, components starting up or shutting down, programming errors, and more.
The ClientConnectFailedInfo and ClientDisconnectedInfo structs passed back with the "connect failed" and "disconnected" callbacks respectively have comprehensive information about the failure, including enum values containing the library's categorization of the failure, protocol reason codes and socket errors where applicable. This information is typically used mostly for logging and debugging. Each of these codes has a respective to_string() function to aid in logging.
For programmatic use, the structs also contain a will_retry member which indicates whether the library plans to retry this connection in the background. The only circumstances under which the library will not retry is when a connection failure is determined to be either a programming error or a user misconfiguration. Some examples of these circumstances are:
The broker explicitly rejected a connection with a reason code indicating a configuration error, such as CONNECT_SCOPE_MISMATCH or CONNECT_DUPLICATE_UID.
The library failed to create a network socket before the connection was initiated.
Adding Endpoints and Responders
As explained in Devices and Gateways, RDMnet devices can contain endpoints which serve as grouping mechanisms for virtual or physical RDM responders. The RDMnet device API has functionality for managing endpoints and responders on a local device.
Adding Physical Endpoints and Responders
Physical endpoints are added using the physical endpoint configuration structure. This structure defines the endpoint number (an integer between 1 and 63,999) and any responders which are present on the endpoint initially.
// Create a physical endpoint numbered 1, with no responders on it initially.
Adding and removing physical responders from an endpoint will typically be done when an RDMnet gateway discovers or loses RDM responders on its RDM ports. For example:
Note that the RDMnet library requires the control field (and optional binding UID) received in the DISC_MUTE message from a physical responder, so that controllers can fetch this information.
You can also add responders initially present on an endpoint at the same time as the endpoint is added. This should be done anytime the initial responders on an endpoint are known, as it reduces the volume of RDMnet messages that need to be sent.
The process for adding virtual endpoints is similar to that for physical endpoints, except that virtual responders can have Dynamic UIDs (see Roles and Addressing for more information about this).
Configuration information for a virtual endpoint on a device.
Definition: device.h:71
Before dynamic virtual responders can be used, they must be assigned a dynamic UID. The status of dynamic UID assignment is communicated through the dynamic UID status callback.
A mapping from a dynamic UID to a responder ID (RID).
Definition: dynamic_uid.h:41
One last thing about endpoints: if the set of physical and virtual endpoints that a device has is known at initialization time, they can be added to the initial configuration structures for a device instance, so that they don't need to be added later.
Handling RDM Commands
Handling RDM commands is the main functionality of RDMnet devices. See Handling RDM Commands for information on how to do this.