Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 52da1f9

Browse files
pimpalemaheshesp
authored and
esp
committedMar 17, 2025
Review changes
1 parent b4f724e commit 52da1f9

12 files changed

+427
-378
lines changed
 

‎examples/temperature-measurement-app/esp32/main/include/diagnostic-logs-provider-delegate-impl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
2828

2929
#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
30-
#include <tracing/esp32_diagnostic_trace/DiagnosticStorageManager.h>
30+
#include <tracing/esp32_diagnostic_trace/DiagnosticStorage.h>
3131
using namespace chip::Tracing::Diagnostics;
3232
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
3333

‎src/tracing/esp32_diagnostic_trace/BUILD.gn

+4-2
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ static_library("backend") {
2727
sources = [
2828
"Counter.cpp",
2929
"Counter.h",
30-
"DiagnosticStorageManager.h",
30+
"DiagnosticStorage.cpp",
31+
"DiagnosticStorage.h",
3132
"DiagnosticTracing.cpp",
3233
"DiagnosticTracing.h",
33-
"Diagnostics.h",
34+
"DiagnosticEntry.h",
35+
"DiagnosticEntry.cpp",
3436
]
3537

3638
public_deps = [

‎src/tracing/esp32_diagnostic_trace/Counter.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,23 @@ uint32_t ESPDiagnosticCounter::GetInstanceCount(const char * label) const
4242
return mCounterList[label];
4343
}
4444

45-
CHIP_ERROR ESPDiagnosticCounter::ReportMetrics(const char * label, DiagnosticStorageInterface * storageInstance)
45+
CHIP_ERROR ESPDiagnosticCounter::ReportMetrics(const char * label, CircularDiagnosticBuffer * storageInstance)
4646
{
4747
VerifyOrReturnError(storageInstance != nullptr, CHIP_ERROR_INCORRECT_STATE,
4848
ChipLogError(DeviceLayer, "Diagnostic Storage Instance cannot be NULL"));
49-
Diagnostic<uint32_t> counter(const_cast<char *>(label), GetInstanceCount(label), esp_log_timestamp());
50-
return storageInstance->Store(counter);
49+
50+
// Allocate buffers for the diagnostic entry
51+
char labelBuffer[kMaxStringValueSize];
52+
strncpy(labelBuffer, label, kMaxStringValueSize);
53+
labelBuffer[kMaxStringValueSize - 1] = '\0';
54+
55+
// Create diagnostic entry
56+
DiagnosticEntry entry = { .label = labelBuffer,
57+
.uintValue = GetInstanceCount(label),
58+
.type = ValueType::kUnsignedInteger,
59+
.timestamp = esp_log_timestamp() };
60+
61+
return storageInstance->Store(entry);
5162
}
5263

5364
} // namespace Diagnostics

‎src/tracing/esp32_diagnostic_trace/Counter.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818

1919
#pragma once
2020

21-
#include "tracing/esp32_diagnostic_trace/Diagnostics.h"
21+
#include "tracing/esp32_diagnostic_trace/DiagnosticStorage.h"
22+
#include "tracing/esp32_diagnostic_trace/DiagnosticEntry.h"
2223
#include <map>
2324

