From 7a09ee4092285bda243b399f0b61ee200b5712c4 Mon Sep 17 00:00:00 2001 From: Julien BLACHE Date: Fri, 30 Jul 2010 18:52:14 +0200 Subject: [PATCH] Add support for streaming unencrypted audio --- src/player.c | 2 ++ src/raop.c | 35 ++++++++++++++++++++++++++--------- src/raop.h | 1 + 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/player.c b/src/player.c index c95c2609..a8687245 100644 --- a/src/player.c +++ b/src/player.c @@ -2983,6 +2983,8 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha rd->name = strdup(at_name); + rd->encrypt = 1; + rd->has_password = has_password; rd->password = val; diff --git a/src/raop.c b/src/raop.c index 72376318..7322233d 100644 --- a/src/raop.c +++ b/src/raop.c @@ -69,11 +69,14 @@ #define AIRTUNES_V2_HDR_LEN 12 #define ALAC_HDR_LEN 3 #define AIRTUNES_V2_PKT_LEN (AIRTUNES_V2_HDR_LEN + ALAC_HDR_LEN + STOB(AIRTUNES_V2_PACKET_SAMPLES)) +#define AIRTUNES_V2_PKT_TAIL_LEN (AIRTUNES_V2_PKT_LEN - AIRTUNES_V2_HDR_LEN - ((AIRTUNES_V2_PKT_LEN / 16) * 16)) +#define AIRTUNES_V2_PKT_TAIL_OFF (AIRTUNES_V2_PKT_LEN - AIRTUNES_V2_PKT_TAIL_LEN) struct raop_v2_packet { - uint8_t data[AIRTUNES_V2_PKT_LEN]; + uint8_t clear[AIRTUNES_V2_PKT_LEN]; + uint8_t encrypted[AIRTUNES_V2_PKT_LEN]; }; struct raop_session @@ -83,6 +86,7 @@ struct raop_session enum raop_session_state state; int req_in_flight; int req_has_auth; + int encrypt; int cseq; char *session; @@ -1403,6 +1407,8 @@ raop_session_make(struct raop_device *rd, int family, raop_status_cb cb) rs->status_cb = cb; rs->server_fd = -1; + rs->encrypt = rd->encrypt; + rs->password = rd->password; rs->ctrl = evrtsp_connection_new(address, port); @@ -2261,21 +2267,29 @@ raop_v2_make_packet(struct raop_v2_packet *pkt, uint8_t *rawbuf, uint64_t rtptim memset(pkt, 0, sizeof(struct raop_v2_packet)); - alac_encode(rawbuf, pkt->data + AIRTUNES_V2_HDR_LEN, STOB(AIRTUNES_V2_PACKET_SAMPLES)); + alac_encode(rawbuf, pkt->clear + AIRTUNES_V2_HDR_LEN, STOB(AIRTUNES_V2_PACKET_SAMPLES)); stream_seq++; seq = htobe16(stream_seq); rtptime32 = htobe32(RAOP_RTPTIME(rtptime)); - pkt->data[0] = 0x80; - pkt->data[1] = (sync_counter == 0) ? 0xe0 : 0x60; + pkt->clear[0] = 0x80; + pkt->clear[1] = (sync_counter == 0) ? 0xe0 : 0x60; - memcpy(pkt->data + 2, &seq, 2); - memcpy(pkt->data + 4, &rtptime32, 4); + memcpy(pkt->clear + 2, &seq, 2); + memcpy(pkt->clear + 4, &rtptime32, 4); /* 4 bytes unknown */ + /* Copy AirTunes v2 header to encrypted packet */ + memcpy(pkt->encrypted, pkt->clear, AIRTUNES_V2_HDR_LEN); + + /* Copy the tail of the audio packet that is left unencrypted */ + memcpy(pkt->encrypted + AIRTUNES_V2_PKT_TAIL_OFF, + pkt->clear + AIRTUNES_V2_PKT_TAIL_OFF, + AIRTUNES_V2_PKT_TAIL_LEN); + /* Reset cipher */ gc_err = gcry_cipher_reset(raop_aes_ctx); if (gc_err != GPG_ERR_NO_ERROR) @@ -2298,8 +2312,8 @@ raop_v2_make_packet(struct raop_v2_packet *pkt, uint8_t *rawbuf, uint64_t rtptim /* Encrypt in blocks of 16 bytes */ gc_err = gcry_cipher_encrypt(raop_aes_ctx, - pkt->data + AIRTUNES_V2_HDR_LEN, ((AIRTUNES_V2_PKT_LEN - AIRTUNES_V2_HDR_LEN) / 16) * 16, - NULL, 0); /* Encrypt in place */ + pkt->encrypted + AIRTUNES_V2_HDR_LEN, ((AIRTUNES_V2_PKT_LEN - AIRTUNES_V2_HDR_LEN) / 16) * 16, + pkt->clear + AIRTUNES_V2_HDR_LEN, ((AIRTUNES_V2_PKT_LEN - AIRTUNES_V2_HDR_LEN) / 16) * 16); if (gc_err != GPG_ERR_NO_ERROR) { gpg_strerror_r(gc_err, ebuf, sizeof(ebuf)); @@ -2316,6 +2330,7 @@ raop_v2_write(uint8_t *buf, uint64_t rtptime) { struct raop_v2_packet pkt; struct raop_session *rs; + uint8_t *data; int ret; ret = raop_v2_make_packet(&pkt, buf, rtptime); @@ -2340,7 +2355,9 @@ raop_v2_write(uint8_t *buf, uint64_t rtptime) if (rs->state != RAOP_STREAMING) continue; - ret = send(rs->server_fd, pkt.data, AIRTUNES_V2_PKT_LEN, 0); + data = (rs->encrypt) ? pkt.encrypted : pkt.clear; + + ret = send(rs->server_fd, data, AIRTUNES_V2_PKT_LEN, 0); if (ret < 0) { DPRINTF(E_LOG, L_RAOP, "Send error for %s: %s\n", rs->devname, strerror(errno)); diff --git a/src/raop.h b/src/raop.h index 1eeab92a..2bca87ad 100644 --- a/src/raop.h +++ b/src/raop.h @@ -30,6 +30,7 @@ struct raop_device char selected; char advertised; + char encrypt; char has_password; const char *password;