Files
pi-pm3/docs/CONSOLE_FILE_TRANSFER.md
michael 4f35df1781 Initial commit - Phase 3/4
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 13:46:22 -08:00

3.2 KiB

Reliable File Transfer via Serial Console

Problem

Transferring files to the Raspberry Pi over a serial console (/dev/ttyUSB1) is unreliable due to:

  • Screen stuff command has buffer/escaping limits
  • Base64 chunks get corrupted or truncated
  • Quotes and special characters are mangled
  • No error detection or recovery

Solutions (Ranked by Reliability)

Pros: Designed for serial transfer, error correction, resume support Cons: Requires lrzsz package on both ends

# On local machine:
apt install lrzsz

# On Pi (check if available):
which sz rz || sudo apt install lrzsz

# Transfer file:
# From local to Pi: run `rz` on Pi, then `sz file.py` locally
# Use screen: Ctrl-A then `:exec !! sz filename`

2. Connect Pi to WiFi First

Approach: Use the console to connect Pi to a shared WiFi network, then use SCP

# On Pi console:
sudo nmcli dev wifi connect "SSID" password "PASSWORD"

# Then from local:
scp file.py dt@<pi-ip>:/path/

3. USB Transfer

  • Create files on a USB drive
  • Plug into Pi
  • Mount and copy

4. HTTP Server Approach

# On local machine (in the directory with files):
python3 -m http.server 8080

# On Pi (after connecting to same network):
wget http://<local-ip>:8080/wifi_manager.py -O /tmp/wifi_manager.py

5. Chunked Transfer with Verification

A more robust chunked approach:

# transfer.py - Run on local machine
import serial
import base64
import hashlib
import time

def send_file(serial_port, local_file, remote_path):
    with open(local_file, 'rb') as f:
        content = f.read()

    b64 = base64.b64encode(content).decode()
    checksum = hashlib.md5(content).hexdigest()

    # Send in small chunks with line-by-line verification
    chunk_size = 200
    chunks = [b64[i:i+chunk_size] for i in range(0, len(b64), chunk_size)]

    # Clear target file
    ser = serial.Serial(serial_port, 115200, timeout=2)
    ser.write(b'> /tmp/recv.b64\n')
    time.sleep(0.5)

    for i, chunk in enumerate(chunks):
        cmd = f"echo -n '{chunk}' >> /tmp/recv.b64\n"
        ser.write(cmd.encode())
        time.sleep(0.3)
        if i % 20 == 0:
            print(f"Sent {i}/{len(chunks)}")

    # Decode and verify
    ser.write(f'base64 -d /tmp/recv.b64 > {remote_path}\n'.encode())
    time.sleep(0.5)
    ser.write(f'md5sum {remote_path}\n'.encode())

    print(f"Expected checksum: {checksum}")
    ser.close()

Immediate Recommendation

For the current situation, the fastest fix is:

  1. Option A: Connect Pi to WiFi manually

    # On Pi console:
    sudo nmcli dev wifi connect "NETGEAR13" password "YOUR_PASSWORD"
    # Then use SCP from local
    
  2. Option B: Install lrzsz and use ZMODEM

    # If lrzsz is installed on Pi:
    # On Pi: rz
    # On local (in screen): Ctrl-A : exec !! sz /path/to/wifi_manager.py
    

Files That Need Transfer

Currently corrupted on Pi and need replacement:

  • /opt/dangerous-pi/app/backend/managers/wifi_manager.py

The local version at /home/work/dangerous-pi/app/backend/managers/wifi_manager.py has all the correct fixes for:

  • Capability-based scanning (no sudo)
  • Frequency parsing (handles float format)
  • BSS line parsing (handles MAC format)
  • Interface detection before scan