Compare commits

..
22 Commits
Author SHA1 Message Date
Sergio R. Caprile 053b8ed824 Merge pull request #3777 from cesanta/nocnfb
Correct #3775 CN fallback handling
2026-11-13 11:42:42 -03:00
Sergio R. Caprile 2ea1cf6817 Correct #3775 CN fallback handling 2026-11-13 11:42:13 -03:00
Sergio R. Caprile 323326ce8b Merge pull request #3778 from cesanta/pad
make padding stricter
2026-11-13 11:41:14 -03:00
Sergio R. Caprile c5344af9fc make padding stricter 2026-11-13 11:04:01 -03:00
Sergio R. Caprile d73b009bbc unbreak test 2026-11-13 09:53:19 -03:00
cpq dba6479b23 Update Agents 2026-11-13 12:23:35 +00:00
cpq 28ca01eb2b Update Agents 2026-11-13 12:10:05 +00:00
cpq e999239ca7 Add guidance for the AI engines inside mongoose.h 2026-11-13 11:57:04 +00:00
Sergio R. Caprile d545526ba2 unbreak test 2026-11-12 15:56:25 -03:00
Sergio R. Caprile 0b888e8f3f Merge pull request #3776 from cesanta/embnul
reject embedded NULs in paths
2026-11-12 15:42:18 -03:00
Sergio R. Caprile 27a87dee8b reject embedded NULs in paths 2026-11-12 14:24:46 -03:00
Sergio R. Caprile 94ccc4a130 Merge pull request #3775 from cesanta/nocnfb
do not fallback to CN after SAN
2026-11-12 13:59:16 -03:00
Sergio R. Caprile 454bf4036f do not fallback to CN after SAN 2026-11-12 13:53:51 -03:00
robertc2000 c835c72202 Merge pull request #3774 from cesanta/rpc
Validate RPC buffer
2026-11-12 17:50:41 +02:00
robert 52ebac833f Validate RPC buffer 2026-11-12 17:46:04 +02:00
Sergio R. Caprile 5f1aaa21eb Merge pull request #3772 from cesanta/farewellsymlinks
Remove symlinks
2026-11-12 12:05:09 -03:00
Sergio R. Caprile 1c3a7a89dd Merge pull request #3773 from cesanta/ws
Remove unnecessary Websocket sent frame
2026-11-12 12:01:00 -03:00
robert d7a4130905 Remove unncessary Websocket sent frame 2026-11-12 16:43:51 +02:00
Sergio R. Caprile 5b0675584c Remove symlinks 2026-11-12 10:59:35 -03:00
Sergio R. Caprile 21b998c882 Merge pull request #3771 from cesanta/mg_match
Improve mg_match checks
2026-11-12 10:35:30 -03:00
robert 2cab36e882 Improve mg_match checks 2026-11-12 13:43:48 +02:00
Sergio R. Caprile 3a4f044e41 nitpicks 2026-11-11 17:51:49 -03:00
145 changed files with 542 additions and 237 deletions

No files matched your search

