No Description

root 07dc293a3a Fix SSH key loading to read .pub file directly 1 month ago
cmd 07dc293a3a Fix SSH key loading to read .pub file directly 1 month ago
dashboard cb9ae43fae Add settings dashboard refactoring and SSH tunnel documentation 1 month ago
internal 186ee32fd6 Initial commit: MyBeacon daemon with Network Manager refactoring 1 month ago
.gitignore 186ee32fd6 Initial commit: MyBeacon daemon with Network Manager refactoring 1 month ago
Makefile 186ee32fd6 Initial commit: MyBeacon daemon with Network Manager refactoring 1 month ago
README.md cb9ae43fae Add settings dashboard refactoring and SSH tunnel documentation 1 month ago
REVERSE_SHELL.md cb9ae43fae Add settings dashboard refactoring and SSH tunnel documentation 1 month ago
go.mod 186ee32fd6 Initial commit: MyBeacon daemon with Network Manager refactoring 1 month ago
go.sum 186ee32fd6 Initial commit: MyBeacon daemon with Network Manager refactoring 1 month ago
logo.svg 3a5036bd04 Add dashboard remote control, NTP management, and mobile improvements 1 month ago

README.md

MyBeacon Native

Нативная реализация BLE/WiFi сканера для Luckfox Pico Ultra W на Alpine Linux.

Hardware

  • SoC: RK1106 (ARM Cortex-A7 @ 1.2 GHz)
  • RAM: 256 MB
  • Storage: 8 GB eMMC
  • WiFi/BT: AIC8800DC (combo chip)
    • 2.4 GHz WiFi (802.11 b/g/n)
    • Bluetooth 5.0 + BLE
    • ВАЖНО: Один радиомодуль - BLE и WiFi в некоторых случаях конфликтуют!

AIC8800 Combo Chip Ограничения

Один физический радиомодуль для WiFi + BLE:

✓ РАБОТАЕТ:
  - BLE scan + WiFi client одновременно
  - BLE scan + WiFi monitor одновременно
  - BLE scan + WiFi AP одновременно  

✗ НЕ РАБОТАЕТ:  
  - WiFi client + monitor одновременно (data transfer blocked)

РЕШЕНИЕ В КОДЕ:
  - Меняем режимы WiFi ТОЛЬКО когда BLE остановлен
  - При подключении WiFi client - BLE временно останавливается
  - После WiFi подключения - BLE автоматически перезапускается
  - С WiFi monitor тоже самое. 

USB Ограничения (для модемов)

USB SWITCH (U10) между Type-C и USB-A:
  - SEL подтянут к VBUS через R70 (62K)

Type-C питание  → USB-A НЕ РАБОТАЕТ (data на Type-C)
POE питание     → USB-A РАБОТАЕТ
5V на гребёнку  → USB-A РАБОТАЕТ

ДЛЯ USB-МОДЕМА: требуется POE или внешний 5V!

Компоненты

  • ble-scanner — BLE сканирование через BlueZ D-Bus API
  • wifi-scanner — WiFi probe request capture через pcap/AF_PACKET
  • beacon-daemon — центральный демон:
    • Управление сканерами (запуск/остановка)
    • Управление сетью (eth0, wlan0 client, AP fallback, NTP)
    • Агрегация событий через ZMQ
    • Batching + gzip + HTTP POST на сервер
    • Spooler (при отсутствии сети)
    • HTTP API + WebSocket для dashboard (вкл/выкл с сервера)
    • SSH туннель (reverse)
    • Config polling (cloud mode)

Device Modes

┌──────────────┐    ┌──────────────┐
│  CLOUD MODE  │    │   LAN MODE   │
│  (default)   │    │              │
├──────────────┤    ├──────────────┤
│ • Config from│    │ • Config     │
│   server     │    │   local only │
│ • Polling ON │    │ • Polling OFF│
│   (30 sec)   │    │              │
└──────────────┘    └──────────────┘

Первая регистрация ВСЕГДА через интернет (для получения device_password)

Network Priority & AP Fallback

