Skip to content

Commit

Permalink
Added Node and fabric data to BDXOtaSender to keep track of connectio…
Browse files Browse the repository at this point in the history
…ns (#16184)
  • Loading branch information
harsha-rajendran authored and pull[bot] committed Dec 7, 2023
1 parent ad610a2 commit ca2260f
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 10 deletions.
31 changes: 31 additions & 0 deletions examples/ota-provider-app/esp32/main/BdxOtaSender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,32 @@ using chip::bdx::StatusCode;
using chip::bdx::TransferControlFlags;
using chip::bdx::TransferSession;

CHIP_ERROR BdxOtaSender::InitializeTransfer(chip::FabricIndex fabricIndex, chip::NodeId nodeId)
{
if (mInitialized)
{
// Reset stale connection from the Same Node if exists
if ((mFabricIndex.HasValue() && mFabricIndex.Value() == fabricIndex) && (mNodeId.HasValue() && mNodeId.Value() == nodeId))
{
Reset();
}
// Prevent a new node connection since another is active
else if ((mFabricIndex.HasValue() && mFabricIndex.Value() != fabricIndex) ||
(mNodeId.HasValue() && mNodeId.Value() != nodeId))
{
return CHIP_ERROR_BUSY;
}
else
{
return CHIP_ERROR_INTERNAL;
}
}
mFabricIndex.SetValue(fabricIndex);
mNodeId.SetValue(nodeId);
mInitialized = true;
return CHIP_NO_ERROR;
}

void BdxOtaSender::SetCallbacks(BdxOtaSenderCallbacks callbacks)
{
mOnBlockQueryCallback = callbacks.onBlockQuery;
Expand Down Expand Up @@ -174,11 +200,16 @@ void BdxOtaSender::HandleTransferSessionOutput(TransferSession::OutputEvent & ev

void BdxOtaSender::Reset()
{
mFabricIndex.ClearValue();
mNodeId.ClearValue();
mTransfer.Reset();
if (mExchangeCtx != nullptr)
{
mExchangeCtx->Close();
mExchangeCtx = nullptr;
}

mInitialized = false;
mNumBytesSent = 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ struct BdxOtaSenderCallbacks
class BdxOtaSender : public chip::bdx::Responder
{
public:
// Initializes BDX transfer-related metadata. Should always be called first.
CHIP_ERROR InitializeTransfer(chip::FabricIndex fabricIndex, chip::NodeId nodeId);

void SetCallbacks(BdxOtaSenderCallbacks callbacks);

/**
Expand All @@ -97,6 +100,12 @@ class BdxOtaSender : public chip::bdx::Responder

uint32_t mNumBytesSent = 0;

bool mInitialized = false;

chip::Optional<chip::FabricIndex> mFabricIndex;

chip::Optional<chip::NodeId> mNodeId;

chip::Callback::Callback<OnBdxBlockQuery> * mOnBlockQueryCallback = nullptr;
chip::Callback::Callback<OnBdxTransferComplete> * mOnTransferCompleteCallback = nullptr;
chip::Callback::Callback<OnBdxTransferFailed> * mOnTransferFailedCallback = nullptr;
Expand Down
30 changes: 30 additions & 0 deletions examples/ota-provider-app/ota-provider-common/BdxOtaSender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,32 @@ BdxOtaSender::BdxOtaSender()
memset(mFileDesignator, 0, chip::bdx::kMaxFileDesignatorLen);
}

CHIP_ERROR BdxOtaSender::InitializeTransfer(chip::FabricIndex fabricIndex, chip::NodeId nodeId)
{
if (mInitialized)
{
// Reset stale connection from the Same Node if exists
if ((mFabricIndex.HasValue() && mFabricIndex.Value() == fabricIndex) && (mNodeId.HasValue() && mNodeId.Value() == nodeId))
{
Reset();
}
// Prevent a new node connection since another is active
else if ((mFabricIndex.HasValue() && mFabricIndex.Value() != fabricIndex) ||
(mNodeId.HasValue() && mNodeId.Value() != nodeId))
{
return CHIP_ERROR_BUSY;
}
else
{
return CHIP_ERROR_INTERNAL;
}
}
mFabricIndex.SetValue(fabricIndex);
mNodeId.SetValue(nodeId);
mInitialized = true;
return CHIP_NO_ERROR;
}

void BdxOtaSender::HandleTransferSessionOutput(TransferSession::OutputEvent & event)
{
CHIP_ERROR err = CHIP_NO_ERROR;
Expand Down Expand Up @@ -152,12 +178,16 @@ void BdxOtaSender::HandleTransferSessionOutput(TransferSession::OutputEvent & ev

void BdxOtaSender::Reset()
{
mFabricIndex.ClearValue();
mNodeId.ClearValue();
mTransfer.Reset();
if (mExchangeCtx != nullptr)
{
mExchangeCtx->Close();
mExchangeCtx = nullptr;
}

mInitialized = false;
mNumBytesSent = 0;
memset(mFileDesignator, 0, chip::bdx::kMaxFileDesignatorLen);
}
9 changes: 9 additions & 0 deletions examples/ota-provider-app/ota-provider-common/BdxOtaSender.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class BdxOtaSender : public chip::bdx::Responder
public:
BdxOtaSender();

// Initializes BDX transfer-related metadata. Should always be called first.
CHIP_ERROR InitializeTransfer(chip::FabricIndex fabricIndex, chip::NodeId nodeId);

private:
// Inherited from bdx::TransferFacilitator
void HandleTransferSessionOutput(chip::bdx::TransferSession::OutputEvent & event) override;
Expand All @@ -35,4 +38,10 @@ class BdxOtaSender : public chip::bdx::Responder
char mFileDesignator[chip::bdx::kMaxFileDesignatorLen];

uint32_t mNumBytesSent = 0;

bool mInitialized = false;

chip::Optional<chip::FabricIndex> mFabricIndex;

chip::Optional<chip::NodeId> mNodeId;
};
Original file line number Diff line number Diff line change
Expand Up @@ -270,18 +270,27 @@ EmberAfStatus OTAProviderExample::HandleQueryImage(chip::app::CommandHandler * c
// Initialize the transfer session in prepartion for a BDX transfer
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)
if (mBdxOtaSender.InitializeTransfer(commandObj->GetSubjectDescriptor().fabricIndex,
commandObj->GetSubjectDescriptor().subject) == CHIP_NO_ERROR)
{
ChipLogError(BDX, "Failed to initialize BDX transfer session: %s", chip::ErrorStr(err));
return EMBER_ZCL_STATUS_FAILURE;
}
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;
}

response.imageURI.Emplace(chip::CharSpan::fromCharString(uriBuf));
response.softwareVersion.Emplace(newSoftwareVersion);
response.softwareVersionString.Emplace(chip::CharSpan::fromCharString(newSoftwareVersionString));
response.updateToken.Emplace(chip::ByteSpan(updateToken));
response.imageURI.Emplace(chip::CharSpan::fromCharString(uriBuf));
response.softwareVersion.Emplace(newSoftwareVersion);
response.softwareVersionString.Emplace(chip::CharSpan::fromCharString(newSoftwareVersionString));
response.updateToken.Emplace(chip::ByteSpan(updateToken));
}
else
{
// Another BDX transfer in progress
queryStatus = OTAQueryStatus::kBusy;
}
}

response.status = queryStatus;
Expand Down
3 changes: 3 additions & 0 deletions src/lib/core/CHIPError.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,9 @@ bool FormatCHIPError(char * buf, uint16_t bufSize, CHIP_ERROR err)
case CHIP_ERROR_IM_MALFORMED_TIMED_REQUEST_MESSAGE.AsInteger():
desc = "Malformed Interaction Model Timed Request Message";
break;
case CHIP_ERROR_BUSY.AsInteger():
desc = "The Resource is busy and cannot process the request";
break;
}
#endif // !CHIP_CONFIG_SHORT_ERROR_STR

Expand Down
9 changes: 9 additions & 0 deletions src/lib/core/CHIPError.h
Original file line number Diff line number Diff line change
Expand Up @@ -2400,6 +2400,15 @@ using CHIP_ERROR = ::chip::ChipError;
*/
#define CHIP_ERROR_INVALID_FILE_IDENTIFIER CHIP_CORE_ERROR(0xda)

/**
* @def CHIP_ERROR_BUSY
*
* @brief
* The Resource is busy and cannot process the request. Trying again might work.
*/
#define CHIP_ERROR_BUSY CHIP_CORE_ERROR(0xdb)


/**
* @}
*/
Expand Down

0 comments on commit ca2260f

Please sign in to comment.