Options for building ACN

Do not edit acncfg.h!

You should not need to edit this header itself.  Instead create a header acncfig_local.h containing any configuration definitions which differ from the defaults described here.  Those options will then override the defaults.

IntroductionThere are many compile time options for building Acacian.
Main OptionsAll options are documented below.
Option Details
Operating system (and stack)Currently only linux is supported but we define some configuration options to bracket OS dependent code.
Network and Transport FeaturesIP version (or other transport)
LoggingLogging options
Data Marshalling and Unmarshalling
Error Checking
Component Model
UUID trackingACN uses UUIDs extensively and various structures including both localor remote components and DDL modules are indexed by UUID.
Event loop and timing
Root Layer Protocol
CF_MAPGENEnable static map generation extensions
EPIsConformance to specific EPIs.


There are many compile time options for building Acacian.  Some of these make significant improvements in code size or performance in specific cases.

Your local build configuration should be defined in “local_cfg.h” which overrides the default values for any options you need to change.

”local_cfg.h” is then included in “acncfg.h” which is included (usually indirectly via “acn.h”) in virtually every source file.  Do not edit “acncfg.h” itself unless adding completely new options to the code.

Important: Most relevant configuration options must be defined to something – usually either to 0 (disabed) or to 1 (enabled).  They are tested using #if ... rather than #ifdef ... and if undefined may result in strange behavior.  The exception is when whole modules are omitted when their detailed configuration options may be left undefined.

Main Options

All options are documented below.  However, to get started, the most significant options you should look at are:

Option Details


CF_VERSIONAn integer which represents the ACN revision to be compiled.


20060000the original ANSI ESTA E1.17-2006 version
20100000the revised version ANSI ESTA E1.17-2010

As of April 2012 only 20100000 is supported

Note: These parts of the original 2006 standard were revised in 2010

  • SDT
  • DMP
  • DDL
  • EPI-10
  • EPI-11
  • EPI-18
  • EPI-19
  • EPI-22

EPIs which were not included in the original ACN suite have their own standardization process and may need their own version numbers as necessary.

Operating system (and stack)

Currently only linux is supported but we define some configuration options to bracket OS dependent code.

CF_OS_LINUXOperating system is Linux.  Macro defines to version number (3 digits each for minor and sub-versions) allowing version tests, though in most cases this is not relevant.
CF_STACK_xxxOnly needed where stack is not defined by the OS default.

Network and Transport Features

IP version (or other transport)

CF_NET_IPV4IP version 4
CF_NET_IPV6IP version 6 (experimental)

Picking more than one is allowed and automatically defines CF_NET_MULTI below but makes code more complex so rely on IPv6 and a hybrid stack which automatically handles IPv4 if you can.  However, this isn’t so well tested.

CF_MAX_IPADSMaximum number of supported IP addresses

The code supports multihoming.  This parameter may be used to set the amount of memory allocated for IP addresses in various operations.

CF_LOCALIP_ANYDelegate all interface decisions to the OS/stack

In hosts with multiple interfaces (including the loopback interface) it is normal to accept packets received on any interface and to leave it to the stack to select the interface for outgoing packets by binding sockets to INADDR_ANY.

If set, RLP and SDT rely on the stack to handle IP addresses and interfaces and Acacian only stores port information.  This saves using resources tracking redundant interface information.  If clear then the API allows higher layers to specify individual interfaces (by their address) at the expense of slightly more code and memory.  This setting still allows the value netx_INADDR_ANY to be explicitly used as required.

CF_MULTICAST_TTLIP multicast TTL value

The Linux manual (man 7 ip) states “It is very important for multicast packets to set the smallest TTL possible” but this conflicts with rfc2365 and SLP defaults to 255.  We follow the RFC thinking by default – routers at critical boundaries will usually block multicast from going further without explicit configuration anyway.

CF_JOIN_TX_GROUPSJoining our own multicast groups

Ideally we don’t want to join all the outgoing groups we transmit on as this just means we get our own messages back.  However, joining a group prompts the stack to emit the correct IGMP messages for group subscription and some (older usually) switches with IGMP snooping will block any messages we transmit to that group unless we do that.

RECEIVE_DEST_ADDRESSRecover the destination address for received packets

When a host has joined many mulitcast groups, it may be useful to know on receipt of a packet, which group it belongs to.  However, this is the destination address in an incoming packet and many stacks make it tortuous or impossible to extract this information so Acacian code cannot rely on this option.


Logging options

These are currently compile-time options so logging cannot be changed in running code.

CF_ACNLOGdetermine how messages are logged.
CF_LOGLEVELdetermine what level of messages are logged.

Options for CF_ACNLOG are

ACNLOG_OFFAll logging is compiled out
ACNLOG_STDOUTLog to standard output (default)
ACNLOG_STDERRLog to standard error

Syslog handles logging levels itself and CF_LOGLEVEL is ignored.  For other options log messages up to CF_LOGLEVEL are logged and higher levels are ignored.  Possible values are (in increasing order).


The acnlog() macro is formatted to match the POSIX syslog...

extern void syslog(int, const char *, ...);

