示例#1
0
        private OBDParameterValue GetJ1939Value(OBDParameter param, OBDResponse response)
        {
            OBDParameterValue value2 = new OBDParameterValue();

            if (response.Header.Substring(2, 2) == "E8")
            {
                // J1939的确认消息,非正确的返回值
                value2.ErrorDetected = true;
                return(value2);
            }
            switch (param.Parameter)
            {
            case 0xFECE:
                value2 = GetDM5Value(param, response);
                break;

            case 0xD300:
                value2 = GetDM19Value(param, response);
                break;

            case 0xFEEC:
                // VIN
                value2.ListStringValue = SetMode09ASCII(17 * 2, response);
                break;
            }
            return(value2);
        }
示例#2
0
        protected int GetDataStartIndex(int headLen, OBDParameter param, bool bIsMultiline)
        {
            int iRet;

            switch (param.Service)
            {
            case 1:
                iRet = headLen + 4;
                break;

            case 2:
                iRet = headLen + 6;
                break;

            case 3:
            case 4:
            case 7:
            case 0x0A:
                iRet = headLen + 2;
                break;

            case 5:
                iRet = headLen + 6;
                break;

            case 9:
                return(param.Parameter % 2 == 0 ? headLen + 6 : headLen + 4);

            default:
                iRet = headLen + 4;
                break;
            }
            return(bIsMultiline ? iRet + 2 : iRet);
        }
示例#3
0
        public OBDParameter GetFreezeFrameCopy(int iFrame)
        {
            OBDParameter copy = GetCopy();

            copy.Service    = 2;
            copy.OBDRequest = "02" + copy.OBDRequest.Substring(2, 2) + iFrame.ToString("D2");
            return(copy);
        }
示例#4
0
        /// <summary>
        /// 返回符合标准协议规定的K线/J1850帧
        /// </summary>
        /// <param name="param"></param>
        /// <param name="tempLines"></param>
        /// <param name="headLen"></param>
        /// <returns></returns>
        protected override List <string> GetLegalLines(OBDParameter param, List <string> tempLines, int headLen)
        {
            List <string> lines = new List <string>();
            // dicFrameType表示找到的正响应的PDU帧类型,key: ECU ID,value: 多帧计数
            // value值,-1:未确认类型,0:单帧,1~7:多帧计数
            Dictionary <string, int> dicFrameType = new Dictionary <string, int>();

            string positiveResponse = (param.Service + 0x40).ToString("X2") + param.OBDRequest.Substring(2);
            string negativeResponse = "7F" + param.OBDRequest.Substring(0, 2);

            for (int i = 0; i < tempLines.Count; i++)
            {
                if (tempLines[i].Length < headLen)
                {
                    continue;
                }
                string ECU_ID = tempLines[i].Substring(2, headLen - 2);
                if (!dicFrameType.Keys.Contains(ECU_ID))
                {
                    dicFrameType.Add(ECU_ID, -1);
                }

                if (tempLines[i].Contains(negativeResponse))
                {
                    // 响应本命令的负反馈,可能有多个
                    lines.Add(tempLines[i]);
                }
                else if (tempLines[i].Contains(positiveResponse))
                {
                    // 响应本命令的正反馈,每个ECU只会有一个
                    int pos = tempLines[i].IndexOf(positiveResponse);
                    try {
                        int iCount = Convert.ToInt32(tempLines[i].Substring(pos + positiveResponse.Length, 2), 16);
                        if (pos == headLen)
                        {
                            if (dicFrameType[ECU_ID] + 1 == iCount)
                            {
                                dicFrameType[ECU_ID] = iCount;
                                lines.Add(tempLines[i]);
                            }
                            else if (dicFrameType[ECU_ID] == -1)
                            {
                                dicFrameType[ECU_ID] = iCount;
                                lines.Add(tempLines[i]);
                            }
                        }
                        else
                        {
                            dicFrameType[ECU_ID] = -1;
                        }
                    } catch (Exception) {
                        dicFrameType[ECU_ID] = -1;
                    }
                }
            }
            return(lines);
        }
