rework nohold option for compatibilty with future video streaming

This commit is contained in:
F. Duncanh
2024-07-17 13:47:15 -04:00
parent 75d64e6b1e
commit c628dd16a6
5 changed files with 42 additions and 19 deletions

View File

@@ -214,21 +214,6 @@ httpd_accept_connection(httpd_t *httpd, int server_fd, int is_ipv6)
remote = netutils_get_address(&remote_saddr, &remote_len, &remote_zone_id);
assert (local_zone_id == remote_zone_id);
/* remove existing connections to make way for new connections, if http->nohold is set:
* this will only occur if open_connections >= 2 and a connection with CONNECTION_TYPE_RAOP already exists */
if (httpd->nohold && httpd->open_connections >= 2) {
if (httpd_count_connection_type(httpd, CONNECTION_TYPE_RAOP)) {
logger_log(httpd->logger, LOGGER_INFO, "Destroying current connections to allow connection by new client");
for (int i = 0; i<httpd->max_connections; i++) {
http_connection_t *connection = &httpd->connections[i];
if (!connection->connected) {
continue;
}
httpd_remove_connection(httpd, connection);
}
}
}
ret = httpd_add_connection(httpd, fd, local, local_len, remote, remote_len, local_zone_id);
if (ret == -1) {
shutdown(fd, SHUT_RDWR);
@@ -238,6 +223,22 @@ httpd_accept_connection(httpd_t *httpd, int server_fd, int is_ipv6)
return 1;
}
bool
httpd_nohold(httpd_t *httpd) {
return (httpd->nohold ? true: false);
}
void
httpd_remove_known_connections(httpd_t *httpd) {
for (int i = 0; i < httpd->max_connections; i++) {
http_connection_t *connection = &httpd->connections[i];
if (!connection->connected || connection->type == CONNECTION_TYPE_UNKNOWN) {
continue;
}
httpd_remove_connection(httpd, connection);
}
}
static THREAD_RETVAL
httpd_thread(void *arg)
{

View File

@@ -34,6 +34,8 @@ struct httpd_callbacks_s {
void (*conn_destroy)(void *ptr);
};
typedef struct httpd_callbacks_s httpd_callbacks_t;
bool httpd_nohold(httpd_t *httpd);
void httpd_remove_known_connections(httpd_t *httpd);
int httpd_set_connection_type (httpd_t *http, void *user_data, connection_type_t type);
int httpd_count_connection_type (httpd_t *http, connection_type_t type);

View File

@@ -174,10 +174,20 @@ conn_request(void *ptr, http_request_t *request, http_response_t **response) {
if (httpd_count_connection_type(conn->raop->httpd, CONNECTION_TYPE_RAOP)) {
char ipaddr[40];
utils_ipaddress_to_string(conn->remotelen, conn->remote, conn->zone_id, ipaddr, (int) (sizeof(ipaddr)));
logger_log(conn->raop->logger, LOGGER_WARNING, "rejecting new connection request from %s", ipaddr);
*response = http_response_create();
http_response_init(*response, protocol, 409, "Conflict: Server is connected to another client");
goto finish;
if (httpd_nohold(conn->raop->httpd)) {
logger_log(conn->raop->logger, LOGGER_INFO, "\"nohold\" feature: switch to new connection request from %s", ipaddr);
if (conn->raop->callbacks.video_reset) {
printf("**************************video_reset*************************\n");
conn->raop->callbacks.video_reset(conn->raop->callbacks.cls);
}
httpd_remove_known_connections(conn->raop->httpd);
} else {
logger_log(conn->raop->logger, LOGGER_WARNING, "rejecting new connection request from %s", ipaddr);
*response = http_response_create();
http_response_init(*response, protocol, 409, "Conflict: Server is connected to another client");
goto finish;
}
}
httpd_set_connection_type(conn->raop->httpd, ptr, CONNECTION_TYPE_RAOP);
conn->connection_type = CONNECTION_TYPE_RAOP;

View File

@@ -63,6 +63,7 @@ struct raop_callbacks_s {
void (*register_client) (void *cls, const char *device_id, const char *pk_str, const char *name);
bool (*check_register) (void *cls, const char *pk_str);
void (*export_dacp) (void *cls, const char *active_remote, const char *dacp_id);
void (*video_reset) (void *cls);
};
typedef struct raop_callbacks_s raop_callbacks_t;
raop_ntp_t *raop_ntp_init(logger_t *logger, raop_callbacks_t *callbacks, const char *remote,

View File

@@ -1450,6 +1450,14 @@ static bool check_blocked_client(char *deviceid) {
// Server callbacks
extern "C" void video_reset(void *cls) {
reset_loop = true;
remote_clock_offset = 0;
relaunch_video = true;
}
extern "C" void display_pin(void *cls, char *pin) {
int margin = 10;
int spacing = 3;
@@ -1817,6 +1825,7 @@ static int start_raop_server (unsigned short display[5], unsigned short tcp[3],
raop_cbs.register_client = register_client;
raop_cbs.check_register = check_register;
raop_cbs.export_dacp = export_dacp;
raop_cbs.video_reset = video_reset;
raop = raop_init(&raop_cbs);
if (raop == NULL) {