[airplay] Add support for AirPlay 2

Includes
- Implementation in src/outputs/airplays2, type OUTPUT_TYPE_AIRPLAY
- Homekit pairing, both normal (with PIN) and transient
- New session startup sequence, incl GET /info, SETPEERS and 2 x SETUP
- No more OPTIONS and ANNOUNCE
- Use POST /feedback for keepalive instead of SET_PARAMETERS
- Sequence dispatching instead of callback chains
- Continue despite "Bad request" to SET_PARAMETER (volume)
- Opening of event connection to receiver (reverse rtsp connection)

Still to be done
- Password authentication
- Handling of events
This commit is contained in:
ejurgensen
2020-11-27 22:46:38 +01:00
parent 86f762bb1f
commit 8368ca7686
14 changed files with 7479 additions and 621 deletions

View File

@@ -45,8 +45,9 @@ extern "C" {
/* Response codes */
#define RTSP_OK 200
#define RTSP_UNAUTHORIZED 401
#define RTSP_FORBIDDEN 403
#define RTSP_UNAUTHORIZED 401
#define RTSP_FORBIDDEN 403
#define RTSP_CONNECTION_AUTH_REQUIRED 470
struct evrtsp_connection;
@@ -135,6 +136,10 @@ void evrtsp_connection_free(struct evrtsp_connection *evcon);
void evrtsp_connection_set_closecb(struct evrtsp_connection *evcon,
void (*)(struct evrtsp_connection *, void *), void *);
/** Set a callback for encryption/decryption. */
void evrtsp_connection_set_ciphercb(struct evrtsp_connection *evcon,
void (*)(struct evbuffer *, void *, int encrypt), void *);
/**
* Associates an event base with the connection - can only be called
* on a freshly created connection object that has not been used yet.

View File

@@ -85,6 +85,9 @@ struct evrtsp_connection {
void (*closecb)(struct evrtsp_connection *, void *);
void *closecb_arg;
void (*ciphercb)(struct evbuffer *evbuf, void *, int encrypt);
void *ciphercb_arg;
struct event_base *base;
};

View File

@@ -620,6 +620,9 @@ evrtsp_read(int fd, short what, void *arg)
return;
}
if (evcon->ciphercb)
evcon->ciphercb(evcon->input_buffer, evcon->ciphercb_arg, 0);
switch (evcon->state) {
case EVCON_READING_FIRSTLINE:
evrtsp_read_firstline(evcon, req);
@@ -725,6 +728,10 @@ evrtsp_request_dispatch(struct evrtsp_connection* evcon)
/* Create the header from the store arguments */
evrtsp_make_header(evcon, req);
/* forked-daapd customisation for encryption */
if (evcon->ciphercb)
evcon->ciphercb(evcon->output_buffer, evcon->ciphercb_arg, 1);
evrtsp_write_buffer(evcon, evrtsp_write_connectioncb, NULL);
}
@@ -1312,6 +1319,14 @@ evrtsp_connection_set_closecb(struct evrtsp_connection *evcon,
evcon->closecb_arg = cbarg;
}
void
evrtsp_connection_set_ciphercb(struct evrtsp_connection *evcon,
void (*cb)(struct evbuffer *, void *, int encrypt), void *cbarg)
{
evcon->ciphercb = cb;
evcon->ciphercb_arg = cbarg;
}
void
evrtsp_connection_get_local_address(struct evrtsp_connection *evcon,
char **address, u_short *port, int *family)