changes to support older protocol with no aeskey/ecdh_secret hashing.

This commit is contained in:
fduncanh
2021-12-13 16:49:08 -05:00
parent 8b255aec02
commit f45af796b7
15 changed files with 91 additions and 98 deletions

View File

@@ -1,4 +1,4 @@
<h1 id="uxplay-1.43-airplayairplay-mirror-server-for-linux-macos-and-unix.">UxPlay 1.43: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix.</h1>
<h1 id="uxplay-1.44-airplayairplay-mirror-server-for-linux-macos-and-unix.">UxPlay 1.44: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix.</h1>
<p>This project is a GPLv3 unix AirPlay2 server which now also works on macOS. Its main use is to act like an AppleTV for screen-mirroring (with audio) of iOS/macOS clients (iPads, iPhones, MacBooks) in a window on the server display (with the possibility of sharing that window on screen-sharing applications such as Zoom) on a host running Linux, macOS, or other unix, using Apples AirPlay Mirror protocol first available in iOS 5. (Details of what is known about the AirPlay2 protocol can be found <a href="https://github.com/SteeBono/airplayreceiver/wiki/AirPlay2-Protocol">here</a> and <a href="https://emanuelecozzi.net/docs/airplay2">here</a>). <strong>Note that Apple DRM (as in Apple TV app content) cannot be decrypted by UxPlay.</strong></p>
<p>The UxPlay server and its client must be on the same local area network, on which a <strong>Bonjour/Zeroconf mDNS/DNS-SD server</strong> is also running (only DNS-SD “Service Discovery” service is necessary, it is not necessary that the local network also be of the “.local” mDNS-based type). On Linux and BSD Unix servers, this is usually provided by <a href="https://www.avahi.org">Avahi</a>, through the avahi-daemon service, and is included in most Linux distributions (this service can also be provided by macOS, iOS or Windows servers).</p>
<p><em>Since v1.38, UxPlay now also supports the Airplay audio-only protocol as well as AirPlay Mirror protocol, and (when the client screen is not being mirrored) can play Apple Lossless (ALAC) audio streamed from the client without video (the accompanying cover-art and metadata is not displayed). The initial connection to the client can be either AirPlay audio or Airplay Mirror mode. An Airplay Mirror connection (with “Advanced Audio Coding” AAC-ELD lossy-compression audio) switches to ALAC if the mirrow window is closed and an AirPlay audio connection is started, and back again to AAC if a new Airplay Mirror connection is made</em>.</p>
@@ -56,7 +56,7 @@
<p>The “OpenGL renderer” window created on Linux by “-vs glimagesink” sometimes does not close properly when its “close” button is clicked. (this is a GStreamer issue). You may need to terminate uxplay with Ctrl-C to close a “zombie” OpenGl window.</p>
<p><strong>GStreamer issues:</strong> To troubleshoot GStreamer execute “export GST_DEBUG=2” to set the GStreamer debug-level environment-variable in the terminal where you will run uxplay, so that you see warning and error messages; (replace “2” by “4” to see much (much) more of what is happening inside GStreamer). Run “gst-inspect-1.0” to see which GStreamer plugins are installed on your system.</p>
<p>Some extra GStreamer packages for special plugins may need to be installed (or reinstalled: a user using a Wayland display system as an alternative to X11 reported that after reinstalling Lubuntu 18.4, UxPlay would not work until gstreamer1.0-x was installed, presumably for Waylands X11-compatibility mode). Different distributions may break up GStreamer 1.x into packages in different ways; the packages listed above in the build instructions should bring in other required GStreamer packages as dependencies, but will not install all possible plugins.</p>
<p><strong>Use with non-Apple clients</strong>: one user tried to use UxPlay with an <em>airmypc</em> client (a non-free commercial Windows application that can mirror a Windows screen on an Apple TV using AirPlay mirror protocol). While <em>airmypc</em> can mirror to a true AppleTV and some other AirPlay receivers, UxPlay appears to correctly pair with this client, but then fails to decrypt both the audio and video streams. Possibly a different variant of the AirPlay encryption/decryption protocol not supported by UxPlay is used by this client. Without further information, there is no obvious fix. UxPlay reports itself to clients as an “AirTunes/220.68” server.</p>
<p><strong>Use with non-Apple clients</strong>: third-party Windows-bases AirPlay clients such as AirMyPC typically use an older protocol that omits the hashing of the audio AES key with the “shared secret” <code>ecdh_secret</code> created during the initial pairing-handshake between client and server. Omission of this step was necessary for successful decryption of audio and video streams from the AirMyPC client, which emulates an old version of iOS, and reports its <code>sourceVersion</code> as <code>280.33</code>. The line <code>#define OLD_PROTOCOL_CLIENT "280.33"</code> in <code>lib/global.h</code> makes UxPlay skip the aeskey hashing step when the client reports this or an older value as its sourceVersion. If both audio and video decryption fail when using another third-party client, and <code>uxplay -d</code> output shows that it reports a later sourceVersion, try increasing the value in global.h.</p>
<h1 id="usage"><strong>Usage:</strong></h1>
<p>Options:</p>
<p><strong>-n server_name</strong> (Default: UxPlay); server_name@_hostname_ will be the name that appears offering AirPlay services to your iPad, iPhone etc, where <em>hostname</em> is the name of the server running uxplay. This will also now be the name shown above the mirror display (X11) window.</p>
@@ -77,6 +77,7 @@
<p><strong>-as 0</strong> (or just <strong>-a</strong>) suppresses playing of streamed audio, but displays streamed video.</p>
<p><strong>-t <em>timeout</em></strong> will cause the server to relaunch (without stopping uxplay) if no connections have been present during the previous <em>timeout</em> seconds. (You may wish to use this because the Server may not be visible to new Clients that were inactive when the Server was launched, and an idle Bonjour registration also eventually becomes unavailable for new connections.) The timer only starts once a Client has first made a mirror connection and then has disconnected with “Stop Mirrroring”. <em>This option should <strong>not</strong> be used if the display window is an OpenGL window on macOS, as such an OpenGL window created by GStreamer does not terminate correctly (it causes a segfault) if it is still open when the GStreamer pipeline is closed.</em></p>
<h1 id="changelog">ChangeLog</h1>
<p>1.44 2021-12-13 no hash of aeskey with ecdh_secret if sourceVersion &lt;= 280.33 (now supports AirMyPC)</p>
<p>1.43 2021-12-07 Various internal changes, such as tests for successful decryption, uniform treatment of informational/debug messages, etc., updated README.</p>
<p>1.42 2021-11-20 Fix MAC detection to work with modern Linux interface naming practices, MacOS and *BSD.</p>
<p>1.41 2021-11-11 Further cleanups of multiple audio format support (internal changes, separated RAOP and GStreamer audio/video startup)</p>
@@ -103,6 +104,7 @@
<li><p>UxPlay now builds on macOS.</p></li>
<li><p>The hostname of the server running uxplay is now appended to the AirPlay server name, which is now displayed as <em>name</em>@hostname, where <em>name</em> is “UxPlay”, (or whatever is set with the <strong>-n</strong> option).</p></li>
<li><p>Added support for audio-only streaming with original (non-Mirror) AirPlay protocol, with Apple Lossless (ALAC) audio.</p></li>
<li><p>Added suppport for the older AirPlay protocol used by third-party Windows-based AirPlay mirror emulators such as AirMyPC.</p></li>
</ol>
<h1 id="disclaimer">Disclaimer</h1>
<p>All the resources in this repository are written using only freely available information from the internet. The code and related resources are meant for educational purposes only. It is the responsibility of the user to make sure all local laws are adhered to.</p>

View File

@@ -1,5 +1,5 @@
# UxPlay 1.43: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix.
# UxPlay 1.44: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix.
This project is a GPLv3 unix AirPlay2 server which now also works on macOS.
Its main use is to act like an AppleTV for screen-mirroring (with audio) of iOS/macOS clients
@@ -251,12 +251,13 @@ reported that after reinstalling Lubuntu 18.4, UxPlay would not work until gstr
Different distributions may break up GStreamer 1.x into packages in different ways; the packages listed above in the build instructions should bring in
other required GStreamer packages as dependencies, but will not install all possible plugins.
**Use with non-Apple clients**: one user tried to use UxPlay with an *airmypc* client (a non-free commercial
Windows application that can mirror a Windows screen on an Apple TV using AirPlay mirror protocol). While *airmypc*
can mirror to a true AppleTV and some other AirPlay receivers, UxPlay appears to correctly pair with this client, but
then fails to decrypt both the audio and video streams. Possibly a different variant of the AirPlay encryption/decryption
protocol not supported by UxPlay is used by this client. Without further information, there is no obvious fix.
UxPlay reports itself to clients as an "AirTunes/220.68" server.
**Use with non-Apple clients**: third-party Windows-bases AirPlay clients such as AirMyPC typically use an older protocol
that omits the hashing of the audio AES key with the "shared secret" ```ecdh_secret``` created during the initial
pairing-handshake between client and server. Omission of this step was necessary for successful decryption of audio and video
streams from the AirMyPC client, which emulates an old version of iOS, and reports its ```sourceVersion``` as ```280.33```.
The line ```#define OLD_PROTOCOL_CLIENT "280.33"``` in ```lib/global.h``` makes UxPlay skip the aeskey hashing step when the client
reports this or an older value as its sourceVersion. If both audio and video decryption fail when using another third-party client, and
```uxplay -d``` output shows that it reports a later sourceVersion, try increasing the value in global.h.
# **Usage:**
@@ -362,6 +363,8 @@ Also: image transforms that had been added to RPiPlay have been ported to UxPlay
# ChangeLog
1.44 2021-12-13 no hash of aeskey with ecdh_secret if sourceVersion <= 280.33 (now supports AirMyPC)
1.43 2021-12-07 Various internal changes, such as tests for successful decryption, uniform treatment
of informational/debug messages, etc., updated README.
@@ -466,6 +469,8 @@ is compiled.) On macOS, Avahi is not used.
12. Added support for audio-only streaming with original (non-Mirror) AirPlay protocol, with Apple Lossless (ALAC) audio.
13. Added suppport for the older AirPlay protocol used by third-party Windows-based AirPlay mirror emulators such as AirMyPC.
# Disclaimer
All the resources in this repository are written using only freely available information from the internet. The code and related resources are meant for educational purposes only. It is the responsibility of the user to make sure all local laws are adhered to.