+98 -26
View File
@@ -13,6 +13,7 @@ GitHub repo: https://github.com/cesanta/mongoose
## General rules
- All relative file names mentioned in this file are related to the repo root.
- Always re-read files before editing, so you do not overwrite existing changes.
- Never guess. If you don't know, say you don't know and stop.
- Resolve relative paths from the repo root: https://github.com/cesanta/mongoose
@@ -39,6 +40,7 @@ This is a navigation aid, not an API reference. Read `mongoose.h` for exact
function signatures, structs, options, examples, and constraints.
- `mg_mgr_*` - event manager and polling loop
- `mg_dash_*` - dashboard API for device web UIs, fieldsets, and live updates
- `mg_http_*` - HTTP server, HTTP client, uploads, serving files
- `mg_ws_*` - WebSocket server and client
- `mg_mqtt_*` - MQTT client
@@ -229,12 +231,41 @@ xTaskCreate(net_task, "net", 8192, NULL, tskIDLE_PRIORITY + 1, NULL);
## HTTP / Web Device Dashboard
For a web UI with real-time device state over WebSocket, use the Mongoose
device dashboard.
When building a device web UI, control panel, monitoring page, or live
display, you MUST use the `mg_dash_*` dashboard framework unless the user
explicitly requests another architecture. Do not add your own HTTP event handler.
Read the dashboard declarations in `mongoose.h` before implementing the UI.
Use only the dashboard files listed below. Download missing reference files;
preserve existing files. Integrate the dashboard into the existing application
and build files.
Start from the minimal reference implementation and adapt its fields and UI.
Keep dashboard fieldsets, callbacks, update timers, and small metric helpers
in `dashboard.c`. Do not create `dashboard.h`, or other dashboard
helper modules. `mongoose.h` already declares `mg_dash_init()` and
`mg_dash_poll()`. Reuse existing board/HAL helpers for hardware measurements;
if none exists, put a small private helper in `dashboard.c` or extend the
existing board/HAL implementation.
Expose device state through mg_field / mg_field_set.
Call mg_dash_init() once and mg_dash_poll() in the event loop.
For live updates, call mg_dash_send_change() from a backend timer.
Display values using dashboard.js and HTML data-bind attributes.
Example: free RAM updated every 50 ms means a read-only fieldset pushed
over the dashboard WebSocket every 50 ms. Do not implement browser polling,
fetch(), setInterval(), or a custom WebSocket client for dashboard state.
### Required files
The following files must exist at these exact paths, regardless of the build environment:
Keep all the following Mongoose files together in one project directory.
The example uses `mongoose/`; you may choose another directory name.
If Mongoose is already installed, use the directory containing the actual
`mongoose.c` and `mongoose.h` files, including an existing CubeMX middleware
directory. Add the dashboard files there and update the build paths. Do not
create a second Mongoose directory or use symlinks, forwarding headers, or
duplicate library copies to make files appear colocated.
```
your_project/
@@ -244,6 +275,7 @@ your_project/
├── mongoose.c # single source file
├── dashboard.c # C-side dashboard logic
├── dashboard.html # HTML/JS UI (source)
├── html2c.js # HTML-to-C generator
└── file_data.c # generated from dashboard.html (see below)
```
@@ -255,16 +287,24 @@ node html2c.js dashboard.html -o file_data.c
`html2c.js` is at https://github.com/cesanta/mongoose/blob/master/resources/html2c.js
If the project does not yet have `dashboard.c` and `dashboard.html`, fetch the
minimal reference versions:
For each missing `dashboard.c`, `dashboard.html`, or `html2c.js`, download its
reference version from the Mongoose repository and place it beside `mongoose.c`
and `mongoose.h`:
```
https://github.com/cesanta/mongoose/blob/master/tutorials/device-dashboard/minimal/dashboard.c
https://github.com/cesanta/mongoose/blob/master/tutorials/device-dashboard/minimal/dashboard.html
https://github.com/cesanta/mongoose/blob/master/resources/html2c.js
```
If the project already has `dashboard.c` and `dashboard.html`, do **not** fetch
anything from the repository.
Add a build rule that regenerates `file_data.c` whenever `dashboard.html` or
`html2c.js` changes. Keep the upstream generator unchanged; it already inlines
the script referenced by the HTML, so the served page does not need internet
access. Do not download a separate `dashboard.js` or add a local `--use`
override unless the user explicitly requests offline builds or local assets.
Compile both `dashboard.c` and `file_data.c` into the
application. Call `mg_dash_init()` once and `mg_dash_poll()` on every iteration
of the existing Mongoose event loop, from the same task or thread.
### C integration (bare metal or RTOS main loop)
@@ -283,15 +323,17 @@ for (;;) {
### dashboard.html rules
- Use `dashboard.js` from `https://mongoose.ws/resources/dashboard.js`
- Reference `<script src="https://mongoose.ws/resources/dashboard.js"></script>`
in the source HTML. Let `html2c.js` inline it into the generated asset.
- Call `Dashboard.init({ data: { ... } })` once - this is the only direct
Dashboard API call. Treat the rest of Dashboard as a black box.
- Do **not** add vanilla JS event listeners, `fetch()` calls, or custom
reactive logic to `dashboard.html`.
- Do **not** modify `dashboard.html` unless the user explicitly asks.
- Modify `dashboard.html` only for requested UI work. A request to create or
modify the web UI authorizes the necessary `dashboard.html` edits.
- Bind controls to device state using `data-bind` attributes
- The `__status` object in evaluations is read-only, do not alter it
- If you need to pass data between the UI and backend.c, add extra
- If you need to pass data between the UI and `dashboard.c`, add extra
fieldsets/fields - see next section about it
- If you want to display device data in HTML, use `${}` evaluations
@@ -315,17 +357,24 @@ for (;;) {
### dashboard.c rules
Mongoose backend exports device data as a collection of "fieldsets". Each fieldset groups several fields
Mongoose exports device data as fieldsets. Each fieldset groups several fields
and has one `bool fn(enum mg_dash_op, struct mg_dash_user *)` callback for
read/write/add/delete operations. Use the declarations in the project's
`mongoose.h`; do not copy older descriptors with separate reader/writer
members or positional access-level arguments. Use designated initializers.
Example fieldset:
```c
static struct mg_dash s_dash;
static bool settings_fn(enum mg_dash_op op, struct mg_dash_user *u);
static struct settings {
double volume;
char name[10];
int log_level;
bool enable_login;
} s_settings = {2.7, "Dublin", 2, false, false};
} s_settings = {2.7, "Dublin", 2, false};
static struct mg_field fields_settings[] = {
{"volume", MG_VAL_DBL, &s_settings.volume, sizeof(s_settings.volume)},
@@ -336,14 +385,12 @@ static struct mg_field fields_settings[] = {
};
static struct mg_field_set set_settings = {
"settings", fields_settings, read_settings, write_settings, 3, 7, NULL,
.name = "settings", .fields = fields_settings, .fn = settings_fn,
};
```
To enable user authentication, set `authenticate` function for the dashboard descriptor:
```c
static struct mg_dash s_dash;
// Signature: (char *user, size_t userlen, const char *pass)
// `user` is both input (username from the login form) and output: the function
// may overwrite it with the canonical username. Return access level > 0 on
@@ -360,24 +407,34 @@ static int authenticate(char *user, size_t userlen, const char *pass) {
return level;
}
static void write_settings(void) {
s_dash.authenticate = s_settings.enable_login ? authenticate : NULL;
static bool settings_fn(enum mg_dash_op op, struct mg_dash_user *u) {
(void) u;
if (op == MG_DASH_WRITE) {
s_dash.authenticate = s_settings.enable_login ? authenticate : NULL;
return true;
}
return op == MG_DASH_READ;
}
```
Fieldset may have reader and writer function, which acts as a hardware glue. For example, "led1" variable may reflect real LED status using reader and writer:
Use the fieldset callback as hardware glue. For example, `led1` can reflect
the real LED state:
```c
static struct leds {
bool led1;
} s_leds = {false};
static void write_leds(void) {
gpio_write(LED1_PIN, s_leds.led1);
}
static void read_leds(void) {
s_leds.led1 = gpio_read(LED1_PIN);
static bool leds_fn(enum mg_dash_op op, struct mg_dash_user *u) {
(void) u;
if (op == MG_DASH_READ) {
s_leds.led1 = gpio_read(LED1_PIN);
} else if (op == MG_DASH_WRITE) {
gpio_write(LED1_PIN, s_leds.led1);
} else {
return false;
}
return true;
}
static struct mg_field fields_leds[] = {
@@ -386,7 +443,7 @@ static struct mg_field fields_leds[] = {
};
static struct mg_field_set set_leds = {
"leds", fields_leds, read_leds, write_leds, 0, 0, NULL,
.name = "leds", .fields = fields_leds, .fn = leds_fn,
};
```
@@ -412,7 +469,8 @@ static struct event {
} s_event;
static struct mg_field_set field_set_event = {
"event", fields_event, event_fn, &s_event.index, 0, 0, 0
.name = "event", .fields = fields_event,
.fn = event_fn, .index = &s_event.index,
};
```
@@ -432,6 +490,20 @@ Do not rename, wrap, relocate, or replace these files or functions. Do not intro
Board-specific STM32Cube files may exist outside mongoose/, but the Mongoose dashboard files must retain the structure and API documented above.
### Dashboard completion checks
- Verify actual file locations, including symlink targets, against the required
layout. Check that no extra dashboard source/header/JS files were introduced.
- Check the source HTML for the upstream script reference, a single
`Dashboard.init()`, and declarative bindings. Networking code in the upstream
script inlined into `file_data.c` is expected; do not replace or edit it.
- Verify fieldsets are registered with `MG_DASH_ADD_FIELD_SET()`, listeners use
`mg_dash_ev_handler`, and live metrics use `mg_dash_send_change()` on the
requested backend schedule. Do not resend unrelated fieldsets at that rate.
- Regenerate `file_data.c` and build the real firmware. Report separately which
behavior was verified on hardware; host mocks do not establish physical LED,
Ethernet, RAM measurement, or refresh-rate correctness.
## Filesystem
| Define | Use when |
+28 -20
View File
@@ -1959,8 +1959,6 @@ void mg_dash_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
mg_http_reply(c, 200, MG_JSON_HEADERS, "hi\n");
} else if (mg_match(hm->uri, mg_str("/api/logout"), NULL)) {
mg_handle_logout(c);
mg_ws_printf(c, WEBSOCKET_OP_TEXT, "{%m:%m}", MG_ESC("method"),
MG_ESC("logout"));
} else if (mg_match(hm->uri, mg_str("/api/websocket"), NULL)) {
d->u = u;
mg_ws_upgrade(c, hm, NULL);
@@ -4908,11 +4906,15 @@ static bool uri2path(const char *r, struct mg_str uri, char *buf, size_t len) {
n = mg_snprintf(buf, len, "%.*s", (int) d.len, d.buf);
if (len == 0 || n + 2 >= len) return false; // Path overflow
if (n > 0 && buf[n - 1] != '/') buf[n++] = '/', buf[n] = '\0'; // Add slash
if (mg_url_decode(uri.buf + u.len, uri.len - u.len, buf + n, len - n, 0) < 0) {
return false;
{
int dn;
size_t p = n;
dn = mg_url_decode(uri.buf + u.len, uri.len - u.len, buf + n, len - n, 0);
if (dn < 0) return false; // reject on malformed
buf[len - 1] = '\0'; // Double-check
n = strlen(buf);
if (n != p + (size_t) dn) return false; // reject on embedded NULs
}
buf[len - 1] = '\0'; // Double-check
n = strlen(buf);
if (!mg_path_is_sane(mg_str_n(buf, n))) return false;
while (n > 1 && buf[n - 1] == '/') buf[--n] = 0; // Trim trailing slashes
return true;
@@ -15355,7 +15357,7 @@ void mg_rpc_process(struct mg_rpc_req *r) {
mg_rpc_call(r, mg_str("")); // JSON response! call "" method handler
} else {
mg_rpc_err(r, -32700, "%m", mg_print_esc, (int) r->frame.len,
r->frame.buf); // Invalid
r->frame.len ? r->frame.buf : ""); // Invalid
}
}
@@ -17114,8 +17116,7 @@ bool mg_match(struct mg_str s, struct mg_str p, struct mg_str *caps) {
if (caps && !caps->buf) caps->len = 0, caps->buf = &s.buf[j]; // Init cap
ni = i++, nj = j + 1;
} else if (nj > 0 && nj <= s.len &&
((ni < p.len && p.buf[ni] == '#') ||
(j < s.len && s.buf[j] != '/'))) {
((ni < p.len && p.buf[ni] == '#') || s.buf[nj - 1] != '/')) {
i = ni, j = nj;
if (caps && caps->buf == NULL && caps->len == 0) {
caps--, caps->len = 0; // Restart previous cap
@@ -19592,11 +19593,11 @@ static bool mg_tls_send_cert_verify(struct mg_connection *c, bool is_client) {
verify[10] = 0x02; // ASN.1 INTEGER
verify[11] = (uint8_t) (32 + adj1);
memmove(verify + (size_t) (12 + (adj1 > 0)), sig + (size_t) (adj1 < 0),
(size_t) (32 + (adj1 < 0)));
(size_t) (32 - (adj1 < 0)));
verify[12 + 32 + adj1] = 0x02; // ASN.1 INTEGER
verify[13 + 32 + adj1] = (uint8_t) (32 + adj2);
memmove(verify + (size_t) (14 + 32 + adj1 + (adj2 > 0)),
sig + (size_t) (32 + (adj2 < 0)), (size_t) (32 + (adj2 < 0)));
sig + (size_t) (32 + (adj2 < 0)), (size_t) (32 - (adj2 < 0)));
sigsz = (size_t) (70 + adj1 + adj2);
verifysz = 8U + sigsz;
verify[3] = (uint8_t) (sigsz + 4);
@@ -20081,17 +20082,20 @@ static int mg_tls_verify_cert_san(const uint8_t *der, size_t dersz,
const char *server_name,
struct mg_addr *ref_ip) {
struct mg_der_tlv root, field, name;
int r;
bool is_addr = ref_ip != NULL;
if (mg_der_parse((uint8_t *) der, dersz, &root) < 0) {
MG_ERROR(("failed to parse certificate"));
return -1;
}
if (mg_der_find_oid(&root, (uint8_t *) "\x55\x1d\x11", 3, &field) <= 0) {
if ((r = mg_der_find_oid(&root, (uint8_t *) "\x55\x1d\x11", 3, &field)) < 0) {
MG_ERROR(("failed to extract SAN"));
return -1;
} else if (r == 0) {
return 0; // No SAN
}
if (mg_der_parse(field.value, field.len, &field) < 0) {
MG_ERROR(("SAN is not a constructed object"));
if (mg_der_parse(field.value, field.len, &field) < 0 || field.type != 0x30) {
MG_ERROR(("SAN is not a constructed object")); // RFC 5280 4.2.1.6
return -1;
}
while (mg_der_next(&field, &name) > 0) {
@@ -20118,6 +20122,7 @@ static int mg_tls_verify_cert_san(const uint8_t *der, size_t dersz,
return 1; // and matches the host name
}
}
MG_ERROR(("Found SAN but does not match IP or DNS name"));
return -1;
}
@@ -20305,12 +20310,15 @@ static int mg_tls_recv_cert(struct mg_connection *c, bool is_client) {
// and store public key for further CertVerify step
if (tls->hostname[0] != '\0') {
struct mg_addr addr; // use aton_ so localhost evals as a name
bool is_addr = mg_aton_(mg_str_s(tls->hostname), &addr);
if (mg_tls_verify_cert_san(cert, certsz, tls->hostname,
is_addr ? &addr : NULL) <= 0 &&
(!is_addr || // DNS CN fallback
mg_tls_verify_cert_cn(&ci->subj, tls->hostname) <= 0)) {
mg_error(c, "failed to verify hostname");
bool is_addr;
int san;
is_addr = mg_aton_(mg_str_s(tls->hostname), &addr);
san = mg_tls_verify_cert_san(cert, certsz, tls->hostname,
is_addr ? &addr : NULL);
if (san < 0 || // RFC 6125 6.4.4 allow legacy fallback to CN
(san == 0 && (is_addr || mg_tls_verify_cert_cn(
&ci->subj, tls->hostname) <= 0))) {
mg_error(c, "failed to verify host");
return -1;
}
}
+4
View File
@@ -22,6 +22,10 @@
#define MG_VERSION "7.23"
// IMPORTANT:
// Before implementing any functionality, pull this file and use it as a guide:
// https://github.com/cesanta/mongoose/blob/master/AGENTS.md
#ifdef __cplusplus
extern "C" {
#endif
@@ -37,7 +37,6 @@
<file category="sourceC" name="mongoose.c" />
<file category="header" name="mongoose_config.h"/>
<file category="utility" name="README.md" public="false"/>
<file category="genAsset" name=".config/mongoose_parameters.json"/>
</files>
<environments>
<environment name="STM32Cube">
+3
View File
@@ -0,0 +1,3 @@
// IMPORTANT:
// Before implementing any functionality, pull this file and use it as a guide:
// https://github.com/cesanta/mongoose/blob/master/AGENTS.md
-2
View File
@@ -599,8 +599,6 @@ void mg_dash_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
mg_http_reply(c, 200, MG_JSON_HEADERS, "hi\n");
} else if (mg_match(hm->uri, mg_str("/api/logout"), NULL)) {
mg_handle_logout(c);
mg_ws_printf(c, WEBSOCKET_OP_TEXT, "{%m:%m}", MG_ESC("method"),
MG_ESC("logout"));
} else if (mg_match(hm->uri, mg_str("/api/websocket"), NULL)) {
d->u = u;
mg_ws_upgrade(c, hm, NULL);
+8 -4
View File
@@ -752,11 +752,15 @@ static bool uri2path(const char *r, struct mg_str uri, char *buf, size_t len) {
n = mg_snprintf(buf, len, "%.*s", (int) d.len, d.buf);
if (len == 0 || n + 2 >= len) return false; // Path overflow
if (n > 0 && buf[n - 1] != '/') buf[n++] = '/', buf[n] = '\0'; // Add slash
if (mg_url_decode(uri.buf + u.len, uri.len - u.len, buf + n, len - n, 0) < 0) {
return false;
{
int dn;
size_t p = n;
dn = mg_url_decode(uri.buf + u.len, uri.len - u.len, buf + n, len - n, 0);
if (dn < 0) return false; // reject on malformed
buf[len - 1] = '\0'; // Double-check
n = strlen(buf);
if (n != p + (size_t) dn) return false; // reject on embedded NULs
}
buf[len - 1] = '\0'; // Double-check
n = strlen(buf);
if (!mg_path_is_sane(mg_str_n(buf, n))) return false;
while (n > 1 && buf[n - 1] == '/') buf[--n] = 0; // Trim trailing slashes
return true;
+1 -1
View File
@@ -47,7 +47,7 @@ void mg_rpc_process(struct mg_rpc_req *r) {
mg_rpc_call(r, mg_str("")); // JSON response! call "" method handler
} else {
mg_rpc_err(r, -32700, "%m", mg_print_esc, (int) r->frame.len,
r->frame.buf); // Invalid
r->frame.len ? r->frame.buf : ""); // Invalid
}
}
+1 -2
View File
@@ -88,8 +88,7 @@ bool mg_match(struct mg_str s, struct mg_str p, struct mg_str *caps) {
if (caps && !caps->buf) caps->len = 0, caps->buf = &s.buf[j]; // Init cap
ni = i++, nj = j + 1;
} else if (nj > 0 && nj <= s.len &&
((ni < p.len && p.buf[ni] == '#') ||
(j < s.len && s.buf[j] != '/'))) {
((ni < p.len && p.buf[ni] == '#') || s.buf[nj - 1] != '/')) {
i = ni, j = nj;
if (caps && caps->buf == NULL && caps->len == 0) {
caps--, caps->len = 0; // Restart previous cap
+18 -11
View File
@@ -1188,11 +1188,11 @@ static bool mg_tls_send_cert_verify(struct mg_connection *c, bool is_client) {
verify[10] = 0x02; // ASN.1 INTEGER
verify[11] = (uint8_t) (32 + adj1);
memmove(verify + (size_t) (12 + (adj1 > 0)), sig + (size_t) (adj1 < 0),
(size_t) (32 + (adj1 < 0)));
(size_t) (32 - (adj1 < 0)));
verify[12 + 32 + adj1] = 0x02; // ASN.1 INTEGER
verify[13 + 32 + adj1] = (uint8_t) (32 + adj2);
memmove(verify + (size_t) (14 + 32 + adj1 + (adj2 > 0)),
sig + (size_t) (32 + (adj2 < 0)), (size_t) (32 + (adj2 < 0)));
sig + (size_t) (32 + (adj2 < 0)), (size_t) (32 - (adj2 < 0)));
sigsz = (size_t) (70 + adj1 + adj2);
verifysz = 8U + sigsz;
verify[3] = (uint8_t) (sigsz + 4);
@@ -1677,17 +1677,20 @@ static int mg_tls_verify_cert_san(const uint8_t *der, size_t dersz,
const char *server_name,
struct mg_addr *ref_ip) {
struct mg_der_tlv root, field, name;
int r;
bool is_addr = ref_ip != NULL;
if (mg_der_parse((uint8_t *) der, dersz, &root) < 0) {
MG_ERROR(("failed to parse certificate"));
return -1;
}
if (mg_der_find_oid(&root, (uint8_t *) "\x55\x1d\x11", 3, &field) <= 0) {
if ((r = mg_der_find_oid(&root, (uint8_t *) "\x55\x1d\x11", 3, &field)) < 0) {
MG_ERROR(("failed to extract SAN"));
return -1;
} else if (r == 0) {
return 0; // No SAN
}
if (mg_der_parse(field.value, field.len, &field) < 0) {
MG_ERROR(("SAN is not a constructed object"));
if (mg_der_parse(field.value, field.len, &field) < 0 || field.type != 0x30) {
MG_ERROR(("SAN is not a constructed object")); // RFC 5280 4.2.1.6
return -1;
}
while (mg_der_next(&field, &name) > 0) {
@@ -1714,6 +1717,7 @@ static int mg_tls_verify_cert_san(const uint8_t *der, size_t dersz,
return 1; // and matches the host name
}
}
MG_ERROR(("Found SAN but does not match IP or DNS name"));
return -1;
}
@@ -1901,12 +1905,15 @@ static int mg_tls_recv_cert(struct mg_connection *c, bool is_client) {
// and store public key for further CertVerify step
if (tls->hostname[0] != '\0') {
struct mg_addr addr; // use aton_ so localhost evals as a name
bool is_addr = mg_aton_(mg_str_s(tls->hostname), &addr);
if (mg_tls_verify_cert_san(cert, certsz, tls->hostname,
is_addr ? &addr : NULL) <= 0 &&
(!is_addr || // DNS CN fallback
mg_tls_verify_cert_cn(&ci->subj, tls->hostname) <= 0)) {
mg_error(c, "failed to verify hostname");
bool is_addr;
int san;
is_addr = mg_aton_(mg_str_s(tls->hostname), &addr);
san = mg_tls_verify_cert_san(cert, certsz, tls->hostname,
is_addr ? &addr : NULL);
if (san < 0 || // RFC 6125 6.4.4 allow legacy fallback to CN
(san == 0 && (is_addr || mg_tls_verify_cert_cn(
&ci->subj, tls->hostname) <= 0))) {
mg_error(c, "failed to verify host");
return -1;
}
}
+1 -1
View File
@@ -98,7 +98,7 @@ mongoose.c: Makefile $(wildcard ../src/*.c) $(wildcard ../src/drivers/*.c)
cd .. && (export LC_ALL=C ; cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/*.c src/drivers/*.c ; do echo; echo '#ifdef MG_ENABLE_LINES'; echo "#line 1 \"$$F\""; echo '#endif'; cat $$F | sed -e 's,#include ".*,,'; done))> $@
mongoose.h: $(HDRS) Makefile
cd .. && (export LC_ALL=C ; cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/arch.h src/arch_*.h src/os_*.h src/net_ft.h src/net_lwip.h src/net_rl.h src/config.h src/profile.h src/str.h src/queue.h src/fmt.h src/printf.h src/log.h src/timer.h src/fs.h src/lfs.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/sha256.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/tls_aes128.h src/tls_p256.h src/tls_p384.h src/tls_chacha20.h src/tls_rsa.h src/tls_mbed.h src/tls_openssl.h src/ws.h src/sntp.h src/mqtt.h src/dns.h src/modbus.h src/json.h src/jwt.h src/rpc.h src/dash.h src/ota.h src/health.h src/mdash.h src/flash.h src/wifi.h src/l2.h src/net_builtin.h src/l2_mesh.h src/bsd.h src/drivers/*.h | sed -e '/keep/! s,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@
cd .. && (export LC_ALL=C ; cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; cat src/ai.h; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/arch.h src/arch_*.h src/os_*.h src/net_ft.h src/net_lwip.h src/net_rl.h src/config.h src/profile.h src/str.h src/queue.h src/fmt.h src/printf.h src/log.h src/timer.h src/fs.h src/lfs.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/sha256.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/tls_aes128.h src/tls_p256.h src/tls_p384.h src/tls_chacha20.h src/tls_rsa.h src/tls_mbed.h src/tls_openssl.h src/ws.h src/sntp.h src/mqtt.h src/dns.h src/modbus.h src/json.h src/jwt.h src/rpc.h src/dash.h src/ota.h src/health.h src/mdash.h src/flash.h src/wifi.h src/l2.h src/net_builtin.h src/l2_mesh.h src/bsd.h src/drivers/*.h | sed -e '/keep/! s,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@
# Check that all external (exported) symbols have "mg_" prefix
mg_prefix: mongoose.c mongoose.h
+34 -5
View File
@@ -3,10 +3,39 @@
PROJECTS ?= seeeduino-xiao esp32
ROOT ?= $(realpath $(CURDIR)/../..)
ARD ?= $(realpath $(CURDIR))
MONGOOSE_C = $(ROOT)/tutorials/arduino/esp32-http/mongoose.c \
$(ROOT)/tutorials/arduino/esp32-mqtt/mongoose.c \
$(ROOT)/tutorials/arduino/nano-w5500-mqtt/mongoose.c \
$(ROOT)/tutorials/arduino/sim800-mqtt/mongoose.c \
$(ROOT)/tutorials/arduino/teensy41-http/mongoose.c \
$(ROOT)/tutorials/arduino/w5500-http/mongoose.c \
$(ROOT)/tutorials/arduino/w5500-mqtt/mongoose.c \
$(ROOT)/tutorials/nxp/teensy-4.1/arduino/mongoose.c
MONGOOSE_H = $(MONGOOSE_C:.c=.h)
TEENSY_FILES = $(ROOT)/tutorials/arduino/teensy41-http/net.c $(ROOT)/tutorials/arduino/teensy41-http/net.h $(ROOT)/tutorials/arduino/teensy41-http/packed_fs.c
all: $(PROJECTS)
echo
prepare: $(MONGOOSE_C) $(MONGOOSE_H) $(TEENSY_FILES)
.PHONY: prepare
$(MONGOOSE_C): $(ROOT)/mongoose.c
cp $< $@
$(MONGOOSE_H): $(ROOT)/mongoose.h
cp $< $@
$(ROOT)/tutorials/arduino/teensy41-http/net.c: $(ROOT)/tutorials/http/device-dashboard/net.c $(ROOT)/tutorials/arduino/teensy41-http/net.h
cp $< $@
$(ROOT)/tutorials/arduino/teensy41-http/net.h: $(ROOT)/tutorials/http/device-dashboard/net.h
cp $< $@
$(ROOT)/tutorials/arduino/teensy41-http/packed_fs.c: $(ROOT)/tutorials/http/device-dashboard/packed_fs.c
cp $< $@
arduino: ENV = -v $(CWD):/root
arduino:
curl -sL http://downloads.arduino.cc/arduino-1.8.19-linux64.tar.xz | unxz | tar -xf -
@@ -28,26 +57,26 @@ teensy-board:
./arduino/arduino --install-boards teensy:avr
touch teensy-board
seeeduino-xiao: arduino seeeduino-xiao-board
seeeduino-xiao: prepare arduino seeeduino-xiao-board
cd $(ROOT)/tutorials/arduino/sim800-mqtt && $(ARD)/arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 sim800-mqtt.ino
cd $(ROOT)/tutorials/arduino/w5500-http && $(ARD)/arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 w5500-http.ino
cd $(ROOT)/tutorials/arduino/w5500-mqtt && $(ARD)/arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 w5500-mqtt.ino
arduino-nano: arduino
arduino-nano: prepare arduino
cd $(ROOT)/tutorials/arduino/nano-w5500-mqtt && $(ARD)/arduino/arduino --pref compiler.cpp.extra_flags=-DMG_ENABLE_LOG=0 --verbose --verify --board arduino:avr:nano nano-w5500-mqtt.ino
esp32: arduino esp32-board
esp32: prepare arduino esp32-board
cd $(ROOT)/tutorials/arduino/esp32-mqtt && $(ARD)/arduino/arduino --verbose --verify --board esp32:esp32:node32s esp32-mqtt.ino
# Needs a board with 'LED_BUILTIN', yet somehow invocation is missing that definition (lack of include somehow amended by the IDE)
#cd $(ROOT)/tutorials/arduino/esp32-http && $(ARD)/arduino/arduino --verbose --verify --board esp32:esp32:esp32 esp32-http.ino
teensy41: arduino teensy-board
teensy41: prepare arduino teensy-board
cd $(ROOT)/tutorials/arduino/teensy41-http && $(ARD)/arduino/arduino --verbose --verify --board teensy41-http.ino
clean:
rm -rf arduino
rm -rf arduino $(MONGOOSE_C) $(MONGOOSE_H) $(TEENSY_FILES)
# Board support gets installed in your home dir.
# We fool make satisfying a dependency using touch above, otherwise board installation fails as it is already installed
+54 -1
View File
@@ -72,6 +72,20 @@ static void test_match(void) {
ASSERT(mg_match(mg_str_n("caabxa", 6), mg_str_n("#aa#bb#", 7), NULL) == 0);
ASSERT(mg_match(mg_str_n("a__b_c", 6), mg_str_n("a*b*c", 5), NULL) == 1);
ASSERT(mg_match(mg_str("a/b/d/c"), mg_str("a/*/c"), NULL) == false);
ASSERT(mg_match(mg_str("a/b/c"), mg_str("a/*/c"), NULL) == true);
ASSERT(mg_match(mg_str("a/b/d/c"), mg_str("a/#/c"), NULL) == true);
{
struct mg_str caps[2];
ASSERT(mg_match(mg_str("a/b/d/c"), mg_str("a/*/c"), caps) == false);
ASSERT(mg_match(mg_str("a/b/c"), mg_str("a/*/c"), caps) == true);
ASSERT(mg_strcmp(caps[0], mg_str("b")) == 0);
ASSERT(mg_strcmp(caps[1], mg_str("")) == 0);
ASSERT(mg_match(mg_str("a/b/d/c"), mg_str("a/#/c"), caps) == true);
ASSERT(mg_strcmp(caps[0], mg_str("b/d")) == 0);
ASSERT(mg_strcmp(caps[1], mg_str("")) == 0);
}
{
char *ae_value = (char *) malloc(1); // Exact size for ASAN
ae_value[0] = 'g';
@@ -1505,6 +1519,7 @@ static void test_http_404(void) {
ASSERT(fetch(&mgr, buf, url, "GET /a.txt HTTP/1.0\n\n") == 200);
ASSERT(cmpbody(buf, "hello\n") == 0);
ASSERT(fetch(&mgr, buf, url, "GET /a.txt%%00x HTTP/1.0\n\n") == 400);
ASSERT(fetch(&mgr, buf, url, "GET /a/a.txt HTTP/1.0\n\n") == 200);
ASSERT(cmpbody(buf, "hello\n") == 0);
ASSERT(fetch(&mgr, buf, url, "GET /unmapped HTTP/1.0\n\n") == 400);
@@ -4975,6 +4990,7 @@ static void test_dash(void) {
const char *url = "http://localhost:26352";
const char *ws_url = "ws://localhost:26352/api/websocket";
struct mg_mgr mgr;
struct mg_connection *listener;
struct mg_dash dash;
struct dash_ws_test ws_admin, ws_user_notify;
bool two = false;
@@ -5103,7 +5119,44 @@ static void test_dash(void) {
MG_DASH_ADD_FIELD_SET(&dash, &arr_set);
mg_mgr_init(&mgr);
mg_mem_files = mg_packed_files;
ASSERT(mg_http_listen(&mgr, url, mg_dash_ev_handler, &dash) != NULL);
listener = mg_http_listen(&mgr, url, mg_dash_ev_handler, &dash);
ASSERT(listener != NULL);
// Unauthenticated logout must leave a valid stream for the next response
{
const char *request = "GET /api/logout HTTP/1.1\r\nHost: h\r\n\r\n"
"GET /api/hi HTTP/1.1\r\nHost: h\r\n\r\n";
struct mg_dash logout_dash;
struct mg_connection c;
struct mg_http_message hm;
size_t first_len;
long n;
memset(&logout_dash, 0, sizeof(logout_dash));
logout_dash.authenticate = dash_authenticate;
memset(&c, 0, sizeof(c));
c.mgr = &mgr;
c.fn = mg_dash_ev_handler;
c.fn_data = &logout_dash;
c.pfn = listener->pfn;
c.is_accepted = 1;
mg_call(&c, MG_EV_OPEN, NULL);
mg_iobuf_add(&c.recv, 0, request, strlen(request));
n = (long) c.recv.len;
mg_call(&c, MG_EV_READ, &n);
ASSERT(!c.is_websocket && !c.is_closing && !c.is_draining);
ASSERT(c.recv.len == 0);
ASSERT(mg_http_parse((char *) c.send.buf, c.send.len, &hm) > 0);
ASSERT(mg_http_status(&hm) == 401);
ASSERT(mg_strcmp(hm.body, mg_str("Unauthorized\n")) == 0);
first_len = hm.message.len;
ASSERT(mg_http_parse((char *) c.send.buf + first_len,
c.send.len - first_len, &hm) > 0);
ASSERT(mg_http_status(&hm) == 200);
ASSERT(mg_strcmp(hm.body, mg_str("hi\n")) == 0);
ASSERT(first_len + hm.message.len == c.send.len);
mg_iobuf_free(&c.recv);
mg_iobuf_free(&c.send);
}
// Test general get / set functionality
ASSERT(fetch(&mgr, buf, url, "GET /api/get HTTP/1.0\n\n") == 200);
-1
View File
@@ -1 +0,0 @@
../../../mongoose.c
-1
View File
@@ -1 +0,0 @@
../../../mongoose.h
-1
View File
@@ -1 +0,0 @@
../../../mongoose.c
-1
View File
@@ -1 +0,0 @@
../../../mongoose.h
@@ -1 +0,0 @@
../../../mongoose.c
@@ -1 +0,0 @@
../../../mongoose.h
-1
View File
@@ -1 +0,0 @@
../../../mongoose.c
-1
View File
@@ -1 +0,0 @@
../../../mongoose.h
@@ -1 +0,0 @@
../../../mongoose.c
@@ -1 +0,0 @@
../../../mongoose.h
-1
View File
@@ -1 +0,0 @@
../../http/device-dashboard/net.c
-1
View File
@@ -1 +0,0 @@
../../http/device-dashboard/net.h
@@ -1 +0,0 @@
../../http/device-dashboard/packed_fs.c
-1
View File
@@ -1 +0,0 @@
../../../mongoose.c
-1
View File
@@ -1 +0,0 @@
../../../mongoose.h
-1
View File
@@ -1 +0,0 @@
../../../mongoose.c
-1
View File
@@ -1 +0,0 @@
../../../mongoose.h
+3 -2
View File
@@ -1,8 +1,9 @@
PROG ?= example # Program we are building
DELETE = rm -rf # Command to remove files
OUT ?= -o $(PROG) # Compiler argument for output file
SOURCES = main.c mongoose.c packed_fs.c # Source code files
CFLAGS = -W -Wall -Wextra -g -I. # Build options
REPO_ROOT ?= ../../..
SOURCES = main.c $(REPO_ROOT)/mongoose.c packed_fs.c # Source code files
CFLAGS = -I$(REPO_ROOT) -W -Wall -Wextra -g -I. # Build options
PACK = ./pack # Utility to pack files into a packed filesystem
# Mongoose build options. See https://mongoose.ws/docs/getting-started/build-environment/
@@ -1 +0,0 @@
../../../mongoose.c
@@ -1 +0,0 @@
../../../mongoose.h
+3 -2
View File
@@ -1,5 +1,6 @@
SOURCES = main.c mongoose.c # Source code files
CFLAGS = -W -Wall -Wextra -g -I. # Build options
REPO_ROOT ?= ../../../..
SOURCES = main.c $(REPO_ROOT)/mongoose.c # Source code files
CFLAGS = -I$(REPO_ROOT) -W -Wall -Wextra -g -I. # Build options
# O(1) Heap
SOURCES += o1heap/o1heap/o1heap.c
-1
View File
@@ -1 +0,0 @@
../../../../mongoose.c
-1
View File
@@ -1 +0,0 @@
../../../../mongoose.h
+3 -2
View File
@@ -1,5 +1,6 @@
SOURCES = main.c mongoose.c # Source code files
CFLAGS = -W -Wall -Wextra -g -I. # Build options
REPO_ROOT ?= ../../..
SOURCES = main.c $(REPO_ROOT)/mongoose.c # Source code files
CFLAGS = -I$(REPO_ROOT) -W -Wall -Wextra -g -I. # Build options
# Mongoose build options. See https://mongoose.ws/docs/getting-started/build-environment/
CFLAGS_MONGOOSE +=
@@ -1 +0,0 @@
../../../mongoose.c
@@ -1 +0,0 @@
../../../mongoose.h
+3 -2
View File
@@ -1,5 +1,6 @@
SOURCES = main.c mongoose.c # Source code files
CFLAGS = -W -Wall -Wextra -g -I. # Build options
REPO_ROOT ?= ../../..
SOURCES = main.c $(REPO_ROOT)/mongoose.c # Source code files
CFLAGS = -I$(REPO_ROOT) -W -Wall -Wextra -g -I. # Build options
# Mongoose build options. See https://mongoose.ws/docs/getting-started/build-environment/
CFLAGS_MONGOOSE +=
-1
View File
@@ -1 +0,0 @@
../../../mongoose.c
-1
View File
@@ -1 +0,0 @@
../../../mongoose.h
+3 -2
View File
@@ -1,8 +1,9 @@
PROG ?= example # Program we are building
DELETE = rm -rf # Command to remove files
OUT ?= -o $(PROG) # Compiler argument for output file
SOURCES = main.c mongoose.c # Source code files
CFLAGS = -W -Wall -Wextra -g -I. # Build options
REPO_ROOT ?= ../../..
SOURCES = main.c $(REPO_ROOT)/mongoose.c # Source code files
CFLAGS = -I$(REPO_ROOT) -W -Wall -Wextra -g -I. # Build options
# Mongoose build options. See https://mongoose.ws/docs/getting-started/build-environment/
CFLAGS_MONGOOSE += -DMG_ENABLE_LINES
-1
View File
@@ -1 +0,0 @@
../../../mongoose.c
-1
View File
@@ -1 +0,0 @@
../../../mongoose.h
+11 -1
View File
@@ -9,9 +9,18 @@ all: example
example:
true
build: Makefile $(wildcard main/*)
build: Makefile $(wildcard main/*) main/net.c main/net.h main/packed_fs.c
$(DOCKER) $(CMD)
main/net.c: ../../http/device-dashboard/net.c main/net.h
cp $< $@
main/net.h: ../../http/device-dashboard/net.h
cp $< $@
main/packed_fs.c: ../../http/device-dashboard/packed_fs.c
cp $< $@
flash:
flash: CMD = idf.py flash
flash: DA = --device $(PORT)
@@ -36,3 +45,4 @@ flash3:
clean:
test -d build && $(DOCKER) rm -rf build sdkconfig || true
rm -f main/net.c main/net.h main/packed_fs.c
@@ -2,6 +2,8 @@ idf_component_register(SRCS "main.c"
"wifi.c"
"net.c"
"packed_fs.c"
"mongoose.c")
"../../../../mongoose.c"
INCLUDE_DIRS "."
"../../../..")
component_compile_options(-DHTTP_URL="http://0.0.0.0:80")
component_compile_options(-DHTTPS_URL="https://0.0.0.0:443")
@@ -1 +0,0 @@
../../../../mongoose.c
@@ -1 +0,0 @@
../../../../mongoose.h
@@ -1 +0,0 @@
../../../http/device-dashboard/net.c
@@ -1 +0,0 @@
../../../http/device-dashboard/net.h
@@ -1 +0,0 @@
../../../http/device-dashboard/packed_fs.c
+8 -2
View File
@@ -8,9 +8,15 @@ all: example
example:
true
build: Makefile $(wildcard main/*)
build: Makefile $(wildcard main/*) main/net.c main/packed_fs.c
docker run --rm $(DA) -v $(MNT):$(MNT) -w $(CWD) espressif/idf idf.py $(CMD)
main/net.c: ../../http/uart-bridge/net.c
cp $< $@
main/packed_fs.c: ../../http/uart-bridge/packed_fs.c
cp $< $@
flash:
flash: CMD = flash
flash: DA = --device $(PORT)
@@ -29,4 +35,4 @@ flash2: bridge.hex
esputil -p $(PORT) monitor
clean:
rm -rf build
rm -rf build main/net.c main/packed_fs.c
@@ -4,5 +4,7 @@ idf_component_register(SRCS "main.c"
"cli.c"
"net.c"
"packed_fs.c"
"mongoose.c")
"../../../../mongoose.c"
INCLUDE_DIRS "."
"../../../..")
component_compile_options(-DUART_API_IMPLEMENTED=1)
@@ -1 +0,0 @@
../../../../mongoose.c
@@ -1 +0,0 @@
../../../../mongoose.h
-1
View File
@@ -1 +0,0 @@
../../../http/uart-bridge/net.c
@@ -1 +0,0 @@
../../../http/uart-bridge/packed_fs.c
+2 -2
View File
@@ -29,8 +29,8 @@ web_root/bundle.js:
curl -s https://npm.reversehttp.com/preact,preact/hooks,htm/preact,preact-router -o $@
# Generate packed filesystem for serving Web UI
packed_fs.c: $(wildcard web_root/*) $(wildcard certs/*) Makefile web_root/bundle.js
node pack.js $(addsuffix ::gzip, $(wildcard web_root/*)) certs/* > $@
packed_fs.c: $(wildcard web_root/*) $(wildcard certs/*) Makefile ../../../test/pack.js web_root/bundle.js
node ../../../test/pack.js $(addsuffix ::gzip, $(wildcard web_root/*)) certs/* > $@
mbedtls:
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@
-1
View File
@@ -1 +0,0 @@
../../../test/pack.js
+6 -2
View File
@@ -24,8 +24,12 @@ endif
all: $(PROG) # Default target. Build and run program
$(RUN) ./$(PROG) $(ARGS)
$(PROG): $(SOURCES) # Build program from sources
$(PROG): $(SOURCES) certs/ca.pem # Build program from sources
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
certs/ca.pem: ../../../test/data/ca.pem
mkdir -p certs
cp $< $@
clean: # Cleanup. Delete built program and all build artifacts
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls $(PACK)
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls $(PACK) certs/ca.pem
-1
View File
@@ -1 +0,0 @@
../../../../test/data/ca.pem
+4 -1
View File
@@ -27,8 +27,11 @@ all: $(PROG) # Default target. Build and run program
$(PROG): $(SOURCES) # Build program from sources
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
packed_fs.c: ../http-client/packed_fs.c
cp $< $@
clean: # Cleanup. Delete built program and all build artifacts
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls packed_fs.c
# see https://mongoose.ws/tutorials/tls/#how-to-build for TLS build options
@@ -1 +0,0 @@
../http-client/packed_fs.c
+4 -1
View File
@@ -24,8 +24,11 @@ all: $(PROG) # Default target. Build and run program
$(PROG): $(SOURCES) # Build program from sources
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
packed_fs.c: ../http-client/packed_fs.c
cp $< $@
clean: # Cleanup. Delete built program and all build artifacts
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls packed_fs.c
# see https://mongoose.ws/tutorials/tls/#how-to-build for TLS build options
@@ -1 +0,0 @@
../http-client/packed_fs.c
+10 -2
View File
@@ -20,14 +20,22 @@ ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC:
OUT ?= -o $(PROG) # Build output
endif
all: $(PROG) # Default target. Build and run program
CERTS = certs/ca.crt certs/ca.key certs/ca.srl certs/client.crt certs/client.csr \
certs/client.key certs/generate.sh certs/server.crt certs/server.csr \
certs/server.key
all: $(CERTS) $(PROG) # Default target. Build and run program
$(RUN) ./$(PROG) $(ARGS)
certs/%: ../../../test/certs/%
mkdir -p certs
cp $< $@
$(PROG): $(SOURCES) # Build program from sources
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
clean: # Cleanup. Delete built program and all build artifacts
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM certs/*
vc98: CC = cl
-1
View File
@@ -1 +0,0 @@
../../../test/certs
@@ -24,8 +24,11 @@ all: $(PROG) # Default target. Build and run program
$(PROG): $(SOURCES) # Build program from sources
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
packed_fs.c: ../http-client/packed_fs.c
cp $< $@
clean: # Cleanup. Delete built program and all build artifacts
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls packed_fs.c
# see https://mongoose.ws/tutorials/tls/#how-to-build for TLS build options
@@ -1 +0,0 @@
../http-client/packed_fs.c
+14 -5
View File
@@ -20,14 +20,23 @@ endif
all: $(PROG) # Default target. Build and run program
$(RUN) $(PROG) $(ARGS)
web_root/bundle.js:
curl -s https://npm.reversehttp.com/preact,preact/hooks,htm/preact,preact-router -o $@
web_root/bundle.js: ../device-dashboard/web_root/bundle.js
cp $< $@
packed_fs.c: $(wildcard web_root/*) Makefile web_root/bundle.js
node pack.js $(addsuffix ::gzip, $(wildcard web_root/*)) > $@
web_root/components.js: ../device-dashboard/web_root/components.js
cp $< $@
web_root/history.min.js: ../device-dashboard/web_root/history.min.js
cp $< $@
web_root/index.html: ../device-dashboard/web_root/index.html
cp $< $@
packed_fs.c: $(wildcard web_root/*) Makefile ../../../test/pack.js web_root/bundle.js web_root/components.js web_root/history.min.js web_root/index.html
node ../../../test/pack.js $(addsuffix ::gzip, $(wildcard web_root/*)) > $@
$(PROG): $(SOURCES) # Build program from sources
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
clean: # Cleanup. Delete built program and all build artifacts
$(DELETE) $(PROG) $(PACK) *.o *.obj *.exe *.dSYM
$(DELETE) $(PROG) $(PACK) *.o *.obj *.exe *.dSYM web_root/bundle.js web_root/components.js web_root/history.min.js web_root/index.html
@@ -1 +0,0 @@
../../../test/pack.js
@@ -1 +0,0 @@
../../device-dashboard/web_root/bundle.js
@@ -1 +0,0 @@
../../device-dashboard/web_root/components.js
@@ -1 +0,0 @@
../../device-dashboard/web_root/history.min.js
@@ -1 +0,0 @@
../../device-dashboard/web_root/index.html
@@ -1,4 +1,5 @@
CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion
REPO_ROOT ?= ../../../..
CFLAGS = -I$(REPO_ROOT) -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion
CFLAGS += -Wformat-truncation -fno-common -Wconversion
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include
@@ -9,7 +10,7 @@ LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--
SOURCES = main.c syscalls.c startup.c
# Mongoose-specific source code files and build options. See https://mongoose.ws/docs/getting-started/build-environment/
SOURCES += mongoose.c net.c packed_fs.c
SOURCES += $(REPO_ROOT)/mongoose.c net.c packed_fs.c
CFLAGS += -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_ARMGCC -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_LINES=1
CFLAGS += -DMG_ENABLE_DRIVER_SAME54=1 -DMG_ENABLE_CUSTOM_RANDOM=1 $(CFLAGS_EXTRA)
@@ -39,6 +40,15 @@ cmsis_sam:
curl -sL https://packs.download.microchip.com/Microchip.SAME54_DFP.3.9.244.atpack -o $@.zip
mkdir $@ && cd $@ && unzip ../$@.zip
net.c: ../../../http/device-dashboard/net.c net.h
cp $< $@
net.h: ../../../http/device-dashboard/net.h
cp $< $@
packed_fs.c: ../../../http/device-dashboard/packed_fs.c
cp $< $@
# Automated test via https://vcon.io/automated-firmware-tests/. Set VCON_API_KEY and update DEVICE_URL
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/9
update: firmware.bin
@@ -50,4 +60,4 @@ test: update
grep 'READY, IP:' /tmp/output.txt # Check for network init
clean:
$(RM) firmware.* cmsis_core cmsis_sam *.zip
$(RM) firmware.* cmsis_core cmsis_sam *.zip net.c net.h packed_fs.c
@@ -1 +0,0 @@
../../../../mongoose.c
@@ -1 +0,0 @@
../../../../mongoose.h
@@ -1 +0,0 @@
../../../http/device-dashboard/net.c
@@ -1 +0,0 @@
../../../http/device-dashboard/net.h
@@ -1 +0,0 @@
../../../http/device-dashboard/packed_fs.c
@@ -1,4 +1,5 @@
CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion
REPO_ROOT ?= ../../../..
CFLAGS = -I$(REPO_ROOT) -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion
CFLAGS += -Wformat-truncation -fno-common -Wconversion
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include
@@ -9,7 +10,7 @@ LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--
SOURCES = main.c syscalls.c startup.c
# Mongoose-specific source code files and build options. See https://mongoose.ws/docs/getting-started/build-environment/
SOURCES += mongoose.c
SOURCES += $(REPO_ROOT)/mongoose.c
CFLAGS += -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_ARMGCC -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_LINES=1
CFLAGS += -DMG_ENABLE_DRIVER_SAME54=1 -DMG_ENABLE_CUSTOM_RANDOM=1 $(CFLAGS_EXTRA)
@@ -1 +0,0 @@
../../../../mongoose.c
@@ -1 +0,0 @@
../../../../mongoose.h
@@ -1 +0,0 @@
../../mongoose/micropython.cmake
@@ -0,0 +1,18 @@
# Create an INTERFACE library for our C module.
add_library(usermod_mongoose INTERFACE)
# Add our source files to the lib
target_sources(usermod_mongoose INTERFACE
${CMAKE_CURRENT_LIST_DIR}/../../mongoose/module.c
${CMAKE_CURRENT_LIST_DIR}/../../../../mongoose.c
${CMAKE_CURRENT_LIST_DIR}/main.c
)
# Add the current directory as an include directory.
target_include_directories(usermod_mongoose INTERFACE
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/../../../../
)
# Link our INTERFACE library to the usermod target.
target_link_libraries(usermod INTERFACE usermod_mongoose)
@@ -1 +0,0 @@
../../mongoose/micropython.mk
@@ -1 +0,0 @@
../../mongoose/module.c
@@ -1 +0,0 @@
../../../../mongoose.c
@@ -1 +0,0 @@
../../../../mongoose.h
@@ -4,13 +4,14 @@ add_library(usermod_mongoose INTERFACE)
# Add our source files to the lib
target_sources(usermod_mongoose INTERFACE
${CMAKE_CURRENT_LIST_DIR}/module.c
${CMAKE_CURRENT_LIST_DIR}/mongoose.c
${CMAKE_CURRENT_LIST_DIR}/../../../mongoose.c
${CMAKE_CURRENT_LIST_DIR}/main.c
)
# Add the current directory as an include directory.
target_include_directories(usermod_mongoose INTERFACE
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/../../..
)
# Link our INTERFACE library to the usermod target.
@@ -2,8 +2,8 @@ CEXAMPLE_MOD_DIR := $(USERMOD_DIR)
# Add all C files to SRC_USERMOD.
SRC_USERMOD += $(CEXAMPLE_MOD_DIR)/module.c
SRC_USERMOD += $(CEXAMPLE_MOD_DIR)/mongoose.c
SRC_USERMOD += $(CEXAMPLE_MOD_DIR)/../../../mongoose.c
SRC_USERMOD += $(CEXAMPLE_MOD_DIR)/main.c
# add our module folder to include paths
CFLAGS_USERMOD += -I$(CEXAMPLE_MOD_DIR)
CFLAGS_USERMOD += -I$(CEXAMPLE_MOD_DIR) -I$(CEXAMPLE_MOD_DIR)/../../..
@@ -1 +0,0 @@
../../../mongoose.c
@@ -1 +0,0 @@
../../../mongoose.h
+4 -1
View File
@@ -24,8 +24,11 @@ all: $(PROG) # Default target. Build and run program
$(PROG): $(SOURCES) # Build program from sources
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
packed_fs.c: ../../http/http-client/packed_fs.c
cp $< $@
clean: # Cleanup. Delete built program and all build artifacts
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls packed_fs.c
# see https://mongoose.ws/tutorials/tls/#how-to-build for TLS build options
@@ -1 +0,0 @@
../../http/http-client/packed_fs.c
@@ -1 +0,0 @@
../../../../mongoose.c
@@ -1 +0,0 @@
../../../../mongoose.h
@@ -1,4 +1,5 @@
CFLAGS = -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion
REPO_ROOT ?= ../../..
CFLAGS = -I$(REPO_ROOT) -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion
CFLAGS += -Wformat-truncation -fno-common -Wconversion -Wno-sign-conversion
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include
@@ -7,7 +8,7 @@ CFLAGS += -Icmsis_mcu/ra/fsp/src/bsp/mcu/all
CFLAGS += -mcpu=cortex-m33 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard $(CFLAGS_EXTRA)
LDFLAGS ?= -Tlink.ld -nostdlib -nostartfiles --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
SOURCES = main.c hal.c mongoose.c net.c packed_fs.c
SOURCES = main.c hal.c $(REPO_ROOT)/mongoose.c net.c packed_fs.c
# CMSIS startup and system files are deeply tied to the BSP, and we don't use it. See hal.c
# Example specific build options. See README.md
@@ -37,6 +38,15 @@ cmsis_core: # ARM CMSIS core headers
cmsis_mcu:
git clone -q --depth 1 -b v5.1.0 https://github.com/renesas/fsp $@
net.c: ../../http/device-dashboard/net.c net.h
cp $< $@
net.h: ../../http/device-dashboard/net.h
cp $< $@
packed_fs.c: ../../http/device-dashboard/packed_fs.c
cp $< $@
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/14
@@ -50,4 +60,4 @@ test: update
grep 'READY, IP:' /tmp/output.txt # Check for network init
clean:
$(RM) firmware.* *.su cmsis_core cmsis_mcu mbedtls *.zip
$(RM) firmware.* *.su cmsis_core cmsis_mcu mbedtls *.zip net.c net.h packed_fs.c
Loaded 100 of 145 files, more files were not shown because too many files have changed in this diff. Show more