private bool ReceiveFrame()
        {
            // check if enough bytes ready
            ushort required_count = this.currentHeader.Length;

            if (this.pendingBytes.Count < required_count)
            {
                return(false);
            }
            this.ReceiveState = ReceiveStates.ReceiveStartByte;
            // create emission description
            EmissionDescriptor desc = new EmissionDescriptor(this.currentHeader,
                                                             this.pendingBytes.Take(required_count).ToList());

            this.mutexEmissions.WaitOne();
            this.emissions.Add(desc);
            this.mutexEmissions.ReleaseMutex();
            // remove emission bytes
            this.pendingBytes.RemoveRange(0, required_count);
            // invoke callback
            if (this.OnEmission != null)
            {
                this.OnEmission(this, desc);
            }
            return(true);
        }
예제 #2
0
        // Handle data read in worker thread
        private void ReceivedDataEvent(byte[] ReadBuffer, int BufferLength)
        {
            for (int x = 0; x < BufferLength; x++)
            {
                switch (CurrentState)
                {
                case ReceiveStates.HEADER1:
                    if (ReadBuffer[x] == PacketHeader[0])
                    {
                        CurrentState = ReceiveStates.HEADER2;
                    }
                    break;

                case ReceiveStates.HEADER2:
                    if (ReadBuffer[x] == PacketHeader[1])
                    {
                        CurrentState = ReceiveStates.SIZE;
                    }
                    else
                    {
                        CurrentState = ReceiveStates.HEADER1;
                    }
                    break;

                case ReceiveStates.SIZE:
                    CurrentPayloadSize = ReadBuffer[x];
                    CurrentState       = ReceiveStates.TYPE;
                    break;

                case ReceiveStates.TYPE:
                    CurrentPayloadType = ReadBuffer[x];
                    CurrentBytesRead   = 0;
                    CurrentState       = ReceiveStates.PAYLOAD;
                    break;

                case ReceiveStates.PAYLOAD:
                    PayloadBuffer[CurrentBytesRead] = ReadBuffer[x];
                    CurrentBytesRead++;
                    if (CurrentBytesRead == CurrentPayloadSize)
                    {
                        OnPacketReceived(CurrentPayloadType, PayloadBuffer,
                                         CurrentBytesRead);
                        CurrentState = ReceiveStates.HEADER1;
                    }
                    break;
                }
            }
        }
        private bool ReceiveHeader()
        {
            // check if enough bytes ready
            int required_count = CONSTANTS.EMISSION_HEADER_SIZE;

            if (this.pendingBytes.Count < required_count)
            {
                return(false);
            }
            this.ReceiveState = ReceiveStates.ReceiveFrame;
            // decode header
            this.currentHeader.Unpack(this.pendingBytes.Take(required_count).ToList());
            // remove header bytes
            this.pendingBytes.RemoveRange(0, required_count);
            return(true);
        }
        private bool ReceiveStartByte()
        {
            // find start byte
            bool success = false;
            int  index   = this.pendingBytes.FindIndex(b => b == CONSTANTS.FRAME_START_BYTE);

            // determine success
            if (index < 0)       // if start byte not found, remove all bytes
            {
                index = this.pendingBytes.Count;
            }
            else
            {
                this.ReceiveState = ReceiveStates.ReceiveHeader;
                success           = true; // if start byte found, remove bytes leading up to it and indicate success
            }
            // remove all bytes leading up to start byte
            if (index > 0)
            {
                this.pendingBytes.RemoveRange(0, index);
            }
            return(success);
        }
