Gurux.DLMS.GXDLMSSettings.CheckFrame C# (CSharp) Method

CheckFrame() public method

public CheckFrame ( byte frame ) : bool
frame byte
return bool
        public bool CheckFrame(byte frame)
        {
            //If U frame.
            if ((frame & (byte)HdlcFrameType.Uframe) == (byte)HdlcFrameType.Uframe)
            {
                if (frame == 0x73 || frame == 0x93)
                {
                    ResetFrameSequence();
                    return true;
                }
            }
            //If S -frame.
            if ((frame & (byte)HdlcFrameType.Sframe) == (byte)HdlcFrameType.Sframe)
            {
                ReceiverFrame = IncreaseReceiverSequence(ReceiverFrame);
                return true;
            }
            //Handle I-frame.
            if (frame == (byte)IncreaseReceiverSequence(IncreaseSendSequence(ReceiverFrame)))
            {
                ReceiverFrame = frame;
                return true;
            }
            //If answer for RR.
            if (frame == (byte)IncreaseSendSequence(ReceiverFrame))
            {
                ReceiverFrame = frame;
                return true;
            }
            //If try to find data from bytestream and not real communicating.
            if (ReceiverFrame == 0xEE)
            {
                return true;
            }
            System.Diagnostics.Debug.WriteLine("Invalid HDLC Frame ID.");
            return false;
        }

Usage Example

Exemplo n.º 1
0
        static byte GetHdlcData(bool server, GXDLMSSettings settings, GXByteBuffer reply, GXReplyData data)
        {
            short ch;
            int pos, packetStartID = reply.Position, frameLen = 0;
            int crc, crcRead;
            // If whole frame is not received yet.
            if (reply.Size - reply.Position < 9)
            {
                data.IsComplete = false;
                return 0;
            }
            data.IsComplete = true;
            // Find start of HDLC frame.
            for (pos = reply.Position; pos < reply.Size; ++pos)
            {
                ch = reply.GetUInt8();
                if (ch == GXCommon.HDLCFrameStartEnd)
                {
                    packetStartID = pos;
                    break;
                }
            }
            // Not a HDLC frame.
            // Sometimes meters can send some strange data between DLMS frames.
            if (reply.Position == reply.Size)
            {
                data.IsComplete = false;
                // Not enough data to parse;
                return 0;
            }
            byte frame = reply.GetUInt8();
            if ((frame & 0xF0) != 0xA0)
            {
                //If same strage data.
                return GetHdlcData(server, settings, reply, data);
            }
            // Check frame length.
            if ((frame & 0x7) != 0)
            {
                frameLen = ((frame & 0x7) << 8);
            }
            ch = reply.GetUInt8();
            // If not enough data.
            frameLen += ch;
            if (reply.Size - reply.Position + 1 < frameLen)
            {
                data.IsComplete = false;
                reply.Position = packetStartID;
                // Not enough data to parse;
                return 0;
            }
            int eopPos = frameLen + packetStartID + 1;
            ch = reply.GetUInt8(eopPos);
            if (ch != GXCommon.HDLCFrameStartEnd)
            {
                throw new GXDLMSException("Invalid data format.");
            }

            // Check addresses.
            if (!CheckHdlcAddress(server, settings, reply, eopPos))
            {
                //If echo,
                reply.Position = 1 + eopPos;
                return GetHdlcData(server, settings, reply, data);
            }

            // Is there more data available.
            if ((frame & 0x8) != 0)
            {
                data.MoreData = (RequestTypes)(data.MoreData | RequestTypes.Frame);
            }
            else
            {
                data.MoreData = (RequestTypes)(data.MoreData & ~RequestTypes.Frame);
            }
            // Get frame type.
            frame = reply.GetUInt8();
            if (data.Xml == null && !settings.CheckFrame(frame))
            {
                reply.Position = (eopPos + 1);
                return GetHdlcData(server, settings, reply, data);
            }
            // Check that header CRC is correct.
            crc = GXFCS16.CountFCS16(reply.Data, packetStartID + 1, reply.Position - packetStartID - 1);
            crcRead = reply.GetUInt16();
            if (crc != crcRead)
            {
                throw new Exception("Wrong CRC.");
            }
            // Check that packet CRC match only if there is a data part.
            if (reply.Position != packetStartID + frameLen + 1)
            {
                crc = GXFCS16.CountFCS16(reply.Data, packetStartID + 1,
                                         frameLen - 2);
                crcRead = reply.GetUInt16(packetStartID + frameLen - 1);
                if (crc != crcRead)
                {
                    throw new Exception("Wrong CRC.");
                }
                // Remove CRC and EOP from packet length.
                data.PacketLength = eopPos - 2;
            }
            else
            {
                data.PacketLength = reply.Position + 1;
            }

            if ((frame & (byte)HdlcFrameType.Uframe) == (byte)HdlcFrameType.Uframe)
            {
                //Get Eop if there is no data.
                if (reply.Position == packetStartID + frameLen + 1)
                {
                    // Get EOP.
                    reply.GetUInt8();
                }
                data.Command = (Command)frame;
            }
            //If S-frame
            else if ((frame & (byte)HdlcFrameType.Sframe) == (byte)HdlcFrameType.Sframe)
            {
                //If frame is rejected.
                int tmp = (frame >> 2) & 0x3;
                if (tmp == (byte)HdlcControlFrame.Reject)
                {
                    data.Error = (int)ErrorCode.Rejected;
                }
                else if (tmp == (byte)HdlcControlFrame.ReceiveNotReady)
                {
                    data.Error = (int)ErrorCode.Rejected;
                }
                else if (tmp == (byte)HdlcControlFrame.ReceiveReady)
                {
                    System.Diagnostics.Debug.WriteLine("Get next frame.");
                }
                //Get Eop if there is no data.
                if (reply.Position == packetStartID + frameLen + 1)
                {
                    // Get EOP.
                    reply.GetUInt8();
                }
            }
            else //Iframe
            {
                //Get Eop if there is no data.
                if (reply.Position == packetStartID + frameLen + 1)
                {
                    // Get EOP.
                    reply.GetUInt8();
                    if ((frame & 0x1) == 0x1)
                    {
                        data.MoreData = RequestTypes.Frame;
                    }
                }
                else
                {
                    if (!GetLLCBytes(server, reply) && data.Xml != null)
                    {
                        GetLLCBytes(!server, reply);
                    }
                }
            }
            return frame;
        }