Commit Graph
1166 Commits
Author SHA1 Message Date
Justin Mitchell c3c2d7b099 Merge remote-tracking branch 'origin/develop' into feat-bluetooth 2026-08-07 05:38:14 -04:00
Justin Mitchell bcb8a74fad Add weak fallback for _btLibraryInUse symbol
Provides a weak definition of _btLibraryInUse to fix linker errors when using BLE controller-only builds with NimBLE-Arduino host. The arduino-esp32 core references this symbol but only defines it when IDF host stacks are enabled. This shim ensures the symbol is always available without conflicts.
2026-08-07 05:32:34 -04:00
Justin Mitchell 2c8bd8ea1a Fix heap check to exclude framebuffer from threshold
The framebuffer loan provides a large contiguous block for inflate but cannot satisfy small allocations during CSS parsing and layout. Including it in the heap check made the threshold effectively always-false (48KB > 40KB floor), allowing builds to run at ~3KB free heap and crash in sscanf when BLE is connected. Now checks only general heap so BLE recovery runs before the build instead of crashing during it.
2026-08-07 05:23:37 -04:00
Justin Mitchell dd2ec5b525 Update freeink-sdk submodule
Update freeink-sdk submodule from a485dc4 to 8b8337b.
2026-08-07 05:20:59 -04:00
Uri Tauber e00f5958df feat: guard against cross-chip firmware installs (#2880) v1.5.0 2026-08-07 09:42:29 +03:00
lranslot 255bab311a fix: read platformio.ini as UTF-8 in git_branch.py (#2897) 2026-08-07 02:05:45 +03:00
Justin Mitchell c507e54478 fix: thread-safety issues in credential store (#2834) 2026-08-07 01:16:22 +03:00
Uri Tauber 5eec70de36 add IPA intervals to SD fonts 2026-08-07 01:08:29 +03:00
+19 28f3260c51 chore: update translations (#2740)
Co-authored-by: Leopoldo Pla Sempere <leopoldo.pla@treelogic.com>
Co-authored-by: muhas <muhas@muhas.ru>
Co-authored-by: Matteo Scopel <matteo@scopel.email>
Co-authored-by: CookieCaptainD <65847023+CookieCaptainD@users.noreply.github.com>
Co-authored-by: Poc031205 <165477165+Poc031205@users.noreply.github.com>
Co-authored-by: Rodrigo Matsuura <matsuura@outlook.com.br>
Co-authored-by: Spigaw <73850535+Spigaw@users.noreply.github.com>
Co-authored-by: Tom-Inge Larsen <tom.inge@gmail.com>
Co-authored-by: Baris Albayrak <80099286+barbarhan@users.noreply.github.com>
Co-authored-by: Barış Albayrak <barisa@pop-os.lan>
Co-authored-by: Hendra Kusumah <h.kusumah87@gmail.com>
Co-authored-by: thehijacker <thehijacker@gmail.com>
Co-authored-by: Andrej Kralj <andrej.kralj@gmail.com>
Co-authored-by: Bastian <391732+dasrecht@users.noreply.github.com>
Co-authored-by: th0m4sek <53303628+th0m4sek@users.noreply.github.com>
Co-authored-by: Dexif <spev@gurtam.team>
Co-authored-by: Mirus <mirusim@gmail.com>
Co-authored-by: Mirza Arnaut <mirza.arnaut45@gmail.com>
Co-authored-by: Husam Younis <youhusam@gmail.com>
Co-authored-by: Ing. Jan Kaláb <jan+github@kalabovi.org>
Co-authored-by: Tadas <tadasss@gmail.com>
Co-authored-by: winst0niuss <chumachenko.vadym@gmail.com>
Co-authored-by: fsocietyipa <fsociety.ipa@gmail.com>
Co-authored-by: Okzhetpes <okzhetpes.valikhanov@gmail.com>
Co-authored-by: KymAndriy <32357131+KymAndriy@users.noreply.github.com>
Co-authored-by: KymAndriy <test@notamail.ua>
Co-authored-by: Martin <35097765+neresus@users.noreply.github.com>
Co-authored-by: Hoang Manh Linh <jetaudio.media@gmail.com>
2026-08-06 23:39:05 +03:00
Phạm Bình An 046827fc31 fix(epub): ruby overflows right border when justifying text, unwanted short lines in Chinese and Japanese (#2781) 2026-08-06 23:26:09 +03:00
Justin Mitchell 28af4189d4 Chunk font bitmap allocations to avoid fragmentation
Replace single contiguous miniBitmap allocation with fixed 4KB chunks to allow large font page bitmaps (20-40KB) to fit in fragmented heap. Each glyph is kept whole within one chunk by padding to next chunk boundary when needed. Falls back to overflow path if glyph exceeds chunk size or max chunks reached. Mirrors existing image .pxc slot chunking strategy.
2026-08-05 16:21:17 -04:00
Uri Tauber fecb9eb3a4 fix: trim curly quotes and dashes in dictionary lookup (#2877) 2026-08-05 15:37:41 -04:00
Justin Mitchell f45f75f966 Add emergency buffer for font glyph rendering
Prevents bold-italic glyphs from rendering blank under heap pressure (when BLE is resident). Pre-allocates a 1KB emergency buffer at font load time when heap is healthy. When per-glyph malloc fails during overflow, falls back to this buffer to render the glyph directly instead of returning null. The emergency buffer bypasses the cache ring and is overwritten on each use, which is safe since getGlyphBitmap() consumes bitmaps immediately.
2026-08-05 15:28:48 -04:00
Justin Mitchell 4564c3e743 Make BT memory patch script robust to package location
Replace hardcoded path lookup with a multi-strategy search that tries PlatformIO's package API first, then falls back to globbing common package directories. This handles cases where the framework package name or location varies across installations.
2026-08-05 15:18:44 -04:00
Jesse Vincent 53232eefab fix: recognize watchdog-triggered resets as panics (#2830) 2026-08-05 22:02:41 +03:00
winst0niuss cc96e3c538 fix: size translated-label buffers for UTF-8, not ASCII (#2850) 2026-08-05 21:51:37 +03:00
Justin Mitchell 1373bef1c6 Fix undefined _btLibraryInUse in BLE-controller builds
Add pre-build script to patch arduino-esp32 core header, converting extern declaration to weak definition. This resolves linker errors when using NimBLE-Arduino host with ESP-IDF BLE controller only (no IDF host stack). The weak definition allows NimBLE translation units to provide the symbol while still allowing the core's strong definition to take precedence when an IDF host stack is enabled.
2026-08-05 12:57:06 -04:00
Justin Mitchell 7dbfcbb52d Split font scan buffers by text style
Previously a single scan buffer was used for all text styles (regular, bold, italic, bold-italic), causing the font decompressor to allocate full-page buffers for each style during prewarming. This led to OOM failures when the BLE stack was resident, causing bold/italic glyphs to render blank.

Now each style maintains its own scan buffer, sized only for the text actually rendered in that style. This keeps secondary style buffers small and prevents allocation failures.
2026-08-05 12:35:49 -04:00
Justin Mitchell 981e73c137 Merge remote-tracking branch 'origin/develop' into feat-bluetooth 2026-08-05 10:59:48 -04:00
Justin Mitchell 4e61903578 fix: add support for new x3 display, x3 battery drain fix, and crypto support (#2864) 2026-08-04 12:08:14 -04:00
Jesse Vincent ba1b849f3d fix: load Settings page's Wi-Fi/OPDS/settings data sequentially (#2831)
## Summary

* **What is the goal of this PR?** Fix a reproducible crash: opening the
web UI's Settings page reliably crashes the device (silent reboot to
Home) under real-world conditions.
* **What changes are included?** `SettingsPage.html` fired three
unawaited `fetch()` calls on page load (`/api/settings`, `/api/wifi`,
`/api/opds`), opening simultaneous connections to the device's web
server. That server (Arduino's `WebServer`) handles one client at a
time; a genuinely concurrent second/third connection can stall a
response mid-stream for multiple seconds — long enough to trip the
firmware's watchdogs (300ms interrupt WDT / 5s task WDT, both
panic-on-timeout in this project's config). This PR makes the three
initial loads run sequentially via a small async IIFE instead of firing
them concurrently. Same end state for the page, no visible behavior
change.

## Scope Check

CrossPoint is intentionally narrow. See
[SCOPE.md](../blob/master/SCOPE.md) and
[ROADMAP.md](../blob/master/ROADMAP.md).

- [x] I have read SCOPE.md and ROADMAP.md.
- [x] This PR is **not** a new built-in theme.
- [x] This PR is **not** a new external network connector.
- [x] This PR is **not** an interactive app, writing tool,
RSS/news/browser, media playback, or PDF feature.
- [x] This is a bug fix for a reproducible crash, not new functionality.
- [x] Does not touch `freeink-sdk/`, `lib/hal/`, the bootloader, OTA, or
recovery code.

## Testing performed

Verified live on an X4 (driven via the `CMD:WIFI` serial debug command
from the companion PR, since I didn't have physical access to the device
for part of this investigation):

- Root-caused via a temporary per-entry heap/timing log in
`handleGetSettings()` (not included in this diff): under concurrent
load, individual `sendContent()` calls stalled 1-3+ seconds between
simple, static settings entries that should serialize in well under a
millisecond each.
- Reproduced the crash directly: firing `/api/settings`, `/api/wifi`,
and `/api/opds` concurrently (mirroring the page's old JS behavior)
crashed the device in 2/2 attempts. The companion PR (watchdog reset
detection) let the second crash actually get logged: reset reason
`ESP_RST_TASK_WDT`, panic confirmed.
- After the fix: same three endpoints, hit sequentially (matching the
new JS), succeeded cleanly across dozens of repeats (single-shot and a
60-request hammer loop) with no crashes and stable free-heap.
- Confirmed the live device served the updated, gzip-compressed
generated header after a normal `pio run` (source HTML →
`SettingsPageHtml.generated.h` via the existing `scripts/build_html.py`
build step).

## Additional Context

Memory/flash impact: none — same JS logic, just sequenced instead of
concurrent. No new allocations, no change to the generated header's size
beyond the few added bytes of source text.

Risk: low. This only changes the *order* three existing fetches happen
in on page load; no new endpoints, no changed request/response shapes.

---

### AI Usage

YES — diagnosed and fixed by Claude (Sonnet 5), including live
reproduction and verification against real hardware.
2026-08-03 16:46:24 -04:00
Uri Tauber 9c48609f8b Make bookmarks survive re-pagination
Ties bookmarks to the actual text on the page rather than to a page number. Page numbers shift whenever the book gets re-laid-out — changing font size, margins, line spacing, or rotating the screen — which could previously land you on the wrong spot.

This is a followup of #2805, making bookmarks use the same mechanism. Several minor improvments ride along.
2026-08-02 00:06:12 +03:00
Thiago Kenji Okada 0f747b82a1 fix: make EPUB sync positions content-based (#2805) 2026-08-01 23:37:07 +03:00
Bob Vincent 1a7f5a9e38 perf: share one static bidi scratch buffer to save ~1.5 KB RAM (#2554) 2026-07-31 19:07:39 +03:00
Uri Tauber 5933da8f1d perf: check dictionary sidecar freshness once per open
needsIndex() opens .idx and .qidx and re-reads the sidecar header on every
call, and DictionaryWordSelectActivity called it once per tapped word rather
than once per dictionary open. A lookup therefore cost 4 SD opens and 2
std::string path temporaries, not the 2 and 0 the previous change set out to
achieve.

Ask needsIndex() once, inside the same guarded block that opens the
dictionary, and feed the build result back so a successful build stops
re-triggering while a failed one still retries on the next word.

Reimplement needsIndex() on openSession() so the "is the sidecar usable?"
rule lives in one place rather than two that have to be kept in step. This
is behaviour-preserving for everything buildIndex() can produce: it always
writes at least one sample (entry 0) and removes the file on failure, so
sampleCount == 0 means absent, stale or corrupt, all of which rebuild. The
one divergence is an improvement -- a corrupt sidecar with a valid magic
previously reported fresh and then full-scanned every lookup forever, and
now rebuilds once.

Also make the open()-time length bound a compile-time constant instead of
two runtime strlen() calls, and correct the buildPath() comment, which
claimed a lookup allocates nothing at all -- cleanWord(), stemVariants() and
the matched headword all still do.
2026-07-31 15:46:42 +03:00