From 588f204eaa6c69a8f09a70d9188cefcb6c6075f6 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sun, 8 Dec 2019 02:26:06 +0100 Subject: Partly redesign rtpmidi backend --- backends/rtpmidi.c | 166 +++++++++-------------------------------------------- 1 file changed, 26 insertions(+), 140 deletions(-) (limited to 'backends/rtpmidi.c') 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"); -- cgit v1.2.3