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

Conflicts:
	Makefile
	components/wifi-manager/index.html
This commit is contained in:
Sebastien
2020-02-19 08:14:49 -05:00
40 changed files with 1009 additions and 387 deletions

View File

@@ -55,7 +55,7 @@ typedef struct raop_ctx_s {
short unsigned port; // RTSP port for AirPlay
int sock; // socket of the above
struct in_addr peer; // IP of the iDevice (airplay sender)
bool running;
bool running, abort;
#ifdef WIN32
pthread_t thread, search_thread;
#else
@@ -83,6 +83,7 @@ typedef struct raop_ctx_s {
TaskHandle_t thread, joiner;
StaticTask_t *xTaskBuffer;
StackType_t xStack[SEARCH_STACK_SIZE] __attribute__ ((aligned (4)));;
SemaphoreHandle_t destroy_mutex;
#endif
} active_remote;
void *owner;
@@ -93,6 +94,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 bool handle_rtsp(raop_ctx_t *ctx, int sock);
static char* rsa_apply(unsigned char *input, int inlen, int *outlen, int mode);
@@ -198,6 +200,12 @@ struct raop_ctx_s *raop_create(struct in_addr host, char *name,
ESP_ERROR_CHECK( mdns_service_add(id, "_raop", "_tcp", ctx->port, txt, sizeof(txt) / sizeof(mdns_txt_item_t)) );
ctx->xTaskBuffer = (StaticTask_t*) heap_caps_malloc(sizeof(StaticTask_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
ctx->thread = xTaskCreateStatic( (TaskFunction_t) rtsp_thread, "RTSP_thread", RTSP_STACK_SIZE, ctx, ESP_TASK_PRIO_MIN + 1, ctx->xStack, ctx->xTaskBuffer);
#endif
return ctx;
}
/*----------------------------------------------------------------------------*/
void raop_abort(struct raop_ctx_s *ctx) {
LOG_INFO("[%p]: aborting RTSP session at next select() wakeup", ctx);
@@ -270,7 +278,7 @@ if (!ctx) return;
NFREE(ctx->rtsp.aeskey);
NFREE(ctx->rtsp.aesiv);
NFREE(ctx->rtsp.fmtp);
NFREE(ctx->rtsp.fmtp);
free(ctx);
}
@@ -323,7 +331,7 @@ void raop_cmd(struct raop_ctx_s *ctx, raop_event_t event, void *param) {
break;
}
default:
break;
break;
}
// no command to send to remote or no remote found yet
@@ -354,6 +362,8 @@ void raop_cmd(struct raop_ctx_s *ctx, raop_event_t event, void *param) {
LOG_INFO("[%p]: sending airplay remote\n%s<== received ==>\n%s", ctx, buf, resp);
NFREE(method);
NFREE(buf);
kd_free(headers);
}
free(command);
@@ -373,6 +383,7 @@ static void *rtsp_thread(void *arg) {
int n;
bool res = false;
if (sock == -1) {
struct sockaddr_in peer;
socklen_t addrlen = sizeof(struct sockaddr_in);
@@ -383,12 +394,13 @@ static void *rtsp_thread(void *arg) {
if (sock != -1 && ctx->running) {
LOG_INFO("got RTSP connection %u", sock);
} else continue;
}
}
FD_ZERO(&rfds);
FD_SET(sock, &rfds);
n = select(sock + 1, &rfds, NULL, NULL, &timeout);
n = select(sock + 1, &rfds, NULL, NULL, &timeout);
if (!n && !ctx->abort) continue;
if (n > 0) res = handle_rtsp(ctx, sock);
@@ -460,27 +472,6 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
kd_add(resp, "Public", "ANNOUNCE, SETUP, RECORD, PAUSE, FLUSH, TEARDOWN, OPTIONS, GET_PARAMETER, SET_PARAMETER");
} else if (!strcmp(method, "ANNOUNCE")) {
char *padded, *p;
NFREE(ctx->rtsp.aeskey);
NFREE(ctx->rtsp.aesiv);
NFREE(ctx->rtsp.fmtp);
// LMS might has taken over the player, leaving us with a running RTP session (should not happen)
if (ctx->rtp) {
LOG_WARN("[%p]: closing unfinished RTP session", ctx);
rtp_end(ctx->rtp);
}
// same, should not happen unless we have missed a teardown ...
if (ctx->active_remote.running) {
ctx->active_remote.joiner = xTaskGetCurrentTaskHandle();
ctx->active_remote.running = false;
vTaskResume(ctx->active_remote.thread);
ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
vTaskDelete(ctx->active_remote.thread);
} else if (!strcmp(method, "ANNOUNCE")) {
char *padded, *p;
@@ -522,6 +513,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
// 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->search_thread, NULL, &search_remote, ctx);
@@ -600,11 +592,10 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
// 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
if (ctx->active_remote.handle) close_mDNS(ctx->active_remote.handle);
pthread_join(ctx->search_thread, NULL);
ctx->active_remote.running = false;
#else
ctx->active_remote.joiner = xTaskGetCurrentTaskHandle();
ctx->active_remote.running = false;
xSemaphoreTake(ctx->active_remote.destroy_mutex, portMAX_DELAY);
@@ -681,6 +672,35 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
NFREE(body);
NFREE(buf);
kd_free(resp);
kd_free(headers);
return true;
}
/*----------------------------------------------------------------------------*/
void abort_rtsp(raop_ctx_t *ctx) {
// first stop RTP process
if (ctx->rtp) {
rtp_end(ctx->rtp);
ctx->rtp = NULL;
LOG_INFO("[%p]: RTP thread aborted", ctx);
}
if (ctx->active_remote.running) {
// need to make sure no search is on-going and reclaim task memory
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);
memset(&ctx->active_remote, 0, sizeof(ctx->active_remote));
LOG_INFO("[%p]: Remote search thread aborted", ctx);
}
NFREE(ctx->rtsp.aeskey);
NFREE(ctx->rtsp.aesiv);
@@ -746,20 +766,10 @@ static void* search_remote(void *args) {
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);
}
}
mdns_query_results_free(results);
}
/*
for some reason which is beyond me, if that tasks gives the semaphore
before the RTSP tasks waits for it, then freeRTOS crashes in queue
management caused by LWIP stack once the RTSP socket is closed. I have
no clue why, but so we'll suspend the tasks as soon as we're done with
search and wait for the resume then give the semaphore
}
}
// PS: I know this is not fully race-condition free
mdns_query_results_free(results);
}
// can't use xNotifyGive as it seems LWIP is using it as well

View File

@@ -27,6 +27,7 @@
struct raop_ctx_s* raop_create(struct in_addr host, char *name, unsigned char mac[6], int latency,
raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb);
void raop_delete(struct raop_ctx_s *ctx);
void raop_cmd(struct raop_ctx_s *ctx, raop_event_t event, void *param);
void raop_abort(struct raop_ctx_s *ctx);
bool raop_cmd(struct raop_ctx_s *ctx, raop_event_t event, void *param);
#endif

View File

@@ -178,6 +178,7 @@ void raop_sink_init(raop_cmd_vcb_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);
// in case we can't communicate with AirPlay controller, abort session
if (!raop_cmd(raop, RAOP_STOP, NULL)) raop_abort(raop);
actrls_unset();
}