55bca92691
Core features: - Class 1 T.30 protocol: full send/receive implementation - HDLC: DLE-stuffing, FCS strip, USR5637 bit-reversal handling - T.4 MH encoder/decoder (1728px A4 standard) - Document pipeline: PDF (Ghostscript), PNG, TIFF input - Width clamping: US Letter 1734px → 1728px fax standard - Cover page: CJK rasterization (TW/CN/JP/EN), TIFF + HTML output - OCR verification: Tesseract 5 with eng+chi_tra, CJK space-tolerant - API server (axum): health, send, jobs, cover, retry, cancel - Background worker: auto-poll queue, speed fallback, retry policy - Modem detection, pool management Real-world test results (2026-07-23): - V90 → 25153038: 4 pages, V.17 12000 bps, 2:33 ✅ - USR5637 → 25153038: 4 pages, V.17 12000 bps, 2:26 ✅ - Both faxes confirmed received on remote machine Tested: loopback (100% pixel match), multi-page, all input formats, cover pages, OCR verify, API endpoints, worker processing. 13 unit tests pass, 0 new clippy warnings.
8.8 KiB
8.8 KiB
Telfax Enterprise Fax Server
A production-ready fax server built in Rust, supporting Class 1 and Class 2 fax protocols.
Features
Core Features
- ✅ Class 2 fax protocol (auto T.30 handling)
- ✅ Class 1 fax protocol (manual T.30 handling)
- ✅ T.4 MH encoding/decoding
- ✅ PDF/TIFF/Image document conversion
- ✅ Chinese cover page generation (PingFang font)
Enterprise Features
- ✅ REST API for job management
- ✅ Token-based authentication
- ✅ Modem pool management (multi-modem support)
- ✅ Job queue with persistence (SQLite)
- ✅ Retry logic with exponential backoff
- ✅ Speed fallback on training failure
- ✅ Prometheus metrics endpoint
- ✅ systemd integration
- ✅ Structured logging (journal-compatible)
Architecture
┌─────────────────────────────────────────────────────────┐
│ telfax Server │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ REST API │────│ Job Queue │ │
│ │ (Axum) │ │ (SQLite) │ │
│ └──────────────┘ └──────────────┘ │
│ │ │ │
│ │ ┌──────▼──────┐ │
│ │ │ Worker │ │
│ │ │ Executor │ │
│ │ └─────────────┘ │
│ │ │ │
│ │ ┌──────▼──────┐ │
│ │ │ Modem Pool │ │
│ │ │ Manager │ │
│ │ └─────────────┘ │
│ │ │ │
│ │ ┌─────────▼─────────┐ │
│ │ │ │ │
│ │ ┌────▼────┐ ┌─────▼─────┐ │
│ │ │ V90 │ │ USR5637 │ │
│ │ │ Class 2 │ │ Class 1 │ │
│ │ │ Primary │ │ Fallback │ │
│ │ └─────────┘ └───────────┘ │
│ │ │
│ ┌──────▼──────────────────────────────┐ │
│ │ Monitoring Layer │ │
│ │ ├─ Metrics (Prometheus) │ │
│ │ ├─ Logging (systemd journal) │ │
│ │ └─ Health checks │ │
│ └─────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────┘
Installation
Prerequisites
- Rust 1.70+ (for building)
- systemd (for service management)
- Ghostscript (for PDF conversion)
Build
cargo build --release
Install
sudo ./deployment/install.sh
Configuration
Configuration file: /opt/telfax/config.toml
[server]
listen = "0.0.0.0:3000"
log_level = "info"
[auth]
rate_limit_per_ip = 100
rate_limit_per_token = 500
[[auth.tokens]]
token = "your-secret-admin-token-here"
permissions = "admin"
[[modems]]
device = "/dev/cu.usbmodem123456781"
name = "V90"
class = 2
priority = 1
enabled = true
[[modems]]
device = "/dev/cu.usbmodem00000021"
name = "USR5637"
class = 1
priority = 2
enabled = true
[queue]
database = "/var/lib/telfax/queue.db"
max_retries = 3
retry_intervals = [60, 300, 900]
[fax]
station_id = "+886-2-1234-5678"
header = "Your Company Name"
resolution = "fine"
speed_fallback = true
default_class = 2
API Reference
Authentication
All API endpoints require Bearer token authentication:
Authorization: Bearer <your-token>
Endpoints
Health Check
GET /api/health
Response:
{
"status": "healthy",
"uptime_seconds": 3600,
"modems": [
{
"name": "V90",
"device": "/dev/cu.usbmodem123456781",
"status": "idle"
}
],
"queue": {
"pending": 5,
"active": 1,
"failed": 2
}
}
Send Fax
POST /api/fax/send
Request:
{
"recipient": "0212345678",
"document_path": "/path/to/document.pdf",
"cover_to": "Recipient Name",
"cover_from": "Your Company",
"cover_subject": "Invoice #123",
"cover_notes": "Additional notes"
}
Response:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"message": "Job queued successfully"
}
List Jobs
GET /api/fax/jobs
Response:
{
"jobs": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"recipient": "0212345678",
"status": "Queued",
"pages": 3,
"retries": 0,
"created_at": "2024-07-05T12:00:00Z",
"updated_at": "2024-07-05T12:00:00Z"
}
],
"total": 1
}
Get Job
GET /api/fax/jobs/{id}
Cancel Job
DELETE /api/fax/jobs/{id}
Retry Job
POST /api/fax/jobs/{id}/retry
Update Cover Page
PUT /api/fax/jobs/{id}/cover
Metrics
GET /api/metrics
Prometheus-compatible metrics:
fax_jobs_total 10
fax_jobs_completed 8
fax_jobs_failed 2
fax_jobs_queued 0
fax_pages_sent_total 24
fax_bytes_sent_total 1234567
modem_errors_total 3
Service Management
Start
sudo systemctl start telfax
Stop
sudo systemctl stop telfax
Enable (auto-start on boot)
sudo systemctl enable telfax
View Logs
# Follow logs
journalctl -u telfax -f
# Today's logs
journalctl -u telfax --since today
# Only errors
journalctl -u telfax -p err
CLI Commands
Send Fax
telfax send 0212345678 /path/to/document.pdf \
--device /dev/cu.usbmodem123456781 \
--class 2 \
--resolution fine \
--to "Recipient" \
--from "Sender" \
--subject "Subject"
Receive Fax
telfax receive \
--device /dev/cu.usbmodem123456781 \
--rings 2 \
--output /var/lib/telfax/received \
--class 2
Detect Modem
telfax detect /dev/cu.usbmodem123456781
Generate Cover Page
telfax cover-create \
--to "Recipient" \
--from "Sender" \
--subject "Subject" \
--note "Notes" \
--pages 3 \
--output cover.html
Worker Configuration
The background worker processes jobs from the queue:
- Poll Interval: 5 seconds (checks for pending jobs)
- Retry Policy: 3 retries with exponential backoff (1min, 5min, 15min)
- Speed Fallback: On training failure, lowers speed: 14400 → 12000 → 9600 → 7200 → 4800
- Concurrent Jobs: 1 per modem (configurable)
Monitoring
Health Check Endpoint
GET /api/health
Prometheus Metrics
GET /api/metrics
Logging
All logs go to systemd journal with structured fields:
job_id: Current job being processedmodem_name: Modem in usestatus: Operation status
Development
Project Structure
src/
├── api/ # REST API routes and auth
├── config_new/ # Configuration management
├── document/ # PDF/TIFF handling, cover pages
├── error/ # Error types
├── fax/ # Fax protocols (Class 1/2)
├── modem/ # Modem driver and pool
├── monitoring/ # Metrics and health checks
├── ocr/ # OCR (optional)
├── preview/ # HTML preview generation
├── queue/ # Job queue and persistence
├── worker/ # Background job executor
└── main.rs # CLI entry point
Running Tests
cargo test
Building Release
cargo build --release
License
MIT License
Support
For issues and feature requests, please open an issue on GitHub.