From 453adecd04dea09f4ec1c3c26cb86c3593077085 Mon Sep 17 00:00:00 2001 From: cbdev Date: Thu, 1 Mar 2018 17:47:28 +0100 Subject: sACN documentation, Update OSC config syntax --- README.md | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- osc.c | 2 +- sacn.c | 11 ++++++++--- sacn.h | 1 + 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f323968..d986de6 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ fixture control. | Option | Example value | Default value | Description | |---------------|-----------------------|-----------------------|-----------------------| -| `bind` | `127.0.0.1 6454` | none | Binds a network address to listen for data. This option may be set multiple times, with each descriptor being assigned an index starting from 0 to be used with the `iface` instance configuration option | +| `bind` | `127.0.0.1 6454` | none | Binds a network address to listen for data. This option may be set multiple times, with each interface being assigned an index starting from 0 to be used with the `interface` instance configuration option. At least one interface is required for transmission. | | `net` | `0` | `0` | The default net to use | #### Instance configuration @@ -99,6 +99,66 @@ A normal channel that is part of a wide channel can not be mapped individually. Currently, no keep-alive frames are sent and the minimum inter-frame-time is disregarded. +### The `sacn` backend + +The sACN backend provides read-write access to the Multicast-UDP based streaming ACN protocol (ANSI E1.31-2016), +used for lighting fixture control. The backend sends universe discovery frames approximately every 10 seconds, +containing all write-enabled universes. + +#### Global configuration + +| Option | Example value | Default value | Description | +|---------------|-----------------------|-----------------------|-----------------------| +| `name` | `sACN source` | `MIDIMonster` | sACN source name | +| `cid` | `0xAA 0xBB 0xCC` ... | `MIDIMonster` | Source CID (16 bytes) | +| `bind` | `0.0.0.0 5568` | none | Binds a network address to listen for data. This option may be set multiple times, with each descriptor being assigned an index starting from 0 to be used with the `interface` instance configuration option. At least one descriptor is required for transmission. | + +#### Instance configuration + +| Option | Example value | Default value | Description | +|---------------|-----------------------|-----------------------|-----------------------| +| `universe` | `0` | none | Universe identifier | +| `interface` | `1` | `0` | The bound address to use for data input/output | +| `priority` | `100` | none | The data priority to transmit for this instance. Setting this option enables the instance for output and includes it in the universe discovery report. | +| `destination` | `10.2.2.2` | Universe multicast | Destination address for unicast output. If unset, the multicast destination for the specified universe is used. | +| `from` | `0xAA 0xBB` ... | none | 16-byte input source CID filter. Setting this option filters the input stream for this universe. | +| `unicast` | `1` | `0` | Prevent this instance from joining its universe multicast group | + +Note that instances accepting multicast input also process unicast frames directed at them, while +instances in `unicast` mode will not receive multicast frames. + +#### Channel specification + +A channel is specified by it's universe index. Channel indices start at 1 and end at 512. + +Example mapping: +``` +sacn1.231 < sacn2.123 +``` + +A 16-bit channel (spanning any two normal channels in the same universe) may be mapped with the syntax +``` +sacn.1+2 > sacn2.5+123 +``` + +A normal channel that is part of a wide channel can not be mapped individually. + +#### Known bugs / problems + +No keepalive frames are sent at this time. This will be implemented in the near future. + +The DMX start code of transmitted and received universes is fixed as `0`. + +The limit on packet transmission rate mandated by section 6.6.1 of the sACN specification is disregarded. + +Universe synchronization is currently not supported, though this feature may be implemented in the future. + +To use multicast input, all networking hardware in the path must support the IGMPv2 protocol. + +The Linux kernel limits the number of multicast groups an interface may join to 20. An instance configured +for input automatically joins the multicast group for its universe, unless configured in `unicast` mode. +This limit can be raised by changing the kernel option in `/proc/sys/net/ipv4/igmp_max_memberships`. + ### The `midi` backend The MIDI backend provides read-write access to the MIDI protocol via virtual ports. @@ -264,7 +324,7 @@ This backend does not take any global configuration. |---------------|-----------------------|-----------------------|-----------------------| | `root` | `/my/osc/path` | none | An OSC path prefix to be prepended to all channels | | `bind` | `:: 8000` | none | The host and port to listen on | -| `dest` | `10.11.12.13 8001` | none | Remote address to send OSC data to. Setting this enables the instance for output. The special value `learn` causes the MIDImonster to always reply to the address the last incoming packet came from. A different remote port for responses can be forced with the syntax `learn@` | +| `destination` | `10.11.12.13 8001` | none | Remote address to send OSC data to. Setting this enables the instance for output. The special value `learn` causes the MIDImonster to always reply to the address the last incoming packet came from. A different remote port for responses can be forced with the syntax `learn@` | Note that specifying an instance root speeds up matching, as packets not matching it are ignored early in processing. diff --git a/osc.c b/osc.c index 6bfd209..adc91f5 100644 --- a/osc.c +++ b/osc.c @@ -401,7 +401,7 @@ static int backend_configure_instance(instance* inst, char* option, char* value) } return 0; } - else if(!strcmp(option, "dest")){ + else if(!strcmp(option, "dest") || !strcmp(option, "destination")){ if(!strncmp(value, "learn", 5)){ data->learn = 1; diff --git a/sacn.c b/sacn.c index b807e2b..822f178 100644 --- a/sacn.c +++ b/sacn.c @@ -256,6 +256,9 @@ static int sacn_configure_instance(instance* inst, char* option, char* value){ fprintf(stderr, "Enabled source CID filter for instance %s\n", inst->name); return 0; } + else if(!strcmp(option, "unicast")){ + data->unicast_input = strtoul(value, NULL, 10); + } fprintf(stderr, "Unknown configuration option %s for sACN backend\n", option); return 1; @@ -630,9 +633,11 @@ static int sacn_start(){ } } - mcast_req.imr_multiaddr.s_addr = htobe32(((uint32_t) 0xefff0000) | ((uint32_t) data->uni)); - if(setsockopt(global_cfg.fd[data->fd_index].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast_req, sizeof(mcast_req))){ - fprintf(stderr, "Failed to join Multicast group for sACN universe %u on instance %s: %s\n", data->uni, inst[u]->name, strerror(errno)); + if(!data->unicast_input){ + mcast_req.imr_multiaddr.s_addr = htobe32(((uint32_t) 0xefff0000) | ((uint32_t) data->uni)); + if(setsockopt(global_cfg.fd[data->fd_index].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast_req, sizeof(mcast_req))){ + fprintf(stderr, "Failed to join Multicast group for sACN universe %u on instance %s: %s\n", data->uni, inst[u]->name, strerror(errno)); + } } if(data->xmit_prio){ diff --git a/sacn.h b/sacn.h index 7804eaf..74549ba 100644 --- a/sacn.h +++ b/sacn.h @@ -38,6 +38,7 @@ typedef struct /*_sacn_instance_model*/ { uint8_t xmit_prio; uint8_t cid_filter[16]; uint8_t filter_enabled; + uint8_t unicast_input; struct sockaddr_storage dest_addr; socklen_t dest_len; sacn_universe data; -- cgit v1.2.3