Stop storing the timing peer list. Clean up generation of device's timing addresses (and fix a bug). Use unique SMI interface for access to NQPTP.

This commit is contained in:
Mike Brady
2021-12-30 11:03:34 +00:00
parent 35317687f9
commit 04aba03b4f
3 changed files with 59 additions and 104 deletions
-3
View File
@@ -350,9 +350,6 @@ typedef struct {
uint64_t type;
uint64_t networkTimeTimelineID; // the clock ID used by the player
uint8_t groupContainsGroupLeader; // information coming from the SETUP
char *ap2_timing_peer_list_message;
#endif
// used as the initials values for calculating the rate at which the source thinks it's sending
+5 -4
View File
@@ -118,9 +118,10 @@ int ptp_get_clock_info(uint64_t *actual_clock_id, uint64_t *time_of_sample, uint
int ptp_shm_interface_open() {
mapped_addr = NULL;
int response = -1;
if (strcmp(config.nqptp_shared_memory_interface_name,"") != 0) {
if (strcmp(config.nqptp_shared_memory_interface_name, "") != 0) {
response = 0;
int shared_memory_file_descriptor = shm_open(config.nqptp_shared_memory_interface_name, O_RDWR, 0);
int shared_memory_file_descriptor =
shm_open(config.nqptp_shared_memory_interface_name, O_RDWR, 0);
if (shared_memory_file_descriptor >= 0) {
mapped_addr =
// needs to be PROT_READ | PROT_WRITE to allow the mapped memory to be writable for the
@@ -137,7 +138,7 @@ int ptp_shm_interface_open() {
response = -1;
}
} else {
debug(1,"No config.nqptp_shared_memory_interface_name");
debug(1, "No config.nqptp_shared_memory_interface_name");
}
return response;
}
@@ -161,7 +162,7 @@ void ptp_send_control_message_string(const char *msg) {
*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);
debug(2, "Send control message to NQPTP: \"%s\"", full_message);
int s;
unsigned short port = htons(NQPTP_CONTROL_PORT);
struct sockaddr_in server;
+54 -97
View File
@@ -1848,18 +1848,6 @@ void handle_setrateanchori(rtsp_conn_info *conn, rtsp_message *req, rtsp_message
// reset_anchor_info(conn); // needed if the player resumes
}
pthread_cleanup_pop(1); // unlock the conn->flush_mutex
if ((rate & 1) != 0) {
// keep this outside the flush_mutex lock
if (conn->ap2_timing_peer_list_message) {
// ptp_send_control_message_string(conn->ap2_timing_peer_list_message);
} else {
debug(1, "Connection %d: No timing peer list!", conn->connection_number);
}
} else {
// player_full_flush(conn);
// ptp_send_control_message_string("T"); // ensure an obsolete clock isn't picked up later.
}
}
pthread_cleanup_pop(1); // plist_free the messagePlist;
} else {
@@ -2407,15 +2395,7 @@ void handle_setpeers(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp
if (ip_address != NULL)
free(ip_address);
}
if (conn->ap2_timing_peer_list_message != NULL)
free(conn->ap2_timing_peer_list_message);
conn->ap2_timing_peer_list_message = strdup(timing_list_message);
// if this rtsp thread is playing...
// if (try_to_hold_play_lock(conn) == 0) {
ptp_send_control_message_string(conn->ap2_timing_peer_list_message);
// release_hold_on_play_lock(conn);
// }
ptp_send_control_message_string(timing_list_message);
}
plist_free(addresses_array);
resp->respcode = 200;
@@ -2498,10 +2478,6 @@ void teardown_phase_two(rtsp_conn_info *conn) {
free(conn->dacp_active_remote);
conn->dacp_active_remote = NULL;
}
if (conn->ap2_timing_peer_list_message) {
free(conn->ap2_timing_peer_list_message);
conn->ap2_timing_peer_list_message = NULL;
}
release_play_lock(conn);
}
}
@@ -2677,7 +2653,7 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
uint8_t isRemoteControlOnlyBoolean = 0;
plist_get_bool_val(isRemoteControlOnly, &isRemoteControlOnlyBoolean);
if (isRemoteControlOnlyBoolean != 0) {
debug(2, "Connection %d: SETUP: Remote Control setup detected.",
debug(1, "Connection %d: SETUP: Remote Control setup detected.",
conn->connection_number);
conn->airplay_stream_category = remote_control_stream;
} else {
@@ -2727,87 +2703,30 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
debug(1, "No groupContainsGroupLeader in SETUP");
}
char timing_list_message[4096];
timing_list_message[0] = 'T';
timing_list_message[1] = 0;
plist_t timing_peer_info = plist_dict_get_item(messagePlist, "timingPeerInfo");
if (timing_peer_info) {
// first, get and retain the incoming plist.
plist_t addresses = plist_new_array(); // to hold the device's peer interfaces
// first, get the incoming plist.
plist_t addresses_array = plist_dict_get_item(timing_peer_info, "Addresses");
if (addresses_array) {
// iterate through the array of items
uint32_t items = plist_array_get_size(addresses_array);
if (items) {
uint32_t item;
struct ifaddrs *addrs, *iap;
getifaddrs(&addrs);
for (item = 0; item < items; item++) {
plist_t n = plist_array_get_item(addresses_array, item);
char *ip_address = NULL;
plist_get_string_val(n, &ip_address);
// debug(1, "Timing peer: %s", ip_address);
// find its family and convert it into an IPv4/6 address
struct sockaddr_storage peer_address;
struct sockaddr_in6 *pa6 = (struct sockaddr_in6 *)&peer_address;
struct sockaddr_in *pa4 = (struct sockaddr_in *)&peer_address;
if (inet_pton(AF_INET6, ip_address, &pa6->sin6_addr) ==
1) { // is an IPv6 address...
peer_address.ss_family = AF_INET6;
for (iap = addrs; iap != NULL; iap = iap->ifa_next) {
if ((iap->ifa_addr) && (iap->ifa_netmask) && (iap->ifa_flags & IFF_UP) &&
((iap->ifa_flags & IFF_LOOPBACK) == 0) &&
(iap->ifa_addr->sa_family == AF_INET6)) {
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)(iap->ifa_addr);
struct sockaddr_in6 *mask6 = (struct sockaddr_in6 *)(iap->ifa_netmask);
unsigned int i;
int different = 0;
for (i = 0; ((i < 16) && (different == 0)); i++) {
unsigned char host_byte =
(addr6->sin6_addr.s6_addr[i] & mask6->sin6_addr.s6_addr[i]);
unsigned char peer_byte =
(pa6->sin6_addr.s6_addr[i] & mask6->sin6_addr.s6_addr[i]);
if (host_byte != peer_byte)
different = 1;
}
char buf[32];
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));
//}
}
}
} else if (inet_pton(AF_INET, ip_address, &pa4->sin_addr) == 1) {
peer_address.ss_family = AF_INET;
for (iap = addrs; iap != NULL; iap = iap->ifa_next) {
if ((iap->ifa_addr) && (iap->ifa_netmask) && (iap->ifa_flags & IFF_UP) &&
((iap->ifa_flags & IFF_LOOPBACK) == 0) &&
(iap->ifa_addr->sa_family == AF_INET)) {
struct sockaddr_in *addr = (struct sockaddr_in *)(iap->ifa_addr);
// not needed if not checking for same subnet
// 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));
// }
}
}
} else {
debug(1, "SETUP on Connection %d: Don't recognise this as an IP address.",
conn->connection_number);
}
strncat(timing_list_message, " ",
sizeof(timing_list_message) - 1 - strlen(timing_list_message));
strncat(timing_list_message, ip_address,
sizeof(timing_list_message) - 1 - strlen(timing_list_message));
free(ip_address);
}
freeifaddrs(addrs);
} else {
debug(1, "SETUP on Connection %d: No timingPeerInfo addresses in the array.",
conn->connection_number);
@@ -2819,6 +2738,49 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
// make up the timing peer info list part of the response...
// debug(1,"Create timingPeerInfoPlist");
plist_t timingPeerInfoPlist = plist_new_dict();
plist_t addresses = plist_new_array(); // to hold the device's interfaces
plist_array_append_item(addresses, plist_new_string(conn->self_ip_string));
// debug(1,"self ip: \"%s\"", conn->self_ip_string);
struct ifaddrs *addrs, *iap;
getifaddrs(&addrs);
for (iap = addrs; iap != NULL; iap = iap->ifa_next) {
// debug(1, "Interface index %d, name: \"%s\"",if_nametoindex(iap->ifa_name), iap->ifa_name);
if ((iap->ifa_addr) && (iap->ifa_netmask) && (iap->ifa_flags & IFF_UP) &&
((iap->ifa_flags & IFF_LOOPBACK) == 0)) {
char buf[INET6_ADDRSTRLEN + 1]; // +1 for a NUL
memset(buf, 0, sizeof(buf));
if (iap->ifa_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)(iap->ifa_addr);
inet_ntop(AF_INET6, (void *)&addr6->sin6_addr, buf, sizeof(buf));
plist_array_append_item(addresses, plist_new_string(buf));
// debug(1, "Own address IPv6: %s", buf);
// strncat(timing_list_message, " ",
// sizeof(timing_list_message) - 1 - strlen(timing_list_message));
// strncat(timing_list_message, buf,
// sizeof(timing_list_message) - 1 - strlen(timing_list_message));
} else {
struct sockaddr_in *addr = (struct sockaddr_in *)(iap->ifa_addr);
inet_ntop(AF_INET, (void *)&addr->sin_addr, buf, sizeof(buf));
plist_array_append_item(addresses, plist_new_string(buf));
// debug(1, "Own address IPv4: %s", buf);
// strncat(timing_list_message, " ",
// sizeof(timing_list_message) - 1 - strlen(timing_list_message));
// strncat(timing_list_message, buf,
// sizeof(timing_list_message) - 1 - strlen(timing_list_message));
}
}
}
freeifaddrs(addrs);
// debug(1,"initial timing peer command: \"%s\".", timing_list_message);
ptp_send_control_message_string(timing_list_message);
plist_dict_set_item(timingPeerInfoPlist, "Addresses", addresses);
plist_dict_set_item(timingPeerInfoPlist, "ID", plist_new_string(conn->self_ip_string));
plist_dict_set_item(setupResponsePlist, "timingPeerInfo", timingPeerInfoPlist);
@@ -3048,11 +3010,6 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
conn->input_bit_depth = conn->stream.fmtp[3];
conn->input_bytes_per_frame = conn->input_num_channels * ((conn->input_bit_depth + 7) / 8);
debug(2, "Realtime Stream Play");
if (conn->ap2_timing_peer_list_message) {
// ptp_send_control_message_string(conn->ap2_timing_peer_list_message);
} else {
debug(1, "No timing peer list!");
}
activity_monitor_signify_activity(1);
player_prepare_to_play(conn);
player_play(conn);