dmp.h

Device Management Protocol

Summary
dmp.hDevice Management Protocol
DMP Message formatAll DMP messages relate to DMP addresses within a component and so all specify one or more addresses in a standard address format.
Message supportDMP messages divide into two clear sets.
Macros for address types
Combined message code and address modesFor many purposes Acacian combines the message code with the address type (header) field.
Getting Property Values
Setting Property Values
Events
ComponentsDMP related data for local or remote components (see component.h).
Connection contextDMP is concerned with connections – these structures maintain the transport protocol relevant information including state and context data, details of remote and local components etc.
Component registration
dmp_registerRegister a local component for DMP access.
DMP Transmit FunctionsWithin an SDT wrapper it is possible to send multiple DMP blocks.
dmp_newblockAllocate and open a new DMP PDU block for the given transmit context.
dmp_closeblockClose the accumulated PDU block for the transmit context.
dmp_flushpdusFlush (transmit) the transmit context.
dmp_abortblockReset the pointers for the block and forget any accumulated data.
dmp_openpduOpen a new PDU with the message type and address format given by vecnrange.
dmp_closepduClose and finalize the previously opened PDU
dmp_closeflushClose the current PDU then close and flush all accumulated blocks.
dmp_truncatepduTruncate and close the current PDU at a smaller size/count than specified when it was opened.
Receive functionsReceive is handled by callback functions.
dmp_sdtRxThis is a callback function which must be passed to SDT to have Acacian’s DMP code parse and handle incoming DMP.

DMP Message format

All DMP messages relate to DMP addresses within a component and so all specify one or more addresses in a standard address format.

Certain messages must also specify data relating to each address which is either a value for the property at that address (e.g. set-property, get-property-reply), or a reason code specifying why a command for that address has failed.  The presence of data and whether it is a value or a reason code is fixed for each specific message code.

In the standard PDU format of ACN the DMP message fields are defined as

vectorOne octet message code.
headerOne octet address encoding, determines single vs range address, field size, single vs multiple data, absolute or relative (to previously used) address.
dataOne or more fields of address only, address + data, or address + reason-code as determined by the message code.  The number of fields is determined by the PDU length.

Message support

DMP messages divide into two clear sets.  Support for these is compiled according to whether CF_DMPCOMP_C_ (controller only), CF_DMPCOMP__D (device only) or CF_DMPCOMP_CD (both) is configured.

Controller→Device messages

Devices must correctly receive and handle these and it is an error for a controller-only component to receive any of them.  The address field in these messages refers to the receiving component.

  • DMP_GET_PROPERTY
  • DMP_SET_PROPERTY
  • DMP_SUBSCRIBE
  • DMP_UNSUBSCRIBE

Device→Controller messages

Controllers must receive and handle these and it is an error for a device-only component to receive any of them.  The address field refers to the transmitting component.

  • DMP_GET_PROPERTY_REPLY
  • DMP_GET_PROPERTY_FAIL
  • DMP_SET_PROPERTY_FAIL
  • DMP_SUBSCRIBE_ACCEPT
  • DMP_SUBSCRIBE_REJECT
  • DMP_EVENT
  • DMP_SYNC_EVENT

Macros for address types

macros

IS_RANGE(header)True if the header value specifies a range address
IS_RELADDR(header)True if the header specifies a relative address
IS_MULTIDATA(header)True if there is a data value for each address in the range
IS_RANGECOMMON(header)True if there is just one value applying to all addresses in the range

Combined message code and address modes

For many purposes Acacian combines the message code with the address type (header) field.  These macros define all the combined message/address codes required by Acacian’s transmit code - there are other permitted values but they mostly have arcane use-cases or duplicate functionality.

Note: the choice of relative/absolute addressing is made automatically as PDUs are constructed.

Note: dmp_openpdu() will substitute the single address version whenever count == 1 so multiple address versions can normally be used

Getting Property Values

PDU_GETPROP_ONEGet Property, single address (no values)
PDU_GETPROP_MANYGet Property, range address (no values)
PDU_GPREPLY_ONEGet property reply, single address + value
PDU_GPREPLY_MANYGet property reply, range address + one value per address
PDU_GPFAIL_ONEGet Property Fail, single address + reason
PDU_GPFAIL_MANYGet Property Fail, range address + one reason per address
PDU_GPFAIL_COMMONGet Property Fail, range address + common reason

Setting Property Values

PDU_SETPROP_ONESet Property, single address + value
PDU_SETPROP_MANYSet Property, range address + one value per address
PDU_SETPROP_COMMONSet property, range address + common value
PDU_SPFAIL_ONESet Property Fail, single address + reason
PDU_SPFAIL_MANYSet Property Fail, range address + one reason per address
PDU_SPFAIL_COMMONSet Property Fail, range address + common reason

Events

PDU_EVENT_ONEEvent, single address + value
PDU_EVENT_MANYEvent, range address + one value per address
PDU_SYNCEV_ONESync Event, single address + value
PDU_SYNCEV_MANYSync Event, range address + one value per address
PDU_SUBS_ONESubscribe, single address (no values)
PDU_SUBS_MANYSubscribe, range address (no values)
PDU_SUBOK_ONESubscribe Accept, single address (no values)
PDU_SUBOK_MANYSubscribe Accept, range address (no values)
PDU_SUBREJ_ONESubscribe Reject, single address + reason
PDU_SUBREJ_MANYSubscribe Reject, range address + one reason per address
PDU_SUBREJ_COMMONSubscribe Reject, range address + common reason
PDU_USUBS_ONEUnsubscribe, single address (no values)
PDU_USUBS_MANYUnsubscribe, range address (no values)

