///<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, GXDLMSConnectionEventArgs connectionInfo) { if (buff == null || buff.Length == 0) { return(null); } if (!Initialized) { throw new Exception("Server not Initialized."); } try { receivedData.Set(buff); bool first = Settings.ServerAddress == 0 && Settings.ClientAddress == 0; GXDLMS.GetData(Settings, receivedData, info); //If all data is not received yet. if (!info.IsComplete) { return(null); } receivedData.Clear(); if (first) { // Check is data send to this server. if (!IsTarget(Settings.ServerAddress, Settings.ClientAddress)) { info.Clear(); return(null); } } //If client want next frame. if ((info.MoreData & RequestTypes.Frame) == RequestTypes.Frame) { return(GXDLMS.GetHdlcFrame(Settings, Settings.ReceiverReady(), replyData)); } //Update command if transaction and next frame is asked. if (info.Command == Command.None) { if (transaction != null) { info.Command = transaction.command; } } //Check inactivity time out. if (hdlcSetup != null) { if (info.Command == Command.Snrm) { dataReceived = DateTime.Now; } else { int elapsed = (int)(DateTime.Now - dataReceived).TotalSeconds; //If inactivity time out is elapsed. if (elapsed >= hdlcSetup.InactivityTimeout) { Reset(); dataReceived = DateTime.MinValue; return(null); } dataReceived = DateTime.Now; } } byte[] reply = HandleCommand(info.Command, info.Data, connectionInfo); info.Clear(); return(reply); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); if (info.Command != Command.None) { return(ReportError(info.Command, ErrorCode.HardwareFault)); } else { Reset(); if (Settings.Connected) { Settings.Connected = false; Disconnected(connectionInfo); } return(null); } } }
///<summary> ///Generates an acknowledgment message, with which the server is informed to send next packets. ///</summary> ///<param name="type"> /// Frame type. /// </param> ///<returns> ///Acknowledgment message as byte array. ///</returns> internal static byte[] ReceiverReady(GXDLMSSettings settings, RequestTypes type) { if (type == RequestTypes.None) { throw new ArgumentException("Invalid receiverReady RequestTypes parameter."); } // Get next frame. if ((type & RequestTypes.Frame) != 0) { byte id = settings.ReceiverReady(); return GetHdlcFrame(settings, id, null); } Command cmd; if (settings.UseLogicalNameReferencing) { if (settings.IsServer) { cmd = Command.GetResponse; } else { cmd = Command.GetRequest; } } else { if (settings.IsServer) { cmd = Command.ReadResponse; } else { cmd = Command.ReadRequest; } } // Get next block. GXByteBuffer bb = new GXByteBuffer(6); if (settings.UseLogicalNameReferencing) { bb.SetUInt32(settings.BlockIndex); } else { bb.SetUInt16((UInt16)settings.BlockIndex); } settings.IncreaseBlockIndex(); byte[][] reply; if (settings.UseLogicalNameReferencing) { GXDLMSLNParameters p = new GXDLMSLNParameters(settings, cmd, (byte)GetCommandType.NextDataBlock, bb, null, 0xff); reply = GXDLMS.GetLnMessages(p); } else { GXDLMSSNParameters p = new GXDLMSSNParameters(settings, cmd, 1, (byte)VariableAccessSpecification.BlockNumberAccess, bb, null); reply = GXDLMS.GetSnMessages(p); } return reply[0]; }