shithub: orca

Download patch

ref: e093799b0775385ed16a59e99af3b338d7336478
parent: df81654324b585f0a0f4167ac2f9dae2106cdc46
author: cancel <cancel@cancel.fm>
date: Sun Dec 9 17:09:03 EST 2018

Change to use IPv6 compatible addressing

--- a/osc_out.c
+++ b/osc_out.c
@@ -1,27 +1,37 @@
 #include "osc_out.h"
 
-//#include <sys/socket.h>
-#include <arpa/inet.h>
 #include <errno.h>
+#include <netdb.h>
 #include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
 
 struct Oosc_dev {
   int fd;
-  struct sockaddr_in addr;
+  struct addrinfo* addr;
 };
 
 Oosc_udp_create_error oosc_dev_create_udp(Oosc_dev** out_ptr,
-                                          char const* dest_addr, U16 port) {
-  int udpfd = socket(AF_INET, SOCK_DGRAM, 0);
+                                          char const* dest_addr,
+                                          char const* dest_port) {
+  struct addrinfo hints;
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = AF_UNSPEC;
+  hints.ai_socktype = SOCK_DGRAM;
+  hints.ai_protocol = 0;
+  hints.ai_flags = AI_ADDRCONFIG;
+  struct addrinfo* addr = NULL;
+  int err = getaddrinfo(dest_addr, dest_port, &hints, &addr);
+  if (err != 0) {
+    fprintf(stderr, "Failed to get address info, error: %d\n", errno);
+    return Oosc_udp_create_error_getaddrinfo_failed;
+  }
+  int udpfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
   if (udpfd < 0) {
     fprintf(stderr, "Failed to open UDP socket, error number: %d\n", errno);
+    freeaddrinfo(addr);
     return Oosc_udp_create_error_couldnt_open_socket;
   }
-  struct sockaddr_in addr;
-  memset(&addr, 0, sizeof(addr));
-  addr.sin_family = AF_INET;
-  addr.sin_addr.s_addr = inet_addr(dest_addr);
-  addr.sin_port = htons((U16)port);
   Oosc_dev* dev = malloc(sizeof(Oosc_dev));
   dev->fd = udpfd;
   dev->addr = addr;
@@ -31,12 +41,13 @@
 
 void oosc_dev_destroy(Oosc_dev* dev) {
   close(dev->fd);
+  freeaddrinfo(dev->addr);
   free(dev);
 }
 
 void oosc_send_datagram(Oosc_dev* dev, char const* data, Usz size) {
-  ssize_t res = sendto(dev->fd, data, size, 0, (struct sockaddr*)&dev->addr,
-                       sizeof(dev->addr));
+  ssize_t res =
+      sendto(dev->fd, data, size, 0, dev->addr->ai_addr, dev->addr->ai_addrlen);
   if (res < 0) {
     fprintf(stderr, "UDP message send failed\n");
     exit(1);
--- a/osc_out.h
+++ b/osc_out.h
@@ -4,11 +4,13 @@
 
 typedef enum {
   Oosc_udp_create_error_ok = 0,
-  Oosc_udp_create_error_couldnt_open_socket = 1,
+  Oosc_udp_create_error_getaddrinfo_failed = 1,
+  Oosc_udp_create_error_couldnt_open_socket = 2,
 } Oosc_udp_create_error;
 
-Oosc_udp_create_error oosc_dev_create_udp(Oosc_dev** out_dev_ptr,
-                                          char const* dest_addr, U16 port);
+Oosc_udp_create_error oosc_dev_create_udp(Oosc_dev** out_ptr,
+                                          char const* dest_addr,
+                                          char const* dest_port);
 void oosc_dev_destroy(Oosc_dev* dev);
 // raw UDP datagram
 void oosc_send_datagram(Oosc_dev* dev, char const* data, Usz size);
@@ -32,10 +34,11 @@
 void susnote_list_add_notes(Susnote_list* sl, Susnote const* restrict notes,
                             Usz count, Usz* restrict start_removed,
                             Usz* restrict end_removed);
-void susnote_list_advance_time(Susnote_list* sl, double delta_time,
-                               Usz* restrict start_removed,
-                               Usz* restrict end_removed,
-                               // 1.0 if no notes remain or none shorter than 1.0
-                               double* soonest_deadline);
-// 1.0 if no notes remain or none shorter than 1.0
+void susnote_list_advance_time(
+    Susnote_list* sl, double delta_time, Usz* restrict start_removed,
+    Usz* restrict end_removed,
+    // 1.0 if no notes remain or none are shorter than 1.0
+    double* soonest_deadline);
+
+// Returns 1.0 if no notes remain or none are shorter than 1.0
 double susnote_list_soonest_deadline(Susnote_list const* sl);
--- a/tui_main.c
+++ b/tui_main.c
@@ -24,19 +24,19 @@
       "                       Default: 2\n"
       "    -h or --help       Print this message and exit.\n"
       "\n"
-      "OSC options:\n"
-      "    --osc-server <address>\n"
-      "        IP address to send OSC messages to.\n"
-      "        Default: 127.0.0.1\n"
+      "OSC/MIDI options:\n"
+      "    --osc-server <hotname>\n"
+      "        Hostname or IP address to send OSC messages to.\n"
+      "        Default: localhost\n"
       "\n"
-      "    --osc-port <number>\n"
-      "        UDP Port to send OSC messages to.\n"
+      "    --osc-port <number or service name>\n"
+      "        UDP port (or service name) to send OSC messages to.\n"
       "        Default: none\n"
       "\n"
       "    --osc-midi-bidule <path>\n"
-      "        Set MIDI to send to via OSC formatted for Plogue Bidule.\n"
+      "        Set MIDI to be sent via OSC formatted for Plogue Bidule.\n"
       "        The path argument is the path of the Plogue OSC MIDI device.\n"
-      "        Example: /OSC_MIDI_0\n"
+      "        Example: /OSC_MIDI_0/MIDI\n"
       );
   // clang-format on
 }
@@ -566,13 +566,14 @@
   return a->is_draw_dirty || a->needs_remarking;
 }
 
