From 4eace79c989ac42f01169504cc5bb420837c1a2e Mon Sep 17 00:00:00 2001 From: hemanth-silabs <50145824+hemanth-silabs@users.noreply.github.com> Date: Wed, 5 Jul 2023 13:01:22 -0400 Subject: [PATCH] [spinel] return error from `SaveFrame` if not enough space is available (#9244) --- src/lib/spinel/multi_frame_buffer.hpp | 25 +++++++++++++++++++------ src/lib/spinel/radio_spinel_impl.hpp | 11 ++++++----- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/lib/spinel/multi_frame_buffer.hpp b/src/lib/spinel/multi_frame_buffer.hpp index 9a374cd6a..2c90d9069 100644 --- a/src/lib/spinel/multi_frame_buffer.hpp +++ b/src/lib/spinel/multi_frame_buffer.hpp @@ -309,14 +309,27 @@ public: * * Saved frame can be retrieved later using `GetNextSavedFrame()`. * + * @retval OT_ERROR_NONE Successfully saved the buffer and prepared the write pointer for the next frame. + * @retval OT_ERROR_NO_BUFS Insufficient buffer space. */ - void SaveFrame(void) + otError SaveFrame(void) { - Encoding::LittleEndian::WriteUint16(GetSkipLength() + GetLength(), mWriteFrameStart + kHeaderTotalLengthOffset); - mWriteFrameStart = mWritePointer; - IgnoreError(SetSkipLength(0)); - mWritePointer = GetFrame(); - mRemainingLength = static_cast(mBuffer + kSize - mWritePointer); + otError error = OT_ERROR_NONE; + + // If the next header will overflow the buffer, we can't save the frame. + if (!CanWrite(kHeaderSize)) + { + error = OT_ERROR_NO_BUFS; + } + else + { + Encoding::LittleEndian::WriteUint16(GetSkipLength() + GetLength(), + mWriteFrameStart + kHeaderTotalLengthOffset); + mWriteFrameStart = mWritePointer; + IgnoreError(SetSkipLength(0)); + } + + return error; } /** diff --git a/src/lib/spinel/radio_spinel_impl.hpp b/src/lib/spinel/radio_spinel_impl.hpp index 35e7baa42..02898e5a7 100644 --- a/src/lib/spinel/radio_spinel_impl.hpp +++ b/src/lib/spinel/radio_spinel_impl.hpp @@ -530,13 +530,14 @@ void RadioSpinel::HandleNotification(SpinelInterface::RxFrameBuff } exit: - if (shouldSaveFrame) - { - aFrameBuffer.SaveFrame(); - } - else + if (!shouldSaveFrame || aFrameBuffer.SaveFrame() != OT_ERROR_NONE) { aFrameBuffer.DiscardFrame(); + + if (shouldSaveFrame) + { + otLogCritPlat("RX Spinel buffer full, dropped incoming frame"); + } } UpdateParseErrorCount(error);