Files
elmer/android/library/com/fr3ts0n/ecu/prot/obd/ObdProt.java
T

925 lines
33 KiB
Java
Executable File

/**
* (C) Copyright 2015 by fr3ts0n <erwin.scheuch-heilig@gmx.at>
* <p>
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
* <p>
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* <p>
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
package com.fr3ts0n.ecu.prot.obd;
import com.fr3ts0n.ecu.Conversion;
import com.fr3ts0n.ecu.EcuCodeItem;
import com.fr3ts0n.ecu.EcuCodeList;
import com.fr3ts0n.ecu.EcuConversions;
import com.fr3ts0n.ecu.EcuDataItem;
import com.fr3ts0n.ecu.EcuDataItems;
import com.fr3ts0n.ecu.EcuDataPv;
import com.fr3ts0n.ecu.ObdCodeItem;
import com.fr3ts0n.ecu.ObdPid;
import com.fr3ts0n.prot.ProtoHeader;
import com.fr3ts0n.prot.TelegramListener;
import com.fr3ts0n.prot.TelegramWriter;
import com.fr3ts0n.pvs.PvChangeEvent;
import com.fr3ts0n.pvs.PvList;
import java.beans.PropertyChangeEvent;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Vector;
/**
* OBD communication protocol layer
*
* The OBD protocol supports services which serve multiple PID's
* A request of PID which is a multiple of 0x20 (0x00,0x20...0xE0) for each
* service returns a bitmask of the next 32 PIDs which are suppoted by the vehicle
* @author erwin
*/
public class ObdProt extends ProtoHeader
implements TelegramListener, TelegramWriter
{
public static final int OBD_SVC_NONE = 0x00;
public static final int OBD_SVC_DATA = 0x01;
public static final int OBD_SVC_FREEZEFRAME = 0x02;
public static final int OBD_SVC_READ_CODES = 0x03;
public static final int OBD_SVC_CLEAR_CODES = 0x04;
public static final int OBD_SVC_O2_RESULT = 0x05;
public static final int OBD_SVC_MON_RESULT = 0x06;
public static final int OBD_SVC_PENDINGCODES = 0x07;
public static final int OBD_SVC_CTRL_MODE = 0x08;
public static final int OBD_SVC_VEH_INFO = 0x09;
public static final int OBD_SVC_PERMACODES = 0x0A;
/** negative response ID */
private static final int OBD_ID_NRC = 0x7F;
/** perform immediate reset on NRC reception? */
private boolean isResetOnNrc()
{
return resetOnNrc;
}
/** Set protocol parameter
* @param resetOnNrc perform immediate reset on NRC reception?
*/
public void setResetOnNrc(boolean resetOnNrc)
{
log.info(String.format("Reset on NRC = %b", resetOnNrc));
this.resetOnNrc = resetOnNrc;
}
/** negative response codes */
public enum NRC
{
GR(0x10, "General reject",DISP.ERROR, REACT.RESET),
SNS(0x11, "Service 0x%02X not supported", DISP.ERROR, REACT.CANCEL),
SFNS(0x12, "Sub-Function not supported (SVC:0x%02X)", DISP.NOTIFY, REACT.SKIP),
IMLOIF(0x13, "Incorrect message length or invalid format", DISP.NOTIFY, REACT.SKIP),
RTL(0x14, "Response too long", DISP.NOTIFY, REACT.SKIP),
BRR(0x21, "Busy repeat request", DISP.NOTIFY, REACT.REPEAT),
CNC(0x22, "Conditions not correct (SVC:0x%02X)", DISP.ERROR, REACT.CANCEL),
RSE(0x24, "Request sequence error", DISP.ERROR, REACT.CANCEL),
NRFSC(0x25, "No response from sub-net component", DISP.ERROR, REACT.RESET),
FPEORA(0x26, "Failure prevents execution of requested action", DISP.ERROR, REACT.CANCEL),
ROOR(0x31, "Request out of range (SVC:0x%02X)", DISP.NOTIFY, REACT.SKIP),
SAD(0x33, "Security access denied", DISP.ERROR, REACT.CANCEL),
IK(0x35, "Invalid key", DISP.ERROR, REACT.RESET),
ENOA(0x36, "Exceeded number of attempts", DISP.ERROR, REACT.RESET),
RTDNE(0x37, "Required time delay not expired", DISP.NOTIFY, REACT.REPEAT),
UDNA(0x70, "Upload/Download not accepted", DISP.ERROR, REACT.CANCEL),
TDS(0x71, "Transfer data suspended", DISP.NOTIFY, REACT.REPEAT),
GPF(0x72, "General programming failure", DISP.ERROR, REACT.CANCEL),
WBSC(0x73, "Wrong Block Sequence Counter", DISP.ERROR, REACT.CANCEL),
RCRRP(0x78, "Request correctly received but response is pending", DISP.NOTIFY, REACT.IGNORE),
SFNSIAS(0x7E, "Sub-Function not supported in active session (SVC:0x%02X)", DISP.NOTIFY, REACT.SKIP),
SNSIAS(0x7F, "Service 0x%02X not supported in active session", DISP.ERROR, REACT.CANCEL);
/** NRC display classifiers */
public enum DISP
{
HIDE, /**< Do NOT display error */
NOTIFY, /**< Display notification (w/o confirmation) */
WARN, /**< Display warning (w/ confirmation) */
ERROR /**< Display error (w/ confirmation) */
}
/** NRC immediate protocol reaction classifiers */
public enum REACT
{
IGNORE, /**< Ignore NRC */
SKIP, /**< Skip last command */
REPEAT, /**< Repeat last command */
CANCEL, /**< Cancel command sequence / loop */
RESET /**< Reset adapter */
}
public final int code;
public final String description;
public final DISP disp;
public final REACT react;
NRC(int _code, String _description, DISP _DISPClass, REACT _REACTClass)
{
code = _code;
description = _description;
disp = _DISPClass;
react = _REACTClass;
}
/**
* Get NRC with specified ID (NRC-code)
* @param id ID (NRC-code) to search
* @return specified NRC, or null if not found
*/
static NRC get(int id)
{
NRC result = null;
for (NRC nrc : values())
{
if (nrc.code == id)
{
result = nrc;
break;
}
}
return result;
}
/** return String representative */
public String toString(int service)
{
return String.format("(NRC:0x%02X) %s", code, String.format(description, service));
}
}
/** property name "number of codes" */
public static final String PROP_NUM_CODES = "numCodes";
public static final String PROP_NRC = "NRC";
// current supported PID
private static int currSupportedPid = 0;
static boolean pidsWrapped = false;
/** content of last sent message */
static String lastTxMsg = "";
/** content of last received message */
static String lastRxMsg = "";
/** Holds value of property service. */
int service = OBD_SVC_NONE;
/** service of last incoming message */
private int msgService = OBD_SVC_NONE;
/** List of PIDs supported by the vehicle */
private static final Vector<ObdPid> pidSupported = new Vector<ObdPid>();
/** positive response fields */
private static final int ID_OBD_SVC = 0;
private static final int ID_OBD_PID = 1;
private static final int ID_OBD_FRAMEID = 2;
/** negative response fields */
public static final int ID_NR_ID = 0;
private static final int ID_NR_SVC = 1;
private static final int ID_NR_CODE = 2;
/**
* Negative response parameters
* List of telegram parameters in order of appearance
*/
private static final int[][] NR_PARAMETERS =
/* START, LEN, PARAM-TYPE // REMARKS */
/* ------------------------------------------- */
{{0, 2, PT_HEX}, // ID_NR_ID
{2, 2, PT_HEX}, // ID_NR_SVC
{4, 2, PT_HEX}, // ID_NR_CODE
};
/**
* List of telegram parameters in order of appearance
*/
private static final int[][] SVC_PARAMETERS =
/* START, LEN, PARAM-TYPE // REMARKS */
/* ------------------------------------------- */
{{0, 2, PT_HEX}, // ID_OBD_SVC
};
/**
* List of telegram parameters in order of appearance
*/
private static final int[][] OBD_PARAMETERS =
/* START, LEN, PARAM-TYPE // REMARKS */
/* ------------------------------------------- */
{{0, 2, PT_HEX}, // ID_OBD_SVC
{2, 2, PT_HEX}, // ID_OBD_PID
};
/**
* List of telegram parameters in order of appearance
*/
private static final int[][] FRZFRM_PARAMETERS =
/* START, LEN, PARAM-TYPE // REMARKS */
/* ------------------------------------------- */
{{0, 2, PT_HEX}, // ID_OBD_SVC
{2, 2, PT_HEX}, // ID_OBD_PID
{2, 2, PT_HEX}, // ID_OBD_FRAMEID
};
private static final int ID_NUM_CODES = 0;
public static final int ID_MSK_CODES = 1;
/**
* List of telegram parameters in order of appearance
*/
private static final int[][] NUMCODE_PARAMETERS =
/* START, LEN, PARAM-TYPE // REMARKS */
/* ------------------------------------------- */
{{4, 2, PT_HEX}, // ID_NUM_CODES
{6, 6, PT_HEX}, // ID_MSK_CODES
};
private static final String[] OBD_DESCRIPTORS =
{
"OBD Service",
"OBD PID",
};
/** new style data items */
public static final EcuDataItems dataItems = new EcuDataItems();
/** OBD data items */
public static PvList PidPvs = new PvList();
/** OBD vehicle identification items */
public static PvList VidPvs = new PvList();
/** current fault codes */
public static PvList tCodes = new PvList();
/** list of known fault codes */
private static final EcuCodeList knownCodes = EcuConversions.codeList;
/** queue of ELM commands to be sent */
static final Vector<String> cmdQueue = new Vector<String>();
/** freeze frame ID to request */
private int freezeFrame_Id = 0;
/** perform reset on NRC reception */
private boolean resetOnNrc = false;
/** Creates a new instance of ObdProt */
ObdProt()
{
paddingChr = '0';
// prepare PID PV list
PidPvs.put(0, new EcuDataPv());
VidPvs.put(0, new EcuDataPv());
tCodes.put(0, new ObdCodeItem(0, "No trouble codes set"));
}
/**
* set Freeze frame id to be requested
* @param freezeFrame_Id ID of freeze frame to be requested
*/
public void setFreezeFrame_Id(int freezeFrame_Id)
{
log.info(String.format("FreezeFrame ID: %d", freezeFrame_Id));
this.freezeFrame_Id = freezeFrame_Id;
setService(OBD_SVC_FREEZEFRAME, true);
}
/**
* list of parameters for specific protocol
* @return complete set of protocol parameters
*/
public int[][] getTelegramParams()
{
return (getTelegramParams(msgService));
}
/**
* list of parameters for specific protocol
* @param service Service which this header is requested for
* @return complete set of protocol parameters
*/
private int[][] getTelegramParams(int service)
{
int fldMap[][];
switch (service)
{
// negative response
case OBD_ID_NRC:
fldMap = NR_PARAMETERS;
break;
case OBD_SVC_FREEZEFRAME:
fldMap = FRZFRM_PARAMETERS;
break;
case OBD_SVC_READ_CODES:
case OBD_SVC_PENDINGCODES:
case OBD_SVC_PERMACODES:
case OBD_SVC_CLEAR_CODES:
fldMap = SVC_PARAMETERS;
break;
default:
fldMap = OBD_PARAMETERS;
}
return (fldMap);
}
/**
* return message footer for protocol payload
* @return buffer of message footer
*/
public char[] getFooter()
{
return (emptyBuffer);
}
/**
* create a new telegram header for selected payload data buffer
* inclunding setting all ID's, sizes and validity issues
* @param buffer buffer of payload data
* @return buffer of new telegram header
*/
protected char[] getNewHeader(char[] buffer)
{
return (getNewHeader(buffer, OBD_SVC_DATA, Integer.valueOf(0)));
}
/**
* create a new telegram header inclunding setting all ID's, sizes and
* validity issues
* @param buffer buffer of payload data
* @param type type of telegram content
* @param id identifier for telegram (may be null)
* @return buffer of new telegram header
*/
@SuppressWarnings("fallthrough")
protected char[] getNewHeader(char[] buffer, int type, Object id)
{
int[][] fldMap = getTelegramParams(type);
char[] header = createEmptyBuffer(fldMap, '0');
setParamValue(ID_OBD_SVC, fldMap, header, Integer.valueOf(type));
switch (type)
{
// these commands do not require parametrs
case OBD_SVC_READ_CODES:
case OBD_SVC_PENDINGCODES:
case OBD_SVC_PERMACODES:
case OBD_SVC_CLEAR_CODES:
break;
// freezeframes require additional frame id
case OBD_SVC_FREEZEFRAME:
setParamValue(ID_OBD_FRAMEID, fldMap, header, freezeFrame_Id);
// NO break here
// all other commands require PID to be set
default:
setParamValue(ID_OBD_PID, fldMap, header, id);
}
return (header);
}
/**
* list of parameter descriptions for specific protocol
* @return complete set of protocol parameter description strings
*/
protected String[] getParamDescriptors()
{
return (OBD_DESCRIPTORS);
}
/**
* prepare process variables for each PID
* @param pvList list of process vars
*/
private void preparePidPvs(int obdService, PvList pvList)
{
// reset fixed PIDs
resetFixedPid();
HashMap<String, EcuDataPv> newList = new HashMap<String, EcuDataPv>();
for (ObdPid currPid : pidSupported)
{
Vector<EcuDataItem> items = dataItems.getPidDataItems(obdService, currPid.intValue());
// if no items defined, create dummy item
if (items == null)
{
log.warning(String.format("unknown PID %02X", currPid.intValue()));
// create new dummy item / OneToOne conversion
Conversion[] dummyCnvs = {EcuConversions.dfltCnv, EcuConversions.dfltCnv};
EcuDataItem newItem = new EcuDataItem(currPid.intValue(), 0, 0, 0, 32, 0xFFFFFFFF, dummyCnvs,
"%#08x", null, null, 0,
String.format("PID %02X", currPid.intValue()),
String.format("PID_%02X", currPid.intValue())
);
dataItems.appendItemToService(obdService, newItem);
// re-load data items for this PID
items = dataItems.getPidDataItems(obdService, currPid.intValue());
}
// loop through all items found ...
for (EcuDataItem pidPv : items)
{
if (pidPv != null)
{
newList.put(pidPv.toString(), pidPv.pv);
}
}
}
pvList.putAll(newList, PvChangeEvent.PV_ADDED, false);
}
/**
* mark all PIDs supported by the vehicle
* @param start Start PID (multiple of 0x20) to process bitmask for
* @param bitmask 32-Bit bitmask which indicates support for the next 32 PIDs
*/
private synchronized void markSupportedPids(int obdService, int start, long bitmask,
PvList pvList)
{
currSupportedPid = 0;
// Clear PID list on initial bitmask (offset 0)
if( start == 0)
{
pidSupported.clear();
}
// loop through bits and mark corresponding PIDs as supported
for (int i = 0; i < 0x1F; i++)
{
if ((bitmask & (0x80000000L >> i)) != 0)
{
pidSupported.add(new ObdPid(i + start + 1));
}
}
log.fine(Long.toHexString(bitmask).toUpperCase()
+ "(" + Long.toHexString(start) + "):"
+ pidSupported);
// if next block may be requested
if ((bitmask & 1) != 0)
{
// request next block
cmdQueue.add(String.format("%02X%02X", obdService, start + 0x20));
}
else
{
// setup PID PVs
preparePidPvs(obdService, pvList);
}
}
/** Holds value of property numCodes. */
private int numCodes;
/** fixed PIDs to limit PID loop to single access */
private static final Vector<ObdPid> fixedPids = new Vector<ObdPid>();
/**
* Set fixed PID for faster data update
* @param pidCodes the fixedPid to set
*/
public static synchronized void setFixedPid(int[] pidCodes)
{
for (ObdPid currPid : pidSupported)
{
if (Arrays.binarySearch(pidCodes, currPid.intValue()) >= 0)
{
fixedPids.add(currPid);
}
}
}
public static synchronized void resetFixedPid()
{
fixedPids.clear();
}
/**
* get the next available supported PID
* @return next available supported PID
*/
synchronized Integer getNextSupportedPid()
{
Integer result = 0;
/* get corresponding PID list */
Vector<ObdPid> pidsToCheck = (fixedPids.size() > 0) ? fixedPids : pidSupported;
try
{
/* sort by next expected request */
Collections.sort(pidsToCheck, ObdPid.requestSorter);
ObdPid pid = pidsToCheck.firstElement();
/* detect wrap around in PID list */
pidsWrapped = pid.getNextRequest() != 0;
/* mark PID as handled */
pid.setNextRequest(System.currentTimeMillis());
/* and return first list element */
result = pid.intValue();
}
catch(Exception e)
{
/* ignore */
}
return result;
}
/**
* handle OBD response telegram
* @param buffer - telegram buffer
* @return number of listeners notified
*/
@Override
@SuppressWarnings("fallthrough")
public synchronized int handleTelegram(char[] buffer)
{
int result = 0;
int msgPid;
if (checkTelegram(buffer))
{
try
{
msgService = (Integer) getParamValue(ID_OBD_SVC, buffer);
// check for negative result
if (msgService == OBD_ID_NRC)
{
// get NR service
int svc = (Integer) getParamValue(ID_NR_SVC, buffer);
// get NRC code
int nrcCode = (Integer) getParamValue(ID_NR_CODE, buffer);
// get NRC object
NRC nrc = NRC.get(nrcCode);
// create NRC error message
String error = nrc.toString(svc);
// log error
log.severe(error);
// notify change listeners
firePropertyChange(new PropertyChangeEvent(this, PROP_NRC, nrc, error));
// handle NRC reaction
switch(nrc.react)
{
case RESET:
if (isResetOnNrc())
{
// perform immediate reset because NRC reception
reset();
} else
{
// otherwise just switch off any active service
setService(OBD_SVC_NONE, true);
}
break;
case CANCEL:
// switch off any active service
setService(OBD_SVC_NONE, true);
break;
case REPEAT:
// Repeat last TX message
sendTelegram(lastTxMsg.toCharArray());
break;
case SKIP:
case IGNORE:
default:
// Intentionally do noting
}
// handling finished
return result;
}
// positive response -> mask service ID
msgService &= ~0x40;
// check service of message
switch (msgService)
{
// OBD Data frame
case OBD_SVC_FREEZEFRAME:
case OBD_SVC_DATA:
msgPid = (Integer) getParamValue(ID_OBD_PID, buffer);
switch (msgPid)
{
case 0x00:
case 0x20:
case 0x40:
case 0x60:
case 0x80:
case 0xA0:
case 0xC0:
case 0xE0:
// Check for optional message count byte, find offset to payload
int offset = (buffer.length % 4 == 0) ? 4 : 6;
// get payload data and mark the indicated supported PIDs
long msgPayload = Long.valueOf(new String(buffer, offset, 8), 16);
markSupportedPids(msgService, msgPid, msgPayload, PidPvs);
break;
// OBD number of fault codes
case 1:
msgPayload = ((Integer) getParamValue(ID_NUM_CODES,
NUMCODE_PARAMETERS,
buffer)).longValue();
setNumCodes(Long.valueOf(msgPayload).intValue());
// no break here ...
default:
long updatePeriod =
dataItems.updateDataItems(msgService,
msgPid,
hexToBytes(String.valueOf(
getPayLoad(buffer))));
/* Update expected request timestamp for PID */
for( ObdPid pid : pidSupported)
{
if(pid.intValue()==msgPid)
{
pid.setNextRequest(System.currentTimeMillis()+updatePeriod);
}
}
break;
}
break;
case OBD_SVC_CTRL_MODE: // Test control mode
case OBD_SVC_VEH_INFO: // get vehicle information (mode 9)
msgPid = (Integer) getParamValue(ID_OBD_PID, buffer);
switch (msgPid)
{
case 0x00:
case 0x20:
case 0x40:
case 0x60:
case 0x80:
case 0xA0:
case 0xC0:
case 0xE0:
// Check for optional message count byte, find offset to payload
int offset = (buffer.length % 4 == 0) ? 4 : 6;
// get payload data and mark the indicated supported PIDs
long msgPayload = Long.valueOf(new String(buffer, offset, 8), 16);
markSupportedPids(msgService, msgPid, msgPayload, VidPvs);
break;
default:
long updatePeriod =
dataItems.updateDataItems(msgService,
msgPid,
hexToBytes(String.valueOf(
getPayLoad(buffer))));
/* Update expected request timestamp for PID */
for( ObdPid pid : pidSupported)
{
if(pid.intValue()==msgPid)
{
pid.setNextRequest(System.currentTimeMillis()+updatePeriod);
}
}
break;
}
break;
// fault code response
case OBD_SVC_READ_CODES:
case OBD_SVC_PENDINGCODES:
case OBD_SVC_PERMACODES:
int currCode;
Integer key;
EcuCodeItem code;
int nCodes = 0;
// default DTC data to start at offset 2 (Byte 1)
int DTCOffs = 2;
// If message contains optional number of codes (1 Byte) then set it ...
boolean hasNumCodes = ((buffer.length % 4) == 0);
if (hasNumCodes)
{
nCodes = Integer.valueOf(new String(buffer, 2, 2), 16);
setNumCodes(nCodes);
// DTC data starts at offset 4 (byte 2)
DTCOffs = 4;
}
// read in all trouble codes
for (int i = DTCOffs; i < buffer.length; i += 4)
{
key = Integer.valueOf(new String(buffer, i, 4), 16);
currCode = key.intValue();
if (currCode != 0)
{
if ((code = knownCodes.get(key)) == null)
{
code = new ObdCodeItem(key.intValue(),
Messages.getString(
"customer.specific.trouble.code.see.manual"));
}
log.fine(String.format("+DFC: %04x: %s", key, code.toString()));
// Remember received message service to know code status
code.put(EcuCodeItem.FID_STATUS, Integer.valueOf(msgService));
tCodes.put(key, code);
// if number of codes hasn't been delivered yet ...
if(!hasNumCodes)
{
// increment number of detected codes
nCodes++;
}
}
}
if (nCodes == 0)
{
tCodes.put(0, new ObdCodeItem(0, Messages.getString(
"no.trouble.codes.set")));
}
break;
// clear code response
case OBD_SVC_CLEAR_CODES:
break;
default:
log.warning("Service not (yet) supported: " + msgService);
}
} catch (Exception e)
{
log.warning("'" + Arrays.toString(buffer) + "':" + e.getMessage());
}
}
return (result);
}
/**
* Notify all telegram Writers about new telegram
* @param buffer - telegram buffer
*/
@Override
public void sendTelegram(char[] buffer)
{
// remember last sent message
lastTxMsg = new String(buffer);
super.sendTelegram(buffer);
}
/**
* Getter for property numCodes.
* @return Value of property numCodes.
*/
public int getNumCodes()
{
return this.numCodes;
}
/**
* Setter for property numCodes.
* @param numCodes New value of property numCodes.
*/
private void setNumCodes(int numCodes)
{
int old = this.numCodes;
this.numCodes = numCodes;
firePropertyChange(new PropertyChangeEvent(this,
PROP_NUM_CODES,
Integer.valueOf(old),
Integer.valueOf(numCodes)));
}
/**
* Getter for property service.
* @return Value of property service.
*/
public int getService()
{
return this.service;
}
/**
* reset all protocol settings
*/
public void reset()
{
// switch off any active service
setService(OBD_SVC_NONE, true);
// clear command queue
cmdQueue.clear();
// clear supported PIDs
pidSupported.clear();
// reset fixed PIDs
resetFixedPid();
// Clear data items
PidPvs.clear();
tCodes.clear();
VidPvs.clear();
}
/**
* clear data lists for selected service
* @param obdService OBD service to clear lists for
*/
private void clearDataLists(int obdService)
{
// clean up data lists
switch (obdService)
{
case OBD_SVC_DATA:
case OBD_SVC_FREEZEFRAME:
// Clear data items
pidSupported.clear();
PidPvs.clear();
break;
case OBD_SVC_READ_CODES:
case OBD_SVC_PENDINGCODES:
case OBD_SVC_PERMACODES:
tCodes.clear();
break;
case OBD_SVC_VEH_INFO:
case OBD_SVC_CTRL_MODE:
// Clear data items
pidSupported.clear();
VidPvs.clear();
break;
}
}
/**
* Setter for property service.
* This includes initialisation of the requested service to the vehicle
* @param obdService New OBD service to be requested.
* @param clearLists clear data list for this service
*/
public void setService(int obdService, boolean clearLists)
{
this.service = obdService;
pidsWrapped = false;
// if lists shall be cleared
if (clearLists)
{
// then do it
clearDataLists(obdService);
}
// set specified OBD service
switch (obdService)
{
case OBD_SVC_NONE:
// sendCommand(CMD_RESET,0);
break;
case OBD_SVC_DATA:
case OBD_SVC_FREEZEFRAME:
case OBD_SVC_CTRL_MODE:
case OBD_SVC_VEH_INFO:
// read vehicle information
// request for PID/TID's supported
writeTelegram(emptyBuffer, obdService, 0);
break;
case OBD_SVC_READ_CODES:
case OBD_SVC_PENDINGCODES:
case OBD_SVC_PERMACODES:
numCodes = 0;
// Queue requests for reading all trouble codes
cmdQueue.add(String.format("%02X", OBD_SVC_READ_CODES, 0));
cmdQueue.add(String.format("%02X", OBD_SVC_PENDINGCODES, 0));
cmdQueue.add(String.format("%02X", OBD_SVC_PERMACODES, 0));
// read PID number of codes ...
writeTelegram(emptyBuffer, OBD_SVC_DATA, 1);
break;
case OBD_SVC_CLEAR_CODES:
// clear trouble codes
writeTelegram(emptyBuffer, obdService, 0);
// wait for codes to be cleared
try
{
Thread.sleep(500);
} catch (InterruptedException e)
{
// Intentionally do nothing
}
break;
case OBD_SVC_O2_RESULT:
case OBD_SVC_MON_RESULT:
default:
log.warning("Service not supported: " + obdService);
}
}
}