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

[OTA] Consolidate provider location between requestor core and driver #16088

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
11 changes: 6 additions & 5 deletions src/app/clusters/ota-requestor/ExtendedOTARequestorDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,16 @@ void ExtendedOTARequestorDriver::PollUserConsentState()
CHIP_ERROR ExtendedOTARequestorDriver::GetUserConsentSubject(chip::ota::UserConsentSubject & subject,
const UpdateDescription & update)
{
if (mLastUsedProvider.HasValue())
Optional<ProviderLocationType> lastUsedProvider;
mRequestor->GetProviderLocation(lastUsedProvider);
if (lastUsedProvider.HasValue())
{
// mLastUsedProvider has the provider fabric index and endpoint id
subject.fabricIndex = mLastUsedProvider.Value().fabricIndex;
subject.providerEndpointId = mLastUsedProvider.Value().endpoint;
subject.fabricIndex = lastUsedProvider.Value().fabricIndex;
subject.providerEndpointId = lastUsedProvider.Value().endpoint;
}
else
{
ChipLogError(SoftwareUpdate, "mLastProvider is empty");
ChipLogError(SoftwareUpdate, "Last used provider is empty");
return CHIP_ERROR_INTERNAL;
}

Expand Down
35 changes: 16 additions & 19 deletions src/app/clusters/ota-requestor/GenericOTARequestorDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ void StartDelayTimerHandler(System::Layer * systemLayer, void * appState)
static_cast<GenericOTARequestorDriver *>(appState)->SendQueryImage();
}

