Changes in this release:
- 7843798 telegrambot: cap TLS at 1.2
- 79cfae5 curl: cap outbound HTTPS at TLS 1.2 Add --tls-max 1.2 to every curl invocation that ships in the image: package updates (thingino-pkg), provisioning, push/notification senders, prusa-connect, raptor, rt-tests, termbin upload, gestalt profile listing, sysupgrade size/range probes, and the Google Photos and WireGuard CGI endpoints. Signed-off-by: Paul Philippov paul@themactep.com
- 72f6ce1 nino: clean up
- ab99377 makefile: build sdk bundle only using buildroot native toolchain
- ce80776 makefile: formatting
- 8edafe2 build: allow THINGINO_BUILDROOT_DIR to override the buildroot tree Point the build at an external buildroot checkout instead of the in-tree submodule, so the symlink/submodule is not needed for a build. The in-tree buildroot/ remains the default when the variable is unset. BR2_MAKE and generate_build_info.sh follow the same variable, and the submodule-checkout rule refuses to run a git submodule update against an external tree that is missing its Makefile. Signed-off-by: Paul Philippov paul@themactep.com
- a2bdc25 prudynt-t: bump to 00bb414 Fixes the recorder issues reported against 2fe05c7: the MP4 audio clock is reset on every segment, the header carries the final mvhd/tkhd/mdhd and mehd durations, and the MP4 video timeline folds encoder domain steps into an offset instead of jumping by the RTSP session age. Fixes #1897 Fixes #1898 Fixes #1899 Signed-off-by: Paul Philippov paul@themactep.com
- 71a9a16 prudynt-t: serve a fresh frame for motion snapshots Bump to 53eeafd, which makes the IPC SNAPSHOT handler wait for a frame captured after the request instead of returning the frame left in snapshot_buf by the previous event. With jpeg_idle_fps=0 the JPEG worker pauses when idle, so motion alerts could deliver a snapshot that was hours old. Signed-off-by: Paul Philippov paul@themactep.com
- ea6427b thingino-mmc: preload exfat in S09mmc /lib/mdev/automount mounts with -t auto, which only tries filesystems already present in /proc/filesystems. Load exfat next to vfat so an exFAT card can be mounted when it appears. Signed-off-by: Paul Philippov paul@themactep.com
- 1eb3fbb prudynt-t: fix motion sensitivity and burn-in exclusion Apply the configured sensitivity to every IVS ROI, not only the first. The burn-in split leaves up to four strips and the unset entries were left at the minimum. Take the burn-in rectangle from
OSD::getBurninRect()instead of estimating it from the format string. The old 3-chars-per-directive estimate made the timestamp hole too narrow ("%F %T" is 19 characters, not 15), so the seconds digits landed in the right ROI strip and triggered false motion. Restart the video pipeline whenmotion.sensitivitychanges at runtime so the new value is applied without a manual restart. Fixes #1895 - 7f710d8 docs: document make update-certs
- 7ce1c51 overlay: refresh the CA trust store, add make update-certs Backport #1893 (bundle refresh and update-certs target) together with the follow-up that rejects empty or non-PEM downloads and keeps the target out of camera selection.
- e1d9025 libhelix-aac, prudynt-t: keep a bad AAC backchannel frame from killing prudynt AACDecode() bounded each element's channel count against AAC_MAX_NCHANS instead of the configured nChans. A mono decoder (raw block mode) that parsed a CPE frame therefore passed the check, and StereoProcess() read coef[1] and the channel-1 scalefactors, which AllocateBuffers() never allocated for one channel. That is a read past the end of the mono buffer, not an error return, and it is reachable from the network: a mis-framed AAC backchannel payload is enough. Bound element channels by aacDecInfo->nChans and validate currBlockID before indexing elementNumChans. Invalid frames now return ERR_AAC_CHANNEL_MAP / ERR_AAC_INVALID_FRAME and the instance stays usable. Confirmed with an ASAN build of the library driven directly, without prudynt code in the path. Prudynt's AAC backchannel kept the thread-local Helix instance after a hard decode error, so the next frame was parsed from wherever the bad one stopped. Flush the codec on anything but ERR_AAC_INDATA_UNDERFLOW and log it as before. Bench C200 (T23N), ciao, prudynt-t 3ff07e4, AAC 16 kHz backchannel: malformed frames 20/20 sessions without a crash (previously SIGSEGV in StereoProcessGroup), valid AAC 20/20 and PCMU 20/20 unchanged. This does not fix the backchannel SIGSEGV reported in #1862: that fault (address 0x8, on 6e48034) is still unreproduced on 3ff07e4 with valid AAC. Signed-off-by: Paul Philippov paul@themactep.com
- 4341057 buildroot: restore the recorded submodule commit The previous commit was meant to touch only the ha-state sanitizer, but git commit -a also staged the working tree's buildroot checkout. Put the branch's original gitlink back.
- 3b554f7 thingino-ha: keep the + in the OTA latest version The sanitizer stripped + from both the cached and the fetched version string, so a camera on ciao+fcbc0c7 published ciaofcbc0c7 and Home Assistant kept showing an available update. Allow + in the character class. It is only special in MQTT topic filters; the version travels as a payload.
- eda8406 webui: keep bootstrap icons base rule in the subset The generated subset copied @font-face and per-icon content rules but dropped the .bi::before base rule that applies font-family. Every icon therefore rendered as a PUA placeholder (tofu) in the fallback font. Extract the base rule from the upstream stylesheet and emit it with the subset. Signed-off-by: Paul Philippov paul@themactep.com
- b3040a6 webui: bundle bootstrap icons for offline mode The offline vendor set dropped the icon stylesheet and hid every .bi element because the subset only carried glyphs used by thingino-webui. Streamer and plugin pages (preview, PTZ, audio) rendered without icons. Generate the subset from all package web roots, install it with the reduced vendor set, and rewrite CDN icon links to the local stylesheet instead of hiding the elements. Signed-off-by: Paul Philippov paul@themactep.com
- a23222a build: fix stale toolchain cache and ciao 3.10 compile errors update_toolchain_bundles.sh checked the wrong dl/ subdirectory and only looked for a stamp that Buildroot never writes, so stale toolchain tarballs were never refreshed. Verify each bundle against the release digest in dl/toolchain-external-custom and record the stamp after a match. wifi-atbm6031: eth_hw_addr_set() only exists since 5.17; keep the direct memcpy() on older kernels so the 3.10.14 build works. thingino-raptor: update to 6afaff96, which carries the faac 2.2 AAC API fix. Signed-off-by: Paul Philippov paul@themactep.com
- a0d0000 gpio: add scan command, drop standalone gpioscan Integrate the gpioscan utility into the standard gpio script as
gpio scan, removing the duplicated devscripts tool. Signed-off-by: Paul Philippov paul@themactep.com - c3d870d openimp, open-tx-isp: drop the stale release-candidate comment Both
.mkfiles say "release candidate 1" while the pinned tag isv2026.10.25-rc2. The version line already carries the exact tag, so drop the parenthetical instead of tracking it by hand. Signed-off-by: Paul Philippov paul@themactep.com - f561638 package/timps: update to v1.11.1 Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- a25d0b4 prudynt-t: fix fMP4 preview on iOS Safari (ManagedMediaSource) Safari 17.1+ exposes window.ManagedMediaSource (which requires the disableremoteplayback attribute on the
- 0244b49 timps webui: test pattern banner behind a toolbar toggle, off by default Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 3fa81c2 timps webui: test pattern as a pipeline banner (sensor, ISP, encoder, IVS) above the stats Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 6c98feb package/timps: update to v1.11.0 Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- d02e213 openimp, open-tx-isp: bump to v2026.10.25-rc2 Second release candidate of the open stack (OpenIMP + open-tx-isp), tested on 19 cameras (T10/T20/T21/T23/T31/T40/T41). Release note: https://github.com/opensensor/openimp/blob/aperto/docs/RELEASE_NOTES_RC2.md Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 3abfd06 tell: portal_is_up() returned 0 in both branches The flag file is tested and the result thrown away, so portal_is_up() is always true and the "configuration portal is down, please power cycle" announcement can never be reached. The copy of this script in package/thingino-raptor/files/tell already has the intended "return 1". Signed-off-by: Markus Mauch markus.mauch@gmail.com
- d2f5eb7 package/timps: WebUI for timps v1.11.0 Test pattern card with motion test scoring and the sensor pattern on the preview page, crop note for the T41 AutoZoom path, ROI inactive under FixQP, encode time and keyframes in the stream stats. Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- ee29142 package/timps: S95timps treats unset webrtc.enabled and cert paths like timps Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 1be8e5f tplink_tapo_c200: fix sensor orientation and PTZ setup The SC2336P driver defaults shvflip to 1, which leaves this board's image upside down. Pass shvflip=0 instead of compensating with software flips. With the upright image, tilt is inverted relative to the UI: enable motors.invert_y. Raise the motor speed to the driver maximum and put the Home preset at the middle of the tilt range. Signed-off-by: Paul Philippov paul@themactep.com
- 4654b3d motors: leave SPI axis inversion to the daemon The SPI branch passed motors.invert_x/invert_y to the kernel module as well as to motors-daemon. The TMI8152 driver accepts both parameters, so setting invert_y flipped the axis in the kernel and then again in the daemon, cancelling the configured inversion. The ms419xx driver does not take these parameters at all. Drop the kernel parameters; motors-daemon already reads invert_x and invert_y from thingino.json and applies them in one place. Normalize the Mercusys invert_y value to a boolean while here. Fixes: #1536 Signed-off-by: Paul Philippov paul@themactep.com
- 75eb0c3 privacy: show save_state on agent-backed prudynt builds The privacy page takes the agent branch whenever the agent service is installed. prudynt depends on thingino-agent, so that is always the case on prudynt builds, and the agent has no save_state leaf. The switch was therefore hidden even though /x/json-prudynt.cgi supports it. Probe the streamer endpoint for privacy.save_state and show the switch when it answers; hide it only when the streamer does not support it. Fixes: #1785 Signed-off-by: Paul Philippov paul@themactep.com
- 51563a3 Merge remote-tracking branch 'origin/ciao' into HEAD # Conflicts: # package/thingino-imp-test/Config.in # package/thingino-imp-test/thingino-imp-test.mk
- 70f0775 send2ftp: use ftp:// scheme for explicit FTPS curl's ftps:// scheme means implicit FTPS: TLS starts before the server greeting and defaults to port 990. Explicit FTPS (AUTH TLS on the control port, typically 21) is ftp:// plus --ssl-reqd, which the script already passes when use_ssl is enabled. The previous change assumed ftps:// was explicit, so explicit-only servers rejected the handshake with "invalid SSL record". Fixes: #1715 Signed-off-by: Paul Philippov paul@themactep.com
- 97554ec timps webui: fix day/night controls save always failing with 400 $(printf '
') expands to nothing, so the multi-line guard matched every body. Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - c23182d prudynt-t: bump to 3ff07e4 Fixes the fMP4 preview staying blank while the audio track's clock offset keeps it ahead of the video track: each track is now rebased to its own first sample. Fixes #1815 Signed-off-by: Paul Philippov paul@themactep.com
- 2f402a7 thingino-imp-test: add imp-test-expr AE probe tool imp-test-expr answers whether the vendor libimp honors a fixed shutter: dlsym-based probe (no IMP link-time dependency), reports which AE APIs the running libimp exports, reads exposure state via IMP_ISP_Tuning_GetExpr, pins integration time via SetExpr(MANUAL), or caps it via SetAe_IT_MAX, and watches whether MANUAL survives AE re-seizure (--watch N). Also supports standalone ISP bring-up (--sensor/--i2c-addr/--spi) for cameras where no streamer is running; the probe only tears down what it brought up itself. Note: SetExpr is the Gen-1 (T10/T20/T21/T23/T30/T31-class) API; T32/T40/T41-class libs export SetAeExprInfo instead. The probe listing shows which generation is present on the running image.
- 0220234 webui: reboot from a detached session
reboot.cgisent the 302 first and ranreboot -fafterwards. The browser follows the redirect and drops the connection, and uhttpd SIGKILLs the CGI once the request is freed, so the reboot usually never ran and the camera stayed up. Start the unmount, sync and reboot in a detachedsetsidchild with stdio dropped before writing the response. Same failure mode thatbf8c86cfixed for ONVIF SystemReboot. Fixes #1816 Signed-off-by: Paul Philippov paul@themactep.com - 4d513e1 prudynt-t: bump to e1c000e Brings the motion ROI fix: the burn-in exclusion clips the timestamp rectangle to the configured ROI instead of widening a non-overlapping ROI to the frame edges. Also picks up the audio tap and H.265 fMP4 preview changes from stable. Fixes #1837 Signed-off-by: Paul Philippov paul@themactep.com
- 3e781ee cfg-backup: keep the camera name and raptor config across upgrades
/etc/hostnameand/etc/raptor.confare lost on an overlay-wiping upgrade: the camera reverts to the generic name and raptor returns to factory stream credentials. Add both to the default list and document the full manifest. Fixes #1842 Signed-off-by: Paul Philippov paul@themactep.com - eceab46 cfg-backup: gzip the payload when gzip is available The backup partition is 64KB and an uncompressed tar of a moderate config already fills 95% of it. gzip is in the image as a busybox applet, so compress the tar and store the smaller payload with its own size and MD5. Restore checks the gzip magic before extracting: busybox tar has no autodetect, so old uncompressed backups go straight to tar and new ones are decompressed first. Without gzip at write time the payload stays a raw tar. See #1842 Signed-off-by: Paul Philippov paul@themactep.com
- d2e681e service: make enable and disable independent of the umask
chmodwithout awhoargument only applies the bits not set in the process umask. With the 077 leaked by dropbear,chmod -xcleared only the owner execute bit: 755 became 655, whichfind -executablestill matches as root, so the init script ran again on the next boot andstatusreported unknown. Usechmod a-xandchmod a+xto reach the expected 644 and 755. Fixes #1843 Signed-off-by: Paul Philippov paul@themactep.com - 40fd172 dropbear: scope umask 077 to host key generation
S50dropbearsetumask 077before generating the host key and never restored it, so dropbear itself started with that umask and every SSH session inherited it. Files created over SSH then lost group and other permissions, and symbolicchmodcalls honoured the mask. Run the key generation in a subshell so the daemon keeps the normal 022. See #1843 Signed-off-by: Paul Philippov paul@themactep.com - 7a0f44a thingino-ha: probe all wireless interfaces for the RSSI sensor
ha-statetook the first entry in /sys/class/net/*/wireless and queried only that interface. Cameras whereap0sorts beforewlan0(AOQEE C1, T23N + ATBM6062CU) sentwpa_cli -i ap0 signal_poll, which fails because the AP interface has no wpa_supplicant control socket, so the WiFi Signal entity stayed unknown. The /proc/net/wireless fallback returned zeros too. Try every wireless interface and keep the first non-zero RSSI instead. Fixes #1849 Signed-off-by: Paul Philippov paul@themactep.com - 58752fd thingino-mmc: tighten the S09mmc reload path Port the master S09mmc fix (#1841, c89fba6). Replace the early exit when the module is already loaded with a conditional reload: anchor the /proc/modules match, reload only when MMC_PARAM is non-empty, and report a failed rmmod instead of hiding it. This lets an S09mmc restart reapply cd_gpio_pin without unloading the XBurst2 SDIO host under the ATBM6461 Wi-Fi function driver. Signed-off-by: Paul Philippov paul@themactep.com
- d8b0c0f busybox: enable
rmdirScripts already call it, but the applet was disabled. The code costs about 400 bytes of text on mips and reuses the libcrmdir(2)wrapper. - f0baf88 thingino-ha: only default
enable_lamp_socketwhen the accessory exists The key leaked intothingino.jsonon every camera with the HA package. Stage it from a conditional default fragment, and ignore the field in the config CGI unlesslamp_socket_ctlis installed. - 01ff886 webui: strip HTML comments from shipped pages Section markers and
<!-- .card-header -->style trailers cost space on the device rootfs with no runtime value. KeepTHINGINO_PLUGIN_PREVIEW_BODYmarkers, which the plugin assembler replaces at build time. - 238e790 buildroot: update to 2026.08.1 Rebase the four Thingino patches on the 2026.08.1 tag in the thingino-2026.08 fork branch: - arch/mips: add XBurst2 variant with nan2008 - support/scripts: reset applied patch list each run - support/kconfig: fix const qualifier in confdata.c - package/bison: force gnu17 for the host build Fork branch: 9a3aee34765e3cdb28ee26648541261a200d3df7 Signed-off-by: Paul Philippov paul@themactep.com
- d2e04fd package/timps: sync the aperto package state (agg-39) to ciao aperto carries the newer timps package (17d5d34, 18.10.), which the test fleet runs; ciao's is from 12.10. Bring ciao to the same state so both branches ship one timps package again. What changes against ciao's current package: - WebUI: shared /events connection (timpsApi.events) instead of per-page EventSources, crop/ROI with a rotated view, crop editor and ROI/privacy geometry clearing reworked, error texts. - timps.mk: asset tag hook so timps pages and scripts get fresh ?ts= cache keys; git describe for a local TIMPS_SITE checkout. - Config.in: timps without OpenIMP pulls the neo libalog/libsysutils and libaudioprocess-neo. - Shipped scripts and pages carry trimmed comments; no behaviour of S95timps, S96onvif_discovery or the motors UI changes. Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com Claude-Session: https://claude.ai/code/session_01NATCTUxg8G1oob978B1XMc
- fc1cea3 udhcpc: map '' to spaces in the DHCP timezone name DHCP option 101 carries tzdb names such as America/Los_Angeles, but tz.json spells multi-word names with spaces (America/Los Angeles), so timectl rejected every such zone from DHCP as "not found". Translate '' to ' ' before calling timectl; single-word names and names with '-' are unchanged. Signed-off-by: CyberNative AI LLC hello@cybernative.ai
- 83a8578 scripts: check tz.json strings against uClibc-ng in make lint check-tz-json.sh parses every tz.json value the way uClibc-ng's tzset() does (libc/misc/time/time.c), so a tzdb update cannot again ship a string that sends cameras to UTC. Besides the rule-time limit it checks the 3-6 character zone names and the 67 characters that fit uClibc-ng's /etc/TZ read buffer, and it holds month and week numbers to POSIX ranges. Signed-off-by: CyberNative AI LLC hello@cybernative.ai
- 9f15aaa overlay: use uClibc-ng compatible strings in tz.json uClibc-ng's tzset() accepts a rule time after '/' only as 0 to 24 hours without a sign, and it falls back to UTC for a string it cannot parse. Five tz 2026e strings use a negative or larger rule time, so cameras set to Nuuk, Scoresbysund, Gaza, Hebron or Jerusalem ran in UTC all year. Use the nearest string uClibc-ng accepts and note the deviations in docs/device/timezone.md: Nuuk, Scoresbysund M3.5.0/-1 -> M3.5.0/0 DST starts 1 h late Jerusalem M3.4.4/26 -> M3.4.4/24 DST starts 2 h early Gaza, Hebron M3.4.4/50 -> M3.5.6/2 a week late when March or M10.4.4/50 -> M10.5.6/2 October ends on a Saturday Signed-off-by: CyberNative AI LLC hello@cybernative.ai
- b7d5aa8 overlay: update tz.json to IANA tz 2026e Regenerated from OpenWrt LuCI's zoneinfo.uc at tz 2026e (luci dc37ec7e). The old table was LuCI's 2022e data with two manual edits, so 20 zones no longer matched the IANA rules. From 2026-11-01 British Columbia stays on UTC-7, Alberta and the Northwest Territories on UTC-6 and Manitoba on UTC-5; the old strings fall back one hour on that date. Fiji has had no DST since 2022, Morocco moved to UTC+0 on 2026-09-20, and the entries for Egypt, Kazakhstan, Greenland, Moldova, Ojinaga and two Antarctic stations were out of date as well. Six names LuCI dropped (tzdb links) stay in the table with their link target's string, so a stored /etc/timezone keeps resolving. Adds America/Ciudad Juarez and America/Coyhaique. Signed-off-by: CyberNative AI LLC hello@cybernative.ai
- 9e7c931 kernel: update default configs for 4.4.94
- 9923d96 wifi: select regdb with a wireless driver
- f2fd648 kopt: extend options for newer kernels
- 1aa2760 kopt: fix regexp for dtsi injection
- e0fdbbb uboot: add a macro to nuke bootloader for bootsel activation
- 3fe2a76 kernel: enable sound support for wyze accessory
- 96fc484 webui: minify assets
- 96d10b8 enhance imp test tools
- 7224769 kernel: add ethernet fixups for kernel 5.x
- 7d4a53c uboot: add t32lq variant fragment
- c972d72 kernel: wire nfs support via kopt fixups
- 968e4af dropbear: fix pty master fd access
- 6ed93bb kernel: add kernel 5.x config and patches
- a9ad979 kernel: update kernel 7.x config and patches
- 1f898ce kernel: disable swap and zram in t32 default config
- 6d5e578 kernel: IPC do not have IDE
- afe6a83 webui: honor confirm dialog for offcanvas navigation Offcanvas menu items carrying the confirm token (e.g. Tools > Reboot camera) navigated unconditionally after the panel closed, while main.js's .confirm scanner opened the shared dialog for the same anchor. The two handlers raced: clicking Cancel left the queued post-close navigation in place, so the camera rebooted anyway. Take ownership of the confirmation in bindOffcanvasNavigation the same way bindNavAction already does for action items: ask the shared dialog first, navigate only on accept, and mark the anchor data-confirm-skip before insertion so the scanner cannot double-bind. Plain items keep the previous close-then-navigate behavior.
- d485dfe webui: allow setting a custom API key when none exists The Web UI could only generate a random API key; there was no way to paste an existing one. Make the API key field editable when no key is set, add a "Save Key" button, and teach api-key.cgi to store a user-supplied key from the JSON body. Generated keys keep the previous behavior; unsupported characters are rejected with 422. Signed-off-by: Paul Philippov paul@themactep.com
- e260f09 send2ftp: add FTPS (explicit TLS) upload support The FTP upload client only spoke plain FTP. Some hosts require FTPS on the control port (AUTH TLS, port 21), e.g. Hetzner Storage Box. Add a "Use FTPS (explicit TLS)" option that switches the upload URL to ftps:// and requires TLS with --ssl-reqd, plus an "Ignore SSL certificate validity" option that adds --insecure for self-signed servers. This mirrors the existing send2email TLS handling. curl's ftps:// scheme is explicit only; implicit FTPS on port 990 is not supported and is left out of scope. - send2ftp: read use_ssl/trust_cert, add -s/-k flags, pick the scheme and pass --ssl-reqd/--insecure. - send2.json: default use_ssl/trust_cert to false. - webui: add the two switches to the FTP page and persist them. - docs: document the FTPS option. Fixes: #1715 Signed-off-by: Paul Philippov paul@themactep.com (cherry picked from commit 251f0ea)
- a4574b6 package/timps: shfmt S95timps and timps-irprobe Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 8d7fe6a package/timps: update to v1.10.1 Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 1dbc3ef package/timps: name the refused keys in failed /control POSTs Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- b95ce8e package/timps: preview day/night tile for the 1.10.1 engine Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 0e36bd2 package/timps: day/night page for the timps 1.10.1 engine Drop the retired probe keys, add daynight.jump_pct, relabel the heartbeats, show night_baseline/day_trigger with their new meaning, add "Request a look now". A 1.10.0 daemon keeps its old view. Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 4b03113 package/timps: rotation selector on the video page Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 922bd66 package/timps: WebUI text for timps error codes Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- bf645e0 openimp, open-tx-isp: pin release candidate v2026.10.11-rc1 Pin both packages to the v2026.10.11-rc1 tag with hashes, as on aperto. T23 runs fully on OpenIMP (no OEM libimp under /opt/openimp-t23), T10 builds OpenIMP via the T20 platform. Drop the open-tx-isp patches, all three are in the release sources. Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- fc47f3a package/timps: update to v1.10.0 Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- c499525 ingenic-sdk: bump pin for t23 sc1a4t 30fps support themactep/ingenic-sdk#52 merged: sc1a4t SENSOR_OUTPUT_MAX_FPS 15 -> 30 plus a real sensor_set_fps implementation (hardware-validated by Nic on Jooan A6M). Pin moves to the post-merge tip. SDK side for master: thingino/ingenic-sdk#7.
- b285f73 timps-dn-isp-log: no isp-m0 read on the vendor T21 driver Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- a6ff46d timps-dn-isp-log: skip the ISP read while timpsd is not running Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 0c6ef5a timps WebUI crop: sensor-aspect preview, live cut-out inside the frame, cached backdrop, wheel zoom; no capture POSTs Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 4d81d11 timps WebUI crop: drop Select area and Max zoom Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 25c70fc timps WebUI crop: cache the full-sensor frame, capture it once when crop is on, cut-out fallback Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 8ba81a2 timps WebUI crop: edit on the main preview with live inset, zoom slider to the real max with crop/zoom split Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 0e9ab47 timps WebUI crop: select area, max zoom, per-stream scaling hint; map only while cropped Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 58b7f84 timps WebUI: crop limits from caps.fcrop, ROI QP range from caps.roi, follow waiting -> on Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 012288c timps webui: help texts for overlays, privacy, ROI and crop; explain crop state waiting Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 41fa0ad timps WebUI: drag the crop window on the sensor map and preview Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 34d8eec linux: build 4.4.94 from the official kernel.org tarball The 4.4.94 kernel came from the thingino-linux git repo, one branch per SoC family. Build it from the official 4.4.94 tarball plus patches instead, the model 3.10.14 already uses. The four branches share most of their delta against 4.4.94, so it is factored into one common patch (the file-level intersection of all branches) followed by a small per-SoC remainder: tarball -> 0001-4.4.94-common.patch -> soc//0001-4.4.94-.patch Binary ISP firmware and other non-text assets a patch cannot carry are restored from package/linux/files/4.4.94/, shared under common/ where the branches agree. - thingino.mk: t23/t31/t32/t41/c100 use the tarball via KERNEL_SOC; a1 and t40 keep the git tree. Drop the now-unused ingenic-*-4.4.94 branches and their commit pins. - Makefile.targets: do not rewrite 4.4.94 to CUSTOM_GIT. - linux/linux-ext-thingino.mk: apply the SoC patch before the camera's own kernel patches, and restore the common + per-SoC assets. - scripts/generate_kernel_4.4.94_patches.rb: regenerate the patches and assets from SOURCES. update_kernel_hashes.sh now reports snapshot drift instead of tracking a commit pin. Signed-off-by: Paul Philippov paul@themactep.com
- ca6daa3 make: calculate minimum size of overlay partition dynamically
- cbf446c send2: make stored media world-readable
- 893ed26 Revert "kernel: fail safe on the OSS3 speaker-amp gpio default" The speaker-amp default lives in the ingenic-sdk audio sources, not the kernel tree: the kernel's in-tree sound/oss3 is dead (CONFIG_SOUND is off, and the built audio.ko comes from the ingenic-sdk override), so the hook patched nothing. The real fix is in ingenic-sdk dc2ab93e. Signed-off-by: Paul Philippov paul@themactep.com
- a7578e5 kernel: fail safe on the OSS3 speaker-amp gpio default The Ingenic OSS3 inner codecs default spk_gpio to the ISVP reference board's enable pin (GPIO_PB(31), gpio 63; GPIO_PC(4) on the es8389 external codec). thingino always passes spk_gpio= on the module command line, but if that parameter is ever missing the codec would claim and drive a pin that on another board is a motor phase, an LED, or a sensor reset. Flip the default to -1 (the driver's own disable sentinel) so an unconfigured board drives nothing. The t31/t40/t41 branches use the ASOC path, which reads ingenic,spken-gpio and already skips an invalid pin, so only the OSS3 tree (t32) is affected. This is a guarded POST_PATCH hook, not a package/all-patches/linux/4.4.94/ patch: that directory is shared by branches that do not carry sound/oss3, so a patch naming those files would fail to apply there. Signed-off-by: Paul Philippov paul@themactep.com
- 0102df5 kernel: take the reset button from the camera dtsi everywhere Give each profile's dtsi fragment a gpio-keys node (reset = KEY_ENTER, plus chime = KEY_1 where gpio.chime exists), the same node the 4.4+ kernel reads from the device tree. The 4.4 kernel had no button node for any board except cinnado, so 4.4 buttons were dead; the .dts-shipping boards keep their own. - inject-camera-dtsi.sh deletes the SoC tree's dev-board gpio_keys node (/delete-node/ &gpio_keys; by label, else by node name) before including a fragment that declares gpio-keys, or it would claim the vendor pins. - thingino.mk parses the node into BUTTON_PIN/CHIME_PIN via scripts/button_pins.sh. - the U-Boot injectors and the 3.10 gpio-userkeys step (ingenic-sdk, now gated to 3.10) read those instead of thingino.json. Drop gpio.button_reset and gpio.chime from the 193 profiles that carried them; the fragment yields the same pins for every one. Signed-off-by: Paul Philippov paul@themactep.com
- cfbeb4f kernel: take MMC card-detect from the camera dtsi everywhere The card-detect pin now lives only in the camera dtsi fragment (the &msc0 ingenic,cd-gpios line the 4.4+ kernel reads). Feed the other two consumers from there instead of keeping a second copy in thingino.json: - thingino.mk parses it into MMC_CD_PIN via scripts/mmc_cd_pin.sh. - S09mmc uses MMC_CD_PIN for the jzmmc (XBurst1) cd_gpio_pin parameter, substituted at build time like MMC_MODULE, instead of reading gpio.mmc_cd from thingino.json at runtime. - inject-uboot-mmc-dt.sh and inject-uboot-gpio-dt.sh read MMC_CD_PIN for the U-Boot cd-gpios injection and the gpio-hog exclusion. Drop gpio.mmc_cd from the 197 profiles that carried it (191 real pins plus 6 -1/"" no-detect markers); the fragment yields the same pin for every one. Signed-off-by: Paul Philippov paul@themactep.com
- f67d9c3 cameras: drop the LED GPIO defconfig entries The camera dtsi fragment is now the LED source for both kernel lines, so the BR2_THINGINO_LED_*_GPIO/_ACTIVE_LOW entries are redundant. Removed from the 171 profiles that carried them; each already ships a fragment whose gpio-leds node yields the identical generated header. Signed-off-by: Paul Philippov paul@themactep.com
- c60d4a7 kernel: source the 3.10 LED header from the camera dtsi The 3.10 gpio-leds board header was generated from BR2_THINGINO_LED_* in the buildroot .config. Prefer the camera's device-tree fragment instead, so the LED definition lives in one place for both kernel lines: the 4.4+ kernel includes the fragment's gpio-leds node in DT, and 3.10 compiles the same node into board_base.c through this header. The generator parses the fragment's gpio-leds children (label and gpios = <&gpX N FLAG ...>) and falls back to the legacy .config values when the fragment is absent or carries no LEDs, so profiles migrate one at a time. The fragment is an optional third argument. Signed-off-by: Paul Philippov paul@themactep.com
- 6a083be kernel: describe board LEDs and MMC card-detect in a camera dtsi Add a per-camera .dtsi fragment carrying the board's gpio-leds and its MMC card-detect pin, and let thingino-kopt inject it into the kernel 4.4+ device tree: it finds the leaf the kernel config builds, copies the fragment into the tree's dts dir and #includes it. A 3.10 tree has no device-tree directory and is left untouched. The injector skips a leaf whose tree lacks a label the fragment opens (&gpa..&gpd, &msc0), so a fragment shipped ahead of a family's 4.4 tree cannot break that family's build. A fragment is generated for every profile with LED gpio values in its defconfig or gpio.mmc_cd in thingino.json (211 profiles). The pins are the same data the 3.10 LED header and S09mmc already read; 3.10 behaviour is unchanged because those sources stay and the fragment is ignored there. Signed-off-by: Paul Philippov paul@themactep.com
- 851017d cameras: cinnado_d1: describe the reset button in the board dtsi The button had no kernel consumer on this 4.4 build: gpio-userkeys is a 3.10 module, and the 4.4 config carried no input stack, so thingino-button found no gpio-keys evdev device. Add a gpio-keys node for gpa22 and enable INPUT_EVDEV/INPUT_KEYBOARD/KEYBOARD_GPIO (ATKBD off) so evdev exposes it. thingino-button autodetects the "gpio-keys" label and thingino-button.conf already maps KEY_ENTER to the reset action. Signed-off-by: Paul Philippov paul@themactep.com
- aeb6550 cameras: cinnado_d1: take MMC card detect from the board dtsi sdhci-ingenic reads ingenic,cd-gpios from the device tree, and S09mmc deliberately ignores gpio.mmc_cd on XBurst2. The family tree carries the reference board's pin (gpb28); this board's card detect is gpa21, as thingino.json and the U-Boot leaf already say. Override it in the camera profile dtsi so the kernel detects the slot. Signed-off-by: Paul Philippov paul@themactep.com
- cebcafd kernel: support a camera-profile dtsi fragment thingino-kopt copies a single .dtsi from the camera profile dir into the kernel dts dir and #includes it in the family leaf .dts before every build, so a camera can describe board pins in the device tree without replacing the family tree. CAMERA_DTSI_FILE mirrors CAMERA_DTS_FILE: one fragment per profile, and the family leaf name (CAMERA_DTS_DEST) is required. First user: cinnado_d1_t32lq_sc4336p_atbm6162u. Its blue and red LEDs move from BR2_THINGINO_LED_* to a gpio-leds node. On t32 4.4 the generated thingino_leds.h is included by nothing, so the defconfig values did nothing; as DT LEDs they now appear as /sys/class/leds/led_b and led_r. Signed-off-by: Paul Philippov paul@themactep.com
- 6767747 kernel: build the 4.4 MAC only for cameras with Ethernet The T32 4.4 base config built the MAC, MII and phylib into every camera. Leave them out; thingino-ethernet selects KOPT_JZ_MAC and the ported MAC_4_4 fixup puts them back on wired boards only. Matches master's f281ad2. Signed-off-by: Paul Philippov paul@themactep.com
- d3f925b thingino-mmc: name the t32 4.4 host module correctly t32 on 4.4 drives MMC through sdhci-ingenic, built as ingenic_sdhci_sdio.ko, but the package picked the module name from BR2_mips_xburst2 alone and so chose jzmmc_v12 on t32. S09mmc then modprobed the wrong name and the slot never came up. Match master: t32 and XBurst2 both use ingenic_sdhci_sdio. Signed-off-by: Paul Philippov paul@themactep.com
- c0e3157 cameras: move USB device-mode boards to DWC2_DUAL_ROLE With DWC2_OTG now meaning host-only, the boards that act as a USB device (webcam / usb-direct) must select DWC2_DUAL_ROLE: anker_c200, k3_100, 360_ap6pcm03, hamedal_c20, wansview_106. Signed-off-by: Paul Philippov paul@themactep.com
- 144403e thingino-kopt: split DWC2 host and dual-role, enable the 4.4 controller Bring ciao's thingino-kopt up to master's DWC2 work: DWC2_OTG now means host-only and the new DWC2_DUAL_ROLE carries the gadget/dual-role stack; the base DWC2 fixup enables CONFIG_USB_DWC2, its DMA buffer mode and the Ingenic INNO PHY, which the T32-class 4.4 configs do not bake in. inject-usb-dt.sh plus the linux ext hook enable the controller and PHY in the 4.4 device tree. thingino-system's usb-role now also accepts DWC2_DUAL_ROLE. ciao's SLUB_DEBUG option and the files/dhcpv6.script fix are preserved. Keeps ciao's T32 kernel building USB (empty lsusb otherwise) and matches master's kopt. Signed-off-by: Paul Philippov paul@themactep.com
- 4f16784 usb: skip the host-mode switch when usb-role is not installed usb-role only installs for DWC2_OTG/DUAL_ROLE boards; WIFI_ONLY boards build host mode into the driver instead. Without the guard S05usb logs a spurious 'Failed to set USB controller to host mode' (command not found). Mirror master's guard. Signed-off-by: Paul Philippov paul@themactep.com
- cb9777d kernel: drop unused T32 4.4 subsystems to fit the partition The T32 4.4 kernel overflowed the fixed 1600K partition: the generic config carried netfilter/iptables/ipset, ext2/ext4/jbd2, cramfs and KALLSYMS_ALL, none of which the build uses. Nothing mounts ext4 or calls iptables/ipset, and the same camera on 3.10.14 as well as master's 4.4.94 config leave all of them off. Disable them. The uImage drops from 1798644 to 1550327 bytes, 86 KiB under the partition. Modularizing was not an option: the rootfs partition has only ~56K free, so moving the code to .ko modules would overflow rootfs instead. Signed-off-by: Paul Philippov paul@themactep.com
- 8deff42 kernel: drop the wireless stack from the generic configs cfg80211/mac80211 and their WEXT/WIRELESS/WLAN dependencies were seeded into every generic .config from the Ingenic BSP base, duplicating what the wifi-* packages already set in their LINUX_CONFIG_FIXUPS. Every camera therefore built the stack whether or not it has wifi - as =y (linked into the kernel image) or, after the earlier stopgap, =m (dead modules in the rootfs). Remove the block from all six generic configs. The fixups re-add the symbols they need (KCONFIG_MUNGE_DOT_CONFIG appends absent options), so wifi cameras are unaffected and non-wifi cameras no longer build the stack. Five fixups that leaned on the base for the WEXT_* options (aic8800, atbm6012bx, atbm6031, rt5370, rtl8189fs) will need them added when the wifi packages are revisited. Signed-off-by: Paul Philippov paul@themactep.com
- 6ff99da prudynt-t: wire the T32 2.2.0 IMP headers The IMP headers come from the include submodule; the pinned prudynt-t commit records the headers commit before T32/2.2.0 was added, so advance the submodule to 5bacc0f. prudynt's platform table also lacks a T32 branch, so it fell back to T31 and 2.2.0's T31 headers carry no imp/. Pass LIBIMP_PLATFORM=T32 for t32 so it resolves include/T32/2.2.0/en. Signed-off-by: Paul Philippov paul@themactep.com
- 479ba96 ingenic-lib: use the 2.2.0 T32 SDK libs The pinned ea62f3d source has no T32/lib/1.0.6/uclibc/5.4.0; the T32 4.4.94 libs live under T32/lib/2.2.0/uclibc/5.4.0. Match master's SDK_VERSION for t32 so staging finds libimp.so. Signed-off-by: Paul Philippov paul@themactep.com
- 5e1d4f4 build: honor the per-camera U-Boot version override The U-Boot version resolver took the first matching BR2_THINGINO_UBOOT_VERSION_* line, so core.fragment's default always beat a camera defconfig that set a different version (a t32lq camera asking for 2026.07 still built 2013.07, whose tree has no isvp_t32lq_sfcnor_config). Take the last match instead: the fragment list is ordered base -> specific, so the camera (and user) override wins. No tracked camera sets the symbol twice, so only overrides change. Signed-off-by: Paul Philippov paul@themactep.com
- 4ea0412 uboot: inject per-board GPIO/MMC/audio DTS from thingino.json Add the three inject-uboot-*.sh helpers and wire them as U-Boot pre-build hooks. They append this board's card-detect, slot power, PTZ/IR-cut/speaker gpio-hogs and the speaker-amp enable line to the leaf .dts and enable CONFIG_GPIO_HOG, so the per-SoC defaults (e.g. msc0 broken-cd) are replaced by the board's real wiring. Signed-off-by: Paul Philippov paul@themactep.com
- 67686d5 uboot: sync the 2026.07 baseline to the master head Replace 0001/0002 with master's regenerated pair, moving the U-Boot 2026.07 baseline to ingenic-t-series @ f0570ec0ccf2 (2026.10-rc4), and drop 0004-pylibfdt: the rebased fork carries that fix, so master dropped it too. For these boards the resulting U-Boot is byte-identical to master's (verified on the T32LQ: same u-boot.dtb, SPL/U-Boot differ only in build strings). The 0001 patch is generated; this commit bypasses the do-not-edit hook the same way the CI regeneration commit does. Signed-off-by: Paul Philippov paul@themactep.com
- 9fc49f3 cameras: add the Cinnado D1 (T32LQ, SC4336P, ATBM6162U) Defconfig and thingino.json for the Cinnado D1: T32LQ, SC4336P, ATBM6162U Wi-Fi, SFC NOR on 16MB flash. Relies on the 4.4.94 default kernel and the per-camera U-Boot 2026.07 override. Signed-off-by: Paul Philippov paul@themactep.com
- b37268e kernel: default to 4.4.94, pin 3.10.14 per camera Flip the kernel-version choice so 4.4.94 is the default for the t23/t31/t32 families too, not only t40/t41/a1/c100, and mirror it in the make-layer fallback. Cameras that need 3.10.14 now say so explicitly with KERNEL_VERSION_3=y; the 220 previously-implicit boards (t10/t20/t21/t23/t30/ t31/t32 plus the legacy t23n cameras-exp one) are pinned in their defconfigs. Also repin the t32 4.4.94 kernel to the current ingenic-t32-4.4.94 tip (470050ba). The previous pin (fac1029e) predates the branch and fails to build goat.dtb. Signed-off-by: Paul Philippov paul@themactep.com
- 0de952b prudynt-t: fall back to MJPEG when H.265 cannot be decoded The fMP4 preview configured
VideoDecoderwithout checking support. On a browser with neither MSE HEVC nor a WebCodecs HEVC decoder (Chrome on Linux, Firefox),configure()failed asynchronously and the error callback reconnected on every attempt, so the status line looped on "H.265 decoder error ... Reconnecting..." forever. AskVideoDecoder.isConfigSupported()before configuring; when the platform cannot decode H.265, stop retrying and swap the video sink for the camera's MJPEG stream, which the ISP produces independently of the video codec. The ch1 JPEG is unavailable while the Main stream owns the encoder, so fall back to ch0 once. Cache the choice per channel so a reconnect does not reopen the fMP4 socket, and treat a decoder error that reports an unsupported configuration as terminal rather than reconnecting. Label the player with the stream encoding and transport: a badge next to the channel selector showing H.265/H.264 and fMP4 (MSE), fMP4 (WebCodecs) or MJPEG. Signed-off-by: Paul Philippov paul@themactep.com - fd126de diag: keep BSSID, frequency, signal and flags in the WIFI-SCAN scrub Review feedback on #1783: the BSSID-anchored regex swallowed every column after the MAC, so frequency, signal level and flags were redacted along with the SSID - the opposite of what the PR promised. Signal level is usually the reason to capture a scan. Redact only the trailing (SSID) field instead, which keeps the useful columns and also handles hidden (empty) SSIDs. Also document the ssid(...) redaction assumption that an SSID contains no ')' - noted by the same review. Suggested-by: Paul Philippov paul@themactep.com Signed-off-by: WLTB Gino gino@wltb.local
- a0032f5 docs: reflect the unified overlay upperdir layout Update the overlay, package-bundle, and on-device notes for the shared upperdir at DATA/root, the bind-mounted /overlay, and the one-time migration. Document the /overlay/ == upper of / contract that jct restore, wlan.in, S44devmounts, and overlay backup/restore rely on. Signed-off-by: Paul Philippov paul@themactep.com
- 8e3f248 ota: stop requiring 1.5x the firmware size in /tmp check_and_free_space counted fw_size + 50% as the tmpfs requirement for full upgrades, but the image is renamed into the workdir and streamed straight to flash, never duplicated; only the ~1 MB busybox clone and the scripts share the tmpfs. The 1.5x demand can exceed the tmpfs size itself (50% of RAM), so the check never passed on low-RAM devices and every full OTA remapped rmem and rebooted first. Require fw_size + 2 MB instead. Signed-off-by: Paul Philippov paul@themactep.com
- 8a7e89f build: warn when the rootfs will not fit an 8 MB flash The image is assembled on an 8 MiB slab and many supported cameras carry only 8 MB of SPI NOR, but pack only reported hard overflows. Warn when the rootfs end (DATA_OFFSET) passes 8 MiB minus the minimal JFFS2 data partition, so a build that quietly needs a 16 MB part still shows up on 8 MB targets. Share the minimal JFFS2 size (5 erase blocks) with the existing data-partition check instead of the hardcoded 327680, so 32 KiB-erase targets use 5 x 32 KiB. Print the new warning in YELLOW so it does not blend into the orange Camera/Device IP lines. Signed-off-by: Paul Philippov paul@themactep.com
- 64ccb84 wifi-atbm6162u: document intermittent teardown crash Add a FIXME at the package describing a kernel oops seen when the interface is brought down (rcK does this on reboot): kfree on an already-freed or non-slab pointer inside the vendored mac80211 station teardown, reached via cfg80211_leave -> ieee80211_mgd_deauth -> sta_info_flush -> __sta_info_destroy. It wedges the reboot until the hardware watchdog fires. Record the trace tail and the functions to start from (__sta_info_destroy's gtk/ptk free block, __ieee80211_key_free / __ieee80211_key_replace) and note the vendor CONFIG_MAC80211_ATBM_ROAMING_CHANGES async sta/key free as a suspect. Not reproducible on demand; a guarded kfree did not catch a double free during forced ifdown and rcK runs. Upstream atbm-606x-c has no fix. Signed-off-by: Paul Philippov paul@themactep.com
- eb43143 init: unify the overlay upperdir layout across kernel drivers The data partition is the overlayfs upperdir, and both the build seed and the runtime writers address it as /overlay/. The 3.10 legacy driver accepts upperdir=/overlay, but the mainline driver (4.4.94, 7.x) rejects a workdir inside the upperdir, so the build kept seeding user files at the partition root while the kernel used upperdir=/overlay/root. Baked files and every hardcoded /overlay writer (wlan.in, S44devmounts, timps-upload, overlay-backup, fw_ota) then hit an inert layer. Pack user overlay/opt under data/overlay/root for both drivers, mount both with upperdir=DATA/root, and bind root/ over /overlay after the pivot_root, so /overlay/ is the upper of / on every kernel. No writer changes. Fold a legacy 3.10 flat upperdir under root/ on first boot, marked so it cannot rerun. On that driver root/ and work/ are the uppers of /root and /work, so they are shuffled aside and restored inside the new container rather than consumed as it. Mainline partitions are already correct and are not touched. Signed-off-by: Paul Philippov paul@themactep.com
- d48cfc6 webui: reach prudynt backends over the same origin A page loaded over HTTPS could not talk to the prudynt HTTP API on
http://<host>:8080: the browser blocked each fetch as mixed content, so the RTSP/ONVIF password form and the streamer config pages failed to load and failed to save. Route browser calls through same-origin CGIs instead.config-rtsp.jsuses the existingx/json-config-rtsp.cgi; everything else goes through the newx/json-prudynt-proxy.cgi, a session-authenticated reverse proxy to127.0.0.1:8080that forwards only/api/v1/*. The fMP4 live stream moves to the streaming proxyx/fmp4.cgi, which reads the API key on the camera and streamschN.mp4. The unusedAPI_BASE/API_KEY_PROMISE/apiFetchcluster in coremain.jsis dropped. Only server-side CGIs talk to127.0.0.1:8080now. Fixes #1786 Signed-off-by: Paul Philippov paul@themactep.com - acc9b9b prudynt-t: split the config into a read-only core and a writable user layer The streamer owned a single writable
/etc/prudynt.json, so a failed write corrupted it and prudynt refused to start. Keep the image default in a read-only core and apply user changes as a layer: /etc/prudynt.json read-only core from the image /etc/prudynt.user.json writable deltas, preserved across upgrades /run/prudynt.json consolidated tmpfs view read by consumers Addprudynt-config, a single get/set/refresh accessor for the layers: it refuses to clobber a corrupt user layer and ignores a non-object one.S31prudyntmigrates a legacy overlay/etc/prudynt.jsoninto the user layer once and seeds/run/prudynt.jsonbefore start;S32prudyntwdwaits for the restart lock and stops when the streamer is disabled. Shell and CGI consumers read/run/prudynt.json, and writers go throughprudynt-configso deltas land in the user layer. Signed-off-by: Paul Philippov paul@themactep.com - 10fdefd config: read the merged prudynt runtime from
/run/prudynt.jsonThe prudynt config is a read-only core (/etc/prudynt.json) plus a writable user layer (/etc/prudynt.user.json) merged into/run/prudynt.json. Readers that still open the core miss user changes. Point the remaining consumers at the runtime:preview.jsreads the FPS through the streamer API (the direct file fetch was never served),S49ntpdandS50mdnsduse the consolidated file, and the dev scripts (rtsp-stress-test.sh,user-push.sh) read/run/prudynt.jsonand write the user layer. Back the user layer up and fix the OSD save prompt. Signed-off-by: Paul Philippov paul@themactep.com - 3de7d47 onvif: bump the package, fix authentication from prudynt config
- 4f99098 wifi: use the selected kernel version in module install paths The module tree path was hardcoded to 3.10.14 across the atbm and mt7601 packages, so building any of them on 4.4 dropped modules.builtin.modinfo into a bogus 3.10.14 directory. atbm6031 and atbm6132u are already used by 4.4 cameras; the rest are 3.10-only today but carry the same trap. Replace the hardcoded release with $(KERNEL_VERSION), as atbm6162s does. No change on 3.10: the value expands to 3.10.14.
- 03b44c1 wifi-atbm6162u: fix build for the 4.4 kernel The pinned commit had no configs/atbm6162u.config, so configuring failed. Bump to the atbm-606x-c commit used by atbm6162s, which carries the config. That config leaves CONFIG_CPTCFG_CFG80211 off, so the driver's bundled cfg80211 was never built and atbm6162u.ko came out with undefined cfg80211 symbols. Enable it in the staged config and turn the kernel's own cfg80211 and mac80211 off, matching atbm6162s: linking the driver's backports against the 4.4.94 headers is an ABI mismatch. Also fix the install path, which was hardcoded to 3.10.14.
- 287d812 diag: scrub SSID from WIFI-SCAN section and ATBM dmesg lines Two SSID leak paths were left in cleartext in diag output: - wpa_cli scan_results (WIFI-SCAN section) was captured with no redaction at all; WIFI-INFO and WPA-STATUS were already scrubbed. Keep BSSID/frequency/signal, drop everything after the flags column (the SSID). - ATBM drivers print the associated SSID into dmesg (atbm_log ... authen:(bssid),ssid(...)), which no capture-time filter covered. Scrub ssid(...) patterns in the final pass alongside the existing openRTSP credential redaction. Validated both patterns against a real diag bundle from an ATBM6031 camera: SSID no longer appears anywhere; BSSID and signal remain for troubleshooting. Reported-by: Omagerrrhd (thingino Discord)
- 5e8cb16 timps WebUI: drop the dead crop 'after restart' note Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 1c4af11 S95timps: note --check-libs exit 80 (could not check) Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 4414aee timps-irprobe: 900 s failsafe watchdog for idle Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- fddb82d timps WebUI: Idle-Dark card on the Day / Night page Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- cd15237 ci: exclude vendored webui assets from the Prettier check The check's case pattern (a/.js) has * crossing directory separators, so it matched a/vendor-lite/.min.js and failed on the minified bundle. Exclude vendor* the same way the pre-commit hook does. Signed-off-by: Paul Philippov paul@themactep.com
- eec601c webui: regenerate the offline vendor CSS for the current pages Re-purge after rebasing onto the latest ciao: the rebased tree adds tab and card markup, so the purged set grows slightly (88412 -> 88650 bytes). Signed-off-by: Paul Philippov paul@themactep.com
- 14795c8 webui: ship a reduced offline asset set for the full UI The full web UI pulls Bootstrap, Bootstrap Icons and a Google font from CDNs. In AP mode the camera has no uplink, so the requests fail and the UI renders unstyled and non-functional. Bundle a reduced local set by default, instead of the 483 KB full vendor dir, so the full UI works offline: - Bootstrap CSS purged from the pristine dist against every package web root (the UI is assembled from thingino-webui plus the streamer/plugin packages, and preview.html comes from the streamer, so purging only thingino-webui dropped classes those pages use) - Bootstrap JS tree-shaken to the components the UI actually uses - the Montserrat webfont, Chart.js and the icon font are not bundled; the rewriter drops their links (the icon subset lacked glyphs the streamer pages use, which rendered as tofu, so icon elements are hidden) Net ~171 KB uncompressed (~45 KB in the squashfs image) vs 483 KB. Also make the paranoid rewriter match CDN tags regardless of attribute order: apply_cdn_fallback.py appends integrity/crossorigin/onerror at install time and this runs later at rootfs time, so the old pristine-tag regexes matched nothing. The pre-commit vendor exclusion now matches vendor* so the minified vendor-lite JS is not run through Prettier. Signed-off-by: Paul Philippov paul@themactep.com
- 757c7bb timps WebUI: ROI and crop/zoom tabs on the overlays page Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 1540526 timps-irprobe: idle and state verbs for Idle-Dark Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- dfa759f webui: tidy the sensor page action buttons The two inline-block buttons shared a row, and the
mt-3on Save pushed it out of line with Upload. Put Upload above the explanatory message and Save below it, so each sits on its own line and lines up. - 51dc49f webui: report the real SoC family on the sensor page
soc -falready returns the family (for examplet31), so stripping digits andxfrom it reduced the value tot. Use the family as is. - b80a888 prudynt-t: collapse the PTZ controls when pan/tilt is unavailable A camera without pan/tilt hardware showed the pad greyed out, and only after the motor-params request resolved, so the dead controls were visible for a while on load. Hide
#ptz-controlsfrom the start and reveal it only when the streamer reports motor steps, leaving the "no pan/tilt hardware" notice as the only thing a non-PTZ camera shows. - 79e2e9b webui: use the standard main card on streamer pages The prudynt and raptor streamer pages rendered their heading as a bare
<h3>while every other page uses<h2 class="card-title">inside a.card-header.main.cssstyles that selector (dark orange, x-large), so the streamer pages looked out of place. Wrap the section content in the standard card on both plugin sets. Thesave-configbutton stays outside the card on main/substream/image, as on the config pages; on the sensor page it stays inside the view column. The OSD header actions move into the card header. - ef94a2c webui: fall back to the Main snapshot for the streamer preview The streamer pages preview the ch1 substream through
/x/ch1.mjpg, but that JPEG channel is not always available: where the Main stream occupies the encoder, the ch1 snapshot answers withjpeg_unavailableand the preview image stays broken. Fall back to the ch0 snapshot once when the configured channel fails to load, and let the full-screen modal follow the effective channel instead of hardcoding ch1. - 151cc18 prudynt-t: repair the hvcC header in the H.265 preview The fMP4 muxer builds the hvcC
profile_tier_levelfrom the raw, emulation-escaped VPS bytes. The copied000003sequences shift the compatibility/constraint flags andgeneral_level_idc, so the level reads as 0 and the WebCodecs codec string is invalid (hvc1.1.c0000002.H0.0090000003), which makesVideoDecodererror out and the preview reconnect forever. Rebuild the 12 header bytes from the VPS NAL the record already carries (de-escaping it first) before deriving the codec string and the decoder description. On the live stream this turns the string intohvc1.1.2.H150.90and the preview starts. Also report the decoder's own error message on reconnect instead of overwriting it with a generic "Decoder reset.". - 5d05ecb webui: fold Information sections into in-page tabs The Information dropdown held 11
info.html?<section>links. Collapse them into a single "Commands and logs" entry and move section selection intoinfo.htmlas Bootstrap nav-pills, grouped Files / Logs / Info. PluginddInfofile sections (prudynt.json,raptor.conf) are merged into the matching group from the plugin manifests, honouring the contributionposition, and their dropdown links are suppressed so no duplicate entries remain. Deep links keep the?<section>shape; unknown or missing sections fall back tostatusinstead of the CGI's emptysystemcommand. Also drop the preview page's container max-width override and restore top-right placement for single card-header action buttons, lost when theh2 + small + buttonrule was replaced by.preview-header-actions. - 3eabd55 wyze-accessory: add Wyze Lamp Socket support Port the Lamp Socket feature merged to master in #1712 (1467f66) to ciao. Adapted to this branch's thingino-ha scripts, which carry extra entities (daynight_state, floodlight brightness) and cached config lookups. The Spotlight and Lamp Socket now share one ch341 module entry and one kernel config fixup block instead of adding each twice. Adds BR2_PACKAGE_WYZE_ACCESSORY_LAMP_SOCKET, lamp_socket_ctl, the S15lamp-socket boot hook, a Settings > Lamp Socket web UI page, a control bar Lamp toggle, and a Home Assistant switch. Enabled in the four wyze_cam3_* defconfigs. Signed-off-by: Paul Philippov paul@themactep.com
- b18d98f prudynt-t: fall back to WebCodecs for H.265 preview Where MSE will not take HEVC (Chromium without a hardware decoder, Firefox) the preview stayed black. Demux the muxer fMP4 fragments in the page, feed
VideoDecoderand paint frames to a canvas, dropping deltas when the decoder falls behind. WebCodecs is secure-context only, so over plain http the status line points at the H.264 substream instead. - 1b6a414 prudynt-t: HEVC codec string for the fMP4 preview web UI The preview fetched the hvc1 init segment but
codecFromInitonly recognisedavcCand always asked MSE foravc1, so an H.265 channel failed to append. ParsehvcCand build the RFC 6381hvc1codec string, and gate the player onMediaSource.isTypeSupportedso a browser without HEVC says so instead of going black. - 9d4ef65 timps: S95timps runs timpsd --check-libs before starting 78/79 (libimp does not fit the build) logs to syslog and skips the start; anything else, or a timpsd without the option, starts as before. Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 12d768e timps: ship image.anti_flicker = 1 (50 Hz) Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 7c22424 timps-irprobe: switch every illuminator daynight.controls enables Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 8ee46a6 thingino-agent: install the null adapter from a finalize hook Every ciao prudynt build shipped the null backend adapter instead of the streamer's, so /api/v1/actions/daynight (and privacy, record, snapshot, service control) failed with "daynight action is not supported without an active backend adapter". The UI toggle then never stuck and reverted to auto. With BR2_PER_PACKAGE_DIRECTORIES=y the final target is assembled by rsyncing each per-package target in $(sort $(PACKAGES)) order. thingino-agent sorts after prudynt-t/thingino-raptor, so the null adapter installed in THINGINO_AGENT_INSTALL_TARGET_CMDS overwrote the real one during the merge, regardless of build order. Match aperto: drop the null install from the install commands and stage it from a TARGET_FINALIZE_HOOKS hook that only fires when no streamer has provided an adapter. Signed-off-by: Paul Philippov paul@themactep.com
- 5d22ab7 ciao: address PR #1654 review minors - json-imp.cgi: replace the non-ASCII em dash in a comment; shipped shell scripts are ASCII-only. - dhcpv6.script: also drop resolv.conf lines written by the older trailing-comment format, so they are not left behind as duplicates. - irled: report a clear error when light is not installed instead of failing with a bare 127. - ptz_set_home: pass an empty description so ptz_presets keeps the existing preset label instead of overwriting it with "Home". Signed-off-by: Paul Philippov paul@themactep.com
- a10c14b timps webui notes: media fetch needs the token on open cameras Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 446dcf8 timps: pin v1.9.33 with hash Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- b7df454 wifi: disable unused mac80211 module for aic8800
- 4317001 make: borrow t32 knobs from the master
- bb3a8d9 overlay: make the NFS mount opt-in with a nested nfs config The share address lived in a top-level nfs_share string, so the only way to stop mounting it on boot was to delete the address. Replace it with an nfs object: "nfs": { "enabled": false, "share": "192.168.88.20:/nfs" } The if-up hook and S43mounts mount only when nfs.enabled is true; when disabled S43mounts warns instead of failing silently. Add
S43mounts forceto persist enabled: true and mount immediately, for when the address is kept but the share is wanted now. Redact the new nested share value from diagnostics (keep nfs_share for dumps still carrying the old key) and document the entry in docs/thingino/nfs-share.md, linked from the overlayfs page. Signed-off-by: Paul Philippov paul@themactep.com - e15491b webui: keep the SSE failure counter pure, back off the session probe Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 534cf30 webui: trim the new comments in main.js Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- e47389d webui: probe the session on a timer, drop the dead status branch Review of #1745: an open SSE stream is authenticated once and keeps delivering after the session expired, so the failure counter never reached the session check. verifySessionStillValid() now also runs every 60 s while the page is visible, only authenticated:false counts as a refusal (session-status.cgi always answers 200), and a successful probe resets the SSE failure counter. Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- bd20c49 libsrt: build with -ffunction-sections -fdata-sections timps compiles its own sources that way and links with --gc-sections, but libsrt.a did not, so the linker could only discard whole object files while timps uses a small slice of libsrt's C API. Worth 28672 bytes packed in an SRT image at no functional cost (libsrt.a itself grows, 1060438 -> 1253430 bytes; the linked binary shrinks). Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 2c76a59 package/ingenic-sdk: update to 635afc9 Update ingenic-sdk from e097418 to 635afc9 Hash change: e0974182df7e001ff76e6cdf25d36d593fde7ed4 -> 635afc94a74afc1358c1164fd3bf46822ff32fca Changelog: 635afc9: sensor-iq: add default IQ file for sc231hai sensor
- c408301 Fix WS73V100 patch metadata and context Co-authored-by: themactep 37488+themactep@users.noreply.github.com
- 2adf398 wifi-ws73v100: use available encoding for INI map Co-authored-by: themactep 37488+themactep@users.noreply.github.com
- 923a48e package/timps: update to v1.9.32 Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 829eddf timps: hash v1.9.28 and v1.9.29 under their git tarball names TIMPS_SITE_METHOD is git, so buildroot stores the archive as timps--git4.tar.gz. The two entries named timps-v1.9.28.tar.gz and timps-v1.9.29.tar.gz never matched it and a build of those versions failed with "No hash found". The new hashes are those of the git archives, as for every other version in the file. Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- f0081c6 timps: link only libimp when OpenIMP provides it OpenIMP's libimp does not link libalog or libsysutils and timps imports no SU_*/alog symbol itself, so with BR2_PACKAGE_OPENIMP neither library is needed. Link -limp alone and stop selecting the Ingenic libsysutils; vendor-libimp builds are unchanged. Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 56a1fa5 ingenic-sdk: jxf23 runs the reset/power-down pulse on every g_chip_ident() Review feedback: only the GPIO request/free is gated on the held flags; the reset and power-down sequence runs on every call while the line is held, so a retry after a failed detect (no remove() in between) gets the pulse too. Patch header uses the noreply address. Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
- 0173819 package/timps: update to v1.9.31 Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 96eb106 package/timps: update to v1.9.30 Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- d0d54aa ingenic-sdk: patches for t21 jxf23 GPIO ownership and t31 sc4336p vflip result - 0002 jxf23 (T21): request the reset/pwdn GPIOs only once and free only the lines the module actually holds, so a re-registration or module reload no longer logs "gpio request failed", skips the reset sequence or frees GPIOs it does not own. - 0003 sc4336p (T31): sensor_set_vflip() returns the real I2C result instead of -1 on success, so the ISP driver no longer logs "sensor flip failed: -1" on every flip. Both apply on the pinned ingenic-sdk e0974182 after 0001. Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 73bb039 timps webui: Effects card (colour effect, scene) on the image page Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 96c778d timps webui: dead-pixel correction slider on the image page Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 9ba8919 package/prudynt-t: update to 6e48034 Fixes the frozen fMP4 preview. serve_fmp4() advertised an AAC track whenever audio was configured, even when the audio encoder failed to initialise (the audio_stream object exists but imp_audio is null, so no audio frames are ever muxed). Browsers then drop the whole muxed stream (MediaSource buffered stays empty), freezing the preview on the first frame while only a page reload shows a new one. 6e48034 registers the audio tap only when the encoder is live and advertises the track only when the tap exists. A camera whose audio encoder failed now produces a video-only fMP4 that plays; cameras with working audio keep it. Signed-off-by: Paul Philippov paul@themactep.com
- a3c95e1 docs/dev: document the sensor registry ABI Record the /proc/jz/sensor/sensorN/ keys, the two registry sources (the open stack via SENSOR_PROC_OWNED_BY_ISP, the proprietary families via SENSOR_REGISTRY_IN_SDK), the flat-tree coexistence required by prudynt, and per-family status: t23 and t31 validated on hardware, t40 and t41 build-level. Signed-off-by: Paul Philippov paul@themactep.com
- e1c1b14 ingenic-sdk: publish the sensor registry for t23/t31/t40/t41 Bump INGENIC_SDK_VERSION to e0974182, which adds the SDK-side sensor registry (common/isp/common/tx-isp-sinfo.c), the per-family hooks and the t40 sc3338 IQ. For the proprietary ISP families, define SENSOR_REGISTRY_IN_SDK so the registry is compiled into tx-isp- and fed from the sensor modules. The open stack keeps SENSOR_PROC_OWNED_BY_ISP, and the vendor flat tree stays published for prudynt. Signed-off-by: Paul Philippov paul@themactep.com
- 8e1e06e package/prudynt-t: update to ef28bcc Update prudynt-t from 6a7a86d to ef28bcc Hash change: 6a7a86d2cb88837d1727b3c9b610cfcd4a16d2ba -> ef28bcc9324210e71307df5b6c130bad98f24d28 Changelog: ef28bcc: t40: use the 1.3.1 en SDK headers
- 25e1e4a cameras: add Sonoff CAM-B1P SC2337P profile
- 34f7172 timps: pass USE_OPENIMP when the openimp package is selected Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 590f68b wireless: allow WLAN GPIO toggling on 4.4 kernels S36wireless applies the gpio.wlan sequence from thingino.json only when uname -r starts with 3.10; on 4.4 (T40/T41) it logs "Skipping WLAN GPIO toggling for kernel 4.4" and does nothing. The 3.10-only gate has no 4.4 counterpart in the tree: no kernel DT regulator/hog and no other init script consumes gpio.wlan, so on T40/T41 boards whose radio has a power-enable GPIO the pin is never driven and the module fails to probe (hit in the wild on a T41NQ board with an RTL8733BU radio, GPIO 61 active-low, where the stock firmware drove the pin from userspace at boot). Apply the same sequence on 4.4. The sequence consumer (apply_wlan_sequence via the gpio tool) is kernel-agnostic; the original 3.10 literal was a very conservative whitelist, not a functional dependency. The bcmdhd unexport cleanup applies unchanged. Backport of 9f245dd from master. Signed-off-by: Paul Philippov paul@themactep.com
- 277805e thingino-motors: fix S59motor stop path wedging motors-daemon stop_daemon() could never actually stop motors-daemon: the daemon self-daemonizes under -d (double-fork + setsid), so the PID start-stop-daemon records via -m is the intermediate child, which exits immediately -- the pidfile is stale from the moment it is written. stop() didn't check stop_daemon's result and proceeded to rmmod anyway, which succeeds against a live daemon because motor_fops lacks .owner = THIS_MODULE (module use count stays 0 with a live opener; filed separately as themactep/ingenic-sdk#45). That leaves motors-daemon in permanently uninterruptible D state, immune to SIGKILL, recoverable only by a power cycle. Fix: stop_daemon now matches the real process (anchored on the binary path, since an unanchored pattern also matches the calling shell) and escalates SIGTERM -> SIGKILL with a bounded wait, returning a real status. stop() now refuses to rmmod unless the daemon is confirmed gone, converting the failure mode from an unrecoverable wedge into an ordinary loud error. Tested live on an Eufy E220 (T8410C, T31X): the exact restart that previously wedged the daemon (reproduced on both legacy and profiled motion_driver, so unrelated to acceleration settings) now completes cleanly and leaves the motor responsive. Backport of 76b15a5 from master; fixes #1510 on ciao. Signed-off-by: Paul Philippov paul@themactep.com
- 95e64d6 prudynt-t: bump to 6a7a86d for the MJPEG IPC parser fix Picks up whole-token IPC key matching: a ch1 MJPEG request no longer parses the
hinsidech=1as a 1-pixel height, which re-inited the shared JPEG encoder at 16x16 on the first request after every restart. See #1724 Signed-off-by: Paul Philippov paul@themactep.com - d61abd1 prudynt-t: resync the fMP4 preview when the live edge drifts behind The preview only compares the playhead to the buffered live edge, so it cannot see a client whose backlog prudynt drains at exactly realtime. After a playback stall the camera queues fragments and then hands them out one per produced frame; buffered.end stays ~1s ahead of currentTime while the whole session plays stale content, so the MAX_AHEAD_S jump never fires. The tab shows smooth 1x video minutes behind the OSD clock until a manual refresh, and the reader/pump split keeps the socket drained so prudynt's send timeout never closes the stale client either. Anchor the media timeline to the wall clock once per session (the live edge at the first appended fragment plus its arrival time) and reconnect when the live edge falls more than MAX_DRIFT_S behind realtime. Only a fresh fetch resets the per-client queue, so tear the session down and start over instead of seeking inside the stale buffer. The anchor resets on teardown, so a reconnect cannot thrash. Signed-off-by: Paul Philippov paul@themactep.com
- ff43184 daynightd: accept ev_log2 == 0 as a valid brightness reading The ISP ev_log2 field reports 0 at the minimum exposure (brightest scene), but every guard tested
ev_log2 > 0, so a legitimate 0 was discarded as though the field were absent. primary_signal then stayed at its -1 sentinel, and since the only exit from NIGHT issig > 0 && sig < day_thr, the daemon latched in night mode whenever the AE exposed down to the floor. Restarting daynightd did not recover it: the -1 signal never satisfies the DAY condition, so initial detection timed out and re-applied NIGHT. Restarting prudynt did not help either, because /run/thingino/daynight_mode stays "night" and S31prudynt re-applies running_mode=1 on start. Only a reboot reset the ISP and the field read positive again, until the next night transition. Treat -1 as the sole "absent" sentinel and 0 as a valid reading across the proc parsers, the brightness mapping, and the initial/hysteresis decisions. scripts/test_daynight_init.py mirrors the daemon algorithm and is updated to match. Signed-off-by: Paul Philippov paul@themactep.com - 89140c7 ingenic-sdk: bump to 7a160931 for the SC2336P/SC2337P die check Picks up the t23 sensor_detect revision check: the two dies share chip id 0x9b/0x3a, and the low nibble of register 0x801e now selects the right driver, so a wrong profile fails AddSensor instead of binding with the wrong init timings and IQ. Signed-off-by: Paul Philippov paul@themactep.com
- 87b7c51 configs: add Sonoff CAM-PT2 SC2337P profile SC2337P is a distinct SmartSens die, not an alias of SC2336P. They share chip ID 0x9b/0x3a, but sinfo/sensor_info.c tells them apart by the low nibble of register 0x801e (SC2336P requires 0, SC2337P requires non-zero); each also has its own IQ bin and its own driver init timings. The SDK builds one sensor driver per profile, so units with the SC2337P die need their own profile. Mirror the sc2336p profile and change only the sensor name. The sensor comes up through the standard sensor-info path (sc2337p.c calls sensor_common_init in the pinned ingenic-sdk), so no prudynt.json sensor override is needed. Supersedes #1668. Signed-off-by: Paul Philippov paul@themactep.com
- 429badb thingino-ha: gate the new day/night entities on their own flags
brightnessanddaynight_statewere published and cleared inside thegainanddaynightblocks, so they could not be enabled or disabled on their own andenable_brightness/enable_daynight_statehad no effect. Add both to HA_ENTITIES and gate them withha_entity_enabled. Brightness comes from daynightd, so only discover it where daynightd exists; before, it was announced on prudynt-only images and stayed "unknown" forever. Follow-up to #1728. Signed-off-by: Paul Philippov paul@themactep.com - 3b9c55d thingino-diag: redact the full MQTT credential in the ps listing The previous pattern matched one quoted run, so a broker host, username or password containing both a single quote and a space was only partly redacted:
_sqemits'\''for an embedded quote, and the regex stopped at the following space.-P 'a'\''b c'became-P REDACTED c', leaving part of the credential in the diagnostics. Move the filter into aredact_pshelper and match the whole shell word, escapes included. Verified on BusyBox sed. Follow-up to #1729. Signed-off-by: Paul Philippov paul@themactep.com - 2b9361f prudynt-t: recover a wedged prudynt and quiet the IVS timeout log
S31prudynt stopforce-killed withstart-stop-daemon -K -s KILL /usr/bin/prudynt, butstop_daemonhad already removed the pidfile and start-stop-daemon cannot match a process stuck in a driver wait. It printed "no /usr/bin/prudynt found; none killed" and left the process running, so the stream watchdog'sservice restart prudyntcould not clear a wedge. Capture the PID before it is removed and SIGKILL it directly, falling back tokillall -9 prudynt. Also bump prudynt to c9cc19f so anIMP_IVS_PollingResulttimeout logs at debug instead of warn; a shortivs_polling_timeoutwas flooding syslog and evicting useful history. Fixes #1611 Signed-off-by: Paul Philippov paul@themactep.com - 9f2222d prudynt-t, webui: unblock motion alerts from clip capture
motionran every send2 service only after the snapshot and the video capture-wait, soplayonspeakerwas delayed by the whole clip (up tovideo_length+ 10 seconds). Split the services by their own media need:playonspeakerand text-only send2 services fire immediately, media-bound ones after the capture. Move the per-service invocation into arun_servicehelper. Exposevideo_length,post_timeandmin_timeon the Motion page;post_timeis the anti-fragmentation knob (an episode ends only onceduration >= max(min_time, post_time)). Also document that events during an active clip are dropped by the singleton guard. Fixes #1647 Signed-off-by: Paul Philippov paul@themactep.com - ea78f63 webui, thingino-ha: use the supported full upgrade path
sysupgrade -phas been a hard error since partial upgrades were disabled (5888605): it prints "Partial upgrades are not supported anymore." and exits 1. The HA firmware update entity ran exactly that, backgrounded with output discarded, so clicking Install in Home Assistant logged "starting partial firmware upgrade" and then did nothing. The same flag was still offered by the WebUI OTA form. Run the HA update assysupgrade -f -B: a full upgrade that keeps the backup partition, soS37cfg-autorestorerestores the config on the next boot. Drop the WebUI "Partial update" option and default the OTA form to full, and fix the comments and help text that still promised-p. Fixes #1664 Signed-off-by: Paul Philippov paul@themactep.com - 06590c9 prudynt-t: bump to 44bdd2f for the motion frame-geometry fix Resolve motion
frame_width/frame_height/roi_1_x/roi_1_yfrom the monitored encoder channel instead of the sensor, so a substream monitor gets an ROI that matches the frames it actually sees. Also fail with a logged error when the channel attributes cannot be read. See #1645 Signed-off-by: Paul Philippov paul@themactep.com - 4373a59 fix: redact mosquitto credentials in thingino-diag process list The PS section now masks the -h, -u and -P arguments of mosquitto_pub and mosquitto_sub command lines. The long-running mosquitto_sub started by thingino-ha showed the MQTT broker host and username in clear in the diagnostic output.
- 996af90 timps webui: Highlights slider is 0..10, not 0..255 Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- 46462b8 timps webui: hide the Custom white-balance mode on T10/T20/T30 Their SDK's isp_core_wb_mode ends at Warm fluorescent, so timps clamps a 9 to 8 and the page would show a correction notice for a choice it offered itself. Hidden by the device SoC from thinginino UI config; an unknown SoC keeps all options. Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- b041135 thingino-ha: report camera brightness in percent The Home Assistant Gain sensor declared dB, but it publishes the raw ISP total gain, so Home Assistant showed a wrong unit and recorded long-term statistics under it. Gain now has no unit and moves to the diagnostic category, and a new Brightness sensor publishes the 0-100 % level that daynightd writes to /run/thingino/daynight_brightness. Both stay under the existing gain option.
- e0aabbf thingino-ha: drive the day/night select through daynightd On images with daynightd the Home Assistant day/night select sent force_mode to prudynt, which ignores it, and read /run/prudynt/daynight_mode, which does not exist, so choosing night left the image in color and the select always showed day. The select now follows the thingino-agent and web UI path (daynight.enabled and daynight.force_mode in thingino.json, the daynight script, SIGHUP to daynightd), gains an auto option that resumes automatic switching, and a new Day/Night State sensor reports the mode actually applied from /run/thingino/daynight_mode. Images without daynightd keep the prudynt path.
- 6917ba5 prudynt-t: bump to 80dbd14 for the IVS idle-pause fix
prudynt80dbd14 keeps a channel that hardware IVS monitors active, so the idle pause no longer disables that channel's framesource and wedges motion detection. Without it, motion events, motion-triggered recording, and the substream frames all die at startup wheneverstream3(JPEG on the substream) ships disabled, which is the default. Fixes #1718 Signed-off-by: Paul Philippov paul@themactep.com - 3cc5ab1 webui, prudynt-t: play a bundled sound for the speaker test
speaker.fileships empty, soplayonspeakeraborted with "No speaker file configured" whilesend.cgibackgrounded it and always returned success. The WebUI showed "Speaker test played." for a no-op, and motion alerts through the same script were silent too. Fall back to a bundled sound when no file is configured:chime_1for the manual test,motiondetectionactivatedfor motion, resolving.opusor.ulawby what the image ships. Run the test synchronously and report the real result, and route the WebUI Test button through the shared test modal so its output is visible. Fixes #1723 Signed-off-by: Paul Philippov paul@themactep.com - 9759429 package/timps: update to v1.9.29 Update timps from v1.9.28 to v1.9.29 Hash change: v1.9.28 -> v1.9.29 (No changelog available)
- 0d0b343 package/lightnvr: update to 0.42.9 Update lightnvr from 0.42.8 to 0.42.9 Hash change: 0.42.8 -> 0.42.9 (No changelog available)
- fb708f8 wifi: rename the portal timeout function so it stops shadowing timeout(1) S38wpa_supplicant defined a shell function named 'timeout' (the portal's 600-second auto-fallback) and called it as 'timeout &'. Defining it shadows the busybox timeout command for the whole script. The prescan bound added in 9862040 used 'timeout -k 1 5 ...', which therefore invoked the function instead of the command, so the prescan ran 'sleep 600' and the camera sat at 'Running pre-portal Wi-Fi scan' for ten minutes. Rename the function to portal_timeout and update its call site; the bound then reaches the real command. Signed-off-by: Paul Philippov paul@themactep.com
- d32de32 wifi: bound the pre-portal prescan instead of trusting its deadline prescan_for_portal() documents a hard PRESCAN_DEADLINE, but that deadline only covers the scan_results polling loops. The two calls that actually touch the driver - 'ip link set $IFACE up' and the standalone wpa_supplicant start - were unbounded, so a driver that wedges during bring-up or supplicant init blocked rcS indefinitely and the camera came up with no login prompt (portal mode, before the AP even starts). Bound both with 'timeout -k': a plain SIGTERM is ignored while a driver ioctl is in flight, so the -k SIGKILL fallback is what makes the bound real. With this, a wedged radio costs at most ~5s and the portal AP still comes up. Signed-off-by: Paul Philippov paul@themactep.com
- 0e84673 S40network: run the Ethernet PHY reset pulse before the portal-mode bail-out, and deassert it properly when active_low The PHY reset block in S40network had two problems. It sat behind the portal/AP-mode early exit, so on a first-boot or wizard-holding camera the PHY was never woken and wired DHCP could never run - fatal for a wired-only board. And the active_low branch drove the line low and left it there, holding an active-low PHY in reset forever. Move the pulse ahead of the portal short-circuit (it is a no-op for boards that do not declare gpio.eth.toggle), end it in the deasserted state, and drop the misleading error log for the no-toggle case. Declare the Jooan Q3R wired-Ethernet PHY reset (GPIO 64, active-low) in its thingino.json so the in-boot pulse actually runs on this board. User's working first-install setup was a hand-written S39phy-reset init script doing exactly this sequence before S40network; a full reflash wiped the overlay and the board came back with dead ethernet and no recovery path through the wizard. With the declaration in the profile, the base-code mechanism replaces the lost script.
- dcb52d2 package/timps: update to v1.9.28 Update timps from v1.9.27 to v1.9.28 Hash change: v1.9.27 -> v1.9.28 (No changelog available)
- 8cd4747 package/thingino-wolfssl: update to v5.9.4-stable Update thingino-wolfssl from v5.9.2-stable to v5.9.4-stable Hash change: v5.9.2-stable -> v5.9.4-stable (No changelog available)
- 56e60d2 package/thingino-ubus: update to 414c60a Update thingino-ubus from 9ba1ab7 to 414c60a Hash change: 9ba1ab795b2f427ba0d9b00e27a3e0b343a8410b -> 414c60a2e29e72c2c4f573bc50ad54aef076d169 Changelog: ce54d7a: ubusd_main: free partially received message on client disconnect 6b5c6f1: ubusd_main: free queued lookup commands on client disconnect b012bc0: ubusd_acl: use SO_PEERGROUPS instead of parsing /proc for peer gids 955ff3f: ubusd: fix use-after-free when resuming a queued object lookup fb1dd8e: ubusd: document the bound on the pending-message body read 3a39a80: libubus-req: fix double close of the fd in ubus_complete_deferred_request 4d60031: libubus: fix msgbuf leak on ubus_channel_connect error path 91b0dad: libubus-req: fix error check on the __ubus_notify_async result 8241694: libubus-io: do not resend the fd on partial writes in writev_retry 618f3cf: libubus-obj: fix fd leaks on object message error paths 2f52ae3: ubusd_main: flush the tx queue after freeing the client's objects cdb648c: ubusd_obj: propagate subscription allocation failure to the client 7c5c068: ubusd_proto: fix double close of forwarded invoke fd d8fec00: ubusd: keep the fd alive while a message waits in the tx queue bde609c: ubusd_acl: copy the filename used as the ACL file vlist key 0086559: ubusd_acl: do not treat unresolvable ACL user/group names as id 0 5331c00: ubusd_event: document reserved event namespace forgery check ef37ed2: ubusd_event: use an unsigned type for the event dedup sequence e12ad4b: ubusd: flag event messages as not expecting a reply 9d709c5: ubusd_event: report allocation failure as out of memory 5170a58: ubusd: use canonical SCM_RIGHTS extraction on the receive path 8dfee69: ubusd_main: do not abort startup when the default socket dir fails 17f7861: ubusd: disconnect the client when a partially sent message is dropped f5e5836: cli: parse monitored payloads with the untrusted blob parser 11e411e: libubus: close the passed fd when the request exceeds the size limit cbc27b6: ubusd: stop writing to a client already flagged for disconnect 2ec13d4: libubus: do not restart the ACL query while one is in flight 297baef: libubus: free queued pending messages on shutdown 1752555: ubus/lua: fix Lua stack imbalance on policy allocation failure fdd9ff1: ubus/lua: copy the Lua strings stored in registered objects eb5a828: ubusd: close the forwarded fd when the invoke reply cannot be built 3930745: tests/fuzz: fix out-of-bounds read in header validation harness b27014c: tests/fuzz: use size of blob_attr, not of a pointer, in length guard 414c60a: ubus/lua: store event handler ref without polluting the callback table
- f0fee2f package/lightnvr: update to 0.42.8 Update lightnvr from 0.42.4 to 0.42.8 Hash change: 0.42.4 -> 0.42.8 (No changelog available)
- 0810a79 package/libjuice: update to v1.7.4 Update libjuice from v1.7.3 to v1.7.4 Hash change: v1.7.3 -> v1.7.4 (No changelog available)
- 1d9eb8b package/libdatachannel: update to v0.24.6 Update libdatachannel from v0.24.5 to v0.24.6 Hash change: v0.24.5 -> v0.24.6 (No changelog available)
- 48b6810 timps: S96onvif_discovery waits for a late gateway instead of giving up Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
- de20e74 webui: redirect to login when the session expires while a page is open The heartbeat SSE error event carries no HTTP status, so an expired session and a network blip looked the same: the page kept retrying with a dead session and never reached the login page. After three consecutive SSE failures the page now asks /x/session-status.cgi, which does report a status, and redirects to /login.html only on a definitive refusal (401/403 or authenticated:false). The slow heartbeat redirects on a 401/403 too. A single exit (redirectToLogin) with a guard flag keeps the three paths from racing each other; an unreachable endpoint or a 5xx still just retries. Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com