From 9d4af7b4ae326e7a689b3808b5cb733b7cc793e8 Mon Sep 17 00:00:00 2001 From: mahesh Date: Mon, 23 Dec 2024 12:49:53 +0530 Subject: [PATCH] diagnostic-buffer: clear buffer after successful bdx log transfer - Add related logic in temperature-measurement-app --- ...diagnostic-logs-provider-delegate-impl.cpp | 28 ++++++++--- .../DiagnosticStorageManager.h | 48 ++++++++++++------- .../esp32_diagnostic_trace/Diagnostics.h | 2 +- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/examples/temperature-measurement-app/esp32/main/diagnostic-logs-provider-delegate-impl.cpp b/examples/temperature-measurement-app/esp32/main/diagnostic-logs-provider-delegate-impl.cpp index 0eb21e349c96fe..5cc6d8f1b7ece5 100644 --- a/examples/temperature-measurement-app/esp32/main/diagnostic-logs-provider-delegate-impl.cpp +++ b/examples/temperature-measurement-app/esp32/main/diagnostic-logs-provider-delegate-impl.cpp @@ -29,6 +29,10 @@ using namespace chip::app::Clusters::DiagnosticLogs; LogProvider LogProvider::sInstance; LogProvider::CrashLogContext LogProvider::sCrashLogContext; +#if CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE +static uint32_t read_entries = 0; +#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE + namespace { bool IsValidIntent(IntentEnum intent) { @@ -116,14 +120,17 @@ CHIP_ERROR LogProvider::PrepareLogContextForIntent(LogContext * context, IntentE case IntentEnum::kEndUserSupport: { #if CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE CircularDiagnosticBuffer & diagnosticStorage = CircularDiagnosticBuffer::GetInstance(); - MutableByteSpan endUserSupportSpan(endUserBuffer, CONFIG_END_USER_BUFFER_SIZE); + MutableByteSpan endUserSupportSpan(endUserBuffer, 2048); VerifyOrReturnError(!diagnosticStorage.IsEmptyBuffer(), CHIP_ERROR_NOT_FOUND, ChipLogError(DeviceLayer, "Empty Diagnostic buffer")); // Retrieve data from the diagnostic storage - CHIP_ERROR err = diagnosticStorage.Retrieve(endUserSupportSpan); - VerifyOrReturnError(err == CHIP_NO_ERROR, err, - ChipLogError(DeviceLayer, "Failed to retrieve data: %s", chip::ErrorStr(err))); + CHIP_ERROR err = diagnosticStorage.Retrieve(endUserSupportSpan, read_entries); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to retrieve data: %s", chip::ErrorStr(err)); + return err; + } context->EndUserSupport.span = endUserSupportSpan; #else context->EndUserSupport.span = @@ -297,11 +304,18 @@ CHIP_ERROR LogProvider::StartLogCollection(IntentEnum intent, LogSessionHandle & CHIP_ERROR LogProvider::EndLogCollection(LogSessionHandle sessionHandle, CHIP_ERROR error) { - if (error != CHIP_NO_ERROR) + #ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE + if (error == CHIP_NO_ERROR) { - // Handle the error - ChipLogProgress(DeviceLayer, "End log collection reason: %s", ErrorStr(error)); + CHIP_ERROR err = CircularDiagnosticBuffer::GetInstance().ClearReadMemory(read_entries); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to clear diagnostic read entries"); + } + ChipLogProgress(DeviceLayer, "Clear all read diagnostics successfully"); } + #endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE + VerifyOrReturnValue(sessionHandle != kInvalidLogSessionHandle, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnValue(mSessionContextMap.count(sessionHandle), CHIP_ERROR_INVALID_ARGUMENT); diff --git a/src/tracing/esp32_diagnostic_trace/DiagnosticStorageManager.h b/src/tracing/esp32_diagnostic_trace/DiagnosticStorageManager.h index 723a25e9654c9e..d5bd22f0ecaec4 100644 --- a/src/tracing/esp32_diagnostic_trace/DiagnosticStorageManager.h +++ b/src/tracing/esp32_diagnostic_trace/DiagnosticStorageManager.h @@ -54,7 +54,7 @@ class CircularDiagnosticBuffer : public chip::TLV::TLVCircularBuffer, public Dia return err; } - CHIP_ERROR Retrieve(MutableByteSpan & span) override + CHIP_ERROR Retrieve(MutableByteSpan & span, uint32_t & read_entries) override { CHIP_ERROR err = CHIP_NO_ERROR; chip::TLV::TLVReader reader; @@ -62,43 +62,45 @@ class CircularDiagnosticBuffer : public chip::TLV::TLVCircularBuffer, public Dia chip::TLV::TLVWriter writer; writer.Init(span.data(), span.size()); + read_entries = 0; + + bool close_success = true; // To check if the last TLV is copied successfully. + uint32_t successful_written_bytes = 0; // Store temporary writer length in case last TLV is not copied successfully. chip::TLV::TLVType outWriterContainer = chip::TLV::kTLVType_NotSpecified; ReturnErrorOnFailure(writer.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_List, outWriterContainer)); while (CHIP_NO_ERROR == reader.Next()) { - VerifyOrReturnError(err == CHIP_NO_ERROR, err, - ChipLogError(DeviceLayer, "Failed to read next TLV element: %s", ErrorStr(err))); - if (reader.GetType() == chip::TLV::kTLVType_Structure && reader.GetTag() == chip::TLV::AnonymousTag()) { - if ((reader.GetLengthRead() - writer.GetLengthWritten()) < ((writer.GetRemainingFreeLength() + TLV_CLOSING_BYTE))) + err = writer.CopyElement(reader); + if (err == CHIP_NO_ERROR) { - err = writer.CopyElement(reader); - if (err == CHIP_ERROR_BUFFER_TOO_SMALL) - { - ChipLogProgress(DeviceLayer, "Buffer too small to occupy current element"); - break; - } + successful_written_bytes = writer.GetLengthWritten(); + read_entries++; } else { - ChipLogProgress(DeviceLayer, "Buffer too small to occupy current TLV"); + close_success = false; + ChipLogError(DeviceLayer, "Failed to copy TLV element: %s", ErrorStr(err)); break; } - VerifyOrReturnError(err == CHIP_NO_ERROR, err, ChipLogError(DeviceLayer, "Failed to copy TLV element")); } else { - ChipLogError(DeviceLayer, "Unexpected TLV element type or tag in outer container"); + ChipLogError(DeviceLayer, "Skipping unexpected TLV element"); } } ReturnErrorOnFailure(writer.EndContainer(outWriterContainer)); ReturnErrorOnFailure(writer.Finalize()); - span.reduce_size(writer.GetLengthWritten()); - ChipLogProgress(DeviceLayer, "---------------Total Retrieved bytes : %ld----------------\n", writer.GetLengthWritten()); + if (close_success) + { + successful_written_bytes = writer.GetLengthWritten(); + } + span.reduce_size(successful_written_bytes); + ChipLogProgress(DeviceLayer, "---------------Total Retrieved bytes : %ld----------------\n", successful_written_bytes); return CHIP_NO_ERROR; } @@ -106,6 +108,20 @@ class CircularDiagnosticBuffer : public chip::TLV::TLVCircularBuffer, public Dia uint32_t GetDataSize() override { return DataLength(); } + CHIP_ERROR ClearReadMemory(uint32_t entries) + { + CHIP_ERROR err = CHIP_NO_ERROR; + while (entries--) + { + err = EvictHead(); + if (err != CHIP_NO_ERROR) + { + break; + } + } + return err; + } + private: CircularDiagnosticBuffer() : chip::TLV::TLVCircularBuffer(nullptr, 0) {} ~CircularDiagnosticBuffer() override = default; diff --git a/src/tracing/esp32_diagnostic_trace/Diagnostics.h b/src/tracing/esp32_diagnostic_trace/Diagnostics.h index d035467d8909ca..44361c9d2f5db0 100644 --- a/src/tracing/esp32_diagnostic_trace/Diagnostics.h +++ b/src/tracing/esp32_diagnostic_trace/Diagnostics.h @@ -107,7 +107,7 @@ class DiagnosticStorageInterface * diagnostic data will be stored. * @return CHIP_ERROR Returns CHIP_NO_ERROR on success, or an appropriate error code on failure. */ - virtual CHIP_ERROR Retrieve(MutableByteSpan & payload) = 0; + virtual CHIP_ERROR Retrieve(MutableByteSpan & payload, uint32_t & read_entries) = 0; /** * @brief Checks if the storage buffer is empty.