Skip to content

opencardev/crankshaft.core

Repository files navigation

Crankshaft

Extensible Infotainment System for Automotive Applications

License: GPL-3.0 Platform: Linux Build Status Qt Version


📖 Table of Contents


Overview

Crankshaft is a modern, extensible infotainment system designed for automotive applications running on Raspberry Pi 4 and compatible Linux platforms. Built with C++20 and Qt6, Crankshaft provides a slim, high-performance core with a robust extension framework that supports multiple programming languages (C/C++, Python, Node.js).

The system features Android Auto integration (wired and wireless), multi-display support, and a responsive, driver-safe UI that follows Design for Driving guidelines. Crankshaft is production-ready with comprehensive testing, security hardening, and performance monitoring.

Design Philosophy

  • Extensibility: Plugin-based architecture with sandboxed extensions
  • Performance: Cold start ≤10s, Android Auto connect ≤15s, UI interactions ≤200ms
  • Safety: Driver-focused UX with limited distractions and large touch targets
  • Modularity: Loosely coupled core with event-driven communication
  • Security: Validated inputs, sandboxed extensions, secure WebSocket (wss) ready
  • Resource Efficiency: Optimised for embedded systems (≤1.5 GB memory target)

Key Features

🚗 Core Capabilities

  • Android Auto Integration: Full support for wired and wireless Android Auto via AASDK

    • Media playback, navigation, messaging, and voice assistant
    • Automatic device detection and connection
    • Session persistence and reconnection
  • Multi-Display Support: Run on physical (EGLFS) and virtual (VNC) displays

    • Independent displays for navigation, media controls, and settings
    • Hot-plug detection for USB displays
    • Resolution-adaptive layouts
  • Extension Framework: Robust plugin system with manifest-based configuration

    • Sandboxed extension processes with permission model
    • WebSocket-based event bus for inter-process communication
    • REST API for diagnostics and health checks
    • Support for C/C++, Python, Node.js extensions

🎨 User Interface

  • Modern, Responsive Design: Built with Qt6/QML

    • Light and dark themes (toggle via Settings)
    • Smooth animations and transitions
    • Touch-optimised with 48dp minimum targets
    • Automotive-grade contrast ratios (4.5:1 minimum)
  • Internationalisation: Multi-language support (i18n ready)

    • Default: English (UK) en-GB
    • Included: German (Germany) de-DE
    • Easy addition of new locales
  • Driver Safety: Compliant with Design for Driving principles

    • Limited keyboard input while driving
    • Simplified navigation with minimal steps
    • High-contrast glanceable information

🔧 System Services

  • Media Services: Audio playback with PipeWire (preferred) or PulseAudio

    • Bluetooth audio streaming
    • Radio tuner integration
    • USB media playback
  • Database: SQLite-backed persistence

    • User preferences and settings
    • Android Auto device and session history
    • Extension configuration
  • Diagnostics & Monitoring: Real-time performance profiling

    • Memory and CPU metrics
    • WebSocket connection tracking
    • Request latency monitoring with percentiles (p50, p95, p99)
    • Alert system with WARNING/CRITICAL thresholds
    • Prometheus export for Grafana integration
  • Security & Compliance: Production-ready hardening

    • Input validation with JSON schema
    • Allowlisted service commands
    • Extension sandboxing with manifest permissions
    • Audit logging for sensitive operations
    • GDPR-compliant data handling

Architecture

Crankshaft uses a multi-process architecture with loosely coupled components communicating via WebSocket and Qt signals:

┌─────────────────────────────────────────────────────────────┐
│                        Crankshaft System                     │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌──────────────┐         ┌──────────────┐                 │
│  │  Core Daemon │◄───────►│  UI Client   │                 │
│  │  (C++/Qt6)   │  WS/QT  │  (Qt6/QML)   │                 │
│  └──────┬───────┘         └──────────────┘                 │
│         │                                                    │
│         │ WebSocket Event Bus (JSON Messages)              │
│         │                                                    │
│  ┌──────┴─────────────────────────────────────────┐        │
│  │                                                  │        │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────┐│        │
│  │  │ Extension 1 │  │ Extension 2 │  │  Ext N  ││        │
│  │  │  (Media)    │  │  (Radio)    │  │ (Custom)││        │
│  │  └─────────────┘  └─────────────┘  └─────────┘│        │
│  │                                                  │        │
│  └──────────────────────────────────────────────────┘        │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │            External Integrations                      │  │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  │  │
│  │  │Android Auto │  │   PipeWire  │  │   SQLite    │  │  │
│  │  │   (AASDK)   │  │   /PulseAudio│  │  Database  │  │  │
│  │  └─────────────┘  └─────────────┘  └─────────────┘  │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Component Responsibilities

