diff options
Diffstat (limited to 'backends')
| -rw-r--r-- | backends/artnet.c | 6 | ||||
| -rw-r--r-- | backends/libmmbackend.c | 15 | ||||
| -rw-r--r-- | backends/libmmbackend.h | 6 | ||||
| -rw-r--r-- | backends/maweb.c | 4 | ||||
| -rw-r--r-- | backends/osc.c | 6 | ||||
| -rw-r--r-- | backends/sacn.c | 26 | ||||
| -rw-r--r-- | backends/sacn.h | 1 | ||||
| -rw-r--r-- | backends/sacn.md | 6 | 
8 files changed, 52 insertions, 18 deletions
| diff --git a/backends/artnet.c b/backends/artnet.c index b181296..aa7c48e 100644 --- a/backends/artnet.c +++ b/backends/artnet.c @@ -68,14 +68,14 @@ MM_PLUGIN_API int init(){  }  static int artnet_configure(char* option, char* value){ -	char* host = NULL, *port = NULL; +	char* host = NULL, *port = NULL, *fd_opts = NULL;  	if(!strcmp(option, "net")){  		//configure default net  		default_net = strtoul(value, NULL, 0);  		return 0;  	}  	else if(!strcmp(option, "bind")){ -		mmbackend_parse_hostspec(value, &host, &port); +		mmbackend_parse_hostspec(value, &host, &port, &fd_opts);  		if(!host){  			fprintf(stderr, "Not valid ArtNet bind address given\n"); @@ -134,7 +134,7 @@ static int artnet_configure_instance(instance* inst, char* option, char* value){  		return 0;  	}  	else if(!strcmp(option, "dest") || !strcmp(option, "destination")){ -		mmbackend_parse_hostspec(value, &host, &port); +		mmbackend_parse_hostspec(value, &host, &port, NULL);  		if(!host){  			fprintf(stderr, "Not a valid ArtNet destination for instance %s\n", inst->name); diff --git a/backends/libmmbackend.c b/backends/libmmbackend.c index ccbeb52..7dbb4ae 100644 --- a/backends/libmmbackend.c +++ b/backends/libmmbackend.c @@ -1,6 +1,6 @@  #include "libmmbackend.h" -void mmbackend_parse_hostspec(char* spec, char** host, char** port){ +void mmbackend_parse_hostspec(char* spec, char** host, char** port, char** options){  	size_t u = 0;  	if(!spec || !host || !port){ @@ -29,6 +29,19 @@ void mmbackend_parse_hostspec(char* spec, char** host, char** port){  		spec[u] = 0;  		*port = spec + u + 1;  	} + +	if(options){ +		*options = NULL; +		if(*port){ +			//scan for space after port +			for(u = 0; (*port)[u] && !isspace((*port)[u]); u++){ +			} +			if(isspace((*port)[u])){ +				(*port)[u] = 0; +				*options = (*port) + u + 1; +			} +		} +	}  }  int mmbackend_parse_sockaddr(char* host, char* port, struct sockaddr_storage* addr, socklen_t* len){ diff --git a/backends/libmmbackend.h b/backends/libmmbackend.h index 5749119..76e588f 100644 --- a/backends/libmmbackend.h +++ b/backends/libmmbackend.h @@ -22,13 +22,15 @@  /*    * Parse spec as host specification in the form - *	host port + *	host port [options]   * into its constituent parts.   * Returns offsets into the original string and modifies it.   * Returns NULL in *port if none given.   * Returns NULL in both *port and *host if spec was an empty string. + * Returns a pointer after the port in *options if options is non-NULL + * and the port was not followed by \0   */ -void mmbackend_parse_hostspec(char* spec, char** host, char** port); +void mmbackend_parse_hostspec(char* spec, char** host, char** port, char** options);  /*    * Parse a given host / port combination into a sockaddr_storage diff --git a/backends/maweb.c b/backends/maweb.c index 4d41f0e..18d0351 100644 --- a/backends/maweb.c +++ b/backends/maweb.c @@ -145,10 +145,10 @@ static int maweb_configure(char* option, char* value){  static int maweb_configure_instance(instance* inst, char* option, char* value){  	maweb_instance_data* data = (maweb_instance_data*) inst->impl; -	char* host = NULL, *port = NULL; +	char* host = NULL, *port = NULL, *fd_opts = NULL;  	if(!strcmp(option, "host")){ -		mmbackend_parse_hostspec(value, &host, &port); +		mmbackend_parse_hostspec(value, &host, &port, &fd_opts);  		if(!host){  			fprintf(stderr, "Invalid host specified for maweb instance %s\n", inst->name);  			return 1; diff --git a/backends/osc.c b/backends/osc.c index 2c65ecb..15b5c24 100644 --- a/backends/osc.c +++ b/backends/osc.c @@ -496,7 +496,7 @@ static int osc_register_pattern(osc_instance_data* data, char* pattern_path, cha  static int osc_configure_instance(instance* inst, char* option, char* value){  	osc_instance_data* data = (osc_instance_data*) inst->impl; -	char* host = NULL, *port = NULL; +	char* host = NULL, *port = NULL, *fd_opts = NULL;  	if(!strcmp(option, "root")){  		if(osc_path_validate(value, 0)){ @@ -516,7 +516,7 @@ static int osc_configure_instance(instance* inst, char* option, char* value){  		return 0;  	}  	else if(!strcmp(option, "bind")){ -		mmbackend_parse_hostspec(value, &host, &port); +		mmbackend_parse_hostspec(value, &host, &port, &fd_opts);  		if(!host || !port){  			fprintf(stderr, "Invalid bind address for instance %s\n", inst->name);  			return 1; @@ -541,7 +541,7 @@ static int osc_configure_instance(instance* inst, char* option, char* value){  			return 0;  		} -		mmbackend_parse_hostspec(value, &host, &port); +		mmbackend_parse_hostspec(value, &host, &port, NULL);  		if(!host || !port){  			fprintf(stderr, "Invalid destination address for instance %s\n", inst->name);  			return 1; 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); diff --git a/backends/sacn.h b/backends/sacn.h index 726fa68..c8d11e9 100644 --- a/backends/sacn.h +++ b/backends/sacn.h @@ -56,7 +56,6 @@ typedef union /*_sacn_instance_id*/ {  typedef struct /*_sacn_socket*/ {  	int fd; -	uint8_t flags;  	size_t universes;  	uint16_t* universe;  	uint64_t* last_frame; diff --git a/backends/sacn.md b/backends/sacn.md index 434beeb..46f1197 100644 --- a/backends/sacn.md +++ b/backends/sacn.md @@ -10,7 +10,11 @@ containing all write-enabled universes.  |---------------|-----------------------|-----------------------|-----------------------|  | `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. | +| `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 operation. | + +The `bind` configuration value can be extended by the keyword `local` to allow software on the +local host to process the sACN output frames from the MIDIMonster (e.g. `bind = 0.0.0.0 5568 local`). +This has the side effect of generating mirroring the output of instances on this descriptors to their input.  #### Instance configuration | 
