The services to access the attributes and methods of COSEM objects are determined on DLMS/COSEM Application layer. The services are carried by Application Protocol Data Units (APDUs).

In DLMS/COSEM the meter is primarily a server, and the controlling system is a client. Also unsolicited (received without a request) messages are available.

コード例 #1
0
 /// <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;
 }
コード例 #2
0
 /// <summary>
 /// Parse AARQ request that client send and returns AARE request.
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 byte[] HandleAARQRequest(byte[] data)
 {
     int index = 0, error;
     byte frame;            
     List<byte> arr = new List<byte>(data);
     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.");
     }
     GXAPDU aarq = new GXAPDU(null);
     aarq.UseLN = this.UseLogicalNameReferencing;
     int pos = 0;
     aarq.EncodeData(arr.ToArray(), ref pos);
     AssociationResult result = AssociationResult.Accepted;
     SourceDiagnostic diagnostic = SourceDiagnostic.None;
     m_Base.Authentication = aarq.Authentication;
     m_Base.CtoSChallenge = null;
     m_Base.StoCChallenge = null;
     if (aarq.Authentication >= Authentication.High)
     {
         m_Base.CtoSChallenge = aarq.Password;
     }
     if (this.UseLogicalNameReferencing != aarq.UseLN)
     {
         result = AssociationResult.PermanentRejected;
         diagnostic = SourceDiagnostic.ApplicationContextNameNotSupported;
     }
     else
     {
         GXAuthentication auth = null;
         foreach (GXAuthentication it in Authentications)
         {
             if (it.Type == aarq.Authentication)
             {
                 auth = it;
                 break;
             }
         }                
         if (auth == null)
         {
             result = AssociationResult.PermanentRejected;
             //If authentication is required.
             if (aarq.Authentication == Authentication.None)
             {
                 diagnostic = SourceDiagnostic.AuthenticationRequired;
             }
             else
             {
                 diagnostic = SourceDiagnostic.AuthenticationMechanismNameNotRecognised;
             }
         }
         //If authentication is used check pw.
         else if (aarq.Authentication != Authentication.None)
         {                    
             if (aarq.Authentication == Authentication.Low)
             {
                 //If Low authentication is used and pw don't match.
                 if (aarq.Password == null || string.Compare(auth.Password, ASCIIEncoding.ASCII.GetString(aarq.Password)) != 0)
                 {
                     result = AssociationResult.PermanentRejected;
                     diagnostic = SourceDiagnostic.AuthenticationFailure;
                 }
             }
             else //If High authentication is used.
             {
                 m_Base.StoCChallenge = GXDLMS.GenerateChallenge();
                 System.Diagnostics.Debug.WriteLine("StoC: " + BitConverter.ToString(m_Base.StoCChallenge));
                 result = AssociationResult.Accepted;
                 diagnostic = SourceDiagnostic.AuthenticationRequired;
             }
         }
     }
     //Generate AARE packet.
     List<byte> buff = new List<byte>();
     byte[] conformanceBlock;
     if (UseLogicalNameReferencing)
     {
         conformanceBlock = LNSettings.m_ConformanceBlock;
     }
     else
     {
         conformanceBlock = SNSettings.m_ConformanceBlock;
     }
     aarq.GenerateAARE(buff, aarq.Authentication, m_Base.StoCChallenge, MaxReceivePDUSize, conformanceBlock, result, diagnostic);
     if (this.InterfaceType == InterfaceType.General)
     {
         buff.InsertRange(0, Gurux.DLMS.Internal.GXCommon.LLCReplyBytes);
     }
     m_Base.ExpectedFrame = 0;
     m_Base.FrameSequence = -1;
     m_Base.ReceiveSequenceNo = 1;
     m_Base.SendSequenceNo = 0;            
     return m_Base.AddFrame(m_Base.GenerateIFrame(), false, buff, 0, buff.Count);
 }
コード例 #3
0
 /// <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);
 }
コード例 #4
0
ファイル: GXDLMSServer.cs プロジェクト: skycod/Gurux.DLMS.Net
 /// <summary>
 /// Parse AARQ request that cliend send and returns AARE request.
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 byte[] HandleAARQRequest(byte[] data)
 {
     int index = 0, error;
     byte frame;            
     List<byte> arr = new List<byte>(data);
     bool packetFull, wrongCrc;
     byte command;
     m_Base.GetDataFromFrame(arr, index, out frame, true, out error, false, out packetFull, out wrongCrc, out command);
     if (!packetFull)
     {
         throw new GXDLMSException("Not enought data to parse frame.");
     }
     if (wrongCrc)
     {
         throw new GXDLMSException("Wrong Checksum.");
     }
     GXAPDU aarq = new GXAPDU(null);
     aarq.UseLN = this.UseLogicalNameReferencing;
     int pos = 0;
     aarq.EncodeData(arr.ToArray(), ref pos);
     AssociationResult result = AssociationResult.Accepted;
     SourceDiagnostic diagnostic = SourceDiagnostic.None;
     if (this.UseLogicalNameReferencing != aarq.UseLN)
     {
         result = AssociationResult.PermanentRejected;
         diagnostic = SourceDiagnostic.ApplicationContextNameNotSupported;
     }
     else
     {
         GXAuthentication auth = null;
         foreach (GXAuthentication it in Authentications)
         {
             if (it.Type == aarq.Authentication)
             {
                 auth = it;
                 break;
             }
         }
         if (auth == null)
         {
             result = AssociationResult.PermanentRejected;
             //If authentication is required.
             if (aarq.Authentication == Authentication.None)
             {
                 diagnostic = SourceDiagnostic.AuthenticationRequired;
             }
             else
             {
                 diagnostic = SourceDiagnostic.AuthenticationMechanismNameNotRecognised;
             }
         }
         //If authentication is used check pw.
         else if (aarq.Authentication != Authentication.None && auth.Password != aarq.Password && string.IsNullOrEmpty(auth.Password) != string.IsNullOrEmpty((aarq.Password)))
         {
             result = AssociationResult.PermanentRejected;
             diagnostic = SourceDiagnostic.AuthenticationFailure;
         }
     }
     //Generate AARE packet.
     List<byte> buff = new List<byte>();
     byte[] conformanceBlock;
     if (UseLogicalNameReferencing)
     {
         conformanceBlock = LNSettings.m_ConformanceBlock;
     }
     else
     {
         conformanceBlock = SNSettings.m_ConformanceBlock;
     }
     aarq.GenerateAARE(buff, MaxReceivePDUSize, conformanceBlock, result, diagnostic);
     if (this.InterfaceType == InterfaceType.General)
     {
         buff.InsertRange(0, new byte[] { 0xE6, 0xE7, 0x00 });
     }
     m_Base.ExpectedFrame = 0;
     m_Base.FrameSequence = -1;            
     return m_Base.AddFrame(m_Base.GenerateIFrame(), false, buff, 0, buff.Count);
 }