ProtoCore v0.0.2
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
gpio_map_routes.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file gpio_map_routes.cpp
6 * @brief GPIO pin-mapper routes (GET serves the JSON, POST drives an output).
7 *
8 * Separated from the host-testable core (gpio_map.cpp) so the serializer + control
9 * parser unit-test without pulling in the server. The pin table is caller-owned.
10 */
11
13
14#if PC_ENABLE_GPIO_MAP
15
16#include "protocore.h"
18
19// All gpio-map-routes state, owned by one instance (internal linkage): the server handle plus
20// the pin table pointer and count, grouped so it is one named owner, unreachable cross-TU.
21// (The route handlers are fixed-signature callbacks, so they reach this single owner directly.)
22struct GpioRoutesCtx
23{
24 PC *srv = nullptr;
25 pc_gpio_pin *pins = nullptr;
26 uint8_t count = 0;
27};
28static GpioRoutesCtx s_gpior;
29
30static void gpio_get_handler(uint8_t slot_id, HttpReq *req)
31{
32 (void)req;
33 pc_gpio_read(s_gpior.pins, s_gpior.count);
34 char buf[PC_GPIO_JSON_BUF];
35 pc_gpio_json(s_gpior.pins, s_gpior.count, buf, sizeof(buf));
36 if (s_gpior.srv)
37 {
38 s_gpior.srv->send(slot_id, 200, PC_MIME_JSON, buf);
39 }
40}
41
42static void gpio_post_handler(uint8_t slot_id, HttpReq *req)
43{
44 if (!s_gpior.srv)
45 {
46 return;
47 }
48 uint8_t pin;
49 uint8_t level;
50 if (!pc_gpio_parse_set((const char *)req->body, req->body_len, &pin, &level))
51 {
52 s_gpior.srv->send(slot_id, 400, PC_MIME_TEXT_PLAIN, "bad request");
53 return;
54 }
55 if (!pc_gpio_is_output(s_gpior.pins, s_gpior.count, pin))
56 {
57 s_gpior.srv->send(slot_id, 403, PC_MIME_TEXT_PLAIN, "pin not a mapped output");
58 return;
59 }
60 pc_gpio_write(pin, level);
61 pc_gpio_read(s_gpior.pins, s_gpior.count);
62 char buf[PC_GPIO_JSON_BUF];
63 pc_gpio_json(s_gpior.pins, s_gpior.count, buf, sizeof(buf));
64 s_gpior.srv->send(slot_id, 200, PC_MIME_JSON, buf);
65}
66
67void pc_gpio_map_begin(PC &server, const char *path, pc_gpio_pin *pins, uint8_t count)
68{
69 s_gpior.srv = &server;
70 s_gpior.pins = pins;
71 s_gpior.count = count;
72 pc_gpio_begin_pins(pins, count);
73 const char *p = (path && path[0]) ? path : "/gpio";
74 server.on(p, HttpMethod::HTTP_GET, gpio_get_handler);
75 server.on(p, HttpMethod::HTTP_POST, gpio_post_handler);
76}
77
78#endif // PC_ENABLE_GPIO_MAP
Single-port HTTP server with deterministic, zero-allocation execution.
Definition protocore.h:348
void on(const char *path, HttpMethod method, Handler callback)
Register a route handler.
Browser GPIO pin-mapper / diagnostics (PC_ENABLE_GPIO_MAP).
Shared HTTP Content-Type ("MIME") string constants (one source of truth).
Layer 7 (Application) - public HTTP routing API.
@ HTTP_POST
Non-idempotent create / action.
@ HTTP_GET
Safe, idempotent read.
#define PC_GPIO_JSON_BUF
Stack buffer for the GPIO-map JSON (bytes).
Fully-parsed HTTP/1.1 request.
uint8_t body[BODY_BUF_SIZE+1]
Stored body bytes, always null-terminated.
size_t body_len
Bytes stored in body[] (≤ BODY_BUF_SIZE).