Skip to content

feat: esim download + UI#37742

Draft
greatgitsby wants to merge 143 commits intocommaai:masterfrom
greatgitsby:esim
Draft

feat: esim download + UI#37742
greatgitsby wants to merge 143 commits intocommaai:masterfrom
greatgitsby:esim

Conversation

@greatgitsby
Copy link
Copy Markdown
Contributor

No description provided.

Add enable, delete, switch, and download profile operations to the LPA.
Process eUICC notifications after profile changes and handle modem
reboot for profile switches. Disable AT command echo on serial open
and handle modem already dropped during reboot (e.g. after catBusy).
Simple UI in network settings to list, switch, delete, and rename eSIM
profiles. Modeled after the WiFi UI with NavScroller + BigButton pattern.
MockLPA provides fake profiles for desktop development.
Track switching_iccid in ESimManager and use scroller.move_item() to
animate the profile being switched to the front, matching WiFi behavior.
State flags were cleared in the background thread before the callback
ran on the UI thread, causing _update_state to briefly see no switching
profile and snap the old active profile back to front.
Show driver camera feed when user taps "add profile", detect LPA
activation codes from QR codes using cv2, check internet connectivity
before downloading, and show animated installing dialog during download.
cv2 is only available in dev dependencies, not on device.
close() sets client=None but render can still be called during dismiss
animation, causing AttributeError.
In Python 3.12, exception variables are deleted after the except block,
so the lambda can't reference 'e' later. Capture str(e) first.
refresh_profiles was writing self._profiles directly from a worker
thread, which could race with _finish_switch on the UI thread and
overwrite fresh profile data with stale data. Use _finish_operation
via the callback queue like all other operations.
4x too aggressive, QR not detected. Back to 2x.
greatgitsby and others added 14 commits April 2, 2026 22:00
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
lte.sh kills the modem which invalidates the serial fd. Reconnect
after the reset and catch OSError from reset_input_buffer on stale fd.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The CFUN 0/1 cycle before EnableProfile leaves the SIM in CME ERROR 13
state. Just close our logical channel instead. The lte.sh recovery in
open_isdr handles stuck modems if needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After EnableProfile the eUICC resets, causing CME ERROR 13 on immediate
ISD-R open. Do the modem reset (CFUN cycle + MM restart) synchronously
before listing profiles so the SIM has time to come back up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the singleton TiciLPA with per-instance filesystem locking via
fcntl.flock. Each public method acquires the lock, opens a fresh ISD-R
channel, and closes it on exit — serializing access across all processes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…s.error

- Retry switch_profile/delete_profile up to 4 times on catBusy (0x05)
  with fresh channel each attempt
- Replace CFUN-based modem reset with lte.sh start + serial reconnect
  (CFUN returns CME ERROR 302 on this serial port)
- Catch termios.error in open_isdr retry loop and serial buffer reset
- Add termios import

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…_acquire_channel

- Add inhibit parameter to _acquire_channel context manager that starts
  sudo mmcli --inhibit-device in background and terminates on exit
- switch_profile uses inhibit=True to clear STK proactive sessions,
  eliminating catBusy errors without retry loops
- Replace CFUN-based modem reset with lte.sh start for post-switch
  modem re-read (CFUN returns CME ERROR 302 on secondary AT port)
- Remove delete_profile catBusy retry loop (inhibit approach preferred)
- Catch termios.error in open_isdr for serial recovery after modem reset

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…bit for delete

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove MockLPA (unused)
- Merge _finish_switch/_finish_operation/_finish_refresh into single _finish
- Extract _run_operation for common worker+callback pattern
- Remove unused _enqueue_callbacks
- Remove docstrings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use raw AT+CFUN=0/1 writes instead of lte.sh start for modem reset
  after profile switch (4s -> <1s)
- Reduce MM inhibit wait from 1s to 0.5s (measured 240ms to take effect)
- Remove subprocess/lte.sh dependency from switch path

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Reduce post-CFUN sleep from 3s to 2s (modem reliably ready)
- Add _finish_refresh that skips UI update when busy, preventing
  stale profile list from flashing during switch operations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
greatgitsby and others added 4 commits April 5, 2026 09:06
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… QR scanner

zxing-cpp is fast enough to decode synchronously on the full frame.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 5, 2026

UI Preview

mici: ⚠️ Videos differ! View Diff Report
big: ⚠️ Videos differ! View Diff Report

greatgitsby and others added 10 commits April 5, 2026 09:27
The silent DBUS fallback caused two TiciLPA instances to use different
transports simultaneously, fighting over the ISD-R channel and causing
slow profile loading on devices where hardwared failed to grab serial.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…leep

Tizi's modem takes longer to reinitialize after CFUN, causing open_isdr
to retry with 2s sleeps and adding 8-24s to switch operations. Now polls
with 0.5s intervals until the ISD-R channel can be opened.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tizi has SIM presence detection wired up, so the eUICC can trigger a
modem refresh directly via SIM toolkit. This avoids the slow CFUN cycle
and post-reset recovery. Mici lacks SIM presence, so it keeps the
manual CFUN cycle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Without this delay, the immediate list_profiles after switch hits an
open_isdr failure because the modem is briefly unavailable during the
SIM toolkit refresh, causing the UI to show stale profile state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Transport is chosen once at init time: try serial first, fall back to
DBUS only if serial is unavailable. The choice is logged and sticky —
no silent switching between transports mid-session.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When multiple processes create TiciLPA simultaneously, each AtClient
sends ATE0 to the serial port during init without holding any lock.
This can inject into the serial stream while another process is
mid-command, causing timeouts. Hold the filesystem lock during
_disable_echo to serialize init across processes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removes ATE0 echo disable — it caused cross-process serial contention
during concurrent init and isn't needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Don't open the serial port in AtClient.__init__ — defer it to the
first query() call, which is always inside _acquire_channel where
the filesystem lock is held. Fixes cross-process serial contention
when multiple TiciLPA instances init concurrently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant