Skip to content

Commit

Permalink
Support multiple sequential BDX transfers (#13329)
Browse files Browse the repository at this point in the history
  • Loading branch information
carol-apple authored Jan 6, 2022
1 parent 48d299f commit 46541fb
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 18 deletions.
21 changes: 3 additions & 18 deletions examples/ota-provider-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,6 @@ constexpr uint16_t kOptionFilepath = 'f';
constexpr uint16_t kOptionQueryImageBehavior = 'q';
constexpr uint16_t kOptionDelayedActionTimeSec = 'd';

// Arbitrary BDX Transfer Params
constexpr uint32_t kMaxBdxBlockSize = 1024;
constexpr chip::System::Clock::Timeout kBdxTimeout = chip::System::Clock::Seconds16(5 * 60); // OTA Spec mandates >= 5 minutes
constexpr chip::System::Clock::Timeout kBdxPollFreq = chip::System::Clock::Milliseconds32(500);

// Global variables used for passing the CLI arguments to the OTAProviderExample object
OTAProviderExample::queryImageBehaviorType gQueryImageBehavior = OTAProviderExample::kRespondWithUpdateAvailable;
uint32_t gDelayedActionTimeSec = 0;
Expand Down Expand Up @@ -139,7 +134,6 @@ int main(int argc, char * argv[])
{
CHIP_ERROR err = CHIP_NO_ERROR;
OTAProviderExample otaProvider;
BdxOtaSender bdxServer;

if (chip::Platform::MemoryInit() != CHIP_NO_ERROR)
{
Expand All @@ -164,8 +158,10 @@ int main(int argc, char * argv[])
// Initialize device attestation config
SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider());

BdxOtaSender * bdxOtaSender = otaProvider.GetBdxOtaSender();
VerifyOrReturnError(bdxOtaSender != nullptr, 1);
err = chip::Server::GetInstance().GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::BDX::Id,
&bdxServer);
bdxOtaSender);
if (err != CHIP_NO_ERROR)
{
ChipLogDetail(SoftwareUpdate, "RegisterUnsolicitedMessageHandler failed: %s", chip::ErrorStr(err));
Expand All @@ -177,24 +173,13 @@ int main(int argc, char * argv[])
if (gOtaFilepath != nullptr)
{
otaProvider.SetOTAFilePath(gOtaFilepath);
bdxServer.SetFilepath(gOtaFilepath);
}

otaProvider.SetQueryImageBehavior(gQueryImageBehavior);
otaProvider.SetDelayedActionTimeSec(gDelayedActionTimeSec);

chip::app::Clusters::OTAProvider::SetDelegate(kOtaProviderEndpoint, &otaProvider);

BitFlags<TransferControlFlags> bdxFlags;
bdxFlags.Set(TransferControlFlags::kReceiverDrive);
err = bdxServer.PrepareForTransfer(&chip::DeviceLayer::SystemLayer(), chip::bdx::TransferRole::kSender, bdxFlags,
kMaxBdxBlockSize, kBdxTimeout, kBdxPollFreq);
if (err != CHIP_NO_ERROR)
{
ChipLogError(BDX, "failed to init BDX server: %s", chip::ErrorStr(err));
return 1;
}

chip::DeviceLayer::PlatformMgr().RunEventLoop();

return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ void BdxOtaSender::HandleTransferSessionOutput(TransferSession::OutputEvent & ev
blockData.IsEof = (blockData.Length < blockSize) ||
(mNumBytesSent + static_cast<uint64_t>(blockData.Length) == mTransfer.GetTransferLength() || (otaFile.peek() == EOF));
mNumBytesSent = static_cast<uint32_t>(mNumBytesSent + blockData.Length);
otaFile.close();

VerifyOrReturn(CHIP_NO_ERROR == mTransfer.PrepareBlock(blockData),
ChipLogError(BDX, "%s: PrepareBlock failed: %s", __FUNCTION__, chip::ErrorStr(err)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include <string.h>

using chip::BitFlags;
using chip::ByteSpan;
using chip::CharSpan;
using chip::FabricIndex;
Expand All @@ -40,13 +41,19 @@ using chip::Optional;
using chip::Server;
using chip::Span;
using chip::app::Clusters::OTAProviderDelegate;
using chip::bdx::TransferControlFlags;
using namespace chip::app::Clusters::OtaSoftwareUpdateProvider;
using namespace chip::app::Clusters::OtaSoftwareUpdateProvider::Commands;

constexpr uint8_t kUpdateTokenLen = 32; // must be between 8 and 32
constexpr uint8_t kUpdateTokenStrLen = kUpdateTokenLen * 2 + 1; // Hex string needs 2 hex chars for every byte
constexpr size_t kUriMaxLen = 256;

// Arbitrary BDX Transfer Params
constexpr uint32_t kMaxBdxBlockSize = 1024;
constexpr chip::System::Clock::Timeout kBdxTimeout = chip::System::Clock::Seconds16(5 * 60); // OTA Spec mandates >= 5 minutes
constexpr chip::System::Clock::Timeout kBdxPollFreq = chip::System::Clock::Milliseconds32(500);

void GetUpdateTokenString(const chip::ByteSpan & token, char * buf, size_t bufSize)
{
const uint8_t * tokenData = static_cast<const uint8_t *>(token.data());
Expand Down Expand Up @@ -124,6 +131,18 @@ EmberAfStatus OTAProviderExample::HandleQueryImage(chip::app::CommandHandler * c
if (strlen(mOTAFilePath) != 0)
{
queryStatus = OTAQueryStatus::kUpdateAvailable;

// Initialize the transfer session in prepartion for a BDX transfer
mBdxOtaSender.SetFilepath(mOTAFilePath);
BitFlags<TransferControlFlags> bdxFlags;
bdxFlags.Set(TransferControlFlags::kReceiverDrive);
CHIP_ERROR err = mBdxOtaSender.PrepareForTransfer(&chip::DeviceLayer::SystemLayer(), chip::bdx::TransferRole::kSender,
bdxFlags, kMaxBdxBlockSize, kBdxTimeout, kBdxPollFreq);
if (err != CHIP_NO_ERROR)
{
ChipLogError(BDX, "Failed to initialize BDX transfer session: %s", chip::ErrorStr(err));
return EMBER_ZCL_STATUS_FAILURE;
}
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <app/CommandHandler.h>
#include <app/clusters/ota-provider/ota-provider-delegate.h>
#include <ota-provider-common/BdxOtaSender.h>

/**
* A reference implementation for an OTA Provider. Includes a method for providing a path to a local OTA file to serve.
Expand All @@ -30,6 +31,7 @@ class OTAProviderExample : public chip::app::Clusters::OTAProviderDelegate
OTAProviderExample();

void SetOTAFilePath(const char * path);
BdxOtaSender * GetBdxOtaSender() { return &mBdxOtaSender; }

// Inherited from OTAProviderDelegate
EmberAfStatus HandleQueryImage(
Expand All @@ -52,6 +54,7 @@ class OTAProviderExample : public chip::app::Clusters::OTAProviderDelegate
void SetDelayedActionTimeSec(uint32_t time) { mDelayedActionTimeSec = time; }

private:
BdxOtaSender mBdxOtaSender;
static constexpr size_t kFilepathBufLen = 256;
char mOTAFilePath[kFilepathBufLen]; // null-terminated
queryImageBehaviorType mQueryImageBehavior;
Expand Down
3 changes: 3 additions & 0 deletions src/app/clusters/ota-requestor/BDXDownloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ void BDXDownloader::OnMessageReceived(const chip::PayloadHeader & payloadHeader,

CHIP_ERROR BDXDownloader::SetBDXParams(const chip::bdx::TransferSession::TransferInitData & bdxInitData)
{
mState = State::kIdle;
mBdxTransfer.Reset();

VerifyOrReturnError(mState == State::kIdle, CHIP_ERROR_INCORRECT_STATE);

// Must call StartTransfer() here to store the the pointer data contained in bdxInitData in the TransferSession object.
Expand Down

0 comments on commit 46541fb

Please sign in to comment.