#include #include #include #include #include #include #include #include #include #define WIFI_HOTSPOT_IP "127.0.0.1" static uint16_t display_framebuffer[DISPLAY_WIDTH * DISPLAY_HEIGHT]; static bool display_state; void display_setup(void) { InitWindow(DISPLAY_WIDTH, DISPLAY_HEIGHT, "ILI9341 screen"); } void display_on(void) { display_state = true; } void display_off(void) { display_state = false; } void display_begin(void) {} void display_end(void) { BeginDrawing(); if (display_state) { for (int32_t y = 0; y < DISPLAY_HEIGHT; y++) { for (int32_t x = 0; x < DISPLAY_WIDTH; x++) { uint16_t c = display_framebuffer[y * DISPLAY_WIDTH + x]; uint8_t r = (c & 0b1111100000000000) >> 8; uint8_t g = (c & 0b0000011111100000) >> 3; uint8_t b = (c & 0b0000000000011111) << 3; DrawPixel(x, y, (Color){ r, g, b, 255 }); } } } else { for (int32_t y = 0; y < DISPLAY_HEIGHT; y++) { for (int32_t x = 0; x < DISPLAY_WIDTH; x++) { DrawPixel(x, y, (Color){ 0, 0, 0, 255 }); } } } EndDrawing(); if (WindowShouldClose()) { CloseWindow(); exit(1); } } void display_clear(uint16_t color) { for (int i = 0; i < DISPLAY_WIDTH * DISPLAY_HEIGHT; i++) display_framebuffer[i] = color; } void display_set_pixel(int32_t x, int32_t y, uint16_t color) { if (x < 0 || x >= DISPLAY_WIDTH || y < 0 || y >= DISPLAY_HEIGHT) return; display_framebuffer[y * DISPLAY_WIDTH + x] = color; } void button_setup(void) { } bool button_get(void) { PollInputEvents(); return IsKeyDown(KEY_SPACE); } static int server_fd = -1; static WifiHandler current_handler = nullptr; static void set_nonblocking(int fd) { fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); } void wifi_setup(void) { } void wifi_hotspot_start(const char *ssid, const char *password, WifiHandler handler) { (void)ssid; (void)password; current_handler = handler; server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd < 0) { printf("socket failed: %s\n", strerror(errno)); return; } int opt = 1; if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) printf("setsockopt failed: %s\n", strerror(errno)); set_nonblocking(server_fd); struct sockaddr_in addr = {}; addr.sin_family = AF_INET; addr.sin_port = htons(8080); addr.sin_addr.s_addr = INADDR_ANY; if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { printf("bind failed: %s\n", strerror(errno)); return; } if (listen(server_fd, 4) < 0) { printf("listen failed: %s\n", strerror(errno)); return; } printf("emulated hotspot at http://localhost:8080\n"); } void wifi_hotspot_stop(void) { if (server_fd >= 0) { close(server_fd); server_fd = -1; printf("stopped hotspot\n"); } } void wifi_tick(void) { if (server_fd < 0) return; int client = accept(server_fd, nullptr, nullptr); if (client < 0) { // no pending connection, non-blocking if (errno != EAGAIN && errno != EWOULDBLOCK) printf("accept error: %s\n", strerror(errno)); return; } printf("got connection\n"); char buf[2048] = {}; read(client, buf, sizeof(buf) - 1); // parse first line: "GET /uri HTTP/1.1" char method[8] = {}, uri[256] = {}; sscanf(buf, "%7s %255s", method, uri); // find body after \r\n\r\n const char *body = strstr(buf, "\r\n\r\n"); if (body) body += 4; WifiRequest req = { .uri = uri, .method = method, .body = (body && *body) ? body : nullptr, }; WifiResponse res = current_handler(&req); char header[256]; snprintf(header, sizeof(header), "HTTP/1.1 %d OK\r\n" "Content-Type: %s\r\n" "Content-Length: %zu\r\n" "Connection: close\r\n" "\r\n", res.status, res.content_type, strlen(res.body) ); write(client, header, strlen(header)); write(client, res.body, strlen(res.body)); close(client); } uint32_t millis() { return (uint32_t)(GetTime() * 1000); }