]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Begin to get SPS to give a unique shm interface name to nqptp. Also clang format
authorMike Brady <4265913+mikebrady@users.noreply.github.com>
Mon, 27 Dec 2021 12:19:01 +0000 (12:19 +0000)
committerMike Brady <4265913+mikebrady@users.noreply.github.com>
Mon, 27 Dec 2021 12:19:01 +0000 (12:19 +0000)
common.h
mqtt.c
nqptp-shm-structures.h
player.c
ptp-utilities.c
rtp.c
rtsp.c
shairport.c

index f4139e56d0e6877b261af47e8c581aa6c36fd593..904b9279ced00576a7231ad0116f25ac12d653c7 100644 (file)
--- a/common.h
+++ b/common.h
@@ -152,7 +152,7 @@ typedef struct {
   int mqtt_publish_cover;
   int mqtt_enable_remote;
 #endif
-  uint8_t hw_addr[8];    // only needs 6 but 8 is handy when converting this to a number
+  uint8_t hw_addr[8]; // only needs 6 but 8 is handy when converting this to a number
   int port;
   int udp_port_base;
   int udp_port_range;
@@ -302,6 +302,7 @@ typedef struct {
   char *airplay_device_id; // for the Bonjour advertisement and the GETINFO PList
   char *airplay_pin;       // non-NULL, 4 char PIN, if required for pairing
   char *airplay_pi;        // UUID in the Bonjour advertisement and the GETINFO Plist
+  char *nqptp_shared_memory_interface_name; // client name for nqptp service
 #endif
 } shairport_cfg;
 
diff --git a/mqtt.c b/mqtt.c
index 912d618c67311697b6398be8a23ba13bcfec072e..462ebd2ab6f9bd4d3bcb7eab0e4f514c566e3c77 100644 (file)
--- a/mqtt.c
+++ b/mqtt.c
@@ -199,7 +199,6 @@ void mqtt_process_metadata(uint32_t type, uint32_t code, char *data, uint32_t le
       case 'svip':
         mqtt_publish("server_ip", data, length);
         break;
-
       }
     }
   }
index f4db8c6e291d95aeeaa83fe0e4a469c79a07f658..8283777820e59631bf25bb56fbc87bc7f4820b1f 100644 (file)
 #ifndef NQPTP_SHM_STRUCTURES_H
 #define NQPTP_SHM_STRUCTURES_H
 
-#define STORAGE_ID "/nqptp"
-#define MAX_CLOCKS 32
-#define NQPTP_SHM_STRUCTURES_VERSION 6
+#define NQPTP_SHM_STRUCTURES_VERSION 7
 #define NQPTP_CONTROL_PORT 9000
 
-// the control port will accept a UDP packet with the first letter being:
-// "T", followed by a space and then a space-delimited
-// list of ip numbers, either IPv4 or IPv6
+// The control port will accept a UDP packet with the first letter being:
+// "T", followed by the name of the shared memory interface, followed by
+// a space and then a space-delimited list of ip numbers, either IPv4 or IPv6
 // the whole not to exceed 4096 characters in total
 // The IPs will become the new list of timing peers, replacing any previous
 
@@ -37,7 +35,6 @@
 struct shm_structure {
   pthread_mutex_t shm_mutex;            // for safely accessing the structure
   uint16_t version;                     // check this is equal to NQPTP_SHM_STRUCTURES_VERSION
-  uint32_t flags;                       // unused
   uint64_t master_clock_id;             // the current master clock
   char master_clock_ip[64];             // where it's coming from
   uint64_t local_time;                  // the time when the offset was calculated
index db7ec1696d186691d484d924f9e9acdc4bc0c317..27b8e69289c5f24d58645a8f01854e91837506f3 100644 (file)
--- a/player.c
+++ b/player.c
@@ -1064,21 +1064,23 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
               int64_t lt = conn->first_packet_time_to_play - local_time_now;
 
               if (lt < 130000000) {
-                debug(1, "Connection %d: Short lead time for first frame %" PRId64 ": %f seconds. Flushing 0.5 seconds",
-                    conn->connection_number, conn->first_packet_timestamp, lt * 0.000000001);
+                debug(1,
+                      "Connection %d: Short lead time for first frame %" PRId64
+                      ": %f seconds. Flushing 0.5 seconds",
+                      conn->connection_number, conn->first_packet_timestamp, lt * 0.000000001);
                 do_flush(conn->first_packet_timestamp + 5 * 4410, conn);
               } else {
                 debug(2, "Connection %d: Lead time for first frame %" PRId64 ": %f seconds.",
-                    conn->connection_number, conn->first_packet_timestamp, lt * 0.000000001);
+                      conn->connection_number, conn->first_packet_timestamp, lt * 0.000000001);
               }
