| 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 | 2762 | void setMockValue(float value, bool mockRedundant) { | ||
| 20 | 2762 | m_mockValue = value; | ||
| 21 | 2762 | m_useMock = true; | ||
| 22 | 2762 | m_valid = true; | ||
| 23 | 2762 | m_mockRedundant = mockRedundant; | ||
| 24 | 2762 | } | ||
| 25 | ||||
| 26 | 63337 | void resetMock() { | ||
| 27 | 63337 | m_useMock = false; | ||
| 28 | 63337 | m_mockValue = 0.0f; | ||
| 29 | 63337 | } | ||
| 30 | ||||
| 31 | 61364 | void reset() { | ||
| 32 | 61364 | m_sensor = nullptr; | ||
| 33 | 61364 | resetMock(); | ||
| 34 | 61364 | } | ||
| 35 | ||||
| 36 | 851 | 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 844 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 6 times.
|
2/2✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 850 times.
|
851 | 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 | 850 | m_sensor = sensor; | ||
| 45 | 850 | return true; | ||
| 46 | } | |||
| 47 | } | |||
| 48 | ||||
| 49 | 690 | void unregister() { | ||
| 50 | 690 | m_sensor = nullptr; | ||
| 51 | 690 | } | ||
| 52 | ||||
| 53 | 36258267 | SensorResult get() const { | ||
| 54 | // Check if mock | |||
| 55 |
2/2✓ Branch 0 taken 1084963 times.
✓ Branch 1 taken 35173304 times.
|
2/2✓ Decision 'true' taken 1084963 times.
✓ Decision 'false' taken 35173304 times.
|
36258267 | if (m_useMock) { |
| 56 |
2/2✓ Branch 0 taken 306 times.
✓ Branch 1 taken 1084657 times.
|
2/2✓ Decision 'true' taken 306 times.
✓ Decision 'false' taken 1084657 times.
|
1084963 | if (!m_valid) { |
| 57 | 306 | return unexpected; | ||
| 58 | } | |||
| 59 | 1084657 | return m_mockValue; | ||
| 60 | } | |||
| 61 | ||||
| 62 | // Get the sensor out of the entry | |||
| 63 | 35173304 | const Sensor *s = m_sensor; | ||
| 64 |
2/2✓ Branch 0 taken 640188 times.
✓ Branch 1 taken 34533116 times.
|
2/2✓ Decision 'true' taken 640188 times.
✓ Decision 'false' taken 34533116 times.
|
35173304 | if (s) { |
| 65 | // If this sensor says it doesn't exist, return unexpected | |||
| 66 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 640188 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 640188 times.
|
640188 | if (!s->hasSensor()) { |
| 67 | ✗ | return UnexpectedCode::Configuration; | ||
| 68 | } | |||
| 69 | ||||
| 70 | // If we found the sensor, ask it for a result. | |||
| 71 | 640188 | return s->get(); | ||
| 72 | } | |||
| 73 | ||||
| 74 | // We've exhausted all valid ways to return something - sensor not found. | |||
| 75 | 34533116 | 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 | 2666774 | bool hasSensor() const { | ||
| 93 |
6/6✓ Branch 0 taken 2666494 times.
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 236 times.
✓ Branch 3 taken 2666258 times.
✓ Branch 5 taken 235 times.
✓ Branch 6 taken 1 time.
|
2666774 | return m_useMock || (m_sensor && m_sensor->hasSensor()); | |
| 94 | } | |||
| 95 | ||||
| 96 | 14339108 | float getRaw() const { | ||
| 97 | 14339108 | const auto sensor = m_sensor; | ||
| 98 | ||||
| 99 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 14339106 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 14339106 times.
|
14339108 | if (sensor) { |
| 100 | 2 | return sensor->getRaw(); | ||
| 101 | } | |||
| 102 | ||||
| 103 | // We've exhausted all valid ways to return something - sensor not found. | |||
| 104 | 14339106 | 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 | 851 | bool Sensor::Register() { | ||
| 132 | 851 | return s_sensorRegistry[getIndex()].Register(this); | ||
| 133 | } | |||
| 134 | ||||
| 135 | 690 | void Sensor::unregister() { | ||
| 136 | 690 | s_sensorRegistry[getIndex()].unregister(); | ||
| 137 | 690 | } | ||
| 138 | ||||
| 139 | 667 | /*static*/ void Sensor::resetRegistry() { | ||
| 140 | // Clear all entries | |||
| 141 |
2/2✓ Branch 1 taken 61364 times.
✓ Branch 2 taken 667 times.
|
2/2✓ Decision 'true' taken 61364 times.
✓ Decision 'false' taken 667 times.
|
62031 | for (size_t i = 0; i < efi::size(s_sensorRegistry); i++) { |
| 142 | 61364 | auto &entry = s_sensorRegistry[i]; | ||
| 143 | ||||
| 144 | 61364 | entry.reset(); | ||
| 145 | } | |||
| 146 | 667 | } | ||
| 147 | ||||
| 148 | 53267511 | /*static*/ SensorRegistryEntry *Sensor::getEntryForType(SensorType type) { | ||
| 149 | 53267511 | size_t index = getIndex(type); | ||
| 150 | // Check that we didn't get garbage | |||
| 151 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 53267511 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 53267511 times.
|
53267511 | if (index >= efi::size(s_sensorRegistry)) { |
| 152 | ✗ | return nullptr; | ||
| 153 | } | |||
| 154 | ||||
| 155 | 53267511 | 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 | 36258267 | /*static*/ SensorResult Sensor::get(SensorType type) { | ||
| 167 | 36258267 | 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 36258267 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 36258267 times.
|
36258267 | if (!entry) { |
| 171 | ✗ | return UnexpectedCode::Configuration; | ||
| 172 | } | |||
| 173 | ||||
| 174 | 36258267 | return entry->get(); | ||
| 175 | } | |||
| 176 | ||||
| 177 | 14339108 | /*static*/ float Sensor::getRaw(SensorType type) { | ||
| 178 | 14339108 | const auto entry = getEntryForType(type); | ||
| 179 | ||||
| 180 |
1/2✓ Branch 0 taken 14339108 times.
✗ Branch 1 not taken.
|
14339108 | 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 | 2666774 | /*static*/ bool Sensor::hasSensor(SensorType type) { | ||
| 190 | 2666774 | const auto entry = getEntryForType(type); | ||
| 191 | ||||
| 192 |
3/4✓ Branch 0 taken 2666774 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 515 times.
✓ Branch 4 taken 2666259 times.
|
2666774 | 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 | 2762 | /*static*/ void Sensor::setMockValue(SensorType type, float value, bool mockRedundant) { | ||
| 204 | 2762 | auto entry = getEntryForType(type); | ||
| 205 | ||||
| 206 |
1/2✓ Branch 0 taken 2762 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 2762 times.
✗ Decision 'false' not taken.
|
2762 | if (entry) { |
| 207 | 2762 | entry->setMockValue(value, mockRedundant); | ||
| 208 | } | |||
| 209 | 2762 | } | ||
| 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 |