Skip to content

Conversation

@lexfrei
Copy link

@lexfrei lexfrei commented Jan 25, 2026

Summary

Fix BLE connections hanging indefinitely on macOS when not using the --debug flag.

Problem

On macOS, BLE connections would hang during scanning or connecting unless the --debug flag was specified. This made the CLI unusable for normal BLE operations without verbose output.

Root Cause

Two issues were identified:

  1. Event loop race condition: The asyncio event loop thread was started, but operations could be submitted before the loop was actually running, causing deadlocks.

  2. CoreBluetooth callback delivery: On macOS, CoreBluetooth requires the main thread to perform occasional I/O for callbacks to be delivered. Without --debug, no I/O occurred, so callbacks were never processed.

The --debug flag masked both issues by introducing timing delays and I/O operations through logging.

Solution

  1. Added threading.Event synchronization to ensure the event loop is running before any async operations are submitted.

  2. Added a sys.stdout.flush() call before waiting for async results, which triggers the necessary I/O for CoreBluetooth callback delivery.

Testing

Tested on macOS 26.2 (Tahoe):

  • meshtastic --ble-scan completes successfully
  • meshtastic --ble <device> --nodes connects and retrieves node information
  • meshtastic --ble <device> --info works as expected

This fixes two issues that caused BLE connections to hang on macOS
when not using the --debug flag:

1. Race condition in BLEClient event loop initialization
   - The event loop thread was started but asyncio operations were
     submitted before the loop was actually running
   - Added threading.Event synchronization to ensure the event loop
     is running before any operations are submitted
   - The ready signal is sent from within the loop via call_soon()
     to guarantee the loop is truly active

2. CoreBluetooth callback delivery on macOS
   - On macOS, CoreBluetooth requires occasional I/O operations for
     callbacks to be properly delivered to the main thread
   - Without --debug, no I/O was happening, causing callbacks to
     never be processed and operations to hang indefinitely
   - Added sys.stdout.flush() call before waiting for async results
     to trigger the necessary I/O

The --debug flag masked these issues because:
- Debug logging introduces timing delays that let the event loop start
- Logger I/O triggers the necessary callback delivery mechanism

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
@CLAassistant
Copy link

CLAassistant commented Jan 25, 2026

CLA assistant check
All committers have signed the CLA.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@NetBUG
Copy link

NetBUG commented Jan 25, 2026

Oh, are there any people who really aren't using Meshtastic without debugging?

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.

3 participants