2425
namespace chip {
@@ -45,7 +46,7 @@ class ESPDiagnosticCounter
4546

4647
uint32_t GetInstanceCount(const char * label) const;
4748

48-
CHIP_ERROR ReportMetrics(const char * label, DiagnosticStorageInterface * storageInstance);
49+
CHIP_ERROR ReportMetrics(const char * label, CircularDiagnosticBuffer * storageInstance);
4950

5051
private:
5152
ESPDiagnosticCounter() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#include <tracing/esp32_diagnostic_trace/DiagnosticEntry.h>
2+
using namespace chip::TLV;
3+
4+
namespace chip {
5+
namespace Tracing {
6+
namespace Diagnostics {
7+
8+
CHIP_ERROR Encode(CircularTLVWriter & writer, const DiagnosticEntry & entry)
9+
{
10+
TLVType DiagnosticOuterContainer = kTLVType_NotSpecified;
11+
ReturnErrorOnFailure(writer.StartContainer(AnonymousTag(), kTLVType_Structure, DiagnosticOuterContainer));
12+
13+
// Write timestamp
14+
ReturnErrorOnFailure(writer.Put(ContextTag(DiagTag::TIMESTAMP), entry.timestamp));
15+
16+
// Write label
17+
if (entry.label != nullptr)
18+
{
19+
if (strlen(entry.label) > kMaxStringValueSize)
20+
{
21+
char labelBuffer[kMaxStringValueSize + 1];
22+
memcpy(labelBuffer, entry.label, kMaxStringValueSize);
23+
labelBuffer[kMaxStringValueSize] = '\0';
24+
ReturnErrorOnFailure(writer.PutString(chip::TLV::ContextTag(DiagTag::LABEL), labelBuffer));
25+
}
26+
else
27+
{
28+
ReturnErrorOnFailure(writer.PutString(chip::TLV::ContextTag(DiagTag::LABEL), entry.label));
29+
}
30+
}
31+
32+
// Write value based on type
33+
switch (entry.type)
34+
{
35+
case ValueType::kCharString:
36+
if (entry.stringValue != nullptr)
37+
{
38+
if (strlen(entry.stringValue) > kMaxStringValueSize)
39+
{
40+
char valueBuffer[kMaxStringValueSize + 1];
41+
memcpy(valueBuffer, entry.stringValue, kMaxStringValueSize);
42+
valueBuffer[kMaxStringValueSize] = '\0';
43+
ReturnErrorOnFailure(writer.PutString(chip::TLV::ContextTag(DiagTag::VALUE), valueBuffer));
44+
}
45+
else
46+
{
47+
ReturnErrorOnFailure(writer.PutString(chip::TLV::ContextTag(DiagTag::VALUE), entry.stringValue));
48+
}
49+
}
50+
break;
51+
52+
case ValueType::kUnsignedInteger:
53+
ReturnErrorOnFailure(writer.Put(chip::TLV::ContextTag(DiagTag::VALUE), entry.uintValue));
54+
break;
55+
56+
case ValueType::kSignedInteger:
57+
ReturnErrorOnFailure(writer.Put(chip::TLV::ContextTag(DiagTag::VALUE), entry.intValue));
58+
break;
59+
}
60+
61+
ReturnErrorOnFailure(writer.EndContainer(DiagnosticOuterContainer));
62+
ReturnErrorOnFailure(writer.Finalize());
63+
ChipLogProgress(DeviceLayer, "Diagnostic Value written to storage successfully. label: %s\n", entry.label);
64+
return CHIP_NO_ERROR;
65+
}
66+
67+
CHIP_ERROR Decode(CircularTLVReader & reader, DiagnosticEntry & entry)
68+
{
69+
TLVType containerType;
70+
ReturnErrorOnFailure(reader.EnterContainer(containerType));
71+
72+
// Read timestamp
73+
ReturnErrorOnFailure(reader.Next(ContextTag(DiagTag::TIMESTAMP)));
74+
ReturnErrorOnFailure(reader.Get(entry.timestamp));
75+
76+
// Read label
77+
ReturnErrorOnFailure(reader.Next(ContextTag(DiagTag::LABEL)));
78+
uint32_t labelSize = reader.GetLength();
79+
if (labelSize > kMaxStringValueSize)
80+
{
81+
return CHIP_ERROR_BUFFER_TOO_SMALL;
82+
}
83+
ReturnErrorOnFailure(reader.GetString(entry.label, kMaxStringValueSize + 1));
84+
85+
// Read value
86+
ReturnErrorOnFailure(reader.Next());
87+
switch (entry.type)
88+
{
89+
case ValueType::kCharString: {
90+
uint32_t valueSize = reader.GetLength();
91+
if (valueSize > kMaxStringValueSize)
92+
{
93+
return CHIP_ERROR_BUFFER_TOO_SMALL;
94+
}
95+
ReturnErrorOnFailure(reader.GetString(entry.stringValue, kMaxStringValueSize + 1));
96+
break;
97+
}
98+
99+
case ValueType::kUnsignedInteger:
100+
ReturnErrorOnFailure(reader.Get(entry.uintValue));
101+
break;
102+
103+
case ValueType::kSignedInteger:
104+
ReturnErrorOnFailure(reader.Get(entry.intValue));
105+
break;
106+
}
107+
108+
ReturnErrorOnFailure(reader.ExitContainer(containerType));
109+
return CHIP_NO_ERROR;
110+
}
111+
112+
} // namespace Diagnostics
113+
} // namespace Tracing
114+
} // namespace chip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
*
3+
* Copyright (c) 2024 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#pragma once
20+
#include <lib/core/TLVCircularBuffer.h>
21+
22+
namespace chip {
23+
namespace Tracing {
24+
namespace Diagnostics {
25+
26+
static constexpr size_t kMaxStringValueSize = 128;
27+
28+
enum class ValueType
29+
{
30+
kCharString,
31+
kUnsignedInteger,
32+
kSignedInteger
33+
};
34+
35+
struct DiagnosticEntry
36+
{
37+
char * label;
38+
union
39+
{
40+
char * stringValue;
41+
uint32_t uintValue;
42+
int32_t intValue;
43+
};
44+
ValueType type;
45+
uint32_t timestamp;
46+
};
47+
48+
enum class DiagTag : uint8_t
49+
{
50+
TIMESTAMP = 1,
51+
LABEL = 2,
52+
VALUE = 3
53+
};
54+
55+
CHIP_ERROR Encode(chip::TLV::CircularTLVWriter & writer, const DiagnosticEntry & entry);
56+
CHIP_ERROR Decode(chip::TLV::CircularTLVReader & reader, DiagnosticEntry & entry);
57+
58+
} // namespace Diagnostics
59+
} // namespace Tracing
60+
} // namespace chip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
*
3+
* Copyright (c) 2024 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#include <tracing/esp32_diagnostic_trace/DiagnosticStorage.h>
20+
using namespace chip::TLV;
21+
22+
namespace chip {
23+
namespace Tracing {
24+
namespace Diagnostics {
25+
26+
CHIP_ERROR CircularDiagnosticBuffer::Store(const DiagnosticEntry & entry)
27+
{
28+
CHIP_ERROR err = CHIP_NO_ERROR;
29+
mWriter.Init(*this);
30+
ReturnLogErrorOnFailure(Encode(mWriter, entry));
31+
return err;
32+
}
33+
34+
CHIP_ERROR CircularDiagnosticBuffer::Retrieve(MutableByteSpan & span, uint32_t & read_entries)
35+
{
36+
CHIP_ERROR err = CHIP_NO_ERROR;
37+
mReader.Init(*this);
38+
39+
TLVWriter writer;
40+
writer.Init(span.data(), span.size());
41+
read_entries = 0;
42+
43+
bool close_success = true; // To check if the last TLV is copied successfully.
44+
uint32_t successful_written_bytes = 0; // Store temporary writer length in case last TLV is not copied successfully.
45+
46+
while ((err = mReader.Next()) == CHIP_NO_ERROR)
47+
{
48+
if (mReader.GetType() == kTLVType_Structure && mReader.GetTag() == AnonymousTag())
49+
{
50+
err = writer.CopyElement(mReader);
51+
if (err == CHIP_NO_ERROR)
52+
{
53+
successful_written_bytes = writer.GetLengthWritten();
54+
read_entries++;
55+
}
56+
else
57+
{
58+
close_success = false;
59+
break;
60+
}
61+
}
62+
else
63+
{
64+
ChipLogDetail(DeviceLayer, "Skipping unexpected TLV element");
65+
}
66+
}
67+
ReturnErrorOnFailure(writer.Finalize());
68+
if (close_success)
69+
{
70+
successful_written_bytes = writer.GetLengthWritten();
71+
}
72+
span.reduce_size(successful_written_bytes);
73+
ChipLogProgress(DeviceLayer, "---------------Total Retrieved bytes : %ld----------------\n", successful_written_bytes);
74+
return CHIP_NO_ERROR;
75+
}
76+
77+
bool CircularDiagnosticBuffer::IsBufferEmpty()
78+
{
79+
return DataLength() == 0;
80+
}
81+
82+
uint32_t CircularDiagnosticBuffer::GetDataSize()
83+
{
84+
return DataLength();
85+
}
86+
87+
CHIP_ERROR CircularDiagnosticBuffer::ClearBuffer()
88+
{
89+
while (!IsBufferEmpty())
90+
{
91+
ReturnErrorOnFailure(EvictHead());
92+
}
93+
return CHIP_NO_ERROR;
94+
}
95+
96+
CHIP_ERROR CircularDiagnosticBuffer::ClearBuffer(uint32_t entries)
97+
{
98+
while (entries--)
99+
{
100+
ReturnErrorOnFailure(EvictHead());
101+
}
102+
return CHIP_NO_ERROR;
103+
}
104+
} // namespace Diagnostics
105+
} // namespace Tracing
106+
} // namespace chip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#pragma once
2+
#include <lib/core/TLVCircularBuffer.h>
3+
#include <lib/support/Span.h>
4+
#include <tracing/esp32_diagnostic_trace/DiagnosticEntry.h>
5+
6+
namespace chip {
7+
namespace Tracing {
8+
namespace Diagnostics {
9+
10+
/**
11+
* @brief Diagnostic storage class
12+
*/
13+
class CircularDiagnosticBuffer : public chip::TLV::TLVCircularBuffer
14+
{
15+
public:
16+
CircularDiagnosticBuffer(uint8_t * buffer, size_t bufferLength) : chip::TLV::TLVCircularBuffer(buffer, bufferLength) {}
17+
18+
/**
19+
* @brief Stores a diagnostic entry in the diagnostic storage buffer.
20+
* @param diagnostic A reference to a `DiagnosticEntry` object that contains
21+
* the diagnostic data to be stored.
22+
* @return CHIP_ERROR Returns `CHIP_NO_ERROR` if the data is successfully stored,
23+
* or an appropriate error code in case of failure.
24+
*/
25+
CHIP_ERROR Store(const DiagnosticEntry & diagnostic);
26+
27+
/**
28+
* @brief Copies diagnostic data from the storage buffer to a payload.
29+
*
30+
* This method retrieves the stored diagnostic data and copies it into the
31+
* provided `payload` buffer. If the buffer is too small to hold all the data,
32+
* the method returns the successfully copied entries along with an error code
33+
* indicating that the buffer was insufficient.
34+
*
35+
* @param payload A reference to a `MutableByteSpan` where the retrieved
36+
* diagnostic data will be copied.
37+
* @param read_entries A reference to an integer that will hold the total
38+
* number of successfully read diagnostic entries.
39+
*
40+
* @retval CHIP_NO_ERROR If the operation succeeded and all data was copied.
41+
* @retval CHIP_ERROR_BUFFER_TOO_SMALL If the buffer was not large enough to hold all data.
42+
* @retval CHIP_ERROR If any other failure occurred during the operation.
43+
*/
44+
CHIP_ERROR Retrieve(MutableByteSpan & payload, uint32_t & read_entries);
45+
46+
/**
47+
* @brief Checks if the diagnostic storage buffer is empty.
48+
*
49+
* This method checks whether the buffer contains any stored diagnostic data.
50+
*
51+
* @return bool Returns `true` if the buffer contains no stored data,
52+
* or `false` if the buffer has data.
53+
*/
54+
bool IsBufferEmpty();
55+
56+
/**
57+
* @brief Retrieves the size of the data currently stored in the diagnostic buffer.
58+
*
59+
* This method returns the total size (in bytes) of all diagnostic data that is
60+
* currently stored in the buffer.
61+
*
62+
* @return uint32_t The size (in bytes) of the stored diagnostic data.
63+
*/
64+
uint32_t GetDataSize();
65+
66+
/**
67+
* @brief Clears entire buffer
68+
*/
69+
CHIP_ERROR ClearBuffer();
70+
71+
/**
72+
* @brief Clears buffer up to the specified number of entries
73+
*/
74+
CHIP_ERROR ClearBuffer(uint32_t entries);
75+
76+
private:
77+
chip::TLV::CircularTLVReader mReader;
78+
chip::TLV::CircularTLVWriter mWriter;
79+
};
80+
81+
} // namespace Diagnostics
82+
} // namespace Tracing
83+
} // namespace chip

‎src/tracing/esp32_diagnostic_trace/DiagnosticStorageManager.h

-111
This file was deleted.

‎src/tracing/esp32_diagnostic_trace/DiagnosticTracing.cpp

+39-6
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,33 @@ void ESP32Diagnostics::LogMetricEvent(const MetricEvent & event)
112112
{
113113
case ValueType::kInt32: {
114114
ChipLogProgress(DeviceLayer, "The value of %s is %" PRId32, event.key(), event.ValueInt32());
115-
Diagnostic<int32_t> metric(const_cast<char *>(event.key()), event.ValueInt32(), esp_log_timestamp());
116-
ReturnOnFailure(mStorageInstance->Store(metric));
115+
116+
// Allocate buffers for the diagnostic entry
117+
char labelBuffer[kMaxStringValueSize];
118+
strncpy(labelBuffer, event.key(), kMaxStringValueSize);
119+
labelBuffer[kMaxStringValueSize - 1] = '\0';
120+
121+
DiagnosticEntry entry = { .label = labelBuffer,
122+
.intValue = event.ValueInt32(),
123+
.type = Diagnostics::ValueType::kSignedInteger,
124+
.timestamp = esp_log_timestamp() };
125+
ReturnOnFailure(mStorageInstance->Store(entry));
117126
}
118127
break;
119128

120129
case ValueType::kUInt32: {
121130
ChipLogProgress(DeviceLayer, "The value of %s is %" PRId32, event.key(), event.ValueUInt32());
122-
Diagnostic<uint32_t> metric(const_cast<char *>(event.key()), event.ValueUInt32(), esp_log_timestamp());
123-
ReturnOnFailure(mStorageInstance->Store(metric));
131+
132+
// Allocate buffers for the diagnostic entry
133+
char labelBuffer[kMaxStringValueSize];
134+
strncpy(labelBuffer, event.key(), kMaxStringValueSize);
135+
labelBuffer[kMaxStringValueSize - 1] = '\0';
136+
137+
DiagnosticEntry entry = { .label = labelBuffer,
138+
.uintValue = event.ValueUInt32(),
139+
.type = Diagnostics::ValueType::kUnsignedInteger,
140+
.timestamp = esp_log_timestamp() };
141+
ReturnOnFailure(mStorageInstance->Store(entry));
124142
}
125143
break;
126144

@@ -161,8 +179,23 @@ CHIP_ERROR ESP32Diagnostics::StoreDiagnostics(const char * label, const char * g
161179
{
162180
VerifyOrReturnError(mStorageInstance != nullptr, CHIP_ERROR_INCORRECT_STATE,
163181
ChipLogError(DeviceLayer, "Diagnostic Storage Instance cannot be NULL"));
164-
Diagnostic<char *> trace(const_cast<char *>(label), const_cast<char *>(group), esp_log_timestamp());
165-
return mStorageInstance->Store(trace);
182+
183+
// Allocate buffers for the diagnostic entry
184+
char labelBuffer[kMaxStringValueSize];
185+
strncpy(labelBuffer, label, kMaxStringValueSize);
186+
labelBuffer[kMaxStringValueSize - 1] = '\0';
187+
188+
char groupBuffer[kMaxStringValueSize];
189+
strncpy(groupBuffer, group, kMaxStringValueSize);
190+
groupBuffer[kMaxStringValueSize - 1] = '\0';
191+
192+
// Create diagnostic entry
193+
DiagnosticEntry entry = { .label = labelBuffer,
194+
.stringValue = groupBuffer,
195+
.type = Diagnostics::ValueType::kCharString,
196+
.timestamp = esp_log_timestamp() };
197+
198+
return mStorageInstance->Store(entry);
166199
}
167200

168201
} // namespace Diagnostics

‎src/tracing/esp32_diagnostic_trace/DiagnosticTracing.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@
1919
*/
2020

2121
#include <tracing/backend.h>
22-
#include <tracing/esp32_diagnostic_trace/Diagnostics.h>
22+
#include <tracing/esp32_diagnostic_trace/DiagnosticStorage.h>
2323
#include <tracing/metric_event.h>
2424

25-
#include <memory>
2625
namespace chip {
2726
namespace Tracing {
2827
namespace Diagnostics {
@@ -32,7 +31,7 @@ namespace Diagnostics {
3231
class ESP32Diagnostics : public ::chip::Tracing::Backend
3332
{
3433
public:
35-
ESP32Diagnostics(DiagnosticStorageInterface * storageInstance) : mStorageInstance(storageInstance) {}
34+
ESP32Diagnostics(CircularDiagnosticBuffer * storageInstance) : mStorageInstance(storageInstance) {}
3635

3736
// Deleted copy constructor and assignment operator to prevent copying
3837
ESP32Diagnostics(const ESP32Diagnostics &) = delete;
@@ -57,7 +56,7 @@ class ESP32Diagnostics : public ::chip::Tracing::Backend
5756

5857
private:
5958
using ValueType = MetricEvent::Value::Type;
60-
DiagnosticStorageInterface * mStorageInstance;
59+
CircularDiagnosticBuffer * mStorageInstance;
6160
CHIP_ERROR StoreDiagnostics(const char * label, const char * group);
6261
};
6362

‎src/tracing/esp32_diagnostic_trace/Diagnostics.h

-249
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.