diff --git a/examples/darwin-framework-tool/commands/provider/Commands.h b/examples/darwin-framework-tool/commands/provider/Commands.h index a762ec7862efef..15f2750a528b5d 100644 --- a/examples/darwin-framework-tool/commands/provider/Commands.h +++ b/examples/darwin-framework-tool/commands/provider/Commands.h @@ -7,8 +7,7 @@ void registerClusterOtaSoftwareUpdateProviderInteractive(Commands & commands) commands_list clusterCommands = { make_unique(), // - make_unique(), // - + make_unique(), // }; commands.Register(clusterName, clusterCommands); diff --git a/examples/darwin-framework-tool/commands/provider/OTAProviderDelegate.h b/examples/darwin-framework-tool/commands/provider/OTAProviderDelegate.h index b75ad27ba2a2d9..80ec40be778db4 100644 --- a/examples/darwin-framework-tool/commands/provider/OTAProviderDelegate.h +++ b/examples/darwin-framework-tool/commands/provider/OTAProviderDelegate.h @@ -61,5 +61,9 @@ typedef NS_ENUM(uint8_t, UserConsentState) { @property (strong, nonatomic, nullable) NSNumber * nodeID; @property (nonatomic, readwrite) MTROtaSoftwareUpdateProviderOTAQueryStatus queryImageStatus; @property (nonatomic, readwrite) UserConsentState userConsentState; +@property (nonatomic, readwrite) MTROtaSoftwareUpdateProviderOTAApplyUpdateAction action; +@property (nonatomic, readwrite, nullable) NSNumber * delayedActionTime; +@property (nonatomic, readwrite, nullable) NSNumber * timedInvokeTimeoutMs; +@property (nonatomic, readwrite, nullable) NSNumber * userConsentNeeded; @end diff --git a/examples/darwin-framework-tool/commands/provider/OTAProviderDelegate.mm b/examples/darwin-framework-tool/commands/provider/OTAProviderDelegate.mm index da0b3d462d591b..9c56fad14efafc 100644 --- a/examples/darwin-framework-tool/commands/provider/OTAProviderDelegate.mm +++ b/examples/darwin-framework-tool/commands/provider/OTAProviderDelegate.mm @@ -35,7 +35,12 @@ - (instancetype)init { if (self = [super init]) { _selectedCandidate = [[DeviceSoftwareVersionModel alloc] init]; + _action = MTROtaSoftwareUpdateProviderOTAApplyUpdateActionProceed; _userConsentState = OTAProviderUserUnknown; + _delayedActionTime = nil; + _timedInvokeTimeoutMs = nil; + _userConsentNeeded = nil; + _queryImageStatus = MTROtaSoftwareUpdateProviderOTAQueryStatusNotAvailable; } return self; } @@ -63,35 +68,13 @@ - (void)handleQueryImageForNodeID:(NSNumber * _Nonnull)nodeID } _selectedCandidate.updateToken = [self generateUpdateToken]; + NSLog(@"Query Image Status: %hhu", _queryImageStatus); + _selectedCandidate.status = @(_queryImageStatus); - if (params.requestorCanConsent.integerValue == 1) { - _selectedCandidate.status = @(MTROtaSoftwareUpdateProviderOTAQueryStatusUpdateAvailable); - _selectedCandidate.userConsentNeeded - = (_userConsentState == OTAProviderUserUnknown || _userConsentState == OTAProviderUserDenied) ? @(1) : @(0); + if (params.requestorCanConsent.integerValue == 1 && _userConsentNeeded) { + _selectedCandidate.userConsentNeeded = _userConsentNeeded; NSLog(@"User Consent Needed: %@", _selectedCandidate.userConsentNeeded); - completionHandler(_selectedCandidate, nil); - return; } - - NSLog(@"Requestor cannot obtain user consent. Our State: %hhu", _userConsentState); - switch (_userConsentState) { - case OTAProviderUserGranted: - NSLog(@"User Consent Granted"); - _queryImageStatus = MTROtaSoftwareUpdateProviderOTAQueryStatusUpdateAvailable; - break; - - case OTAProviderUserObtaining: - NSLog(@"User Consent Obtaining"); - _queryImageStatus = MTROtaSoftwareUpdateProviderOTAQueryStatusBusy; - break; - - case OTAProviderUserDenied: - case OTAProviderUserUnknown: - NSLog(@"User Consent Denied or Uknown"); - _queryImageStatus = MTROtaSoftwareUpdateProviderOTAQueryStatusNotAvailable; - break; - } - _selectedCandidate.status = @(_queryImageStatus); completionHandler(_selectedCandidate, nil); } @@ -104,7 +87,14 @@ - (void)handleApplyUpdateRequestForNodeID:(NSNumber * _Nonnull)nodeID { MTROtaSoftwareUpdateProviderClusterApplyUpdateResponseParams * applyUpdateResponseParams = [[MTROtaSoftwareUpdateProviderClusterApplyUpdateResponseParams alloc] init]; - applyUpdateResponseParams.action = @(MTROtaSoftwareUpdateProviderOTAApplyUpdateActionProceed); + applyUpdateResponseParams.action = @(_action); + if (_delayedActionTime) { + applyUpdateResponseParams.delayedActionTime = _delayedActionTime; + } + if (_timedInvokeTimeoutMs) { + applyUpdateResponseParams.timedInvokeTimeoutMs = _timedInvokeTimeoutMs; + } + completionHandler(applyUpdateResponseParams, nil); } diff --git a/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.h b/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.h index f17147c2eb4d45..96aee18ea4e1d5 100644 --- a/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.h +++ b/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.h @@ -28,7 +28,10 @@ class OTASoftwareUpdateBase : public CHIPCommandBridge { { } CHIP_ERROR SetCandidatesFromFilePath(char * _Nonnull filePath); - CHIP_ERROR SetUserConsentStatus(char * _Nonnull status); + CHIP_ERROR SetActionReplyStatus(uint16_t action); + CHIP_ERROR SetReplyStatus(uint16_t status); + CHIP_ERROR SetUserConsentStatus(uint16_t status); + CHIP_ERROR SetUserConsentNeeded(uint16_t status); static constexpr size_t kFilepathBufLen = 256; CHIP_ERROR Run() override; @@ -56,17 +59,31 @@ class OTASoftwareUpdateSetFilePath : public OTASoftwareUpdateBase { char * _Nonnull mOTACandidatesFilePath; }; -class OTASoftwareUpdateSetStatus : public OTASoftwareUpdateBase { +class OTASoftwareUpdateSetParams : public OTASoftwareUpdateBase { public: - OTASoftwareUpdateSetStatus() - : OTASoftwareUpdateBase("set-consent-status") + OTASoftwareUpdateSetParams() + : OTASoftwareUpdateBase("set-reply-params") { - AddArgument("status", &mUserConsentStatus); + AddArgument("action", 0, UINT16_MAX, &mAction); + AddArgument("status", 0, UINT16_MAX, &mStatus); + AddArgument("consent", 0, UINT16_MAX, &mUserConsentStatus); + AddArgument("consentNeeded", 0, UINT16_MAX, &mUserConsentNeeded); + AddArgument("delayedActionTime", 0, UINT64_MAX, &mDelayedActionTime); + AddArgument("timedInvokeTimeoutMs", 0, UINT64_MAX, &mTimedInvokeTimeoutMs); } /////////// CHIPCommandBridge Interface ///////// CHIP_ERROR RunCommand() override; + CHIP_ERROR SetParams(chip::Optional action, chip::Optional status, chip::Optional consent, + chip::Optional userConsentNeeded, chip::Optional delayedActionTime, + chip::Optional timedInvokeTimeoutMs); + private: - char * _Nonnull mUserConsentStatus; + chip::Optional mAction; + chip::Optional mStatus; + chip::Optional mUserConsentStatus; + chip::Optional mUserConsentNeeded; + chip::Optional mDelayedActionTime; + chip::Optional mTimedInvokeTimeoutMs; }; diff --git a/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.mm b/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.mm index 3bc3192b743b69..1c8caa56089ca4 100644 --- a/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.mm +++ b/examples/darwin-framework-tool/commands/provider/OTASoftwareUpdateInteractive.mm @@ -111,13 +111,128 @@ static bool ParseJsonFileAndPopulateCandidates( return error; } -CHIP_ERROR OTASoftwareUpdateSetStatus::RunCommand() +CHIP_ERROR OTASoftwareUpdateSetParams::RunCommand() { - auto error = SetUserConsentStatus(mUserConsentStatus); + auto error = SetParams(mAction, mStatus, mUserConsentStatus, mUserConsentNeeded, mDelayedActionTime, mTimedInvokeTimeoutMs); SetCommandExitStatus(nil); return error; } +CHIP_ERROR OTASoftwareUpdateSetParams::SetParams(chip::Optional action, chip::Optional status, + chip::Optional consent, chip::Optional userConsentNeeded, chip::Optional delayedActionTime, + chip::Optional timedInvokeTimeoutMs) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + if (action.HasValue()) { + error = SetActionReplyStatus(action.Value()); + if (error != CHIP_NO_ERROR) { + return error; + } + } + if (delayedActionTime.HasValue()) { + mOTADelegate.delayedActionTime = @(delayedActionTime.Value()); + } + if (timedInvokeTimeoutMs.HasValue()) { + mOTADelegate.timedInvokeTimeoutMs = @(timedInvokeTimeoutMs.Value()); + } + if (status.HasValue()) { + error = SetReplyStatus(status.Value()); + if (error != CHIP_NO_ERROR) { + return error; + } + } + if (consent.HasValue()) { + error = SetUserConsentStatus(consent.Value()); + if (error != CHIP_NO_ERROR) { + return error; + } + } + if (userConsentNeeded.HasValue()) { + error = SetUserConsentNeeded(userConsentNeeded.Value()); + if (error != CHIP_NO_ERROR) { + return error; + } + } + + return error; +} + +CHIP_ERROR OTASoftwareUpdateBase::SetActionReplyStatus(uint16_t action) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + if (action == 0) { + mOTADelegate.action = MTROtaSoftwareUpdateProviderOTAApplyUpdateActionProceed; + ChipLogDetail(chipTool, "Successfully set action to: MTROtaSoftwareUpdateProviderOTAApplyUpdateActionProceed"); + } else if (action == 1) { + mOTADelegate.action = MTROtaSoftwareUpdateProviderOTAApplyUpdateActionAwaitNextAction; + ChipLogDetail(chipTool, "Successfully set action to: MTROtaSoftwareUpdateProviderOTAApplyUpdateActionAwaitNextAction"); + } else if (action == 2) { + mOTADelegate.action = MTROtaSoftwareUpdateProviderOTAApplyUpdateActionDiscontinue; + ChipLogDetail(chipTool, "Successfully set action to: MTROtaSoftwareUpdateProviderOTAApplyUpdateActionDiscontinue"); + } else { + ChipLogError(chipTool, "Only accepts the following: 0 (Proceed), 1 (Await Next Action), 2 (Discontinue)"); + error = CHIP_ERROR_INTERNAL; + } + return error; +} +CHIP_ERROR OTASoftwareUpdateBase::SetReplyStatus(uint16_t status) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + if (status == 0) { + mOTADelegate.queryImageStatus = MTROtaSoftwareUpdateProviderOTAQueryStatusUpdateAvailable; + ChipLogDetail(chipTool, "Successfully set status to: MTROtaSoftwareUpdateProviderOTAQueryStatusUpdateAvailable"); + } else if (status == 1) { + mOTADelegate.queryImageStatus = MTROtaSoftwareUpdateProviderOTAQueryStatusBusy; + ChipLogDetail(chipTool, "Successfully set status to: MTROtaSoftwareUpdateProviderOTAQueryStatusBusy"); + } else if (status == 2) { + mOTADelegate.queryImageStatus = MTROtaSoftwareUpdateProviderOTAQueryStatusNotAvailable; + ChipLogDetail(chipTool, "Successfully set status to: MTROtaSoftwareUpdateProviderOTAQueryStatusNotAvailable"); + } else if (status == 4) { + mOTADelegate.queryImageStatus = MTROtaSoftwareUpdateProviderOTAQueryStatusDownloadProtocolNotSupported; + ChipLogDetail( + chipTool, "Successfully set status to: MTROtaSoftwareUpdateProviderOTAQueryStatusDownloadProtocolNotSupported"); + } else { + ChipLogError(chipTool, "Only accepts the following: 0 (Available), 1 (Busy), 2 (Not Available), 3 (Not Supported)"); + error = CHIP_ERROR_INTERNAL; + } + return error; +} + +CHIP_ERROR OTASoftwareUpdateBase::SetUserConsentStatus(uint16_t consent) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + if (consent == 0) { + mOTADelegate.userConsentState = OTAProviderUserGranted; + ChipLogDetail(chipTool, "Successfully set User Consent to: OTAProviderUserGranted"); + } else if (consent == 1) { + mOTADelegate.userConsentState = OTAProviderUserObtaining; + ChipLogDetail(chipTool, "Successfully set User Consent to: OTAProviderUserObtaining"); + } else if (consent == 2) { + mOTADelegate.userConsentState = OTAProviderUserDenied; + ChipLogDetail(chipTool, "Successfully set User Consent to: OTAProviderUserDenied"); + } else { + ChipLogError(chipTool, "Only accepts the following: 0 (granted), 1 (obtaining), and 2 (denied)."); + error = CHIP_ERROR_INTERNAL; + } + return error; +} + +CHIP_ERROR OTASoftwareUpdateBase::SetUserConsentNeeded(uint16_t userConsentNeeded) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + if (userConsentNeeded == 0) { + mOTADelegate.userConsentNeeded = @(0); + ChipLogDetail(chipTool, "Successfully set User Consent to: OTAProviderUserGranted"); + } else if (userConsentNeeded == 1) { + mOTADelegate.userConsentNeeded = @(1); + ChipLogDetail(chipTool, "Successfully set User Consent to: OTAProviderUserObtaining"); + } else { + ChipLogError(chipTool, "Only accepts the following: 0 (Not Needed), and 1 (Needed)."); + error = CHIP_ERROR_INTERNAL; + } + return error; +} + CHIP_ERROR OTASoftwareUpdateBase::SetCandidatesFromFilePath(char * _Nonnull filePath) { NSMutableArray * candidates; @@ -167,22 +282,6 @@ static bool ParseJsonFileAndPopulateCandidates( return CHIP_NO_ERROR; } -CHIP_ERROR OTASoftwareUpdateBase::SetUserConsentStatus(char * _Nonnull otaSTatus) -{ - CHIP_ERROR error = CHIP_NO_ERROR; - if (strcmp(otaSTatus, "granted") == 0) { - mOTADelegate.userConsentState = OTAProviderUserGranted; - } else if (strcmp(otaSTatus, "obtaining") == 0) { - mOTADelegate.userConsentState = OTAProviderUserObtaining; - } else if (strcmp(otaSTatus, "denied") == 0) { - mOTADelegate.userConsentState = OTAProviderUserDenied; - } else { - ChipLogError(chipTool, "Only accepts the following: granted, obtaining, and denied."); - error = CHIP_ERROR_INTERNAL; - } - return error; -} - CHIP_ERROR OTASoftwareUpdateBase::Run() { if (!IsInteractive()) {