Skip to content

Commit

Permalink
[OTA] Consolidate provider location between requestor core and driver (
Browse files Browse the repository at this point in the history
  • Loading branch information
carol-apple authored Mar 11, 2022
1 parent 10b8046 commit ae514b6
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 40 deletions.
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

0 comments on commit ae514b6

Please sign in to comment.