/// <summary> /// Read an network packet from the interface, and return a Response/Message /// </summary> protected override Task Receive() { //this.Logger.AddDebugMessage("Trace: Read Network Packet"); PassThruMsg PassMess = new PassThruMsg(); Message TempMessage = new Message(null); int NumMessages = 1; IntPtr rxMsgs = Marshal.AllocHGlobal((int)(Marshal.SizeOf(typeof(PassThruMsg)) * NumMessages)); OBDError = 0; //Clear any previous faults Stopwatch sw = new Stopwatch(); sw.Start(); while (OBDError == J2534Err.STATUS_NOERROR || sw.ElapsedMilliseconds > (long)ReadTimeout) { NumMessages = 1; OBDError = J2534Port.Functions.PassThruReadMsgs((int)ChannelID, rxMsgs, ref NumMessages, ReadTimeout); if (OBDError != J2534Err.STATUS_NOERROR) { this.Logger.AddDebugMessage("ReadMsgs OBDError: " + OBDError); return(Task.FromResult(0)); } sw.Stop(); PassMess = rxMsgs.AsMsgList(1).Last(); if ((int)PassMess.RxStatus == (((int)RxStatus.TX_INDICATION_SUCCESS) + ((int)RxStatus.TX_MSG_TYPE)) || (PassMess.RxStatus == RxStatus.START_OF_MESSAGE)) { continue; } else { byte[] TempBytes = PassMess.GetBytes(); //Perform additional filter check if required here... or show to debug break;//leave while loop } } Marshal.FreeHGlobal(rxMsgs); if (OBDError != J2534Err.STATUS_NOERROR || sw.ElapsedMilliseconds > (long)ReadTimeout) { this.Logger.AddDebugMessage("ReadMsgs OBDError: " + OBDError); return(Task.FromResult(0)); } this.Logger.AddDebugMessage("RX: " + PassMess.GetBytes().ToHex()); this.Enqueue(new Message(PassMess.GetBytes(), PassMess.Timestamp, (ulong)OBDError)); return(Task.FromResult(0)); }
/// <summary> /// Parse the replies checking for a valid response, if we have a valid response extract the payload data /// </summary> /// <param name="rxMsgs"></param> /// <param name="txMode"></param> /// <param name="payload"></param> /// <returns></returns> UDSPacket ParseUDSResponse(PassThruMsg rxMsg, UDScmd.Mode txMode) { var rxMsgBytes = rxMsg.GetBytes(); UDSPacket rxPacket = new UDSPacket(); //Iterate the reply bytes to find the echod ECU index, response code, function response and payload data if there is any //If we could use some kind of HEX regex this would be a bit neater int stateMachine = 0; for (int i = 0; i < rxMsgBytes.Length; i++) { switch (stateMachine) { case 0: if (rxMsgBytes[i] == 0x07) { stateMachine = 1; } else if (rxMsgBytes[i] != 0) { return(rxPacket); } break; case 1: if (rxMsgBytes[i] == 0xE8) { stateMachine = 2; } else { return(rxPacket); } break; case 2: var payload = new byte[rxMsgBytes.Length - i]; int payloadLength = rxMsgBytes.Length - i; if (payloadLength > 0) { payload = new byte[payloadLength]; Array.Copy(rxMsgBytes, i, payload, 0, payloadLength); rxPacket = new UDSPacket(payload, txMode); ; } return(rxPacket); case 3: default: return(rxPacket); } } return(rxPacket); }
/// <summary> /// readMessages is the "run" method of this class. It reads all incomming messages /// and publishes them to registered ICANListeners. /// </summary> public void readMessages() { uint id; int numMsgs = 1; const int timeout = 1000; CANMessage canMessage = new CANMessage(); logger.Debug("readMessages started"); while (true) { lock (m_synchObject) { if (m_endThread) { logger.Debug("readMessages thread ended"); return; } } IntPtr rxMsgs = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PassThruMsg))); m_status = passThru.PassThruReadMsgs(m_channelId, rxMsgs, ref numMsgs, timeout); if (m_status == J2534Err.STATUS_NOERROR) { if (numMsgs > 0) { PassThruMsg msg = rxMsgs.AsMsgList(numMsgs)[0]; byte[] all = msg.GetBytes(); id = (uint)(all[2] * 0x100 + all[3]); uint length = msg.DataSize - 4; byte[] data = new byte[length]; Array.Copy(all, 4, data, 0, length); if (acceptMessageId(id)) { canMessage.setID(id); canMessage.setTimeStamp(msg.Timestamp); canMessage.setCanData(data, (byte)(length)); receivedMessage(canMessage); } } } else { logger.Debug(String.Format("PassThruReadMsgs, status:{0}", m_status)); } Marshal.FreeHGlobal(rxMsgs); } }
private bool ReadObdPid(byte mode, byte pid, ProtocolID protocolId, ref List <byte> value) { PassThruMsg txMsg = new PassThruMsg(); int timeout; txMsg.ProtocolID = protocolId; switch (protocolId) { case ProtocolID.ISO15765: txMsg.TxFlags = TxFlag.ISO15765_FRAME_PAD; if (mode == 0x03 || mode == 0x04) { txMsg.SetBytes(new byte[] { 0x00, 0x00, 0x07, 0xdf, mode }); } else { txMsg.SetBytes(new byte[] { 0x00, 0x00, 0x07, 0xdf, mode, pid }); } timeout = 50; break; case ProtocolID.J1850PWM: case ProtocolID.J1850VPW: case ProtocolID.ISO9141: case ProtocolID.ISO14230: byte protocolByte = (byte)((protocolId == ProtocolID.J1850PWM) ? 0x61 : 0x68); txMsg.TxFlags = TxFlag.NONE; txMsg.SetBytes(new byte[] { protocolByte, 0x6A, 0xF1, mode, pid }); timeout = 100; break; default: return(false); } m_j2534Interface.ClearRxBuffer(m_channelId); int numMsgs = 1; m_status = m_j2534Interface.PassThruWriteMsgs(m_channelId, txMsg.ToIntPtr(), ref numMsgs, timeout); if (J2534Err.STATUS_NOERROR != m_status) { return(false); } IntPtr rxMsgs = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PassThruMsg)) * numMsgs); numMsgs = 1; while (J2534Err.STATUS_NOERROR == m_status) { m_status = m_j2534Interface.PassThruReadMsgs(m_channelId, rxMsgs, ref numMsgs, timeout * 4); } if (J2534Err.ERR_BUFFER_EMPTY == m_status || J2534Err.ERR_TIMEOUT == m_status) { if (numMsgs > 0) { // Select the last value PassThruMsg msg = rxMsgs.AsMsgList(numMsgs).Last(); value = msg.GetBytes().ToList(); value.RemoveRange(0, txMsg.GetBytes().Length); return(true); } return(false); } return(false); }