Skip to content

Commit

Permalink
OTA-Provider: Implementation for obtaining user consent (#13816)
Browse files Browse the repository at this point in the history
* ota-provider: Implementation for obtaining user consent

* ota-provider: Support for user consent in linux app

* Added an API SourceNodeId() in CommandHandler

Using PRIu16 for logging endpoint and ChipLogFormatX64/ChipLogValueX64
for logging Node Id.

Use Clock::Seconds32 insetead of Clock::Milliseconds32

* Modified the UserConsent delegate and added default implementation

UserConsent is not a SHALL so, using it when its available.
Default implementation returns true by default, also added APIs to grant
and revoke the UserConsent.

* Do not crash if it's a group session

* Keep supporting query behaviour option and set DelayedActionTime in Busy
and NotAvailable Case

* restyled

* Fixing error after resolving merge conflict

* Remove unnecessary chip:: resolution usage

* Use GetSubjectDescriptor() to get SourceNodeId

* Addressed review comments

* minor changes

* Addressed review comments and removed per subject handling, for now
supporting only global user consent poliy.
  • Loading branch information
shubhamdp authored Feb 2, 2022
1 parent 4f391f1 commit 1ae483d
Show file tree
Hide file tree
Showing 8 changed files with 380 additions and 77 deletions.
45 changes: 42 additions & 3 deletions examples/ota-provider-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
#include <lib/support/CHIPArgParser.hpp>
#include <lib/support/CHIPMem.h>
#include <lib/support/logging/CHIPLogging.h>

#include <ota-provider-common/BdxOtaSender.h>
#include <ota-provider-common/DefaultUserConsentProvider.h>
#include <ota-provider-common/OTAProviderExample.h>

#include <fstream>
Expand All @@ -54,12 +54,14 @@ constexpr uint16_t kOptionFilepath = 'f';
constexpr uint16_t kOptionOtaImageList = 'o';
constexpr uint16_t kOptionQueryImageBehavior = 'q';
constexpr uint16_t kOptionDelayedActionTimeSec = 'd';
constexpr uint16_t kOptionUserConsent = 'u';

// Global variables used for passing the CLI arguments to the OTAProviderExample object
static OTAProviderExample::QueryImageBehaviorType gQueryImageBehavior = OTAProviderExample::kRespondWithUpdateAvailable;
static OTAProviderExample::QueryImageBehaviorType gQueryImageBehavior = OTAProviderExample::kRespondWithUnknown;
static uint32_t gDelayedActionTimeSec = 0;
static const char * gOtaFilepath = nullptr;
static const char * gOtaImageListFilepath = nullptr;
static chip::ota::UserConsentState gUserConsentState = chip::ota::UserConsentState::kUnknown;

// Parses the JSON filepath and extracts DeviceSoftwareVersionModel parameters
static bool ParseJsonFileAndPopulateCandidates(const char * filepath,
Expand Down Expand Up @@ -183,6 +185,30 @@ bool HandleOptions(const char * aProgram, OptionSet * aOptions, int aIdentifier,
case kOptionDelayedActionTimeSec:
gDelayedActionTimeSec = static_cast<uint32_t>(strtol(aValue, NULL, 0));
break;
case kOptionUserConsent:
if (aValue == NULL)
{
PrintArgError("%s: ERROR: NULL UserConsent parameter\n", aProgram);
retval = false;
}
else if (strcmp(aValue, "granted") == 0)
{
gUserConsentState = chip::ota::UserConsentState::kGranted;
}
else if (strcmp(aValue, "denied") == 0)
{
gUserConsentState = chip::ota::UserConsentState::kDenied;
}
else if (strcmp(aValue, "deferred") == 0)
{
gUserConsentState = chip::ota::UserConsentState::kObtaining;
}
else
{
PrintArgError("%s: ERROR: Invalid UserConsent parameter: %s\n", aProgram, aValue);
retval = false;
}
break;
default:
PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName);
retval = false;
Expand All @@ -197,6 +223,7 @@ OptionDef cmdLineOptionsDef[] = {
{ "otaImageList", chip::ArgParser::kArgumentRequired, kOptionOtaImageList },
{ "QueryImageBehavior", chip::ArgParser::kArgumentRequired, kOptionQueryImageBehavior },
{ "DelayedActionTimeSec", chip::ArgParser::kArgumentRequired, kOptionDelayedActionTimeSec },
{ "UserConsent", chip::ArgParser::kArgumentRequired, kOptionUserConsent },
{},
};

Expand All @@ -209,7 +236,12 @@ OptionSet cmdLineOptions = { HandleOptions, cmdLineOptionsDef, "PROGRAM OPTIONS"
" Status value in the Query Image Response\n"
" -d/--DelayedActionTimeSec <time>\n"
" Value in seconds for the DelayedActionTime in the Query Image Response\n"
" and Apply Update Response\n" };
" and Apply Update Response\n"
" -u/--UserConsent <granted | denied | deferred>\n"
" granted: Status value in QueryImageResponse is set to UpdateAvailable\n"
" denied: Status value in QueryImageResponse is set to UpdateNotAvailable\n"
" deferred: Status value in QueryImageResponse is set to Busy\n"
" -q/--QueryImageBehavior overrides this option\n" };

HelpOptions helpOptions("ota-provider-app", "Usage: ota-provider-app [options]", "1.0");

Expand All @@ -219,6 +251,7 @@ int main(int argc, char * argv[])
{
CHIP_ERROR err = CHIP_NO_ERROR;
OTAProviderExample otaProvider;
chip::ota::DefaultUserConsentProvider userConsentProvider;

if (chip::Platform::MemoryInit() != CHIP_NO_ERROR)
{
Expand Down Expand Up @@ -263,6 +296,12 @@ int main(int argc, char * argv[])
otaProvider.SetQueryImageBehavior(gQueryImageBehavior);
otaProvider.SetDelayedActionTimeSec(gDelayedActionTimeSec);

if (gUserConsentState != chip::ota::UserConsentState::kUnknown)
{
userConsentProvider.SetGlobalUserConsentState(gUserConsentState);
otaProvider.SetUserConsentDelegate(&userConsentProvider);
}

ChipLogDetail(SoftwareUpdate, "Using ImageList file: %s", gOtaImageListFilepath ? gOtaImageListFilepath : "(none)");

if (gOtaImageListFilepath != nullptr)
Expand Down
3 changes: 3 additions & 0 deletions examples/ota-provider-app/ota-provider-common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ chip_data_model("ota-provider-common") {
sources = [
"BdxOtaSender.cpp",
"BdxOtaSender.h",
"DefaultUserConsentProvider.cpp",
"DefaultUserConsentProvider.h",
"OTAProviderExample.cpp",
"OTAProviderExample.h",
"UserConsentDelegate.h",
]

deps = [ "${chip_root}/src/protocols/bdx" ]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
*
* Copyright (c) 2022 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <lib/support/logging/CHIPLogging.h>
#include <ota-provider-common/DefaultUserConsentProvider.h>

namespace chip {
namespace ota {

void DefaultUserConsentProvider::LogUserConsentSubject(const UserConsentSubject & subject)
{
ChipLogDetail(SoftwareUpdate, "User consent request for:");
ChipLogDetail(SoftwareUpdate, ": FabricIndex: %" PRIu8, subject.fabricIndex);
ChipLogDetail(SoftwareUpdate, ": RequestorNodeId: " ChipLogFormatX64, ChipLogValueX64(subject.requestorNodeId));
ChipLogDetail(SoftwareUpdate, ": ProviderEndpointId: %" PRIu16, subject.providerEndpointId);
ChipLogDetail(SoftwareUpdate, ": RequestorVendorId: %" PRIu16, subject.requestorVendorId);
ChipLogDetail(SoftwareUpdate, ": RequestorProductId: %" PRIu16, subject.requestorProductId);
ChipLogDetail(SoftwareUpdate, ": RequestorCurrentVersion: %" PRIu32, subject.requestorCurrentVersion);
ChipLogDetail(SoftwareUpdate, ": RequestorTargetVersion: %" PRIu32, subject.requestorTargetVersion);
ChipLogDetail(SoftwareUpdate, ": Metadata:");
ChipLogByteSpan(SoftwareUpdate, subject.metadata);
}

UserConsentState DefaultUserConsentProvider::GetUserConsentState(const UserConsentSubject & subject)
{
LogUserConsentSubject(subject);

if (mUseGlobalConsent)
{
return mGlobalConsentState;
}

return UserConsentState::kGranted;
}

} // namespace ota
} // namespace chip
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
*
* Copyright (c) 2022 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

#include <lib/core/CHIPError.h>
#include <ota-provider-common/UserConsentDelegate.h>

namespace chip {
namespace ota {

class DefaultUserConsentProvider : public UserConsentDelegate
{
public:
DefaultUserConsentProvider() = default;

~DefaultUserConsentProvider() = default;

// This method returns kGranted unless explicitly denied by the user by calling RevokeUserConsent()
UserConsentState GetUserConsentState(const UserConsentSubject & subject) override;

// If this is set to true, all the user consent requests will be replied with global consent.
void SetGlobalUserConsentState(UserConsentState state)
{
mUseGlobalConsent = true;
mGlobalConsentState = state;
}

// state is only valid if isGlobalConsentSet is true
void GetGlobalUserConsentState(bool & isGlobalConsentSet, UserConsentState & state)
{
isGlobalConsentSet = mUseGlobalConsent;
state = mGlobalConsentState;
}

// Clear the global user consent state
void ClearGlobalUserConsentState() { mUseGlobalConsent = false; }

private:
bool mUseGlobalConsent = false;

UserConsentState mGlobalConsentState = UserConsentState::kGranted;

void LogUserConsentSubject(const UserConsentSubject & subject);
};

} // namespace ota
} // namespace chip
Loading

0 comments on commit 1ae483d

Please sign in to comment.