Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2025 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 16 : CHIP_ERROR CircularDiagnosticBuffer::Store(const DiagnosticEntry & entry)
27 : {
28 16 : CHIP_ERROR err = CHIP_NO_ERROR;
29 16 : mWriter.Init(*this);
30 16 : ReturnLogErrorOnFailure(Encode(mWriter, entry));
31 16 : return err;
32 : }
33 :
34 4 : CHIP_ERROR CircularDiagnosticBuffer::Retrieve(MutableByteSpan & span, uint32_t & read_entries)
35 : {
36 4 : CHIP_ERROR err = CHIP_NO_ERROR;
37 4 : mReader.Init(*this);
38 :
39 4 : TLVWriter writer;
40 4 : writer.Init(span.data(), span.size());
41 4 : read_entries = 0;
42 :
43 4 : uint32_t successful_written_bytes = 0; // Store temporary writer length in case last TLV is not copied successfully.
44 :
45 20 : while ((err = mReader.Next()) == CHIP_NO_ERROR)
46 : {
47 17 : if (mReader.GetType() == kTLVType_Structure && mReader.GetTag() == AnonymousTag())
48 : {
49 17 : err = writer.CopyElement(mReader);
50 17 : if (err == CHIP_NO_ERROR)
51 : {
52 16 : successful_written_bytes = writer.GetLengthWritten();
53 16 : read_entries++;
54 : }
55 1 : else if (err == CHIP_ERROR_BUFFER_TOO_SMALL)
56 : {
57 : // If we ran out of space, this is expected - not an error
58 1 : ChipLogProgress(DeviceLayer, "Buffer full after %" PRIu32 " entries", read_entries);
59 1 : err = CHIP_NO_ERROR;
60 1 : break;
61 : }
62 : else
63 : {
64 : // error occurred during copy
65 0 : ChipLogError(DeviceLayer, "Error copying TLV element: %" CHIP_ERROR_FORMAT, err.Format());
66 0 : break;
67 : }
68 : }
69 : else
70 : {
71 0 : ChipLogDetail(DeviceLayer, "Skipping TLV element. Found unexpected type: %d", static_cast<int>(mReader.GetType()));
72 : }
73 : }
74 :
75 : // Only finalize if we have at least one successful entry
76 4 : if (read_entries > 0)
77 : {
78 4 : ReturnErrorOnFailure(writer.Finalize());
79 : }
80 0 : else if (err != CHIP_END_OF_TLV && err != CHIP_NO_ERROR)
81 : {
82 0 : return err;
83 : }
84 :
85 4 : span.reduce_size(successful_written_bytes);
86 4 : ChipLogProgress(DeviceLayer, "Total Retrieved bytes: %" PRIu32 " (%" PRIu32 " entries)", successful_written_bytes,
87 : read_entries);
88 :
89 : // CHIP_END_OF_TLV is expected when we reach the end of the buffer
90 4 : return CHIP_NO_ERROR;
91 : }
92 :
93 1 : bool CircularDiagnosticBuffer::IsBufferEmpty()
94 : {
95 1 : return DataLength() == 0;
96 : }
97 :
98 0 : uint32_t CircularDiagnosticBuffer::GetDataSize()
99 : {
100 0 : return DataLength();
101 : }
102 :
103 0 : CHIP_ERROR CircularDiagnosticBuffer::ClearBuffer()
104 : {
105 0 : while (!IsBufferEmpty())
106 : {
107 0 : ReturnErrorOnFailure(EvictHead());
108 : }
109 0 : return CHIP_NO_ERROR;
110 : }
111 :
112 2 : CHIP_ERROR CircularDiagnosticBuffer::ClearBuffer(uint32_t entries)
113 : {
114 12 : while (entries--)
115 : {
116 10 : ReturnErrorOnFailure(EvictHead());
117 : }
118 2 : return CHIP_NO_ERROR;
119 : }
120 : } // namespace Diagnostics
121 : } // namespace Tracing
122 : } // namespace chip
|