150 lines
5.0 KiB
C
150 lines
5.0 KiB
C
#include "server.h"
|
|
#include "esp_http_server.h"
|
|
#include "epd.h"
|
|
#include "esp_heap_caps.h"
|
|
#include "settings.h"
|
|
|
|
#define WRITE_HEADER(req, buffer, name, format, src) \
|
|
sprintf(buffer, format, src); \
|
|
ESP_ERROR_CHECK(httpd_resp_set_hdr(req, name, buffer));
|
|
static esp_err_t http_index(httpd_req_t* req) {
|
|
EpdData data = n_epd_data();
|
|
char width[20], height[20], temperature[20];
|
|
WRITE_HEADER(req, width, "width", "%d", data.width);
|
|
WRITE_HEADER(req, height, "height", "%d", data.height);
|
|
WRITE_HEADER(req, temperature, "temperature", "%d", data.temperature);
|
|
const char* response = "Hello! Check headers\n";
|
|
httpd_resp_set_type(req, "text/plain");
|
|
httpd_resp_set_status(req, "200");
|
|
httpd_resp_send(req, response, HTTPD_RESP_USE_STRLEN);
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t http_clear(httpd_req_t* req) {
|
|
ESP_LOGI(__FUNCTION__, "Clear\n");
|
|
n_epd_clear();
|
|
const char* response = "Cleared\n";
|
|
httpd_resp_set_type(req, "text/plain");
|
|
httpd_resp_set_status(req, "200");
|
|
httpd_resp_send(req, response, HTTPD_RESP_USE_STRLEN);
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t http_draw(httpd_req_t* req) {
|
|
// optional headers: x,y. Default to 0
|
|
// required headers: height, width
|
|
// Content should be a stream of special bytes - we're reading 4 bits at a time.
|
|
int x, y, width, height, clear;
|
|
char header[20];
|
|
memset(header, 0, 20);
|
|
if (httpd_req_get_hdr_value_str(req, "clear", header, 20) == ESP_OK) {
|
|
sscanf(header, "%d", &clear);
|
|
} else {
|
|
clear = 0;
|
|
}
|
|
if (httpd_req_get_hdr_value_str(req, "x", header, 20) == ESP_OK) {
|
|
sscanf(header, "%d", &x);
|
|
} else {
|
|
x = 0;
|
|
}
|
|
if (httpd_req_get_hdr_value_str(req, "y", header, 20) == ESP_OK) {
|
|
sscanf(header, "%d", &y);
|
|
} else {
|
|
y = 0;
|
|
}
|
|
if (httpd_req_get_hdr_value_str(req, "width", header, 20) == ESP_OK) {
|
|
sscanf(header, "%d", &width);
|
|
} else {
|
|
char response[60];
|
|
sprintf(response, "Missing header width");
|
|
httpd_resp_set_type(req, "text/plain");
|
|
httpd_resp_set_status(req, "400");
|
|
httpd_resp_send(req, response, HTTPD_RESP_USE_STRLEN);
|
|
return ESP_OK;
|
|
}
|
|
if (httpd_req_get_hdr_value_str(req, "height", header, 20) == ESP_OK) {
|
|
sscanf(header, "%d", &height);
|
|
} else {
|
|
char response[60];
|
|
sprintf(response, "Missing header height");
|
|
httpd_resp_set_type(req, "text/plain");
|
|
httpd_resp_set_status(req, "400");
|
|
httpd_resp_send(req, response, HTTPD_RESP_USE_STRLEN);
|
|
return ESP_OK;
|
|
}
|
|
|
|
// READING STREAM
|
|
int req_size = req->content_len;
|
|
char* content = (char*)heap_caps_malloc(req_size, MALLOC_CAP_SPIRAM);
|
|
if (content == NULL) {
|
|
char msg[50];
|
|
sprintf(msg, "Failed to allocate %d chars\n", req_size);
|
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, msg);
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
int current_pos = 0;
|
|
int amount_recieved;
|
|
while ((amount_recieved = httpd_req_recv(req, (content + current_pos), req_size)) > 0) {
|
|
ESP_LOGI(__FUNCTION__, "Read %d bytes\n", amount_recieved);
|
|
current_pos += amount_recieved;
|
|
}
|
|
if (amount_recieved < 0) {
|
|
char msg[50];
|
|
heap_caps_free(content);
|
|
ESP_LOGE(msg, "Failed to read byets. Error code %d\n", amount_recieved);
|
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, msg);
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
ESP_LOGI(__FUNCTION__, "Done reading %d bytes out of %d\n", current_pos, req_size);
|
|
|
|
if (clear) {
|
|
n_epd_clear();
|
|
}
|
|
n_epd_draw(((uint8_t*)content), x, y, width, height);
|
|
heap_caps_free(content);
|
|
|
|
// Done reading
|
|
char response[100];
|
|
sprintf(
|
|
response, "x %d, y %d, width %d, height %d, byte count %d\n", x, y, width, height, req_size
|
|
);
|
|
httpd_resp_set_type(req, "text/plain");
|
|
httpd_resp_set_status(req, "200");
|
|
httpd_resp_send(req, response, HTTPD_RESP_USE_STRLEN);
|
|
return ESP_OK;
|
|
}
|
|
|
|
void register_paths(httpd_handle_t server) {
|
|
{
|
|
httpd_uri_t uri
|
|
= { .uri = "/", .method = HTTP_GET, .handler = http_index, .user_ctx = NULL };
|
|
httpd_register_uri_handler(server, &uri);
|
|
}
|
|
{
|
|
httpd_uri_t uri
|
|
= { .uri = "/clear", .method = HTTP_POST, .handler = http_clear, .user_ctx = NULL };
|
|
httpd_register_uri_handler(server, &uri);
|
|
}
|
|
{
|
|
httpd_uri_t uri
|
|
= { .uri = "/draw", .method = HTTP_POST, .handler = http_draw, .user_ctx = NULL };
|
|
httpd_register_uri_handler(server, &uri);
|
|
}
|
|
}
|
|
|
|
void app_main(void) {
|
|
// Initialize NVS, needed for wifi
|
|
esp_err_t ret = nvs_flash_init();
|
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
|
ret = nvs_flash_init();
|
|
}
|
|
ESP_ERROR_CHECK(ret);
|
|
|
|
httpd_handle_t server = get_server();
|
|
if (server != NULL) {
|
|
register_paths(server);
|
|
}
|
|
n_epd_setup(&SCREEN_MODEL);
|
|
}
|