Component Description Technologies
Core Daemon Central service manager, event bus, Android Auto integration, extension lifecycle management C++20, Qt6 Core, QWebSocket, AASDK
UI Client User interface for touch displays, theme support, localization Qt6 QML/Quick, Qt Declarative
Extensions Pluggable services (media, radio, Bluetooth, custom), sandboxed processes C/C++, Python, Node.js
WebSocket Server Event bus for publish/subscribe messaging, service commands, authentication Qt6 QWebSocket, JSON validation
Diagnostics API REST endpoints for health checks, metrics, alerts OpenAPI 3.0, Qt HTTP server
Database Persistent storage for preferences, sessions, device history SQLite (Qt SQL module)

Communication Patterns

WebSocket Messages (JSON over WS):

  • subscribe / unsubscribe: Topic-based subscriptions
  • publish / event: Broadcast events to subscribers
  • service_command / service_response: Request/response RPC pattern
  • Schema validation: contracts/ws-schema.json

Event Bus Topics (Examples):

  • android_auto.device.connected → New Android Auto device detected
  • media.playback.state_changed → Media playback state update
  • ui.theme.changed → User toggled light/dark theme
  • extension.lifecycle.started → Extension process started successfully

Service Commands (Allowlisted):

  • get_session_info: Retrieve current Android Auto session
  • start_extension: Launch an extension by ID
  • stop_extension: Gracefully stop an extension
  • get_preferences: Fetch user preferences by key

Quick Start

Prerequisites

  • OS: Ubuntu 22.04 LTS or later (native Linux or WSL2)
  • RAM: 2 GB minimum (4 GB recommended for build)
  • Disk: 6 GB free space
  • CPU: 2 cores minimum (4+ recommended for faster builds)

Build in 5 Minutes

# 1. Install dependencies (Ubuntu 22.04)
sudo apt-get update && sudo apt-get install -y \
    build-essential cmake ninja-build pkg-config \
    qt6-base-dev qt6-declarative-dev qt6-websockets-dev \
    libsqlite3-dev libpipewire-0.3-dev libpulse-dev

# 2. Clone the repository
git clone https://github.com/opencardev/crankshaft-mvp.git
cd crankshaft-mvp

# 3. Build core and UI
mkdir build && cd build
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
ninja

# 4. Run the application (VNC for testing)
./ui/crankshaft-ui -platform vnc:size=1024x600,port=5900
# Connect via VNC client to localhost:5900

For detailed instructions, see Quick Start Guide.


Installation

Production Deployment (Raspberry Pi 4)

Recommended: Use pre-built DEB packages from the OpenCarDev APT repository:

# Add OpenCarDev repository
curl -fsSL https://packages.opencardev.org/opencardev-apt.asc | sudo gpg --dearmor -o /usr/share/keyrings/opencardev-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/opencardev-archive-keyring.gpg] https://packages.opencardev.org/debian trixie stable" | sudo tee /etc/apt/sources.list.d/opencardev.list

# Install Crankshaft
sudo apt-get update
sudo apt-get install crankshaft-core crankshaft-ui

# Enable and start services
sudo systemctl enable crankshaft-core
sudo systemctl start crankshaft-core
sudo systemctl enable crankshaft-ui
sudo systemctl start crankshaft-ui

Architecture Support:

  • arm64 (64-bit Raspberry Pi OS, recommended)
  • armhf (32-bit legacy support)
  • amd64 (Development workstations)

Build from Source

For custom builds or development:

# Cross-compile for Raspberry Pi (on x86_64 host)
./scripts/build-rpi.sh --arch arm64 --build-type Release --package

# Native build (on Raspberry Pi)
./scripts/build.sh --build-type Release --package

# Output: build/*.deb packages

Build Options:

  • --build-type: Debug (with symbols) or Release (optimised)
  • --component: Build specific components (core, ui, extensions)
  • --package: Generate DEB packages with CPack
  • --with-tests: Include test executables

User Stories

For End Users (Drivers)

US-001: As a driver, I want to connect my Android phone to display Android Auto on the head unit, so I can safely access navigation, media, and messaging while driving.

US-002: As a driver, I want to switch between light and dark themes, so the display is comfortable in different lighting conditions.

US-003: As a driver, I want the system to remember my preferences (volume, last media source, theme), so I don't have to reconfigure after every ignition cycle.

