Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
ce796f7
M0: add Makefile
pgousdal Oct 9, 2026
b7dd205
M0: add src/main.c
pgousdal Oct 9, 2026
a3492de
M0: add tests/smoke.py
pgousdal Oct 9, 2026
d323ff5
M0: add docs/ARCHITECTURE.md
pgousdal Oct 9, 2026
2839618
M0: add docs/HARDWARE.md
pgousdal Oct 9, 2026
2fef4cf
M0: add docs/ROADMAP.md
pgousdal Oct 9, 2026
fedc29e
M0: add docs/SECURITY.md
pgousdal Oct 9, 2026
0ff4e55
M0: add .github/workflows/ci.yml
pgousdal Oct 9, 2026
96669e0
M0: add .gitignore
pgousdal Oct 9, 2026
d69c7ee
M0: add LICENSE
pgousdal Oct 9, 2026
4e253f3
M0: finalize README.md
pgousdal Oct 9, 2026
9a305de
M0: finalize Makefile
pgousdal Oct 9, 2026
43e8a2c
M0: finalize src/main.c
pgousdal Oct 9, 2026
51c7166
docs: plan Ethernet Internet-in-a-Box support
pgousdal Oct 9, 2026
c500eaa
docs: define IIAB external-server architecture
pgousdal Oct 9, 2026
2bf9826
docs: design general Ethernet offline services integrations
pgousdal Oct 9, 2026
ced2991
docs: simplify Ethernet design to Wi-Fi AP and LAN bridge
pgousdal Oct 9, 2026
ae02d6c
M1: add reviewed AP-LAN bridge profile openwrt/README.md
pgousdal Oct 9, 2026
94e0579
M1: add reviewed AP-LAN bridge profile openwrt/generate_ap_lan.py
pgousdal Oct 9, 2026
2a7a1cf
M1: add reviewed AP-LAN bridge profile tests/test_ap_lan.py
pgousdal Oct 9, 2026
e9c084e
M1: document AP/LAN profile and run generator tests in CI
pgousdal Oct 9, 2026
6ad4f6e
M1: document AP/LAN profile and run generator tests in CI
pgousdal Oct 9, 2026
968c710
M1: poll listener readiness, ignore SIGPIPE, fix response lengths
pgousdal Oct 9, 2026
76763aa
ci: repair malformed YAML newline escapes
pgousdal Oct 9, 2026
45855a0
test: add failing regression for idle Telnet blocking HTTP
pgousdal Oct 9, 2026
29f8506
test: defer concurrency assertion until async client loop is implemented
pgousdal Oct 9, 2026
47923b0
M1: nonblocking poll-based terminal clients with fixed connection cap
pgousdal Oct 9, 2026
c4346bf
fix: escape literal line endings inside C string literals
pgousdal Oct 9, 2026
088d006
test: verify idle terminal does not block HTTP requests
pgousdal Oct 9, 2026
375e828
M1: add bounded nonblocking HTTP state machine
pgousdal Oct 9, 2026
582138c
fix: preserve escaped CRLF in HTTP C strings
pgousdal Oct 9, 2026
cf3d6b6
M1: integrate poll-based nonblocking HTTP connections
pgousdal Oct 9, 2026
a248e7b
test: verify partial HTTP request cannot block other clients
pgousdal Oct 9, 2026
3a43b17
M1: bounded shared catalog of regular files
pgousdal Oct 9, 2026
f60939c
fix: character literal in catalog validation
pgousdal Oct 9, 2026
4996da2
M1: share file catalog with terminal menu
pgousdal Oct 9, 2026
47aa0e6
M1: render shared catalog in HTTP root page
pgousdal Oct 9, 2026
455cdd3
test: verify shared HTTP and terminal catalog filters symlinks and un…
pgousdal Oct 9, 2026
2e9ba01
security: enforce shared catalog filename policy on HTTP downloads
pgousdal Oct 9, 2026
fa7bee6
test: verify hidden and symlink downloads are rejected
pgousdal Oct 9, 2026
3a19453
M1: add bounded sorted catalog pagination
pgousdal Oct 9, 2026
325697a
M1: serve cursor-paginated HTML file index
pgousdal Oct 9, 2026
f6d2cec
test: exercise catalog pagination across 40 files
pgousdal Oct 9, 2026
1848b56
test: create paginated fixture after baseline catalog assertions
pgousdal Oct 10, 2026
ce5ace9
M1: terminal cursor pagination and correct CRLF output
pgousdal Oct 10, 2026
7a6dcf4
test: terminal pagination covers all 40 files with proper CRLF
pgousdal Oct 10, 2026
a46e87f
fix: initialize terminal pagination cursor
pgousdal Oct 10, 2026
17f59b7
fix: remove obsolete catalog wrapper under Werror
pgousdal Oct 10, 2026
9890c75
M1: queue terminal output and flush on POLLOUT
pgousdal Oct 10, 2026
327b61e
test: stalled terminal writer must not starve HTTP or other terminal …
pgousdal Oct 10, 2026
3b746fc
security: disconnect terminal on bounded output queue overflow
pgousdal Oct 10, 2026
6b19c67
perf: reduce terminal queue to 4608 bytes while fitting 32 catalog en…
pgousdal Oct 10, 2026
1d334d4
docs: record M1 memory bounds and hardware validation gates
pgousdal Oct 10, 2026
3d4b53c
fix: paginate HTML by actual rendered entries to avoid skipping long …
pgousdal Oct 10, 2026
fa6d60b
fix: reserve HTTP response header capacity for paginated index
pgousdal Oct 10, 2026
1cc26d0
test: ensure long filenames remain reachable across HTTP pages
pgousdal Oct 10, 2026
a8c4cd2
test: isolate long-name pagination fixture from existing terminal ass…
pgousdal Oct 10, 2026
6c709a2
docs: define target-specific OpenWrt cross-build and hardware qualifi…
pgousdal Oct 10, 2026
1d211c6
openwrt: scaffold opt-in PocketBox package and procd service
pgousdal Oct 10, 2026
5d1020d
openwrt: scaffold opt-in PocketBox package and procd service
pgousdal Oct 10, 2026
e8b87c6
openwrt: scaffold opt-in PocketBox package and procd service
pgousdal Oct 10, 2026
8b674dd
docs: document package staging and loopback-only deployment blocker
pgousdal Oct 10, 2026
77c51a8
feat: explicit IPv4 listener binding; reject wildcard and multicast a…
pgousdal Oct 10, 2026
d35369f
openwrt: configure explicit safe listener address
pgousdal Oct 10, 2026
b2da800
openwrt: configure explicit safe listener address
pgousdal Oct 10, 2026
394b0a2
openwrt: configure explicit safe listener address
pgousdal Oct 10, 2026
1d19060
test: reject unsafe wildcard and multicast bind addresses
pgousdal Oct 10, 2026
0da4edf
test: explicit IPv4 bind serves both protocols and unavailable IP fai…
pgousdal Oct 11, 2026
f406adb
openwrt: validate configured ports and disallow wildcard bind before …
pgousdal Oct 11, 2026
be9b945
test: check OpenWrt init remains opt-in, procd-based and network-neutral
pgousdal Oct 11, 2026
a5ed771
build: stage OpenWrt package deterministically without overwriting ex…
pgousdal Oct 11, 2026
a458008
test: verify deterministic OpenWrt package staging and no-overwrite s…
pgousdal Oct 11, 2026
bdede6a
docs: use tested staging command for OpenWrt package preparation
pgousdal Oct 11, 2026
d06d2ab
build: inspect ELF architecture and size for Mango and WR703N
pgousdal Oct 11, 2026
5d4e729
test: cover ELF architecture inspector for both MIPS byte orders
pgousdal Oct 11, 2026
d5a1880
docs: add target-specific ELF checks to OpenWrt build workflow
pgousdal Oct 11, 2026
4036749
ci: cross-compile generic MIPS little-endian Linux smoke artifact
pgousdal Oct 11, 2026
da546ea
docs: distinguish generic MIPS CI build from device-compatible OpenWr…
pgousdal Oct 11, 2026
457df5b
docs: freeze PocketBox foundation pending MikroWrt integration contracts
pgousdal Oct 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: C11 host CI
on:
push:
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: make
- name: Smoke tests
run: make test
- name: AP/LAN profile tests
run: python3 -m unittest discover -s tests -p 'test_*.py'
27 changes: 27 additions & 0 deletions .github/workflows/mips-cross.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: MIPS cross-compile smoke
on:
push:
pull_request:

