Coverage Report

Created: 2026-02-12 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/connectedhomeip/examples/common/tracing/decoder/bdx/Decoder.cpp
Line
Count
Source
1
/*
2
 *   Copyright (c) 2022 Project CHIP Authors
3
 *   All rights reserved.
4
 *
5
 *   Licensed under the Apache License, Version 2.0 (the "License");
6
 *   you may not use this file except in compliance with the License.
7
 *   You may obtain a copy of the License at
8
 *
9
 *       http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 *   Unless required by applicable law or agreed to in writing, software
12
 *   distributed under the License is distributed on an "AS IS" BASIS,
13
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 *   See the License for the specific language governing permissions and
15
 *   limitations under the License.
16
 *
17
 */
18
19
#include "Decoder.h"
20
21
#include "../logging/Log.h"
22
23
#include <lib/core/CHIPSafeCasts.h>
24
#include <protocols/bdx/BdxMessages.h>
25
26
namespace {
27
constexpr char kProtocolName[] = "Bulk Data Exchange";
28
29
constexpr char kUnknown[]            = "Unknown";
30
constexpr char kSendInit[]           = "Send Init";
31
constexpr char kSendAccept[]         = "Send Accept";
32
constexpr char kReceiveInit[]        = "Receive Init";
33
constexpr char kReceiveAccept[]      = "Receive Accept";
34
constexpr char kBlockQuery[]         = "Block Query";
35
constexpr char kBlock[]              = "Block";
36
constexpr char kBlockEOF[]           = "Block End Of File";
37
constexpr char kBlockAck[]           = "Block Ack";
38
constexpr char kBlockAckEOF[]        = "Block Ack End Of File";
39
constexpr char kBlockQueryWithSkip[] = "Block Query With Skip";
40
41
constexpr char kDataHeader[] = "Data";
42
} // namespace
43
44
using MessageType          = chip::bdx::MessageType;
45
using RangeControlFlags    = chip::bdx::RangeControlFlags;
46
using TransferControlFlags = chip::bdx::TransferControlFlags;
47
48
namespace chip {
49
namespace trace {
50
namespace bdx {
51
52
using namespace logging;
53
54
CHIP_ERROR DecodeTransferInit(System::PacketBufferHandle msgData);
55
CHIP_ERROR DecodeSendAccept(System::PacketBufferHandle msgData);
56
CHIP_ERROR DecodeReceiveAccept(System::PacketBufferHandle msgData);
57
CHIP_ERROR DecodeBlockCounter(System::PacketBufferHandle msgData);
58
CHIP_ERROR DecodeDataBlock(System::PacketBufferHandle msgData);
59
CHIP_ERROR DecodeBlockQueryWithSkip(System::PacketBufferHandle msgData);
60
void DecodeAndPrintTransferControl(const char * header, BitFlags<TransferControlFlags> & flags);
61
void DecodeAndPrintRangeControl(const char * header, BitFlags<RangeControlFlags> & flags);
62
void DecodeAndPrintMetadata(const ByteSpan & data);
63
64
const char * ToProtocolName()
65
0
{
66
0
    return kProtocolName;
67
0
}
68
69
const char * ToProtocolMessageTypeName(uint8_t protocolCode)
70
0
{
71
0
    switch (protocolCode)
72
0
    {
73
0
    case to_underlying(MessageType::SendInit):
74
0
        return kSendInit;
75
0
    case to_underlying(MessageType::SendAccept):
76
0
        return kSendAccept;
77
0
    case to_underlying(MessageType::ReceiveInit):
78
0
        return kReceiveInit;
79
0
    case to_underlying(MessageType::ReceiveAccept):
80
0
        return kReceiveAccept;
81
0
    case to_underlying(MessageType::BlockQuery):
82
0
        return kBlockQuery;
83
0
    case to_underlying(MessageType::Block):
84
0
        return kBlock;
85
0
    case to_underlying(MessageType::BlockEOF):
86
0
        return kBlockEOF;
87
0
    case to_underlying(MessageType::BlockAck):
88
0
        return kBlockAck;
89
0
    case to_underlying(MessageType::BlockAckEOF):
90
0
        return kBlockAckEOF;
91
0
    case to_underlying(MessageType::BlockQueryWithSkip):
92
0
        return kBlockQueryWithSkip;
93
0
    }
94
95
0
    return kUnknown;
96
0
}
97
98
CHIP_ERROR LogAsProtocolMessage(uint8_t protocolCode, const uint8_t * data, size_t len)
99
0
{
100
0
    auto msgData = System::PacketBufferHandle::NewWithData(data, len);
101
102
0
    switch (protocolCode)
103
0
    {
104
0
    case to_underlying(MessageType::SendInit):
105
0
        return DecodeTransferInit(std::move(msgData));
106
0
    case to_underlying(MessageType::SendAccept):
107
0
        return DecodeSendAccept(std::move(msgData));
108
0
    case to_underlying(MessageType::ReceiveInit):
109
0
        return DecodeTransferInit(std::move(msgData));
110
0
    case to_underlying(MessageType::ReceiveAccept):
111
0
        return DecodeReceiveAccept(std::move(msgData));
112
0
    case to_underlying(MessageType::BlockQuery):
113
0
        return DecodeBlockCounter(std::move(msgData));
114
0
    case to_underlying(MessageType::Block):
115
0
        return DecodeDataBlock(std::move(msgData));
116
0
    case to_underlying(MessageType::BlockEOF):
117
0
        return DecodeDataBlock(std::move(msgData));
118
0
    case to_underlying(MessageType::BlockAck):
119
0
        return DecodeBlockCounter(std::move(msgData));
120
0
    case to_underlying(MessageType::BlockAckEOF):
121
0
        return DecodeBlockCounter(std::move(msgData));
122
0
    case to_underlying(MessageType::BlockQueryWithSkip):
123
0
        return DecodeBlockQueryWithSkip(std::move(msgData));
124
0
    }
125
126
0
    return CHIP_ERROR_NOT_IMPLEMENTED;
127
0
}
128
129
CHIP_ERROR DecodeTransferInit(System::PacketBufferHandle msgData)
130
0
{
131
0
    auto scopedIndent = ScopedLogIndentWithSize(kDataHeader, msgData->DataLength());
132
133
0
    chip::bdx::TransferInit msg;
134
0
    ReturnErrorOnFailure(msg.Parse(msgData.Retain()));
135
136
0
    auto ptc      = msg.TransferCtlOptions;
137
0
    auto rc       = msg.mRangeCtlFlags;
138
0
    auto pmbs     = msg.MaxBlockSize;
139
0
    auto startofs = msg.StartOffset;
140
0
    auto len      = msg.MaxLength;
141
0
    auto fdl      = msg.FileDesLength;
142
0
    auto fd       = CharSpan(Uint8::to_const_char(msg.FileDesignator), msg.FileDesLength);
143
0
    auto mdata    = ByteSpan(msg.Metadata, msg.MetadataLength);
144
145
0
    DecodeAndPrintTransferControl("Proposed Transfer Control", ptc);
146
0
    DecodeAndPrintRangeControl("Range Control", rc);
147
0
    Log("Proposed Max Block Size", pmbs);
148
149
0
    if (rc.Has(RangeControlFlags::kStartOffset))
150
0
    {
151
0
        LogAsHex("Start Offset", startofs);
152
0
    }
153
154
0
    if (rc.Has(RangeControlFlags::kDefLen))
155
0
    {
156
0
        LogAsHex("Proposed Max Length", len);
157
0
    }
158
159
0
    Log("File Designator Length", fdl);
160
0
    Log("File Designator", fd);
161
0
    DecodeAndPrintMetadata(mdata);
162
163
0
    return CHIP_NO_ERROR;
164
0
}
165
166
CHIP_ERROR DecodeSendAccept(System::PacketBufferHandle msgData)
167
0
{
168
0
    auto scopedIndent = ScopedLogIndentWithSize(kDataHeader, msgData->DataLength());
169
170
0
    chip::bdx::SendAccept msg;
171
0
    ReturnErrorOnFailure(msg.Parse(msgData.Retain()));
172
173
0
    auto tc    = msg.TransferCtlFlags;
174
0
    auto mbs   = msg.MaxBlockSize;
175
0
    auto mdata = ByteSpan(msg.Metadata, msg.MetadataLength);
176
177
0
    DecodeAndPrintTransferControl("Transfer Control", tc);
178
0
    Log("Max Block Size", mbs);
179
0
    DecodeAndPrintMetadata(mdata);
180
181
0
    return CHIP_NO_ERROR;
182
0
}
183
184
CHIP_ERROR DecodeReceiveAccept(System::PacketBufferHandle msgData)
185
0
{
186
0
    auto scopedIndent = ScopedLogIndentWithSize(kDataHeader, msgData->DataLength());
187
188
0
    chip::bdx::ReceiveAccept msg;
189
0
    ReturnErrorOnFailure(msg.Parse(msgData.Retain()));
190
191
0
    auto tc    = msg.TransferCtlFlags;
192
0
    auto rc    = msg.mRangeCtlFlags;
193
0
    auto mbs   = msg.MaxBlockSize;
194
0
    auto len   = msg.Length;
195
0
    auto mdata = ByteSpan(msg.Metadata, msg.MetadataLength);
196
197
0
    DecodeAndPrintTransferControl("Transfer Control", tc);
198
0
    DecodeAndPrintRangeControl("Range Control", rc);
199
0
    Log("Max Block Size", mbs);
200
201
0
    if (rc.Has(RangeControlFlags::kDefLen))
202
0
    {
203
0
        LogAsHex("Length", len);
204
0
    }
205
206
0
    DecodeAndPrintMetadata(mdata);
207
208
0
    return CHIP_NO_ERROR;
209
0
}
210
211
CHIP_ERROR DecodeBlockCounter(System::PacketBufferHandle msgData)
212
0
{
213
0
    auto scopedIndent = ScopedLogIndent(kDataHeader);
214
215
0
    chip::bdx::CounterMessage msg;
216
0
    ReturnErrorOnFailure(msg.Parse(msgData.Retain()));
217
218
0
    Log("BlockCounter", msg.BlockCounter);
219
220
0
    return CHIP_NO_ERROR;
221
0
}
222
223
CHIP_ERROR DecodeDataBlock(System::PacketBufferHandle msgData)
224
0
{
225
0
    auto scopedIndent = ScopedLogIndentWithSize(kDataHeader, msgData->DataLength());
226
227
0
    chip::bdx::DataBlock msg;
228
0
    ReturnErrorOnFailure(msg.Parse(msgData.Retain()));
229
230
0
    Log("BlockCounter", msg.BlockCounter);
231
232
0
    auto data = ByteSpan(msg.Data, msg.DataLength);
233
0
    Log("Data", data);
234
235
0
    return CHIP_NO_ERROR;
236
0
}
237
238
CHIP_ERROR DecodeBlockQueryWithSkip(System::PacketBufferHandle msgData)
239
0
{
240
0
    auto scopedIndent = ScopedLogIndent(kDataHeader);
241
242
0
    chip::bdx::BlockQueryWithSkip msg;
243
0
    ReturnErrorOnFailure(msg.Parse(msgData.Retain()));
244
245
0
    Log("BlockCounter", msg.BlockCounter);
246
0
    LogAsHex("BytesToSkip", msg.BytesToSkip);
247
248
0
    return CHIP_NO_ERROR;
249
0
}
250
251
void DecodeAndPrintTransferControl(const char * header, BitFlags<TransferControlFlags> & flags)
252
0
{
253
0
    auto scopedIndent = ScopedLogIndentWithFlags(header, flags.Raw());
254
255
0
    if (flags.Has(TransferControlFlags::kSenderDrive))
256
0
    {
257
0
        Log("SenderDrive");
258
0
    }
259
260
0
    if (flags.Has(TransferControlFlags::kReceiverDrive))
261
0
    {
262
0
        Log("ReceivedDrive");
263
0
    }
264
265
0
    if (flags.Has(TransferControlFlags::kAsync))
266
0
    {
267
0
        Log("Async");
268
0
    }
269
0
}
270
271
void DecodeAndPrintRangeControl(const char * header, BitFlags<RangeControlFlags> & flags)
272
0
{
273
0
    auto scopedIndent = ScopedLogIndentWithFlags(header, flags.Raw());
274
275
0
    if (flags.Has(chip::bdx::RangeControlFlags::kDefLen))
276
0
    {
277
0
        Log("DefLen");
278
0
    }
279
280
0
    if (flags.Has(RangeControlFlags::kStartOffset))
281
0
    {
282
0
        Log("StartOffset");
283
0
    }
284
285
0
    if (flags.Has(RangeControlFlags::kWiderange))
286
0
    {
287
0
        Log("Widerange");
288
0
    }
289
0
}
290
291
void DecodeAndPrintMetadata(const ByteSpan & data)
292
0
{
293
0
    if (data.size())
294
0
    {
295
        // TODO Make metadata decoding prettier.
296
0
        Log("HasMetadata");
297
0
    }
298
0
}
299
300
} // namespace bdx
301
} // namespace trace
302
} // namespace chip