Priority 1: eth0 (carrier detect)
    │
    ├── Link UP → DHCP/Static → ONLINE
    │
    └── Link DOWN
            │
Priority 2: wlan0 client (if configured, НЕЗАВИСИМО от eth0!)
    │
    ├── WiFi.ClientEnabled = true → Connect
    │   └── Success → ONLINE (eth0 + wlan0 одновременно)
    │
    └── WiFi.ClientEnabled = false OR connection failed
            │
WiFi Scanner: если wlan0 free AND MonitorEnabled
    │       └── BLE останавливается (AIC8800 conflict)
    │
Fallback: wlan0 AP (120 сек без сети)
    │
    └── AP UP (SSID: mybeacon_XXXX, пароль: device_password)
        └── Продолжаем пробовать wlan0 client каждые 30 сек!

AP Settings:
  SSID: "mybeacon_<4 последних символа MAC>" (например: mybeacon_1bac)
  Password: device_password из /opt/mybeacon/etc/device.json (8 цифр с регистрации)
            fallback: "mybeacon" (если device_password пустой)
  IP: 192.168.4.1
  DHCP: 192.168.4.100-200 (dnsmasq)

BLE Types (3 типа)

  1. iBeacon (Apple 0x004C)

    • UUID + Major + Minor + TxPower
  2. my-beacon_acc (Nordic 0x0059)

    • Format: "acc" + X/Y/Z (accel) + battery + temp
  3. rt_mybeacon (Custom 0xFFFF)

    • Relay beacon: "rt" + orig_mac + orig_rssi + payload

Architecture

┌─────────────────────────────────────────────────────────────┐
│                 beacon-daemon (Go)                           │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ Network Manager                                       │   │
│  │ - eth0 (DHCP/Static)                                 │   │
│  │ - wlan0 client (WPA2-PSK)                            │   │
│  │ - wlan0 AP fallback (120s timeout)                   │   │
│  │ - NTP sync (auto-start on network up)               │   │
│  │ - WiFi/BLE scanner coordination (AIC8800 workaround) │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ Scanner Manager                                       │   │
│  │ - Starts/stops ble-scanner and wifi-scanner          │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │ ZMQ SUB     │  │ ZMQ SUB     │  │ HTTP API + WS       │  │
│  │ (BLE)       │  │ (WiFi)      │  │ (Dashboard)         │  │
│  │ :5555       │  │ :5556       │  │ :80                 │  │
│  └──────┬──────┘  └──────┬──────┘  └─────────────────────┘  │
│         │                │                                   │
│         └───────┬────────┘                                   │
│                 ▼                                            │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ Event Batcher → gzip → HTTP POST → Server            │   │
│  │                    ↓ (on failure)                     │   │
│  │                 Spooler (max 100MB)                   │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │ Config      │  │ Registration│  │ SSH Tunnel          │  │
│  │ Poller      │  │ Handler     │  │ Manager             │  │
│  │ (30s)       │  │             │  │ (reverse)           │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
        │                                    │
        │ spawns                             │ spawns
        ▼                                    ▼
┌─────────────────┐                ┌─────────────────┐
│ ble-scanner     │                │ wifi-scanner    │
│ (Go)            │                │ (Go)            │
│                 │                │                 │
│ BlueZ D-Bus API │                │ pcap + nl80211  │
│ ZMQ PUB :5555   │                │ ZMQ PUB :5556   │
└─────────────────┘                └─────────────────┘

ZMQ Протокол

Сканеры публикуют события в формате: topic JSON

Топики:

  • ble.ibeacon — iBeacon
  • ble.acc — my-beacon accelerometer
  • ble.relay — relay beacon
  • wifi.probe — WiFi probe request

Пример:

ble.ibeacon {"type":"ble.ibeacon","mac":"AA:BB:CC:DD:EE:FF","rssi":-65,"ts_ms":1703001234567,...}

HTTP API

GET  /api/status          - статус (сеть, режим, counters, uptime)
GET  /api/metrics         - метрики системы (CPU, mem, temp)
GET  /api/ble/recent      - последние BLE события (15 sec TTL)
GET  /api/wifi/recent     - последние WiFi события
GET  /api/config          - конфиг (без секретов)
POST /api/settings        - применить настройки (требует пароль)
POST /api/unlock          - проверить device_password
GET  /api/logs            - daemon logs (last 100 lines)
WS   /api/ws              - live updates (BLE/WiFi events)

