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 <android/hardware/automotive/vehicle/2.0/types.h>
18 #include <utils/Log.h>
19 #include <vhal_v2_0/Obd2SensorStore.h>
20 #include <vhal_v2_0/PropertyUtils.h>
21 #include <vhal_v2_0/VehiclePropertyStore.h>
22 #include <vhal_v2_0/VehicleUtils.h>
23 
24 namespace android {
25 namespace hardware {
26 namespace automotive {
27 namespace vehicle {
28 namespace V2_0 {
29 
30 namespace impl {
31 
32 namespace {
33 
fillDefaultObd2Frame(size_t numVendorIntegerSensors,size_t numVendorFloatSensors)34 std::unique_ptr<Obd2SensorStore> fillDefaultObd2Frame(size_t numVendorIntegerSensors,
35                                                       size_t numVendorFloatSensors) {
36     std::unique_ptr<Obd2SensorStore> sensorStore(
37             new Obd2SensorStore(numVendorIntegerSensors, numVendorFloatSensors));
38 
39     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS,
40                                   toInt(Obd2FuelSystemStatus::CLOSED_LOOP));
41     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON, 0);
42     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::IGNITION_MONITORS_SUPPORTED,
43                                   toInt(Obd2IgnitionMonitorKind::SPARK));
44     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::IGNITION_SPECIFIC_MONITORS,
45                                   Obd2CommonIgnitionMonitors::COMPONENTS_AVAILABLE |
46                                           Obd2CommonIgnitionMonitors::MISFIRE_AVAILABLE |
47                                           Obd2SparkIgnitionMonitors::AC_REFRIGERANT_AVAILABLE |
48                                           Obd2SparkIgnitionMonitors::EVAPORATIVE_SYSTEM_AVAILABLE);
49     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::INTAKE_AIR_TEMPERATURE, 35);
50     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::COMMANDED_SECONDARY_AIR_STATUS,
51                                   toInt(Obd2SecondaryAirStatus::FROM_OUTSIDE_OR_OFF));
52     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT, 1);
53     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::RUNTIME_SINCE_ENGINE_START, 500);
54     sensorStore->setIntegerSensor(
55             DiagnosticIntegerSensorIndex::DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON, 0);
56     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::WARMUPS_SINCE_CODES_CLEARED, 51);
57     sensorStore->setIntegerSensor(
58             DiagnosticIntegerSensorIndex::DISTANCE_TRAVELED_SINCE_CODES_CLEARED, 365);
59     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::ABSOLUTE_BAROMETRIC_PRESSURE, 30);
60     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::CONTROL_MODULE_VOLTAGE, 12);
61     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::AMBIENT_AIR_TEMPERATURE, 18);
62     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::MAX_FUEL_AIR_EQUIVALENCE_RATIO, 1);
63     sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::FUEL_TYPE,
64                                   toInt(Obd2FuelType::GASOLINE));
65     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD, 0.153);
66     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1, -0.16);
67     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1, -0.16);
68     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK2, -0.16);
69     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK2, -0.16);
70     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::INTAKE_MANIFOLD_ABSOLUTE_PRESSURE, 7.5);
71     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ENGINE_RPM, 1250.);
72     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::VEHICLE_SPEED, 40.);
73     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::TIMING_ADVANCE, 2.5);
74     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::THROTTLE_POSITION, 19.75);
75     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::OXYGEN_SENSOR1_VOLTAGE, 0.265);
76     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::FUEL_TANK_LEVEL_INPUT, 0.824);
77     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::EVAPORATION_SYSTEM_VAPOR_PRESSURE,
78                                 -0.373);
79     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::CATALYST_TEMPERATURE_BANK1_SENSOR1,
80                                 190.);
81     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::RELATIVE_THROTTLE_POSITION, 3.);
82     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ABSOLUTE_THROTTLE_POSITION_B, 0.306);
83     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ACCELERATOR_PEDAL_POSITION_D, 0.188);
84     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ACCELERATOR_PEDAL_POSITION_E, 0.094);
85     sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::COMMANDED_THROTTLE_ACTUATOR, 0.024);
86 
87     return sensorStore;
88 }
89 
90 }  // namespace
91 
initObd2LiveFrame(VehiclePropertyStore * propStore,const VehiclePropConfig & propConfig)92 void initObd2LiveFrame(VehiclePropertyStore* propStore, const VehiclePropConfig& propConfig) {
93     auto liveObd2Frame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
94     auto sensorStore = fillDefaultObd2Frame(static_cast<size_t>(propConfig.configArray[0]),
95                                             static_cast<size_t>(propConfig.configArray[1]));
96     sensorStore->fillPropValue("", liveObd2Frame.get());
97     liveObd2Frame->prop = OBD2_LIVE_FRAME;
98 
99     propStore->writeValue(*liveObd2Frame, true);
100 }
101 
initObd2FreezeFrame(VehiclePropertyStore * propStore,const VehiclePropConfig & propConfig)102 void initObd2FreezeFrame(VehiclePropertyStore* propStore, const VehiclePropConfig& propConfig) {
103     auto sensorStore = fillDefaultObd2Frame(static_cast<size_t>(propConfig.configArray[0]),
104                                             static_cast<size_t>(propConfig.configArray[1]));
105 
106     static std::vector<std::string> sampleDtcs = {"P0070", "P0102", "P0123"};
107     for (auto&& dtc : sampleDtcs) {
108         auto freezeFrame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
109         sensorStore->fillPropValue(dtc, freezeFrame.get());
110         freezeFrame->prop = OBD2_FREEZE_FRAME;
111         ALOGE("freeze frame: %lld", (long long)freezeFrame->timestamp);
112 
113         propStore->writeValue(*freezeFrame, true);
114     }
115 }
116 
fillObd2FreezeFrame(VehiclePropertyStore * propStore,const VehiclePropValue & requestedPropValue,VehiclePropValue * outValue)117 StatusCode fillObd2FreezeFrame(VehiclePropertyStore* propStore,
118                                const VehiclePropValue& requestedPropValue,
119                                VehiclePropValue* outValue) {
120     if (requestedPropValue.value.int64Values.size() != 1) {
121         ALOGE("asked for OBD2_FREEZE_FRAME without valid timestamp");
122         return StatusCode::INVALID_ARG;
123     }
124     if (propStore->readValuesForProperty(OBD2_FREEZE_FRAME).size() == 0) {
125         // Should no freeze frame be available at the given timestamp, a response of NOT_AVAILABLE
126         // must be returned by the implementation
127         return StatusCode::NOT_AVAILABLE;
128     }
129     auto timestamp = requestedPropValue.value.int64Values[0];
130     auto freezeFrame = propStore->readValueOrNull(OBD2_FREEZE_FRAME, 0, timestamp);
131     if (freezeFrame == nullptr) {
132         ALOGE("asked for OBD2_FREEZE_FRAME at invalid timestamp");
133         return StatusCode::INVALID_ARG;
134     }
135     outValue->prop = OBD2_FREEZE_FRAME;
136     outValue->value.int32Values = freezeFrame->value.int32Values;
137     outValue->value.floatValues = freezeFrame->value.floatValues;
138     outValue->value.bytes = freezeFrame->value.bytes;
139     outValue->value.stringValue = freezeFrame->value.stringValue;
140     outValue->timestamp = freezeFrame->timestamp;
141     return StatusCode::OK;
142 }
143 
fillObd2DtcInfo(VehiclePropertyStore * propStore,VehiclePropValue * outValue)144 StatusCode fillObd2DtcInfo(VehiclePropertyStore* propStore, VehiclePropValue* outValue) {
145     std::vector<int64_t> timestamps;
146     for (const auto& freezeFrame : propStore->readValuesForProperty(OBD2_FREEZE_FRAME)) {
147         timestamps.push_back(freezeFrame.timestamp);
148     }
149     outValue->value.int64Values = timestamps;
150     outValue->prop = OBD2_FREEZE_FRAME_INFO;
151     return StatusCode::OK;
152 }
153 
clearObd2FreezeFrames(VehiclePropertyStore * propStore,const VehiclePropValue & propValue)154 StatusCode clearObd2FreezeFrames(VehiclePropertyStore* propStore,
155                                  const VehiclePropValue& propValue) {
156     if (propValue.value.int64Values.size() == 0) {
157         propStore->removeValuesForProperty(OBD2_FREEZE_FRAME);
158         return StatusCode::OK;
159     } else {
160         for (int64_t timestamp : propValue.value.int64Values) {
161             auto freezeFrame = propStore->readValueOrNull(OBD2_FREEZE_FRAME, 0, timestamp);
162             if (freezeFrame == nullptr) {
163                 ALOGE("asked for OBD2_FREEZE_FRAME at invalid timestamp");
164                 return StatusCode::INVALID_ARG;
165             }
166             propStore->removeValue(*freezeFrame);
167         }
168     }
169     return StatusCode::OK;
170 }
171 
isDiagnosticProperty(const VehiclePropConfig & propConfig)172 bool isDiagnosticProperty(const VehiclePropConfig& propConfig) {
173     return (propConfig.prop == OBD2_LIVE_FRAME || propConfig.prop == OBD2_FREEZE_FRAME ||
174             propConfig.prop == OBD2_FREEZE_FRAME_CLEAR ||
175             propConfig.prop == OBD2_FREEZE_FRAME_INFO);
176 }
177 
178 }  // namespace impl
179 
180 }  // namespace V2_0
181 }  // namespace vehicle
182 }  // namespace automotive
183 }  // namespace hardware
184 }  // namespace android
185