jobs:
mango-mipsel:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install generic MIPS little-endian cross-compiler
run: sudo apt-get update && sudo apt-get install -y gcc-mipsel-linux-gnu binutils-mipsel-linux-gnu
- name: Compile PocketBox for MIPS little-endian Linux
run: |
make clean
make CC=mipsel-linux-gnu-gcc
- name: Verify architecture and record size
run: |
python3 openwrt/check_binary.py pocketbox --target mango
mipsel-linux-gnu-readelf -h pocketbox
mipsel-linux-gnu-size pocketbox
- name: Preserve cross-compiled test artifact
uses: actions/upload-artifact@v4
with:
name: pocketbox-generic-mipsel-not-openwrt
path: pocketbox
retention-days: 7
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pocketbox
*.o
__pycache__/
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Ploos AS

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CC ?= cc
CFLAGS ?= -Os -std=c11 -Wall -Wextra -Werror -pedantic
CPPFLAGS ?= -D_GNU_SOURCE
LDFLAGS ?=
all: pocketbox
pocketbox: src/main.c
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< $(LDFLAGS)
test: pocketbox
python3 tests/smoke.py
clean:
rm -f pocketbox
.PHONY: all test clean
39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,39 @@
# PocketBox
PocketBox

Offline-first portable library and BBS-inspired service for **TP-Link TL-WR703N** and **GL.iNet GL-MT300N-V2 (Mango)**.