bool ProviderLocationsEqual(const ProviderLocation::Type & a, const ProviderLocation::Type & b)
bool GenericOTARequestorDriver::ProviderLocationsEqual(const ProviderLocationType & a, const ProviderLocationType & b)
{
if ((a.fabricIndex == b.fabricIndex) && (a.providerNodeID == b.providerNodeID) && (a.endpoint == b.endpoint))
{
Expand Down Expand Up @@ -104,36 +104,35 @@ void GenericOTARequestorDriver::UpdateNotFound(UpdateNotFoundReason reason, Syst
{
VerifyOrDie(mRequestor != nullptr);

ProviderLocation::Type providerLocation;
ProviderLocationType providerLocation;
bool willTryAnotherQuery = false;

switch (reason)
{
case UpdateNotFoundReason::UpToDate:
willTryAnotherQuery = false;
break;

case UpdateNotFoundReason::Busy:
willTryAnotherQuery = true;
break;

case UpdateNotFoundReason::ConnectionFailed:
case UpdateNotFoundReason::NotAvailable:
case UpdateNotFoundReason::NotAvailable: {
// IMPLEMENTATION CHOICE:
// This implementation schedules a query only if a different provider is available
Optional<ProviderLocationType> lastUsedProvider;
mRequestor->GetProviderLocation(lastUsedProvider);
if ((DetermineProviderLocation(providerLocation) != true) ||
(mLastUsedProvider.HasValue() && ProviderLocationsEqual(providerLocation, mLastUsedProvider.Value())))
(lastUsedProvider.HasValue() && ProviderLocationsEqual(providerLocation, lastUsedProvider.Value())))
{
willTryAnotherQuery = false;
}
else
{
willTryAnotherQuery = true;
mRequestor->SetCurrentProviderLocation(providerLocation);
}
mRequestor->SetCurrentProviderLocation(providerLocation);
mLastUsedProvider.SetValue(providerLocation);
break;

}
default:
willTryAnotherQuery = false;
break;
Expand All @@ -143,6 +142,7 @@ void GenericOTARequestorDriver::UpdateNotFound(UpdateNotFoundReason reason, Syst
{
delay = kDefaultDelayedActionTime;
}

if (willTryAnotherQuery == true)
{
ChipLogProgress(SoftwareUpdate, "UpdateNotFound, scheduling a retry");
Expand All @@ -151,7 +151,6 @@ void GenericOTARequestorDriver::UpdateNotFound(UpdateNotFoundReason reason, Syst
else
{
ChipLogProgress(SoftwareUpdate, "UpdateNotFound, not scheduling further retries");
mRequestor->ClearCurrentProviderLocation();
}
}

Expand Down Expand Up @@ -259,7 +258,6 @@ void GenericOTARequestorDriver::ProcessAnnounceOTAProviders(

// Point the OTARequestor to the announced provider
mRequestor->SetCurrentProviderLocation(providerLocation);
mLastUsedProvider.SetValue(providerLocation);

ScheduleDelayedAction(System::Clock::Seconds32(secToStart), StartDelayTimerHandler, this);
}
Expand All @@ -283,15 +281,14 @@ void GenericOTARequestorDriver::DefaultProviderTimerHandler(System::Layer * syst
ChipLogProgress(SoftwareUpdate, "Default Provider timer handler is invoked");

// Determine which provider to query next
ProviderLocation::Type providerLocation;
ProviderLocationType providerLocation;
if (DetermineProviderLocation(providerLocation) != true)
{
StartDefaultProviderTimer();
return;
}

mRequestor->SetCurrentProviderLocation(providerLocation);
mLastUsedProvider.SetValue(providerLocation);

SendQueryImage();
}
Expand All @@ -301,8 +298,6 @@ void GenericOTARequestorDriver::StartDefaultProviderTimer()
ChipLogProgress(SoftwareUpdate, "Starting the Default Provider timer, timeout: %u seconds",
(unsigned int) mPeriodicQueryTimeInterval);

DeviceLayer::SystemLayer().ScheduleLambda([this] { mRequestor->ClearCurrentProviderLocation(); });

ScheduleDelayedAction(
System::Clock::Seconds32(mPeriodicQueryTimeInterval),
[](System::Layer *, void * context) {
Expand All @@ -325,14 +320,16 @@ void GenericOTARequestorDriver::StopDefaultProviderTimer()
* Returns the next available Provider location. The algorithm is to simply loop through the list of DefaultOtaProviders and return
* the next value (based on the last used provider). If no suitable candidate is found, FALSE is returned.
*/

bool GenericOTARequestorDriver::DetermineProviderLocation(ProviderLocation::Type & providerLocation)
bool GenericOTARequestorDriver::DetermineProviderLocation(ProviderLocationType & providerLocation)
{
Optional<ProviderLocationType> lastUsedProvider;
mRequestor->GetProviderLocation(lastUsedProvider);

// Iterate through the default providers list and find the last used provider. If found, return the provider after it
auto iterator = mRequestor->GetDefaultOTAProviderListIterator();
while (mLastUsedProvider.HasValue() && iterator.Next())
while (lastUsedProvider.HasValue() && iterator.Next())
{
if (ProviderLocationsEqual(iterator.GetValue(), mLastUsedProvider.Value()))
if (ProviderLocationsEqual(iterator.GetValue(), lastUsedProvider.Value()))
{
if (iterator.Next())
{
Expand Down
3 changes: 1 addition & 2 deletions src/app/clusters/ota-requestor/GenericOTARequestorDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,12 @@ class GenericOTARequestorDriver : public OTARequestorDriver
void DefaultProviderTimerHandler(System::Layer * systemLayer, void * appState);
void ScheduleDelayedAction(System::Clock::Seconds32 delay, System::TimerCompleteCallback action, void * aAppState);
void CancelDelayedAction(System::TimerCompleteCallback action, void * aAppState);
bool ProviderLocationsEqual(const ProviderLocationType & a, const ProviderLocationType & b);

OTARequestorInterface * mRequestor = nullptr;
OTAImageProcessorInterface * mImageProcessor = nullptr;
uint32_t mOtaStartDelaySec = 0;
uint32_t mPeriodicQueryTimeInterval = (24 * 60 * 60); // Timeout for querying providers on the default OTA provider list

Optional<ProviderLocationType> mLastUsedProvider; // Provider location used for the last query or update
};

} // namespace DeviceLayer
Expand Down
12 changes: 6 additions & 6 deletions src/app/clusters/ota-requestor/OTARequestor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,9 @@ EmberAfStatus OTARequestor::HandleAnnounceOTAProvider(app::CommandHandler * comm
return EMBER_ZCL_STATUS_FAILURE;
}

ProviderLocation::Type providerLocation = { .providerNodeID = commandData.providerNodeId,
.endpoint = commandData.endpoint,
.fabricIndex = commandObj->GetAccessingFabricIndex() };
ProviderLocationType providerLocation = { .providerNodeID = commandData.providerNodeId,
.endpoint = commandData.endpoint,
.fabricIndex = commandObj->GetAccessingFabricIndex() };

ChipLogDetail(SoftwareUpdate, " FabricIndex: %u", providerLocation.fabricIndex);
ChipLogDetail(SoftwareUpdate, " ProviderNodeID: 0x" ChipLogFormatX64, ChipLogValueX64(providerLocation.providerNodeID));
Expand Down Expand Up @@ -474,7 +474,7 @@ void OTARequestor::TriggerImmediateQueryInternal()
// Sends the QueryImage command to the next available Provider
OTARequestorInterface::OTATriggerResult OTARequestor::TriggerImmediateQuery()
{
ProviderLocation::Type providerLocation;
ProviderLocationType providerLocation;
if (mOtaRequestorDriver->DetermineProviderLocation(providerLocation) != true)
{
ChipLogError(SoftwareUpdate, "No OTA Providers available");
Expand Down Expand Up @@ -539,13 +539,13 @@ CHIP_ERROR OTARequestor::ClearDefaultOtaProviderList(FabricIndex fabricIndex)
return mStorage->StoreDefaultProviders(mDefaultOtaProviderList);
}

CHIP_ERROR OTARequestor::AddDefaultOtaProvider(const ProviderLocation::Type & providerLocation)
CHIP_ERROR OTARequestor::AddDefaultOtaProvider(const ProviderLocationType & providerLocation)
{
// Look for an entry with the same fabric index indicated
auto iterator = mDefaultOtaProviderList.Begin();
while (iterator.Next())
{
ProviderLocation::Type pl = iterator.GetValue();
ProviderLocationType pl = iterator.GetValue();
if (pl.GetFabricIndex() == providerLocation.GetFabricIndex())
{
ChipLogError(SoftwareUpdate, "Default OTA provider entry with fabric %d already exists", pl.GetFabricIndex());
Expand Down
7 changes: 3 additions & 4 deletions src/app/clusters/ota-requestor/OTARequestor.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,10 @@ class OTARequestor : public OTARequestorInterface, public BDXDownloader::StateDe
mProviderLocation.SetValue(providerLocation);
}

void ClearCurrentProviderLocation() override { mProviderLocation.ClearValue(); }
void GetProviderLocation(Optional<ProviderLocationType> & providerLocation) override { providerLocation = mProviderLocation; }

// Add a default OTA provider to the cached list
CHIP_ERROR AddDefaultOtaProvider(
const app::Clusters::OtaSoftwareUpdateRequestor::Structs::ProviderLocation::Type & providerLocation) override;
CHIP_ERROR AddDefaultOtaProvider(const ProviderLocationType & providerLocation) override;

// Retrieve an iterator to the cached default OTA provider list
ProviderLocationList::Iterator GetDefaultOTAProviderListIterator(void) override { return mDefaultOtaProviderList.Begin(); }
Expand Down Expand Up @@ -313,7 +312,7 @@ class OTARequestor : public OTARequestorInterface, public BDXDownloader::StateDe
OTAUpdateStateEnum mCurrentUpdateState = OTAUpdateStateEnum::kUnknown;
Server * mServer = nullptr;
ProviderLocationList mDefaultOtaProviderList;
Optional<ProviderLocationType> mProviderLocation; // Provider location used for the current update in progress
Optional<ProviderLocationType> mProviderLocation; // Provider location used for the current/last update in progress
};

} // namespace chip
8 changes: 4 additions & 4 deletions src/app/clusters/ota-requestor/OTARequestorInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,12 @@ class OTARequestorInterface
// Set the provider location to be used in the next query and OTA update process
virtual void SetCurrentProviderLocation(ProviderLocationType providerLocation) = 0;

// Clear the provider location to indicate that no OTA update may be in progress
virtual void ClearCurrentProviderLocation() = 0;
// If there is an OTA update in progress, returns the provider location for the current OTA update, otherwise, returns the
// provider location that was last used
virtual void GetProviderLocation(Optional<ProviderLocationType> & providerLocation) = 0;

// Add a default OTA provider to the cached list
virtual CHIP_ERROR
AddDefaultOtaProvider(const app::Clusters::OtaSoftwareUpdateRequestor::Structs::ProviderLocation::Type & providerLocation) = 0;
virtual CHIP_ERROR AddDefaultOtaProvider(const ProviderLocationType & providerLocation) = 0;

// Retrieve an iterator to the cached default OTA provider list
virtual ProviderLocationList::Iterator GetDefaultOTAProviderListIterator(void) = 0;
Expand Down