View File

@@ -1,4 +1,4 @@
UxPlay 1.43: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix.
UxPlay 1.44: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix.
======================================================================
This project is a GPLv3 unix AirPlay2 server which now also works on
@@ -333,16 +333,18 @@ GStreamer 1.x into packages in different ways; the packages listed above
in the build instructions should bring in other required GStreamer
packages as dependencies, but will not install all possible plugins.
**Use with non-Apple clients**: one user tried to use UxPlay with an
*airmypc* client (a non-free commercial Windows application that can
mirror a Windows screen on an Apple TV using AirPlay mirror protocol).
While *airmypc* can mirror to a true AppleTV and some other AirPlay
receivers, UxPlay appears to correctly pair with this client, but then
fails to decrypt both the audio and video streams. Possibly a different
variant of the AirPlay encryption/decryption protocol not supported by
UxPlay is used by this client. Without further information, there is no
obvious fix. UxPlay reports itself to clients as an "AirTunes/220.68"
server.
**Use with non-Apple clients**: third-party Windows-bases AirPlay
clients such as AirMyPC typically use an older protocol that omits the
hashing of the audio AES key with the "shared secret" `ecdh_secret`
created during the initial pairing-handshake between client and server.
Omission of this step was necessary for successful decryption of audio
and video streams from the AirMyPC client, which emulates an old version
of iOS, and reports its `sourceVersion` as `280.33`. The line
`#define OLD_PROTOCOL_CLIENT "280.33"` in `lib/global.h` makes UxPlay
skip the aeskey hashing step when the client reports this or an older
value as its sourceVersion. If both audio and video decryption fail when
using another third-party client, and `uxplay -d` output shows that it
reports a later sourceVersion, try increasing the value in global.h.
**Usage:**
==========
@@ -459,6 +461,9 @@ still open when the GStreamer pipeline is closed.*
ChangeLog
=========
1.44 2021-12-13 no hash of aeskey with ecdh\_secret if sourceVersion \<=
280.33 (now supports AirMyPC)
1.43 2021-12-07 Various internal changes, such as tests for successful
decryption, uniform treatment of informational/debug messages, etc.,
updated README.
@@ -582,6 +587,9 @@ Improvements since the original UxPlay by antimof:
12. Added support for audio-only streaming with original (non-Mirror)
AirPlay protocol, with Apple Lossless (ALAC) audio.
13. Added suppport for the older AirPlay protocol used by third-party
Windows-based AirPlay mirror emulators such as AirMyPC.
Disclaimer
==========

