1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "Obd2SensorStore.h"
18
19 #include <VehicleUtils.h>
20
21 #include <utils/SystemClock.h>
22
23 namespace android {
24 namespace hardware {
25 namespace automotive {
26 namespace vehicle {
27 namespace fake {
28 namespace obd2frame {
29
30 using ::aidl::android::hardware::automotive::vehicle::DiagnosticFloatSensorIndex;
31 using ::aidl::android::hardware::automotive::vehicle::DiagnosticIntegerSensorIndex;
32 using ::aidl::android::hardware::automotive::vehicle::StatusCode;
33 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
34 using ::android::base::Error;
35 using ::android::base::Result;
36
BitmaskInVector(size_t numBits)37 Obd2SensorStore::BitmaskInVector::BitmaskInVector(size_t numBits) {
38 mNumBits = numBits;
39 resize(numBits);
40 }
41
resize(size_t numBits)42 void Obd2SensorStore::BitmaskInVector::resize(size_t numBits) {
43 mNumBits = numBits;
44 mStorage = std::vector<uint8_t>((numBits + 7) / 8, 0);
45 }
46
set(size_t index,bool value)47 Result<void> Obd2SensorStore::BitmaskInVector::set(size_t index, bool value) {
48 const size_t byteIndex = index / 8;
49 const size_t bitIndex = index % 8;
50 if (index >= mNumBits) {
51 return Error() << "out of bound";
52 }
53 const uint8_t byte = mStorage[byteIndex];
54 uint8_t newValue = value ? (byte | (1 << bitIndex)) : (byte & ~(1 << bitIndex));
55 mStorage[byteIndex] = newValue;
56 return {};
57 }
58
get(size_t index) const59 Result<bool> Obd2SensorStore::BitmaskInVector::get(size_t index) const {
60 const size_t byteIndex = index / 8;
61 const size_t bitIndex = index % 8;
62 if (index >= mNumBits) {
63 return Error() << "out of bound";
64 }
65 const uint8_t byte = mStorage[byteIndex];
66 return (byte & (1 << bitIndex)) != 0;
67 }
68
getBitmask() const69 const std::vector<uint8_t>& Obd2SensorStore::BitmaskInVector::getBitmask() const {
70 return mStorage;
71 }
72
Obd2SensorStore(std::shared_ptr<VehiclePropValuePool> valuePool,size_t numVendorIntegerSensors,size_t numVendorFloatSensors)73 Obd2SensorStore::Obd2SensorStore(std::shared_ptr<VehiclePropValuePool> valuePool,
74 size_t numVendorIntegerSensors, size_t numVendorFloatSensors)
75 : mValuePool(valuePool) {
76 const size_t numSystemIntegerSensors = getLastIndex<DiagnosticIntegerSensorIndex>() + 1;
77 const size_t numSystemFloatSensors = getLastIndex<DiagnosticFloatSensorIndex>() + 1;
78 mIntegerSensors = std::vector<int32_t>(numSystemIntegerSensors + numVendorIntegerSensors, 0);
79 mFloatSensors = std::vector<float>(numSystemFloatSensors + numVendorFloatSensors, 0);
80 mSensorsBitmask.resize(mIntegerSensors.size() + mFloatSensors.size());
81 }
82
setIntegerSensor(DiagnosticIntegerSensorIndex index,int32_t value)83 StatusCode Obd2SensorStore::setIntegerSensor(DiagnosticIntegerSensorIndex index, int32_t value) {
84 return setIntegerSensor(toInt(index), value);
85 }
setFloatSensor(DiagnosticFloatSensorIndex index,float value)86 StatusCode Obd2SensorStore::setFloatSensor(DiagnosticFloatSensorIndex index, float value) {
87 return setFloatSensor(toInt(index), value);
88 }
89
setIntegerSensor(size_t index,int32_t value)90 StatusCode Obd2SensorStore::setIntegerSensor(size_t index, int32_t value) {
91 if (index >= mIntegerSensors.size()) {
92 ALOGE("failed to set integer sensor: OOB");
93 return StatusCode::INVALID_ARG;
94 }
95 mIntegerSensors[index] = value;
96 if (auto result = mSensorsBitmask.set(index, true); !result.ok()) {
97 ALOGE("failed to set integer sensor: %s", result.error().message().c_str());
98 return StatusCode::INVALID_ARG;
99 }
100 return StatusCode::OK;
101 }
102
setFloatSensor(size_t index,float value)103 StatusCode Obd2SensorStore::setFloatSensor(size_t index, float value) {
104 if (index >= mFloatSensors.size()) {
105 ALOGE("failed to set integer sensor: OOB");
106 return StatusCode::INVALID_ARG;
107 }
108 mFloatSensors[index] = value;
109 if (auto result = mSensorsBitmask.set(index + mIntegerSensors.size(), true); !result.ok()) {
110 ALOGE("failed to set float sensor: %s", result.error().message().c_str());
111 return StatusCode::INVALID_ARG;
112 }
113 return StatusCode::OK;
114 }
115
getIntegerSensors() const116 const std::vector<int32_t>& Obd2SensorStore::getIntegerSensors() const {
117 return mIntegerSensors;
118 }
119
getFloatSensors() const120 const std::vector<float>& Obd2SensorStore::getFloatSensors() const {
121 return mFloatSensors;
122 }
123
getSensorsBitmask() const124 const std::vector<uint8_t>& Obd2SensorStore::getSensorsBitmask() const {
125 return mSensorsBitmask.getBitmask();
126 }
127
getSensorProperty(const std::string & dtc) const128 VehiclePropValuePool::RecyclableType Obd2SensorStore::getSensorProperty(
129 const std::string& dtc) const {
130 auto propValue = mValuePool->obtain(VehiclePropertyType::MIXED);
131 propValue->timestamp = elapsedRealtimeNano();
132 propValue->value.int32Values = getIntegerSensors();
133 propValue->value.floatValues = getFloatSensors();
134 propValue->value.byteValues = getSensorsBitmask();
135 propValue->value.stringValue = dtc;
136 return propValue;
137 }
138
139 } // namespace obd2frame
140 } // namespace fake
141 } // namespace vehicle
142 } // namespace automotive
143 } // namespace hardware
144 } // namespace android
145