10 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
onvif-go is a production-ready Go library for communicating with ONVIF-compliant IP cameras. It provides both a client library for camera control and a server implementation for camera simulation/testing.
Key Features:
- ONVIF client with 200+ APIs across Device, Media, PTZ, and Imaging services
- ONVIF server for virtual camera simulation
- WS-Discovery for network camera detection
- WS-Security authentication with digest passwords
- Multiple CLI tools for camera interaction and diagnostics
Essential Commands
Build
# Build all CLI tools for current platform
make build
# Build for multiple platforms (Linux, Windows, macOS)
make build-all
# Build specific CLI tool
go build -o bin/onvif-cli ./cmd/onvif-cli
Test
# Run all tests
go test ./...
# Run tests with coverage
go test -v -race -coverprofile=coverage.out ./...
make test-coverage
# Run benchmarks
make bench
go test -bench=. -benchmem ./...
# Run specific package tests
go test -v ./discovery
go test -v ./server
Lint and Format
# Run all checks (fmt, vet, lint)
make check
# Format code
make fmt
# Run linter
make lint # Requires golangci-lint
Development
# Install dependencies
make deps
# Clean build artifacts
make clean
# Build examples
make examples
# Run CLI tools
./bin/onvif-cli
./bin/onvif-quick
CLI Tools
onvif-cli: Comprehensive ONVIF client with interactive and non-interactive modes
# Interactive menu
./bin/onvif-cli
# Discover cameras
./bin/onvif-cli discover -interface eth0 -timeout 5
# Get device info
./bin/onvif-cli -op info -endpoint http://camera-ip/onvif/device_service -username admin -password pass
onvif-diagnostics: Camera testing and XML capture for debugging
./bin/onvif-diagnostics -endpoint http://camera-ip/onvif/device_service -username admin -password pass -verbose
# Capture raw SOAP XML
./bin/onvif-diagnostics ... -capture-xml
onvif-server: Virtual camera server for testing
./bin/onvif-server -profiles 5 -username admin -password mypass -port 9000
Architecture
Package Structure
onvif-go/
├── *.go # Core client library (client.go, device.go, media.go, ptz.go, imaging.go, etc.)
├── types.go # ONVIF type definitions (all SOAP XML structures)
├── internal/soap/ # SOAP client with WS-Security (NOT exported)
├── discovery/ # WS-Discovery implementation (exported package)
├── server/ # ONVIF server implementation (exported package)
├── cmd/ # CLI tools
│ ├── onvif-cli/ # Full-featured client
│ ├── onvif-quick/ # Lightweight tool
│ ├── onvif-diagnostics/ # Debugging and XML capture
│ ├── onvif-server/ # Server CLI
│ └── generate-tests/ # Test generation from XML captures
├── testing/ # Test utilities (mock_server.go)
├── testdata/captures/ # Real camera SOAP response captures
└── examples/ # Usage examples
Key Components
Client Layer (client.go):
- Main
Clientstruct with HTTP connection pooling - Functional options pattern for configuration (WithCredentials, WithTimeout, WithHTTPClient)
- Context-aware operations throughout
- Thread-safe credential management with sync.RWMutex
Service Implementations:
device.go+device_*.go: 98 Device Management APIs (configuration, users, network, certificates, WiFi, storage)media.go: Media profiles, stream URIs (RTSP/HTTP), snapshots, encoder configurationptz.go: PTZ control (continuous, absolute, relative movement, presets)imaging.go: Image settings (brightness, contrast, exposure, focus, white balance)event.go: Event service (subscriptions, pull-point)deviceio.go: Device I/O and relay control
SOAP Layer (internal/soap/):
- WS-Security UsernameToken authentication with password digest (SHA-1)
- XML marshaling/unmarshaling for ONVIF SOAP messages
- Error handling with ONVIFError type
- NOT exported - internal implementation detail
Discovery (discovery/):
- WS-Discovery multicast probe on 239.255.255.250:3702
- Network interface selection support
- Device deduplication by endpoint reference
Server (server/):
- Virtual multi-lens camera simulator
- Implements Device, Media, PTZ, and Imaging services
- Configurable number of camera profiles (up to 10)
- WS-Security authentication support
Type System
All ONVIF types are defined in types.go (~30,000+ lines). Key patterns:
- XML struct tags for SOAP serialization
- Pointer fields for optional values (ONVIF convention)
- Namespace-aware XML marshaling
- Comprehensive coverage of ONVIF Core, Device, Media, PTZ, Imaging specs
Development Patterns
Client Usage Pattern
// 1. Create client with options
client, err := onvif.NewClient(
endpoint,
onvif.WithCredentials(username, password),
onvif.WithTimeout(30*time.Second),
)
// 2. Initialize to discover service endpoints
if err := client.Initialize(ctx); err != nil {
return err
}
// 3. Use service methods
profiles, err := client.GetProfiles(ctx)
Context Usage
All network operations require context.Context as first parameter:
- Enables timeouts:
context.WithTimeout() - Enables cancellation:
context.WithCancel() - No blocking indefinitely
Error Handling
- Sentinel errors:
ErrServiceNotSupported,ErrAuthenticationFailed - Typed errors:
ONVIFErrorfor SOAP faults - Use
errors.Is()anderrors.As()for error checking - Always wrap errors with context:
fmt.Errorf("operation failed: %w", err)
Testing Strategy
- Unit tests alongside implementation files (
*_test.go) - Real camera tests in
*_real_camera_test.go(skipped without-tags=real_camera) - Mock server in
testing/mock_server.gofor integration tests - XML captures in
testdata/captures/for regression testing - Comprehensive test coverage tracked in
docs/testing/
Authentication Implementation
WS-Security digest authentication requires:
- Generate 16-byte random nonce
- Get UTC timestamp
- Calculate:
Base64(SHA1(nonce + timestamp + password)) - Include Username, Password (digest), Nonce, Created in SOAP header
Critical Implementation Details
SOAP Message Structure
All ONVIF operations use SOAP 1.2 over HTTP POST:
- Envelope with WS-Security header (if authenticated)
- Body contains operation-specific request
- Response parsed from SOAP envelope body
- SOAP faults mapped to Go errors
Service Endpoint Discovery
The Initialize() method discovers service endpoints:
- Calls
GetCapabilities()to get service URLs - Caches endpoints (media, PTZ, imaging, event)
- Falls back to device service endpoint if not found
- Subsequent operations use cached endpoints
Connection Pooling
HTTP client configured for optimal performance:
- Idle connection timeout: 90s
- Max idle connections: 10
- Max idle per host: 5
- Custom transport for TLS control
Network Interface Selection (Discovery)
Discovery supports binding to specific interfaces:
- By interface name:
"eth0","en0" - By IP address:
"192.168.1.100" - Auto-detection tries all active interfaces if not specified
- Uses
golang.org/x/net/ipv4for multicast control
File Organization
- Root
*.go: Public API and implementation *_test.go: Unit tests (run withgo test)*_real_camera_test.go: Integration tests requiring real camerasdocs/: Comprehensive documentation organized by categorytest-reports/: JSON reports from real camera testingexamples/: Standalone example programs
Build System
Makefile targets:
make all: deps + check + test + buildmake build: Build CLI tools for current platformmake build-all: Cross-compile for all platforms (Linux, Windows, macOS - amd64, arm64, arm)make release: Build + create archives + checksumsmake test: Run tests with race detectionmake bench: Run benchmarksmake check: fmt + vet + lintmake clean: Remove build artifacts
Build flags:
CGO_ENABLED=0: Static binaries-ldflags="-s -w": Strip symbols for smaller size- Version injection:
-X main.Version=$(VERSION)
Testing Without Real Cameras
Use the diagnostic tool to capture real camera responses:
# 1. Capture XML from real camera
./onvif-diagnostics -endpoint http://camera/onvif/device_service -username user -password pass -capture-xml
# 2. Generate test from capture
./generate-tests -capture camera-logs/*_xmlcapture_*.tar.gz -output testdata/captures/
# 3. Run generated tests
go test -v ./testdata/captures/
This allows testing library changes against real camera behavior without physical hardware.
Important Notes
- ONVIF specification compliance: Follows ONVIF Core, Device, Media, PTZ, Imaging specs
- WS-Security: Digest authentication (SHA-1) per ONVIF requirements
- Concurrency: All operations are thread-safe
- XML namespaces: Critical for ONVIF - handled in types.go struct tags
- Pointer semantics: Optional fields use pointers (ONVIF convention)
- Service support detection: Always check capabilities before calling service-specific methods
- Endpoint flexibility: Accepts full URLs, IP:port, or bare IPs (auto-adds http:// and /onvif/device_service)
Common Development Tasks
Adding a new ONVIF operation:
- Define request/response types in
types.gowith XML tags - Implement method in appropriate service file (
device.go,media.go, etc.) - Use
callMethod()helper for SOAP invocation - Add unit test in corresponding
*_test.go - Update documentation in
docs/api/
Adding a new CLI command:
- Add command/flags in
cmd/onvif-cli/main.go - Implement handler function
- Update CLI help text
- Add example to
docs/CLI_*.md
Adding server functionality:
- Implement handler in
server/*.go - Register handler in SOAP router
- Add test in
server/*_test.go - Update
server/README.md
Dependencies
Minimal dependencies (see go.mod):
golang.org/x/net: HTTP/2 and IDNA supportgithub.com/0x524A/rtspeek: RTSP stream validation (diagnostics tool)- Standard library for everything else
Go version: 1.21+ (currently 1.24)