示例#5
0
        public OBDParameter GetCopy()
        {
            OBDParameter p = new OBDParameter {
                ValueTypes  = ValueTypes,
                _OBDRequest = OBDRequest,
                _parameter  = Parameter,
                Service     = Service,
                SignalName  = SignalName,
            };

            return(p);
        }
示例#6
0
        public OBDResponseList GetResponseList(OBDParameter param)
        {
            OBDResponseList responses = _obdDevice.Query(param);
            string          strItem   = "Responses: ";

            for (int i = 0; i < responses.ResponseCount; i++)
            {
                strItem += string.Format("[{0}] ", Utility.GetReadableHexString(0, responses.GetOBDResponse(i).Data));
            }
            strItem = strItem.TrimEnd();
            _log.TraceInfo(strItem);
            return(responses);
        }
示例#7
0
        private OBDParameterValue GetDM19Value(OBDParameter param, OBDResponse response)
        {
            OBDParameterValue value2 = new OBDParameterValue();

            if (response.GetDataByteCount() < 20)
            {
                value2.ErrorDetected = true;
                return(value2);
            }

            int    qty             = response.Data.Length / (20 * 2);
            string strData         = "";
            int    OriginalParam   = param.Parameter;
            int    OriginalService = param.Service;

            param.Service = 9;
            switch (param.SignalName)
            {
            case "CVN":
                param.Parameter = 0x06;
                for (int i = 0; i < qty; i++)
                {
                    strData += response.Data.Substring(i * 20 * 2, 4 * 2);
                }
                response.Data = strData;
                value2        = GetMode010209Value(param, response);
                for (int i = 0; i < value2.ListStringValue.Count; i++)
                {
                    string strVal = value2.ListStringValue[i];
                    value2.ListStringValue[i] = strVal.Substring(6, 2) + strVal.Substring(4, 2) + strVal.Substring(2, 2) + strVal.Substring(0, 2);
                }
                break;

            case "CAL_ID":
                param.Parameter = 0x04;
                for (int i = 0; i < qty; i++)
                {
                    strData += response.Data.Substring(4 * 2 + i * 20 * 2, 16 * 2);
                }
                response.Data = strData;
                value2        = GetMode010209Value(param, response);
                break;

            default:
                value2.ErrorDetected = true;
                break;
            }
            param.Parameter = OriginalParam;
            param.Service   = OriginalService;
            return(value2);
        }
示例#8
0
        private OBDParameterValue GetDM5Value(OBDParameter param, OBDResponse response)
        {
            OBDParameterValue value2 = new OBDParameterValue();

            if (response.GetDataByteCount() < 8)
            {
                value2.ErrorDetected = true;
                return(value2);
            }

            switch (param.SignalName)
            {
            case "":
            case "OBDSUP":
                // OBD型式
                response.Data = response.GetDataByte(2);
                value2        = GetPIDValue(0x11C, response.Data, param.SignalName);
                break;

            case "ACT_DTC_CNT":
                // 激活的故障代码,未实现解析功能
                response.Data = response.GetDataByte(0);
                break;

            case "PRE_DTC_CNT":
                // 先前激活的诊断故障代码,未实现解析功能
                response.Data = response.GetDataByte(1);
                break;

            case "CON_MON":
                // 持续监视系统支持/状态,未实现解析功能
                response.Data = response.GetDataByte(3);
                break;

            case "NON_SUP":
                // 非持续监视系统支持,未实现解析功能
                response.Data = response.GetDataByte(4) + response.GetDataByte(5);
                break;

            case "NON_STAT":
                // 非持续监视系统状态,未实现解析功能
                response.Data = response.GetDataByte(6) + response.GetDataByte(7);
                break;

            default:
                value2.ErrorDetected = true;
                break;
            }
            return(value2);
        }