-bool app_set_osc_udp(App_state* a, char const* dest_addr, U16 port) {
+bool app_set_osc_udp(App_state* a, char const* dest_addr,
+                     char const* dest_port) {
   if (a->oosc_dev) {
     oosc_dev_destroy(a->oosc_dev);
     a->oosc_dev = NULL;
   }
   Oosc_udp_create_error err =
-      oosc_dev_create_udp(&a->oosc_dev, dest_addr, port);
+      oosc_dev_create_udp(&a->oosc_dev, dest_addr, dest_port);
   if (err) {
     return false;
   }
@@ -976,8 +977,8 @@
       {NULL, 0, NULL, 0}};
   char* input_file = NULL;
   int margin_thickness = 2;
-  U16 osc_port = 0;
-  char const* osc_ip_send_addr = "127.0.0.1";
+  char const* osc_ip_send_addr = NULL;
+  char const* osc_port = NULL;
   Midi_mode midi_mode;
   midi_mode_init(&midi_mode);
   for (;;) {
@@ -1002,15 +1003,7 @@
       osc_ip_send_addr = optarg;
     } break;
     case Argopt_osc_port: {
-      int osc_port0 = atoi(optarg);
-      if (osc_port0 <= 0) {
-        fprintf(stderr, "OSC port must be greater than 0.\n");
-        return 1;
-      } else if (osc_port0 > UINT16_MAX) {
-        fprintf(stderr, "OSC port must be <= %d\n", (int)UINT16_MAX);
-        return 1;
-      }
-      osc_port = (U16)osc_port0;
+      osc_port = optarg;
     } break;
     case Argopt_osc_midi_bidule: {
       midi_mode_set_osc_bidule(&midi_mode, optarg);
@@ -1037,9 +1030,18 @@
   App_state app_state;
   app_init(&app_state);
 
-  if (osc_port != 0) {
+  if (osc_ip_send_addr != NULL && osc_port == NULL) {
+    fprintf(stderr,
+            "An OSC server address was specified, but no OSC port was "
+            "specified.\n"
+            "OSC output is not possible without specifying an OSC port.\n");
+    app_deinit(&app_state);
+    exit(1);
+  }
+  if (osc_port != NULL) {
     if (!app_set_osc_udp(&app_state, osc_ip_send_addr, osc_port)) {
-      fprintf(stderr, "Failed to open OSC UDP port %d\n", (int)osc_port);
+      fprintf(stderr, "Failed to set up OSC networking\n");
+      app_deinit(&app_state);
       exit(1);
     }
   }