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>
Adds a new default plugin that provides a web UI for browsing,
downloading, and analyzing captured WiFi handshakes and network data.
Features:
- Browse and search captured .pcap handshake files
- Download individual files or all as a zip archive
- Interactive network map with D3.js force-directed graph
- Zoom, pan, drag nodes to rearrange
- AP nodes colored by encryption type, sized by client count
- Click AP to highlight its connected clients
- Auto-fits to viewport after layout settles
- Sortable table view with expandable AP rows showing clients
- Handshake column with download links for captured .pcap files
- Historical AP import from existing pcap filenames
- Live data from bettercap session merged with persistent history
- Stats bar: AP count, unique clients, total data volume
- Persistent JSON storage surviving reboots
Add _IFACE_RE regex and _validate_iface() classmethod that validates
Linux network interface names (max 15 chars, alphanumeric plus dash
and underscore). Provides a safety net against malformed names if
interface configuration is ever externalized.
on_epoch and on_bcap_sys_log run from different threads (main loop vs
bettercap event handler). Both read and write self.LASTTRY without
synchronization, creating a race where two recovery actions fire
simultaneously. Similarly, isReloadingMon can be checked and set by
concurrent threads leading to overlapping restarts.
Add a threading.Lock to serialize cooldown checks and state mutations:
- on_bcap_sys_log: lock around LASTTRY cooldown check
- on_epoch: lock around LASTTRY cooldown check
- _tryTurningItOffAndOnAgain: lock around duplicate-attempt guard,
early return instead of else-block to flatten indentation
Signed-off-by: PwnPacker <4704376+CoderFX@users.noreply.github.com>
Patterns 5 (concurrent map iteration) and 6 (panic: runtime error) had
identical handlers — both log "Bettercap has crashed!", restart bettercap,
and restart pwnagotchi. Merge into a single elif with an or condition.
Closes#539
Signed-off-by: PwnPacker <4704376+CoderFX@users.noreply.github.com>