Protocol-agnostic UAV telemetry edge gateway - Bridge the gap between drone protocols and cloud platforms.
Open-UAV-Telemetry-Bridge (OUTB) is a lightweight, high-performance telemetry gateway designed for the Internet of Drones (IoD). It translates between various drone protocols (MAVLink, DJI, GB/T 28181) and outputs standardized data via MQTT, WebSocket, HTTP, or gRPC.
- Protocol Fragmentation: PX4 uses MAVLink, DJI uses proprietary protocols, government platforms require GB/T 28181
- Coordinate System Chaos: GPS outputs WGS84, but Chinese maps require GCJ02/BD09 offsets
- Bandwidth Constraints: Raw telemetry at 50-100Hz is too much for 4G networks
- Integration Complexity: Each platform needs a custom adapter
OUTB solves all these problems with a unified, pluggable architecture.
- Multi-Protocol Support: MAVLink (UDP/TCP/Serial), DJI (via Android Forwarder), GB/T 28181
- Unified Data Model: Standardized JSON output regardless of source protocol
- Coordinate Conversion: Automatic WGS84 → GCJ02/BD09 transformation for China maps
- Frequency Throttling: Configurable downsampling (e.g., 50Hz → 1Hz) to save bandwidth
- State Caching: In-memory state store with historical track storage
- MQTT Publisher: Standard MQTT 3.1.1 with LWT (Last Will and Testament) support
- HTTP REST API: Query drone states, health checks, gateway status
- WebSocket: Real-time push notifications for state updates
- Track Storage: Historical trajectory with ring buffer (configurable retention)
- GB/T 28181 Publisher: SIP registration and position reporting to government platforms
- JWT Authentication: Optional token-based authentication for API access
- Rate Limiting: IP-based request throttling to prevent abuse
- TLS/HTTPS: Optional TLS encryption for secure connections
- Alert System: Configurable alert rules with severity levels (battery low, signal loss, etc.)
- Geofencing: Define zones with entry/exit breach detection
- Log Buffer: Real-time log streaming via WebSocket
- Edge-Ready: Runs on Raspberry Pi 4, Jetson Nano, or cloud servers
- Zero Dependencies: Single binary, no external runtime required
- Hot Configuration: YAML-based configuration with runtime management API
- Web Dashboard: React + TypeScript management interface
- Go 1.21 or higher
- (Optional) MQTT Broker (e.g., Mosquitto)
# Clone the repository
git clone https://github.com/iannil/open-uav-telemetry-bridge.git
cd open-uav-telemetry-bridge
# Build
make build
# Or build for Raspberry Pi / Jetson
make build-linux-arm64# Copy example configuration
cp configs/config.example.yaml configs/config.yaml
# Edit as needed
vim configs/config.yaml# Run with configuration file
./bin/outb configs/config.yaml# Check health
curl http://localhost:8080/health
# Get gateway status
curl http://localhost:8080/api/v1/status
# List connected drones
curl http://localhost:8080/api/v1/drones┌─────────────────────────────────────────────────────────────┐
│ Northbound Interfaces │
│ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌────────────┐ │
│ │ MQTT │ │ WebSocket │ │ HTTP │ │ gRPC │ │
│ └────┬─────┘ └─────┬─────┘ └────┬─────┘ └─────┬──────┘ │
└───────┼──────────────┼─────────────┼──────────────┼─────────┘
│ │ │ │
└──────────────┴──────┬──────┴──────────────┘
│
┌─────────────────────────────┼───────────────────────────────┐
│ Core Engine │
│ ┌─────────────┐ ┌─────────┴────────┐ ┌────────────────┐ │
│ │ Throttler │ │ State Store │ │ Track Storage │ │
│ └─────────────┘ └──────────────────┘ └────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ Coordinate Converter (WGS84→GCJ02/BD09) ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────┬───────────────────────────────┘
│
┌─────────────────────────────┼───────────────────────────────┐
│ Southbound Adapters │
│ ┌──────────────┐ ┌────────────────┐ ┌─────────────────┐ │
│ │ MAVLink │ │ DJI Forwarder │ │ GB/T 28181 │ │
│ │ (UDP/TCP/Ser)│ │ (TCP Server) │ │ (SIP/NOTIFY) │ │
│ └──────┬───────┘ └───────┬────────┘ └────────┬────────┘ │
└─────────┼──────────────────┼────────────────────┼───────────┘
│ │ │
┌────┴────┐ ┌──────┴──────┐ ┌──────┴──────┐
│PX4/Ardu │ │ DJI Drone │ │ Gov Platform│
│ Pilot │ │ (via App) │ │ │
└─────────┘ └─────────────┘ └─────────────┘
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Health check |
| GET | /api/v1/status |
Gateway status and statistics |
| GET | /api/v1/drones |
List all connected drones |
| GET | /api/v1/drones/{id} |
Get specific drone state |
| GET | /api/v1/drones/{id}/track |
Get historical track points |
| DELETE | /api/v1/drones/{id}/track |
Clear track history |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/auth/login |
Login and get JWT token |
| POST | /api/v1/auth/logout |
Logout (client-side token removal) |
| GET | /api/v1/auth/me |
Get current user info |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/config |
Get current configuration |
| PUT | /api/v1/config/adapters/mavlink |
Update MAVLink adapter config |
| PUT | /api/v1/config/adapters/dji |
Update DJI adapter config |
| PUT | /api/v1/config/publishers/mqtt |
Update MQTT publisher config |
| PUT | /api/v1/config/publishers/gb28181 |
Update GB28181 publisher config |
| PUT | /api/v1/config/throttle |
Update throttle config |
| PUT | /api/v1/config/coordinate |
Update coordinate conversion config |
| PUT | /api/v1/config/track |
Update track storage config |
| POST | /api/v1/config/apply |
Apply configuration changes |
| POST | /api/v1/config/export |
Export configuration to file |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/alerts |
List all alerts |
| DELETE | /api/v1/alerts |
Clear all alerts |
| GET | /api/v1/alerts/stats |
Get alert statistics |
| GET | /api/v1/alerts/{id} |
Get specific alert |
| POST | /api/v1/alerts/{id}/ack |
Acknowledge alert |
| GET | /api/v1/alerts/rules |
List alert rules |
| POST | /api/v1/alerts/rules |
Create alert rule |
| GET | /api/v1/alerts/rules/{id} |
Get specific rule |
| PUT | /api/v1/alerts/rules/{id} |
Update alert rule |
| DELETE | /api/v1/alerts/rules/{id} |
Delete alert rule |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/geofences |
List all geofences |
| POST | /api/v1/geofences |
Create geofence |
| GET | /api/v1/geofences/stats |
Get geofence statistics |
| GET | /api/v1/geofences/breaches |
List breach events |
| DELETE | /api/v1/geofences/breaches |
Clear breach history |
| GET | /api/v1/geofences/{id} |
Get specific geofence |
| PUT | /api/v1/geofences/{id} |
Update geofence |
| DELETE | /api/v1/geofences/{id} |
Delete geofence |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/logs |
Get buffered logs |
| GET | /api/v1/logs/stream |
Stream logs via SSE |
| DELETE | /api/v1/logs |
Clear log buffer |
Connect to ws://localhost:8080/api/v1/ws for real-time updates.
Message Types:
// State update (server → client)
{
"type": "state_update",
"data": { /* DroneState */ }
}
// Subscribe to specific drones (client → server)
{
"type": "subscribe",
"device_ids": ["drone-001", "drone-002"]
}
// Unsubscribe (client → server)
{
"type": "unsubscribe",
"device_ids": ["drone-001"]
}{
"device_id": "mavlink-001",
"timestamp": 1709882231000,
"protocol_source": "mavlink",
"location": {
"lat": 39.9042,
"lon": 116.4074,
"lat_gcj02": 39.9066,
"lon_gcj02": 116.4136,
"alt": 120.5,
"coordinate_system": "WGS84"
},
"attitude": {
"roll": 0.05,
"pitch": -0.12,
"yaw": 180.0
},
"velocity": {
"vx": 10.5,
"vy": 0.0,
"vz": -0.5
},
"status": {
"battery_percent": 85,
"flight_mode": "AUTO",
"armed": true,
"signal_quality": 95
}
}# Server settings
server:
log_level: info # debug, info, warn, error
log_buffer_size: 1000 # Log entries to keep in memory
# MAVLink Adapter
mavlink:
enabled: true
connection_type: udp # udp | tcp | serial
address: "0.0.0.0:14550"
# DJI Forwarder Adapter
dji:
enabled: false
listen_address: "0.0.0.0:14560"
max_clients: 10
# MQTT Publisher
mqtt:
enabled: true
broker: "tcp://localhost:1883"
client_id: "outb-001"
topic_prefix: "uav/telemetry"
qos: 1
lwt:
enabled: true
topic: "uav/status"
message: "offline"
# GB/T 28181 Publisher
gb28181:
enabled: false
device_id: "34020000001320000001"
server_id: "34020000002000000001"
server_ip: "192.168.1.1"
server_port: 5060
position_interval: 5
# HTTP API
http:
enabled: true
address: "0.0.0.0:8080"
cors_enabled: true
cors_origins: ["*"]
webui_enabled: true
# TLS Configuration
tls:
enabled: false
cert_file: "/path/to/cert.pem"
key_file: "/path/to/key.pem"
# Rate Limiting
rate_limit:
enabled: true
requests_per_sec: 100
burst_size: 200
# Authentication (JWT)
auth:
enabled: false
username: "admin"
password_hash: "" # bcrypt hash
jwt_secret: ""
token_expiry_hours: 24
# Frequency Throttling
throttle:
default_rate_hz: 1.0
min_rate_hz: 0.5
max_rate_hz: 10.0
# Coordinate Conversion (China maps)
coordinate:
convert_gcj02: true # For Amap, Tencent, Google China
convert_bd09: false # For Baidu Maps
# Track Storage
track:
enabled: true
max_points_per_drone: 10000
sample_interval_ms: 1000Deploy on Raspberry Pi or Jetson mounted on the drone.
[Flight Controller] --Serial--> [OUTB on Pi] --4G--> [Cloud]
Run alongside your GCS software.
[Drone] --Radio--> [GCS + OUTB] --WiFi/4G--> [Cloud]
Centralized protocol conversion for fleet management.
[Drone Fleet] --TCP/UDP--> [OUTB on Cloud] --> [Backend Services]
- v0.1 - MAVLink → MQTT basic pipeline
- v0.2 - DJI Android Forwarder app
- v0.3 - Coordinate conversion + HTTP API
- v0.3.1 - WebSocket + Track storage
- v0.4 - GB/T 28181 national standard support
- v1.0 - Web management dashboard (React + TypeScript)
- v1.1 - Security & Operations
- JWT authentication
- Rate limiting
- TLS/HTTPS support
- Alert system with configurable rules
- Geofencing with breach detection
- Real-time log streaming
- Configuration management API
├── cmd/outb/ # Application entry point
├── internal/
│ ├── adapters/ # Southbound protocol adapters
│ │ ├── mavlink/ # MAVLink (UDP/TCP/Serial)
│ │ └── dji/ # DJI Forwarder (TCP Server)
│ ├── api/ # HTTP/WebSocket server
│ │ ├── auth/ # JWT authentication
│ │ ├── handlers/ # API handlers (config, alerts, logs, geofences)
│ │ └── ratelimit/ # IP-based rate limiting
│ ├── config/ # YAML configuration
│ ├── core/ # Core engine
│ │ ├── alerter/ # Alert rules engine
│ │ ├── coordinator/ # Coordinate conversion
│ │ ├── geofence/ # Geofencing engine
│ │ ├── logger/ # Log buffer
│ │ ├── statestore/ # State caching
│ │ ├── throttler/ # Frequency control
│ │ └── trackstore/ # Historical tracks
│ ├── models/ # Unified data models
│ ├── publishers/ # Northbound publishers
│ │ ├── mqtt/ # MQTT publisher
│ │ └── gb28181/ # GB/T 28181 SIP publisher
│ └── web/ # Embedded Web UI assets
├── web/ # Web UI source (React + TypeScript)
├── android/ # DJI Android Forwarder (Kotlin)
├── configs/ # Configuration examples
├── scripts/ # Test utilities
└── docs/ # Documentation
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- gomavlib - Go MAVLink library
- paho.mqtt.golang - Eclipse Paho MQTT client
- chi - Lightweight HTTP router
- sipgo - SIP library for GB/T 28181
- gorilla/websocket - WebSocket implementation
- golang-jwt/jwt - JWT authentication