diff options
| author | cbdev <cb@cbcdn.com> | 2018-03-25 23:17:15 +0200 | 
|---|---|---|
| committer | cbdev <cb@cbcdn.com> | 2018-03-25 23:17:15 +0200 | 
| commit | cf889dd8bd983182534457b6778892ef0634e592 (patch) | |
| tree | c48ae905f6f825b8935b8e64326ff5e772132726 /backends | |
| parent | 52cb34c88129145597984913b86321a940fc520a (diff) | |
| download | midimonster-cf889dd8bd983182534457b6778892ef0634e592.tar.gz midimonster-cf889dd8bd983182534457b6778892ef0634e592.tar.bz2 midimonster-cf889dd8bd983182534457b6778892ef0634e592.zip | |
Rough rtpmidi backend skeleton
Diffstat (limited to 'backends')
| -rw-r--r-- | backends/Makefile | 2 | ||||
| -rw-r--r-- | backends/rtpmidi.c | 130 | ||||
| -rw-r--r-- | backends/rtpmidi.h | 94 | 
3 files changed, 225 insertions, 1 deletions
| diff --git a/backends/Makefile b/backends/Makefile index 446ad70..771e97e 100644 --- a/backends/Makefile +++ b/backends/Makefile @@ -1,6 +1,6 @@  .PHONY: all clean  LINUX_BACKENDS = midi.so evdev.so -BACKENDS = artnet.so osc.so loopback.so sacn.so +BACKENDS = artnet.so osc.so loopback.so sacn.so rtpmidi.so  SYSTEM := $(shell uname -s) diff --git a/backends/rtpmidi.c b/backends/rtpmidi.c new file mode 100644 index 0000000..f77f93b --- /dev/null +++ b/backends/rtpmidi.c @@ -0,0 +1,130 @@ +#include <string.h> +#include <unistd.h> + +#include "rtpmidi.h" + +#define BACKEND_NAME "rtpmidi" + +/** rtpMIDI backend w/ AppleMIDI support + * + * Global configuration + * 	bind = 0.0.0.0 + * 	apple-bind = 0.0.0.1 + * 	mdns-bind = 0.0.0.0 + * 	mdns-name = mdns-name + *  + * Instance configuration + * 	interface = 0 + * 	(opt) ssrc = X + * + * 	apple-session = session-name + * 	apple-invite = invite-peer + * 	apple-allow = * + * or + * 	connect =  + * 	reply-any = 1 + */ + +static struct /*_rtpmidi_global*/ { +	int mdns_fd; +	char* mdns_name; +	size_t nfds; +	rtpmidi_fd* fds; +} cfg = { +	.mdns_fd = -1, +	.mdns_name = NULL, +	.nfds = 0, +	.fds = NULL +}; + +int init(){ +	backend rtpmidi = { +		.name = BACKEND_NAME, +		.conf = rtpmidi_configure, +		.create = rtpmidi_instance, +		.conf_instance = rtpmidi_configure_instance, +		.channel = rtpmidi_channel, +		.handle = rtpmidi_set, +		.process = rtpmidi_handle, +		.start = rtpmidi_start, +		.shutdown = rtpmidi_shutdown +	}; + +	if(mm_backend_register(rtpmidi)){ +		fprintf(stderr, "Failed to register rtpMIDI backend\n"); +		return 1; +	} + +	return 0; +} + +static int rtpmidi_configure(char* option, char* value){ +	if(!strcmp(option, "mdns-name")){ +		if(cfg.mdns_name){ +			free(cfg.mdns_name); +		} + +		cfg.mdns_name = strdup(value); +		if(!cfg.mdns_name){ +			fprintf(stderr, "Failed to allocate memory\n"); +			return 1; +		} +		//TODO this should create the mdns broadcaster and responder socket +		return 0; +	} +	else if(!strcmp(option, "bind")){ +		//TODO open listening control and data fds +	} + +	fprintf(stderr, "Unknown rtpMIDI backend option %s\n", option); +	return 1; +} + +static int rtpmidi_configure_instance(instance* inst, char* option, char* value){ +	//TODO +	return 1; +} + +static instance* rtpmidi_instance(){ +	//TODO +	return NULL; +} + +static channel* rtpmidi_channel(instance* inst, char* spec){ +	//TODO +	return NULL; +} + +static int rtpmidi_set(instance* inst, size_t num, channel** c, channel_value* v){ +	//TODO +	return 1; +} + +static int rtpmidi_handle(size_t num, managed_fd* fds){ +	//TODO +	return 1; +} + +static int rtpmidi_start(){ +	//TODO +	return 1; +} + +static int rtpmidi_shutdown(){ +	size_t u; + +	free(cfg.mdns_name); +	if(cfg.mdns_fd >= 0){ +		close(cfg.mdns_fd); +	} + +	for(u = 0; u < cfg.nfds; u++){ +		if(cfg.fds[u].data >= 0){ +			close(cfg.fds[u].data); +		} +		if(cfg.fds[u].control >= 0){ +			close(cfg.fds[u].control); +		} +	} +	return 0; +} diff --git a/backends/rtpmidi.h b/backends/rtpmidi.h new file mode 100644 index 0000000..f14357f --- /dev/null +++ b/backends/rtpmidi.h @@ -0,0 +1,94 @@ +#include <sys/socket.h> +#include "midimonster.h" + +int init(); +static int rtpmidi_configure(char* option, char* value); +static int rtpmidi_configure_instance(instance* instance, char* option, char* value); +static instance* rtpmidi_instance(); +static channel* rtpmidi_channel(instance* instance, char* spec); +static int rtpmidi_set(instance* inst, size_t num, channel** c, channel_value* v); +static int rtpmidi_handle(size_t num, managed_fd* fds); +static int rtpmidi_start(); +static int rtpmidi_shutdown(); + +#define RTPMIDI_DEFAULT_PORTBASE "9001" +#define RTPMIDI_RECV_BUF 4096 + +#define RTPMIDI_COMMAND_LEN +#define RTPMIDI_COMMAND_DATA_OFFSET +#define RTPMIDI_HAS_JOURNAL +#define RTPMIDI_IS_PHANTOM + +typedef enum /*_rtpmidi_peer_mode*/ { +	peer_learned, +	peer_invited, +	peer_invited_by, +	peer_sync, +	peer_connect +} rtpmidi_peer_mode; + +typedef struct /*_rtpmidi_peer*/ { +	rtpmidi_peer_mode mode; +	struct sockaddr_storage dest; +	socklen_t dest_len; +	uint32_t ssrc; +} rtpmidi_peer; + +typedef struct /*_rtpmidi_fd*/ { +	int data; +	int control; +} rtpmidi_fd; + +typedef struct /*_rtmidi_instance_data*/ { +	size_t fd_index; +	size_t npeers; +	rtpmidi_peer* peers; +	uint32_t ssrc; + +	//apple-midi config +	char* session_name; +	char* invite_peers; +	char* invite_accept; + +	//generic mode config +	uint8_t learn_peers; +} rtpmidi_instance_data; + +#pragma pack(push, 1) +typedef struct /*_apple_session_command*/ { +	uint16_t res1; +	uint8_t command[2]; +	uint32_t version; +	uint32_t token; +	uint32_t ssrc; +	//char* name +} apple_command; + +typedef struct /*_apple_session_sync*/ { +	uint16_t res1; +	uint8_t command[2]; +	uint32_t ssrc; +	uint8_t count; +	uint8_t res2[3]; +	uint64_t timestamp[3]; +} apple_sync; + +typedef struct /*_apple_session_feedback*/ { +	uint16_t res1; +	uint8_t command[2]; +	uint32_t ssrc; +	uint32_t sequence; +} apple_feedback; + +typedef struct /*_rtp_midi_header*/ { +	uint16_t vpxccmpt; //this is really just an amalgamated constant value +	uint16_t sequence; +	uint32_t timestamp; +	uint32_t ssrc; +} rtpmidi_header; + +typedef struct /*_rtp_midi_command*/ { +	uint8_t flags; +	uint8_t additional_length; +} rtpmidi_command; +#pragma pack(pop) | 
