forked from project-chip/connectedhomeip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEmberReadWriteOverride.cpp
129 lines (106 loc) · 4.17 KB
/
EmberReadWriteOverride.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "EmberReadWriteOverride.h"
#include <app/util/attribute-storage.h>
#include <app/util/ember-io-storage.h>
#include <lib/support/Span.h>
using chip::Protocols::InteractionModel::Status;
namespace {
constexpr size_t kMaxTestIoSize = 128;
uint8_t gEmberIoBuffer[kMaxTestIoSize];
size_t gEmberIoBufferFill;
Status gEmberStatusCode = Status::InvalidAction;
} // namespace
namespace chip {
namespace Test {
void SetEmberReadOutput(std::variant<chip::ByteSpan, Status> what)
{
if (const chip::ByteSpan * span = std::get_if<chip::ByteSpan>(&what))
{
gEmberStatusCode = Status::Success;
if (span->size() > sizeof(gEmberIoBuffer))
{
ChipLogError(Test, "UNEXPECTED STATE: Too much data set for ember read output");
gEmberStatusCode = Status::ResourceExhausted;
return;
}
memcpy(gEmberIoBuffer, span->data(), span->size());
gEmberIoBufferFill = span->size();
return;
}
if (const Status * status = std::get_if<Status>(&what))
{
gEmberIoBufferFill = 0;
gEmberStatusCode = *status;
return;
}
ChipLogError(Test, "UNEXPECTED STATE: invalid ember read output setting");
gEmberStatusCode = Status::InvalidAction;
}
ByteSpan GetEmberBuffer()
{
return ByteSpan(gEmberIoBuffer, gEmberIoBufferFill);
}
} // namespace Test
} // namespace chip
/// TODO: this SHOULD be part of attribute-storage mocks and allow proper I/O control
/// with helpers for "ember encoding"
Status emAfReadOrWriteAttribute(const EmberAfAttributeSearchRecord * attRecord, const EmberAfAttributeMetadata ** metadata,
uint8_t * buffer, uint16_t readLength, bool write)
{
if (gEmberStatusCode != Status::Success)
{
return gEmberStatusCode;
}
if (write)
{
// copy over as much data as possible
// NOTE: we do NOT use (*metadata)->size since it is unclear if our mocks set that correctly
size_t len = std::min<size_t>(sizeof(gEmberIoBuffer), readLength);
memcpy(gEmberIoBuffer, buffer, len);
gEmberIoBufferFill = len;
}
else
{
VerifyOrDie(gEmberIoBufferFill <= readLength);
memcpy(buffer, gEmberIoBuffer, gEmberIoBufferFill);
}
return Status::Success;
}
Status emAfWriteAttributeExternal(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID,
uint8_t * dataPtr, EmberAfAttributeType dataType)
{
if (gEmberStatusCode != Status::Success)
{
return gEmberStatusCode;
}
// ember here deduces the size of dataPtr. For testing however, we KNOW we read
// out of the ember IO buffer, so we try to use that
VerifyOrDie(dataPtr == chip::app::Compatibility::Internal::gEmberAttributeIOBufferSpan.data());
// In theory this should do type validation and sizes. This is NOT done for testing.
// copy over as much data as possible
// NOTE: we do NOT use (*metadata)->size since it is unclear if our mocks set that correctly
size_t len = std::min<size_t>(sizeof(gEmberIoBuffer), chip::app::Compatibility::Internal::gEmberAttributeIOBufferSpan.size());
memcpy(gEmberIoBuffer, dataPtr, len);
gEmberIoBufferFill = len;
return Status::Success;
}
Status emberAfWriteAttribute(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID, uint8_t * dataPtr,
EmberAfAttributeType dataType)
{
return emAfWriteAttributeExternal(endpoint, cluster, attributeID, dataPtr, dataType);
}