espilon-source/tools/flasher/README.md
2026-01-19 11:37:27 +01:00

12 KiB

Espilon Multi-Device Flasher

Automated tool for building and flashing multiple ESP32 devices with custom configurations for the Espilon project.

Features

  • Build firmware with custom configurations per device
  • Support for WiFi and GPRS modes
  • Configurable modules (Network, Recon, FakeAP)
  • Multi-device batch processing
  • Individual device manual configuration
  • Automatic hostname generation
  • Build-only and flash-only modes

Prerequisites

  • Python 3.8+
  • ESP-IDF v5.3.2 (properly configured with export.sh)
  • esptool.py (usually included with ESP-IDF)
  • ESP32 development boards connected via USB

Installation

No installation required. The script is standalone.

cd tools/flasher
chmod +x flash.py

Configuration File

Structure

The devices.json file contains:

  • project: Path to the espilon_bot directory
  • devices: Array of device configurations

Example: devices.json

{
  "project": "/home/user/epsilon/espilon_bot",
  "devices": [
    ## WiFi AGENT ##
    {
      "device_id": "ce4f626b",
      "port": "/dev/ttyUSB0",
      "srv_ip": "192.168.1.13",
      "srv_port": 2626,
      "network_mode": "wifi",
      "wifi_ssid": "MyWiFi",
      "wifi_pass": "MyPassword123",
      "hostname": "pixel-8-pro",
      "module_network": true,
      "module_recon": false,
      "module_fakeap": false,
      "recon_camera": false,
      "recon_ble_trilat": false,
      "crypto_key": "testde32chars00000000000000000000",
      "crypto_nonce": "noncenonceno"
    },
    ## GPRS AGENT ##
    {
      "device_id": "a91dd021",
      "port": "/dev/ttyUSB1",
      "srv_ip": "203.0.113.10",
      "srv_port": 2626,
      "network_mode": "gprs",
      "gprs_apn": "sl2sfr",
      "hostname": "galaxy-s24-ultra",
      "module_network": true,
      "module_recon": false,
      "module_fakeap": false
    }
  ]
}

Device Configuration Fields

Field Required Default Description
device_id Yes - Unique device identifier (8 hex chars)
port Yes - Serial port (e.g., /dev/ttyUSB0, COM3)
srv_ip Yes - C2 server IP address
srv_port No 2626 C2 server port
network_mode No "wifi" Network mode: "wifi" or "gprs"
wifi_ssid WiFi only - WiFi network SSID
wifi_pass WiFi only - WiFi network password
gprs_apn GPRS only "sl2sfr" GPRS APN
hostname No Random Device hostname for network identification
module_network No true Enable network commands module
module_recon No false Enable reconnaissance module
module_fakeap No false Enable fake AP module
recon_camera No false Enable camera reconnaissance (ESP32-CAM)
recon_ble_trilat No false Enable BLE trilateration
crypto_key No Test key ChaCha20 encryption key (32 chars)
crypto_nonce No Test nonce ChaCha20 nonce (12 chars)

Usage

1. Flash All Devices from Config

python3 flash.py --config devices.json

This will:

  1. Read device configurations from devices.json
  2. Build firmware for each device
  3. Flash each device sequentially
  4. Display summary report

2. Manual Single Device (WiFi)

python3 flash.py --manual \
  --project /home/user/epsilon/espilon_bot \
  --device-id abc12345 \
  --port /dev/ttyUSB0 \
  --srv-ip 192.168.1.100 \
  --wifi-ssid MyWiFi \
  --wifi-pass MyPassword123

3. Manual Single Device (GPRS)

python3 flash.py --manual \
  --project /home/user/epsilon/espilon_bot \
  --device-id def67890 \
  --port /dev/ttyUSB1 \
  --srv-ip 203.0.113.10 \
  --network-mode gprs \
  --gprs-apn sl2sfr

4. Build Only (No Flash)

Useful for generating firmware files without flashing:

python3 flash.py --config devices.json --build-only

Firmware files are saved to: espilon_bot/firmware/<device_id>.bin

5. Flash Only (Skip Build)

Flash pre-built firmware:

python3 flash.py --config devices.json --flash-only

Requires firmware files in espilon_bot/firmware/ directory.

6. Enable Modules

python3 flash.py --manual \
  --project /home/user/epsilon/espilon_bot \
  --device-id xyz98765 \
  --port /dev/ttyUSB0 \
  --srv-ip 192.168.1.100 \
  --wifi-ssid MyWiFi \
  --wifi-pass MyPassword123 \
  --enable-recon \
  --enable-fakeap \
  --enable-ble-trilat

7. Custom Encryption Keys

python3 flash.py --manual \
  --project /home/user/epsilon/espilon_bot \
  --device-id secure01 \
  --port /dev/ttyUSB0 \
  --srv-ip 192.168.1.100 \
  --wifi-ssid MyWiFi \
  --wifi-pass MyPassword123 \
  --crypto-key "your32charencryptionkeyhere!!" \
  --crypto-nonce "yournonce12b"

Advanced Features

Hostname Generation

If hostname is not specified, the script generates a realistic device name:

  • iPhone models (iPhone-15-pro-max, etc.)
  • Android devices (galaxy-s24-ultra, pixel-8-pro, etc.)
  • Windows PCs (DESKTOP-XXXXXXX)

This helps devices blend in on networks during authorized testing.

Configuration Backup

Before building, the script automatically backs up the existing sdkconfig.defaults to sdkconfig.defaults.bak.

Firmware Storage

Built firmware is saved in:

espilon_bot/firmware/<device_id>.bin