Static: /                 - Vue.js dashboard

Dashboard

┌─────────────────────────────────────────────────────────────┐
│  🟢 MyBeacon                    Device: 38:54:39:4b:1b:ac   │
├─────────────────────────────────────────────────────────────┤
│  [Status] [Daemon Log] [Settings]                           │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  Status Tab:                                                 │
│  - System info (uptime, CPU, memory, temp)                  │
│  - Server connection status                                 │
│  - NTP server                                               │
│  - Ethernet (IP, gateway, DNS, RX/TX)                       │
│  - Wireless (IP, SSID, gateway, channel, RSSI, RX/TX)       │
│  - Live BLE devices (last 15s with TTL countdown)           │
│                                                              │
│  Settings Tab (device_password protected):                  │
│  - Mode (Cloud/LAN)                                         │
│  - eth0 config (DHCP/Static IP/Gateway/DNS)                 │
│  - WiFi client (Enable/SSID/PSK)                            │
│  - WiFi monitor mode (Enable/Disable)                       │
│  - NTP servers                                              │
│  - API endpoints (для LAN mode)                             │
│  - SSH Tunnel config                                        │
│                                                              │
│  Daemon Log Tab:                                            │
│  - Real-time logs через WebSocket                           │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Доступ: http://192.168.4.1 (AP mode) или http://<device-ip>

Recovery Procedure (AP Fallback)

  1. Выдернуть Ethernet кабель
  2. Отключить WiFi на стороне сервера (если device подключен как client)
  3. Подождать 120 секунд
  4. Устройство автоматически поднимает AP: mybeacon_XXXX (где XXXX - последние 4 символа MAC)
  5. Пароль AP: device_password из /opt/mybeacon/etc/device.json
  6. Подключиться к AP с телефона/ноутбука
  7. Зайти на http://192.168.4.1
  8. Ввести device_password в Settings
  9. Исправить настройки (WiFi SSID/PSK или eth0)
  10. Воткнуть кабель обратно ИЛИ включить WiFi на сервере

Пароль забыт? → Посмотреть в личном кабинете на сервере или в /opt/mybeacon/etc/device.json (требуется SSH доступ)

File Layout

/opt/mybeacon/
├── bin/
│   ├── ble-scanner         # BLE сканер
│   ├── wifi-scanner        # WiFi сканер
│   ├── beacon-daemon       # Главный демон
│   ├── wifi-connect.sh     # WiFi client подключение
│   ├── ap-start.sh         # Запуск AP fallback
│   └── ap-stop.sh          # Остановка AP fallback
├── etc/
│   ├── config.json         # Конфигурация (user-editable)
│   ├── device.json         # Device state (device_id, device_token, device_password)
│   └── tunnel_key          # SSH private key для туннеля
└── www/                    # Vue.js dashboard (dist)
    ├── index.html
    └── assets/

/var/spool/mybeacon/        # Очередь событий (при отсутствии сети)
├── ble/
└── wifi/

/var/log/                   # tmpfs (10MB, не убивает eMMC)
├── mybeacon.log            # Daemon logs
├── wifi-connect.log        # WiFi connection logs
└── ap.log                  # AP fallback logs

/etc/init.d/
├── S01tmpfs-log            # Mount /var/log as tmpfs
├── S10udev
├── S10usbhost
├── S15wireless             # Load AIC8800 modules
├── S20dbus                 # D-Bus (required for BlueZ)
├── S30network              # Базовая сеть (deprecated, управляет Network Manager)
├── S30usbmodem             # USB modem support
├── S36bluetooth            # BlueZ (required for BLE)
├── S50sshd                 # SSH server
└── S98mybeacon             # MyBeacon daemon (управляет сетью и NTP!)

Сборка

# Prerequisites
sudo apt install golang libzmq3-dev gcc-arm-linux-gnueabihf