Where int is the combination of facility and error level (or’d), const * is a formatting string and ... is a list of arguments.  This allows for a function similar to the standard printf

Individual modules (rlp, sdt etc.) each have their own facilities which may be set in <acncfg_local.h> to

LOG_OFFdon’t log (the default)
LOG_ONlog to the default facility (same as LOG_USER)

Or if using syslog you may select a specific facility e.g.  LOG_LOCAL0

for example

#define LOG_RLP LOG_ON
acnlog(LOG_RLP, "I got an error");
anclog(LOG_RLP, "I got %d errors", error_count);

Log levels can still be added: this would only print if CF_LOGLEVEL was LOG_INFO or higher:

acn_log(LOG_RLP | LOG_INFO, "I do not like errors");
CF_LOGFUNCSLog function entry and exit

Useful for deep debugging but very verbose, function start (and end) logging gets its own config so it can be turned off separately.

LOG_RLPLog the root layer
LOG_NETXLog network interface
LOG_DDLLog DDL parsing
LOG_MISCLog various utilities
LOG_EVLOOPLog the event/timer loop
LOG_E131Log sACN
LOG_APPAvailable for your application
LOG_SESSSpecial setting for SDT sessions command

Separate macros allow logging to be set for different modiles

Data Marshalling and Unmarshalling

CF_MARSHAL_INLINEUse inline functions for Data Marshalling

Inline functions for marshaling data are efficient and typecheck the code.  If the compiler supports inline code well then they are preferable.

If you do not want to compile inline, then setting this false uses macros instead, but these evaluate their arguments multiple times and do not check their types so beware.

Error Checking

CF_STRICT_CHECKSExtra error checking

We can spend a lot of time checking for unlikely errors Turn on CF_STRICT_CHECKS to enable a bunch of more esoteric and paranoid tests.

Component Model

CF_MULTI_COMPONENTOne or many components?

A large number of applications (probably the majority) only define a single component, so including code to register and maintain many of them is wasteful.  If your application implements multiple components then set this true.

ACN_FCTN_SIZELength (in bytes) assigned for FCTN
ACN_UACN_SIZELength (in bytes) assigned for UACN

Fixed Component Type Name (FCTN) and User Assigned Component Name (UACN) are defined in EPI19.  They are also used in E1.31.  They are transmitted in UTF-8 encoding.

The standard does not specify a size for FCTN so we arbirarily assign storage.

The standard specifies a minimum storage of 63 characters for UACN which can require 189 bytesa if stored as UTF-8.  This is probably a mistake in the standard which should have specified 63 octets however we default to 190 to be on the safe side.  Storing as UTF-16 would require less storage but more processing.

UUID tracking

ACN uses UUIDs extensively and various structures including both localor remote components and DDL modules are indexed by UUID.  Acacian implements generic routines for high speed indexing and searching by UUID see uuid.h.

CF_UUIDS_RADIXUse radix tree (patricia tree) to store UUIDs
CF_UUIDS_HASHUse a hash table to store UUIDs (not tested recently).

These are mutually exclusive.  If using CF_UUIDS_HASH you may also want to change:

CF_Rcomp_HASHBITSHash size for remote component table
CF_Lcomp_HASHBITSHash size for local component table
CF_DDL_HASHBITSHash size for DDL modules

If using CF_UUIDS_HASH then the size of the hash table (number of bits in the hash) must be defined for each table.

Event loop and timing

CF_EVLOOPUse Acacian event loop and timing services

Acacian provides a single threaded event loop using epoll.  The application can register its own events in this loop if desired.  Turn this off to provide an alternative model

CF_TIME_msUse simple millisecond integers for times
CF_TIME_POSIX_timevalUse POSIX timeval struictures for timing
CF_TIME_POSIX_timespecUse timespec struictures for timing

Millisecond counters are adequate (just) for SDT specifications.

Root Layer Protocol

CF_RLPenable the ACN root layer

Root layer is needed for UDP but may not be needed for other transports.

CF_RLP_MAX_CLIENT_PROTOCOLSNumber of client protocols to allocate space for

Typically very few client protocols are used.  The default is to build a generic RLP for multiple client protocols However, efficiency gains can be made if RLP is built for only one client protocol (probably SDT or E1.31), in this case set CF_RLP_MAX_CLIENT_PROTOCOLS to 1 and define CF_RLP_CLIENTPROTO to the protocol ID of that client.

CF_RLP_CLIENTPROTOClient protocol ID for single protocol implementations. ignored if CF_RLP_MAX_CLIENT_PROTOCOLS is greater than one.

e.g.  For SDT only support


Normally both CF_RLP_MAX_CLIENT_PROTOCOLS and CF_RLP_CLIENTPROTO are set to useful default values depending on CF_SDT and CF_E131

CF_RLP_OPTIMIZE_PACKOptimize PDU packing in RLP (at the cost of speed)


CF_SDTenable the SDT layer
CF_SDT_MAX_CLIENT_PROTOCOLSNumber of client protocols to allocate space for.  Typically very few client protocols are used.  See CF_RLP_MAX_CLIENT_PROTOCOLS for explanation of this and CF_SDT_CLIENTPROTO
CF_SDT_CLIENTPROTOClient protocol for single protocol implementations