This allows:

  • Reuse without rebuilding (--flash-only)
  • Firmware version archival
  • Quick reflashing of multiple devices

Workflow Examples

Scenario 1: Initial Setup (3 devices)

  1. Edit devices.json:

    {
      "project": "/home/user/epsilon/espilon_bot",
      "devices": [
        {"device_id": "dev00001", "port": "/dev/ttyUSB0", ...},
        {"device_id": "dev00002", "port": "/dev/ttyUSB1", ...},
        {"device_id": "dev00003", "port": "/dev/ttyUSB2", ...}
      ]
    }
    
  2. Flash all:

    python3 flash.py --config devices.json
    
  3. Devices are ready for deployment

Scenario 2: Update Single Device

  1. Modify configuration in devices.json
  2. Flash only that device:
    # Remove other devices from JSON or use manual mode
    python3 flash.py --manual --device-id dev00002 --port /dev/ttyUSB1 ...
    

Scenario 3: Quick Reflash

# Build once
python3 flash.py --config devices.json --build-only

# Flash multiple times (testing, replacement devices)
python3 flash.py --config devices.json --flash-only

Scenario 4: WiFi + GPRS Mixed Fleet

{
  "project": "/home/user/epsilon/espilon_bot",
  "devices": [
    {
      "device_id": "wifi001",
      "network_mode": "wifi",
      "wifi_ssid": "HomeNetwork",
      "wifi_pass": "password123",
      ...
    },
    {
      "device_id": "gprs001",
      "network_mode": "gprs",
      "gprs_apn": "sl2sfr",
      ...
    }
  ]
}

Troubleshooting

Error: "Port not found"

❌ Flash failed: Serial port /dev/ttyUSB0 not found

Solution: Check device connection and port:

ls /dev/ttyUSB* /dev/ttyACM*

Add user to dialout group:

sudo usermod -a -G dialout $USER
# Log out and log back in

Error: "Build failed"

❌ Build failed for device_id

Solutions:

  1. Verify ESP-IDF is sourced:

    . $HOME/esp-idf/export.sh
    
  2. Check project path in devices.json

  3. Manually test build:

    cd espilon_bot
    idf.py build
    

Error: "Permission denied"

❌ Permission denied: /dev/ttyUSB0

Solution:

sudo chmod 666 /dev/ttyUSB0
# Or add user to dialout group (permanent)
sudo usermod -a -G dialout $USER

Error: "Binary not found"

❌ Binary not found: epsilon_bot.bin

Solution: Check build output for compilation errors. The binary name should match the project configuration.

WiFi Mode Missing Credentials

ValueError: WiFi mode requires wifi_ssid and wifi_pass

Solution: Ensure wifi_ssid and wifi_pass are set for devices with network_mode: "wifi".

Output Example

============================================================
# Device 1/3: ce4f626b
############################################################

============================================================
🔧 Building firmware for: ce4f626b (WIFI) on /dev/ttyUSB0
============================================================
✅ Generated sdkconfig.defaults for ce4f626b
🗑️  Removed old sdkconfig
⚙️  Running idf.py build...
✅ Firmware saved: espilon_bot/firmware/ce4f626b.bin

============================================================
🚀 Flashing: ce4f626b (WIFI) on /dev/ttyUSB0
============================================================
📁 Bootloader: espilon_bot/build/bootloader/bootloader.bin
📁 Partitions: espilon_bot/build/partition_table/partition-table.bin
📁 Application: espilon_bot/firmware/ce4f626b.bin
🔌 Port: /dev/ttyUSB0
✅ Successfully flashed ce4f626b

============================================================
📊 SUMMARY
============================================================
✅ Success: 3/3
❌ Failed:  0/3
============================================================

Security Considerations

Encryption Keys

WARNING: The default crypto keys are for TESTING ONLY:

  • crypto_key: "testde32chars00000000000000000000"
  • crypto_nonce: "noncenonceno"

For production use:

  1. Generate secure keys:

    # 32-byte key
    openssl rand -hex 32
    
    # 12-byte nonce
    openssl rand -hex 12
    
  2. Update in devices.json or use --crypto-key and --crypto-nonce

  3. Never commit real keys to version control

Device IDs

Generate random device IDs:

openssl rand -hex 4  # Generates 8-character hex ID

Files Generated

During operation, the script creates:

espilon_bot/
├── sdkconfig                   # Generated during build (auto-deleted)
├── sdkconfig.defaults          # Overwritten per device
├── sdkconfig.defaults.bak      # Backup of previous config
├── build/                      # ESP-IDF build artifacts
│   ├── bootloader/
│   ├── partition_table/
│   └── epsilon_bot.bin
└── firmware/                   # Saved firmware binaries
    ├── ce4f626b.bin
    ├── a91dd021.bin
    └── f34592e0.bin

Tips

  1. Batch Processing: Connect multiple ESP32s to different USB ports, configure all in devices.json, and flash them all at once.

  2. Parallel Builds: For faster processing with many devices, consider building in parallel (future enhancement).

  3. Configuration Templates: Keep multiple devices.json files for different deployment scenarios:

    • devices-wifi.json
    • devices-gprs.json
    • devices-production.json
    • devices-testing.json
  4. Firmware Archive: Save firmware binaries with version tags:

    mkdir -p firmware-archive/v1.0
    cp espilon_bot/firmware/*.bin firmware-archive/v1.0/
    
  5. Serial Port Mapping: Create udev rules for consistent port naming (Linux):

    # /etc/udev/rules.d/99-esp32.rules
    SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="esp32-dev1"
    SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="esp32-dev2"
    

Help

python3 flash.py --help

Displays full usage information with examples.

License

Part of the Espilon project. See LICENSE for details.