# Clone
cd /home/user/work/luckfox/alpine/mybeacon

# Download Go dependencies
go mod download

# ARM cross-compile (для Luckfox)
make arm

# Результат в bin/arm/:
# - beacon-daemon
# - ble-scanner
# - wifi-scanner

Конфигурация

/opt/mybeacon/etc/config.json

{
  "mode": "cloud",
  "api_base": "http://server:5000/api/v1",
  "zmq_addr_ble": "tcp://127.0.0.1:5555",
  "zmq_addr_wifi": "tcp://127.0.0.1:5556",
  "spool_dir": "/var/spool/mybeacon",
  "wifi_iface": "wlan0",
  "debug": false,

  "ble": {
    "enabled": true,
    "batch_interval_ms": 2500
  },

  "wifi": {
    "monitor_enabled": true,
    "client_enabled": false,
    "ssid": "",
    "psk": "",
    "batch_interval_ms": 10000
  },

  "network": {
    "ntp_servers": ["pool.ntp.org"],
    "eth0": {
      "static": false,
      "address": "",
      "gateway": "",
      "dns": ""
    }
  },

  "ap_fallback": {
    "password": "mybeacon"
  },

  "dashboard": {
    "enabled": true
  },

  "ssh_tunnel": {
    "enabled": false,
    "server": "tunnel.example.com",
    "port": 22,
    "user": "tunnel",
    "key_path": "/opt/mybeacon/etc/tunnel_key",
    "remote_port": 12345,
    "keepalive_interval": 30,
    "reconnect_delay": 5
  }
}

/opt/mybeacon/etc/device.json (generated on first registration)

{
  "device_id": "38:54:39:4b:1b:ac",
  "device_token": "VL9tUGZrxGR7G4KmSDYjhrfZT7Por7C/ghvH9HdwMjQ=",
  "device_password": "62358673"
}

Server Config (from GET /api/v1/config)

Конфигурация, которую устройство получает с сервера каждые 30 секунд в cloud mode:

{
  "force_cloud": false,
  "ble": {
    "enabled": true,
    "batch_interval_ms": 2500,
    "uuid_filter_hex": ""
  },
  "wifi": {
    "client_enabled": false,
    "ssid": "AP_name",
    "psk": "123456789",
    "monitor_enabled": true,
    "batch_interval_ms": 10000
  },
  "ssh_tunnel": {
    "enabled": false,
    "server": "tunnel.example.com",
    "port": 22,
    "user": "tunnel",
    "remote_port": 0,
    "keepalive_interval": 30
  },
  "dashboard": {
    "enabled": true
  },
  "net": {
    "ntp": {
      "servers": ["pool.ntp.org", "time.google.com"]
    }
  },
  "debug": false
}

Приоритет настроек:

  • Cloud mode: серверные настройки имеют приоритет (BLE, WiFi, NTP)
  • LAN mode: локальные настройки имеют приоритет
  • SSH tunnel: ВСЕГДА с сервера (для удалённой поддержки)
  • Dashboard: ВСЕГДА с сервера (для удалённого управления)
  • eth0: ВСЕГДА локальные (никогда с сервера)

Server API Endpoints

Устройство взаимодействует с сервером через следующие endpoints:

POST /api/v1/registration

Регистрация нового устройства. Отправляется один раз при первом запуске.

Request:

{
  "device_id": "38:54:39:4b:1b:ac",
  "eth_ip": "192.168.1.100",
  "wlan_ip": "192.168.1.101"
}

Response:

{
  "device_token": "secure-token-here",
  "device_password": "generated-password"
}

GET /api/v1/config

Получение конфигурации от сервера (polling каждые 30 секунд в Cloud Mode).

Headers:

Authorization: Bearer {device_token}

Response: см. выше (Server Config)

POST /api/v1/ble

Загрузка BLE событий.

Headers:

Authorization: Bearer {device_token}
Content-Type: application/json
Content-Encoding: gzip

Request (gzipped):

{
  "device_id": "38:54:39:4b:1b:ac",
  "events": [
    {
      "timestamp": 1234567890,
      "mac": "AA:BB:CC:DD:EE:FF",
      "rssi": -65,
      "name": "Device Name"
    }
  ]
}

