1 /*
2  * Copyright (C) 2017 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 package com.android.car.obd2.test;
18 
19 import static com.android.car.obd2.test.Utils.concatIntArrays;
20 import static com.android.car.obd2.test.Utils.stringsToIntArray;
21 import static org.junit.Assert.*;
22 
23 import com.android.car.obd2.Obd2Command;
24 import com.android.car.obd2.Obd2Connection;
25 import java.util.Optional;
26 import org.junit.Test;
27 
28 public class Obd2CommandTest {
29     private static final String[] EXPECTED_INIT_COMMANDS =
30             new String[] {
31                 "ATD\r", "ATZ\r", "AT E0\r", "AT L0\r", "AT S0\r", "AT H0\r", "AT SP 0\r"
32             };
33 
34     private static final String OBD2_PROMPT = ">";
35 
36     private static final String[] EXPECTED_INIT_RESPONSES =
37             new String[] {
38                 OBD2_PROMPT,
39                 OBD2_PROMPT,
40                 OBD2_PROMPT,
41                 OBD2_PROMPT,
42                 OBD2_PROMPT,
43                 OBD2_PROMPT,
44                 OBD2_PROMPT
45             };
46 
47     private static final float FLOAT_EQUALITY_DELTA = 0.0001f;
48 
checkLiveFrameIntCommand(int pid, String responseBytes, int expectedResponse)49     void checkLiveFrameIntCommand(int pid, String responseBytes, int expectedResponse) {
50         String[] commandToSend = new String[] {String.format("01%02X\r", pid)};
51 
52         String[] responseToGet =
53                 new String[] {String.format("41 %02X %s", pid, responseBytes), OBD2_PROMPT};
54 
55         MockObd2UnderlyingTransport transport =
56                 new MockObd2UnderlyingTransport(
57                         concatIntArrays(
58                                 stringsToIntArray(EXPECTED_INIT_COMMANDS),
59                                 stringsToIntArray(commandToSend)),
60                         concatIntArrays(
61                                 stringsToIntArray(EXPECTED_INIT_RESPONSES),
62                                 stringsToIntArray(responseToGet)));
63         Obd2Connection obd2Connection = new Obd2Connection(transport);
64         Obd2Command<Integer> commandObject =
65                 Obd2Command.getLiveFrameCommand(Obd2Command.getIntegerCommand(pid));
66         assertNotNull(commandObject);
67         Optional<Integer> receivedResponse = Optional.empty();
68         try {
69             receivedResponse = commandObject.run(obd2Connection);
70         } catch (Exception e) {
71             assertTrue("live frame command " + pid + " caused an exception: " + e, false);
72         }
73         assertTrue("live frame contains a response", receivedResponse.isPresent());
74         assertEquals(expectedResponse, (int) receivedResponse.get());
75     }
76 
checkLiveFrameFloatCommand(int pid, String responseBytes, float expectedResponse)77     void checkLiveFrameFloatCommand(int pid, String responseBytes, float expectedResponse) {
78         String[] commandToSend = new String[] {String.format("01%02X\r", pid)};
79 
80         String[] responseToGet =
81                 new String[] {String.format("41 %02X %s", pid, responseBytes), OBD2_PROMPT};
82 
83         MockObd2UnderlyingTransport transport =
84                 new MockObd2UnderlyingTransport(
85                         concatIntArrays(
86                                 stringsToIntArray(EXPECTED_INIT_COMMANDS),
87                                 stringsToIntArray(commandToSend)),
88                         concatIntArrays(
89                                 stringsToIntArray(EXPECTED_INIT_RESPONSES),
90                                 stringsToIntArray(responseToGet)));
91         Obd2Connection obd2Connection = new Obd2Connection(transport);
92         Obd2Command<Float> commandObject =
93                 Obd2Command.getLiveFrameCommand(Obd2Command.getFloatCommand(pid));
94         assertNotNull(commandObject);
95         Optional<Float> receivedResponse = Optional.empty();
96         try {
97             receivedResponse = commandObject.run(obd2Connection);
98         } catch (Exception e) {
99             assertTrue("live frame command " + pid + " caused an exception: " + e, false);
100         }
101         assertTrue("live frame contains a response", receivedResponse.isPresent());
102         assertEquals(expectedResponse, (float) receivedResponse.get(), FLOAT_EQUALITY_DELTA);
103     }
104 
checkFreezeFrameIntCommand(int pid, String responseBytes, int expectedResponse)105     void checkFreezeFrameIntCommand(int pid, String responseBytes, int expectedResponse) {
106         String[] commandToSend = new String[] {String.format("02%02X 01\r", pid)};
107 
108         String[] responseToGet =
109                 new String[] {String.format("42 %02X 01 %s", pid, responseBytes), OBD2_PROMPT};
110 
111         MockObd2UnderlyingTransport transport =
112                 new MockObd2UnderlyingTransport(
113                         concatIntArrays(
114                                 stringsToIntArray(EXPECTED_INIT_COMMANDS),
115                                 stringsToIntArray(commandToSend)),
116                         concatIntArrays(
117                                 stringsToIntArray(EXPECTED_INIT_RESPONSES),
118                                 stringsToIntArray(responseToGet)));
119         Obd2Connection obd2Connection = new Obd2Connection(transport);
120         Obd2Command<Integer> commandObject =
121                 Obd2Command.getFreezeFrameCommand(Obd2Command.getIntegerCommand(pid), 0x1);
122         assertNotNull(commandObject);
123         Optional<Integer> receivedResponse = Optional.empty();
124         try {
125             receivedResponse = commandObject.run(obd2Connection);
126         } catch (Exception e) {
127             assertTrue("freeze frame command " + pid + " caused an exception: " + e, false);
128         }
129         assertTrue("freeze frame contains a response", receivedResponse.isPresent());
130         assertEquals(expectedResponse, (int) receivedResponse.get());
131     }
132 
checkFreezeFrameFloatCommand(int pid, String responseBytes, float expectedResponse)133     void checkFreezeFrameFloatCommand(int pid, String responseBytes, float expectedResponse) {
134         String[] commandToSend = new String[] {String.format("02%02X 01\r", pid)};
135 
136         String[] responseToGet =
137                 new String[] {String.format("42 %02X 01 %s", pid, responseBytes), OBD2_PROMPT};
138 
139         MockObd2UnderlyingTransport transport =
140                 new MockObd2UnderlyingTransport(
141                         concatIntArrays(
142                                 stringsToIntArray(EXPECTED_INIT_COMMANDS),
143                                 stringsToIntArray(commandToSend)),
144                         concatIntArrays(
145                                 stringsToIntArray(EXPECTED_INIT_RESPONSES),
146                                 stringsToIntArray(responseToGet)));
147         Obd2Connection obd2Connection = new Obd2Connection(transport);
148         Obd2Command<Float> commandObject =
149                 Obd2Command.getFreezeFrameCommand(Obd2Command.getFloatCommand(pid), 0x1);
150         assertNotNull(commandObject);
151         Optional<Float> receivedResponse = Optional.empty();
152         try {
153             receivedResponse = commandObject.run(obd2Connection);
154         } catch (Exception e) {
155             assertTrue("freeze frame command " + pid + " caused an exception: " + e, false);
156         }
157         assertTrue("freeze frame contains a response", receivedResponse.isPresent());
158         assertEquals(expectedResponse, (float) receivedResponse.get(), FLOAT_EQUALITY_DELTA);
159     }
160 
checkCommand(int pid, String responseBytes, int expectedResponse)161     void checkCommand(int pid, String responseBytes, int expectedResponse) {
162         checkLiveFrameIntCommand(pid, responseBytes, expectedResponse);
163         checkFreezeFrameIntCommand(pid, responseBytes, expectedResponse);
164     }
165 
checkCommand(int pid, String responseBytes, float expectedResponse)166     void checkCommand(int pid, String responseBytes, float expectedResponse) {
167         checkLiveFrameFloatCommand(pid, responseBytes, expectedResponse);
168         checkFreezeFrameFloatCommand(pid, responseBytes, expectedResponse);
169     }
170 
171     @Test
testEngineOilTemperature()172     public void testEngineOilTemperature() {
173         checkCommand(0x5C, "87", 95);
174     }
175 
176     @Test
testAmbientAirTemperature()177     public void testAmbientAirTemperature() {
178         checkCommand(0x46, "A1", 63.137257f);
179     }
180 
181     @Test
testCalculatedEngineLoad()182     public void testCalculatedEngineLoad() {
183         checkCommand(0x04, "34", 23.1111f);
184     }
185 
186     @Test
testEngineCoolantTemperature()187     public void testEngineCoolantTemperature() {
188         checkCommand(0x05, "63", 59);
189     }
190 
191     @Test
testFuelGaugePressure()192     public void testFuelGaugePressure() {
193         checkCommand(0x0A, "12", 54);
194     }
195 
196     @Test
testFuelSystemStatus()197     public void testFuelSystemStatus() {
198         checkCommand(0x03, "08", 8);
199     }
200 
201     @Test
testFuelTankLevel()202     public void testFuelTankLevel() {
203         checkCommand(0x2F, "5F", 37.2549f);
204     }
205 
206     @Test
testFuelTrim()207     public void testFuelTrim() {
208         checkCommand(0x06, "42", 54.6875f);
209         checkCommand(0x07, "42", 54.6875f);
210         checkCommand(0x08, "42", 54.6875f);
211         checkCommand(0x09, "42", 54.6875f);
212     }
213 
214     @Test
testRpm()215     public void testRpm() {
216         checkCommand(0x0C, "12 0F", 1155);
217     }
218 
219     @Test
testEngineRuntime()220     public void testEngineRuntime() {
221         checkCommand(0x1F, "04 10", 1040);
222     }
223 
224     @Test
testSpeed()225     public void testSpeed() {
226         checkCommand(0x0D, "82", 130);
227     }
228 
229     @Test
testThrottlePosition()230     public void testThrottlePosition() {
231         checkCommand(0x11, "3D", 23.921576f);
232     }
233 }
234