Skip to content

Commit

Permalink
Handle the output event of type TransferSession::OutputEventType::kIn… (
Browse files Browse the repository at this point in the history
project-chip#37324)

* Handle the output event of type TransferSession::OutputEventType::kInternalError in the ProcessOuputEvents processing loop

- The transfer session state machine generates an output event of type TransferSession::OutputEventType::kInternalError in
certain error scenarios which put the transfer session in a bad state and when that happens, we need to unwind the processing
loop for events and clean up.

* Update src/protocols/bdx/AsyncTransferFacilitator.cpp

Co-authored-by: Boris Zbarsky <[email protected]>

* Address review comments

* Update src/protocols/bdx/AsyncTransferFacilitator.cpp

Co-authored-by: Boris Zbarsky <[email protected]>

---------

Co-authored-by: Boris Zbarsky <[email protected]>
  • Loading branch information
2 people authored and yufengwangca committed Feb 4, 2025
1 parent 92f71c4 commit 796f169
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 171 deletions.
164 changes: 2 additions & 162 deletions .github/workflows/examples-linux-standalone.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,170 +55,9 @@ jobs:
with:
gh-context: ${{ toJson(github) }}

- name: Build Standalone cert tool
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-chip-cert \
build"
- name: Build minmdns example with platform dns
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-address-resolve-tool-platform-mdns-ipv6only \
build"
- name: Build example Standalone chip tool
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-chip-tool \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug chip-tool \
out/linux-x64-chip-tool/chip-tool \
/tmp/bloat_reports/
- name: Build example Standalone Shell
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-shell \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug shell \
out/linux-x64-shell/chip-shell \
/tmp/bloat_reports/
- name: Build example Standalone All Clusters Server
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-all-clusters \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug all-clusters-app \
out/linux-x64-all-clusters/chip-all-clusters-app \
/tmp/bloat_reports/
- name: Clean out build output
run: rm -rf ./out
- name: Build example Standalone All Clusters Minimal Server
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-all-clusters-minimal \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug all-clusters-minimal-app \
out/linux-x64-all-clusters-minimal/chip-all-clusters-minimal-app \
/tmp/bloat_reports/
- name: Build example TV app
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-tv-app \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug tv-app \
out/linux-x64-tv-app/chip-tv-app \
/tmp/bloat_reports/
- name: Build example Standalone TV Casting App
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-tv-casting-app \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug tv-casting-app \
out/linux-x64-tv-casting-app/chip-tv-casting-app \
/tmp/bloat_reports/
- name: Build example lighting app with RPCs and UI
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-light-rpc-with-ui \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug+rpc+ui lighting-app \
out/linux-x64-light-rpc-with-ui/chip-lighting-app \
/tmp/bloat_reports/
- name: Clean out build output
run: rm -rf ./out
- name: Build example Standalone Bridge
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-bridge \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug bridge-app \
out/linux-x64-bridge/chip-bridge-app \
/tmp/bloat_reports/
- name: Build example OTA Provider
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-ota-provider \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug ota-provider-app \
out/linux-x64-ota-provider/chip-ota-provider-app \
/tmp/bloat_reports/
- name: Build example OTA Requestor
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-ota-requestor \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug ota-requestor-app \
out/linux-x64-ota-requestor/chip-ota-requestor-app \
/tmp/bloat_reports/
- name: Clean out build output
run: rm -rf ./out
- name: Build example Standalone Lock App
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-lock-no-thread \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug lock-app \
out/linux-x64-lock-no-thread/chip-lock-app \
/tmp/bloat_reports/
- name: Build example contact sensor with UI
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-contact-sensor-no-ble-with-ui \
build"
- name: Build example Air Purifier
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-air-purifier \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug air-purifier-app \
out/linux-x64-air-purifier/chip-air-purifier-app \
/tmp/bloat_reports/
- name: Build example Fabric Admin
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-fabric-admin-rpc \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug fabric-admin \
out/linux-x64-fabric-admin-rpc/fabric-admin \
/tmp/bloat_reports/
- name: Build example Fabric Bridge App
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--target linux-x64-fabric-bridge-no-ble-rpc \
build"
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
linux debug fabric-bridge-app \
out/linux-x64-fabric-bridge-no-ble-rpc/fabric-bridge-app \
/tmp/bloat_reports/

- name: Build example Fabric Sync
run: |
./scripts/run_in_build_env.sh \
Expand All @@ -229,6 +68,7 @@ jobs:
linux debug fabric-sync \
out/linux-x64-fabric-sync-no-ble/fabric-sync \
/tmp/bloat_reports/
- name: Uploading Size Reports
uses: ./.github/actions/upload-size-reports
if: ${{ !env.ACT }}
Expand Down
30 changes: 22 additions & 8 deletions src/protocols/bdx/AsyncTransferFacilitator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ void AsyncTransferFacilitator::ProcessOutputEvents()
mTransfer.GetNextAction(outEvent);
while (outEvent.EventType != TransferSession::OutputEventType::kNone)
{

// If the transfer session state machine generates an event of type TransferSession::OutputEventType::kInternalError,
// indicating that the session is in a bad state, it will keep doing that thereafter.
//
// So stop trying to process events, and go ahead and destroy ourselves to clean up the transfer.
if (outEvent.EventType == TransferSession::OutputEventType::kInternalError)
{
mDestroySelfAfterProcessingEvents = true;
break;
}

if (outEvent.EventType == TransferSession::OutputEventType::kMsgToSend)
{
CHIP_ERROR err = SendMessage(outEvent.msgTypeData, outEvent.MsgData);
Expand Down Expand Up @@ -170,22 +181,25 @@ void AsyncResponder::NotifyEventHandled(const TransferSession::OutputEventType e
ChipLogDetail(BDX, "NotifyEventHandled : Event %s Error %" CHIP_ERROR_FORMAT,
TransferSession::OutputEvent::TypeToString(eventType), status.Format());

// If this is the end of the transfer (whether a clean end, or some sort of error condition), ensure that
// we destroy ourselves after processing any output events that might have been generated by
// the transfer session to handle end-of-transfer (e.g. in some error conditions it might want to send
// out a status report).
// If this is the end of the transfer (whether a clean end, or some sort of error condition), ensure
// that we destroy ourselves after unwinding the processing loop in the ProcessOutputEvents API.
// We can ignore the status for these output events because none of them are supposed to result in
// us sending a StatusReport, and that's all we use the status for.
//
// In particular, for kTransferTimeout, kAckEOFReceived, and kStatusReceived per spec we
// are not supposed to reply with a StatusReport. And for kInternalError the state machine
// is in an unrecoverable state of some sort, and we should stop trying to make use of it.
if (eventType == TransferSession::OutputEventType::kAckEOFReceived ||
eventType == TransferSession::OutputEventType::kInternalError ||
eventType == TransferSession::OutputEventType::kTransferTimeout ||
eventType == TransferSession::OutputEventType::kStatusReceived)
{
mDestroySelfAfterProcessingEvents = true;
}

// If there was an error handling the output event, this should notify the transfer object to abort transfer so it can send a
// status report across the exchange when we call ProcessOutputEvents below.
if (status != CHIP_NO_ERROR)
else if (status != CHIP_NO_ERROR)
{
// If there was an error handling the output event, this should notify the transfer object to abort transfer
// so it can send a status report across the exchange when we call ProcessOutputEvents below.
mTransfer.AbortTransfer(GetBdxStatusCodeFromChipError(status));
}

Expand Down
4 changes: 3 additions & 1 deletion src/protocols/bdx/AsyncTransferFacilitator.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ class AsyncTransferFacilitator : public Messaging::ExchangeDelegate
*/
virtual void DestroySelf() = 0;

// Calling ProcessOutputEvents can destroy this object before the call returns.
/**
* Calling ProcessOutputEvents can destroy this object before the call returns.
*/
void ProcessOutputEvents();

// The transfer session corresponding to this AsyncTransferFacilitator object.
Expand Down

0 comments on commit 796f169

Please sign in to comment.