aboutsummaryrefslogtreecommitdiffhomepage
path: root/backends/rtpmidi.c
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2019-12-08 02:26:06 +0100
committercbdev <cb@cbcdn.com>2019-12-08 02:26:06 +0100
commit588f204eaa6c69a8f09a70d9188cefcb6c6075f6 (patch)
treed3b0c97e3387427c8adfe372c5d322b7327deede /backends/rtpmidi.c
parentf95dae04478b32fccaf7c6ebe1ecfd4e2fef1358 (diff)
downloadmidimonster-588f204eaa6c69a8f09a70d9188cefcb6c6075f6.tar.gz
midimonster-588f204eaa6c69a8f09a70d9188cefcb6c6075f6.tar.bz2
midimonster-588f204eaa6c69a8f09a70d9188cefcb6c6075f6.zip
Partly redesign rtpmidi backend
Diffstat (limited to 'backends/rtpmidi.c')
-rw-r--r--backends/rtpmidi.c166
1 files changed, 26 insertions, 140 deletions
diff --git a/backends/rtpmidi.c b/backends/rtpmidi.c
index 6a8032a..5387d86 100644
--- a/backends/rtpmidi.c
+++ b/backends/rtpmidi.c
@@ -11,36 +11,14 @@
#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;
+ uint8_t detect;
} cfg = {
.mdns_fd = -1,
.mdns_name = NULL,
- .nfds = 0,
- .fds = NULL
+ .detect = 0
};
int init(){
@@ -57,121 +35,17 @@ int init(){
};
if(mm_backend_register(rtpmidi)){
- fprintf(stderr, "Failed to register rtpMIDI backend\n");
- return 1;
- }
-
- return 0;
-}
-
-static int rtpmidi_listener(char* host, char* port){
- int fd = -1, status, yes = 1, flags;
- struct addrinfo hints = {
- .ai_family = AF_UNSPEC,
- .ai_socktype = SOCK_DGRAM,
- .ai_flags = AI_PASSIVE
- };
- struct addrinfo* info;
- struct addrinfo* addr_it;
-
- status = getaddrinfo(host, port, &hints, &info);
- if(status){
- fprintf(stderr, "Failed to get socket info for %s port %s: %s\n", host, port, gai_strerror(status));
- return -1;
- }
-
- for(addr_it = info; addr_it != NULL; addr_it = addr_it->ai_next){
- fd = socket(addr_it->ai_family, addr_it->ai_socktype, addr_it->ai_protocol);
- if(fd < 0){
- continue;
- }
-
- yes = 1;
- if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(yes)) < 0){
- fprintf(stderr, "Failed to set SO_REUSEADDR on socket\n");
- }
-
- yes = 1;
- if(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void*)&yes, sizeof(yes)) < 0){
- fprintf(stderr, "Failed to set SO_BROADCAST on socket\n");
- }
-
- yes = 0;
- if(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void*)&yes, sizeof(yes)) < 0){
- fprintf(stderr, "Failed to unset IP_MULTICAST_LOOP option: %s\n", strerror(errno));
- }
-
- status = bind(fd, addr_it->ai_addr, addr_it->ai_addrlen);
- if(status < 0){
- close(fd);
- continue;
- }
-
- break;
- }
-
- freeaddrinfo(info);
-
- if(!addr_it){
- fprintf(stderr, "Failed to create listening socket for %s port %s\n", host, port);
- return -1;
- }
-
- //set nonblocking
- flags = fcntl(fd, F_GETFL, 0);
- if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0){
- fprintf(stderr, "Failed to set rtpMIDI descriptor nonblocking\n");
- close(fd);
- return -1;
- }
- return 0;
-}
-
-static int rtpmidi_parse_addr(char* host, char* port, struct sockaddr_storage* addr, socklen_t* len){
- struct addrinfo* head;
- struct addrinfo hints = {
- .ai_family = AF_UNSPEC,
- .ai_socktype = SOCK_DGRAM
- };
-
- int error = getaddrinfo(host, port, &hints, &head);
- if(error || !head){
- fprintf(stderr, "Failed to parse address %s port %s: %s\n", host, port, gai_strerror(error));
- return 1;
- }
-
- memcpy(addr, head->ai_addr, head->ai_addrlen);
- *len = head->ai_addrlen;
-
- freeaddrinfo(head);
- return 0;
-}
-
-static int rtpmidi_separate_hostspec(char* in, char** host, char** port, char* default_port){
- size_t u;
-
- if(!in || !host || !port){
+ fprintf(stderr, "Failed to register rtpmidi backend\n");
return 1;
}
- for(u = 0; in[u] && !isspace(in[u]); u++){
- }
-
- //guess
- *host = in;
-
- if(in[u]){
- in[u] = 0;
- *port = in + u + 1;
- }
- else{
- //no port given
- *port = default_port;
- }
return 0;
}
static int rtpmidi_configure(char* option, char* value){
+ char* host = NULL, *port = NULL;
+ char next_port[10];
+
if(!strcmp(option, "mdns-name")){
if(cfg.mdns_name){
fprintf(stderr, "Duplicate mdns-name assignment\n");
@@ -191,17 +65,27 @@ static int rtpmidi_configure(char* option, char* value){
return 1;
}
+ if(mmbackend_parse_hostspec(value, &host, &port)){
+ fprintf(stderr, "Not a valid mDNS bind address: %s\n", value);
+ return 1;
+ }
- //TODO create mdns broadcast/responder socket
- }
- else if(!strcmp(option, "bind")){
- //TODO open listening data fd for raw rtpmidi instance
+ cfg.mdns_fd = mmbackend_socket(host, (port ? port : RTPMIDI_MDNS_PORT), SOCK_DGRAM, 1, 1);
+ if(cfg.mdns_fd < 0){
+ fprintf(stderr, "Failed to bind mDNS interface: %s\n", value);
+ return 1;
+ }
+ return 0;
}
- else if(!strcmp(option, "apple-bind")){
- //TODO open control and data fd for applemidi session/rtpmidi+apple-extensions instance
+ else if(!strcmp(option, "detect")){
+ cfg.detect = 0;
+ if(!strcmp(value, "on")){
+ cfg.detect = 1;
+ }
+ return 0;
}
- fprintf(stderr, "Unknown rtpMIDI backend option %s\n", option);
+ fprintf(stderr, "Unknown rtpmidi backend option %s\n", option);
return 1;
}
@@ -215,7 +99,7 @@ static instance* rtpmidi_instance(){
return NULL;
}
-static channel* rtpmidi_channel(instance* inst, char* spec){
+static channel* rtpmidi_channel(instance* inst, char* spec, uint8_t flags){
//TODO
return NULL;
}
@@ -242,6 +126,8 @@ static int rtpmidi_start(){
instance** inst = NULL;
rtpmidi_instance_data* data = NULL;
+ //TODO if mdns name defined and no socket, bind default values
+
//fetch all defined instances
if(mm_backend_instances(BACKEND_NAME, &n, &inst)){
fprintf(stderr, "Failed to fetch instance list\n");