diff --git a/examples/ota-provider-app/esp32/main/include/ota-provider-common/BdxOtaSender.h b/examples/ota-provider-app/esp32/main/include/ota-provider-common/BdxOtaSender.h index 70a90a0aaa21df..4940d676dedd58 100644 --- a/examples/ota-provider-app/esp32/main/include/ota-provider-common/BdxOtaSender.h +++ b/examples/ota-provider-app/esp32/main/include/ota-provider-common/BdxOtaSender.h @@ -89,9 +89,6 @@ class BdxOtaSender : public chip::bdx::Responder */ uint64_t GetTransferLength(void); - /* ota-provider-common/OTAProviderExample.cpp requires this */ - void SetFilepath(const char * path) {} - private: // Inherited from bdx::TransferFacilitator void HandleTransferSessionOutput(chip::bdx::TransferSession::OutputEvent & event) override; diff --git a/examples/ota-provider-app/ota-provider-common/BdxOtaSender.cpp b/examples/ota-provider-app/ota-provider-common/BdxOtaSender.cpp index c471e61fe8e367..bd89f71eb2bf9b 100644 --- a/examples/ota-provider-app/ota-provider-common/BdxOtaSender.cpp +++ b/examples/ota-provider-app/ota-provider-common/BdxOtaSender.cpp @@ -32,19 +32,7 @@ using chip::bdx::TransferSession; BdxOtaSender::BdxOtaSender() { - memset(mFilepath, 0, kFilepathMaxLength); -} - -void BdxOtaSender::SetFilepath(const char * path) -{ - if (path != nullptr) - { - chip::Platform::CopyString(mFilepath, path); - } - else - { - memset(mFilepath, 0, kFilepathMaxLength); - } + memset(mFileDesignator, 0, chip::bdx::kMaxFileDesignatorLen); } void BdxOtaSender::HandleTransferSessionOutput(TransferSession::OutputEvent & event) @@ -88,6 +76,15 @@ void BdxOtaSender::HandleTransferSessionOutput(TransferSession::OutputEvent & ev acceptData.Length = mTransfer.GetTransferLength(); VerifyOrReturn(mTransfer.AcceptTransfer(acceptData) == CHIP_NO_ERROR, ChipLogError(BDX, "%s: %s", __FUNCTION__, chip::ErrorStr(err))); + + // Store the file designator used during block query + uint16_t fdl = 0; + const uint8_t * fd = mTransfer.GetFileDesignator(fdl); + VerifyOrReturn(fdl < chip::bdx::kMaxFileDesignatorLen, + ChipLogError(BDX, "Cannot store file designator with length = %d", fdl)); + memcpy(mFileDesignator, fd, fdl); + mFileDesignator[fdl] = 0; + break; } case TransferSession::OutputEventType::kQueryReceived: { @@ -110,7 +107,7 @@ void BdxOtaSender::HandleTransferSessionOutput(TransferSession::OutputEvent & ev return; } - std::ifstream otaFile(mFilepath, std::ifstream::in); + std::ifstream otaFile(mFileDesignator, std::ifstream::in); VerifyOrReturn(otaFile.good(), ChipLogError(BDX, "%s: file read failed", __FUNCTION__)); otaFile.seekg(mNumBytesSent); otaFile.read(reinterpret_cast(blockBuf->Start()), bytesToRead); @@ -162,5 +159,5 @@ void BdxOtaSender::Reset() } mNumBytesSent = 0; - memset(mFilepath, 0, kFilepathMaxLength); + memset(mFileDesignator, 0, chip::bdx::kMaxFileDesignatorLen); } diff --git a/examples/ota-provider-app/ota-provider-common/BdxOtaSender.h b/examples/ota-provider-app/ota-provider-common/BdxOtaSender.h index 9d7220ca34fbcb..49da42aeff7827 100644 --- a/examples/ota-provider-app/ota-provider-common/BdxOtaSender.h +++ b/examples/ota-provider-app/ota-provider-common/BdxOtaSender.h @@ -25,16 +25,14 @@ class BdxOtaSender : public chip::bdx::Responder public: BdxOtaSender(); - void SetFilepath(const char * path); - private: // Inherited from bdx::TransferFacilitator void HandleTransferSessionOutput(chip::bdx::TransferSession::OutputEvent & event) override; void Reset(); - static constexpr size_t kFilepathMaxLength = 256; - char mFilepath[kFilepathMaxLength]; + // Null-terminated string representing file designator + char mFileDesignator[chip::bdx::kMaxFileDesignatorLen]; uint32_t mNumBytesSent = 0; }; diff --git a/examples/ota-provider-app/ota-provider-common/OTAProviderExample.cpp b/examples/ota-provider-app/ota-provider-common/OTAProviderExample.cpp index c498e3d6f0a1db..fd9da5274f20ae 100644 --- a/examples/ota-provider-app/ota-provider-common/OTAProviderExample.cpp +++ b/examples/ota-provider-app/ota-provider-common/OTAProviderExample.cpp @@ -261,7 +261,6 @@ EmberAfStatus OTAProviderExample::HandleQueryImage(chip::app::CommandHandler * c ChipLogDetail(SoftwareUpdate, "Generated URI: %.*s", static_cast(uri.size()), uri.data()); // Initialize the transfer session in prepartion for a BDX transfer - mBdxOtaSender.SetFilepath(otaFilePath); BitFlags bdxFlags; bdxFlags.Set(TransferControlFlags::kReceiverDrive); CHIP_ERROR err = mBdxOtaSender.PrepareForTransfer(&chip::DeviceLayer::SystemLayer(), chip::bdx::TransferRole::kSender, diff --git a/src/app/clusters/ota-requestor/OTARequestor.cpp b/src/app/clusters/ota-requestor/OTARequestor.cpp index 77e8325dd7e2f5..134e08aa814a48 100644 --- a/src/app/clusters/ota-requestor/OTARequestor.cpp +++ b/src/app/clusters/ota-requestor/OTARequestor.cpp @@ -141,6 +141,18 @@ void OTARequestor::OnQueryImageResponse(void * context, const QueryImageResponse requestorCore->mTargetVersion = update.softwareVersion; requestorCore->mUpdateToken = updateToken; + // Store file designator needed for BDX transfers + MutableCharSpan fileDesignator(requestorCore->mFileDesignatorBuffer); + if (update.fileDesignator.size() > fileDesignator.size()) + { + ChipLogError(SoftwareUpdate, "File designator size %zu is too large to store", update.fileDesignator.size()); + requestorCore->RecordErrorUpdateState(UpdateFailureState::kQuerying, err); + return; + } + memcpy(fileDesignator.data(), update.fileDesignator.data(), update.fileDesignator.size()); + fileDesignator.reduce_size(update.fileDesignator.size()); + requestorCore->mFileDesignator = fileDesignator; + requestorCore->mOtaRequestorDriver->UpdateAvailable(update, System::Clock::Seconds32(response.delayedActionTime.ValueOr(0))); } @@ -656,7 +668,9 @@ CHIP_ERROR OTARequestor::ExtractUpdateDescription(const QueryImageResponseDecoda VerifyOrReturnError(response.imageURI.HasValue(), CHIP_ERROR_INVALID_ARGUMENT); ReturnErrorOnFailure(bdx::ParseURI(response.imageURI.Value(), nodeId, fileDesignator)); - update.imageURI = response.imageURI.Value(); + VerifyOrReturnError(IsSpanUsable(fileDesignator), CHIP_ERROR_INVALID_ARGUMENT); + update.nodeId = nodeId; + update.fileDesignator = fileDesignator; VerifyOrReturnError(response.softwareVersion.HasValue(), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(response.softwareVersionString.HasValue(), CHIP_ERROR_INVALID_ARGUMENT); @@ -681,9 +695,8 @@ CHIP_ERROR OTARequestor::StartDownload(OperationalDeviceProxy & deviceProxy) TransferSession::TransferInitData initOptions; initOptions.TransferCtlFlags = bdx::TransferControlFlags::kReceiverDrive; initOptions.MaxBlockSize = mOtaRequestorDriver->GetMaxDownloadBlockSize(); - char testFileDes[9] = { "test.txt" }; - initOptions.FileDesLength = static_cast(strlen(testFileDes)); - initOptions.FileDesignator = reinterpret_cast(testFileDes); + initOptions.FileDesLength = static_cast(mFileDesignator.size()); + initOptions.FileDesignator = reinterpret_cast(mFileDesignator.data()); chip::Messaging::ExchangeManager * exchangeMgr = deviceProxy.GetExchangeManager(); VerifyOrReturnError(exchangeMgr != nullptr, CHIP_ERROR_INCORRECT_STATE); diff --git a/src/app/clusters/ota-requestor/OTARequestor.h b/src/app/clusters/ota-requestor/OTARequestor.h index 5a86bf20074c28..eeb931c999e880 100644 --- a/src/app/clusters/ota-requestor/OTARequestor.h +++ b/src/app/clusters/ota-requestor/OTARequestor.h @@ -287,8 +287,10 @@ class OTARequestor : public OTARequestorInterface, public BDXDownloader::StateDe BDXMessenger mBdxMessenger; // TODO: ideally this is held by the application uint8_t mUpdateTokenBuffer[kMaxUpdateTokenLen]; ByteSpan mUpdateToken; - uint32_t mCurrentVersion = 0; - uint32_t mTargetVersion = 0; + uint32_t mCurrentVersion = 0; + uint32_t mTargetVersion = 0; + char mFileDesignatorBuffer[bdx::kMaxFileDesignatorLen]; + CharSpan mFileDesignator; OTAUpdateStateEnum mCurrentUpdateState = OTAUpdateStateEnum::kIdle; Server * mServer = nullptr; chip::Optional mRequestorCanConsent; diff --git a/src/include/platform/OTARequestorDriver.h b/src/include/platform/OTARequestorDriver.h index 23df6d99c41716..3b6c87698e3a61 100644 --- a/src/include/platform/OTARequestorDriver.h +++ b/src/include/platform/OTARequestorDriver.h @@ -33,7 +33,8 @@ namespace chip { // The set of parameters needed for starting a BDX download. struct UpdateDescription { - CharSpan imageURI; + NodeId nodeId; + CharSpan fileDesignator; uint32_t softwareVersion; CharSpan softwareVersionStr; ByteSpan updateToken; diff --git a/src/protocols/bdx/BdxMessages.cpp b/src/protocols/bdx/BdxMessages.cpp index 3ac30d50912998..410e61d47cad02 100644 --- a/src/protocols/bdx/BdxMessages.cpp +++ b/src/protocols/bdx/BdxMessages.cpp @@ -31,8 +31,7 @@ #include namespace { -constexpr uint8_t kVersionMask = 0x0F; -constexpr uint8_t kMaxFileDesignatorLen = 32; +constexpr uint8_t kVersionMask = 0x0F; } // namespace using namespace chip; diff --git a/src/protocols/bdx/BdxMessages.h b/src/protocols/bdx/BdxMessages.h index ec76d97c6b5c82..d1fb419cc0f470 100644 --- a/src/protocols/bdx/BdxMessages.h +++ b/src/protocols/bdx/BdxMessages.h @@ -32,6 +32,8 @@ namespace chip { namespace bdx { +constexpr uint16_t kMaxFileDesignatorLen = 0xFF; + enum class MessageType : uint8_t { SendInit = 0x01, diff --git a/src/protocols/bdx/BdxTransferSession.h b/src/protocols/bdx/BdxTransferSession.h index bb2f456bed7f6b..a6ff92abc21409 100644 --- a/src/protocols/bdx/BdxTransferSession.h +++ b/src/protocols/bdx/BdxTransferSession.h @@ -298,6 +298,11 @@ class DLL_EXPORT TransferSession uint64_t GetTransferLength() const { return mTransferLength; } uint16_t GetTransferBlockSize() const { return mTransferMaxBlockSize; } size_t GetNumBytesProcessed() const { return mNumBytesProcessed; } + const uint8_t * GetFileDesignator(uint16_t & fileDesignatorLen) const + { + fileDesignatorLen = mTransferRequestData.FileDesLength; + return mTransferRequestData.FileDesignator; + } TransferSession();