aboutsummaryrefslogtreecommitdiffhomepage
path: root/backends/sacn.c
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2019-12-12 20:29:03 +0100
committercbdev <cb@cbcdn.com>2019-12-12 20:29:03 +0100
commitbef4dd78ca2a610b4c669ea2c7a477283769997d (patch)
treec02ff860ea761a1f99692610197dd44d44156516 /backends/sacn.c
parent763f6d6a434b6e5a9d166cb538857d0cac5fa29e (diff)
downloadmidimonster-bef4dd78ca2a610b4c669ea2c7a477283769997d.tar.gz
midimonster-bef4dd78ca2a610b4c669ea2c7a477283769997d.tar.bz2
midimonster-bef4dd78ca2a610b4c669ea2c7a477283769997d.zip
Extend hostspec parsing and implement local mode for sACN (#39)
Diffstat (limited to 'backends/sacn.c')
-rw-r--r--backends/sacn.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/backends/sacn.c b/backends/sacn.c
index ef422e8..2a04245 100644
--- a/backends/sacn.c
+++ b/backends/sacn.c
@@ -17,6 +17,10 @@
#define MAX_FDS 4096
#define BACKEND_NAME "sacn"
+enum /*_sacn_fd_flags*/ {
+ mcast_loop = 1
+};
+
static struct /*_sacn_global_config*/ {
uint8_t source_name[64];
uint8_t cid[16];
@@ -58,8 +62,8 @@ MM_PLUGIN_API int init(){
return 0;
}
-static int sacn_listener(char* host, char* port, uint8_t fd_flags){
- int fd = -1;
+static int sacn_listener(char* host, char* port, uint8_t flags){
+ int fd = -1, yes = 1;
if(global_cfg.fds >= MAX_FDS){
fprintf(stderr, "sACN backend descriptor limit reached\n");
return -1;
@@ -80,10 +84,17 @@ static int sacn_listener(char* host, char* port, uint8_t fd_flags){
fprintf(stderr, "sACN backend interface %" PRIsize_t " bound to %s port %s\n", global_cfg.fds, host, port);
global_cfg.fd[global_cfg.fds].fd = fd;
- global_cfg.fd[global_cfg.fds].flags = fd_flags;
global_cfg.fd[global_cfg.fds].universes = 0;
global_cfg.fd[global_cfg.fds].universe = NULL;
global_cfg.fd[global_cfg.fds].last_frame = NULL;
+
+ if(flags & mcast_loop){
+ //set IP_MCAST_LOOP to allow local applications to receive output
+ if(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void*)&yes, sizeof(yes)) < 0){
+ fprintf(stderr, "Failed to disable IP_MULTICAST_LOOP on socket: %s\n", strerror(errno));
+ }
+ }
+
global_cfg.fds++;
return 0;
}
@@ -110,17 +121,22 @@ static int sacn_configure(char* option, char* value){
}
}
else if(!strcmp(option, "bind")){
- mmbackend_parse_hostspec(value, &host, &port);
+ mmbackend_parse_hostspec(value, &host, &port, &next);
if(!host){
fprintf(stderr, "No valid sACN bind address provided\n");
return 1;
}
+ if(next && !strncmp(next, "local", 5)){
+ flags = mcast_loop;
+ }
+
if(sacn_listener(host, port ? port : SACN_PORT, flags)){
fprintf(stderr, "Failed to bind sACN descriptor: %s\n", value);
return 1;
}
+
return 0;
}
@@ -151,7 +167,7 @@ static int sacn_configure_instance(instance* inst, char* option, char* value){
return 0;
}
else if(!strcmp(option, "destination")){
- mmbackend_parse_hostspec(value, &host, &port);
+ mmbackend_parse_hostspec(value, &host, &port, NULL);
if(!host){
fprintf(stderr, "No valid sACN destination for instance %s\n", inst->name);