-/*
-              int64_t lateness = local_time_now - conn->first_packet_time_to_play;
-              if (lateness > 0) {
-                debug(1, "First packet is %" PRId64 " nanoseconds late! Flushing 0.5 seconds",
-                      lateness);
+              /*
+                            int64_t lateness = local_time_now - conn->first_packet_time_to_play;
+                            if (lateness > 0) {
+                              debug(1, "First packet is %" PRId64 " nanoseconds late! Flushing 0.5
+                 seconds", lateness);
 
-              }
-*/
+                            }
+              */
             }
 
             if (conn->first_packet_time_to_play != 0) {
index fa1c64071c5c732b8f873d42591b876f08f7addc..78a43ed4cf9bf42eb65c2c7e3a0e47be4a15df0b 100644 (file)
@@ -30,6 +30,7 @@
 #include <fcntl.h>
 #include <pthread.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/mman.h>
 #ifdef COMPILE_FOR_FREEBSD
@@ -148,27 +149,41 @@ int ptp_shm_interface_close() {
 }
 
 void ptp_send_control_message_string(const char *msg) {
-  debug(2, "Send control message to NQPTP: \"%s\"", msg);
-  int s;
-  unsigned short port = htons(NQPTP_CONTROL_PORT);
-  struct sockaddr_in server;
+  size_t full_message_size =
+      strlen(config.nqptp_shared_memory_interface_name) + strlen(" ") + strlen(msg) + 1;
+  char *full_message = malloc(full_message_size);
+  if (full_message != NULL) {
+    *full_message = '\0';
+    snprintf(full_message, full_message_size, "%s %s", config.nqptp_shared_memory_interface_name,
+             msg);
+    debug(1, "Send control message to NQPTP: \"%s\"", full_message);
+    int s;
+    unsigned short port = htons(NQPTP_CONTROL_PORT);
+    struct sockaddr_in server;
 
-  /* Create a datagram socket in the internet domain and use the
-   * default protocol (UDP).
-   */
-  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-    die("Can't open a socket to NQPTP");
-  }
+    /* Create a datagram socket in the internet domain and use the
+     * default protocol (UDP).
+     */
+    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+      die("Can't open a socket to NQPTP");
+    }
 
-  /* Set up the server name */
-  server.sin_family = AF_INET; /* Internet Domain    */
-  server.sin_port = port;      /* Server Port        */
-  server.sin_addr.s_addr = 0;  /* Server's Address   */
+    /* Set up the server name */
+    server.sin_family = AF_INET; /* Internet Domain    */
+    server.sin_port = port;      /* Server Port        */
+    server.sin_addr.s_addr = 0;  /* Server's Address   */
 
-  /* Send the message in buf to the server */
-  if (sendto(s, msg, (strlen(msg) + 1), 0, (struct sockaddr *)&server, sizeof(server)) < 0) {
-    die("error sending timing_peer_list to NQPTP");
+    /* Send the message in buf to the server */
+    if (sendto(s, full_message, full_message_size, 0, (struct sockaddr *)&server, sizeof(server)) <
+        0) {
+      die("error sending timing_peer_list to NQPTP");
+    }
+    /* Deallocate the socket */
+    close(s);
+
+    /* deallocate the message string */
+    free(full_message);
+  } else {
+    debug(1, "Couldn't allocate memory to prepare a qualified ptp control message string.");
   }
-  /* Deallocate the socket */
-  close(s);
 }
diff --git a/rtp.c b/rtp.c
index 348ac869761442724e443f520a0b89c5edf0e912..cf53c545ed08ca570942290c4342987c1c2e3768 100644 (file)
--- a/rtp.c
+++ b/rtp.c
@@ -290,8 +290,8 @@ void *rtp_control_receiver(void *arg) {
                                                                 obfp += 2;
                                                               };
                                                               *obfp = 0;
