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.
|Introduction||There are many compile time options for building Acacian.|
|Main Options||All options are documented below.|
|Operating system (and stack)||Currently only linux is supported but we define some configuration options to bracket OS dependent code.|
|Network and Transport Features||IP version (or other transport)|
|Data Marshalling and Unmarshalling|
|UUID tracking||ACN 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_MAPGEN||Enable static map generation extensions|
|EPIs||Conformance 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.
All options are documented below. However, to get started, the most significant options you should look at are:
|CF_VERSION||An integer which represents the ACN revision to be compiled.|
|20060000||the original ANSI ESTA E1.17-2006 version|
|20100000||the revised version ANSI ESTA E1.17-2010|
As of April 2012 only 20100000 is supported
EPIs which were not included in the original ACN suite have their own standardization process and may need their own version numbers as necessary.
Currently only linux is supported but we define some configuration options to bracket OS dependent code.
|CF_OS_LINUX||Operating 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_xxx||Only needed where stack is not defined by the OS default.|
IP version (or other transport)
|CF_NET_IPV4||IP version 4|
|CF_NET_IPV6||IP 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_IPADS||Maximum 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_ANY||Delegate 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_TTL||IP 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_GROUPS||Joining 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_ADDRESS||Recover 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.
These are currently compile-time options so logging cannot be changed in running code.
|CF_ACNLOG||determine how messages are logged.|
|CF_LOGLEVEL||determine what level of messages are logged.|
Options for CF_ACNLOG are
|ACNLOG_OFF||All logging is compiled out|
|ACNLOG_SYSLOG||Log using POSIX Syslog|
|ACNLOG_STDOUT||Log to standard output (default)|
|ACNLOG_STDERR||Log 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_OFF||don’t log (the default)|
|LOG_ON||log to the default facility (same as LOG_USER)|
Or if using syslog you may select a specific facility e.g. LOG_LOCAL0
#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_LOGFUNCS||Log 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_RLP||Log the root layer|
|LOG_NETX||Log network interface|
|LOG_DDL||Log DDL parsing|
|LOG_MISC||Log various utilities|
|LOG_EVLOOP||Log the event/timer loop|
|LOG_APP||Available for your application|
|LOG_SESS||Special setting for SDT sessions command|
Separate macros allow logging to be set for different modiles
|CF_MARSHAL_INLINE||Use 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.
|CF_MULTI_COMPONENT||One 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_SIZE||Length (in bytes) assigned for FCTN|
|ACN_UACN_SIZE||Length (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.
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_RADIX||Use radix tree (patricia tree) to store UUIDs|
|CF_UUIDS_HASH||Use 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_HASHBITS||Hash size for remote component table|
|CF_Lcomp_HASHBITS||Hash size for local component table|
|CF_DDL_HASHBITS||Hash 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.
|CF_EVLOOP||Use 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_ms||Use simple millisecond integers for times|
|CF_TIME_POSIX_timeval||Use POSIX timeval struictures for timing|
|CF_TIME_POSIX_timespec||Use timespec struictures for timing|
Millisecond counters are adequate (just) for SDT specifications.
|CF_RLP||enable the ACN root layer|
Root layer is needed for UDP but may not be needed for other transports.
|CF_RLP_MAX_CLIENT_PROTOCOLS||Number 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_CLIENTPROTO||Client protocol ID for single protocol implementations. ignored if CF_RLP_MAX_CLIENT_PROTOCOLS is greater than one.|
e.g. For SDT only support
#define CF_RLP_MAX_CLIENT_PROTOCOLS 1 #define CF_RLP_CLIENTPROTO SDT_PROTOCOL_ID
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_PACK||Optimize PDU packing in RLP (at the cost of speed)|
|CF_SDT||enable the SDT layer|
|CF_SDT_MAX_CLIENT_PROTOCOLS||Number 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_CLIENTPROTO||Client protocol for single protocol implementations|
e.g. for DMP only
#define CF_SDT_MAX_CLIENT_PROTOCOLS 1 #define CF_SDT_CLIENTPROTO DMP_PROTOCOL_ID
|CF_SDTRX_AUTOCALL||When 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_ASSOC||The 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_DMP||enable the DMP layer|
Device or Controller?
|CF_DMPCOMP__D||Build DMP device code only|
|CF_DMPCOMP_C_||Build DMP controller code only|
|CF_DMPCOMP_CD||Build 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_SUBSCRIPTIONS||Number of property subscriptions to accept|
|CF_DMPAD_MAXBYTES||Maximum 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_SEARCH||Use 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_INDEX||Store 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_NONE||eliminate all address checking code in the DMP layer and simply passes up all addresses unchecked to the application.|
|CF_DMPMAP_NAME||For 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 protocols||DMP may operate over multiple transport protocols. e.g. SDT and TCP CF_DMP_MULTITRANSPORT|
|CF_DMPON_SDT||Include SDT transport support|
|CF_DMPON_TCP||Include TCP transport support|
|CF_DMP_RMAXCXNS||Number of connections to/from the same remote component. These take space in the component structure for each remote.|
|CF_DDL||Enable 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_DMP||Compile DDL for DMP access|
|CF_DDLACCESS_EPI26||Compile 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_BEHAVIORS||Parse and apply DDL behaviors|
|CF_DDL_IMMEDIATEPROPS||Parse and record values for immediate properties.|
|CF_DDL_MAXNEST||Maximum XML nesting level within a single DDL module.|
|CF_DDL_MAXTEXT||Size allocated for parsing text nodes.|
|CF_E131||Enable E1.31 code|
|CF_E131_RX||Generate receive code|
|CF_E131_TX||generate transmit code|
We have separate configures for transmit and receive as they are frequently different components and do not share much code.
|E131MEM_MAXUNIVS||Maximum number of universes to track|
|CF_E131_ZSTART_ONLY||Drop ASC packets on read and automatically add a zero start on write|
|CF_E131_IGNORE_PREVIEW||Drop 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_EPI10||Multicast address allocation|
|CF_EPI12||Requirements on Homogeneous Ethernet Networks|
|CF_EPI13||IPv4 Addresses. Superseded by EPI29|
|CF_EPI15||Multicast allocation infrastructure|
|CF_EPI17||Root layer protocol for UDP|
|CF_EPI18||Requirements for SDT on UDP|
|CF_EPI19||Discovery using RLP|
|CF_EPI26||DDL syntax for E1.31/DMX access|
|CF_EPI29||IPv4 address assignment|
Read the received wrapper queue (properly received wrappers only, there may be others awaiting sequencing) and dispatch to client protocol handlers.