private byte[] ReportError(Command cmd, ErrorCode error) { switch (cmd) { case Command.ReadRequest: cmd = Command.ReadResponse; break; case Command.WriteRequest: cmd = Command.WriteResponse; break; case Command.GetRequest: cmd = Command.GetResponse; break; case Command.SetRequest: cmd = Command.SetResponse; break; case Command.MethodRequest: cmd = Command.MethodResponse; break; default: //Return HW error and close connection.. break; } if (Settings.UseLogicalNameReferencing) { GXDLMS.GetLNPdu(new GXDLMSLNParameters(Settings, 0, cmd, 1, null, null, (byte)error), replyData); } else { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8(error); GXDLMSSNParameters p = new GXDLMSSNParameters(Settings, cmd, 1, (byte)error, null, bb); GXDLMS.GetSNPdu(p, replyData); } if (this.InterfaceType == Enums.InterfaceType.WRAPPER) { return(GXDLMS.GetWrapperFrame(Settings, replyData)); } else { return(GXDLMS.GetHdlcFrame(Settings, 0, replyData)); } }
/// <summary> /// Load XML commands from the file. /// </summary> /// <param name="fileName"></param> /// <returns></returns> public byte[][] PduToMessages(GXDLMSXmlPdu pdu) { List <byte[]> messages = new List <byte[]>(); if (pdu.Command == Command.Snrm) { messages.Add(pdu.Data); } else if (pdu.Command == Command.Ua) { messages.Add(pdu.Data); } else if (pdu.Command == Command.DisconnectRequest) { messages.Add(GXDLMS.GetHdlcFrame(Settings, (byte)Command.DisconnectRequest, new GXByteBuffer(pdu.Data))); } else { GXByteBuffer reply; if (Settings.InterfaceType == InterfaceType.WRAPPER) { if (Ciphering.Security != (byte)Security.None) { GXDLMSLNParameters p = new GXDLMSLNParameters(this, Settings, 0, pdu.Command, 0x0, null, null, 0xff, Command.None); reply = new GXByteBuffer(GXDLMS.Cipher0(p, pdu.Data)); } else { reply = new GXByteBuffer(pdu.Data); } } else { if (Ciphering.Security != (byte)Security.None) { GXDLMSLNParameters p = new GXDLMSLNParameters(this, Settings, 0, pdu.Command, 0x0, null, null, 0xff, Command.None); byte[] tmp = GXDLMS.Cipher0(p, pdu.Data); reply = new GXByteBuffer((UInt16)(3 + tmp.Length)); reply.Set(GXCommon.LLCSendBytes); reply.Set(tmp); } else { reply = new GXByteBuffer((UInt16)(3 + pdu.Data.Length)); reply.Set(GXCommon.LLCSendBytes); reply.Set(pdu.Data); } } byte frame = 0; while (reply.Position != reply.Size) { if (Settings.InterfaceType == Enums.InterfaceType.WRAPPER) { messages.Add(GXDLMS.GetWrapperFrame(Settings, pdu.Command, reply)); } else if (Settings.InterfaceType == Enums.InterfaceType.HDLC) { if (pdu.Command == Command.Aarq) { frame = 0x10; } else if (pdu.Command == Command.Aare) { frame = 0x30; } else if (pdu.Command == Command.EventNotification) { frame = 0x13; } messages.Add(GXDLMS.GetHdlcFrame(Settings, frame, reply)); if (reply.Position != reply.Size) { frame = Settings.NextSend(false); } } else if (Settings.InterfaceType == Enums.InterfaceType.PDU) { messages.Add(reply.Array()); break; } else { throw new ArgumentOutOfRangeException("InterfaceType"); } } } return(messages.ToArray()); }
///<summary> /// Handle received command. ///</summary> private byte[] HandleCommand(Command cmd, GXByteBuffer data, GXDLMSConnectionEventArgs connectionInfo) { byte frame = 0; switch (cmd) { case Command.AccessRequest: GXDLMSLNCommandHandler.HandleAccessRequest(Settings, this, data, replyData, null); break; case Command.SetRequest: GXDLMSLNCommandHandler.HandleSetRequest(Settings, this, data, replyData, null); break; case Command.WriteRequest: GXDLMSSNCommandHandler.HandleWriteRequest(Settings, this, data, replyData, null); break; case Command.GetRequest: if (data.Size != 0) { GXDLMSLNCommandHandler.HandleGetRequest(Settings, this, data, replyData, null); } break; case Command.ReadRequest: GXDLMSSNCommandHandler.HandleReadRequest(Settings, this, data, replyData, null); break; case Command.MethodRequest: GXDLMSLNCommandHandler.HandleMethodRequest(Settings, this, data, connectionInfo, replyData, null); break; case Command.Snrm: HandleSnrmRequest(); frame = (byte)Command.Ua; break; case Command.Aarq: HandleAarqRequest(data, connectionInfo); break; case Command.ReleaseRequest: case Command.DisconnectRequest: GenerateDisconnectRequest(); Settings.Connected = false; Disconnected(connectionInfo); frame = (byte)Command.Ua; break; case Command.None: //Get next frame. break; default: Debug.WriteLine("Invalid command: " + (int)cmd); break; } byte[] reply; if (this.InterfaceType == Enums.InterfaceType.WRAPPER) { reply = GXDLMS.GetWrapperFrame(Settings, replyData); } else { reply = GXDLMS.GetHdlcFrame(Settings, frame, replyData); } return(reply); }
///<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> /// Load XML commands from the file. /// </summary> /// <param name="fileName"></param> /// <returns></returns> public byte[][] PduToMessages(GXDLMSXmlPdu pdu) { List <byte[]> messages = new List <byte[]>(); if (pdu.Command == Command.Snrm) { messages.Add(pdu.Data); } else if (pdu.Command == Command.Ua) { messages.Add(pdu.Data); } else if (pdu.Command == Command.DisconnectRequest) { messages.Add(GXDLMS.GetHdlcFrame(Settings, (byte)Command.DisconnectRequest, new GXByteBuffer(pdu.Data))); } else { GXByteBuffer reply; if (Settings.InterfaceType == Enums.InterfaceType.WRAPPER) { reply = new GXByteBuffer(pdu.Data); } else { reply = new GXByteBuffer((UInt16)(3 + pdu.Data.Length)); reply.Set(GXCommon.LLCSendBytes); reply.Set(pdu.Data); } while (reply.Position != reply.Size) { if (Settings.InterfaceType == Enums.InterfaceType.WRAPPER) { messages.Add(GXDLMS.GetWrapperFrame(Settings, reply)); } else if (Settings.InterfaceType == Enums.InterfaceType.HDLC) { byte frame = 0; if (pdu.Command == Command.Aarq) { frame = 0x10; } else if (pdu.Command == Command.Aare) { frame = 0x30; } else if (pdu.Command == Command.EventNotification) { frame = 0x13; } messages.Add(GXDLMS.GetHdlcFrame(Settings, frame, reply)); if (reply.Position != reply.Size) { if (Settings.IsServer || pdu.Command == Command.SetRequest || pdu.Command == Command.MethodRequest) { frame = 0; } else { frame = Settings.NextSend(false); } } } else if (Settings.InterfaceType == Enums.InterfaceType.PDU) { messages.Add(reply.Array()); break; } else { throw new ArgumentOutOfRangeException("InterfaceType"); } } } return(messages.ToArray()); }
/// <summary> /// Load XML commands from the file. /// </summary> /// <param name="fileName"></param> /// <returns></returns> public List <GXDLMSXmlMessage> Load(string fileName) { XmlDocument doc = new XmlDocument(); doc.LoadXml(File.ReadAllText(fileName)); List <GXDLMSXmlMessage> actions = new List <GXDLMSXmlMessage>(); foreach (XmlNode m1 in doc.ChildNodes) { if (m1.NodeType == XmlNodeType.Element) { foreach (XmlNode node in m1.ChildNodes) { if (node.NodeType == XmlNodeType.Element) { List <byte[]> messages = new List <byte[]>(); GXDLMSXmlSettings s = new GXDLMSXmlSettings(translator.OutputType, translator.Hex, translator.ShowStringAsHex, translator.tagsByName);; s.settings.ClientAddress = Settings.ClientAddress; s.settings.ServerAddress = Settings.ServerAddress; GXByteBuffer reply = new GXByteBuffer(translator.XmlToPdu(node.OuterXml, s)); if (s.command == Command.Snrm) { messages.Add(reply.Array()); } else if (s.command == Command.Ua) { Settings.Limits.MaxInfoTX = s.settings.Limits.MaxInfoTX; Settings.Limits.MaxInfoRX = s.settings.Limits.MaxInfoRX; Settings.Limits.WindowSizeRX = s.settings.Limits.WindowSizeRX; Settings.Limits.WindowSizeTX = s.settings.Limits.WindowSizeTX; messages.Add(reply.Array()); } else if (s.command == Command.DisconnectRequest) { messages.Add(GXDLMS.GetHdlcFrame(Settings, (byte)Command.DisconnectRequest, reply)); } else { while (reply.Position != reply.Size) { if (Settings.InterfaceType == Enums.InterfaceType.WRAPPER) { messages.Add(GXDLMS.GetWrapperFrame(Settings, reply)); } else if (Settings.InterfaceType == Enums.InterfaceType.HDLC) { byte frame = 0; if (s.command == Command.Aarq) { frame = 0x10; } else if (s.command == Command.Aare) { frame = 0x30; } else if (s.command == Command.EventNotification) { frame = 0x13; } messages.Add(GXDLMS.GetHdlcFrame(Settings, frame, reply)); if (reply.Position != reply.Size) { if (Settings.IsServer || s.command == Command.SetRequest) { frame = 0; } else { frame = Settings.NextSend(false); } } } else if (Settings.InterfaceType == Enums.InterfaceType.PDU) { messages.Add(reply.Array()); break; } else { throw new ArgumentOutOfRangeException("InterfaceType"); } } } actions.Add(new GXDLMSXmlMessage(s.command, node, messages.ToArray())); } } } } return(actions); }