aboutsummaryrefslogtreecommitdiffhomepage
path: root/backends
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2019-08-10 15:30:48 +0200
committercbdev <cb@cbcdn.com>2019-08-10 15:30:48 +0200
commitcf93d280af47aea1bf8bdafa30eabb2c2de005b8 (patch)
tree9e412411ee907b0ebfcd5ddfb77fa24281d2b7ea /backends
parent7c20eeea5b1ee8c3c93e29f92e907a14498f9b73 (diff)
downloadmidimonster-cf93d280af47aea1bf8bdafa30eabb2c2de005b8.tar.gz
midimonster-cf93d280af47aea1bf8bdafa30eabb2c2de005b8.tar.bz2
midimonster-cf93d280af47aea1bf8bdafa30eabb2c2de005b8.zip
Implement stream client connections in libmmbackend (Fixes #19)
Diffstat (limited to 'backends')
-rw-r--r--backends/artnet.c2
-rw-r--r--backends/libmmbackend.c62
-rw-r--r--backends/libmmbackend.h22
-rw-r--r--backends/lua.md2
-rw-r--r--backends/osc.c2
-rw-r--r--backends/sacn.c2
6 files changed, 67 insertions, 25 deletions
diff --git a/backends/artnet.c b/backends/artnet.c
index a6df4ab..7f3f08c 100644
--- a/backends/artnet.c
+++ b/backends/artnet.c
@@ -19,7 +19,7 @@ static int artnet_listener(char* host, char* port){
return -1;
}
- fd = mmbackend_socket(host, port, SOCK_DGRAM, 1);
+ fd = mmbackend_socket(host, port, SOCK_DGRAM, 1, 1);
if(fd < 0){
return -1;
}
diff --git a/backends/libmmbackend.c b/backends/libmmbackend.c
index b27ebc5..2fd3b8b 100644
--- a/backends/libmmbackend.c
+++ b/backends/libmmbackend.c
@@ -52,7 +52,7 @@ int mmbackend_parse_sockaddr(char* host, char* port, struct sockaddr_storage* ad
return 0;
}
-int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener){
+int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener, uint8_t mcast){
int fd = -1, status, yes = 1;
struct addrinfo hints = {
.ai_family = AF_UNSPEC,
@@ -80,20 +80,31 @@ int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener){
fprintf(stderr, "Failed to enable SO_REUSEADDR on socket\n");
}
- yes = 1;
- if(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void*)&yes, sizeof(yes)) < 0){
- fprintf(stderr, "Failed to enable SO_BROADCAST on socket\n");
- }
+ if(mcast){
+ yes = 1;
+ if(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void*)&yes, sizeof(yes)) < 0){
+ fprintf(stderr, "Failed to enable SO_BROADCAST on socket\n");
+ }
- yes = 0;
- 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));
+ yes = 0;
+ 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));
+ }
}
- status = bind(fd, addr_it->ai_addr, addr_it->ai_addrlen);
- if(status < 0){
- close(fd);
- continue;
+ if(listener){
+ status = bind(fd, addr_it->ai_addr, addr_it->ai_addrlen);
+ if(status < 0){
+ close(fd);
+ continue;
+ }
+ }
+ else{
+ status = connect(fd, addr_it->ai_addr, addr_it->ai_addrlen);
+ if(status < 0){
+ close(fd);
+ continue;
+ }
}
break;
@@ -107,11 +118,11 @@ int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener){
//set nonblocking
#ifdef _WIN32
- u_long mode = 1;
- if(ioctlsocket(fd, FIONBIO, &mode) != NO_ERROR){
- closesocket(fd);
- return 1;
- }
+ u_long mode = 1;
+ if(ioctlsocket(fd, FIONBIO, &mode) != NO_ERROR){
+ closesocket(fd);
+ return 1;
+ }
#else
int flags = fcntl(fd, F_GETFL, 0);
if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0){
@@ -123,3 +134,20 @@ int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener){
return fd;
}
+
+int mmbackend_send(int fd, uint8_t* data, size_t length){
+ ssize_t total = 0, sent;
+ while(total < length){
+ sent = send(fd, data + total, length - total, 0);
+ if(sent < 0){
+ fprintf(stderr, "Failed to send: %s\n", strerror(errno));
+ return 1;
+ }
+ total += sent;
+ }
+ return 0;
+}
+
+int mmbackend_send_str(int fd, char* data){
+ return mmbackend_send(fd, (uint8_t*) data, strlen(data));
+}
diff --git a/backends/libmmbackend.h b/backends/libmmbackend.h
index 77cad6a..31c4b96 100644
--- a/backends/libmmbackend.h
+++ b/backends/libmmbackend.h
@@ -16,7 +16,8 @@
#include <fcntl.h>
#include "../portability.h"
-/* Parse spec as host specification in the form
+/*
+ * Parse spec as host specification in the form
* host port
* into its constituent parts.
* Returns offsets into the original string and modifies it.
@@ -25,13 +26,26 @@
*/
void mmbackend_parse_hostspec(char* spec, char** host, char** port);
-/* Parse a given host / port combination into a sockaddr_storage
+/*
+ * Parse a given host / port combination into a sockaddr_storage
* suitable for usage with connect / sendto
* Returns 0 on success
*/
int mmbackend_parse_sockaddr(char* host, char* port, struct sockaddr_storage* addr, socklen_t* len);
-/* Create a socket of given type and mode for a bind / connect host.
+/*
+ * Create a socket of given type and mode for a bind / connect host.
* Returns -1 on failure, a valid file descriptor for the socket on success.
*/
-int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener);
+int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener, uint8_t mcast);
+
+/*
+ * Send arbitrary data over multiple writes if necessary
+ * Returns 1 on failure, 0 on success.
+ */
+int mmbackend_send(int fd, uint8_t* data, size_t length);
+
+/*
+ * Wraps mmbackend_send for cstrings
+ */
+int mmbackend_send_str(int fd, char* data);
diff --git a/backends/lua.md b/backends/lua.md
index 1c67477..6ad5c2a 100644
--- a/backends/lua.md
+++ b/backends/lua.md
@@ -37,7 +37,7 @@ Input values range between 0.0 and 1.0, output values are clamped to the same ra
#### Global configuration
-The backend does not take any global configuration.
+The `lua` backend does not take any global configuration.
#### Instance configuration
diff --git a/backends/osc.c b/backends/osc.c
index 03e431f..77bbde4 100644
--- a/backends/osc.c
+++ b/backends/osc.c
@@ -525,7 +525,7 @@ static int osc_configure_instance(instance* inst, char* option, char* value){
return 1;
}
- data->fd = mmbackend_socket(host, port, SOCK_DGRAM, 1);
+ data->fd = mmbackend_socket(host, port, SOCK_DGRAM, 1, 1);
if(data->fd < 0){
fprintf(stderr, "Failed to bind for instance %s\n", inst->name);
return 1;
diff --git a/backends/sacn.c b/backends/sacn.c
index 6f7d1a5..2f418e5 100644
--- a/backends/sacn.c
+++ b/backends/sacn.c
@@ -60,7 +60,7 @@ static int sacn_listener(char* host, char* port, uint8_t fd_flags){
return -1;
}
- fd = mmbackend_socket(host, port, SOCK_DGRAM, 1);
+ fd = mmbackend_socket(host, port, SOCK_DGRAM, 1, 1);
if(fd < 0){
return -1;
}