-
-
+                                             
+                                             
                                                               // get raw timestamp information
                                                               // I think that a good way to understand these timestamps is that
                                                               // (1) the rtlt below is the timestamp of the frame that should be playing at the
@@ -302,19 +302,19 @@ void *rtp_control_receiver(void *arg) {
                                                               // Thus, (3) the latency can be calculated by subtracting the second from the
                                                               // first.
                                                               // There must be more to it -- there something missing.
-
+                                             
                                                               // In addition, it seems that if the value of the short represented by the second
                                                               // pair of bytes in the packet is 7
                                                               // then an extra time lag is expected to be added, presumably by
                                                               // the AirPort Express.
-
+                                             
                                                               // Best guess is that this delay is 11,025 frames.
-
+                                             
                                                               uint32_t rtlt = nctohl(&packet[4]); // raw timestamp less latency
                                                               uint32_t rt = nctohl(&packet[16]);  // raw timestamp
-
+                                             
                                                               uint32_t fl = nctohs(&packet[2]); //
-
+                                             
                                                               debug(1,"Sync Packet of %d bytes received: \"%s\", flags: %d, timestamps %u and %u,
                                                           giving a latency of %d frames.",plen,obf,fl,rt,rtlt,rt-rtlt);
                                                               //debug(1,"Monotonic timestamps are: %" PRId64 " and %" PRId64 "
diff --git a/rtsp.c b/rtsp.c
index cd76c537f457f3ebb137968f2664e92a8c9dd4f4..17fcf397b95663ca2d906b20a7fcca8f756354e4 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -536,7 +536,7 @@ void release_play_lock(rtsp_conn_info *conn) {
 }
 
 int get_play_lock(rtsp_conn_info *conn) {
-    debug(2, "Connection %d: request play lock.", conn->connection_number);
+  debug(2, "Connection %d: request play lock.", conn->connection_number);
   // returns -1 if it failed, 0 if it succeeded and 1 if it succeeded but
   // interrupted an existing session
   int response = 0;
@@ -1176,9 +1176,9 @@ enum rtsp_read_request_response rtsp_read_request(rtsp_conn_info *conn, rtsp_mes
   ssize_t buflen = 4096;
 #ifdef CONFIG_METADATA
   if ((config.metadata_enabled != 0) && (config.get_coverart != 0))
-    buflen = 1024 * 256;  // big enough for typical picture data, which will be base64 encoded
+    buflen = 1024 * 256; // big enough for typical picture data, which will be base64 encoded
 #endif
-  int release_buffer = 0; // on exit, don't deallocate the buffer if everything was okay
+  int release_buffer = 0;         // on exit, don't deallocate the buffer if everything was okay
   char *buf = malloc(buflen + 1); // add a NUL at the end
   if (!buf) {
     warn("Connection %d: rtsp_read_request: can't get a buffer.", conn->connection_number);
@@ -1348,9 +1348,12 @@ int msg_write_response(rtsp_conn_info *conn, rtsp_message *resp) {
     char *string;
   };
 
-  struct response_t responses[] = {
-      {200, "OK"}, {400, "Bad Request"}, {403, "Unauthorized"}, {451, "Unavailable"}, {501, "Not Implemented"}};
-      // 451 is really "Unavailable For Legal Reasons"!
+  struct response_t responses[] = {{200, "OK"},
+                                   {400, "Bad Request"},
+                                   {403, "Unauthorized"},
+                                   {451, "Unavailable"},
+                                   {501, "Not Implemented"}};
+  // 451 is really "Unavailable For Legal Reasons"!
   int found = 0;
   char *respcode_text = "Unauthorized";
   for (i = 0; i < sizeof(responses) / sizeof(struct response_t); i++) {
@@ -2302,7 +2305,8 @@ void handle_command(__attribute__((unused)) rtsp_conn_info *conn, rtsp_message *
                   uint64_t length = 0;
                   plist_get_data_val(the_item, &buff, &length);
                   // debug(1,"Item %d, length: %" PRId64 " bytes", item_number, length);
-                  if ((buff != NULL) && (length >= strlen("bplist00")) && (strstr(buff, "bplist00") == buff)) {
+                  if ((buff != NULL) && (length >= strlen("bplist00")) &&
+                      (strstr(buff, "bplist00") == buff)) {
                     // debug(1,"Contains a plist.");
                     plist_t subsidiary_plist = NULL;
                     plist_from_memory(buff, length, &subsidiary_plist);
@@ -2756,9 +2760,9 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
                         memset(buf, 0, sizeof(buf));
                         inet_ntop(AF_INET6, (void *)&addr6->sin6_addr, buf, sizeof(buf));
                         // don't insist there are in the same subnet...
-                        //if (!different) {
-                          // debug(1, "%s is in the same subnet as %s.", buf, ip_address);
-                          plist_array_append_item(addresses, plist_new_string(buf));
+                        // if (!different) {
+                        // debug(1, "%s is in the same subnet as %s.", buf, ip_address);
+                        plist_array_append_item(addresses, plist_new_string(buf));
                         //}
                       }
                     }
@@ -2773,12 +2777,12 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
                         // struct sockaddr_in *mask = (struct sockaddr_in *)(iap->ifa_netmask);
                         // if ((addr->sin_addr.s_addr & mask->sin_addr.s_addr) ==
                         //    (pa4->sin_addr.s_addr & mask->sin_addr.s_addr)) {
-                          char buf[32];
-                          memset(buf, 0, sizeof(buf));
-                          inet_ntop(AF_INET, (void *)&addr->sin_addr, buf, sizeof(buf));
-                          // no longer insisting they are in the same subnet
-                          // debug(1, "%s is in the same subnet as %s.", buf, ip_address);
-                          plist_array_append_item(addresses, plist_new_string(buf));
+                        char buf[32];
+                        memset(buf, 0, sizeof(buf));
+                        inet_ntop(AF_INET, (void *)&addr->sin_addr, buf, sizeof(buf));
+                        // no longer insisting they are in the same subnet
+                        // debug(1, "%s is in the same subnet as %s.", buf, ip_address);
+                        plist_array_append_item(addresses, plist_new_string(buf));
                         // }
                       }
                     }
@@ -2838,8 +2842,6 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
                   get_category_string(conn->airplay_stream_category));
             mdns_update(NULL, secondary_txt_records);
 
-
-
             resp->respcode = 200;
           } else {
             debug(1, "SETUP on Connection %d: PTP setup -- no timingPeerInfo plist.",
@@ -2875,8 +2877,7 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
 
           plist_dict_set_item(setupResponsePlist, "eventPort",
                               plist_new_uint(conn->local_event_port));
-          plist_dict_set_item(setupResponsePlist, "timingPort",
-                              plist_new_uint(0));
+          plist_dict_set_item(setupResponsePlist, "timingPort", plist_new_uint(0));
           cancel_all_RTSP_threads(
               remote_control_stream,
               conn->connection_number); // kill all the other remote control listeners
index 88db792477cdaaaeb22c682bda17841b0440dde8..eaa020fa550ef42e6190faa10422231119e24d91 100644 (file)
@@ -289,7 +289,8 @@ void usage(char *progname) {
 #ifdef CONFIG_METADATA
   printf("    -M, --metadata-enable   ask for metadata from the source and process it.\n");
   printf("    --metadata-pipename=PIPE send metadata to PIPE, e.g. "
-         "--metadata-pipename=/tmp/%s-metadata.\n", config.appName);
+         "--metadata-pipename=/tmp/%s-metadata.\n",
+         config.appName);
   printf("                            The default is /tmp/%s-metadata.\n", config.appName);
   printf("    -g, --get-coverart      send cover art through the metadata pipe.\n");
 #endif
@@ -1262,7 +1263,7 @@ int parse_options(int argc, char **argv) {
     strcat(temp_metadata_pipe_name, config.appName);
     strcat(temp_metadata_pipe_name, "-metadata");
     config.metadata_pipename = strdup(temp_metadata_pipe_name);
-    debug(1,"default metadata_pipename is \"%s\".", temp_metadata_pipe_name);
+    debug(1, "default metadata_pipename is \"%s\".", temp_metadata_pipe_name);
   }
 #endif
 
@@ -1320,7 +1321,7 @@ int parse_options(int argc, char **argv) {
   char temp_pid_dir[4096];
   strcpy(temp_pid_dir, "/var/run/");
   strcat(temp_pid_dir, config.appName);
-  debug(1,"default pid filename is \"%s\".", temp_pid_dir);
+  debug(1, "default pid filename is \"%s\".", temp_pid_dir);
   char *use_this_pid_dir = temp_pid_dir;
 #endif
   // debug(1,"config.piddir \"%s\".",config.piddir);
@@ -1445,6 +1446,14 @@ void exit_function() {
 #ifdef CONFIG_AIRPLAY_2
       if (config.regtype2)
         free(config.regtype2);
+      if (config.nqptp_shared_memory_interface_name)
+        free(config.nqptp_shared_memory_interface_name);
+      if (config.airplay_device_id)
+        free(config.airplay_device_id);
+      if (config.airplay_pin)
+        free(config.airplay_pin);
+      if (config.airplay_pi)
+        free(config.airplay_pi);
 #endif
 
 #ifdef CONFIG_LIBDAEMON
@@ -1462,6 +1471,7 @@ void exit_function() {
       config_destroy(config.cfg);
     if (config.appName)
       free(config.appName);
+
       // probably should be freeing malloc'ed memory here, including strdup-created strings...
 
 #ifdef CONFIG_LIBDAEMON
@@ -1833,32 +1843,39 @@ int main(int argc, char **argv) {
   // use the start of the config.hw_addr and the PID to generate the default airplay_device_id
   uint64_t apid = nctoh64(config.hw_addr);
   apid = apid >> 16; // we only use the first 6 bytes but have imported 8.
-  
+
   int64_t aid;
+
   // add the airplay_device_id_offset if provided
   if (config_lookup_int64(config.cfg, "general.airplay_device_id_offset", &aid)) {
     apid += aid;
-  } 
-  
+  }
+
   // replace the airplay_device_id with this, if provided
   if (config_lookup_int64(config.cfg, "general.airplay_device_id", &aid)) {
     apid = aid;
   }
-  
-  char apids[6*2+5+1]; // six pairs of digits, 5 colons and a NUL
-  apids[6*2+5] = 0; // NUL termination
+
+  char shared_memory_interface_name[256] = "";
+  snprintf(shared_memory_interface_name, sizeof(shared_memory_interface_name), "/%s-%" PRIx64 "",
+           config.appName, apid);
+  debug(1, "smi name: \"%s\"", shared_memory_interface_name);
+
+  config.nqptp_shared_memory_interface_name = strdup(shared_memory_interface_name);
+
+  char apids[6 * 2 + 5 + 1]; // six pairs of digits, 5 colons and a NUL
+  apids[6 * 2 + 5] = 0;      // NUL termination
   int i;
   char hexchar[] = "0123456789abcdef";
   for (i = 5; i >= 0; i--) {
-    apids[i*3+1] = hexchar[apid & 0xF];
+    apids[i * 3 + 1] = hexchar[apid & 0xF];
     apid = apid >> 4;
-    apids[i*3] = hexchar[apid & 0xF];
+    apids[i * 3] = hexchar[apid & 0xF];
     apid = apid >> 4;
     if (i != 0)
-      apids[i*3-1] = ':';
+      apids[i * 3 - 1] = ':';
   }
-  
+
   config.airplay_device_id = strdup(apids);
 
   // now generate a UUID
@@ -2017,9 +2034,12 @@ int main(int argc, char **argv) {
   debug(1, "run_this_after_play_ends action is \"%s\".", strnull(config.cmd_stop));
   debug(1, "wait-cmd status is %d.", config.cmd_blocking);
   debug(1, "run_this_before_play_begins may return output is %d.", config.cmd_start_returns_output);
-  debug(1, "run_this_if_an_unfixable_error_is_detected action is \"%s\".", strnull(config.cmd_unfixable));
-  debug(1, "run_this_before_entering_active_state action is  \"%s\".", strnull(config.cmd_active_start));
-  debug(1, "run_this_after_exiting_active_state action is  \"%s\".", strnull(config.cmd_active_stop));
+  debug(1, "run_this_if_an_unfixable_error_is_detected action is \"%s\".",
+        strnull(config.cmd_unfixable));
+  debug(1, "run_this_before_entering_active_state action is  \"%s\".",
+        strnull(config.cmd_active_start));
+  debug(1, "run_this_after_exiting_active_state action is  \"%s\".",
+        strnull(config.cmd_active_stop));
   debug(1, "active_state_timeout is  %f seconds.", config.active_state_timeout);
   debug(1, "mdns backend \"%s\".", strnull(config.mdns_name));
   debug(2, "userSuppliedLatency is %d.", config.userSuppliedLatency);