Merge branch 'feature/cameras' into main - #259
Merged
Merged
Conversation
Adds proposal, design, specs, and tasks for the SBMD v4 runtime migration from YAML+mapper drivers to JavaScript handler-based drivers. Capabilities: - sbmd-v4-runtime: core runtime (eval, registration, dispatch, result builder) - sbmd-v4-light-driver: light driver as proof of life - observability-metrics: lightweight metric instruments with JSON dump - sbmd-system: factory and driver changes (modified) - sbmd-script-execution-limits: overall timeout, max deferral depth (modified)
- Move all .sbmd v3 spec files to specs/v3-pending/ - Skip non-light integration tests (pending v4 conversion) - Make SBMD schema validation conditional on spec files existing - Point sbmdParserTest at v3-pending/ directory - Implement SbmdUtils.result() mutable builder in sbmd-utils.js: - dataModel.updateResource() (2/3/4-arg), dataModel.setMetadata() - storage.setPersistentData(), storage.setTransientData() - device.sendCommand(), device.writeAttribute() - device.requestCommand(), device.readAttribute() (deferred terminals) - log(), success(), error() - Terminal sealing prevents post-terminal operations - Add 23 ResultBuilderTest unit tests (C++ harness via mquickjs) - All 300 unit tests pass
- Add SbmdV4Registration.h — C++ data structures for v4 driver registrations:
SbmdV4Alias, SbmdV4Supplements, SbmdV4ResourceHandler, SbmdV4Resource,
SbmdV4Endpoint, SbmdV4DeviceHandler, SbmdV4Registration
- Add SbmdV4Loader.h/.cpp — two-pass .sbmd.js file evaluation:
- InjectCaptureFunction: sets up SbmdDriver() and __sbmd_registration
- ExtractConstants: text-scans for constants: block, brace-matches,
evaluates as object literal, produces name→value pairs
- LoadDriver: prepends var preamble, IIFE-wraps, evaluates, extracts
registration metadata + handler JSValues
- Reset __sbmd_registration on error paths (prevents cross-driver leaks)
- Add 23 SbmdV4LoaderTest unit tests covering:
- Constants extraction (basic, hex, booleans, strings, empty, non-primitive rejection)
- Full driver loading (metadata, aliases, endpoints, resources, handlers)
- Error cases (missing name, double SbmdDriver call, no SbmdDriver call)
- Cross-driver isolation via IIFE wrapping
- Note: mquickjs does not support computed property names ([expr]:)
in object literals — drivers must use string literal keys
- All 323 unit tests pass
Add SbmdV4ResultExecutor::Parse() which walks the {ops, terminal} JSValue
returned by v4 handlers and extracts it into typed C++ structures:
- ResultOp variants: UpdateResource, SetMetadata, SetPersistentData,
SetTransientData, Log
- ResultTerminal variants: Success, Error, SendCommand, WriteAttribute,
RequestCommand, ReadAttribute
The parser extracts options (endpointId, timedInvokeTimeoutMs) from the
nested options object, keeps TLV payloads as base64 strings for later
decoding by the execution layer, and captures deferred handler JSValues
(onResponse/onError) for requestCommand/readAttribute terminals.
Unknown op types are skipped with a warning; unknown terminal types fail
the parse.
22 new tests covering all op types, terminal types, options parsing,
deferred handler extraction, operation ordering, and edge cases.
345/345 tests passing.
…roup 5) Add SbmdV4Driver class that manages the v4 driver lifecycle: - Metadata-only (inactive): registration data always available, handlers not GC-rooted. Source text retained for re-evaluation. - Active: re-evaluates .sbmd.js file to get fresh handler JSValues, GC-roots them via JS_AddGCRef with stable std::list<JSGCRef> storage. Handlers are callable across GC cycles. - Deactivate: releases all GC roots via JS_DeleteGCRef, resets handler JSValues to JS_UNDEFINED. 13 new tests: initial state, activation, handler invocation after activation, double activate/deactivate safety, deactivation clears handlers, metadata preserved, re-activation, minimal driver with no handlers. 358/358 tests passing.
… Group 6) Add SbmdV4DispatchTable that maps incoming Matter reports to handlers: - Resolves alias names to (clusterId, elementId) dispatch keys - Supports three priority levels: Specific (single alias), Multi (multiple aliases), Wildcard (no element ID — matches any in cluster) - Lookup returns all matching handlers in priority order - Separate tables for attribute, event, and command handlers Integrate dispatch tables into SbmdV4Driver: - Built automatically during Activate() from registration aliases - Cleared during Deactivate() - Accessible via GetAttributeDispatch/GetEventDispatch/GetCommandDispatch Fix handler declaration format in driver tests to use object form (matching the loader's expected format). 16 new dispatch tests: empty/single/multi/wildcard lookup, priority ordering (all three levels), unknown alias handling, event/command dispatch, clear, multiple handlers per key, plus 3 integration tests with the driver lifecycle. 374/374 tests passing.
…erDeviceDriver Task Group 9: Update SpecBasedMatterDeviceDriver for v4 runtime. SbmdV4HandlerInvoker (new): - BuildAttributeArgs/BuildResourceArgs: construct JS args objects - InvokeHandler: call JS handler via mquickjs, parse result chain - ExecuteOps: execute non-terminal ops (updateResource, setMetadata, log) SpecBasedMatterDeviceDriver changes: - New v4 constructor taking SbmdV4Driver* (non-owning) - All metadata methods dispatch to v4 registration when IsV4() - AddDevice: v4 path sets V4AttributeCallback, checks prerequisites - DoRegisterResources: v4 path iterates registration endpoints/resources - DoRead/Write/ExecuteResource: v4 path uses HandleV4ResourceOp - DoSynchronizeDevice: v4 path seeds via v4 seed handlers - HandleV4AttributeReport: dispatches attribute changes through tables - ExecuteV4Terminal: handles sendCommand/writeAttribute terminals - CheckPrerequisitesV4: evaluates v4 resource prerequisites MatterDevice changes: - Added V4AttributeCallback type and SetV4AttributeCallback() - CacheCallback::OnAttributeChanged delegates to v4 callback when set - Added WriteAttributeFromTlv() for v4 writeAttribute terminal - Added friend class SpecBasedMatterDeviceDriver for access Tests: 15 new handler invoker tests, 389/389 total passing.
Task Group 10: Update SbmdFactory for v4 runtime. SbmdFactory changes: - Split RegisterDriversFromDirectory into RegisterV3DriversFromDirectory (for .sbmd files) and RegisterV4DriversFromDirectory (for .sbmd.js files) - V4 loading pipeline: read file → SbmdV4Loader::LoadDriver → create SbmdV4Driver → Activate → create SpecBasedMatterDeviceDriver(v4) → register with MatterDriverFactory - Factory owns SbmdV4Driver instances (stored in v4Drivers vector) to ensure they outlive SpecBasedMatterDeviceDriver wrappers - V4 drivers are activated immediately at startup (all drivers active) - File discovery uses double extension check: .js extension + .sbmd stem Also covers deferred tasks 5.4 (factory integration) and 5.5 (activation at startup — simplified to activate-all for now). Tests: 4 new factory tests (file loading, driver activation, file discovery pattern, nonexistent directory). 393/393 total passing.
Task Group 12: Light Driver Conversion light.sbmd.js (new): - Complete v4 light driver with constants block for all cluster/attribute/ command/resource IDs - 13 supported device types matching v3 driver - Endpoint 1 with isOn (seed+write) and currentLevel (optional, seed+write) - Attribute handlers for OnOff and CurrentLevel with TLV decoding - Write handlers: isOn sends On/Off commands, currentLevel sends MoveToLevelWithOnOff with percent-to-level conversion SbmdFactory runtime initialization: - Added mquickjs runtime initialization (Initialize + LoadBundle + InjectCaptureFunction) in RegisterV4DriversFromDirectory - Fixed deadlock: LoadBundle internally takes the JS mutex on error paths, so callers must not hold it across the call - Added v4RuntimeReady flag to avoid redundant initialization SpecBasedMatterDeviceDriver fixes: - Fixed TLV extraction in HandleV4AttributeReport: use TLVWriter:: CopyElement instead of GetRemainingLength() (returns 0 for cache data) - Fixed CheckPrerequisitesV4: use strtoul instead of std::stoul to avoid ASAN __cxa_throw CHECK failure in ASAN-preloaded builds CMake: - Added .sbmd.js file installation alongside .sbmd files Tests: 393/393 unit tests passing. 3/3 light integration tests passing.
Convert all v3 YAML-based SBMD drivers to v4 JavaScript handler format: - temperature-sensor, humidity-sensor, contact-sensor, occupancy-sensor - water-leak-detector, air-quality-sensor, door-lock, thermostat - ikea-timmerflotte (vendor-specific multi-endpoint driver) Fix caching policy inversion in SpecBasedMatterDeviceDriver: resources without read handlers now use CACHING_POLICY_ALWAYS (subscription-driven), resources with read handlers use CACHING_POLICY_NEVER (driver-called). Add read handler fallback that returns cached value when no JS handler exists (safety net for CACHING_POLICY_ALWAYS resources). Fix multi-endpoint resource routing in ikea-timmerflotte: humidity handler uses explicit endpoint '1' in updateResource since the humidity cluster lives on Matter endpoint 2 but the resource is registered on endpoint 1. Remove pytest skip markers from 6 integration test files and fix test ordering in ikea_timmerflotte_test.py (register listeners before commissioning). All 393 unit tests pass. Integration tests verified: - light: 3/3, temperature: 2/2, humidity: 2/2 - thermostat: 8/8, thermostat_with_fan: 21/21, door_lock: 7/7 - ikea_timmerflotte: 4/4
Delete v3 SBMD parser (SbmdParser.h, SbmdParser.cpp) and its unit test (sbmdParserTest.cpp). All drivers now use v4 JavaScript format. Delete v3-pending/ staging directory containing all 10 original .sbmd YAML driver files, replaced by .sbmd.js equivalents in specs/. Delete schema/ directory (v2 and v3 JSON schemas for YAML validation). Remove v3 SbmdUtils.Response helpers (value, error, invoke, write) from sbmd-utils.js — v4 drivers use SbmdUtils.result() builder instead. Remove RegisterV3DriversFromDirectory from SbmdFactory and its header declaration. Consolidate directory validation into RegisterV4Drivers. Remove yaml-cpp dependency from core/CMakeLists.txt (was only used by SbmdParser). Remove SBMD schema validation build target and .sbmd file install target. SbmdSpec.h, ScriptResult.h/.cpp, and ScriptResultTest.cpp are retained as they are shared infrastructure used by the v4 runtime. 392 unit tests pass (1 removed: sbmdParserTest). Integration smoke test verified.
- Rename all SbmdV4* files/classes/methods to Sbmd* (17 file renames) - Remove all v3/v4 version prefixes from symbols, comments, and logs - Remove duplicate v3 code paths from SpecBasedMatterDeviceDriver - Rename SbmdSpec.h types to SbmdSpec* prefix to avoid collision - Update unit tests to use SbmdRegistration types directly - Delete docs/SBMD-v3-legacy.md - Clean SBMD.md title and references 392/392 unit tests pass.
Remove the entire v3 script-based SBMD runtime:
Source files deleted:
- SbmdScript.h, SbmdSpec.h — v3 spec/script interfaces
- ScriptResult.h/.cpp — v3 result handling
- quickjs/SbmdScriptImpl.h/.cpp — QuickJS v3 engine
- mquickjs/SbmdScriptImpl.h/.cpp — mQuickJS v3 engine
MatterDevice.h/cpp changes:
- Remove all Bind*Info() methods and binding maps
- Remove HandleResource{Read,Write,Execute}() v3 paths
- Remove ReadSeedValueFromAttribute/SeedResourceFromAttribute
- Remove v3 script-based OnAttributeChanged/OnEventData paths
- Remove v3 command response mapping (MapCommandExecuteResponse)
- Update SendCommandFromTlv to take direct fields instead of SbmdCommand
- Add cachedClusterFeatureMaps member with accessor
Test files deleted:
- SbmdScriptTest.cpp (2093 lines) — v3 script engine tests
- ScriptResultTest.cpp (452 lines) — v3 result tests
- MatterDeviceTest.cpp (206 lines) — v3 event tests
Test files updated:
- MatterDeviceTestHelpers.h — remove MockSbmdScript, v3 binding helpers
- MatterDeviceEndpointMapTest.cpp — remove OnAttributeChangedFanOutTest
- CMakeLists.txt — remove deleted test targets
256/256 unit tests pass.
Implement requestCommand and readAttribute deferred terminals that park resource operations and resume them when device responses arrive. MatterDevice changes: - Add SendCommandWithCallbacks() for deferred command invocation - Extend CommandContext with deferred onResponse/onError callbacks - Update OnResponse/OnError/OnDone to route through deferred callbacks SpecBasedMatterDeviceDriver changes: - Add PendingOperation struct with GC-rooted handlers, match criteria, overall deadline, and deferral depth counter - Implement ExecuteRequestCommand() — sends command, parks promise, registers pending operation with deferred callbacks - Implement ExecuteReadAttribute() — reads from cache, calls onResponse handler, continues chain - Implement HandleDeferredCommandResponse() — encodes response TLV as base64, invokes onResponse handler, continues chain - Implement HandleDeferredCommandError() — invokes onError handler - Implement ContinueDeferredChain() — handles re-arming (new requestCommand/readAttribute), immediate terminals (success/error/ sendCommand/writeAttribute), depth and deadline enforcement - Implement CompletePendingOperation() and ReleasePendingGcRoots() SbmdHandlerInvoker changes: - Add BuildCommandResponseArgs() for deferred command responses - Add BuildAttributeReadResponseArgs() for deferred attribute reads - Add BuildDeferredErrorArgs() for timeout/error callbacks Tests (9 new, 265/265 total): - BuildCommandResponseArgs with data and null data - BuildAttributeReadResponseArgs - BuildDeferredErrorArgs (timeout and commandFailed) - InvokeDeferredOnResponseHandler end-to-end - InvokeDeferredOnErrorHandler end-to-end - InvokeDeferredOnResponse returning requestCommand (chaining) - InvokeDeferredReadAttributeResponse end-to-end
…TG6.2-6.3) Add supplements support that pre-fetches declared attribute and resource values before calling handler functions, delivering them as args.supplements.attributes and args.supplements.resources. SbmdHandlerInvoker changes: - Add AttributeSupplementFetcher and ResourceSupplementFetcher callback types for testable data fetching - Add AddSupplements() — builds args.supplements JS object from SbmdSupplements declarations using fetcher callbacks. Empty supplements are a no-op. Missing values are set to null. SpecBasedMatterDeviceDriver changes: - Add MakeAttrFetcher() — resolves alias names via the driver's alias map, reads TLV from MatterDevice data cache, returns base64-encoded values - Add MakeResFetcher() — parses endpoint/resource paths, reads values via deviceServiceGetResourceById() - Wire AddSupplements into all three handler invocation paths: InvokeSeedHandler (resource seed), HandleResourceOp (resource read/write/execute), HandleAttributeReport (attribute report handlers) Unit tests (7 new, 272 total): - AddSupplementsEmpty: no-op when supplements are empty - AddSupplementsAttributesOnly: attribute values keyed by alias name - AddSupplementsResourcesOnly: resource values keyed by path - AddSupplementsBothAttributesAndResources: combined supplements - AddSupplementsMissingValuesAreNull: unfetchable values become null - SupplementsAccessibleFromHandler: end-to-end handler reads supplements - SupplementsNullHandledByHandler: handler null-checks work correctly Also updates tasks.md checkboxes for TG3.2, TG8, TG13, TG14.
All five resources (airQuality, temperature, humidity, co2Concentration, pm25Concentration) are populated by attribute handlers that fire when the device data cache is primed at startup and on every subsequent attribute report. Seed handlers are only needed for event-driven resources that cannot be replayed from the attribute cache. Since these resources are all attribute-driven, the seed handlers were redundant overhead.
Remove seed handlers from contact sensor, door lock, humidity sensor, light, occupancy sensor, temperature sensor, thermostat, and water leak detector SBMD drivers. These resources are all populated by attribute handlers, and those handlers are invoked when the initial device data cache is primed at startup as well as on subsequent attribute reports. Seed handlers are only needed for resources whose state is populated by runtime events and cannot be reconstructed from the attribute cache. This keeps startup initialization efficient by relying on the initial cache processing path and avoids unnecessary placeholder or default resource writes before real attribute values arrive.
Remove 'dynamic' and 'emitEvents' from mode arrays in all .sbmd.js specs since these are now on by default. Authors use 'static' or 'noEvents' to opt out. - ConvertModesToBitmask starts with DYNAMIC|DYNAMIC_CAPABLE|EMIT_EVENTS set and returns std::optional<uint8_t> to reject unsupported modes - Remove redundant mode strings from all 10 driver specs and test fixture - Clean stale v3 reference in docs/SBMD.md and door-lock comment
…ilder extraction
Storage implementation (openspec: sbmd-storage):
- Add persistentData[] and transientData[] to SbmdSupplements struct
- Parse persistentData/transientData arrays in SbmdLoader::ExtractSupplements
- Add PersistentDataFetcher, TransientDataFetcher, TransientDataSetter typedefs
- Extend AddSupplements to build args.supplements.persistentData and
args.supplements.transientData JS objects from fetcher callbacks
- Wire setPersistentData op to deviceServiceSetMetadata
(URI: /devices/{uuid}/metadata/sbmd.{key})
- Implement transient storage as in-memory map with TTL-based lazy expiry
on SpecBasedMatterDeviceDriver (per-device scoping)
- Wire setTransientData op to driver's transient store via TransientDataSetter
- Add ttlSecs (uint32_t) to SetTransientData struct and JS builder
- Remove Sbmd.getPersistentData()/getTransientData() from docs — all storage
reads go through supplements only
updateResource metadata wiring:
- Change JS builder from op.options to op.metadata = JSON.stringify(d)
- Add std::optional<std::string> metadata to UpdateResource struct
- Parse metadata string in SbmdResultExecutor
- In ExecuteOps, parse metadata JSON string to cJSON* and pass to
updateResource() C function for the BCoreResourceUpdatedEvent
Result builder extraction:
- Extract ResultBuilder into separate sbmd-result.js loaded after sbmd-utils.js
- Rename SbmdUtilsLoader to SbmdBundleLoader (loads both JS bundles)
SBMD.md documentation updates:
- Section 4.12: Add persistentData and transientData supplement types
- Section 5.1: Add persistentData and transientData to supplements table
- Section 7.1: Fix updateResource metadata param description
- Section 7.3: Rewrite storage section — reads via supplements, remove
standalone getter functions, document ttlSecs on setTransientData
- Section 8: Fix handleLockAlarms example to use supplements instead of
Sbmd.getPersistentData()
Known doc-vs-code discrepancies documented in tasks.md (items 11-19):
- requestCommand: doc shows 4-arg, code is 5-arg with separate deferred obj
- readAttribute: doc shows 3-arg, code is 4-arg with separate deferred obj
- Response callback: doc says 'handler', code uses 'onResponse'
- setMetadata: doc says 2-arg, code is 4-arg (resource field unused in C++)
- endpointId option undocumented on all device operations
- Several options documented but not implemented (timeoutMs, successValue,
context, passthrough, matterCode)
- Sbmd.Tlv.TYPE and decodeStruct() undocumented
Tests: 154 passing (Sbmd + ResultBuilder)
…lue, and API cleanup Wire context/matterCode through the deferred operation pipeline and clean up the JS and C++ APIs based on doc-vs-code review (tasks 11-19). Deferred handler context: - requestCommand/readAttribute accept 'context' option, forwarded to onResponse/onError handlers as args.handlerContext - Context JSValue is GC-rooted in PendingOperation and released on completion - All BuildCommandResponseArgs, BuildAttributeReadResponseArgs, and BuildDeferredErrorArgs call sites pass context through Error reporting: - BuildDeferredErrorArgs accepts matterCode (int32_t), exposed as args.error.matterCode (number or null) in JS error handlers - Command failure passes CHIP_ERROR code via error.AsInteger() sendCommand successValue: - sendCommand options accept 'successValue' string - On successful send, sets *executeResponse optimistically (same semantics as .success(value)) requestCommand timeoutMs override: - Per-operation timeoutMs overrides driver defaultTimeoutMs and system default for the pending operation deadline API simplification: - requestCommand changed from 5-arg to 4-arg form: payload is optional 3rd arg, options detected via 'var opts = options || payload' pattern - readAttribute changed from 4-arg to 3-arg form (options as 3rd arg) - setMetadata changed from 4-arg to 2-arg form: setMetadata(name, value) - Removed passthrough option from requestCommand (code, docs, specs) - Removed timeoutMs from sendCommand/writeAttribute (deferred to future) - Removed Sbmd.Tlv.decodeStruct() alias (use decode() directly) - Fixed response handler args: args.command -> args.response for command response handlers (unsolicited command handlers keep args.command) - Updated defaultTimeoutMs description to scope to deferred operations only Documentation (SBMD.md): - Updated section 6.2 example with args.response.data and handlerContext usage - Fixed all response handler references (args.command -> args.response) - Removed passthrough from options tables and runtime behavior descriptions - Updated requestCommand/writeAttribute options tables Tests: - Added 9 new unit tests: ParseSendCommandWithSuccessValue, ParseRequestCommandWithContext, ParseReadAttributeWithContext, BuildCommandResponseArgsWithHandlerContext, BuildAttributeReadResponseArgsWithHandlerContext, BuildDeferredErrorArgsWithMatterCode, BuildDeferredErrorArgsMatterCodeNullWhenNotProvided, BuildDeferredErrorArgsWithHandlerContext, InvokeDeferredOnResponseHandlerWithContext - All 163 tests passing
…MD handlers
Add the callback infrastructure and dispatch logic for events and unsolicited
commands, completing the pipeline from Matter SDK callbacks through to SBMD
handler invocation.
Event dispatch (full pipeline):
- Add EventCallback typedef + SetEventCallback() + eventCallback member to
MatterDevice, mirroring the existing AttributeCallback pattern
- Wire MatterDevice::CacheCallback::OnEventData to call eventCallback instead
of being a logging-only stub
- SpecBasedMatterDeviceDriver::AddDevice sets the event callback alongside the
existing attribute callback
- Add HandleEvent() which mirrors HandleAttributeReport: looks up handlers via
GetEventDispatch().Lookup(), base64-encodes TLV, builds args, invokes JS
handlers, and executes result ops
Unsolicited command dispatch:
- Add HandleCommand() to SpecBasedMatterDeviceDriver for dispatching commands
that arrive without a matching pending requestCommand
- HandleCommand receives pre-encoded TLV base64 so it can be called from the
deferred response fallback path (to be wired in a follow-up)
JS args builders (SbmdHandlerInvoker):
- Add BuildEventArgs(): creates args.event = { clusterId, eventId, tlvBase64 }
- Add BuildCommandArgs(): creates args.command = { clusterId, commandId, tlvBase64 }
- Both follow the same pattern as BuildAttributeArgs
Unit tests (6 new, 169 total passing):
- BuildEventArgsHasEventFields, BuildEventArgsEmptyTlv, InvokeEventHandler
- BuildCommandArgsHasCommandFields, BuildCommandArgsEmptyTlv, InvokeCommandHandler
…prehensive tests Add server-side incoming command support via Matter's CommandHandlerInterface, allowing SBMD drivers to handle truly unsolicited commands (as opposed to deferred command responses which already worked via requestCommand). CommandHandlerInterface infrastructure (MatterDevice): - CommandCallback typedef and SetCommandCallback() for routing incoming commands from the Matter SDK to the SBMD dispatch pipeline - IncomingCommandHandler inner class implementing chip::app::CommandHandlerInterface, registered per-cluster with CommandHandlerInterfaceRegistry - RegisterIncomingCommandHandler(clusterId) creates and registers a handler for a specific cluster; UnregisterIncomingCommandHandlers() cleans up all handlers (called from destructor) - InvokeCommand() delegates to commandCallback and responds with Status::Success SbmdDispatchTable (SbmdDispatch.h/cpp): - GetRegisteredClusterIds() returns all unique cluster IDs with at least one handler registered, used to know which clusters need CommandHandlerInterface instances SpecBasedMatterDeviceDriver wiring: - AddDevice now sets commandCallback that base64-encodes TLV and calls HandleCommand(), then iterates GetCommandDispatch().GetRegisteredClusterIds() to register IncomingCommandHandler for each cluster Test infrastructure: - Created testing/resources/sbmd-specs/ for contrived test-only .sbmd.js drivers - Added command-echo.sbmd.js test driver exercising specific, multi-alias, and wildcard command handlers with timeout configuration - Wired test specs directory into integration test environment via semicolon- delimited _sbmd_dirs in base_environment_orchestrator.py - Added SbmdHandlerInvoker.cpp to testSbmdDispatch CMake target (+ C API stubs) Unit tests added (26 new tests, 195 total): - SbmdDispatchTableTest: 5 tests for GetRegisteredClusterIds (empty, specific, wildcard, mixed, cleared-after-clear) - SbmdDispatchDriverTest: 5 tests for command dispatch integration (CommandDispatchBuiltOnActivation, CommandDispatchClearedOnDeactivation, CommandHandlerInvocation with BuildCommandArgs round-trip, CommandWildcardDispatch priority ordering, AllThreeDispatchTables) - SbmdDriverTest: 7 tests for command handler lifecycle and timeout config (CommandHandlerCallableAfterActivation, CommandHandlersUndefinedAfterDeactivation, DefaultTimeoutMsParsedFromMatterBlock, DefaultTimeoutMsAbsentWhenNotSpecified, ReportingIntervalsParsed, HandlerWithTimedInvokeTimeout, HandlerWithDeferredTimeoutAndTimedInvoke, HandlerWithDeferredReadAttributeTimeout) - SbmdLoaderTest: 2 tests for timeout defaults (DefaultTimeoutAbsentWhenNotSpecified, ReportingDefaultsToZeroWhenAbsent) - SbmdResultExecutorTest: 6 tests for timeout parsing permutations (ParseSendCommandTimedInvokeOnly, ParseRequestCommandWithTimedInvoke, ParseRequestCommandNoTimeoutMs, ParseReadAttributeNoTimeoutMs, ParseRequestCommandWithEndpoint, ParseReadAttributeWithEndpoint)
The seed handler for the locked resource was removed in 735d697 under the assumption that RegenerateAttributeReport() would populate the value from the attribute cache at commission time. However, RegenerateAttributeReport() is scheduled asynchronously via PlatformMgr().ScheduleWork() and runs AFTER deviceServiceDeviceFound() returns — which is after the DEVICE_ADDED event has already been emitted. This left the locked resource with a null value at the moment clients first observe it. Restore the seed handler so the locked resource is initialized to 'true' synchronously inside DoRegisterDriverResources, before DEVICE_ADDED fires. The LockState attribute handler continues to keep the resource current via subscription reports after commission. Also fix stale test docstrings that referenced a removed v3 seedFrom mapper mechanism and a nonexistent LockOperation event handler.
Change driverVersion from a semver-style string ('1.0.0') to a plain
uint32_t integer (1) across the entire SBMD system:
- SbmdRegistration.h: std::string → uint32_t
- SbmdLoader.cpp: GetStringProp → GetUint32Prop, update log format
- All 10 production .sbmd.js specs and 1 test spec: '1.0.0' → 1
- All unit test inline driver sources: "1.0" → 1
- Test assertions: string comparison → unsigned integer comparison
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Resolved all conflicts in favor of main (theirs) — main contains the SBMD v4 refactor which supersedes the older implementation on this branch.
…lback (#246) Add a `kLargePayloadWithMRPFallback` transport capability that prefers a TCP session for large payloads (e.g. WebRTC SDP) and transparently falls back to MRP/UDP for peers without TCP support. Use it as the default for all controller connections. - Patch the Matter library: add the capability and its SessionManager/ OperationalSessionSetup handling, default GetConnectedDevice to it, and fall back to UDP (with a log) when the active TCP connection pool is full. - Allow large-payload CommandSender buffers when the session supports them. - Initiate GetConnectedDevice synchronously on the Matter thread in ConnectAndExecute. - Log the GetConnectedDevice error in DeviceDataCache. - Raise CHIP_CONFIG_MAX_ACTIVE_TCP_CONNECTIONS from 4 to 50.
Add a 'volatile' resource mode that disables value caching (CACHING_POLICY_NEVER) so updateResource emits an event on every call, even when the value is unchanged. This supports event-only signaling resources where identical values must each be delivered as distinct events (e.g. repeated 'failed' notifications across sessions), which the default cached behavior would suppress. Wire it through the JSON schema, the script type definitions, and the SBMD driver's caching-policy selection.
Add end-to-end support for a Matter WebRTC camera device driver. - Add the WebRTCTransportRequestor cluster (Offer/Answer/ICECandidates/End commands, CurrentSessions attribute) to the Barton Matter library, defined in barton-library.zap and declared as an external cluster; the generated barton-library.matter is regenerated from the ZAP via the SDK generator. - Configure a WebRTC requestor node and grant commissioned peers CASE/operate access to the requestor cluster via a shared ACL helper (refactored from the OTA-requestor-specific helper). Treat ACL entries with no targets as granting all clusters, per CHIP ACL semantics. - Add the SBMD camera driver spec (camera.sbmd.js) with an abstract camera session endpoint and a WebRTC signaling endpoint (offer/answer/ICE resources and incoming command handlers), using the volatile mode for the event-only webrtcError resource. - Restrict SBMD attribute/event/command handlers to alias binding (remove the inline clusterId form). This is a breaking schema change. - De-version the SBMD schema surface: a single sbmd-spec-schema.json (no version in the filename), the validator renamed validate_sbmd_specs.py, and version history tracked in schema/CHANGELOG.md; schemaVersion is still validated against the schema's expected version. Update the schema, type definitions, specs, and docs. - Add unit tests for the camera WebRTC driver, and extract the shared, driver-agnostic SBMD test harness (SbmdDriverTestBase) used by both the camera and handler-invoker tests.
# Conflicts: # docker/version
InvokeExecuteHandler/InvokeCommandHandler captured a raw JSValue handler and then built args/supplements, which allocate and can relocate the handler under mquickjs's moving GC, leaving the snapshot stale and making JS_Call dispatch through a null pointer (SEGV). Root the handler in a SafeJSValue and pass Get() at the call, mirroring production's Fn() usage.
Add a 'cs' camera stream command to the reference app that acts as the in-container WebRTC peer to a Matter camera and serves the decoded stream. - cameraWebrtcClient: webrtcbin peer (host-only ICE), SDP offer/answer, trickle ICE, H.264 passthrough muxed to fragmented MP4, connectivity watchdog, and a keyframe (RTCP PLI) burst worker to start playback quickly. - cameraMediaServer: a small HTTP server that serves the live fragmented MP4 to a browser via a Media Source Extensions player, replaying a cached init segment to late joiners. - cameraCategory / cameraDeviceSession: drive the Matter WebRTC signaling handshake and route media to a file (file://) or the HTTP server. - Timestamp emitOutput/emitError and drain log/command output on a dedicated thread so the prompt stays intact during blocking commands. - Gate the command behind the BCORE_REFERENCE_CAMERA_SUPPORT CMake option (enabled in the dev Linux platform); add the GStreamer stack to the image and forward the stream port in the devcontainer. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Commit the OpenSpec artifacts for the camera / WebRTC work.
- Archive the `webrtc-endpoint-and-camera-stream-command` and
`camera-session-status-redesign` changes.
- Sync their deltas into the main specs:
- new `camera-session-lifecycle` (abstract endpoint, `stream` returns
`{protocol, entryPoint}`, no `sessionStatus`)
- `webrtc-signaling-endpoint` (five resources incl. `volatile`
`webrtcError`; `End`/async failures emit `webrtcError`; `sessionStatus`
requirement removed)
- `camera-stream-reference-command` (`--out <uri>` record/serve,
passthrough pipeline serving fragmented MP4 to a browser via MSE,
host-only ICE, connectivity timeout, updated build deps)
- `sbmd-v4-runtime` (add the `volatile` resource mode)
# Conflicts: # core/test/CMakeLists.txt # docker/version
The main-merge that introduced SBMD runtime observability added
${SBMD_METRICS_SRC}/${SBMD_OBS_NOOP_SRC} (and BartonCommon::xhConcurrent) to the
other SBMD test targets but missed testSbmdCameraWebrtc, so it failed to link
(undefined MQuickJsRuntimeMetrics::* / observability* symbols).
…256) The ep/webrtc negotiationRole resource is the camera's data model, so it now reports the CAMERA's WebRTC role — offerer when the camera generates the offer (SolicitOffer flow), answerer when it answers the client's offer (ProvideOffer flow) — instead of the role the client must take. An intrinsic cameraIsOfferer() predicate drives both the reported role and the (unchanged) Matter flow selection. The reference app inverts the reported value to choose its own role. The Matter signaling sequence is unchanged. Driver, reference app, the camera unit test (adds NegotiationRoleReportsCameraRole), and the webrtc-signaling- endpoint / camera-stream-reference-command specs are updated to the camera perspective; archives the openspec change.
cleithner-comcast
requested review from
kfundecmcsa,
mkkoch,
rchowdcmcsa and
tleacmcsa
as code owners
August 4, 2026 18:39
Contributor
Author
|
Strategy is merge commit. |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR merges the feature/cameras branch into main, bringing in Matter/WebRTC camera-streaming support (requestor cluster + large-payload transport handling), SBMD schema updates (v5.0), reference-app camera streaming (GStreamer) behind a build flag, plus related CI/devcontainer/Docker and test-harness updates.
Changes:
- Add WebRTC Transport Requestor cluster + camera-stream reference command support (GStreamer) and associated specs/docs.
- Improve Matter transport/session behavior for large payloads (prefer TCP with fallback) and raise TCP connection limits.
- Update SBMD to schema v5.0 (schema file + docs + typings), refactor SBMD unit-test support, and update validation wiring.
Reviewed changes
Copilot reviewed 76 out of 77 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| third_party/matter/barton-library/patches/0003-transport-add-kLargePayloadWithMRPFallback-capabilit.patch | Adds a new transport payload capability and TCP→UDP fallback behavior in upstream Matter patchset. |
| third_party/matter/barton-library/linux/BartonProjectConfig.h.in | Raises active TCP connection cap to match endpoint pool. |
| third_party/matter/barton-library/barton-common/BUILD.gn | Adds external cluster for WebRTC Transport Requestor. |
| third_party/matter/barton-library/barton-common/barton-library.zap | Adds WebRTC Transport Requestor cluster definition to ZAP output. |
| third_party/matter/barton-library/barton-common/barton-library.matter | Extends Matter data model (WebRTC cluster definitions and endpoint wiring). |
| testing/resources/sbmd-specs/deferred-command-test.sbmd.js | Minor JS cleanup in SBMD test driver (ternary formatting). |
| scripts/ci/validate_sbmd_v4_specs.py | Removes old v4-only SBMD validator script. |
| reference/src/cameraWebrtcClient.h | Adds GStreamer-backed WebRTC client API for camera streaming. |
| reference/src/cameraMediaServer.h | Adds minimal HTTP media server interface for streaming fragmented MP4. |
| reference/src/cameraDeviceSession.h | Adds camera session orchestration API over Barton resources. |
| reference/src/cameraDeviceSession.c | Implements camera session lifecycle + signaling event handling via BCoreClient. |
| reference/src/cameraCategory.h | Adds camera command category interface for reference app. |
| reference/src/barton-core-reference-io.c | Improves prompt/log interleaving with a dedicated drain thread + terminal locking and timestamped output. |
| reference/src/barton-core-reference-app.c | Registers the camera command category behind BCORE_REFERENCE_CAMERA_SUPPORT. |
| reference/CMakeLists.txt | Adds BCORE_REFERENCE_CAMERA_SUPPORT option and links GStreamer/GIO when enabled. |
| openspec/specs/webrtc-signaling-endpoint/spec.md | Adds/updates WebRTC signaling endpoint requirements (camera-perspective role semantics). |
| openspec/specs/sbmd-v4-runtime/spec.md | Specifies volatile mode semantics for SBMD runtime (unconditional event emission). |
| openspec/specs/camera-stream-reference-command/spec.md | Specifies the cameraStream/cs reference command behavior and lifecycle. |
| openspec/specs/camera-session-lifecycle/spec.md | Specifies abstract camera endpoint lifecycle and stream return shape {protocol, entryPoint}. |
| openspec/changes/archive/2026-08-03-negotiation-role-camera-perspective/tasks.md | Archives implementation tasks for negotiation-role contract inversion. |
| openspec/changes/archive/2026-08-03-negotiation-role-camera-perspective/specs/webrtc-signaling-endpoint/spec.md | Archives delta spec for camera-perspective negotiation role. |
| openspec/changes/archive/2026-08-03-negotiation-role-camera-perspective/specs/camera-stream-reference-command/spec.md | Archives delta spec for reference command role inversion. |
| openspec/changes/archive/2026-08-03-negotiation-role-camera-perspective/proposal.md | Archives proposal for negotiation-role inversion. |
| openspec/changes/archive/2026-08-03-negotiation-role-camera-perspective/design.md | Archives design notes for negotiation-role inversion. |
| openspec/changes/archive/2026-08-03-negotiation-role-camera-perspective/.openspec.yaml | Archives OpenSpec metadata for the change. |
| openspec/changes/archive/2026-07-16-camera-session-status-redesign/tasks.md | Archives tasks for sessionStatus removal + webrtcError + volatile mode. |
| openspec/changes/archive/2026-07-16-camera-session-status-redesign/specs/webrtc-signaling-endpoint/spec.md | Archives delta spec for webrtcError and signaling error delivery. |
| openspec/changes/archive/2026-07-16-camera-session-status-redesign/specs/sbmd-v4-runtime/spec.md | Archives delta spec describing volatile resource mode. |
| openspec/changes/archive/2026-07-16-camera-session-status-redesign/specs/camera-stream-reference-command/spec.md | Archives delta spec updates for the reference streaming command. |
| openspec/changes/archive/2026-07-16-camera-session-status-redesign/specs/camera-session-lifecycle/spec.md | Archives delta spec for camera session lifecycle changes. |
| openspec/changes/archive/2026-07-16-camera-session-status-redesign/proposal.md | Archives proposal for camera session status redesign. |
| openspec/changes/archive/2026-07-16-camera-session-status-redesign/design.md | Archives design notes for sessionStatus removal and error propagation. |
| openspec/changes/archive/2026-07-16-camera-session-status-redesign/.openspec.yaml | Archives OpenSpec metadata for the change. |
| openspec/changes/archive/2026-07-13-webrtc-endpoint-and-camera-stream-command/tasks.md | Archives tasks for initial WebRTC endpoint + camera stream command. |
| openspec/changes/archive/2026-07-13-webrtc-endpoint-and-camera-stream-command/specs/webrtc-signaling-endpoint/spec.md | Archives initial WebRTC endpoint spec delta. |
| openspec/changes/archive/2026-07-13-webrtc-endpoint-and-camera-stream-command/specs/camera-stream-reference-command/spec.md | Archives initial reference command spec delta. |
| openspec/changes/archive/2026-07-13-webrtc-endpoint-and-camera-stream-command/proposal.md | Archives proposal for initial WebRTC endpoint + command. |
| openspec/changes/archive/2026-07-13-webrtc-endpoint-and-camera-stream-command/design.md | Archives design notes for the initial WebRTC endpoint/command work. |
| openspec/changes/archive/2026-07-13-webrtc-endpoint-and-camera-stream-command/.openspec.yaml | Archives OpenSpec metadata for the change. |
| docs/SBMD.md | Updates SBMD documentation to schema v5.0 and “aliases-only” handler binding. |
| docker/version | Bumps docker image version. |
| docker/Dockerfile | Adds GStreamer packages and builds Matter camera sample/controller binaries into the image. |
| core/test/src/SbmdHandlerInvokerTest.cpp | Refactors tests onto shared SBMD test base/harness. |
| core/test/src/SbmdDriverTestSupport.cpp | Adds shared SBMD C-stub recording implementation for tests. |
| core/test/src/SbmdDriverTestBase.h | Adds shared SBMD test fixture utilities and assertion helpers. |
| core/test/CMakeLists.txt | Wires new SBMD camera test and shared SBMD test support source. |
| core/src/subsystems/matter/Matter.h | Refactors ACL helper declarations and formatting. |
| core/src/subsystems/matter/Matter.cpp | Adds cluster-host detection, WebRTC ACL configuration, and related ACL helper refactor. |
| core/src/subsystems/matter/DeviceDataCache.cpp | Improves connection error reporting and forwards subscription-established callback. |
| core/deviceDrivers/matter/sbmd/specs/water-leak-detector.sbmd.js | Updates SBMD driver schemaVersion to 5.0. |
| core/deviceDrivers/matter/sbmd/specs/thermostat.sbmd.js | Updates SBMD driver schemaVersion to 5.0. |
| core/deviceDrivers/matter/sbmd/specs/temperature-sensor.sbmd.js | Updates SBMD driver schemaVersion to 5.0. |
| core/deviceDrivers/matter/sbmd/specs/occupancy-sensor.sbmd.js | Updates SBMD driver schemaVersion to 5.0. |
| core/deviceDrivers/matter/sbmd/specs/light.sbmd.js | Updates SBMD driver schemaVersion to 5.0. |
| core/deviceDrivers/matter/sbmd/specs/ikea-timmerflotte.sbmd.js | Updates SBMD driver schemaVersion to 5.0. |
| core/deviceDrivers/matter/sbmd/specs/humidity-sensor.sbmd.js | Updates SBMD driver schemaVersion to 5.0. |
| core/deviceDrivers/matter/sbmd/specs/door-lock.sbmd.js | Updates SBMD driver schemaVersion to 5.0. |
| core/deviceDrivers/matter/sbmd/specs/contact-sensor.sbmd.js | Updates SBMD driver schemaVersion to 5.0. |
| core/deviceDrivers/matter/sbmd/specs/air-quality-sensor.sbmd.js | Updates SBMD driver schemaVersion to 5.0. |
| core/deviceDrivers/matter/sbmd/SpecBasedMatterDeviceDriver.cpp | Adds support for volatile and accepts default-on modes as no-ops. |
| core/deviceDrivers/matter/sbmd/scriptCommon/sbmd-script.d.ts | Updates typings for schema v5.0 and “aliases-only” handler definitions. |
| core/deviceDrivers/matter/sbmd/schema/sbmd-spec-schema.json | Renames/updates schema to v5.0, adds volatile, and enforces mutually-exclusive mode pairs. |
| core/deviceDrivers/matter/sbmd/schema/CHANGELOG.md | Adds v5.0 changelog entries (schema file naming, aliases-only, volatile, mode constraints). |
| core/deviceDrivers/matter/MatterDeviceDriver.cpp | Makes connection initiation ordering deterministic via RunOnMatterSync. |
| core/deviceDrivers/matter/MatterDevice.cpp | Enables large-payload command sending based on session capabilities and improves TLV error logs. |
| core/CMakeLists.txt | Updates SBMD schema validation target to use the new validator script name. |
| config/cmake/platforms/dev/linux.cmake | Enables camera stream support by default on dev linux platform. |
| api/c/src/barton-core-client.c | Adds observability include (currently duplicated). |
| .github/skills/validate-sbmd/SKILL.md | Updates skill instructions for new validator/schema file names. |
| .devcontainer/devcontainer.json | Forwards camera media server port and sets env for X11 + GStreamer sink selection. |
Time-to-ready in CI lands at ~5.0-5.05s (SBMD driver load is the long pole), so the 5s wait_for_client_to_be_ready timeout flakes. Bump to 10s.
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 77 out of 78 changed files in this pull request and generated no new comments.
Suppressed comments (1)
api/c/src/barton-core-client.c:43
observability/observability.his included twice, which is redundant and can slow compilation / increase include-order brittleness.
#include "icTypes/icLinkedList.h"
#include "observability/observability.h"
#include "icTypes/icLinkedListFuncs.h"
#include "observability/observability.h"
tleacmcsa
approved these changes
Aug 5, 2026
rchowdcmcsa
approved these changes
Aug 5, 2026
kfundecmcsa
approved these changes
Aug 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.