US-004: As a driver, I want large, touch-friendly controls, so I can operate the system safely while the vehicle is in motion.

For Extension Developers

US-010: As an extension developer, I want to publish events to the event bus, so my extension can notify the UI and other extensions of state changes.

US-011: As an extension developer, I want to declare required permissions in a manifest, so users understand what resources my extension needs.

US-012: As an extension developer, I want a documented REST API for diagnostics, so I can query system health and metrics programmatically.

For System Integrators

US-020: As a system integrator, I want to deploy Crankshaft via DEB packages, so I can automate fleet installations with standard package managers.

US-021: As a system integrator, I want to run 24-hour soak tests, so I can validate stability before production deployments.

US-022: As a system integrator, I want Prometheus-compatible metrics, so I can monitor fleet performance with existing observability tools.


Development

Build System

Crankshaft uses CMake with Ninja generator for fast incremental builds:

# Configure build
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -S . -B build

# Build all targets
cmake --build build --parallel

# Build specific component
cmake --build build --target crankshaft-core
cmake --build build --target crankshaft-ui

# Install to system (requires sudo)
sudo cmake --install build

Running Tests

# Run all tests
ctest --test-dir build --output-on-failure

# Run specific test suite
ctest --test-dir build -R WebSocket

# Run with verbose output
ctest --test-dir build --verbose

# Generate coverage report (Debug build with --coverage)
cmake --build build --target coverage

Test Coverage (Current):

  • Integration Tests: 55/60 passing (91.7%)
  • Unit Tests: Core services, WebSocket validation, AndroidAuto lifecycle
  • Contract Tests: JSON schema validation for WS messages

Code Quality

# Format C++ code (clang-format)
./scripts/format_cpp.sh fix

# Check formatting
./scripts/format_cpp.sh check

# Lint with clang-tidy
./scripts/lint_cpp.sh clang-tidy

# Static analysis with cppcheck
./scripts/lint_cpp.sh cppcheck

# Check license headers
./scripts/check_license_headers.sh

# Pre-commit checks (format, lint, tests)
# (Automatically runs on git commit if using pre-commit hooks)

Performance Profiling

Real-Time Metrics Dashboard:

# Start metrics collection
curl http://localhost:8080/metrics/summary

# View active alerts
curl http://localhost:8080/metrics/alerts

# Export Prometheus format
curl http://localhost:8080/metrics/prometheus

24-Hour Soak Test:

# Run stability test (24 hours)
./tests/integration/soak_test.sh

# Quick validation (1 hour)
./tests/integration/soak_test.sh 1

# Monitor progress
tail -f soak-logs/soak_test.log

# View report
cat docs/SOAK_TEST_RESULTS.md

Profiling Tools:

  • Valgrind: Memory leak detection (valgrind --leak-check=full ./build/core/crankshaft-core)
  • Heaptrack: Heap profiler (heaptrack ./build/core/crankshaft-core)
  • perf: Linux profiler (perf record -g ./build/core/crankshaft-core)

Extension Development

Creating a New Extension:

  1. Define Manifest (extension.json):
{
  "id": "org.example.myextension",
  "name": "My Extension",
  "version": "1.0.0",
  "entrypoint": "/usr/lib/crankshaft/extensions/myextension",
  "permissions": ["websocket.publish", "preferences.read"],
  "resources": {
    "cpu_limit": "50%",
    "memory_limit": "128MB"
  }
}
  1. Implement Extension (Python example):
import json
import websocket

def on_message(ws, message):
    event = json.loads(message)
    if event['type'] == 'event' and event['topic'] == 'system.startup':
        # Publish response
        response = {
            'type': 'publish',
            'topic': 'myextension.ready',
            'payload': {'status': 'initialized'}
        }
        ws.send(json.dumps(response))

if __name__ == '__main__':
    ws = websocket.WebSocketApp("ws://localhost:8080/ws",
                                 on_message=on_message)
    ws.run_forever()
  1. Register Extension:
# Copy manifest to extensions directory
sudo cp extension.json /etc/crankshaft/extensions/

# Restart core service to load extension
sudo systemctl restart crankshaft-core

Extension API Documentation: See Extension Developer Guide for complete API reference and examples.


Performance

Benchmarks (Raspberry Pi 4, 4GB RAM)

Metric Target Measured Status
Cold Start (Core + UI) ≤10s 3.2s avg ✅ PASS (68% below target)
Android Auto Connect ≤15s 12.5s avg ✅ PASS (17% below target)
Media Latency (p95) <200ms 186ms ⚠️ PASS WITH WARNINGS
Touch Latency <50ms 35ms avg ✅ PASS