Components

DMP related data for local or remote components (see component.h).

dmp_Lcomp_sLocal component DMP layer structure
dmp_Rcomp_sRemote component DMP layer structure

If we are a device the local component must include an address map to enable decoding of addresses.  Similarly for a controller, remote must include an address map.

Connection context

DMP is concerned with connections – these structures maintain the transport protocol relevant information including state and context data, details of remote and local components etc.

On transmission it is possible to be accumulating transmit data in multiple transmit contexts at the same time.  For example while handling a multi-address set-property message or series of messages a device may accumulate set-property-fail responses for some properties in the context of the controller’s session whilst generating event messages in it’s own event session for properties whose value has been successfully changed.

Component registration

dmp_register

int dmp_register(ifMC(struct Lcomponent_s *Lcomp))

Register a local component for DMP access.

Parameters

Lcompthe component being registered.

DMP Transmit Functions

Within an SDT wrapper it is possible to send multiple DMP blocks.  The usual reaason for this is to combine messages to different session members, or to all members, into a single wrapper.  Each block can therefore have a different destination provided each is within the same channel.  The destination is embedded in the transmit context structure.

Within a block there may be multiple DMP PDUs.  Each PDU contains a message code and address format, then multiple address, or address + data fields.

dmp_newblock

int dmp_newblock(struct dmptcxt_s *tcxt,
int *size)

Allocate and open a new DMP PDU block for the given transmit context.  If a block is already open it is first closed.

dmp_closeblock

void dmp_closeblock(struct dmptcxt_s *tcxt)

Close the accumulated PDU block for the transmit context.  Any opened PDU will be closed first.

dmp_flushpdus

void dmp_flushpdus(struct dmptcxt_s *tcxt)

Flush (transmit) the transmit context.  Any open block is closed first then transmitted.

dmp_abortblock

void dmp_abortblock(struct dmptcxt_s *tcxt)

Reset the pointers for the block and forget any accumulated data.

dmp_openpdu

uint8_t *dmp_openpdu(struct dmptcxt_s *tcxt,
uint16_t vecnrange,
struct adspec_s *ads,
int size)

Open a new PDU with the message type and address format given by vecnrange.  The ads structure indicates the number of addresses etc. and size, the space needed.

A new block is opened if necessary.

dmp_closepdu

void dmp_closepdu(struct dmptcxt_s *tcxt,
uint8_t *nxtp)

Close and finalize the previously opened PDU

dmp_closeflush

void dmp_closeflush(struct dmptcxt_s *tcxt,
uint8_t *nxtp)

Close the current PDU then close and flush all accumulated blocks.

dmp_truncatepdu

void dmp_truncatepdu(struct dmptcxt_s *tcxt,
uint32_t count,
uint8_t *nxtp)

Truncate and close the current PDU at a smaller size/count than specified when it was opened.  This is useful when errors are encountered whilst accumulating responses for example.

count specifies the number of items successfully accumulated and nxtp the end of the accumulated data.

Receive functions

Receive is handled by callback functions.  Application level callbacks are specified either in the rxvec field of dmp_Lcomp_s, or for devices may be specified on a per-property basis using DDL property extensions.

dmp_sdtRx

void dmp_sdtRx(struct member_s *memb,
const uint8_t *pdus,
int blocksize,
void *ref)

This is a callback function which must be passed to SDT to have Acacian’s DMP code parse and handle incoming DMP.  DMP is split into individual messages and addresses matched to properties and decoded before calling the application provided message handlers.

Utilities for management of local and remote components
int dmp_register(ifMC(struct Lcomponent_s *Lcomp))
Register a local component for DMP access.
int dmp_newblock(struct dmptcxt_s *tcxt,
int *size)
Allocate and open a new DMP PDU block for the given transmit context.
void dmp_closeblock(struct dmptcxt_s *tcxt)
Close the accumulated PDU block for the transmit context.
void dmp_flushpdus(struct dmptcxt_s *tcxt)
Flush (transmit) the transmit context.
void dmp_abortblock(struct dmptcxt_s *tcxt)
Reset the pointers for the block and forget any accumulated data.
uint8_t *dmp_openpdu(struct dmptcxt_s *tcxt,
uint16_t vecnrange,
struct adspec_s *ads,
int size)
Open a new PDU with the message type and address format given by vecnrange.
void dmp_closepdu(struct dmptcxt_s *tcxt,
uint8_t *nxtp)
Close and finalize the previously opened PDU
void dmp_closeflush(struct dmptcxt_s *tcxt,
uint8_t *nxtp)
Close the current PDU then close and flush all accumulated blocks.
void dmp_truncatepdu(struct dmptcxt_s *tcxt,
uint32_t count,
uint8_t *nxtp)
Truncate and close the current PDU at a smaller size/count than specified when it was opened.
void dmp_sdtRx(struct member_s *memb,
const uint8_t *pdus,
int blocksize,
void *ref)
This is a callback function which must be passed to SDT to have Acacian’s DMP code parse and handle incoming DMP.
Build DMP controller code only
Build DMP device code only
Build combined device and controller code
Local component DMP layer structure
Close