ospp / protocol
PHP SDK for the OSPP (Open Self-Service Point Protocol) — enums, envelope, crypto, state machines
v0.38.0
2026-09-10 18:13 UTC
Requires
- php: ^8.3
- ext-gmp: *
- ext-json: *
- ext-openssl: *
- ext-sodium: *
- paragonie/ecc: ^2.5
Requires (Dev)
- brianium/paratest: ^7.8
- opis/json-schema: ^2.3
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.0
Suggests
- opis/json-schema: Required for payload schema validation (^2.3)
Provides
None
Conflicts
None
Replaces
None
- dev-main
- v0.38.0
- v0.37.2
- v0.37.1
- v0.37.0
- v0.36.5
- v0.36.4
- v0.36.3
- v0.36.2
- v0.36.1
- v0.36.0
- v0.35.0
- v0.34.0
- v0.33.0
- v0.32.1
- v0.32.0
- v0.31.0
- v0.30.0
- v0.29.0
- v0.28.0
- v0.27.0
- v0.26.0
- v0.25.0
- v0.24.1
- v0.23.0
- v0.22.0
- v0.20.0
- v0.19.0
- v0.18.0
- v0.17.0
- v0.16.0
- v0.15.0
- v0.14.0
- v0.13.0
- v0.12.0
- v0.11.0
- v0.10.0
- v0.9.0
- v0.8.4
- v0.8.3
- v0.8.2
- v0.8.1
- v0.8.0
- v0.7.0
- v0.6.2
- v0.6.1
- v0.6.0
- v0.5.7
- v0.5.6
- v0.5.5
- v0.5.4
- v0.5.3
- v0.5.2
- v0.5.1
- v0.5.0
- v0.4.3
- v0.4.2
- v0.4.1
- v0.4.0
- v0.3.2
- v0.3.1
- v0.3.0
- v0.2.1
- v0.2.0
- v0.1.0
This package is auto-updated.
Last update: 2026-09-10 18:14:08 UTC
README
PHP SDK for the Open Self-Service Point Protocol (OSPP) — a communication protocol for self-service station management systems.
This package provides the shared protocol layer used by CSMS servers, station simulators, and testing tools.
Requirements
- PHP 8.3+
- ext-json
- ext-openssl (optional — required only for ECDSA offline pass signing)
Installation
composer require ospp/protocol For private repositories, add the VCS source first: { "repositories": [ { "type": "vcs", "url": "git@github.com:ospp-org/ospp-sdk-php.git" } ] } What's Included ┌──────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Module │ Description │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ Enums │ MessageType, SessionSource, BayStatus, SessionStatus, Severity, SigningMode, OsppErrorCode (119 codes), │ │ │ FirmwareUpdateStatus, DiagnosticsStatus, ReservationStatus, BootNotificationStatus, BootReason, │ │ │ NetworkConnectionType, TransactionEventStatus, ChangeConfigResultStatus, DataTransferStatus, │ │ │ TriggerMessageStatus, CertificateType, ResetType, SecurityEventType, StationConnectivity, │ │ │ BleServiceStatus, PricingType, LogLevel, SessionEndReason, ConfigurationKey (28 keys with metadata) │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ State │ Transition tables for Station (6 states), Bay (7 states), Session (6 states), Firmware (10 states), │ │ Machines │ Diagnostics (5 states), Reservation (5 states) │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ Envelope │ MessageEnvelope, MessageBuilder — wire-format message construction with correlation support │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ Crypto │ HMAC-SHA256 message signing (MacSigner), ECDSA P-256 offline pass signing, canonical JSON serialization, │ │ │ MessageSigningRegistry (3 structural signing exemptions), SessionProofCalculator (BLE session proof) │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ Value │ MessageId (UUID v4), ProtocolVersion (semver) │ │ Objects │ │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ Actions │ OsppAction — all 30 protocol actions (27 MQTT + 3 API-only) with validation │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ JSON │ 86 schema files (ble, common, mqtt, the root) accessible via SchemaPath::directory() │ │ Schemas │ │ └──────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ Quick Start Build and sign a message use Ospp\Protocol\Envelope\MessageBuilder; use Ospp\Protocol\Crypto\MacSigner; $envelope = MessageBuilder::request('StartService') ->withPayload(['bayId' => 'bay-1', 'userId' => 'user-123']) ->build(); $signer = new MacSigner($sessionKey); $signed = $envelope->withMac($signer->sign($envelope->payload)); $json = $signed->toJson(); Check state transitions use Ospp\Protocol\Enums\SessionStatus; use Ospp\Protocol\StateMachines\SessionTransitions; $sessions = new SessionTransitions(); $allowed = $sessions->canTransition(SessionStatus::PENDING, SessionStatus::AUTHORIZED); // true $timeout = $sessions->getTimeout(SessionStatus::ACTIVE); // 3600 Wire format conversion use Ospp\Protocol\Enums\BayStatus; $status = BayStatus::fromOspp('Available'); // BayStatus::AVAILABLE $wire = BayStatus::OCCUPIED->toOspp(); // 'Occupied' Access JSON Schemas use Ospp\Protocol\SchemaPath; $schemasDir = SchemaPath::directory(); $bootSchema = json_decode(file_get_contents($schemasDir . '/mqtt/boot-notification-request.schema.json'), true); Architecture - Zero external dependencies — only PHP extensions (json, openssl) - Pure PHP 8.3 — readonly classes, enums, match expressions, named arguments - Immutable — all DTOs and value objects are final readonly - Framework-agnostic — no Laravel, Symfony, or other framework dependency - PSR-4 autoloading — Ospp\Protocol\ namespace Testing composer install vendor/bin/phpunit 4 test suites: ┌─────────────┬───────────────────────────────────────┐ │ Suite │ Purpose │ ├─────────────┼───────────────────────────────────────┤ │ Unit │ Individual class behavior │ ├─────────────┼───────────────────────────────────────┤ │ Regression │ Pins previously found bugs │ ├─────────────┼───────────────────────────────────────┤ │ Contract │ Behavioral alignment with CSMS server │ ├─────────────┼───────────────────────────────────────┤ │ Integration │ Cross-component workflows │ └─────────────┴───────────────────────────────────────┘ The per-suite test counts are deliberately not printed here. They changed on every commit and nothing compared them, so they rotted: this table read 478/10/153/27 against an actual 482/10/776/26, and the total said 668 against 1294. A number that must be re-derived by hand on every push is not documentation, it is a second place to be wrong. Static analysis: vendor/bin/phpstan analyse --level=9 src/ License MIT