///<summary> /// Get packet from received data. ///</summary> ///<param name="buff"> /// Received data. </param> ///<returns> ///Reply if any. ///</returns> private byte[] GetPacket(byte[] buff) { GXByteBuffer receivedFrame = new GXByteBuffer(buff); // Save position where data was. This is used if data is not sent to // this server. ushort offset = Reply.Data.Size; GXDLMS.GetData(Settings, receivedFrame, Reply); // If all data is not received yet. if (!Reply.IsComplete) { return(null); } byte[] data; // If client sends keepalive or get next frame request. if ((Reply.MoreData & RequestTypes.Frame) != 0) { if (Frames != null && Frames.Length > FrameIndex) { data = Frames[FrameIndex++]; return(data); } FrameIndex = 0; data = GXDLMS.SplitToHdlcFrames(Settings, Settings.KeepAlive(), null)[0]; return(data); } // Check is data sent to this server. if (ConnectedServerAddress == 0 || ConnectedClientAddress == 0) { // Check is data send to this server. if (!IsTarget(Settings.ServerAddress, Settings.ClientAddress)) { Reply.Data.Size = offset; Reply.IsComplete = false; } ConnectedServerAddress = Settings.ServerAddress; ConnectedClientAddress = Settings.ClientAddress; } else if (Settings.ServerAddress != ConnectedServerAddress || Settings.ClientAddress != ConnectedClientAddress) { Reply.Data.Size = offset; Reply.IsComplete = false; } // Clear received data. receivedFrame.Clear(); ServerReply.Data = Reply.Data; FrameIndex = 0; return(null); }
///<summary> /// Handle received command. ///</summary> private void HandleCommand() { switch (Reply.Command) { case Command.SetRequest: Frames = HandleSetRequest(); break; case Command.WriteRequest: Frames = HandleWriteRequest(); break; case Command.GetRequest: Frames = HandleGetRequest(); break; case Command.ReadRequest: Frames = HandleReadRequest(); break; case Command.MethodRequest: Frames = HandleMethodRequest(); break; case Command.Snrm: Frames = HandleSnrmRequest(); break; case Command.Aarq: Frames = HandleAarqRequest(); break; case Command.DisconnectRequest: Frames = GenerateDisconnectRequest(); break; default: Debug.WriteLine("Invalid command: " + Reply.Command.ToString()); Frames = GXDLMS.SplitToHdlcFrames(Settings, (byte)FrameType.Rejected, null); break; } }
///<summary> ///Generates disconnect request. /// </summary> ///<returns> ///Disconnect request. ///</returns> private byte[][] GenerateDisconnectRequest() { GXByteBuffer buff; if (this.InterfaceType == InterfaceType.WRAPPER) { buff = new GXByteBuffer(2); buff.SetUInt8(0x63); buff.SetUInt8(0x0); return(GXDLMS.SplitToWrapperFrames(Settings, buff)); } else { buff = new GXByteBuffer(22); buff.SetUInt8(0x81); // FromatID buff.SetUInt8(0x80); // GroupID buff.SetUInt8(0); // Length buff.SetUInt8(HDLCInfo.MaxInfoTX); buff.SetUInt8(GXCommon.GetSize(Limits.MaxInfoTX)); buff.Add(Limits.MaxInfoTX); buff.SetUInt8(HDLCInfo.MaxInfoRX); buff.SetUInt8(GXCommon.GetSize(Limits.MaxInfoRX)); buff.Add(Limits.MaxInfoRX); buff.SetUInt8(HDLCInfo.WindowSizeTX); buff.SetUInt8(GXCommon.GetSize(Limits.WindowSizeTX)); buff.Add(Limits.WindowSizeTX); buff.SetUInt8(HDLCInfo.WindowSizeRX); buff.SetUInt8(GXCommon.GetSize(Limits.WindowSizeRX)); buff.Add(Limits.WindowSizeRX); int len = buff.Position - 3; buff.SetUInt8(2, (byte)len); // Length. } return(GXDLMS.SplitToHdlcFrames(Settings, (byte)Command.Ua, buff)); }
///<summary> /// Handles client request. /// </summary> ///<param name="buff"> /// Received data from the client. </param> ///<returns> ///Response to the request. Response is null if request packet is not complete. ///</returns> public virtual byte[] HandleRequest(byte[] buff) { if (buff == null || buff.Length == 0) { return(null); } if (!Initialized) { throw new Exception("Server not Initialized."); } try { byte[] data = GetPacket(buff); // If all data is not received yet or message is not accepted. if (!Reply.IsComplete) { return(null); } if (data != null) { return(data); } HandleCommand(); if (!Reply.IsMoreData) { Reply.Clear(); } data = Frames[FrameIndex++]; return(data); } catch (Exception e) { // Disconnect. Debug.WriteLine(e.ToString()); byte[] data = GXDLMS.SplitToHdlcFrames(Settings, (byte)FrameType.Rejected, null)[0]; Reset(); return(data); } }
///<summary> ///Parse SNRM Request. If server do not accept client empty byte array is returned. /// </summary> ///<returns> ///Returns returned UA packet. ///</returns> private byte[][] HandleSnrmRequest() { GXByteBuffer bb = new GXByteBuffer(25); bb.SetUInt8(0x81); // FromatID bb.SetUInt8(0x80); // GroupID bb.SetUInt8(0); // Length bb.SetUInt8(HDLCInfo.MaxInfoTX); bb.SetUInt8(GXCommon.GetSize(Limits.MaxInfoTX)); bb.Add(Limits.MaxInfoTX); bb.SetUInt8(HDLCInfo.MaxInfoRX); bb.SetUInt8(GXCommon.GetSize(Limits.MaxInfoRX)); bb.Add(Limits.MaxInfoRX); bb.SetUInt8(HDLCInfo.WindowSizeTX); bb.SetUInt8(GXCommon.GetSize(Limits.WindowSizeTX)); bb.Add(Limits.WindowSizeTX); bb.SetUInt8(HDLCInfo.WindowSizeRX); bb.SetUInt8(GXCommon.GetSize(Limits.WindowSizeRX)); bb.Add(Limits.WindowSizeRX); bb.SetUInt8(2, (byte)(bb.Size - 3)); return(GXDLMS.SplitToHdlcFrames(Settings, (byte)Command.Ua, bb)); }