Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | #include "pch.h" | |||
2 | #include "auto_generated_sensor.h" | |||
3 | ||||
4 | // This struct represents one sensor in the registry. | |||
5 | // It stores whether the sensor should use a mock value, | |||
6 | // the value to use, and if not a pointer to the sensor that | |||
7 | // can provide a real value. | |||
8 | class SensorRegistryEntry { | |||
9 | public: | |||
10 | 219 | const Sensor* getSensor() { | ||
11 | 219 | return m_sensor; | ||
12 | } | |||
13 | ||||
14 | 104 | void setInvalidMockValue() { | ||
15 | 104 | m_useMock = true; | ||
16 | 104 | m_valid = false; | ||
17 | 104 | } | ||
18 | ||||
19 | 2760 | void setMockValue(float value, bool mockRedundant) { | ||
20 | 2760 | m_mockValue = value; | ||
21 | 2760 | m_useMock = true; | ||
22 | 2760 | m_valid = true; | ||
23 | 2760 | m_mockRedundant = mockRedundant; | ||
24 | 2760 | } | ||
25 | ||||
26 | 63245 | void resetMock() { | ||
27 | 63245 | m_useMock = false; | ||
28 | 63245 | m_mockValue = 0.0f; | ||
29 | 63245 | } | ||
30 | ||||
31 | 61272 | void reset() { | ||
32 | 61272 | m_sensor = nullptr; | ||
33 | 61272 | resetMock(); | ||
34 | 61272 | } | ||
35 | ||||
36 | 850 | bool Register(Sensor* sensor) { | ||
37 | // If there's somebody already here - a consumer tried to double-register a sensor | |||
38 |
4/4✓ Branch 0 taken 7 times.
✓ Branch 1 taken 843 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 6 times.
|
2/2✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 849 times.
|
850 | if (m_sensor && m_sensor != sensor) { |
39 | // This sensor has already been registered. Don't re-register it. | |||
40 | 1 | firmwareError(ObdCode::CUSTOM_OBD_26, "Duplicate registration for sensor \"%s\"", sensor->getSensorName()); | ||
41 | ✗ | return false; | ||
42 | } else { | |||
43 | // Put the sensor in the registry | |||
44 | 849 | m_sensor = sensor; | ||
45 | 849 | return true; | ||
46 | } | |||
47 | } | |||
48 | ||||
49 | 689 | void unregister() { | ||
50 | 689 | m_sensor = nullptr; | ||
51 | 689 | } | ||
52 | ||||
53 | 35693685 | SensorResult get() const { | ||
54 | // Check if mock | |||
55 |
2/2✓ Branch 0 taken 1068881 times.
✓ Branch 1 taken 34624804 times.
|
2/2✓ Decision 'true' taken 1068881 times.
✓ Decision 'false' taken 34624804 times.
|
35693685 | if (m_useMock) { |
56 |
2/2✓ Branch 0 taken 306 times.
✓ Branch 1 taken 1068575 times.
|
2/2✓ Decision 'true' taken 306 times.
✓ Decision 'false' taken 1068575 times.
|
1068881 | if (!m_valid) { |
57 | 306 | return unexpected; | ||
58 | } | |||
59 | 1068575 | return m_mockValue; | ||
60 | } | |||
61 | ||||
62 | // Get the sensor out of the entry | |||
63 | 34624804 | const Sensor *s = m_sensor; | ||
64 |
2/2✓ Branch 0 taken 619464 times.
✓ Branch 1 taken 34005340 times.
|
2/2✓ Decision 'true' taken 619464 times.
✓ Decision 'false' taken 34005340 times.
|
34624804 | if (s) { |
65 | // If this sensor says it doesn't exist, return unexpected | |||
66 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 619464 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 619464 times.
|
619464 | if (!s->hasSensor()) { |
67 | ✗ | return UnexpectedCode::Configuration; | ||
68 | } | |||
69 | ||||
70 | // If we found the sensor, ask it for a result. | |||
71 | 619464 | return s->get(); | ||
72 | } | |||
73 | ||||
74 | // We've exhausted all valid ways to return something - sensor not found. | |||
75 | 34005340 | return UnexpectedCode::Configuration; | ||
76 | } | |||
77 | ||||
78 | ✗ | void showInfo(const char* sensorName) const { | ||
79 | ✗ | if (m_useMock) { | ||
80 | ✗ | efiPrintf("Sensor \"%s\" mocked with value %.2f", sensorName, m_mockValue); | ||
81 | } else { | |||
82 | ✗ | const auto sensor = m_sensor; | ||
83 | ||||
84 | ✗ | if (sensor) { | ||
85 | ✗ | sensor->showInfo(sensorName); | ||
86 | } else { | |||
87 | ✗ | efiPrintf("Sensor \"%s\" is not configured.", sensorName); | ||
88 | } | |||
89 | } | |||
90 | ✗ | } | ||
91 | ||||
92 | 2626172 | bool hasSensor() const { | ||
93 |
6/6✓ Branch 0 taken 2625892 times.
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 236 times.
✓ Branch 3 taken 2625656 times.
✓ Branch 5 taken 235 times.
✓ Branch 6 taken 1 time.
|
2626172 | return m_useMock || (m_sensor && m_sensor->hasSensor()); | |
94 | } | |||
95 | ||||
96 | 14119760 | float getRaw() const { | ||
97 | 14119760 | const auto sensor = m_sensor; | ||
98 | ||||
99 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 14119758 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 14119758 times.
|
14119760 | if (sensor) { |
100 | 2 | return sensor->getRaw(); | ||
101 | } | |||
102 | ||||
103 | // We've exhausted all valid ways to return something - sensor not found. | |||
104 | 14119758 | return 0; | ||
105 | } | |||
106 | ||||
107 | 236 | bool isRedundant() const { | ||
108 | 236 | const auto sensor = m_sensor; | ||
109 | ||||
110 |
2/2✓ Branch 0 taken 209 times.
✓ Branch 1 taken 27 times.
|
2/2✓ Decision 'true' taken 209 times.
✓ Decision 'false' taken 27 times.
|
236 | if (sensor) { |
111 | 209 | return sensor->isRedundant(); | ||
112 | } | |||
113 | ||||
114 |
1/2✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 27 times.
✗ Decision 'false' not taken.
|
27 | if (m_useMock) { |
115 | 27 | return m_mockRedundant; | ||
116 | } | |||
117 | ||||
118 | ✗ | return false; | ||
119 | } | |||
120 | ||||
121 | private: | |||
122 | bool m_useMock = false; | |||
123 | bool m_valid = false; | |||
124 | bool m_mockRedundant = false; | |||
125 | float m_mockValue; | |||
126 | Sensor* m_sensor = nullptr; | |||
127 | }; | |||
128 | ||||
129 | static SensorRegistryEntry s_sensorRegistry[static_cast<size_t>(SensorType::PlaceholderLast)] = {}; | |||
130 | ||||
131 | 850 | bool Sensor::Register() { | ||
132 | 850 | return s_sensorRegistry[getIndex()].Register(this); | ||
133 | } | |||
134 | ||||
135 | 689 | void Sensor::unregister() { | ||
136 | 689 | s_sensorRegistry[getIndex()].unregister(); | ||
137 | 689 | } | ||
138 | ||||
139 | 666 | /*static*/ void Sensor::resetRegistry() { | ||
140 | // Clear all entries | |||
141 |
2/2✓ Branch 1 taken 61272 times.
✓ Branch 2 taken 666 times.
|
2/2✓ Decision 'true' taken 61272 times.
✓ Decision 'false' taken 666 times.
|
61938 | for (size_t i = 0; i < efi::size(s_sensorRegistry); i++) { |
142 | 61272 | auto &entry = s_sensorRegistry[i]; | ||
143 | ||||
144 | 61272 | entry.reset(); | ||
145 | } | |||
146 | 666 | } | ||
147 | ||||
148 | 52442977 | /*static*/ SensorRegistryEntry *Sensor::getEntryForType(SensorType type) { | ||
149 | 52442977 | size_t index = getIndex(type); | ||
150 | // Check that we didn't get garbage | |||
151 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 52442977 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 52442977 times.
|
52442977 | if (index >= efi::size(s_sensorRegistry)) { |
152 | ✗ | return nullptr; | ||
153 | } | |||
154 | ||||
155 | 52442977 | return &s_sensorRegistry[index]; | ||
156 | } | |||
157 | ||||
158 | 219 | /*static*/ const Sensor *Sensor::getSensorOfType(SensorType type) { | ||
159 | 219 | auto entry = getEntryForType(type); | ||
160 |
1/2✓ Branch 0 taken 219 times.
✗ Branch 1 not taken.
|
219 | return entry ? entry->getSensor() : nullptr; | |
161 | } | |||
162 | ||||
163 | /** | |||
164 | * @returns NotNull: sensor result or UnexpectedCode::Configuration if sensor is not registered | |||
165 | */ | |||
166 | 35693685 | /*static*/ SensorResult Sensor::get(SensorType type) { | ||
167 | 35693685 | const auto entry = getEntryForType(type); | ||
168 | ||||
169 | // Check if this is a valid sensor entry | |||
170 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 35693685 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 35693685 times.
|
35693685 | if (!entry) { |
171 | ✗ | return UnexpectedCode::Configuration; | ||
172 | } | |||
173 | ||||
174 | 35693685 | return entry->get(); | ||
175 | } | |||
176 | ||||
177 | 14119760 | /*static*/ float Sensor::getRaw(SensorType type) { | ||
178 | 14119760 | const auto entry = getEntryForType(type); | ||
179 | ||||
180 |
1/2✓ Branch 0 taken 14119760 times.
✗ Branch 1 not taken.
|
14119760 | return entry ? entry->getRaw() : 0; | |
181 | } | |||
182 | ||||
183 | 236 | /*static*/ bool Sensor::isRedundant(SensorType type) { | ||
184 | 236 | const auto entry = getEntryForType(type); | ||
185 | ||||
186 |
3/4✓ Branch 0 taken 236 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 234 times.
✓ Branch 4 taken 2 times.
|
236 | return entry ? entry->isRedundant() : false; | |
187 | } | |||
188 | ||||
189 | 2626172 | /*static*/ bool Sensor::hasSensor(SensorType type) { | ||
190 | 2626172 | const auto entry = getEntryForType(type); | ||
191 | ||||
192 |
3/4✓ Branch 0 taken 2626172 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 515 times.
✓ Branch 4 taken 2625657 times.
|
2626172 | return entry ? entry->hasSensor() : false; | |
193 | } | |||
194 | ||||
195 | 104 | void Sensor::setInvalidMockValue(SensorType type) { | ||
196 | 104 | auto entry = getEntryForType(type); | ||
197 | ||||
198 |
1/2✓ Branch 0 taken 104 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 104 times.
✗ Decision 'false' not taken.
|
104 | if (entry) { |
199 | 104 | entry->setInvalidMockValue(); | ||
200 | } | |||
201 | 104 | } | ||
202 | ||||
203 | 2760 | /*static*/ void Sensor::setMockValue(SensorType type, float value, bool mockRedundant) { | ||
204 | 2760 | auto entry = getEntryForType(type); | ||
205 | ||||
206 |
1/2✓ Branch 0 taken 2760 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 2760 times.
✗ Decision 'false' not taken.
|
2760 | if (entry) { |
207 | 2760 | entry->setMockValue(value, mockRedundant); | ||
208 | } | |||
209 | 2760 | } | ||
210 | ||||
211 | 41 | /*static*/ void Sensor::resetMockValue(SensorType type) { | ||
212 | 41 | auto entry = getEntryForType(type); | ||
213 | ||||
214 |
1/2✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 41 times.
✗ Decision 'false' not taken.
|
41 | if (entry) { |
215 | 41 | entry->resetMock(); | ||
216 | } | |||
217 | 41 | } | ||
218 | ||||
219 | 21 | /*static*/ void Sensor::resetAllMocks() { | ||
220 | // Reset all mocks | |||
221 |
2/2✓ Branch 1 taken 1932 times.
✓ Branch 2 taken 21 times.
|
2/2✓ Decision 'true' taken 1932 times.
✓ Decision 'false' taken 21 times.
|
1953 | for (size_t i = 0; i < efi::size(s_sensorRegistry); i++) { |
222 | 1932 | s_sensorRegistry[i].resetMock(); | ||
223 | } | |||
224 | 21 | } | ||
225 | ||||
226 | 122 | /*static*/ const char* Sensor::getSensorName(SensorType type) { | ||
227 | 122 | return getSensorType(type); | ||
228 | } | |||
229 | ||||
230 | /*static*/ bool Sensor::s_inhibitSensorTimeouts = false; | |||
231 | ||||
232 | ✗ | /*static*/ void Sensor::inhibitTimeouts(bool inhibit) { | ||
233 | ✗ | Sensor::s_inhibitSensorTimeouts = inhibit; | ||
234 | ✗ | } | ||
235 | ||||
236 | // Print information about all sensors | |||
237 | ✗ | /*static*/ void Sensor::showAllSensorInfo() { | ||
238 | ✗ | for (size_t i = 1; i < efi::size(s_sensorRegistry); i++) { | ||
239 | ✗ | auto& entry = s_sensorRegistry[i]; | ||
240 | ✗ | const char* name = getSensorType((SensorType)i); | ||
241 | ||||
242 | ✗ | entry.showInfo(name); | ||
243 | } | |||
244 | ✗ | } | ||
245 | ||||
246 | // Print information about a particular sensor | |||
247 | ✗ | /*static*/ void Sensor::showInfo(SensorType type) { | ||
248 | ✗ | auto entry = getEntryForType(type); | ||
249 | ||||
250 | ✗ | if (entry) { | ||
251 | ✗ | entry->showInfo(getSensorName(type)); | ||
252 | } | |||
253 | ✗ | } | ||
254 | ||||
255 | /** | |||
256 | * this is definitely not the fastest implementation possible but good enough for now? | |||
257 | * todo: some sort of hashmap in the future? | |||
258 | */ | |||
259 | 8 | SensorType findSensorTypeByName(const char *name) { | ||
260 | using namespace rusefi::stringutil; | |||
261 | ||||
262 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
1/2✓ Decision 'true' taken 16 times.
✗ Decision 'false' not taken.
|
16 | for (size_t i = 0;i < efi::size(s_sensorRegistry); i++) { |
263 | 16 | SensorType type = (SensorType)i; | ||
264 | 16 | const char *sensorName = getSensorType(type); | ||
265 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
|
2/2✓ Decision 'true' taken 8 times.
✓ Decision 'false' taken 8 times.
|
16 | if (strEqualCaseInsensitive(sensorName, name)) { |
266 | 8 | return type; | ||
267 | } | |||
268 | } | |||
269 | ||||
270 | ✗ | return SensorType::Invalid; | ||
271 | } | |||
272 |