POST /api/v1/wifi

Загрузка WiFi событий.

Headers:

Authorization: Bearer {device_token}
Content-Type: application/json
Content-Encoding: gzip

Request (gzipped):

{
  "device_id": "38:54:39:4b:1b:ac",
  "events": [
    {
      "timestamp": 1234567890,
      "mac": "AA:BB:CC:DD:EE:FF",
      "rssi": -65,
      "ssid": "Network Name"
    }
  ]
}

POST /api/v1/wifi-credentials

Обновление WiFi credentials пользователем через Dashboard (только в Cloud Mode).

Headers:

Authorization: Bearer {device_token}
Content-Type: application/json

Request:

{
  "ssid": "NewNetwork",
  "psk": "password123"
}

Response:

{
  "success": true
}

Назначение: Когда пользователь в Cloud Mode изменяет WiFi Client credentials через Dashboard, устройство:

  1. Сохраняет новые credentials локально
  2. Применяет их для подключения к WiFi
  3. Отправляет их на сервер для централизованного управления

Сервер может использовать эти данные для:

  • Отображения текущей WiFi конфигурации в личном кабинете
  • Удалённого управления WiFi подключением (через GET /api/v1/config)
  • Автоматической синхронизации настроек между устройствами

Деплой

Через образ Alpine Linux

cd /home/user/work/luckfox/alpine

# 1. Собрать бинарники
cd mybeacon && make arm && cd ..

# 2. Скопировать в overlay
cp mybeacon/bin/arm/* overlay/opt/mybeacon/bin/

# 3. Собрать dashboard
cd mybeacon/dashboard && npm run build && cd ../..
cp -r mybeacon/dashboard/dist/* overlay/opt/mybeacon/www/

# 4. Собрать образ
cd scripts && sudo ./build_update_img.sh

# 5. Прошить (device в maskrom mode)
sudo /home/user/work/luckfox/upgrade_tool_v2.17_for_linux/upgrade_tool uf output/update.img

Обновление только демона (через SSH)

# Собрать
cd /home/user/work/luckfox/alpine/mybeacon && make arm

# Залить
scp bin/arm/beacon-daemon root@<device-ip>:/opt/mybeacon/bin/

# Перезапустить
ssh root@<device-ip> '/etc/init.d/S98mybeacon restart'

Текущий статус

  • BLE Scanner (BlueZ D-Bus API) - работает
  • WiFi Scanner (pcap + nl80211) - работает (с AIC8800 workaround)
  • Daemon core (ZMQ, batching, gzip, upload) - работает
  • Scanner Manager - работает
  • Network Manager (eth0/wlan0 client/AP fallback/NTP) - работает
  • Device Registration - работает
  • Config Polling (cloud mode, 30s) - работает, сразу после регистрации
  • HTTP API - работает
  • Vue.js Dashboard - работает
  • Dashboard remote control (enable/disable from server) - работает
  • NTP management (auto-start on network up) - работает
  • Spooler (offline queue) - работает
  • SSH Tunnel - реализовано (не тестировалось)
  • Logs optimization (tmpfs, rotation, spam reduction) - работает

Known Issues

  1. AIC8800 BLE + WiFi monitor conflict - решено через координацию в Network Manager
  2. WiFi scanner spam "bad file descriptor" при остановке - решено (graceful exit)
  3. Upload failed spam при отсутствии сети - решено (логирование раз в минуту)
  4. ap0 interface не удалялся через ip link del - решено (используется iw dev ap0 del)
  5. Dashboard обрезался снизу на мобильных - решено (padding-bottom: 6rem)

Performance

  • BLE events: ~2-5 events/sec → batching 2.5s → ~5-12 events/request
  • WiFi events: ~1-20 probes/sec → batching 10s → ~10-200 events/request
  • CPU usage: ~5-10% (idle), ~15-20% (active scanning)
  • Memory: ~30-40 MB (daemon + scanners)
  • Network: ~1-5 KB/sec upload (compressed)

License

Proprietary - All Rights Reserved