Resource Usage (Typical)

State Core Memory UI Memory Total CPU Usage
Idle (no AA) 125 MB 180 MB 305 MB 5%
Active (AA + media) 285 MB 320 MB 605 MB 30.8%
Peak (AA + 3 extensions) 420 MB 350 MB 770 MB 45%

Performance Monitoring:

  • Real-time metrics collected every 60 seconds
  • Historical data: 24 hours (1440 samples)
  • Alert thresholds: Memory (1536 MB warning, 2048 MB critical), CPU (70% warning, 90% critical)
  • Overhead: <0.01% CPU for monitoring

Validated Platforms:

  • Raspberry Pi 4 (4GB RAM, arm64, Raspberry Pi OS Bookworm)
  • Raspberry Pi 4 (2GB RAM, arm64, optimised build)
  • Ubuntu 22.04 LTS (x86_64, WSL2, development)

Documentation

User Documentation

Developer Documentation

CI/CD Documentation

Complete GitHub Actions CI/CD system for building, testing, and releasing Crankshaft:

Testing Documentation


Contributing

We welcome contributions! Crankshaft is an open-source project under the GPL-3.0 license.

How to Contribute

  1. Fork the repository on GitHub
  2. Create a feature branch: git checkout -b feature/my-amazing-feature
  3. Follow coding standards:
  4. Write tests: Add unit/integration tests for new features
  5. Run pre-commit checks: ./scripts/pre-commit-check.sh
  6. Commit with conventional commits: feat:, fix:, docs:, test:, etc.
  7. Push to your fork: git push origin feature/my-amazing-feature
  8. Open a Pull Request on GitHub

Code Review Process

  • All PRs require one approval from a maintainer
  • CI must pass (build, tests, linting)
  • PRs should address a single concern (no mega-PRs)
  • Include documentation updates for user-facing changes

Reporting Issues

Code of Conduct

This project follows the Contributor Covenant Code of Conduct. Please be respectful and inclusive.


License

Crankshaft is licensed under the GNU General Public License v3.0.

Project: Crankshaft
Copyright (C) 2025 OpenCarDev Team

Crankshaft is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

Crankshaft is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Crankshaft. If not, see <http://www.gnu.org/licenses/>.

Third-Party Licenses:


Community

Get Help

Stay Updated

Project Roadmap

Current Status: Production-ready MVP (v1.0.0)

Upcoming Features (v1.1+):

  • Extension store with web-based marketplace
  • Wireless Android Auto improvements (Wi-Fi Direct)
  • Bluetooth hands-free calling (HFP)
  • Backup camera integration (V4L2)
  • Fleet management API

Long-Term Vision:

  • Multi-user profiles with cloud sync
  • Voice assistant integration (offline-capable)
  • OBD-II diagnostics and vehicle telemetry
  • Automotive-grade Linux (AGL) compliance

Acknowledgments

Crankshaft builds on the excellent work of:

Special thanks to all contributors who have helped make Crankshaft possible! 🚀


Ready to get started? Check out the Quick Start Guide or explore the documentation.

Check formatting

bash scripts/lint.sh

Run tests

bash scripts/run_tests.sh

Build package

cd build && cpack -G DEB


## Features

- ✅ EventBus with thread-safe pub/sub
- ✅ WebSocket communication (Core ↔ UI)
- ✅ JSON message protocol
- ✅ Theme system (light/dark mode)
- ✅ Internationalisation (en-GB, de-DE)
- ✅ Material Design Icons
- ✅ Unit and integration tests
- ✅ CI/CD pipeline (multi-arch DEB builds, SBOM generation)
- ✅ About page with acknowledgements, SBOM and changelog links

## Recent Enhancements

- Multi-architecture CI/CD workflows (amd64, arm64, armhf) producing DEB packages
- Automated CycloneDX SBOM generation published with builds/releases
- About page enhancements with acknowledgements and external links
- New Settings UI components (link/header) for richer About content
- Changelog generation workflow and documented changelog in `docs/CHANGELOG.md`

## Documentation

- [Architecture](docs/ARCHITECTURE.md)
- [WebSocket API](docs/API.md)
- [Development Guide](docs/DEVELOPMENT.md)
- [Changelog](docs/CHANGELOG.md)
- AASDK Modern Logger (verbose USB/AOAP debugging): `external/aasdk/MODERN_LOGGER.md`

## License

GPL v3 - See LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •