Repository navigation
0.9.0
Changes since 0.8.5.
Highlights
- OCP.2 (AES70-4, JSON) on controller and device, over WebSocket and datagrams (including Network.framework). Parameter and event-data names follow the AES70-2A model and are checked against it; events reach a subscriber already parsed, and can be decoded on the client.
- Connection Management 4: controller and device classes, shared helpers (typed blobs, MAC addresses, counter sets), and the Milan (AES70-22), AES67 and Dante adaptations, following the 2026-09-16 and 2026-09-19 AES70-21 drafts.
- Methods declared once:
@OcaMethod/@OcaDeviceMethodgenerate one method descriptor that drives the client'sinvokeand the device's dispatch. Every class is converted, with the model's names, and guarded by golden statuses, a descriptor sweep and a check of the model's spelling.
Device
- Notifications raised in one scope are sent together, fanned out to controllers concurrently, and delivered only to controllers subscribed to that event; event parameters are encoded only when someone will receive them, once per controller.
- Setting a device property to the value it already has no longer notifies.
- Every controller's subscriptions are kept in the subscription manager.
- A notification's recipient can read its event and event data, and a property change's property ID, without decoding the value (SPI).
- Datasets: storage providers can cap a dataset's size and total storage; SQLite datasets are listed without loading their contents;
FindDatasetsRecursiveis answered; a block on a device without dataset storage answers dataset queries with no datasets. - A command with too few or malformed parameters is answered with its status, not a decoding failure.
- A group's lock is checked before the members a command names are resolved.
ClearResetCauseand the Device Reset message are implemented.- The device manager's
Managerslists every registered manager; default object roles have no spaces. - A device property belongs to the class its ID names, not to its depth in the lineage; a vector property is described with both its property IDs; the value type is
valueType. - Other packages can enumerate a device object's properties, tell the device a controller has gone, and register, browse and resolve DNS-SD services of any type.
Controller
OcaMediaClock3.setCurrentRate(rate:)sets a media clock's rate and keeps its time source.- Connection broker: a client can choose how each device's connection is made, and the default is public; device opens are single-flight;
resetBrowsing; a service is resolved before it is added and given up on after 5 s; each service a browser finds is handled in its own task; DNS-SD removals are a hint, not a fact. - Connecting does not block, so one dead candidate cannot use up the budget; IP literals resolve numerically, so NAT64 cannot rewrite them; hostnames resolve on Windows.
- Requests time out on one timer per connection.
- The well-known proxies go through the object registry, and the controller classes the device registry knows are registered.
Transport and protocol
- The OCP.1 Codable coder is rewritten; PDUs are encoded in one pass into exact-size
Data. - Framing and lifecycle hardening across stream, datagram, WebSocket, CFSocket, OpenSSL and Mach transports: writes serialised per connection, one PDU reader per connection, read watchdogs, stale socket files unlinked before binding, empty datagrams ignored.
- WebSocket: the advertised path is honoured; an upgrade naming only control protocols the path does not serve is refused; an endpoint can serve other routes beside its control protocols; AES70-3 §8.4.3.4 is followed.
- Several messages for a packet transport are divided into PDUs that fit.
- Non-finite numbers are represented in JSON as strings.
- TXT records are registered with
txtversandprotoversfirst.
Fixes
OcaMatrix: real size bounds, all six values ofGetSize, locking as AES70-2 specifies,SetCurrentXYkeeps the prior lock state,currentMembersis a property.OcaFilterArbitraryCurvesends its transfer function as three parameters;OcaStringSensorhas the AES70-2 shape;OcaTemperatureSensor's reading andOcaMediaTransportNetwork's alignment level and gain are bounded.- 2D arrays are emitted and indexed in storage order.
- A malformed MAC address is rejected instead of losing octets.
- The AES70-2024
busystatus is added. - A Swift SIL optimiser miscompile is avoided by casting decoder metatypes out of line.
- Darwin: the Mach listener port is destroyed when the endpoint stops; SwiftOCAUI and Network.framework isolation warnings are cleaned up.
Breaking changes
- Dual-protocol types are
Oca, notOcp1:Ocp1Parameters→OcaParameters; the connection, endpoint and controller typesOcp1…→Oca…;Ocp1MessageBatcher→OcaMessageBatcher. Ocp1Error.notImplementedis removed in favour of the.notImplementedstatus.OcaClassID(parent:_:)takes the parent first; a proprietary class ID's authority is not a level indefLevel.OcaIntervalis inclusive.- Parameter records are renamed after the AES70-2A model.
- Classes declare their methods with
@OcaMethod/@OcaDeviceMethod; subclasses that override method handling should use the method tables. - The provisional Dante application adaptation data is replaced by the drafts' types.
- Requires Swift 6.3 or later (IORingSwift 2.0.0), upstream sideeffect-io AsyncExtensions 0.7 instead of the fork, and swift-binary-parsing 0.0.2 (which still pins swift-syntax 602).
Tooling
OCAPerfBenchcompares OCP.1 and OCP.2.ocp2-nc.shdumps a device's whole hierarchy.- The Xcode project builds only the OCABrowser app, with the libraries from the package.