Moved bt-tether to core functionality of Pwnagotchi.
Moved auto-tune to core functionality of Pwnagotchi.
They are no longer plugins, except for bt-tether which can still be disabled if you don't want it.
Signed-off-by: Jeroen Oudshoorn <oudshoorn.jeroen@gmail.com>
Updated defaults.toml to reflect strategy extraction:
Added [main] configuration:
- extra_channels = 15 (number of random channels to explore per epoch)
- restrict_channels = commented example (optional: limit to specific channels)
Removed:
- [main.plugins.auto-tune] section (now moved to core pwnagotchi/strategy)
The channel selection strategy is now configured via [main] section instead of
as a plugin, making it a core infrastructure component with clear, simple
configuration options.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Connected pwnagotchi/strategy module to agent.py so channel selection is always active:
Changes:
1. Import Strategy in agent.py
2. Initialize strategy in Agent.__init__()
3. Wire strategy event handlers to key agent methods:
- on_wifi_update(): called when WiFi list refreshed
- select_next_channels(): called to set channels for next epoch
- on_association(): track assoc interactions per channel
- on_deauthentication(): track deauth interactions per channel
- on_handshake(): track handshake captures per channel
Integration points:
- set_access_points(): updates strategy and selects next channels
- associate(): reports association to strategy
- deauth(): reports deauth to strategy
- _on_event_new_handshake(): reports handshake to strategy
The strategy now:
- Receives every relevant agent event
- Maintains per-channel statistics
- Selects next channels to scan based on active APs + random exploration
- Updates config['personality']['channels'] for next epoch
- Guides agent behavior through channel selection
This makes channel selection strategy a core, always-active component instead of
an optional plugin, ensuring intelligent adaptation to environment changes.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
The auto-tune plugin has been disabled (.disabled) since its core functionality
(channel selection strategy, AP tracking, statistics) is now in pwnagotchi/strategy.
Why:
- Channel selection strategy is essential, not optional
- Should not be disableable via plugin system
- Cleaner to have it as core infrastructure
- Reduces plugin complexity
Users who want advanced tuning/presets can recreate the web UI as a separate plugin
that reads from the new Strategy facade, but that's now optional, not essential.
Original: auto-tune.py.backup for reference
Disabled: auto-tune.py.disabled (won't be loaded by plugin system)
New core: pwnagotchi/strategy/ module (always active)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Extracted intelligent channel selection strategy from auto-tune plugin into core
as pwnagotchi/strategy/ module with 3 focused components:
1. channels.py: ChannelStrategy
- Selects channels for each epoch (active + extra unscanned)
- Builds on active_channels and explores new areas
- Handles channel list repopulation from config/agent
2. statistics.py: ChannelStatistics
- Tracks per-channel statistics (AP counts, interactions)
- Maintains known AP database
- Manages active vs unscanned channel lists
- Records interactions (assoc, deauth, handshakes)
3. __init__.py: Strategy facade
- Unified entry point for agent integration
- Event handler dispatch
- Public API for stats access
Key changes:
- Strategy is now ALWAYS active (not optional like plugin)
- Personality/config loaded from config.toml, not plugin options
- No web UI or preset management (core only)
- Clean event integration with agent
- Removed ~600 lines of UI/preset code
Auto-tune.py is now DISABLED. Original backed up as auto-tune.py.backup.
The strategy replaces the removed RL-based AI with intelligent heuristics:
- Always scan active channels (high capture probability)
- Explore unscanned channels (discovery)
- Track statistics to guide behavior
- Adapt to environment changes
Configuration in config.toml:
[main]
extra_channels = 15
restrict_channels = [1, 6, 11] # optional
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Updated bt-tether-thin.py to include the complete original HTML interface with:
- Full styling (dark theme, responsive design)
- Connection status monitoring with real-time updates
- Trusted devices summary
- Device discovery and scanning UI
- Internet connectivity testing
- Live log viewer with auto-scroll
- Interactive control buttons (Connect/Disconnect/Pair/Scan)
The simplified template has been replaced with the full feature-rich version,
maintaining 100% visual and functional parity with the original plugin while
delegating core Bluetooth logic to the modular pwnagotchi.bluetooth service.
This ensures a smooth migration path: users can simply rename bt-tether-thin.py
to bt-tether.py once testing is complete, with no loss of functionality.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Split the monolithic 5000+ line bt-tether plugin into:
1. Core module (pwnagotchi/bluetooth/) with 7 focused submodules:
- device.py: Device state and validation
- connection.py: Core Bluetooth operations (pairing, connect, disconnect)
- network.py: PAN interface and network management
- agent.py: Pairing agent lifecycle
- monitor.py: Connection monitoring and auto-reconnect
- ui.py: Display rendering and status caching
- __init__.py: Service facade with public API
2. Thin plugin wrapper (bt-tether-thin.py):
- Delegates to BluetoothService
- Reduced from 5000+ to ~750 lines
- Maintains plugin interface compatibility
- Handles webhook routing and event dispatch
Benefits:
- Core Bluetooth logic is now testable and reusable
- Clear separation of concerns (each module has single responsibility)
- Non-blocking UI updates via UICache pattern
- Proper error handling and timeout management
- Threading/locking concerns isolated by module
- Formal event system for plugin-core communication
Original bt-tether.py backed up as bt-tether.py.backup for reference.
Fixed security issue: replaced os.system() command injection in handler.py with subprocess.run()
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
skip_until_reload is initialized as a set, but on_internet_available called .append() on it, which sets don't support. This raised an AttributeError whenever an upload failed and the handshake needed to be skipped until reload, masking the original upload error in the logs
Signed-off-by: Bready2Crumble <83258877+BraedenP232@users.noreply.github.com>