diff --git a/examples/ota-provider-app/linux/main.cpp b/examples/ota-provider-app/linux/main.cpp index f4cf840025523e..2f749324d5399a 100644 --- a/examples/ota-provider-app/linux/main.cpp +++ b/examples/ota-provider-app/linux/main.cpp @@ -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; @@ -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) { @@ -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)); @@ -177,7 +173,6 @@ int main(int argc, char * argv[]) if (gOtaFilepath != nullptr) { otaProvider.SetOTAFilePath(gOtaFilepath); - bdxServer.SetFilepath(gOtaFilepath); } otaProvider.SetQueryImageBehavior(gQueryImageBehavior); @@ -185,16 +180,6 @@ int main(int argc, char * argv[]) chip::app::Clusters::OTAProvider::SetDelegate(kOtaProviderEndpoint, &otaProvider); - BitFlags 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; diff --git a/examples/ota-provider-app/ota-provider-common/BdxOtaSender.cpp b/examples/ota-provider-app/ota-provider-common/BdxOtaSender.cpp index 5946a8610ab7b1..1a7cd315b61724 100644 --- a/examples/ota-provider-app/ota-provider-common/BdxOtaSender.cpp +++ b/examples/ota-provider-app/ota-provider-common/BdxOtaSender.cpp @@ -121,6 +121,7 @@ void BdxOtaSender::HandleTransferSessionOutput(TransferSession::OutputEvent & ev blockData.IsEof = (blockData.Length < blockSize) || (mNumBytesSent + static_cast(blockData.Length) == mTransfer.GetTransferLength() || (otaFile.peek() == EOF)); mNumBytesSent = static_cast(mNumBytesSent + blockData.Length); + otaFile.close(); VerifyOrReturn(CHIP_NO_ERROR == mTransfer.PrepareBlock(blockData), ChipLogError(BDX, "%s: PrepareBlock failed: %s", __FUNCTION__, chip::ErrorStr(err))); diff --git a/examples/ota-provider-app/ota-provider-common/OTAProviderExample.cpp b/examples/ota-provider-app/ota-provider-common/OTAProviderExample.cpp index 2e4abd703884e3..968bcea2b61a6f 100644 --- a/examples/ota-provider-app/ota-provider-common/OTAProviderExample.cpp +++ b/examples/ota-provider-app/ota-provider-common/OTAProviderExample.cpp @@ -30,6 +30,7 @@ #include +using chip::BitFlags; using chip::ByteSpan; using chip::CharSpan; using chip::FabricIndex; @@ -40,6 +41,7 @@ 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; @@ -47,6 +49,11 @@ constexpr uint8_t kUpdateTokenLen = 32; // must be betwe 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(token.data()); @@ -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 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 { diff --git a/examples/ota-provider-app/ota-provider-common/OTAProviderExample.h b/examples/ota-provider-app/ota-provider-common/OTAProviderExample.h index 3a7fdcf5c7e0c5..67e4a70e277282 100644 --- a/examples/ota-provider-app/ota-provider-common/OTAProviderExample.h +++ b/examples/ota-provider-app/ota-provider-common/OTAProviderExample.h @@ -20,6 +20,7 @@ #include #include +#include /** * A reference implementation for an OTA Provider. Includes a method for providing a path to a local OTA file to serve. @@ -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( @@ -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; diff --git a/src/app/clusters/ota-requestor/BDXDownloader.cpp b/src/app/clusters/ota-requestor/BDXDownloader.cpp index 8c2ef8c3626562..d33f634089cec2 100644 --- a/src/app/clusters/ota-requestor/BDXDownloader.cpp +++ b/src/app/clusters/ota-requestor/BDXDownloader.cpp @@ -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.