Search in sources :

Example 1 with VagConversion

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);
}
Also used : VagConversion(com.fr3ts0n.ecu.VagConversion) EcuDataPv(com.fr3ts0n.ecu.EcuDataPv) EcuCodeItem(com.fr3ts0n.ecu.EcuCodeItem) EcuDataItem(com.fr3ts0n.ecu.EcuDataItem)

Aggregations

EcuCodeItem (com.fr3ts0n.ecu.EcuCodeItem)1 EcuDataItem (com.fr3ts0n.ecu.EcuDataItem)1 EcuDataPv (com.fr3ts0n.ecu.EcuDataPv)1 VagConversion (com.fr3ts0n.ecu.VagConversion)1