From bb4bbdc6ea5dc462d39e841485eabd569cafd97d Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Thu, 7 Jul 2022 15:14:39 +0200 Subject: [PATCH] Be flexible on setting camera params --- cmd/camera-streamer.c | 41 +++++++++++++++++++++++++++++++++-------- http/http.c | 34 ++++++++++++++++++++++++++++++++++ http/http.h | 2 ++ 3 files changed, 69 insertions(+), 8 deletions(-) diff --git a/cmd/camera-streamer.c b/cmd/camera-streamer.c index 79b9e3d..da294f0 100644 --- a/cmd/camera-streamer.c +++ b/cmd/camera-streamer.c @@ -16,18 +16,43 @@ extern unsigned int html_jmuxer_min_js_len; camera_t *camera; -void camera_http_option(http_worker_t *worker, FILE *stream) +void *camera_http_set_option(http_worker_t *worker, FILE *stream, const char *key, const char *value, void *headersp) { - if (strstr(worker->client_method, "autofocus")) { - if (camera && !device_set_option_string(camera->camera, "AfTrigger", "1")) { - http_200(stream, "Auto-focus triggered.\r\n"); - } else { - http_500(stream, "Cannot set auto-focus.\r\n"); + bool *headers = headersp; + + if (!camera) { + if (!*headers) { + http_500(stream, ""); + *headers = true; } - return; + fprintf(stream, "No camera attached.\r\n"); + return NULL; } - http_404(stream, "No option found.\r\n"); + if (device_set_option_string(camera->camera, key, value) == 0) { + if (!*headers) { + http_200(stream, ""); + *headers = true; + } + fprintf(stream, "The '%s' was set to '%s'.\r\n", key, value); + } else { + if (!*headers) { + http_500(stream, ""); + *headers = true; + } + fprintf(stream, "Cannot set '%s' to '%s'.\r\n", key, value); + } + + return NULL; +} + +void camera_http_option(http_worker_t *worker, FILE *stream) +{ + bool headers = false; + http_enum_params(worker, stream, camera_http_set_option, &headers); + if (!headers) { + http_404(stream, "No options passed.\r\n"); + } } http_method_t http_methods[] = { diff --git a/http/http.c b/http/http.c index 6990166..d34abaa 100644 --- a/http/http.c +++ b/http/http.c @@ -52,6 +52,40 @@ error: return -1; } +void *http_enum_params(http_worker_t *worker, FILE *stream, http_param_fn fn, void *opaque) +{ + const char *params = strstr(worker->client_method, "?"); + if (!params) { + return NULL; + } + + void *ret = NULL; + char *start = strdup(params + 1); + char *string = start; + char *option; + + // Drop after ` ` + if ((option = strstr(start, " ")) != NULL) { + *option = 0; + } + + while ((option = strsep(&string, "&")) != NULL) { + char *value = option; + char *key = strsep(&value, "="); + + ret = fn(worker, stream, key, value, opaque); + if (ret) { + break; + } + + // consume all separators + while (strsep(&value, "=")); + } + + free(start); + return ret; +} + static void http_process(http_worker_t *worker, FILE *stream) { // Read headers diff --git a/http/http.h b/http/http.h index e36d639..319ee1d 100644 --- a/http/http.h +++ b/http/http.h @@ -11,6 +11,7 @@ typedef struct buffer_s buffer_t; typedef struct http_worker_s http_worker_t; typedef void (*http_method_fn)(struct http_worker_s *worker, FILE *stream); +typedef void *(*http_param_fn)(struct http_worker_s *worker, FILE *stream, const char *key, const char *value, void *opaque); #define BUFSIZE 256 @@ -48,6 +49,7 @@ void http_content(http_worker_t *worker, FILE *stream); void http_200(FILE *stream, const char *data); void http_404(FILE *stream, const char *data); void http_500(FILE *stream, const char *data); +void *http_enum_params(http_worker_t *worker, FILE *stream, http_param_fn fn, void *opaque); // M-JPEG void http_snapshot(http_worker_t *worker, FILE *stream);