Merge remote-tracking branch 'origin/master' into httpd

This commit is contained in:
Sebastien
2020-01-29 11:10:34 -05:00
29 changed files with 1427 additions and 162 deletions

View File

@@ -532,7 +532,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
ctx->active_remote.thread = xTaskCreateStatic( (TaskFunction_t) search_remote, "search_remote", SEARCH_STACK_SIZE, ctx, ESP_TASK_PRIO_MIN + 1, ctx->active_remote.xStack, ctx->active_remote.xTaskBuffer);
#endif
} else if (!strcmp(method, "SETUP") && ((buf = kd_lookup(headers, "Transport")) != NULL)) {
} else if (!strcmp(method, "SETUP") && ((buf = kd_lookup(headers, "Transport")) != NULL)) {
char *p;
rtp_resp_t rtp = { 0 };
short unsigned tport = 0, cport = 0;
@@ -571,7 +571,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
kd_add(resp, "Audio-Latency", latency);
}
buf = kd_lookup(headers, "RTP-Info");
buf = kd_lookup(headers, "RTP-Info");
if (buf && (p = strcasestr(buf, "seq")) != NULL) sscanf(p, "%*[^=]=%hu", &seqno);
if (buf && (p = strcasestr(buf, "rtptime")) != NULL) sscanf(p, "%*[^=]=%u", &rtptime);
@@ -584,7 +584,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
unsigned rtptime = 0;
char *p;
buf = kd_lookup(headers, "RTP-Info");
buf = kd_lookup(headers, "RTP-Info");
if ((p = strcasestr(buf, "seq")) != NULL) sscanf(p, "%*[^=]=%hu", &seqno);
if ((p = strcasestr(buf, "rtptime")) != NULL) sscanf(p, "%*[^=]=%u", &rtptime);
@@ -615,7 +615,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
LOG_INFO("[%p]: mDNS search task terminated", ctx);
#endif
memset(&ctx->active_remote, 0, sizeof(ctx->active_remote));
NFREE(ctx->rtsp.aeskey);
NFREE(ctx->rtsp.aesiv);
@@ -626,9 +626,18 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
} else if (!strcmp(method, "SET_PARAMETER")) {
char *p;
if (body && (p = strcasestr(body, "volume")) != NULL) {
if (body && (p = strcasestr(body, "volume")) != NULL) {
float volume;
sscanf(p, "%*[^:]:%f", &volume);
LOG_INFO("[%p]: SET PARAMETER volume %f", ctx, volume);
volume = (volume == -144.0) ? 0 : (1 + volume / 30);
success = ctx->cmd_cb(RAOP_VOLUME, volume);
} else if (body && (p = strcasestr(body, "progress")) != NULL) {
int start, current, stop = 0;
sscanf(p, "%*[^:]:%u/%u/%u", &start, &current, &stop);
current = (current - start) / 44100;
if (stop) stop = (stop - start) / 44100;
else stop = -1;
LOG_INFO("[%p]: SET PARAMETER progress %u/%u %s", ctx, current, stop, p);
@@ -636,23 +645,28 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
}
if (body && ((p = kd_lookup(headers, "Content-Type")) != NULL) && !strcasecmp(p, "application/x-dmap-tagged")) {
struct metadata_s metadata;
dmap_settings settings = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, on_dmap_string, NULL,
NULL
};
LOG_INFO("[%p]: received metadata");
settings.ctx = &metadata;
memset(&metadata, 0, sizeof(struct metadata_s));
if (!dmap_parse(&settings, body, len)) {
if (!dmap_parse(&settings, body, len)) {
LOG_INFO("[%p]: received metadata\n\tartist: %s\n\talbum: %s\n\ttitle: %s",
ctx, metadata.artist, metadata.album, metadata.title);
success = ctx->cmd_cb(RAOP_METADATA, metadata.artist, metadata.album, metadata.title);
free_metadata(&metadata);
}
}
}
}
// don't need to free "buf" because kd_lookup return a pointer, not a strdup
kd_add(resp, "Audio-Jack-Status", "connected; type=analog");
kd_add(resp, "CSeq", kd_lookup(headers, "CSeq"));
if (success) {
buf = http_send(sock, "RTSP/1.0 200 OK", resp);
} else {

View File

@@ -14,9 +14,10 @@
#include "config.h"
#include "raop.h"
#include "audio_controls.h"
#include "display.h"
#include "accessors.h"
#include "log_util.h"
#include "trace.h"
#ifndef CONFIG_AIRPLAY_NAME
@@ -28,6 +29,7 @@ log_level util_loglevel;
static log_level *loglevel = &raop_loglevel;
static struct raop_ctx_s *raop;
static raop_cmd_vcb_t cmd_handler_chain;
static void raop_volume_up(void) {
raop_cmd(raop, RAOP_VOLUME_UP, NULL);
@@ -78,11 +80,52 @@ const static actrls_t controls = {
};
/****************************************************************************************
* Airplay taking/giving audio system's control
* Command handler
*/
void raop_master(bool on) {
if (on) actrls_set(controls, NULL);
else actrls_unset();
static bool cmd_handler(raop_event_t event, ...) {
va_list args;
va_start(args, event);
// handle audio event and stop if forbidden
if (!cmd_handler_chain(event, args)) {
va_end(args);
return false;
}
// now handle events for display
switch(event) {
case RAOP_SETUP:
actrls_set(controls, NULL);
displayer_control(DISPLAYER_ACTIVATE, "AIRPLAY");
break;
case RAOP_PLAY:
displayer_control(DISPLAYER_TIMER_RUN);
break;
case RAOP_FLUSH:
displayer_control(DISPLAYER_TIMER_PAUSE);
break;
case RAOP_STOP:
actrls_unset();
displayer_control(DISPLAYER_SUSPEND);
break;
case RAOP_METADATA: {
char *artist = va_arg(args, char*), *album = va_arg(args, char*), *title = va_arg(args, char*);
displayer_metadata(artist, album, title);
break;
}
case RAOP_PROGRESS: {
int elapsed = va_arg(args, int), duration = va_arg(args, int);
displayer_timer(DISPLAYER_ELAPSED, elapsed, duration);
break;
}
default:
break;
}
va_end(args);
return true;
}
/****************************************************************************************
@@ -96,7 +139,7 @@ void raop_sink_deinit(void) {
/****************************************************************************************
* Airplay sink initialization
*/
void raop_sink_init(raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb) {
void raop_sink_init(raop_cmd_vcb_t cmd_cb, raop_data_cb_t data_cb) {
const char *hostname;
char sink_name[64-6] = CONFIG_AIRPLAY_NAME;
tcpip_adapter_ip_info_t ipInfo;
@@ -123,7 +166,8 @@ void raop_sink_init(raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb) {
// create RAOP instance, latency is set by controller
uint8_t mac[6];
esp_read_mac(mac, ESP_MAC_WIFI_STA);
raop = raop_create(host, sink_name, mac, 0, cmd_cb, data_cb);
cmd_handler_chain = cmd_cb;
raop = raop_create(host, sink_name, mac, 0, cmd_handler, data_cb);
}
/****************************************************************************************
@@ -131,6 +175,7 @@ void raop_sink_init(raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb) {
*/
void raop_disconnect(void) {
LOG_INFO("forced disconnection");
displayer_control(DISPLAYER_SHUTDOWN);
raop_cmd(raop, RAOP_STOP, NULL);
actrls_unset();
}

View File

@@ -10,31 +10,28 @@
#define RAOP_SINK_H
#include <stdint.h>
#include <stdarg.h>
#define RAOP_SAMPLE_RATE 44100
typedef enum { RAOP_SETUP, RAOP_STREAM, RAOP_PLAY, RAOP_FLUSH, RAOP_PAUSE, RAOP_STOP,
typedef enum { RAOP_SETUP, RAOP_STREAM, RAOP_PLAY, RAOP_FLUSH, RAOP_METADATA, RAOP_PROGRESS, RAOP_PAUSE, RAOP_STOP,
RAOP_VOLUME, RAOP_TIMING, RAOP_PREV, RAOP_NEXT, RAOP_REW, RAOP_FWD,
RAOP_VOLUME_UP, RAOP_VOLUME_DOWN, RAOP_RESUME, RAOP_TOGGLE } raop_event_t ;
typedef bool (*raop_cmd_cb_t)(raop_event_t event, void *param);
typedef bool (*raop_cmd_cb_t)(raop_event_t event, ...);
typedef bool (*raop_cmd_vcb_t)(raop_event_t event, va_list args);
typedef void (*raop_data_cb_t)(const u8_t *data, size_t len, u32_t playtime);
/**
* @brief init sink mode (need to be provided)
*/
void raop_sink_init(raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb);
void raop_sink_init(raop_cmd_vcb_t cmd_cb, raop_data_cb_t data_cb);
/**
* @brief deinit sink mode (need to be provided)
*/
void raop_sink_deinit(void);
/**
* @brief do what's necessary when becoming in charge
*/
void raop_master(bool on);
/**
* @brief force disconnection
*/

View File

@@ -429,7 +429,7 @@ static void buffer_put_packet(rtp_t *ctx, seq_t seqno, unsigned rtptime, bool fi
ctx->ab_read = seqno;
ctx->flush_seqno = -1;
ctx->playing = true;
ctx->resent_req = ctx->resent_rec = ctx->silent_frames = ctx->discarded = 0;
ctx->resent_req = ctx->resent_rec = ctx->silent_frames = ctx->discarded = 0;
playtime = ctx->synchro.time + (((s32_t)(rtptime - ctx->synchro.rtp)) * 1000) / RAOP_SAMPLE_RATE;
ctx->cmd_cb(RAOP_PLAY, playtime);
} else {
@@ -671,7 +671,7 @@ static void *rtp_thread_func(void *arg) {
if (!count--) {
rtp_request_timing(ctx);
count = 3;
count = 3;
}
if ((ctx->synchro.status & RTP_SYNC) && (ctx->synchro.status & NTP_SYNC)) ctx->cmd_cb(RAOP_TIMING);

View File

@@ -47,11 +47,8 @@ typedef struct metadata_s {
u8_t channels;
} metadata_t;
/*
void free_metadata(struct metadata_s *metadata);
void dup_metadata(struct metadata_s *dst, struct metadata_s *src);
*/
u32_t gettime_ms(void);