示例#9
0
        private string GetLogString(OBDParameter param, OBDParameterValue obdValue)
        {
            string strRet = "Values: ";

            if ((param.ValueTypes & (int)OBDParameter.EnumValueTypes.Double) == (int)OBDParameter.EnumValueTypes.Double)
            {
                strRet += string.Format("[ECU: {1}, Double: {0}] ", obdValue.DoubleValue.ToString(), obdValue.ECUResponseID);
            }
            if ((param.ValueTypes & (int)OBDParameter.EnumValueTypes.Bool) == (int)OBDParameter.EnumValueTypes.Bool)
            {
                strRet += string.Format("[ECU: {1}, Bool: {0}] ", obdValue.BoolValue.ToString(), obdValue.ECUResponseID);
            }
            if ((param.ValueTypes & (int)OBDParameter.EnumValueTypes.String) == (int)OBDParameter.EnumValueTypes.String)
            {
                strRet += string.Format("[ECU: {1}, String: {0}] ", obdValue.StringValue, obdValue.ECUResponseID);
            }
            if ((param.ValueTypes & (int)OBDParameter.EnumValueTypes.ListString) == (int)OBDParameter.EnumValueTypes.ListString)
            {
                strRet += string.Format("[ECU: {0}, ListString: ", obdValue.ECUResponseID);
                if (obdValue.ListStringValue != null && obdValue.ListStringValue.Count > 0)
                {
                    foreach (string strx in obdValue.ListStringValue)
                    {
                        strRet = string.Concat(strRet, strx + ", ");
                    }
                    strRet = strRet.Substring(0, strRet.Length - 2);
                }
                strRet += "]";
            }
            if ((param.ValueTypes & (int)OBDParameter.EnumValueTypes.ShortString) == (int)OBDParameter.EnumValueTypes.ShortString)
            {
                strRet += string.Format("[ECU: {1}, ShortString: {0}] ", obdValue.ShortStringValue, obdValue.ECUResponseID);
            }
            if ((param.ValueTypes & (int)OBDParameter.EnumValueTypes.BitFlags) == (int)OBDParameter.EnumValueTypes.BitFlags)
            {
                strRet += string.Format("[ECU: {0}, BitFlags: ", obdValue.ECUResponseID);
                for (int idx = 0; idx < 32; idx++)
                {
                    strRet += (obdValue.GetBitFlag(idx) ? "1" : "0");
                    if (idx % 8 == 7)
                    {
                        strRet += " ";
                    }
                }
                strRet = strRet.TrimEnd() + "]";
            }
            strRet = strRet.TrimEnd();
            return(strRet);
        }
示例#10
0
        public OBDParameterValue GetMode010209Value(OBDParameter param, OBDResponse response)
        {
            OBDParameterValue value2;

            if (param.Parameter % 0x20 == 0)
            {
                value2 = GetPIDSupport(response);
            }
            else
            {
                uint ID = (uint)((param.Service == 2 ? param.Service - 1 : param.Service << 8) + param.Parameter);
                value2 = GetPIDValue(ID, response.Data, param.SignalName);
            }
            return(value2);
        }
示例#11
0
        public List <OBDParameterValue> GetValueList(OBDParameter param)
        {
            List <OBDParameterValue> ValueList = new List <OBDParameterValue>();

            _log.TraceInfo("Requesting: " + param.OBDRequest);
            OBDResponseList responses = _obdDevice.Query(param);
            string          strItem   = "Responses: ";

            if (responses.ErrorDetected)
            {
                strItem += "Error Detected!";
                OBDParameterValue value = new OBDParameterValue {
                    ErrorDetected    = true,
                    StringValue      = "Error Detected in OBDResponseList!",
                    ShortStringValue = "ERROR_RESP"
                };
                ValueList.Add(value);
                _log.TraceInfo(strItem);
                return(ValueList);
            }
            else
            {
                for (int i = 0; i < responses.ResponseCount; i++)
                {
                    strItem += string.Format("[{0}] ", Utility.GetReadableHexString(0, responses.GetOBDResponse(i).Data));
                }
                strItem = strItem.TrimEnd();
                _log.TraceInfo(strItem);
            }

            for (int i = 0; i < responses.ResponseCount; i++)
            {
                OBDParameterValue obdValue = _obdInterpreter.GetValue(param, responses.GetOBDResponse(i));
                if (obdValue.ErrorDetected)
                {
                    _log.TraceError(string.Format("Values: [ECU: {0}, Error Detected!]", obdValue.ECUResponseID));
                }
                else
                {
                    _log.TraceInfo(GetLogString(param, obdValue));
                }
                ValueList.Add(obdValue);
            }
            return(ValueList);
        }
示例#12
0
 protected abstract List <string> GetLegalLines(OBDParameter param, List <string> tempLines, int headLen);
示例#13
0
 public abstract OBDResponseList Parse(OBDParameter param, string response);
示例#14
0
        public override OBDResponseList Query(OBDParameter param)
        {
            OBDResponseList orl = _Parser.Parse(param, GetOBDResponse(param.OBDRequest));
            int             errorQty;

            for (errorQty = 0; errorQty < 2; errorQty++)
            {
                if (!orl.ErrorDetected)
                {
                    break;
                }
                if (Online)
                {
                    Thread.Sleep(500);
                }
                orl = _Parser.Parse(param, GetOBDResponse(param.OBDRequest));
            }
            // 重试3次后还是出错的话,软重启ELM327后再重试3次
            if (errorQty >= 2)
            {
                ConfirmAT("ATWS");
                InitELM327Format();
                ConfirmAT("ATSP" + ((int)_iProtocol).ToString("X1"));
                for (errorQty = 0; errorQty < 3; errorQty++)
                {
                    if (!orl.ErrorDetected)
                    {
                        break;
                    }
                    if (Online && errorQty != 0)
                    {
                        Thread.Sleep(500);
                    }
                    orl = _Parser.Parse(param, GetOBDResponse(param.OBDRequest));
                }
            }
            if (orl.RawResponse == "PENDING")
            {
                int waittingTime = 60; // 重试总时间,单位秒
                int interval     = 6;  // 重试间隔时间,单位秒
                // NRC=78 处理
                _log.TraceWarning("Receive only NRC78, handle pending message");
                switch (_iProtocol)
                {
                case ProtocolType.J1850_PWM:
                case ProtocolType.J1850_VPW:
                    // 间隔30秒重复发送一次请求,直到有正响应消息返回
                    interval = 30;
                    for (int i = waittingTime / interval; i > 0; i--)
                    {
                        Thread.Sleep(interval * 1000);
                        orl = _Parser.Parse(param, GetOBDResponse(param.OBDRequest));
                        if (!(orl.RawResponse == "PENDING" || orl.ErrorDetected))
                        {
                            break;
                        }
                    }
                    break;

                case ProtocolType.ISO9141_2:
                    // 间隔4秒重复发送一次请求,直到有正响应消息返回
                    interval = 4;
                    for (int i = waittingTime / interval; i > 0; i--)
                    {
                        Thread.Sleep(interval * 1000);
                        orl = _Parser.Parse(param, GetOBDResponse(param.OBDRequest));
                        if (!(orl.RawResponse == "PENDING" || orl.ErrorDetected))
                        {
                            break;
                        }
                    }
                    break;

                default:
                    // ISO14230-4 会在50ms内发送NRC78负响应直到发送正响应,v2.1以下的ELM327一般可收到所需要的消息,只需要过滤NRC78的负响应即可
                    // ISO15765-4 会在5s内发送NRC78负响应直到发送正响应,v2.1以下的ELM327无法收到所需要的消息,需要上层应用自己处理
                    // 间隔6s(5s加上传输延时)检测一次是否有正响应消息返回,如果没有则继续
                    for (int i = waittingTime / interval; i > 0; i--)
                    {
                        Thread.Sleep(interval * 1000);
                        string RxLine = _CommELM.GetRxLine();
                        if (RxLine != null && RxLine.Length > 0)
                        {
                            _log.TraceInfo("RX: " + RxLine.Replace("\r", "\\r"));
                            orl = _Parser.Parse(param, RxLine);
                            if (!(orl.RawResponse == "PENDING" || orl.ErrorDetected))
                            {
                                break;
                            }
                        }
                    }
                    break;
                }
            }
            return(orl);
        }
示例#15
0
        public OBDParameterValue GetValue(OBDParameter param, OBDResponse response)
        {
            OBDParameterValue value2 = new OBDParameterValue();

            if (response == null)
            {
                value2.ErrorDetected = true;
                return(value2);
            }
            switch (param.Service)
            {
            case 0:
                // SAE J1939
                value2 = GetJ1939Value(param, response);
                break;

            case 1:
            case 2:
                value2 = GetMode010209Value(param, response);
                break;

            case 3:
            case 7:
            case 0x0A:
                value2 = GetMode03070AValue(response);
                break;

            case 9:
                value2 = GetMode010209Value(param, response);
                break;

            case 0x19:
                // ISO 27145 ReadDTCInformation
                string reportType = param.OBDRequest.Substring(2, 2);
                if (reportType == "42")
                {
                    value2 = Get42DTCValue(response);
                }
                else if (reportType == "55")
                {
                    value2 = Get55DTCValue(response);
                }
                break;

            case 0x22:
                // ISO 27145 ReadDataByIdentifer
                int HByte           = (param.Parameter >> 8) & 0xFF;
                int LByte           = param.Parameter & 0x00FF;
                int OriginalParam   = param.Parameter;
                int OriginalService = param.Service;
                param.Parameter = LByte;
                if (HByte == 0xF4)
                {
                    param.Service = 1;
                    value2        = GetMode010209Value(param, response);
                }
                else if (HByte == 0xF8)
                {
                    param.Service = 9;
                    value2        = GetMode010209Value(param, response);
                }
                param.Parameter = OriginalParam;
                param.Service   = OriginalService;
                break;

            default:
                value2.ErrorDetected = true;
                break;
            }
            value2.ECUResponseID = response.Header;
            if (value2.ECUResponseID.Length == 6)
            {
                // 如果是K线协议的话ECUResponseID取最后2个字节
                value2.ECUResponseID = value2.ECUResponseID.Substring(2);
            }
            else if (value2.ECUResponseID.Length == 8 && param.Service == 0)
            {
                // 如果是J1939协议的话ECUResponseID取最后1个字节
                value2.ECUResponseID = value2.ECUResponseID.Substring(6);
            }
            return(value2);
        }
示例#16
0
 public override OBDResponseList Parse(OBDParameter param, string response)
 {
     return(Parse(param, response, HEADER_LENGTH));
 }
示例#17
0
 public abstract OBDResponseList Query(OBDParameter param);
示例#18
0
        public OBDResponseList Parse(OBDParameter param, string response, int headLen)
        {
            if (string.IsNullOrEmpty(response))
            {
                response = "";
            }

            OBDResponseList responseList = new OBDResponseList(response);

            response = Strip(response);
            response = ErrorFilter(response);
            if (ErrorCheck(response))
            {
                responseList.ErrorDetected = true;
                return(responseList);
            }

            List <string> legalLines = SplitByCR(response);

            legalLines = GetLegalLines(param, legalLines, headLen);
            List <string> lines = new List <string>();

            foreach (string item in legalLines)
            {
                if (item.Length > 0 && item.Length < headLen)
                {
                    // 过滤数据帧总长小于帧头长度的错误数据
                    continue;
                }
                string strNRC = GetNRC(item, headLen);
                if (strNRC.Length == 0)
                {
                    lines.Add(item);
                }
                else if (strNRC == "78")
                {
                    responseList.Pending = true;
                }
            }
            if (lines.Count == 0)
            {
                if (responseList.Pending)
                {
                    responseList.RawResponse = "PENDING";
                    return(responseList);
                }
                else
                {
                    responseList.ErrorDetected = true;
                    return(responseList);
                }
            }

            lines.Sort();
            List <List <string> > groups = new List <List <string> >();
            List <string>         group  = new List <string> {
                lines[0]
            };

            groups.Add(group);
            if (lines[0].Length < headLen)
            {
                responseList.ErrorDetected = true;
                return(responseList);
            }

            string header = lines[0].Substring(0, headLen);

            for (int i = 1; i < lines.Count; i++)
            {
                if (lines[i].Length >= headLen)
                {
                    if (lines[i].Substring(0, headLen).CompareTo(header) == 0)
                    {
                        group.Add(lines[i]);
                    }
                    else
                    {
                        group = new List <string> {
                            lines[i]
                        };
                        groups.Add(group);
                        header = lines[i].Substring(0, headLen);
                    }
                }
                else
                {
                    responseList.ErrorDetected = true;
                    return(responseList);
                }
            }
            for (int i = 0; i < groups.Count; i++)
            {
                OBDResponse obd_response = new OBDResponse();
                bool        bIsMultiline = false;
                if (groups[i].Count > 1)
                {
                    bIsMultiline = true;
                }
                int dataStartIndex = GetDataStartIndex(headLen, param, bIsMultiline);
                int length1        = groups[i][0].Length - dataStartIndex - 2;
                obd_response.Header = groups[i][0].Substring(0, headLen);
                obd_response.Data   = length1 > 0 ? groups[i][0].Substring(dataStartIndex, length1) : "";
                for (int j = 1; j < groups[i].Count; j++)
                {
                    int length2 = groups[i][j].Length - dataStartIndex - 2;
                    obd_response.Data += (length2 > 0 ? groups[i][j].Substring(dataStartIndex, length2) : "");
                }
                responseList.AddOBDResponse(obd_response);
            }
            return(responseList);
        }
示例#19
0
        private bool GetSupportStatus(int mode, Dictionary <string, bool[]> supportStatus)
        {
            supportStatus.Clear();
            OBDParameter param = new OBDParameter();
            int          HByte = 0;

            if (_OBDIf.STDType == StandardType.ISO_27145)
            {
                HByte = (mode << 8) & 0xFF00;
                param = new OBDParameter(0x22, HByte, "", 32);
            }
            else if (_OBDIf.STDType == StandardType.ISO_15031)
            {
                param = new OBDParameter(mode, 0, "", 32);
            }
            else if (_OBDIf.STDType == StandardType.SAE_J1939)
            {
                param = new OBDParameter(0, mode, "", 0);
                List <OBDParameterValue> valueList = _OBDIf.GetValueList(param);
                foreach (OBDParameterValue value in valueList)
                {
                    if (value.ErrorDetected)
                    {
                        return(false);
                    }
                    supportStatus.Add(value.ECUResponseID, null);
                }
                return(true);
            }

            for (int i = 0; (i * 0x20) < MAX_PID; i++)
            {
                param.Parameter = HByte + i * 0x20;
                List <OBDParameterValue> valueList = _OBDIf.GetValueList(param);
                bool next = false;
                foreach (OBDParameterValue value in valueList)
                {
                    if (value.ErrorDetected)
                    {
                        return(false);
                    }
                    if (!supportStatus.ContainsKey(value.ECUResponseID))
                    {
                        bool[] bitFlag = new bool[MAX_PID];
                        supportStatus.Add(value.ECUResponseID, bitFlag);
                    }

                    foreach (string key in supportStatus.Keys)
                    {
                        if (value.ECUResponseID == key)
                        {
                            for (int j = 0; j < 0x20; j++)
                            {
                                supportStatus[key][j + i * 0x20] = value.GetBitFlag(j);
                            }
                        }
                    }
                    next = next || value.GetBitFlag(31);
                }
                if (!next)
                {
                    break;
                }
            }

            foreach (string key in supportStatus.Keys)
            {
                string log = "";
                if (_OBDIf.STDType == StandardType.ISO_27145)
                {
                    log = "DID " + mode.ToString("X2") + " Support: [" + key + "], [";
                }
                else if (_OBDIf.STDType == StandardType.ISO_15031)
                {
                    log = "Mode" + mode.ToString("X2") + " Support: [" + key + "], [";
                }
                for (int i = 0; i * 8 < MAX_PID; i++)
                {
                    for (int j = 0; j < 8; j++)
                    {
                        log += supportStatus[key][i * 8 + j] ? "1" : "0";
                    }
                    log += " ";
                }
                log  = log.TrimEnd();
                log += "]";
                _log.TraceInfo(log);
            }
            return(true);
        }