#include "server.h" #include #include #include #include "shared.h" #include "leds.h" #include "parse.h" #include #include #include #include const char* http_response_ok = "OK!"; static httpd_handle_t g_http_server = NULL; // convert a (valid) request as described in api-doc.txt to a gradient. static struct result_t request_to_gradient(httpd_req_t* request) { // buffer for query string char* query_buffer; size_t query_length = httpd_req_get_url_query_len(request) + 1; struct result_t result = { .error = NULL }; if(query_length > 1) { query_buffer = malloc(query_length * sizeof(char)); if(httpd_req_get_url_query_str(request, query_buffer, query_length) == ESP_OK) { LOGLN("Received query."); result = parse_leds_query(query_buffer, query_length); } free(query_buffer); } return result; } // receives HTTP GET requests on root static esp_err_t on_http_get_root(httpd_req_t* request) { const char* response_msg = http_response_ok; LOGLN("GET received on '/next'."); // convert the request url to a gradient struct result_t result = request_to_gradient(request); // an error was returned, pass it on to the API caller if(!result.is_ok) { httpd_resp_set_status(request, "400 Bad Request"); response_msg = result.error; } else { // grab a lock on the leds data xSemaphoreTake(g_led_mutex, portMAX_DELAY); // modify leds data leds_set_current_gradient(result.ok, 0); // release lock xSemaphoreGive(g_led_mutex); // request to gradient allocates the gradient on the heap, // we can free that after use free(result.ok); } // respond to http caller httpd_resp_send(request, response_msg, strlen(response_msg)); return ESP_OK; } httpd_uri_t get_root_uri = { .uri="/", .method=HTTP_GET, .handler=&on_http_get_root, .user_ctx = NULL }; static esp_err_t on_http_get_default(httpd_req_t* request) { const char* response_msg = http_response_ok; LOGLN("GET received on '/default'."); // convert the request to a gradient object struct result_t result = request_to_gradient(request); // handle invalid query if(!result.is_ok) { httpd_resp_set_status(request, "400 Bad Request"); response_msg = result.error; } else { // set default gradient // take lock on leds data xSemaphoreTake(g_led_mutex, portMAX_DELAY); leds_set_default_gradient(result.ok); // release lock on leds data xSemaphoreGive(g_led_mutex); // we allocated a gradient_t struct with request_to_gradient, // we no longer need it so we'll free it asap free(result.ok); } // send http response httpd_resp_send(request, response_msg, strlen(response_msg)); return ESP_OK; } httpd_uri_t get_default_uri = { .uri="/default", .method=HTTP_GET, .handler=&on_http_get_default, .user_ctx=NULL }; // Configure server and enable the http handler. static httpd_handle_t start_webserver(void) { httpd_handle_t server = NULL; httpd_config_t server_config = HTTPD_DEFAULT_CONFIG(); LOGLN("Starting HTTPd server ':%d'.", server_config.server_port); if(httpd_start(&server, &server_config) == ESP_OK) { httpd_register_uri_handler(server, &get_root_uri); httpd_register_uri_handler(server, &get_default_uri); return server; } LOGLN("Failed to start HTTPd server."); return NULL; } // Start an http server and store it's handle in g_http_server. void server_init(void) { g_http_server = start_webserver(); }