Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arm failsafe on PASE establishment #1563

Merged
merged 3 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The main work (all changes without a GitHub username in brackets in the below li

- @matter/node
- Enhancement: Matter protocol initialization now runs independently of and after behavior initialization, giving behaviors more flexibility in participating in protocol setup
- Enhancement: Each new PASE session now automatically arms the failsafe timer for 60s as required by specs
- Fix: Fixes withBehaviors() method on endpoints

- @matter/nodejs-ble
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { AdministratorCommissioning } from "#clusters/administrator-commissionin
import { GeneralCommissioning } from "#clusters/general-commissioning";
import { Logger, MatterFlowError } from "#general";
import { ServerNode } from "#node/ServerNode.js";
import { assertSecureSession, DeviceCommissioner, FabricManager, SessionManager } from "#protocol";
import { assertSecureSession, DeviceCommissioner, FabricManager, SecureSession, SessionManager } from "#protocol";
import { GeneralCommissioningBehavior } from "./GeneralCommissioningBehavior.js";
import { ServerNodeFailsafeContext } from "./ServerNodeFailsafeContext.js";

Expand Down Expand Up @@ -39,10 +39,25 @@ export class GeneralCommissioningServer extends GeneralCommissioningBehavior {
}

this.state.breadcrumb = 0;

const sessionManager = this.env.get(SessionManager);
this.reactTo(sessionManager.sessions.added, this.#handleAddedPaseSessions);
}

/** As required by Commissioning Flows any new PASE session needs to arm the failsafe for 60s. */
async #handleAddedPaseSessions(session: SecureSession) {
if (!session.isPase) {
return;
}
logger.debug(`New PASE session added: ${session.id}. Arming Failsafe for 60s.`);
await this.#armFailSafe({ breadcrumb: this.state.breadcrumb, expiryLengthSeconds: 60 }, session);
}

override async armFailSafe({ breadcrumb, expiryLengthSeconds }: GeneralCommissioning.ArmFailSafeRequest) {
assertSecureSession(this.session, "armFailSafe can only be called on a secure session");
async #armFailSafe(
{ breadcrumb, expiryLengthSeconds }: GeneralCommissioning.ArmFailSafeRequest,
session: SecureSession,
) {
assertSecureSession(session, "armFailSafe can only be called on a secure session");
const commissioner = this.env.get(DeviceCommissioner);

try {
Expand All @@ -55,13 +70,13 @@ export class GeneralCommissioningServer extends GeneralCommissioningBehavior {
!commissioner.isFailsafeArmed &&
this.agent.get(AdministratorCommissioningServer).state.windowStatus !==
AdministratorCommissioning.CommissioningWindowStatus.WindowNotOpen &&
!this.session.isPase
!session.isPase
) {
throw new MatterFlowError("Failed to arm failsafe using CASE while commissioning window is opened.");
}

if (commissioner.isFailsafeArmed) {
await commissioner.failsafeContext.extend(this.session.fabric, expiryLengthSeconds);
await commissioner.failsafeContext.extend(session.fabric, expiryLengthSeconds);
} else {
// If ExpiryLengthSeconds is 0 and the fail-safe timer was not armed, then this command invocation SHALL lead
// to a success response with no side effect against the fail-safe context.
Expand All @@ -73,7 +88,7 @@ export class GeneralCommissioningServer extends GeneralCommissioningBehavior {
sessions: this.env.get(SessionManager),
expiryLengthSeconds,
maxCumulativeFailsafeSeconds: this.state.basicCommissioningInfo.maxCumulativeFailsafeSeconds,
associatedFabric: this.session.fabric,
associatedFabric: session.fabric,
}),
);
}
Expand All @@ -95,6 +110,10 @@ export class GeneralCommissioningServer extends GeneralCommissioningBehavior {
return SuccessResponse;
}

override armFailSafe(request: GeneralCommissioning.ArmFailSafeRequest) {
return this.#armFailSafe(request, this.session);
}

override async setRegulatoryConfig({
breadcrumb,
newRegulatoryConfig,
Expand Down
Loading