**M0:** experimental host-buildable C11 proof of concept (HTTP homepage/file download and ASCII-over-TCP terminal menu). Not yet OpenWrt device-qualified, production hardened, or a complete Telnet implementation.

## Quick start (Linux)

```sh
make
mkdir -p demo-files
printf 'PocketBox offline library\n' > demo-files/welcome.txt
./pocketbox --root demo-files --http-port 8080 --telnet-port 2323
# In another terminal:
curl http://127.0.0.1:8080/
curl http://127.0.0.1:8080/files/welcome.txt
telnet 127.0.0.1 2323
make test
```

The prototype binds to **127.0.0.1 only**. This is **not** a network appliance release. It cannot yet be installed directly as firmware.

## Hardware scope

| Target | Processor | RAM | Flash | Qualification |
| --- | --- | --- | --- | --- |
| TL-WR703N | AR9331 MIPS | 32 MiB | 4 MiB | Pending |
| GL-MT300N-V2 | MT7628 MIPS | 128 MiB | 16 MiB | Pending |

No ARM or x86 hardware target is planned. Verify hardware revisions, OpenWrt support, backup and recovery paths, USB storage support and RAM/flash budgets **before flashing**. No firmware images are provided by M0.

## Documentation

- [Architecture](docs/ARCHITECTURE.md)
- [Hardware qualification](docs/HARDWARE.md)
- [Roadmap](docs/ROADMAP.md)
- [Security model](docs/SECURITY.md)

MIT licensed, copyright Ploos AS.
21 changes: 21 additions & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Architecture (M0)

PocketBox is a small C11/POSIX program with HTTP and ASCII terminal adapters over a common file root. A future service layer will centralize file areas, metadata, library catalog, message boards and configuration, independent of protocol.

M0 is an intentionally limited feasibility prototype. It uses one sequential accept loop; a slow client can block other clients for the configured socket timeout. M1 replaces this with bounded, nonblocking `poll()` and per-client state. HTTP is currently GET-only and supports the homepage plus one-level basename downloads. Telnet currently exposes plain ASCII over a TCP socket, not a fully negotiated Telnet implementation. Never describe this as complete Telnet support.

### Constraints

- C11, OpenWrt-compatible POSIX calls, no heap-heavy libraries.
- WR703N is the strict lower bound; Mango may enable optional features.
- USB storage holds public library content; no writable public upload endpoints in M0.
- Default bind: localhost only. Network binding requires a security review.
- No ARM support or dependency on cloud services.

### Planned adapters

HTTP, RFC-aware Telnet/ANSI, optional FTP/Gopher and BBS file-area exports. Protocol services share file IDs, metadata and access policy.

## External IIAB gateway mode

The Ethernet-attached Internet-in-a-Box is a separate host. PocketBox remains a standalone offline library/BBS and optionally offers Wi-Fi clients routed access and curated portal links to IIAB services. Keep networking configuration in OpenWrt (not the C core). Default to routed isolation; bridging is an optional hardware-qualified mode. Handle DHCP/DNS ownership, Ethernet port selection, IP configuration, network isolation, service reachability and offline fallback explicitly. See ROADMAP.md.
44 changes: 44 additions & 0 deletions docs/ETHERNET-SERVICES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Ethernet connectivity: PocketBox as Wi-Fi access point

