Skip to content

ssc377_lite: add TP-Link Tapo C120 device profile - #162

Merged
openipc-ai merged 1 commit into
OpenIPC:masterfrom
nzzane:tapo-c120
Sep 19, 2026
Merged

openipc-ai merged 1 commit into
OpenIPC:masterfrom
nzzane:tapo-c120

Conversation

@nzzane

@nzzane nzzane commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Adds devices/ssc377_lite_tp-link-tapo-c120 for the TP-Link Tapo C120: SSC377, SmartSens SC430AI (4 MP), 16 MB NOR (XM25QH128C), RTL8188FTV on USB.

What the device carries, and why each piece is here rather than in firmware:

  • ssc377_lite_tp-link-tapo-c120_defconfig — the generic ssc377_lite defconfig with BR2_OPENIPC_FLASH_SIZE="16", BR2_PACKAGE_RTL8188FU_OPENIPC=y, and BR2_PACKAGE_WPA_SUPPLICANT_OPENIPC=y in place of the stock supplicant (wpa_supplicant-openipc: 2.11 with WPA3-SAE on mbedtls firmware#2449; WPA3-SAE, needed for WPA3-only networks). Kernel config is the stock infinity6c-ssc027a.config, unchanged: cfg80211 as a module is fine with 8188fu.
  • general/overlay/etc/wireless/usb — the rtl8188fu-tapo-c120 entry: the Wi-Fi module's power is gated by GPIO 42, so it is driven high before modprobe 8188fu.
  • customizer.sh — upgrade URL, wlandev, sensor, and majestic's IR-cut (GPIO 81, single wire, inverted), backlight (GPIO 14) and opus audio.
  • S96irled — mirrors the IR-cut state onto the two IR LED GPIOs (12, 13); majestic has one backlight pin and this board has two LED banks.
  • sigmastar-osdrv-infinity6c/files/sensor/configs/sc430ai.bin — the SC430AI IQ file, from the camera's own stock firmware. Same arrangement as ssc335_lite_tp-link-tapo-c310-v220 (sc3335.bin, sc3338.bin); it was deliberately kept out of sigmastar: infinity6c: load the SmartSens SC430AI (TP-Link Tapo C120) firmware#2445 under that repo's binary policy. If it is not wanted here either, say so and I will drop it and keep the "take it from your own dump" instruction on the wiki.
  • excludes/ssc377_lite.list — the other infinity6c sensor modules and IQ files.

Depends on OpenIPC/sensors#7 (driver, built by sigmastar-osdrv-sensors at HEAD), OpenIPC/firmware#2445 (load_sigmastar entry) and OpenIPC/firmware#2449 (the supplicant package). Until those merge, CI here cannot build this device, so this is a draft until they do.

Built and tested locally against those three branches, on the camera (flashed with sysupgrade --kernel --rootfs):

  • uImage.ssc377 2039304 B (cap 2048 KB), rootfs.squashfs.ssc377 5513216 B (cap 8192 KB at 16 MB).
  • lsmod: cfg80211 184320 1 8188fu; wpa_cli status: key_mgmt=SAE pmf=2 wpa_state=COMPLETED on a WPA3-only AP; DHCP.
  • ipcinfo -ssc430ai; majestic Sensor index 0: 2688x1520@30fps, Load api bin Success - /etc/sensors/sc430ai.bin (found by sensor name, no sensorConfig set); RTSP and JPEG fine, colour correct with IR-cut in the day position.
  • customizer.sh ran on first boot: upgrade, wlandev, sensor set in the environment.
  • ci-matrix.py --self-test passes (116 devices).

Known limitation, from OpenIPC/firmware#2449: the stock wlan0 script still writes a WPA2-PSK block, so a WPA3-only network needs key_mgmt=SAE in the config by hand until the follow-up lands there.

Flash layout is the standard OpenIPC 16 MB map (3072k(kernel),10240k(rootfs)); the U-Boot image is the stock u-boot-ssc377-nor.bin. The wiki page (OpenIPC/wiki#549) is being updated to point at this device.

SSC377, SmartSens SC430AI, 16 MB NOR, RTL8188FTV on USB. The generic
ssc377_lite defconfig with the 16 MB layout, the rtl8188fu driver and the
SAE-capable wpa_supplicant-openipc; the Wi-Fi module's power gate (GPIO 42)
in the wireless/usb entry; IR-cut, backlight and IR LED pins; the SC430AI
IQ file.

Depends on OpenIPC/sensors#7 (driver), OpenIPC/firmware#2445 (loader entry)
and OpenIPC/firmware#2449 (supplicant package).

@openipc-ai openipc-ai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All three dependencies are merged: OpenIPC/sensors#7 (0294a00), OpenIPC/firmware#2445 (e155691a) and OpenIPC/firmware#2449 (4d145e6c). Taking this out of draft so it can build.

On sc430ai.bin: keep it. It is the right thing here for the reason you gave — ssc335_lite_tp-link-tapo-c310-v220 already ships sc3335.bin and sc3338.bin at the same path, and this repository's own notes describe kc110-board-support shipping a device-specific binary through SITE_METHOD = local. Per-device vendor assets are what devices/ is for; the firmware tree's binary gate is about what reaches every camera, which is exactly why keeping it out of #2445 was correct. Both halves of that were right.

The rest reads well:

  • The defconfig is a three-line delta from generic ssc377_lite — flash size, the driver, the supplicant — and nothing else, which is the shape a device profile should have.
  • excludes/ssc377_lite.list resolves against ${OPENIPC_SOC_MODEL}_${OPENIPC_VARIANT}.list, which is the name rootfs_script.sh looks for, and every one of its 16 entries matches a real file, so test_excludes_report.sh will stay quiet.
  • wireless/usb calls gpio and modprobe only; gpio is a shell script in the shared overlay, so it is on the image. The gpio set idiom matches five other devices here.
  • S96irled explains why it exists in its header — majestic has one backlight pin and this board has two LED banks — which is the comment style this tree wants.

Merging once CI is green.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Add TP-Link Tapo C120 profile for SSC377 Lite

✨ Enhancement ⚙️ Configuration changes 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Adds an SSC377 Lite firmware profile for the TP-Link Tapo C120.
• Configures SC430AI imaging, WPA3-capable RTL8188FU Wi-Fi, audio, and 16 MB flash.
• Synchronizes dual IR LEDs with Majestic’s IR-cut state using board GPIOs.
Diagram

graph TD
  A["Build profile"] --> B["Firmware image"] --> C["Device customizer"] --> D["Majestic runtime"]
  E["Sensor assets"] --> B
  B --> F["Wi-Fi startup"] --> G["RTL8188FU driver"]
  D --> H["IR LED service"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Add native dual-IR support to Majestic
  • ➕ Avoids continuous GPIO polling and a background shell process
  • ➕ Provides reusable multi-bank IR illumination support for other devices
  • ➕ Keeps IR-cut and illumination transitions within one runtime component
  • ➖ Requires coordinated changes in another project
  • ➖ Broadens the scope and delays this device profile
  • ➖ May require a new configuration schema and compatibility handling

Recommendation: Keep the profile-local S96irled service for this PR because it isolates board-specific behavior and avoids another external dependency. Native multi-pin illumination support in Majestic would be cleaner long term and should be considered as a follow-up if additional boards need the same behavior.

Files changed (7) +162 / -0 · 1 not counted

Enhancement (3) +49 / -0
S96irledMirror IR-cut state to both IR LED banks +33/-0

Mirror IR-cut state to both IR LED banks

• Adds an init service that exports GPIOs 12 and 13 and periodically mirrors the inverse of GPIO 81. Start, stop, and restart actions manage the background polling process through a PID file.

devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled

usbPower and initialize the RTL8188FTV module +16/-0

Power and initialize the RTL8188FTV module

• Adds a board-specific wireless hook that enables the USB daughterboard through GPIO 42 before loading the 8188fu kernel module.

devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/wireless/usb

sc430ai.binAdd SC430AI image-quality calibration not counted

Add SC430AI image-quality calibration

• Packages the SC430AI IQ binary sourced from the camera’s stock firmware so Majestic can load sensor-specific image calibration at runtime.

devices/ssc377_lite_tp-link-tapo-c120/general/package/sigmastar-osdrv-infinity6c/files/sensor/configs/sc430ai.bin

Documentation (1) +1 / -0
README.mdList the Tapo C120 as a testing device +1/-0

List the Tapo C120 as a testing device

• Adds the TP-Link Tapo C120 to the supported-device table with its SSC377 SoC, SC430AI sensor, RTL8188FU USB wireless chipset, and 16 MB NOR flash.

README.md

Other (3) +112 / -0
ssc377_lite_tp-link-tapo-c120_defconfigDefine the SSC377 Lite Tapo C120 build +68/-0

Define the SSC377 Lite Tapo C120 build

• Adds a 16 MB Infinity6C/SSC377 Lite Buildroot configuration using the stock kernel configuration. It enables the RTL8188FU driver, OpenIPC WPA supplicant for SAE support, Majestic, Opus, and required firmware utilities.

devices/ssc377_lite_tp-link-tapo-c120/br-ext-chip-sigmastar/configs/ssc377_lite_tp-link-tapo-c120_defconfig

customizer.shApply Tapo C120 first-boot settings +27/-0

Apply Tapo C120 first-boot settings

• Configures the device-specific upgrade URL, SC430AI sensor, RTL8188FU wireless identifier, Opus audio, and Majestic night-mode GPIOs. The IR-cut is configured as a single inverted output on GPIO 81 with backlight on GPIO 14.

devices/ssc377_lite_tp-link-tapo-c120/general/overlay/usr/share/openipc/customizer.sh

ssc377_lite.listExclude unrelated Infinity6C sensor assets +17/-0

Exclude unrelated Infinity6C sensor assets

• Removes unused sensor calibration files and kernel modules from the device image, retaining only the assets required by the Tapo C120 profile.

devices/ssc377_lite_tp-link-tapo-c120/general/scripts/excludes/ssc377_lite.list

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 19, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Wi-Fi failures are reported as success 🐞 Bug ☼ Reliability
Description
The wireless USB script runs modprobe 8188fu and then unconditionally returns zero instead of
preserving the command's status. When the module is missing or cannot load, wireless initialization
receives a successful result even though no interface was created.
Code

devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/wireless/usb[R12-13]

+	modprobe 8188fu
+	exit 0
Evidence
The selected profile powers the device, invokes modprobe, and then always exits successfully; in
contrast, another repository USB profile uses exec modprobe so load failures propagate to its
caller. The customizer selects this exact C120 profile for normal wireless startup.

devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/wireless/usb[8-16]
devices/ssc377_lite_tp-link-tapo-c120/general/overlay/usr/share/openipc/customizer.sh[20-23]
devices/ssc337de_lite_zte-k543/general/overlay/etc/wireless/usb[8-15]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The C120 wireless profile returns success even when `modprobe 8188fu` fails, masking a failed Wi-Fi initialization.
## Fix Focus Areas
- devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/wireless/usb[12-13]
## Recommended Fix
Replace the `modprobe` followed by unconditional `exit 0` with `exec modprobe 8188fu`, or explicitly capture and return the command's exit status.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Stopping leaves IR illuminators on 🐞 Bug ☼ Reliability
Description
The stop branch of S96irled kills the polling process without driving GPIOs 12 and 13 low or
releasing them. If the service is stopped while night mode is active, both illuminator banks retain
their last asserted output after the service has supposedly stopped.
Code

devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[R24-25]

+	stop)
+		[ -f $PID ] && kill "$(cat $PID)" 2>/dev/null; rm -f $PID
Evidence
Startup exports both LED GPIOs and configures them as outputs, while shutdown only kills the
recorded process and removes its PID file. Nothing in the shutdown path changes the output values
that the loop previously wrote.

devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[7-18]
devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[24-25]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Stopping the IR LED service leaves GPIOs 12 and 13 at their previous values, which can keep both illuminator banks enabled.
## Fix Focus Areas
- devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[7-10]
- devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[24-25]
## Recommended Fix
After terminating the worker, explicitly drive GPIOs 12 and 13 low and unexport the lines owned by this service so stopping establishes a safe off state.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Repeated starts leave hidden workers 🐞 Bug ☼ Reliability
Description
The start branch of S96irled always launches another infinite polling subshell and overwrites
the single PID file without checking for an existing worker. After multiple starts, stop
terminates only the newest PID while older loops continue polling and controlling both LED GPIOs.
Code

devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[R21-22]

+		) &
+		echo $! > $PID
Evidence
The script backgrounds an unconditional infinite loop and stores only its newest PID, whereas the
stop branch reads and kills only that one PID. An existing repository polling service uses
start-stop-daemon with a PID file to manage a single worker lifecycle.

devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[11-25]
devices/hi3518ev300_lite_xiaomi-mjsxj02hl/general/overlay/etc/init.d/S96autonight[5-20]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Every `start` invocation creates another infinite IR LED polling worker, but only the newest process remains addressable through the PID file.
## Fix Focus Areas
- devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[11-22]
- devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[24-25]
## Recommended Fix
Before launching, validate the PID file with `kill -0` and treat an existing live worker as already started; remove stale PID files before creating a new worker. Alternatively, move the loop into an executable managed by `start-stop-daemon` with a PID file.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +12 to +13
modprobe 8188fu
exit 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Wi-fi failures are reported as success 🐞 Bug ☼ Reliability

The wireless USB script runs modprobe 8188fu and then unconditionally returns zero instead of
preserving the command's status. When the module is missing or cannot load, wireless initialization
receives a successful result even though no interface was created.
Agent Prompt
## Issue description
The C120 wireless profile returns success even when `modprobe 8188fu` fails, masking a failed Wi-Fi initialization.

## Fix Focus Areas
- devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/wireless/usb[12-13]

## Recommended Fix
Replace the `modprobe` followed by unconditional `exit 0` with `exec modprobe 8188fu`, or explicitly capture and return the command's exit status.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +24 to +25
stop)
[ -f $PID ] && kill "$(cat $PID)" 2>/dev/null; rm -f $PID

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Stopping leaves ir illuminators on 🐞 Bug ☼ Reliability

