use of com.fr3ts0n.ecu.VagConversion in project AndrOBD by fr3ts0n.
the class Kw1281Prot method handleTelegram.
/**
* handle incoming protocol telegram
* default implementaion only checks telegram and notifies listeners with
* protocol payload
*
* @param buffer - telegram buffer
* @return number of listeners notified
*/
@Override
public int handleTelegram(char[] buffer) {
int cnt = 0;
log.fine("RX:" + ProtUtils.hexDumpBuffer(buffer));
// if telegram is OK
if (checkTelegram(buffer)) {
// get command
int cmd = getParamInt(FLD_ID_CMD, buffer);
// update block counter
blockCounter = (char) getParamInt(FLD_ID_BLKCNT, buffer).intValue();
// get payload
char[] payLoad = getPayLoad(buffer);
switch(cmd) {
case ID_GRPINFO_HEAD:
// field number within group
int fldId = 0;
// loop through all data items within telegram
for (int i = 0; i < payLoad.length; ) {
// get data id from group reading
int dId = (int) payLoad[i];
// get the corresponding data items for svc/pid
Vector<EcuDataItem> pidItems = itms.getPidDataItems(ID_GRPINFO_DATA, dId);
// if item was found ...
if (pidItems != null && pidItems.size() > 0) {
EcuDataItem currItm;
// if item already exists
if (currGrpItems.size() > fldId) {
// re-use existing item
currItm = currGrpItems.get(fldId);
} else {
// otherwise clone a new one
currItm = (EcuDataItem) pidItems.get(0).clone();
// set specific values for this item
currItm.pid = (int) getCurrDataGroup();
currItm.ofs += fldId;
currItm.pv.put(EcuDataPv.FID_PID, Integer.valueOf(currItm.pid));
currItm.pv.put(EcuDataPv.FID_OFS, Integer.valueOf(currItm.ofs));
// ensure there are enough elements in list
while (currGrpItems.size() <= fldId) currGrpItems.add(null);
// add item to list of group data items
currGrpItems.set(fldId, currItm);
}
// update metadata
int numTblChrs = payLoad[i + 2];
// if conversion is a VagConversion, we may adjust meta parameters
if (currItm.cnv[0] instanceof VagConversion) {
// set meta parameter for conversion
((VagConversion) currItm.cnv[0]).setMetaNw(payLoad[i + 1]);
// any following table data available?
if (numTblChrs != 0) {
// set table values for conversion
((VagConversion) currItm.cnv[0]).setMetaTblValues(String.valueOf(payLoad, i + 3, numTblChrs).toCharArray());
}
}
// increment byte index to next entry
i += 3 + numTblChrs;
// increment field number
fldId++;
}
}
showGroupItems(getCurrDataGroup());
// now request again to get real data
requestGroupData(getCurrDataGroup());
break;
case ID_GRPINFO_DATA:
if (currGrpItems == null || currGrpItems.size() < BLK_NUM_ITEMS) {
log.severe(String.format("Missing/Incomplete Metadata for GRP:%d", (int) getCurrDataGroup()));
}
{
for (int i = 0; i < Math.min(payLoad.length, currGrpItems.size()); i++) {
EcuDataItem currItm = currGrpItems.get(i);
if (currItm != null) {
// and update corresponding process var
currItm.updatePvFomBuffer(payLoad);
} else {
log.severe(String.format("Data w/o meta GRP:%d, ITM:%d", (int) getCurrDataGroup(), i));
}
}
}
// if we do group reading and desired group has not changed ...
if (service == SVC_READ_DATA_GRP && getCurrDataGroup() == getSelectedDataGroup()) {
// request same group again
requestGroupData(getCurrDataGroup());
} else {
// otherwise close this group by requesting ACK
requestACK();
}
break;
case ID_GRPREAD_DATA:
// loop through all 4 entries of group
for (int i = 0; i < payLoad.length; i += 3) {
// get data it from group reading
int dId = (int) payLoad[i];
// get the corresponding data items for svc/pid
Vector<EcuDataItem> pidItems = itms.getPidDataItems(cmd, dId);
// if item was found ...
if (pidItems != null) {
// loop through all data items for this dId
Iterator<EcuDataItem> it = pidItems.iterator();
while (it.hasNext()) {
EcuDataItem currItm = (EcuDataItem) it.next().clone();
// set specific values for this item
currItm.pid = (int) getCurrDataGroup();
currItm.ofs += i / 3;
currItm.pv.put(EcuDataPv.FID_PID, Integer.valueOf(currItm.pid));
currItm.pv.put(EcuDataPv.FID_OFS, Integer.valueOf(currItm.ofs));
// ensure there are enough elements in list
while (currGrpItems.size() < (i / 3)) currGrpItems.add(null);
// add item to list of group data items
currGrpItems.set(i / 3, currItm);
// and update corresponding process var
currItm.updatePvFomBuffer(Arrays.copyOfRange(payLoad, i + 1, i + 3));
}
} else {
log.warning("Unknown data ID:" + dId);
}
}
// if we do group reading and desired group has not changed ...
if (service == SVC_READ_DATA_GRP && getCurrDataGroup() == getSelectedDataGroup()) {
// request same group again
requestGroupData(getCurrDataGroup());
} else {
// otherwise close this group by requesting ACK
requestACK();
}
break;
case CMD_ACK:
switch(service) {
case SVC_READ_DATA_ALL:
// request next available data group
requestGroupData(getNextDataGroup());
break;
case SVC_READ_DATA_GRP:
// ensure new selection of group is updated
setCurrDataGroup(getSelectedDataGroup());
// request same group again
requestGroupData(getCurrDataGroup());
break;
case SVC_READ_DFCS:
// clear fault code list
tCodes.clear();
setNumCodes(0);
// request failure codes
requestDFCs();
break;
case SVC_CLEAR_DFCS:
// Request clearing DFCs ...
requestClearDFCs();
// ... and continue with Reading DFCc
setService(SVC_READ_DFCS);
break;
case SVC_SHUTDOWN:
requestEndComm();
// now set to Service NONE
setService(SVC_FINISHED);
break;
case SVC_NONE:
default:
requestACK();
break;
}
break;
case ID_NODATA:
log.info(String.format("NODATA: Group:%d -> remove", (int) getCurrDataGroup()));
// since data is not available, remove group from map ...
knownGrpItems.remove(Integer.valueOf(getCurrDataGroup()));
// if we finished the initial turaround, save preset data
if (currDataGroup == 0) {
savePreset();
}
// request ACK
requestACK();
break;
case ID_DFC_DATA:
int nCodes = numCodes;
// loop through all codes reported
for (int i = 0; i < payLoad.length; i += 3) {
// get code number and status
int dfcNum = getParamInt(i, 2, payLoad);
int dfcStat = getParamInt(i + 2, 1, payLoad);
// enter code into code list for visualisation
EcuCodeItem code = knownCodes.get(dfcNum);
// if code is not known ...
if (code == null) {
// create new one and add it to list of known codes
code = new EcuCodeItem(dfcNum, "Unknown Fault code");
}
code.put(EcuCodeItem.FID_STATUS, Integer.valueOf(dfcStat));
tCodes.put(dfcNum, code);
if (dfcNum != 0xFFFF) {
nCodes++;
// set the MIL status based on code status
nCodes |= dfcStat & 0x80;
}
}
// set number of codes
setNumCodes(nCodes);
// finish service since we received corresponding answer
setService(SVC_NONE);
// further DFCs may still come after ACK ...
requestACK();
break;
case ID_ASCII_DATA:
// save vehicle ID data
EcuDataPv pv = new EcuDataPv();
pv.put(EcuDataPv.FID_DESCRIPT, "ID");
pv.put(EcuDataPv.FID_VALUE, String.valueOf(payLoad));
VidPvs.put(VidPvs.size(), pv);
// if this is the first VID dataset, try to load corresponding preset
if (VidPvs.size() == 1)
loadPreset();
// send ACK
requestACK();
break;
default:
requestACK();
break;
}
cnt++;
}
return (cnt);
}
Aggregations