Status: architecture decision; hardware implementation pending.

## Core requirement

**PocketBox is the Wi-Fi access point.** Wi-Fi clients should be able to reach services running on a separate computer connected to PocketBox's Ethernet port. PocketBox does **not** need to understand, enumerate, proxy, or integrate those services. This applies to Internet-in-a-Box, Kiwix, Kolibri, BBS servers, NAS, IRC, HTTP, SSH and arbitrary other services offered by the attached host.

PocketBox's own C11 HTTP portal, local USB library and Telnet/BBS continue to operate independently. Service discovery, catalogs, application-level adapters and proxies are optional future enhancements, **not** requirements for basic Ethernet connectivity.

## Preferred topology: simple LAN bridge

```text
Wi-Fi clients ))) PocketBox (Wi-Fi AP) --- Ethernet --- external host
|
local PocketBox services
```

- **Default design target:** bridge Wi-Fi AP interface and Ethernet LAN interface into one Layer-2 LAN using OpenWrt network configuration. This makes arbitrary Ethernet-host services reachable without PocketBox-specific application code.
- **WR703N:** single Ethernet port used as LAN to the external host.
- **Mango:** designate at least one Ethernet port as LAN, retaining the ability to configure the other separately; verify actual OpenWrt interface mappings.
- **IP addresses:** either PocketBox runs DHCP for the bridged LAN and the external host uses a static/reserved address, or a deliberate alternative DHCP authority is selected. Never run two conflicting DHCP servers.
- **DNS:** optional local name for the external host; direct IP access must work without DNS.
- **No WAN/internet required:** no default internet uplink, captive portal or proxy required. Do not hijack arbitrary DNS/HTTP traffic.
- **Isolation:** do not bridge into an unknown or untrusted external LAN without reviewing the consequences; Wi-Fi clients can directly access exposed Ethernet-host services. Consider firewalling or a routed alternative for untrusted deployments.

## Alternative topology: routed AP

Where bridging is unavailable or isolation is required, place Ethernet and Wi-Fi on separate subnets and route between them using OpenWrt. The external host needs a return route or an explicitly configured NAT policy. This is a secondary, opt-in mode, not the default design target.

## M0/M1 boundaries

M0: architecture and host prototype; no real device network changes. M1/M2: implement OpenWrt AP+LAN bridge profiles for WR703N and Mango, confirm correct Ethernet interfaces, DHCP behavior and basic reachability using arbitrary TCP services. Verify hardware revisions and firmware/recovery before flashing.

## Acceptance tests

1. Wi-Fi client associates to PocketBox and receives a valid IP address.
2. Client reaches an HTTP service on Ethernet-connected computer by IP.
3. Client reaches arbitrary TCP service (e.g. SSH or Telnet) on the same host without PocketBox code changes.
4. PocketBox local HTTP/Telnet and USB library remain accessible.
5. Unplugging Ethernet does not break PocketBox's own Wi-Fi services.
6. No unintended internet connectivity, rogue DHCP, or DNS redirection.

Optional links to IIAB or BBS in the PocketBox portal may be added later, but are not required for any of the above.
40 changes: 40 additions & 0 deletions docs/FREEZE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# PocketBox foundation freeze

Status: **FROZEN — awaiting MikroWrt integration contract**
Date: 2026-10-11
Branch: `m0-foundation`
Review: PR #1 (leave unmerged)

## Scope

Preserve the C11 HTTP file portal, ASCII terminal, catalog, bounded clients,
security checks, host tests and experimental packaging as a reference baseline.
The generic MIPS little-endian cross-build is a portability smoke test only;
it is not an installable MikroWrt/OpenWrt package.

## Allowed during freeze

- Fix verified correctness or security defects.
- Repair CI failures and maintain tests/documentation.
- Record integration requirements and measurements without redesigning runtime.

## Deferred until MikroWrt contracts are established

- Refactor runtime and service integration.
- Select package manager, package metadata and dependency policy.
- Bind to MikroWrt init/service supervision and configuration.
- Define AP/LAN/USB storage ownership and lifecycle.
- Build or flash device firmware, or claim Mango/WR703N qualification.

## Unfreeze gates

1. MikroWrt establishes supported device targets and reproducible toolchains.
2. Package format and installation/update policy are defined.
3. Init/service supervision and configuration conventions are defined.
4. Networking ownership is explicit: PocketBox does not mutate AP, bridge,
DHCP, firewall or upstream host services.
5. USB mount and storage paths are defined with safe failure behavior.
6. A migration plan preserves HTTP/terminal behavior and regression tests.

