/// // // server.h // Call server_init() to start up an http webserver. // listens on '/' for POST queries with a url query format like // ?l=*&r0=*&g0=*&b0=*&a0=*&t0=* ... &rl=*&gl=*&bl=*&al=*&tl=* // Where l is the number of points on a gradient. And each point of the gradient has a r* g* b* a* and t* where * is the index. // r g and b are the red green and blue 8-bit colour components of a point on the gradient. A is the 5-bit global component of the led at that point. // t is the offset from the start measured in leds. // /// #ifndef _potion_party_server_h #define _potion_party_server_h #include #include #include #include "shared.h" #include "leds.h" #include "esp_http_server.h" #include "esp_system.h" #include "esp_netif.h" #include "sys_arch.h" static httpd_handle_t g_http_server = NULL; // Parse a gradient query static void parse_leds_query(char* query_string, size_t query_size) { char query_value[16]; char query_key[3]; size_t gradient_point_count = 0; if(httpd_query_key_value(query_string, "l", query_value, sizeof(query_value)) == ESP_OK) { gradient_point_count = atoi(query_value); } else { return; } struct gradient_point_t* points = malloc(gradient_point_count * sizeof(union led_t)); for(int point = 0; point < gradient_point_count; ++point) { sprintf(query_key, "r%d", point); if(httpd_query_key_value(query_string, query_key, query_value, sizeof(query_size)) == ESP_OK) { points[point].led.components.red = atoi(query_value); } sprintf(query_key, "g%d", point); if(httpd_query_key_value(query_string, query_key, query_value, sizeof(query_size)) == ESP_OK) { points[point].led.components.green = atoi(query_value); } sprintf(query_key, "b%d", point); if(httpd_query_key_value(query_string, query_key, query_value, sizeof(query_value)) == ESP_OK) { points[point].led.components.blue = atoi(query_value); } sprintf(query_key, "a%d", point); if(httpd_query_key_value(query_string, query_key, query_value, sizeof(query_value)) == ESP_OK) { points[point].led.components.global = GLOBAL(atoi(query_value)); } sprintf(query_key, "t%d", point); if(httpd_query_key_value(query_string, query_key, query_value, sizeof(query_value)) == ESP_OK) { points[point].offset = atoi(query_value); } LOGLN("led %d:", point); LOGLN(" r %d", points[point].led.components.red); LOGLN(" g %d", points[point].led.components.green); LOGLN(" b %d", points[point].led.components.blue); LOGLN(" global %d", points[point].led.components.global >> 3); LOGLN(" t %d", (int)points[point].offset); } leds_set_gradient(points, gradient_point_count, 1); } // receives HTTP POST requests on root static esp_err_t on_http_post(httpd_req_t* request) { LOGLN("POST received on '/'."); char* buffer; size_t buffer_len; buffer_len = httpd_req_get_url_query_len(request) + 1; if(buffer_len > 1) { buffer = malloc(buffer_len * sizeof(char)); if(httpd_req_get_url_query_str(request, buffer, buffer_len) == ESP_OK) { LOGLN("Received query."); parse_leds_query(buffer, buffer_len); } } const char* response = "OK!"; httpd_resp_send(request, response, strlen(response)); return ESP_OK; } httpd_uri_t post = { .uri="/", .method=HTTP_POST, .handler=&on_http_post, .user_ctx = NULL }; // Configure and enable the http server. 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, &post); return server; } LOGLN("Failed to start HTTPd server."); return NULL; } // Start an http server and store it's handle in g_http_server. static void server_init(void) { g_http_server = start_webserver(); } #endif // !_potion_party_server_h