/// <summary> /// Parses the AARE response. /// </summary> /// <param name="reply"></param> /// <remarks> /// Parse method will update the following data: /// <ul> /// <li>DLMSVersion</li> /// <li>MaxReceivePDUSize</li> /// <li>UseLogicalNameReferencing</li> /// <li>LNSettings or SNSettings</li> /// </ul> /// LNSettings or SNSettings will be updated, depending on the referencing, /// Logical name or Short name. /// </remarks> /// <returns>The AARE response</returns> /// <seealso cref="AARQRequest"/> /// <seealso cref="UseLogicalNameReferencing"/> /// <seealso cref="DLMSVersion"/> /// <seealso cref="MaxReceivePDUSize"/> /// <seealso cref="LNSettings"/> /// <seealso cref="SNSettings"/> public GXDLMSTagCollection ParseAAREResponse(byte[] reply) { byte frame; int error, index = 0; List<byte> arr = new List<byte>(reply); bool packetFull, wrongCrc; byte command; m_Base.GetDataFromFrame(arr, index, out frame, true, out error, false, out packetFull, out wrongCrc, out command, false); if (!packetFull) { throw new GXDLMSException("Not enough data to parse frame."); } if (wrongCrc) { throw new GXDLMSException("Wrong Checksum."); } //Parse AARE data. GXDLMSTagCollection Tags = new GXDLMSTagCollection(); GXAPDU pdu = new GXAPDU(Tags); pdu.EncodeData(arr.ToArray(), ref index); UseLogicalNameReferencing = pdu.UseLN; if (UseLogicalNameReferencing) { System.Diagnostics.Debug.WriteLine("--- Logical Name settings are---\r\n"); } else { System.Diagnostics.Debug.WriteLine("--- Short Name settings are---\r\n"); } m_Base.StoCChallenge = pdu.Password; AssociationResult ret = pdu.ResultComponent; if (ret == AssociationResult.Accepted) { System.Diagnostics.Debug.WriteLine("- Client has accepted connection."); if (UseLogicalNameReferencing) { m_Base.LNSettings = new GXDLMSLNSettings(pdu.UserInformation.ConformanceBlock); } else { m_Base.SNSettings = new GXDLMSSNSettings(pdu.UserInformation.ConformanceBlock); } MaxReceivePDUSize = pdu.UserInformation.MaxReceivePDUSize; DLMSVersion = pdu.UserInformation.DLMSVersioNumber; } else { m_Base.LNSettings = null; m_Base.SNSettings = null; throw new GXDLMSException(ret, pdu.ResultDiagnosticValue); } IsAuthenticationRequired = pdu.ResultDiagnosticValue == SourceDiagnostic.AuthenticationRequired; if (IsAuthenticationRequired) { System.Diagnostics.Debug.WriteLine("Authentication is used."); } System.Diagnostics.Debug.WriteLine("- Server max PDU size is " + MaxReceivePDUSize); System.Diagnostics.Debug.WriteLine("- Value of quality of service is " + ValueOfQualityOfService); System.Diagnostics.Debug.WriteLine("- Server DLMS version number is " + DLMSVersion); if (DLMSVersion != 6) { throw new GXDLMSException("Invalid DLMS version number."); } System.Diagnostics.Debug.WriteLine("- Number of unused bits is " + NumberOfUnusedBits); return Tags; }
///<summary> ///Constructor. ///</summary> public GXAPDU(GXDLMSTagCollection tags) { this.Authentication = Authentication.None; Tags = tags; }
/// <summary> /// Generate AARQ request. /// </summary> /// <param name="Tags">Reserved for future use.</param> /// <returns>AARQ request as byte array.</returns> /// <seealso cref="ParseAAREResponse"/> /// <seealso cref="IsDLMSPacketComplete"/> public byte[][] AARQRequest(GXDLMSTagCollection Tags) { List<byte> buff = new List<byte>(); m_Base.CheckInit(); GXAPDU aarq = new GXAPDU(Tags); aarq.UseLN = this.UseLogicalNameReferencing; if (this.UseLogicalNameReferencing) { m_Base.SNSettings = null; m_Base.LNSettings = new GXDLMSLNSettings(new byte[] { 0x00, 0x7E, 0x1F }); aarq.UserInformation.ConformanceBlock = LNSettings.m_ConformanceBlock; } else { m_Base.LNSettings = null; m_Base.SNSettings = new GXDLMSSNSettings(new byte[] { 0x1C, 0x03, 0x20 }); aarq.UserInformation.ConformanceBlock = SNSettings.m_ConformanceBlock; } aarq.UserInformation.DLMSVersioNumber = DLMSVersion; aarq.UserInformation.MaxReceivePDUSize = MaxReceivePDUSize; m_Base.StoCChallenge = null; if (Authentication > Authentication.Low)//If High Security Level { m_Base.CtoSChallenge = GXDLMS.GenerateChallenge(); aarq.SetAuthentication(this.Authentication, m_Base.CtoSChallenge); } else { m_Base.CtoSChallenge = null; aarq.SetAuthentication(this.Authentication, Password); } aarq.CodeData(buff, this.InterfaceType); m_Base.FrameSequence = -1; m_Base.ExpectedFrame = -1; m_Base.ReceiveSequenceNo = m_Base.SendSequenceNo = -1; return m_Base.SplitToBlocks(buff, Command.None, false, null); }