예제 #1
0
        /// <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));
        }
예제 #2
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);
        }
예제 #3
0
        /// <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);
            }
        }
예제 #4
0
        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);
        }