-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Integrate BDX and ExchangeDelegate (#8514)
* BdxEndpoint class for ExchangeContext integration * restyling and small comment change * Add CONFIG_DEVICE_LAYER compile guards around SystemLayer::StartTimer * initialize with System::Layer pointer instead of using DeviceLayer * remove unnecessary chip::bdx:: prefix Co-authored-by: Boris Zbarsky <[email protected]> * Rename Endpoint to TransferFacilitator * call WillSendMessage() for every received BDX message * restyle BUILD.gn * fix comment spelling Co-authored-by: Boris Zbarsky <[email protected]> Co-authored-by: Boris Zbarsky <[email protected]>
- Loading branch information
1 parent
5f3f225
commit 77c1c53
Showing
3 changed files
with
257 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* | ||
* | ||
* Copyright (c) 2021 Project CHIP Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "TransferFacilitator.h" | ||
|
||
#include <core/CHIPError.h> | ||
#include <messaging/ExchangeContext.h> | ||
#include <messaging/ExchangeDelegate.h> | ||
#include <platform/CHIPDeviceLayer.h> | ||
#include <protocols/bdx/BdxTransferSession.h> | ||
#include <support/BitFlags.h> | ||
#include <system/SystemClock.h> | ||
#include <system/SystemLayer.h> | ||
|
||
namespace chip { | ||
namespace bdx { | ||
|
||
CHIP_ERROR TransferFacilitator::OnMessageReceived(chip::Messaging::ExchangeContext * ec, const chip::PacketHeader & packetHeader, | ||
const chip::PayloadHeader & payloadHeader, | ||
chip::System::PacketBufferHandle && payload) | ||
{ | ||
if (mExchangeCtx == nullptr) | ||
{ | ||
mExchangeCtx = ec; | ||
} | ||
|
||
ChipLogDetail(BDX, "%s: message 0x%x protocol %u", __FUNCTION__, static_cast<uint8_t>(payloadHeader.GetMessageType()), | ||
payloadHeader.GetProtocolID().GetProtocolId()); | ||
CHIP_ERROR err = | ||
mTransfer.HandleMessageReceived(payloadHeader, std::move(payload), System::Platform::Clock::GetMonotonicMilliseconds()); | ||
if (err != CHIP_NO_ERROR) | ||
{ | ||
ChipLogError(BDX, "failed to handle message: %s", ErrorStr(err)); | ||
} | ||
|
||
// Almost every BDX message will follow up with a response on the exchange. Even messages that might signify the end of a | ||
// transfer could necessitate a response if they are received at the wrong time. | ||
// For this reason, it is left up to the application logic to call ExchangeContext::Close() when it has determined that the | ||
// transfer is finished. | ||
mExchangeCtx->WillSendMessage(); | ||
|
||
return err; | ||
} | ||
|
||
void TransferFacilitator::OnResponseTimeout(Messaging::ExchangeContext * ec) | ||
{ | ||
ChipLogError(BDX, "%s, ec: %d", __FUNCTION__, ec->GetExchangeId()); | ||
mExchangeCtx = nullptr; | ||
mTransfer.Reset(); | ||
} | ||
|
||
void TransferFacilitator::PollTimerHandler(chip::System::Layer * systemLayer, void * appState, CHIP_ERROR error) | ||
{ | ||
VerifyOrReturn(appState != nullptr); | ||
static_cast<TransferFacilitator *>(appState)->PollForOutput(); | ||
} | ||
|
||
void TransferFacilitator::PollForOutput() | ||
{ | ||
TransferSession::OutputEvent outEvent; | ||
mTransfer.PollOutput(outEvent, System::Platform::Clock::GetMonotonicMilliseconds()); | ||
HandleTransferSessionOutput(outEvent); | ||
|
||
VerifyOrReturn(mSystemLayer != nullptr, ChipLogError(BDX, "%s mSystemLayer is null", __FUNCTION__)); | ||
mSystemLayer->StartTimer(mPollFreqMs, PollTimerHandler, this); | ||
} | ||
|
||
void TransferFacilitator::ScheduleImmediatePoll() | ||
{ | ||
VerifyOrReturn(mSystemLayer != nullptr, ChipLogError(BDX, "%s mSystemLayer is null", __FUNCTION__)); | ||
mSystemLayer->StartTimer(kImmediatePollDelayMs, PollTimerHandler, this); | ||
} | ||
|
||
CHIP_ERROR Responder::PrepareForTransfer(System::Layer * layer, TransferRole role, BitFlags<TransferControlFlags> xferControlOpts, | ||
uint16_t maxBlockSize, uint32_t timeoutMs, uint32_t pollFreqMs) | ||
{ | ||
VerifyOrReturnError(layer != nullptr, CHIP_ERROR_INVALID_ARGUMENT); | ||
|
||
mPollFreqMs = pollFreqMs; | ||
mSystemLayer = layer; | ||
|
||
ReturnErrorOnFailure(mTransfer.WaitForTransfer(role, xferControlOpts, maxBlockSize, timeoutMs)); | ||
|
||
mSystemLayer->StartTimer(mPollFreqMs, PollTimerHandler, this); | ||
return CHIP_NO_ERROR; | ||
} | ||
|
||
CHIP_ERROR Initiator::InitiateTransfer(System::Layer * layer, TransferRole role, const TransferSession::TransferInitData & initData, | ||
uint32_t timeoutMs, uint32_t pollFreqMs) | ||
{ | ||
VerifyOrReturnError(layer != nullptr, CHIP_ERROR_INVALID_ARGUMENT); | ||
|
||
mPollFreqMs = pollFreqMs; | ||
mSystemLayer = layer; | ||
|
||
ReturnErrorOnFailure(mTransfer.StartTransfer(role, initData, timeoutMs)); | ||
|
||
mSystemLayer->StartTimer(mPollFreqMs, PollTimerHandler, this); | ||
return CHIP_NO_ERROR; | ||
} | ||
|
||
} // namespace bdx | ||
} // namespace chip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
/* | ||
* | ||
* Copyright (c) 2021 Project CHIP Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
/** | ||
* @file BdxEndpoint.h | ||
* | ||
* This file defines interfaces for connecting the BDX state machine (TransferSession) to the messaging layer. | ||
*/ | ||
|
||
#include <core/CHIPError.h> | ||
#include <messaging/ExchangeContext.h> | ||
#include <messaging/ExchangeDelegate.h> | ||
#include <protocols/bdx/BdxTransferSession.h> | ||
#include <support/BitFlags.h> | ||
#include <system/SystemLayer.h> | ||
|
||
#pragma once | ||
|
||
namespace chip { | ||
namespace bdx { | ||
|
||
/** | ||
* An abstract class with methods for handling BDX messages from an ExchangeContext and polling a TransferSession state machine. | ||
* | ||
* This class does not define any methods for beginning a transfer or initializing the underlying TransferSession object (see | ||
* Initiator and Responder below). | ||
* This class contains a repeating timer which regurlaly polls the TransferSession state machine. | ||
* A CHIP node may have many TransferFacilitator instances but only one TransferFacilitator should be used for each BDX transfer. | ||
*/ | ||
class TransferFacilitator : public Messaging::ExchangeDelegate | ||
{ | ||
public: | ||
TransferFacilitator() : mExchangeCtx(nullptr), mSystemLayer(nullptr), mPollFreqMs(kDefaultPollFreqMs) {} | ||
~TransferFacilitator() = default; | ||
|
||
private: | ||
// Inherited from ExchangeContext | ||
CHIP_ERROR OnMessageReceived(chip::Messaging::ExchangeContext * ec, const chip::PacketHeader & packetHeader, | ||
const chip::PayloadHeader & payloadHeader, chip::System::PacketBufferHandle && payload) override; | ||
void OnResponseTimeout(Messaging::ExchangeContext * ec) override; | ||
|
||
/** | ||
* This method should be implemented to contain business-logic handling of BDX messages and other TransferSession events. | ||
* | ||
* NOTE: It is the responsiblity of the implementer to Close the underlying ExchangeContext when it has determined that the | ||
* transfer is finished. This class assumes that a response message will be sent for all received messages. | ||
* | ||
* @param[in] event An OutputEvent that contains output from the TransferSession object. | ||
*/ | ||
virtual void HandleTransferSessionOutput(TransferSession::OutputEvent & event) = 0; | ||
|
||
protected: | ||
/** | ||
* The callback for when the poll timer expires. The poll timer regulates how often the TransferSession is polled. | ||
*/ | ||
static void PollTimerHandler(chip::System::Layer * systemLayer, void * appState, CHIP_ERROR error); | ||
|
||
/** | ||
* Polls the TransferSession object and calls HandleTransferSessionOutput. | ||
*/ | ||
void PollForOutput(); | ||
|
||
/** | ||
* Starts the poll timer with a very short timeout. | ||
*/ | ||
void ScheduleImmediatePoll(); | ||
|
||
TransferSession mTransfer; | ||
Messaging::ExchangeContext * mExchangeCtx; | ||
System::Layer * mSystemLayer; | ||
uint32_t mPollFreqMs; | ||
static constexpr uint32_t kDefaultPollFreqMs = 500; | ||
static constexpr uint32_t kImmediatePollDelayMs = 1; | ||
}; | ||
|
||
/** | ||
* A TransferFacilitator that is initialized to respond to an incoming BDX transfer request. | ||
* | ||
* Provides a method for initializing the TransferSession member but still needs to be extended to implement | ||
* HandleTransferSessionOutput. It is intended that this class will be used as a delegate for handling an unsolicited BDX message. | ||
*/ | ||
class Responder : public TransferFacilitator | ||
{ | ||
public: | ||
/** | ||
* Initialize the TransferSession state machine to be ready for an incoming transfer request, and start the polling timer. | ||
* | ||
* @param[in] layer A System::Layer pointer to use to start the polling timer | ||
* @param[in] role The role of the Responder: Sender or Receiver of BDX data | ||
* @param[in] xferControlOpts Supported transfer modes (see TransferControlFlags) | ||
* @param[in] maxBlockSize The supported maximum size of BDX Block data | ||
* @param[in] timeoutMs The chosen timeout delay for the BDX transfer in milliseconds | ||
* @param[in] pollFreqMs The period for the TransferSession poll timer in milliseconds | ||
*/ | ||
CHIP_ERROR PrepareForTransfer(System::Layer * layer, TransferRole role, BitFlags<TransferControlFlags> xferControlOpts, | ||
uint16_t maxBlockSize, uint32_t timeoutMs, | ||
uint32_t pollFreqMs = TransferFacilitator::kDefaultPollFreqMs); | ||
}; | ||
|
||
/** | ||
* A TransferFacilitator that initiates a BDX transfer. | ||
* | ||
* Provides a method for initializing the TransferSession member (thus beginning the transfer) but still needs to be extended to | ||
* implement HandleTransferSessionOutput. | ||
*/ | ||
class Initiator : public TransferFacilitator | ||
{ | ||
public: | ||
/** | ||
* Initialize the TransferSession state machine to prepare a transfer request message (does not send the message) and start the | ||
* poll timer. | ||
* | ||
* @param[in] layer A System::Layer pointer to use to start the polling timer | ||
* @param[in] role The role of the Initiator: Sender or Receiver of BDX data | ||
* @param[in] initData Data needed for preparing a transfer request BDX message | ||
* @param[in] timeoutMs The chosen timeout delay for the BDX transfer in milliseconds | ||
* @param[in] pollFreqMs The period for the TransferSession poll timer in milliseconds | ||
*/ | ||
CHIP_ERROR InitiateTransfer(System::Layer * layer, TransferRole role, const TransferSession::TransferInitData & initData, | ||
uint32_t timeoutMs, uint32_t pollFreqMs = TransferFacilitator::kDefaultPollFreqMs); | ||
}; | ||
|
||
} // namespace bdx | ||
} // namespace chip |