View File

@@ -5,6 +5,7 @@
#define GLOBAL_MODEL "AppleTV2,1"
#define GLOBAL_VERSION "220.68"
#define OLD_PROTOCOL_CLIENT "280.33"
#define MAX_HWADDR_LEN 6
#endif

View File

@@ -34,19 +34,13 @@ struct mirror_buffer_s {
/* AES key and IV */
// Need secondary processing to use
unsigned char aeskey[RAOP_AESKEY_LEN];
unsigned char ecdh_secret[32];
};
void
mirror_buffer_init_aes(mirror_buffer_t *mirror_buffer, uint64_t streamConnectionID)
{
sha_ctx_t *ctx = sha_init();
unsigned char eaeskey[64] = {};
unsigned char eaeskey[16];
memcpy(eaeskey, mirror_buffer->aeskey, 16);
sha_update(ctx, eaeskey, 16);
sha_update(ctx, mirror_buffer->ecdh_secret, 32);
sha_final(ctx, eaeskey, NULL);
unsigned char hash1[64];
unsigned char hash2[64];
char* skey = "AirPlayStreamKey";
@@ -55,7 +49,8 @@ mirror_buffer_init_aes(mirror_buffer_t *mirror_buffer, uint64_t streamConnection
unsigned char sivall[255];
sprintf((char*) skeyall, "%s%" PRIu64, skey, streamConnectionID);
sprintf((char*) sivall, "%s%" PRIu64, siv, streamConnectionID);
sha_reset(ctx);
sha_ctx_t *ctx = sha_init();
sha_update(ctx, skeyall, strlen((char*) skeyall));
sha_update(ctx, eaeskey, 16);
sha_final(ctx, hash1, NULL);
@@ -82,22 +77,18 @@ mirror_buffer_init_aes(mirror_buffer_t *mirror_buffer, uint64_t streamConnection
}
mirror_buffer_t *
mirror_buffer_init(logger_t *logger,
const unsigned char *aeskey,
const unsigned char *ecdh_secret)
mirror_buffer_init(logger_t *logger, const unsigned char *aeskey)
{
mirror_buffer_t *mirror_buffer;
assert(aeskey);
assert(ecdh_secret);
mirror_buffer = calloc(1, sizeof(mirror_buffer_t));
if (!mirror_buffer) {
return NULL;
}
memcpy(mirror_buffer->aeskey, aeskey, RAOP_AESKEY_LEN);
memcpy(mirror_buffer->ecdh_secret, ecdh_secret, 32);
mirror_buffer->logger = logger;
mirror_buffer->nextDecryptCount = 0;
//mirror_buffer_init_aes(mirror_buffer, aeskey, ecdh_secret, streamConnectionID);
//mirror_buffer_init_aes(mirror_buffer, aeskey, streamConnectionID);
return mirror_buffer;
}

View File

@@ -21,9 +21,7 @@
typedef struct mirror_buffer_s mirror_buffer_t;
mirror_buffer_t *mirror_buffer_init( logger_t *logger,
const unsigned char *aeskey,
const unsigned char *ecdh_secret);
mirror_buffer_t *mirror_buffer_init( logger_t *logger, const unsigned char *aeskey);
void mirror_buffer_init_aes(mirror_buffer_t *mirror_buffer, uint64_t streamConnectionID);
void mirror_buffer_decrypt(mirror_buffer_t *raop_mirror, unsigned char* input, unsigned char* output, int datalen);
void mirror_buffer_destroy(mirror_buffer_t *mirror_buffer);

View File

@@ -57,24 +57,20 @@ struct raop_buffer_s {
raop_buffer_entry_t entries[RAOP_BUFFER_LENGTH];
};
void
raop_buffer_init_key_iv(raop_buffer_t *raop_buffer,
const unsigned char *aeskey,
const unsigned char *aesiv,
const unsigned char *ecdh_secret)
raop_buffer_t *
raop_buffer_init(logger_t *logger,
const unsigned char *aeskey,
const unsigned char *aesiv)
{
// Initialization key
unsigned char eaeskey[64];
memcpy(eaeskey, aeskey, 16);
sha_ctx_t *ctx = sha_init();
sha_update(ctx, eaeskey, 16);
sha_update(ctx, ecdh_secret, 32);
sha_final(ctx, eaeskey, NULL);
sha_destroy(ctx);
memcpy(raop_buffer->aeskey, eaeskey, 16);
raop_buffer_t *raop_buffer;
assert(aeskey);
assert(aesiv);
raop_buffer = calloc(1, sizeof(raop_buffer_t));
if (!raop_buffer) {
return NULL;
}
raop_buffer->logger = logger;
memcpy(raop_buffer->aeskey, aeskey, RAOP_AESKEY_LEN);
memcpy(raop_buffer->aesiv, aesiv, RAOP_AESIV_LEN);
#ifdef DUMP_AUDIO
@@ -84,24 +80,6 @@ raop_buffer_init_key_iv(raop_buffer_t *raop_buffer,
fclose(file_keyiv);
}
#endif
}
raop_buffer_t *
raop_buffer_init(logger_t *logger,
const unsigned char *aeskey,
const unsigned char *aesiv,
const unsigned char *ecdh_secret)
{
raop_buffer_t *raop_buffer;
assert(aeskey);
assert(aesiv);
assert(ecdh_secret);
raop_buffer = calloc(1, sizeof(raop_buffer_t));
if (!raop_buffer) {
return NULL;
}
raop_buffer->logger = logger;
raop_buffer_init_key_iv(raop_buffer, aeskey, aesiv, ecdh_secret);
for (int i = 0; i < RAOP_BUFFER_LENGTH; i++) {
raop_buffer_entry_t *entry = &raop_buffer->entries[i];

View File

@@ -24,8 +24,7 @@ typedef int (*raop_resend_cb_t)(void *opaque, unsigned short seqno, unsigned sho
raop_buffer_t *raop_buffer_init(logger_t *logger,
const unsigned char *aeskey,
const unsigned char *aesiv,
const unsigned char *ecdh_secret);
const unsigned char *aesiv);
int raop_buffer_enqueue(raop_buffer_t *raop_buffer, unsigned char *data, unsigned short datalen, uint64_t timestamp, int use_seqnum);
void *raop_buffer_dequeue(raop_buffer_t *raop_buffer, unsigned int *length, uint64_t *timestamp, int no_resend);
void raop_buffer_handle_resends(raop_buffer_t *raop_buffer, raop_resend_cb_t resend_cb, void *opaque);

View File

@@ -340,10 +340,9 @@ raop_handler_setup(raop_conn_t *conn,
// Parsing bplist
plist_t req_root_node = NULL;
plist_from_bin(data, data_len, &req_root_node);
plist_t req_streams_node = plist_dict_get_item(req_root_node, "streams");
plist_t req_eiv_node = plist_dict_get_item(req_root_node, "eiv");
plist_t req_ekey_node = plist_dict_get_item(req_root_node, "ekey");
plist_t req_eiv_node = plist_dict_get_item(req_root_node, "eiv");
// For the response
plist_t res_root_node = plist_new_dict();
@@ -360,7 +359,7 @@ raop_handler_setup(raop_conn_t *conn,
plist_get_data_val(req_eiv_node, &eiv, &eiv_len);
memcpy(aesiv, eiv, 16);
logger_log(conn->raop->logger, LOGGER_DEBUG, "eiv_len = %llu", eiv_len);
char *str = utils_data_to_string(aesiv, 16, 16);
char* str = utils_data_to_string(aesiv, 16, 16);
logger_log(conn->raop->logger, LOGGER_DEBUG, "16 byte aesiv (needed for AES-CBC audio decryption iv):\n%s", str);
free(str);
@@ -384,6 +383,24 @@ raop_handler_setup(raop_conn_t *conn,
str = utils_data_to_string(ecdh_secret, X25519_KEY_SIZE, 16);
logger_log(conn->raop->logger, LOGGER_DEBUG, "32 byte shared ecdh_secret:\n%s", str);
free(str);
/* sha-512 hashing of aeskey is skipped where the client has sourceVersion <= OLD_PROTOCOL_CLIENT (defined in global.h) */
plist_t req_source_version_node = plist_dict_get_item(req_root_node, "sourceVersion");
char* sourceVersion;
plist_get_string_val(req_source_version_node, &sourceVersion);
logger_log(conn->raop->logger, LOGGER_INFO, "client sourceVersion %s (no hash of aeskey if <= %s)", sourceVersion, OLD_PROTOCOL_CLIENT);
char *end_ptr;
if (strtoul(sourceVersion, &end_ptr, 10) > strtoul(OLD_PROTOCOL_CLIENT , &end_ptr, 10)) {
unsigned char eaeskey[64] = {0};
memcpy(eaeskey, aeskey, 16);
sha_ctx_t *ctx = sha_init();
sha_update(ctx, eaeskey, 16);
sha_update(ctx, ecdh_secret, 32);
sha_final(ctx, eaeskey, NULL);
sha_destroy(ctx);
memcpy(aeskey, eaeskey, 16);
}
// Time port
uint64_t timing_rport;
@@ -395,8 +412,8 @@ raop_handler_setup(raop_conn_t *conn,
conn->raop_ntp = raop_ntp_init(conn->raop->logger, conn->remote, conn->remotelen, timing_rport);
raop_ntp_start(conn->raop_ntp, &timing_lport);
conn->raop_rtp = raop_rtp_init(conn->raop->logger, &conn->raop->callbacks, conn->raop_ntp, conn->remote, conn->remotelen, aeskey, aesiv, ecdh_secret);
conn->raop_rtp_mirror = raop_rtp_mirror_init(conn->raop->logger, &conn->raop->callbacks, conn->raop_ntp, conn->remote, conn->remotelen, aeskey, ecdh_secret);
conn->raop_rtp = raop_rtp_init(conn->raop->logger, &conn->raop->callbacks, conn->raop_ntp, conn->remote, conn->remotelen, aeskey, aesiv);
conn->raop_rtp_mirror = raop_rtp_mirror_init(conn->raop->logger, &conn->raop->callbacks, conn->raop_ntp, conn->remote, conn->remotelen, aeskey);
plist_t res_event_port_node = plist_new_uint(conn->raop->port);
plist_t res_timing_port_node = plist_new_uint(timing_lport);
@@ -407,6 +424,7 @@ raop_handler_setup(raop_conn_t *conn,
}
// Process stream setup requests
plist_t req_streams_node = plist_dict_get_item(req_root_node, "streams");
if (PLIST_IS_ARRAY(req_streams_node)) {
plist_t res_streams_node = plist_new_array();

View File

@@ -132,8 +132,8 @@ raop_rtp_parse_remote(raop_rtp_t *raop_rtp, const unsigned char *remote, int rem
}
raop_rtp_t *
raop_rtp_init(logger_t *logger, raop_callbacks_t *callbacks, raop_ntp_t *ntp, const unsigned char *remote, int remotelen,
const unsigned char *aeskey, const unsigned char *aesiv, const unsigned char *ecdh_secret)
raop_rtp_init(logger_t *logger, raop_callbacks_t *callbacks, raop_ntp_t *ntp, const unsigned char *remote,
int remotelen, const unsigned char *aeskey, const unsigned char *aesiv)
{
raop_rtp_t *raop_rtp;
@@ -156,7 +156,7 @@ raop_rtp_init(logger_t *logger, raop_callbacks_t *callbacks, raop_ntp_t *ntp, co
}
memcpy(&raop_rtp->callbacks, callbacks, sizeof(raop_callbacks_t));
raop_rtp->buffer = raop_buffer_init(logger, aeskey, aesiv, ecdh_secret);
raop_rtp->buffer = raop_buffer_init(logger, aeskey, aesiv);
if (!raop_rtp->buffer) {
free(raop_rtp);
return NULL;

View File

@@ -26,8 +26,8 @@
typedef struct raop_rtp_s raop_rtp_t;
raop_rtp_t *raop_rtp_init(logger_t *logger, raop_callbacks_t *callbacks, raop_ntp_t *ntp, const unsigned char *remote, int remotelen,
const unsigned char *aeskey, const unsigned char *aesiv, const unsigned char *ecdh_secret);
raop_rtp_t *raop_rtp_init(logger_t *logger, raop_callbacks_t *callbacks, raop_ntp_t *ntp, const unsigned char *remote,
int remotelen, const unsigned char *aeskey, const unsigned char *aesiv);
void raop_rtp_start_audio(raop_rtp_t *raop_rtp, int use_udp, unsigned short control_rport,
unsigned short *control_lport, unsigned short *data_lport);

View File

@@ -109,8 +109,7 @@ raop_rtp_parse_remote(raop_rtp_mirror_t *raop_rtp_mirror, const unsigned char *r
#define NO_FLUSH (-42)
raop_rtp_mirror_t *raop_rtp_mirror_init(logger_t *logger, raop_callbacks_t *callbacks, raop_ntp_t *ntp,
const unsigned char *remote, int remotelen,
const unsigned char *aeskey, const unsigned char *ecdh_secret)
const unsigned char *remote, int remotelen, const unsigned char *aeskey)
{
raop_rtp_mirror_t *raop_rtp_mirror;
@@ -125,7 +124,7 @@ raop_rtp_mirror_t *raop_rtp_mirror_init(logger_t *logger, raop_callbacks_t *call
raop_rtp_mirror->ntp = ntp;
memcpy(&raop_rtp_mirror->callbacks, callbacks, sizeof(raop_callbacks_t));
raop_rtp_mirror->buffer = mirror_buffer_init(logger, aeskey, ecdh_secret);
raop_rtp_mirror->buffer = mirror_buffer_init(logger, aeskey);
if (!raop_rtp_mirror->buffer) {
free(raop_rtp_mirror);
return NULL;

View File

@@ -24,8 +24,7 @@ typedef struct raop_rtp_mirror_s raop_rtp_mirror_t;
typedef struct h264codec_s h264codec_t;
raop_rtp_mirror_t *raop_rtp_mirror_init(logger_t *logger, raop_callbacks_t *callbacks, raop_ntp_t *ntp,
const unsigned char *remote, int remotelen,
const unsigned char *aeskey, const unsigned char *ecdh_secret);
const unsigned char *remote, int remotelen, const unsigned char *aeskey);
void raop_rtp_init_mirror_aes(raop_rtp_mirror_t *raop_rtp_mirror, uint64_t streamConnectionID);
void raop_rtp_start_mirror(raop_rtp_mirror_t *raop_rtp_mirror, int use_udp, unsigned short *mirror_data_lport);
void raop_rtp_mirror_stop(raop_rtp_mirror_t *raop_rtp_mirror);

View File

@@ -1,11 +1,11 @@
.TH UXPLAY "1" "December 2021" "1.43" "User Commands"
.TH UXPLAY "1" "December 2021" "1.44" "User Commands"
.SH NAME
uxplay \- start AirPlay server
.SH SYNOPSIS
.B uxplay
[\fI\,-n name\/\fR] [\fI\,-s wxh\/\fR] [\fI\,-p \/\fR[\fI\,n\/\fR]] [more \fI OPTIONS \/\fR ...]
.SH DESCRIPTION
UxPlay 1.43: An open\-source AirPlay mirroring server based on RPiPlay
UxPlay 1.44: An open\-source AirPlay mirroring server based on RPiPlay
.SH OPTIONS
.TP
.B

View File

@@ -36,10 +36,6 @@
#include <net/if_dl.h>
#endif
#include "log.h"
#include "lib/raop.h"
#include "lib/stream.h"
@@ -48,7 +44,7 @@
#include "renderers/video_renderer.h"
#include "renderers/audio_renderer.h"
#define VERSION "1.43"
#define VERSION "1.44"
#define DEFAULT_NAME "UxPlay"
#define DEFAULT_DEBUG_LOG false
@@ -74,7 +70,6 @@ static unsigned char compression_type = 0;
static std::string audiosink = "autoaudiosink";
static bool use_audio = true;
gboolean connection_callback (gpointer loop){
if (!connections_stopped) {
counter = 0;