The stop branch of S96irled kills the polling process without driving GPIOs 12 and 13 low or
releasing them. If the service is stopped while night mode is active, both illuminator banks retain
their last asserted output after the service has supposedly stopped.
Agent Prompt
## Issue description
Stopping the IR LED service leaves GPIOs 12 and 13 at their previous values, which can keep both illuminator banks enabled.

## Fix Focus Areas
- devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[7-10]
- devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[24-25]

## Recommended Fix
After terminating the worker, explicitly drive GPIOs 12 and 13 low and unexport the lines owned by this service so stopping establishes a safe off state.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +21 to +22
) &
echo $! > $PID

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. Repeated starts leave hidden workers 🐞 Bug ☼ Reliability

The start branch of S96irled always launches another infinite polling subshell and overwrites
the single PID file without checking for an existing worker. After multiple starts, stop
terminates only the newest PID while older loops continue polling and controlling both LED GPIOs.
Agent Prompt
## Issue description
Every `start` invocation creates another infinite IR LED polling worker, but only the newest process remains addressable through the PID file.

## Fix Focus Areas
- devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[11-22]
- devices/ssc377_lite_tp-link-tapo-c120/general/overlay/etc/init.d/S96irled[24-25]

## Recommended Fix
Before launching, validate the PID file with `kill -0` and treat an existing live worker as already started; remove stale PID files before creating a new worker. Alternatively, move the loop into an executable managed by `start-stop-daemon` with a PID file.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@openipc-ai
openipc-ai merged commit 5e1bb92 into OpenIPC:master Sep 19, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants