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); }
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); }
public OBDParameter GetFreezeFrameCopy(int iFrame) { OBDParameter copy = GetCopy(); copy.Service = 2; copy.OBDRequest = "02" + copy.OBDRequest.Substring(2, 2) + iFrame.ToString("D2"); return(copy); }
/// <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); }
public OBDParameter GetCopy() { OBDParameter p = new OBDParameter { ValueTypes = ValueTypes, _OBDRequest = OBDRequest, _parameter = Parameter, Service = Service, SignalName = SignalName, }; return(p); }
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); }
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); }
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); }
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); }
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); }
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); }
protected abstract List <string> GetLegalLines(OBDParameter param, List <string> tempLines, int headLen);
public abstract OBDResponseList Parse(OBDParameter param, string response);
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); }
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); }
public override OBDResponseList Parse(OBDParameter param, string response) { return(Parse(param, response, HEADER_LENGTH)); }
public abstract OBDResponseList Query(OBDParameter param);
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); }
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); }