e.g. for DMP only

CF_SDTRX_AUTOCALLWhen an sdt wrapper is correctly received it is placed in an ordered queue.  If CF_SDTRX_AUTOCALL is set then all queued messages are unpacked and processed on completion of the wrapper processing.  If not defined then readrxqueue must be called from elsewhere to process the queue.
CF_SDT_CHECK_ASSOCThe association field in SDT wrappers is entirely redundant and this implementation has no need of it.  It sets it appropriately on transmit but only checks on receive if this macro is true.


CF_DMPenable the DMP layer

Device or Controller?

CF_DMPCOMP__DBuild DMP device code only
CF_DMPCOMP_C_Build DMP controller code only
CF_DMPCOMP_CDBuild combined device and controller code

At least one must be set.  Many components need to implement both device and controller functions, but if they only do one or the other then a bunch of code can be omitted.

Note: for a multicomponent implementation (see CF_MULTI_COMPONENT) then if both funtionalities must be built unless it is guaranteed that all local components will be either device-only or controller-only.

DMP_MAX_SUBSCRIPTIONSNumber of property subscriptions to accept
CF_DMPAD_MAXBYTESMaximum DMP address size

For DMP devices where it is known that all addresses fall within a one or two byte range, reducing CF_DMPAD_MAXBYTES to 1 or 2 may enable some simplifications.  For generic controller code this must be four (or undefined).

Property Mapping DMP usually uses property maps to screen for bad addresses, for access permissions, and to tie incoming messages to device properties.  These property maps can be generated from DDL.

CF_DMPMAP_SEARCHUse a binary search to identify the property associated with an address.  This is the most generic form suitable for use in general purpose controllers or code serving multiple complex devices.
CF_DMPMAP_INDEXStore properties in an array indexed by address.  It is faster and simpler than searching but only suitable for applications where all device types are known and whose property addresses are packed close enough to fit within a directly addressed array.
CF_DMPMAP_NONEeliminate all address checking code in the DMP layer and simply passes up all addresses unchecked to the application.
CF_DMPMAP_NAMEFor a single device or a controller matched to a single device type, define to the name of the statically defined map structure to save a lot of passing pointers and references.  Leave undefined if not using this.
Transport protocolsDMP may operate over multiple transport protocols. e.g.  SDT and TCP CF_DMP_MULTITRANSPORT
CF_DMPON_SDTInclude SDT transport support
CF_DMPON_TCPInclude TCP transport support
CF_DMP_RMAXCXNSNumber of connections to/from the same remote component.  These take space in the component structure for each remote.


CF_DDLEnable DDL code

DDL Parsing is rather open ended.  We have various levels starting at a basic parse which extracts only DMPproperty map - even this level needs to support parameters and includedevs

CF_DDLACCESS_DMPCompile DDL for DMP access
CF_DDLACCESS_EPI26Compile DDL for EPI26 (DMX/E1.31) access

DDL describes how to access network devices using an access protocol.  It is currently defined for two access protocols, DMP and EPI26 (E1.31/DMX512) and may be extended to others.

CF_DDL_BEHAVIORSParse and apply DDL behaviors
CF_DDL_IMMEDIATEPROPSParse and record values for immediate properties.
CF_DDL_MAXNESTMaximum XML nesting level within a single DDL module.
CF_DDL_MAXTEXTSize allocated for parsing text nodes.


Enable static map generation extensions


CF_E131Enable E1.31 code
CF_E131_RXGenerate receive code
CF_E131_TXgenerate transmit code

We have separate configures for transmit and receive as they are frequently different components and do not share much code.

E131MEM_MAXUNIVSMaximum number of universes to track
CF_E131_ZSTART_ONLYDrop ASC packets on read and automatically add a zero start on write
CF_E131_IGNORE_PREVIEWDrop preview packets on read and never set preview on write.  All the while PREVIEW is the only option flag apart from Terminate, this also cuts passing of options to and from the app altogether.


Conformance to specific EPIs.  This is the complete set of EPIs for ACN 2010 p;us some defined in ANSI E1.30.  They are defined (or not) for completeness but some have no effect.

Note: Turning some of these options off may just mean the system will not build since there are currently no alternatives available.

CF_EPI10Multicast address allocation
CF_EPI11DDL Retrieval
CF_EPI12Requirements on Homogeneous Ethernet Networks
CF_EPI13IPv4 Addresses.  Superseded by EPI29
CF_EPI15Multicast allocation infrastructure
CF_EPI16ESTA/PLASA Identifiers
CF_EPI17Root layer protocol for UDP
CF_EPI18Requirements for SDT on UDP
CF_EPI19Discovery using RLP
CF_EPI26DDL syntax for E1.31/DMX access
CF_EPI29IPv4 address assignment
One or many components?
Number of client protocols to allocate space for
Number of client protocols to allocate space for.
Build DMP controller code only
Build DMP device code only
Build combined device and controller code
UUID conversion, handling and tracking
void readrxqueue()
Read the received wrapper queue (properly received wrappers only, there may be others awaiting sequencing) and dispatch to client protocol handlers.