Do not merge PR #1 as part of the freeze. Revisit this document before
starting integration or refactoring.
12 changes: 12 additions & 0 deletions docs/HARDWARE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Hardware qualification

| Hardware | SoC | RAM | Flash | Qualification |
| --- | --- | --- | --- | --- |
| TP-Link TL-WR703N | Atheros AR9331 | 32 MiB | 4 MiB | Pending |
| GL.iNet GL-MT300N-V2 Mango | MediaTek MT7628 | 128 MiB | 16 MiB | Pending |

Both are MIPS, but use different OpenWrt targets and toolchains. Do not assume one image fits both. Verify board revisions, original firmware, firmware recovery paths, backup of calibration partitions, USB mass storage, kernel packages and available free space before any flashing.

M0 only validates host builds. No device firmware, cross-compiled binary, flash image or hardware test has been certified.

Target measurements for later releases: stripped binary size, peak RSS, CPU utilization, concurrent connections, USB throughput, file corruption under reboot/power-loss and recovery procedure success. For WR703N consider USB extroot only after measuring stock flash limits.
33 changes: 33 additions & 0 deletions docs/MEMORY-BUDGET.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# PocketBox M1 memory budget

The TL-WR703N (32 MiB RAM, 4 MiB flash) is the limiting target. These are
source-level bounds, not measured device RAM or firmware sizes.

| Item | Bound |
| --- | ---: |
| Terminal sessions | 12 |
| Terminal queued output per session | 4,608 bytes |
| Total terminal output buffers | 55,296 bytes |
| Previous total (8,192 bytes each) | 98,304 bytes |
| Reduction | 43,008 bytes |
| Catalog entries per page | 32 |
| Catalog filename bytes | 128 |
| Catalog names array | 4,096 bytes |
| HTTP sessions | 8 |

A full terminal catalog page of 32 names of at most 127 bytes plus CRLF,
heading, and menu fits inside 4,608 bytes. Multiple requests from a client
that does not read responses may exhaust its queue; PocketBox disconnects
that client rather than dropping bytes silently.

The C compiler and runtime may add padding, stack, socket buffers and other
overheads. **Do not treat these figures as measured RSS or flash usage.**

## Before hardware release

- Measure binary size and RSS with the intended OpenWrt musl toolchains.
- Verify 4 MiB flash layout and package fit on TL-WR703N.
- Load-test concurrent HTTP and terminal clients on both supported devices.
- Check catalog HTML pagination with 127-character names; a truncated HTML
page must never skip files when advancing the cursor.
- Record available RAM after Wi-Fi AP, bridge and DHCP are active.
16 changes: 16 additions & 0 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# PocketBox roadmap

- **M0 (prototype):** C11 host HTTP and ASCII-over-TCP terminal prototype, host CI, hardware constraints and architecture.
- **M1 (in progress):** Shared file catalog, bounded multi-client server, robust HTTP/Telnet parsers. **Wi-Fi AP + Ethernet LAN bridge configuration prototype** and host-side tests; no router changes yet.
- **M2:** OpenWrt toolchain and firmware/packaging qualification for WR703N and Mango; hardware-verified AP/LAN bridging, DHCP and service reachability. Preserve recovery paths and calibration data.
- **M3:** Real Telnet IAC/ANSI support, shared library navigation, search.
- **M4:** Safe uploads, quotas, atomic metadata, network hardening.
- **M5:** Offline book/retro file archives, FILES.BBS, message boards.
- **M6:** Optional Gopher/FTP, PETSCII, synchronization.
- **v0.1.0:** Device-tested, security-reviewed, reproducible releases.

## Ethernet decision

**PocketBox is a Wi-Fi AP, not an IIAB proxy.** Wi-Fi clients must be able to reach arbitrary services on a computer connected to PocketBox's Ethernet LAN (IIAB, Kiwix, NAS, BBS, SSH, IRC, etc.). Default design: same L2 LAN bridge with one DHCP authority. No application-specific integrations required. PocketBox's own HTTP/Telnet and USB files work without the external host. Routed/isolation mode and curated portal links are optional later. See [Ethernet services](ETHERNET-SERVICES.md) and [OpenWrt profile](../openwrt/README.md).