예제 #5
0
        /// <summary>
        /// Get packets out of the received data. Check length, checksum and header.
        /// Modified version of the original code from KSPSerialIO.
        /// The original code made sure, that it's possible to receive the data in packs
        /// smaller than one full frame. The Tcp Server receives the data in whole frames,
        /// in worst case multiple frames are buffered. So CurrentState has not to be saved
        /// between multiple calls.
        /// </summary>
        /// <param name="data">Received data</param>
        private void ReceivedDataEvent(byte[] data)
        {
            ReceiveStates CurrentState        = ReceiveStates.FIRSTHEADER;
            byte          CurrentPacketLength = 0;
            byte          CurrentBytesRead    = 0;

            byte[] PayloadBuffer   = new byte[DataPackets.MaxPayloadSize];
            byte[] NewPacketBuffer = new byte[DataPackets.MaxPayloadSize];

            for (int x = 0; x < data.Length; x++)
            {
                switch (CurrentState)
                {
                case ReceiveStates.FIRSTHEADER:
                    if (data[x] == 0xBE)
                    {
                        CurrentState = ReceiveStates.SECONDHEADER;
                    }
                    break;

                case ReceiveStates.SECONDHEADER:
                    if (data[x] == 0xEF)
                    {
                        CurrentState = ReceiveStates.SIZE;
                    }
                    else
                    {
                        CurrentState = ReceiveStates.FIRSTHEADER;
                    }
                    break;

                case ReceiveStates.SIZE:
                    CurrentPacketLength = data[x];
                    CurrentBytesRead    = 0;
                    CurrentState        = ReceiveStates.PAYLOAD;
                    break;

                case ReceiveStates.PAYLOAD:
                    PayloadBuffer[CurrentBytesRead] = data[x];
                    CurrentBytesRead++;
                    if (CurrentBytesRead == CurrentPacketLength)
                    {
                        CurrentState = ReceiveStates.CS;
                    }
                    break;

                case ReceiveStates.CS:
                    if (CompareChecksum(data[x], CurrentPacketLength, PayloadBuffer))
                    {
                        Buffer.BlockCopy(PayloadBuffer, 0, NewPacketBuffer, 0, CurrentBytesRead);
                        InboundPacketHandler(NewPacketBuffer);
                    }
                    else
                    {
                        Debug.LogWarning("[KSPEthernetIO]: Checksum error");
                    }
                    CurrentState = ReceiveStates.FIRSTHEADER;
                    break;
                }
            }
        }
        private async Task <ReceivedWapMessage> ReceiveMessage(CancellationToken ct)
        {
            ReceiveStates state    = ReceiveStates.Idle;
            List <byte>   msgBytes = new List <byte>();

            await _rxSem.WaitAsync(ct);

            while (true)
            {
                if (ct.IsCancellationRequested)
                {
                    _rxSem.Release();
                    ct.ThrowIfCancellationRequested();
                }

                byte[] bs;
                if (_bufBytes.Count > 0)
                {
                    bs = _bufBytes.ToArray();
                    _bufBytes.Clear();
                }
                else
                {
                    byte[] buf   = new byte[ReadBlockSize];
                    int    count = await _stream.ReadAsync(buf, 0, ReadBlockSize, ct).ConfigureAwait(false);

                    if (count == 0)
                    {
                        _rxSem.Release();
                        throw new OperationCanceledException("End of Stream reached during reading");
                    }

                    bs = new byte[count];
                    Array.Copy(buf, bs, count);
                }

                for (int i = 0; i < bs.Length; i++)
                {
                    byte b = bs[i];

                    switch (state)
                    {
                    case ReceiveStates.Idle:
                        if (b == StartByte)
                        {
                            state = ReceiveStates.Reading;
                        }
                        break;

                    case ReceiveStates.Reading:
                        if (b == StartByte)
                        {
                            _rxSem.Release();
                            throw new BrokenFrameException("Unexpected start byte", msgBytes);
                        }
                        else if (b == EndByte)
                        {
                            ReceivedWapMessage msg;
                            try
                            {
                                msg = new ReceivedWapMessage(msgBytes.ToArray());
                            }
                            catch (Exception ex)
                            {
                                _rxSem.Release();
                                throw new BrokenFrameException("Parsing failed", msgBytes, ex);
                            }

                            _bufBytes.AddRange(bs.Skip(i + 1));
                            _rxSem.Release();
                            return(msg);
                        }
                        else if (b == EscapeByte)
                        {
                            state = ReceiveStates.ReadingEscaped;
                        }
                        else
                        {
                            msgBytes.Add(b);
                        }
                        break;

                    case ReceiveStates.ReadingEscaped:
                        if (b < EscapeOffset)
                        {
                            msgBytes.Add(b);
                            _rxSem.Release();
                            throw new BrokenFrameException("Illegal escaped sequence", msgBytes);
                        }
                        else
                        {
                            b -= EscapeOffset;
                            msgBytes.Add(b);
                            state = ReceiveStates.Reading;
                        }
                        break;
                    }
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Waits for a complete TPDU frame, checks the checksum and sends the ACK, NAK
        /// </summary>
        /// <returns></returns>
        private byte[] ReceiveTpduFrame()
        {
            bool        frameComplete = false;
            List <byte> frameData     = new List <byte>();

            //Time measurement, the receive of a whole Frame should not exceed BLOCK_TIMEOUT
            int startTick = Environment.TickCount;

            ReceiveStates currentState = ReceiveStates.WaitForStartingDLE;

            int myTimeout = RECEIVE_RESPONSE_TIMEOUT;

            if (!_masterMode)
            {
                myTimeout = MASTER_RESPONES_TIMEOUT;
            }

            while (!frameComplete && (!_masterMode || Environment.TickCount - startTick < RECEIVE_RESPONSE_TIMEOUT))
            {
                //For the first [DLE] the timeout is BLOCK_TIMEOUT, after the DLE was received
                //only BYTE_TIMEOUT is allowed during the bytes
                byte?myByte = _buffer.WaitForByte(myTimeout, true);

                //A Timeout occured, set state to error state and send nak
                if (myByte == null)
                {
                    _log.Debug("ReceiveTpduFrame: timeout occured, going into error state");
                    frameComplete = true;
                    currentState  = ReceiveStates.Error;
                    continue;
                }


                if (currentState != ReceiveStates.WaitForStartingDLE)
                {
                    frameData.Add(myByte.Value);
                }


                //Simple Statemachine implementation see ReceiveStates for possible state transitions

                if (currentState == ReceiveStates.WaitForStartingDLE && myByte.Value == RS232Tpdu.DLE)
                {
                    frameData.Add(myByte.Value);
                    currentState = ReceiveStates.WaitForSTX;
                }
                else if (currentState == ReceiveStates.WaitForSTX && myByte.Value == RS232Tpdu.STX)
                {
                    currentState = ReceiveStates.APDUData;
                }
                else if (currentState == ReceiveStates.WaitForSTX)
                {
                    _log.Debug("ReceiveTpduFrame: No STX after DLE, resetting and waiting for DLE");
                    currentState = ReceiveStates.WaitForStartingDLE;
                    frameData.Clear();
                }
                else if (currentState == ReceiveStates.APDUData && myByte.Value == RS232Tpdu.DLE)
                {
                    currentState = ReceiveStates.WaitForDoubleDLE;
                }
                else if (currentState == ReceiveStates.WaitForDoubleDLE && myByte.Value == RS232Tpdu.DLE)
                {
                    currentState = ReceiveStates.APDUData;
                }
                else if (currentState == ReceiveStates.WaitForDoubleDLE && myByte.Value == RS232Tpdu.ETX)
                {
                    currentState = ReceiveStates.WaitForCRCLow;
                }
                else if (currentState == ReceiveStates.WaitForDoubleDLE)
                {
                    _log.Debug("ReceiveTpduFrame: Invalid byte after DLE, received {0:X2}", myByte.Value);
                    frameComplete = true;
                    currentState  = ReceiveStates.Error;
                }
                else if (currentState == ReceiveStates.WaitForCRCLow)
                {
                    currentState = ReceiveStates.WaitForCRCHigh;
                }
                else if (currentState == ReceiveStates.WaitForCRCHigh)
                {
                    _log.Debug("ReceiveTpduFrame: {0}", ByteHelpers.ByteToString(frameData.ToArray()));
                    frameComplete = true;
                    currentState  = ReceiveStates.Completed;
                }
            }

            if (currentState == ReceiveStates.Completed)
            {
                return(frameData.ToArray());
            }
            else
            {
                return(null);
            }
        }