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

Conflicts:
	components/raop/raop.c
	components/raop/rtp.c
	main/cmd_squeezelite.c
This commit is contained in:
Sebastien
2020-03-08 09:54:50 -04:00
48 changed files with 951 additions and 481 deletions

View File

@@ -44,7 +44,7 @@
#include "log_util.h"
#define RTSP_STACK_SIZE (8*1024)
#define SEARCH_STACK_SIZE (2*1048)
#define SEARCH_STACK_SIZE (3*1048)
typedef struct raop_ctx_s {
#ifdef WIN32
@@ -57,9 +57,9 @@ typedef struct raop_ctx_s {
struct in_addr peer; // IP of the iDevice (airplay sender)
bool running;
#ifdef WIN32
pthread_t thread, search_thread;
pthread_t thread;
#else
TaskHandle_t thread, search_thread, joiner;
TaskHandle_t thread, joiner;
StaticTask_t *xTaskBuffer;
StackType_t xStack[RTSP_STACK_SIZE] __attribute__ ((aligned (4)));
#endif
@@ -81,11 +81,12 @@ typedef struct raop_ctx_s {
char DACPid[32], id[32];
struct in_addr host;
u16_t port;
bool running;
#ifdef WIN32
struct mDNShandle_s *handle;
pthread_t thread;
#else
bool running;
TaskHandle_t thread, joiner;
TaskHandle_t thread;
StaticTask_t *xTaskBuffer;
StackType_t xStack[SEARCH_STACK_SIZE] __attribute__ ((aligned (4)));;
SemaphoreHandle_t destroy_mutex;
@@ -99,7 +100,7 @@ extern log_level raop_loglevel;
static log_level *loglevel = &raop_loglevel;
static void* rtsp_thread(void *arg);
static void abort_rtsp(raop_ctx_t *ctx);
static void cleanup_rtsp(raop_ctx_t *ctx, bool abort);
static bool handle_rtsp(raop_ctx_t *ctx, int sock);
static char* rsa_apply(unsigned char *input, int inlen, int *outlen, int mode);
@@ -218,7 +219,7 @@ void raop_delete(struct raop_ctx_s *ctx) {
}
/*----------------------------------------------------------------------------*/
void raop_delete(struct raop_ctx_s *ctx) {
void raop_delete(struct raop_ctx_s *ctx) {
#ifdef WIN32
int sock;
struct sockaddr addr;
@@ -240,25 +241,13 @@ void raop_delete(struct raop_ctx_s *ctx) {
rtp_end(ctx->rtp);
shutdown(ctx->sock, SD_BOTH);
shutdown(ctx->sock, SD_BOTH);
closesocket(ctx->sock);
// terminate search, but do not reclaim memory of pthread if never launched
if (ctx->active_remote.handle) {
close_mDNS(ctx->active_remote.handle);
pthread_join(ctx->active_remote.thread, NULL);
}
// stop broadcasting devices
mdns_service_remove(ctx->svr, ctx->svc);
mdnsd_stop(ctx->svr);
#else
// first stop the search task if any
if (ctx->active_remote.running) {
ctx->active_remote.joiner = xTaskGetCurrentTaskHandle();
ctx->active_remote.running = false;
vTaskResume(ctx->active_remote.thread);
}
// stop broadcasting devices
@@ -267,10 +256,11 @@ void raop_delete(struct raop_ctx_s *ctx) {
#else
// then the RTSP task
ctx->joiner = xTaskGetCurrentTaskHandle();
ctx->running = false;
ctx->running = false;
ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
vTaskDelete(ctx->thread);
heap_caps_free(ctx->xTaskBuffer);
shutdown(ctx->sock, SHUT_RDWR);
closesocket(ctx->sock);
@@ -405,7 +395,7 @@ static void *rtsp_thread(void *arg) {
FD_SET(sock, &rfds);
n = select(sock + 1, &rfds, NULL, NULL, &timeout);
if (!n && !ctx->abort) continue;
if (n > 0) res = handle_rtsp(ctx, sock);
@@ -515,10 +505,10 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
NFREE(p);
}
// on announce, search remote
// on announce, search remote
if ((buf = kd_lookup(headers, "DACP-ID")) != NULL) strcpy(ctx->active_remote.DACPid, buf);
if ((buf = kd_lookup(headers, "Active-Remote")) != NULL) strcpy(ctx->active_remote.id, buf);
#ifdef WIN32
ctx->active_remote.handle = init_mDNS(false, ctx->host);
pthread_create(&ctx->active_remote.thread, NULL, &search_remote, ctx);
@@ -580,37 +570,14 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
unsigned short seqno = 0;
unsigned rtptime = 0;
char *p;
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);
// only send FLUSH if useful (discards frames above buffer head and top)
if (ctx->rtp && rtp_flush(ctx->rtp, seqno, rtptime, true)) {
// only send FLUSH if useful (discards frames above buffer head and top)
if (ctx->rtp && rtp_flush(ctx->rtp, seqno, rtptime))
success = ctx->cmd_cb(RAOP_FLUSH);
} else if (!strcmp(method, "TEARDOWN")) {
rtp_end(ctx->rtp);
ctx->rtp = NULL;
// need to make sure no search is on-going and reclaim pthread memory
#ifdef WIN32
if (ctx->active_remote.handle) close_mDNS(ctx->active_remote.handle);
pthread_join(ctx->search_thread, NULL);
#else
ctx->active_remote.joiner = xTaskGetCurrentTaskHandle();
ctx->active_remote.running = false;
xSemaphoreTake(ctx->active_remote.destroy_mutex, portMAX_DELAY);
vTaskDelete(ctx->active_remote.thread);
vSemaphoreDelete(ctx->active_remote.thread);
heap_caps_free(ctx->active_remote.xTaskBuffer);
LOG_INFO("[%p]: mDNS search task terminated", ctx);
#endif
success = ctx->cmd_cb(RAOP_FLUSH);
rtp_flush_release(ctx->rtp);
}
@@ -631,18 +598,16 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
success = ctx->cmd_cb(RAOP_VOLUME, volume);
} else if (body && (p = strcasestr(body, "progress")) != NULL) {
int start, current, stop = 0;
// we want ms, not s
sscanf(p, "%*[^:]:%u/%u/%u", &start, &current, &stop);
current = ((current - start) / 44100) * 1000;
if (stop) stop = ((stop - start) / 44100) * 1000;
// we want ms, not s
sscanf(p, "%*[^:]:%u/%u/%u", &start, &current, &stop);
current = ((current - start) / 44100) * 1000;
if (stop) stop = ((stop - start) / 44100) * 1000;
else stop = -1;
LOG_INFO("[%p]: SET PARAMETER progress %d/%u %s", ctx, current, stop, p);
success = ctx->cmd_cb(RAOP_PROGRESS, max(current, 0), stop);
} else if (body && ((p = kd_lookup(headers, "Content-Type")) != NULL) && !strcasecmp(p, "application/x-dmap-tagged")) {
struct metadata_s metadata;
struct metadata_s metadata;
dmap_settings settings = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, on_dmap_string, NULL,
NULL
@@ -651,6 +616,10 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
LOG_INFO("[%p]: received metadata", ctx);
settings.ctx = &metadata;
memset(&metadata, 0, sizeof(struct metadata_s));
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);
}
} else {
@@ -678,26 +647,28 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
NFREE(body);
NFREE(buf);
kd_free(resp);
kd_free(headers);
kd_free(headers);
return true;
}
/*----------------------------------------------------------------------------*/
void abort_rtsp(raop_ctx_t *ctx) {
/*----------------------------------------------------------------------------*/
void cleanup_rtsp(raop_ctx_t *ctx, bool abort) {
// first stop RTP process
if (ctx->rtp) {
rtp_end(ctx->rtp);
ctx->rtp = NULL;
if (abort) LOG_INFO("[%p]: RTP thread aborted", ctx);
}
ctx->rtp = NULL;
if (ctx->active_remote.running) {
}
#ifdef WIN32
pthread_join(ctx->active_remote.thread, NULL);
close_mDNS(ctx->active_remote.handle);
#else
// need to make sure no search is on-going and reclaim task memory
ctx->active_remote.running = false;
xSemaphoreTake(ctx->active_remote.destroy_mutex, portMAX_DELAY);
xSemaphoreTake(ctx->active_remote.destroy_mutex, portMAX_DELAY);
vTaskDelete(ctx->active_remote.thread);
vSemaphoreDelete(ctx->active_remote.thread);
@@ -767,7 +738,7 @@ static void* search_remote(void *args) {
if (r) {
for (a = r->addr; a && a->addr.type != IPADDR_TYPE_V4; a = a->next);
if (a) {
found = true;
found = true;
ctx->active_remote.host.s_addr = a->addr.u_addr.ip4.addr;
ctx->active_remote.port = r->port;
LOG_INFO("found remote %s %s:%hu", r->instance_name, inet_ntoa(ctx->active_remote.host), ctx->active_remote.port);
@@ -947,9 +918,8 @@ static unsigned int token_decode(const char *token)
return DECODE_ERROR;
for (i = 0; i < 4; i++) {
val *= 64;
if (token[i] == '=')
marker++;
else if (marker > 0)
if (token[i] == '=')
marker++;
else if (marker > 0)
return DECODE_ERROR;
else