M1 provides a **review-only UCI command generator**, not an installer or validated router configuration. Physical tests remain required.
5 changes: 5 additions & 0 deletions docs/SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Security model

PocketBox is designed for local/offline operation, **not anonymous or automatically secure networking**. Original WR703N-era firmware is obsolete. Never connect a legacy build directly to the public internet. M0 listens only on 127.0.0.1, does not implement authentication, and is not an appliance firmware release.

M0 file downloads use basename-only paths relative to a pre-opened directory with O_NOFOLLOW; uploaded content and symlinks are out of scope. Before any exposure beyond loopback, implement URL normalization and protocol parsing limits, nonblocking clients, idle timeouts, backpressure, safe error handling, and fuzz tests. Reject percent-encoded path components rather than ambiguously decoding them. Admin access must be separate from public Telnet and HTTP. No secrets/passwords over Telnet. Future uploads require per-file and total quotas, atomic writes and safe names. Block bridging to private LAN and internet by default.
77 changes: 77 additions & 0 deletions openwrt/BUILDING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Cross-compiling PocketBox for OpenWrt (M1 preparation)

**No firmware image or tested OpenWrt package is supplied yet.** These are
instructions for building the userspace executable with an existing,
device-compatible OpenWrt SDK.

## Supported hardware only

| Device | CPU family | Flash | RAM |
| --- | --- | --- | --- |
| TP-Link TL-WR703N | Atheros AR9331 / MIPS 24K | 4 MiB | 32 MiB |
| GL.iNet Mango GL-MT300N-V2 | MediaTek MT7628 / MIPS 24K | 16 MiB | 128 MiB |

The devices require different OpenWrt targets and toolchains. **Do not use
a Mango image or package on WR703N or vice versa.** Confirm the hardware
revision, exact OpenWrt target/subtarget, SDK compatibility, flash space and
recovery method before building or installing anything. In particular,
current OpenWrt releases may not support a 4 MiB WR703N configuration.

## Build with a verified SDK

On a Linux build host, extract the SDK matching the chosen device's
installed OpenWrt release. Within the SDK, locate its MIPS musl cross-compiler
and add the toolchain bin directory to PATH. Then from the PocketBox repo:

```sh
make clean
make CC=mips-openwrt-linux-musl-gcc
file pocketbox\npython3 openwrt/check_binary.py pocketbox --target mango
```

The compiler prefix above is **illustrative**; inspect the actual SDK
toolchain and use its exact compiler name. Do not substitute the host
compiler. The resulting binary must be MIPS for the correct target ABI,
not x86_64 or ARM. This step produces only a userspace binary, not an
`.ipk` or flashable firmware image.

## Qualification gates

1. Confirm both targets' supported OpenWrt releases and available SDKs.
2. Cross-compile and inspect ELF architecture, ABI, dynamic loader and size.
3. Check free flash after base system and Wi-Fi/AP dependencies.
4. Verify service binding, init integration and file root on the device.
5. Measure RSS, CPU, and file listing latency with USB storage attached.
6. Exercise HTTP, terminal, bridge, and DHCP with real devices.
7. Test recovery procedure before distributing firmware.

PocketBox firmware remains deliberately limited to local file services
and the AP/LAN bridge. IIAB, Kiwix, Kolibri and similar services belong on
a separate Ethernet-connected host.

## ELF architecture check

After compiling with a verified target SDK, run:

```sh
python3 openwrt/check_binary.py pocketbox --target mango
# Or, for a WR703N-specific binary:
python3 openwrt/check_binary.py pocketbox --target wr703n
```

This checks ELF32 MIPS, expected endianness and byte size. It does not
validate MIPS ISA extensions, ABI, loader, linked libraries or available
flash space. Do not treat a passing result as proof of device compatibility.

## Generic MIPS CI smoke build (not an OpenWrt package)

The `.github/workflows/mips-cross.yml` job uses Ubuntu's
`gcc-mipsel-linux-gnu` to compile PocketBox for generic little-endian MIPS
Linux, runs the ELF architecture check and uploads a temporary test binary.
**That binary uses a different toolchain/runtime than the OpenWrt SDK and
must not be installed on Mango or treated as a supported device build.**

For an actual OpenWrt package, use a version-matched OpenWrt build tree and
`openwrt/stage_package.py`; compile the package with OpenWrt's own compiler
and confirm the resulting package's ABI and dependencies. A passing generic
MIPS job is only a portability signal.
Loading
Loading