コード例 #1
0
 /// <summary>
 /// Constructor for AARE error.
 /// </summary>
 internal GXDLMSException(AssociationResult result, AcseServiceProvider diagnostic)
     : base("Connection is " + GetResult(result) + ". " + GetDiagnostic(diagnostic))
 {
     Result     = result;
     Diagnostic = (byte)diagnostic;
     HelpLink   = "https://www.gurux.fi/Gurux.DLMS.ErrorCodes";
 }
コード例 #2
0
        ///<summary>
        ///Parse AARQ request that client send and returns AARE request.
        /// </summary>
        ///<returns>
        ///Reply to the client.
        ///</returns>
        private void HandleAarqRequest(GXByteBuffer data, GXDLMSConnectionEventArgs connectionInfo)
        {
            AssociationResult result = AssociationResult.Accepted;

            Settings.CtoSChallenge = null;
            if (!Settings.UseCustomChallenge)
            {
                Settings.StoCChallenge = null;
            }
            // Reset settings for wrapper.
            if (Settings.InterfaceType == InterfaceType.WRAPPER)
            {
                Reset(true);
            }
            SourceDiagnostic diagnostic = GXAPDU.ParsePDU(Settings, Settings.Cipher, data, null);

            if (diagnostic != SourceDiagnostic.None)
            {
                result     = AssociationResult.PermanentRejected;
                diagnostic = SourceDiagnostic.ApplicationContextNameNotSupported;
                InvalidConnection(connectionInfo);
            }
            else
            {
                diagnostic = ValidateAuthentication(Settings.Authentication, Settings.Password);
                if (diagnostic != SourceDiagnostic.None)
                {
                    result = AssociationResult.PermanentRejected;
                    InvalidConnection(connectionInfo);
                }
                else if (Settings.Authentication > Authentication.Low)
                {
                    // If High authentication is used.
                    if (!Settings.UseCustomChallenge)
                    {
                        Settings.StoCChallenge = GXSecure.GenerateChallenge(Settings.Authentication);
                    }
                    result     = AssociationResult.Accepted;
                    diagnostic = SourceDiagnostic.AuthenticationRequired;
                }
                else
                {
                    Connected(connectionInfo);
                    Settings.Connected = true;
                }
            }
            Settings.IsAuthenticationRequired = diagnostic == SourceDiagnostic.AuthenticationRequired;
            if (Settings.InterfaceType == Enums.InterfaceType.HDLC)
            {
                replyData.Set(GXCommon.LLCReplyBytes);
            }
            // Generate AARE packet.
            GXAPDU.GenerateAARE(Settings, replyData, result, diagnostic, Settings.Cipher, null);
        }
コード例 #3
0
 /// <summary>
 /// Get resulat as a string.
 /// </summary>
 /// <param name="result"></param>
 /// <returns></returns>
 static string GetResult(AssociationResult result)
 {
     if (result == AssociationResult.PermanentRejected)
     {
         return("permanently rejected");
     }
     if (result == AssociationResult.TransientRejected)
     {
         return("transient rejected");
     }
     throw new InvalidOperationException();
 }
コード例 #4
0
 /// <summary>
 /// Get resulat as a string.
 /// </summary>
 /// <param name="result"></param>
 /// <returns></returns>
 static string GetResult(AssociationResult result)
 {
     if (result == AssociationResult.PermanentRejected)
     {
         return "permanently rejected";
     }
     if (result == AssociationResult.TransientRejected)
     {
         return "transient rejected";
     }
     throw new InvalidOperationException();
 }
コード例 #5
0
ファイル: GXDLMSServer.cs プロジェクト: 01F0/Gurux.DLMS.Net
        ///<summary>
        ///Parse AARQ request that client send and returns AARE request.
        /// </summary>
        ///<returns>
        ///Reply to the client.
        ///</returns>
        private byte[][] HandleAarqRequest()
        {
            AssociationResult result = AssociationResult.Accepted;

            Settings.CtoSChallenge = null;
            if (!Settings.UseCustomChallenge)
            {
                Settings.StoCChallenge = null;
            }
            SourceDiagnostic diagnostic = GXAPDU.ParsePDU(Settings, Settings.Cipher, Reply.Data);

            if (diagnostic != SourceDiagnostic.None)
            {
                result     = AssociationResult.PermanentRejected;
                diagnostic = SourceDiagnostic.ApplicationContextNameNotSupported;
            }
            else
            {
                // Check that user can access server.
                diagnostic = ValidateAuthentication(Settings.Authentication, Settings.Password);
                if (diagnostic != SourceDiagnostic.None)
                {
                    result = AssociationResult.PermanentRejected;
                }
                else if (Settings.Authentication > Authentication.Low)
                {
                    // If High authentication is used.
                    Settings.StoCChallenge = GXSecure.GenerateChallenge(Settings.Authentication);
                    result     = AssociationResult.Accepted;
                    diagnostic = SourceDiagnostic.AuthenticationRequired;
                }
            }
            // Generate AARE packet.
            GXByteBuffer buff = new GXByteBuffer(150);

            GXAPDU.GenerateAARE(Settings, buff, result, diagnostic, Settings.Cipher);
            return(GXDLMS.SplitPdu(Settings, Command.Aare, 0, buff,
                                   ErrorCode.Ok, DateTime.MinValue)[0]);
        }
コード例 #6
0
 /// <summary>
 /// Constructor for AARE error.
 /// </summary>
 internal GXDLMSException(AssociationResult result, SourceDiagnostic diagnostic)
     : base("Connection is " + GetResult(result) + Environment.NewLine + GetDiagnostic(diagnostic))
 {
     Result     = result;
     Diagnostic = diagnostic;
 }
コード例 #7
0
ファイル: GXAPDU.cs プロジェクト: 01F0/Gurux.DLMS.Net
        ///<summary>
        ///Server generates AARE message.
        ///</summary>
        internal static void GenerateAARE(GXDLMSSettings settings, GXByteBuffer data,
                                          AssociationResult result, SourceDiagnostic diagnostic, GXICipher cipher)
        {
            int offset = data.Position;

            // Set AARE tag and length
            data.SetUInt8(((byte)BerType.Application | (byte)BerType.Constructed | (byte)PduType.ApplicationContextName)); //0x61
            // Length is updated later.
            data.SetUInt8(0);
            GenerateApplicationContextName(settings, data, cipher);
            //Result
            data.SetUInt8((byte)BerType.Context | (byte)BerType.Constructed | (byte)BerType.Integer); //0xA2
            data.SetUInt8(3);                                                                         //len
            data.SetUInt8(BerType.Integer);                                                           //Tag
            //Choice for result (INTEGER, universal)
            data.SetUInt8(1);                                                                         //Len
            data.SetUInt8((byte)result);                                                              //ResultValue
            //SourceDiagnostic
            data.SetUInt8(0xA3);
            data.SetUInt8(5);                //len
            data.SetUInt8(0xA1);             //Tag
            data.SetUInt8(3);                //len
            data.SetUInt8(2);                //Tag
            //Choice for result (INTEGER, universal)
            data.SetUInt8(1);                //Len
            data.SetUInt8((byte)diagnostic); //diagnostic

            //SystemTitle
            if (cipher != null && (cipher.IsCiphered() || settings.Authentication == Authentication.HighGMAC))
            {
                data.SetUInt8((byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledApInvocationId);
                data.SetUInt8((byte)(2 + cipher.SystemTitle.Length));
                data.SetUInt8((byte)BerType.OctetString);
                data.SetUInt8((byte)cipher.SystemTitle.Length);
                data.Set(cipher.SystemTitle);
            }

            if (result != AssociationResult.PermanentRejected && diagnostic == SourceDiagnostic.AuthenticationRequired)
            {
                //Add server ACSE-requirenents field component.
                data.SetUInt8(0x88);
                data.SetUInt8(0x02);  //Len.
                data.SetUInt16(0x0780);
                //Add tag.
                data.SetUInt8(0x89);
                data.SetUInt8(0x07);//Len
                data.SetUInt8(0x60);
                data.SetUInt8(0x85);
                data.SetUInt8(0x74);
                data.SetUInt8(0x05);
                data.SetUInt8(0x08);
                data.SetUInt8(0x02);
                data.SetUInt8((byte)settings.Authentication);
                //Add tag.
                data.SetUInt8(0xAA);
                data.SetUInt8((byte)(2 + settings.StoCChallenge.Length));//Len
                data.SetUInt8((byte)BerType.Context);
                data.SetUInt8((byte)settings.StoCChallenge.Length);
                data.Set(settings.StoCChallenge);
            }
            //Add User Information
            //Tag 0xBE
            data.SetUInt8((byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.UserInformation);
            byte[] tmp = GetUserInformation(settings, cipher);
            data.SetUInt8((byte)(2 + tmp.Length));
            //Coding the choice for user-information (Octet STRING, universal)
            data.SetUInt8(BerType.OctetString);
            //Length
            data.SetUInt8((byte)tmp.Length);
            data.Set(tmp);
            data.SetUInt8((UInt16)(offset + 1), (byte)(data.Size - offset - 2));
        }
コード例 #8
0
ファイル: GXAPDU.cs プロジェクト: 01F0/Gurux.DLMS.Net
        ///<summary>
        ///Parse APDU.
        ///</summary>
        static internal SourceDiagnostic ParsePDU(GXDLMSSettings settings, GXICipher cipher, GXByteBuffer buff)
        {
            // Get AARE tag and length
            int tag = buff.GetUInt8();

            if (settings.IsServer)
            {
                if (tag != ((byte)BerType.Application | (byte)BerType.Constructed | (byte)PduType.ProtocolVersion))
                {
                    throw new Exception("Invalid tag.");
                }
            }
            else
            {
                if (tag != ((byte)BerType.Application | (byte)BerType.Constructed | (byte)PduType.ApplicationContextName))
                {
                    throw new Exception("Invalid tag.");
                }
            }
            int len  = buff.GetUInt8();
            int size = buff.Size - buff.Position;

            if (len > size)
            {
                throw new Exception("Not enough data.");
            }
            AssociationResult resultComponent       = AssociationResult.Accepted;
            SourceDiagnostic  resultDiagnosticValue = SourceDiagnostic.None;

            while (buff.Position < buff.Size)
            {
                tag = buff.GetUInt8();
                switch (tag)
                {
                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.ApplicationContextName:    //0xA1
                    if (!ParseApplicationContextName(settings, buff))
                    {
                        throw new GXDLMSException(AssociationResult.PermanentRejected, SourceDiagnostic.ApplicationContextNameNotSupported);
                    }
                    break;

                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledApTitle:    ////Result 0xA2
                    //Get len.
                    if (buff.GetUInt8() != 3)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    //Choice for result (INTEGER, universal)
                    if (buff.GetUInt8() != (byte)BerType.Integer)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    //Get len.
                    if (buff.GetUInt8() != 1)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    resultComponent = (AssociationResult)buff.GetUInt8();
                    break;

                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledAeQualifier:    ////SourceDiagnostic 0xA3
                    len = buff.GetUInt8();
                    // ACSE service user tag.
                    tag = buff.GetUInt8();
                    len = buff.GetUInt8();
                    // Result source diagnostic component.
                    if (buff.GetUInt8() != (byte)BerType.Integer)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 1)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    resultDiagnosticValue = (SourceDiagnostic)buff.GetUInt8();
                    break;

                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledApInvocationId:    ////Result 0xA4
                    //Get len.
                    if (buff.GetUInt8() != 0xA)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    //Choice for result (Universal, Octetstring type)
                    if (buff.GetUInt8() != (byte)BerType.OctetString)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    //responding-AP-title-field
                    //Get len.
                    len = buff.GetUInt8();
                    settings.SourceSystemTitle = new byte[len];
                    buff.Get(settings.SourceSystemTitle);
                    break;

                //Client Challenge.
                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CallingApTitle:    //0xA6
                    len = buff.GetUInt8();
                    tag = buff.GetUInt8();
                    len = buff.GetUInt8();
                    settings.SourceSystemTitle = new byte[len];
                    buff.Get(settings.SourceSystemTitle);
                    break;

                //Server Challenge.
                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.SenderAcseRequirements:    //0xAA
                    len = buff.GetUInt8();
                    tag = buff.GetUInt8();
                    len = buff.GetUInt8();
                    settings.StoCChallenge = new byte[len];
                    buff.Get(settings.StoCChallenge);
                    break;

                case (byte)BerType.Context | (byte)PduType.SenderAcseRequirements:   //0x8A
                case (byte)BerType.Context | (byte)PduType.CallingApInvocationId:    //0x88
                    //Get sender ACSE-requirements field component.
                    if (buff.GetUInt8() != 2)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != (byte)BerType.ObjectDescriptor)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 0x80)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    break;

                case (byte)BerType.Context | (byte)PduType.MechanismName:         //0x8B
                case (byte)BerType.Context | (byte)PduType.CallingAeInvocationId: //0x89
                    len = buff.GetUInt8();
                    if (buff.GetUInt8() != 0x60)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 0x85)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 0x74)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 0x05)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 0x08)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff.GetUInt8() != 0x02)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    int tmp = buff.GetUInt8();
                    if (tmp < 0 || tmp > 5)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    settings.Authentication = (Authentication)tmp;
                    break;

                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CallingAuthenticationValue:    //0xAC
                    len = buff.GetUInt8();
                    // Get authentication information.
                    if (buff.GetUInt8() != 0x80)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    len = buff.GetUInt8();
                    if (settings.Authentication < Authentication.HighMD5)
                    {
                        settings.Password = new byte[len];
                        buff.Get(settings.Password);
                    }
                    else
                    {
                        settings.CtoSChallenge = new byte[len];
                        buff.Get(settings.CtoSChallenge);
                    }
                    break;

                case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.UserInformation:    //0xBE
                    if (resultComponent != AssociationResult.Accepted && resultDiagnosticValue != SourceDiagnostic.None)
                    {
                        throw new GXDLMSException(resultComponent, resultDiagnosticValue);
                    }
                    ParseUserInformation(settings, cipher, buff);
                    break;

                default:
                    //Unknown tags.
                    System.Diagnostics.Debug.WriteLine("Unknown tag: " + tag + ".");
                    len            = buff.GetUInt8();
                    buff.Position += (UInt16)len;
                    break;
                }
            }
            return(resultDiagnosticValue);
        }
コード例 #9
0
ファイル: GXAPDU.cs プロジェクト: jacea/Gurux.DLMS.Net
 ///<summary>
 ///Server generates AARE message.
 ///</summary>
 internal void GenerateAARE(List<byte> data, Authentication authentication, byte[] challenge, ushort maxReceivePDUSize, byte[] conformanceBlock, AssociationResult result, SourceDiagnostic diagnostic)
 {
     // Set AARE tag and length
     data.Add(0x61);
     ApplicationContextName.CodeData(data);
     //Result
     data.Add(0xA2);
     data.Add(3); //len
     data.Add(2); //Tag
     //Choice for result (INTEGER, universal)
     data.Add(1); //Len
     data.Add((byte) result); //ResultValue            
     //SourceDiagnostic
     data.Add(0xA3);
     data.Add(5); //len
     data.Add(0xA1); //Tag
     data.Add(3); //len
     data.Add(2); //Tag
     //Choice for result (INTEGER, universal)
     data.Add(1); //Len
     data.Add((byte)diagnostic); //diagnostic            
     if (diagnostic == SourceDiagnostic.AuthenticationRequired)
     {                
         //Add server ACSE-requirenents field component.
         data.Add(0x88);
         data.Add(0x02);  //Len.
         GXCommon.SetUInt16(0x0780, data);
         //Add tag.
         data.Add(0x89);
         data.Add(0x07);//Len
         data.Add(0x60);
         data.Add(0x85);
         data.Add(0x74);
         data.Add(0x05);
         data.Add(0x08);
         data.Add(0x02);
         data.Add((byte) authentication);
         //Add tag.
         data.Add(0xAA);
         data.Add((byte) (2 + challenge.Length));//Len
         data.Add(0x80);
         data.Add((byte) challenge.Length);
         data.AddRange(challenge);
     }            
     //Add User Information
     data.Add(0xBE); //Tag
     data.Add(0x10); //Length for AARQ user field
     data.Add(0x04); //Coding the choice for user-information (Octet STRING, universal)
     data.Add(0xE); //Length
     data.Add(GXCommon.InitialResponce); // Tag for xDLMS-Initiate response
     data.Add(0x00); // Usage field for the response allowed component (not used)
     data.Add(6); // DLMSVersioNumber
     data.Add(0x5F);
     data.Add(0x1F);
     data.Add(0x04);// length of the conformance block
     data.Add(0x00);// encoding the number of unused bits in the bit string            
     data.AddRange(conformanceBlock);
     GXCommon.SetUInt16(maxReceivePDUSize, data);
     //VAA Name VAA name (0x0007 for LN referencing and 0xFA00 for SN)
     if (UseLN)
     {
         GXCommon.SetUInt16(0x0007, data);
     }
     else
     {
         GXCommon.SetUInt16(0xFA00, data);
     }            
     data.Insert(1, (byte) (data.Count - 1));
 }
コード例 #10
0
ファイル: GXAPDU.cs プロジェクト: jacea/Gurux.DLMS.Net
 ///<summary>
 ///EncodeData
 ///</summary>
 internal void EncodeData(byte[] buff, ref int index)
 {
     // Get AARE tag and length
     int tag = buff[index++];
     if (tag != 0x61 && tag != 0x60 && tag != 0x81 && tag != 0x80)
     {
         throw new Exception("Invalid tag.");
     }
     int len = buff[index++];
     int size = buff.Length - index;
     if (len > size)
     {
         throw new Exception("Not enought data.");
     }
     while (index < buff.Length)
     {
         tag = buff[index];
         if (tag == 0xA1)
         {
             ApplicationContextName.EncodeData(buff, ref index);
         }
         else if (tag == 0xBE)
         {
             if (ResultValue != AssociationResult.Accepted && ResultDiagnosticValue != SourceDiagnostic.None)
             {
                 return;
             }
             UserInformation.EncodeData(buff, ref index);
         }
         else if (tag == 0xA2) //Result
         {
             tag = buff[index++];
             len = buff[index++];
             //Choice for result (INTEGER, universal)
             tag = buff[index++];
             len = buff[index++];
             ResultValue = (AssociationResult)buff[index++];
         }
         else if (tag == 0xA3) //SourceDiagnostic
         {
             tag = buff[index++];
             len = buff[index++];
             // ACSE service user tag.
             tag = buff[index++];
             len = buff[index++];
             // Result source diagnostic component.
             tag = buff[index++];
             len = buff[index++];
             ResultDiagnosticValue = (SourceDiagnostic)buff[index++];
         }
         else if (tag == 0x8A || tag == 0x88) //Authentication.
         {
             tag = buff[index++];
             //Get sender ACSE-requirenents field component.
             if (buff[index++] != 2)
             {
                 throw new Exception("Invalid tag.");
             }
             int val = GXCommon.GetUInt16(buff, ref index);
             if (val != 0x0780 && val != 0x0680)
             {
                 throw new Exception("Invalid tag.");
             }
         }               
         else if (tag == 0xAA) //Server Challenge.                
         {
             tag = buff[index++];
             len = buff[index++];
             ++index;
             len = buff[index++];
             //Get challenge
             index += len;
         }
         else if (tag == 0x8B || tag == 0x89) //Authentication.
         {
             tag = buff[index++];
             len = buff[index++];
             bool IsAuthenticationTag = len > 7;
             if (buff[index++] != 0x60)
             {
                 throw new Exception("Invalid tag.");
             }
             if (buff[index++] != 0x85)
             {
                 throw new Exception("Invalid tag.");
             }
             if (buff[index++] != 0x74)
             {
                 throw new Exception("Invalid tag.");
             }
             if (buff[index++] != 0x05)
             {
                 throw new Exception("Invalid tag.");
             }
             if (buff[index++] != 0x08)
             {
                 throw new Exception("Invalid tag.");
             }
             if (buff[index++] != 0x02)
             {
                 throw new Exception("Invalid tag.");
             }
             int tmp = buff[index++];
             if (tmp < 0 || tmp > 5)
             {
                 throw new Exception("Invalid tag.");
             }
             if (IsAuthenticationTag)
             {
                 Authentication = (Authentication)tmp;
                 byte tag2 = buff[index++];
                 if (tag2 != 0xAC && tag2 != 0xAA)
                 {
                     throw new Exception("Invalid tag.");
                 }
                 len = buff[index++];
                 //Get authentication information.
                 if (buff[index++] != 0x80)
                 {
                     throw new Exception("Invalid tag.");
                 }
                 len = buff[index++];
                 Password = new byte[len];
                 Array.Copy(buff, index, Password, 0, len);
                 index += len;
             }
             else
             {
                 Authentication = Authentication.None;
             }
         }
         //Unknown tags.
         else
         {
             tag = buff[index++];
             len = buff[index++];
             if (Tags != null)
             {
                 GXDLMSTag tmp = new GXDLMSTag();
                 tmp.ID = tag;
                 tmp.Data = new byte[len];
                 tmp.Data = GXCommon.Swap(buff, index, len);
                 Tags.Add(tmp);
             }
             index += len;
         }
     }
 }       
コード例 #11
0
ファイル: GXAPDU.cs プロジェクト: Gurux/Gurux.DLMS.Net
        ///<summary>
        ///Server generates AARE message.
        ///</summary>
        internal static void GenerateAARE(GXDLMSSettings settings, GXByteBuffer data,
                                          AssociationResult result, SourceDiagnostic diagnostic, GXICipher cipher,
                                          GXByteBuffer encryptedData)
        {
            int offset = data.Size;
            // Set AARE tag and length
            data.SetUInt8(((byte)BerType.Application | (byte)BerType.Constructed | (byte)PduType.ApplicationContextName)); //0x61
                                                                                                                           // Length is updated later.
            data.SetUInt8(0);
            GenerateApplicationContextName(settings, data, cipher);
            //Result
            data.SetUInt8((byte)BerType.Context | (byte)BerType.Constructed | (byte)BerType.Integer);//0xA2
            data.SetUInt8(3); //len
            data.SetUInt8(BerType.Integer); //Tag
                                            //Choice for result (INTEGER, universal)
            data.SetUInt8(1); //Len
            data.SetUInt8((byte)result); //ResultValue
                                         //SourceDiagnostic
            data.SetUInt8(0xA3);
            data.SetUInt8(5); //len
            data.SetUInt8(0xA1); //Tag
            data.SetUInt8(3); //len
            data.SetUInt8(2); //Tag
                              //Choice for result (INTEGER, universal)
            data.SetUInt8(1); //Len
            data.SetUInt8((byte)diagnostic); //diagnostic

            //SystemTitle
            if (cipher != null && (cipher.IsCiphered() || settings.Authentication == Authentication.HighGMAC))
            {
                data.SetUInt8((byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledApInvocationId);
                data.SetUInt8((byte)(2 + cipher.SystemTitle.Length));
                data.SetUInt8((byte)BerType.OctetString);
                data.SetUInt8((byte)cipher.SystemTitle.Length);
                data.Set(cipher.SystemTitle);
            }

            if (result != AssociationResult.PermanentRejected && diagnostic == SourceDiagnostic.AuthenticationRequired)
            {
                //Add server ACSE-requirenents field component.
                data.SetUInt8(0x88);
                data.SetUInt8(0x02);  //Len.
                data.SetUInt16(0x0780);
                //Add tag.
                data.SetUInt8(0x89);
                data.SetUInt8(0x07);//Len
                data.SetUInt8(0x60);
                data.SetUInt8(0x85);
                data.SetUInt8(0x74);
                data.SetUInt8(0x05);
                data.SetUInt8(0x08);
                data.SetUInt8(0x02);
                data.SetUInt8((byte)settings.Authentication);
                //Add tag.
                data.SetUInt8(0xAA);
                data.SetUInt8((byte)(2 + settings.StoCChallenge.Length));//Len
                data.SetUInt8((byte)BerType.Context);
                data.SetUInt8((byte)settings.StoCChallenge.Length);
                data.Set(settings.StoCChallenge);
            }
            byte[] tmp;
            //Add User Information
            //Tag 0xBE
            data.SetUInt8((byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.UserInformation);
            if (encryptedData != null && encryptedData.Size != 0)
            {
                GXByteBuffer tmp2 = new GXByteBuffer((UInt16)(2 + encryptedData.Size));
                tmp2.SetUInt8((byte)Command.GloInitiateResponse);
                GXCommon.SetObjectCount(encryptedData.Size, tmp2);
                tmp2.Set(encryptedData);
                tmp = tmp2.Array();
            }
            else
            {
                tmp = GetUserInformation(settings, cipher);
            }
            data.SetUInt8((byte)(2 + tmp.Length));
            //Coding the choice for user-information (Octet STRING, universal)
            data.SetUInt8(BerType.OctetString);
            //Length
            data.SetUInt8((byte)tmp.Length);
            data.Set(tmp);
            data.SetUInt8((UInt16)(offset + 1), (byte)(data.Size - offset - 2));
        }
コード例 #12
0
 /// <summary>
 /// Constructor for AARE error.
 /// </summary>
 internal GXDLMSException(AssociationResult result, SourceDiagnostic diagnostic)
     : base("Connection is " + GetResult(result) + ". " + GetDiagnostic(diagnostic))
 {
     Result     = result;
     Diagnostic = (byte)diagnostic;
 }
コード例 #13
0
 /// <summary>
 /// Constructor for AARE error.
 /// </summary>
 internal GXDLMSException(AssociationResult result, AcseServiceProvider diagnostic)
     : base("Connection is " + GetResult(result) + ". " + GetDiagnostic(diagnostic))
 {
     Result     = result;
     Diagnostic = (byte)diagnostic;
 }
コード例 #14
0
 ///<summary>
 ///Server generates AARE message.
 ///</summary>
 internal void GenerateAARE(List <byte> data, Authentication authentication, byte[] challenge, ushort maxReceivePDUSize, byte[] conformanceBlock, AssociationResult result, SourceDiagnostic diagnostic)
 {
     // Set AARE tag and length
     data.Add(0x61);
     ApplicationContextName.CodeData(data);
     //Result
     data.Add(0xA2);
     data.Add(3);            //len
     data.Add(2);            //Tag
     //Choice for result (INTEGER, universal)
     data.Add(1);            //Len
     data.Add((byte)result); //ResultValue
     //SourceDiagnostic
     data.Add(0xA3);
     data.Add(5);                //len
     data.Add(0xA1);             //Tag
     data.Add(3);                //len
     data.Add(2);                //Tag
     //Choice for result (INTEGER, universal)
     data.Add(1);                //Len
     data.Add((byte)diagnostic); //diagnostic
     if (diagnostic == SourceDiagnostic.AuthenticationRequired)
     {
         //Add server ACSE-requirenents field component.
         data.Add(0x88);
         data.Add(0x02);  //Len.
         GXCommon.SetUInt16(0x0780, data);
         //Add tag.
         data.Add(0x89);
         data.Add(0x07);//Len
         data.Add(0x60);
         data.Add(0x85);
         data.Add(0x74);
         data.Add(0x05);
         data.Add(0x08);
         data.Add(0x02);
         data.Add((byte)authentication);
         //Add tag.
         data.Add(0xAA);
         data.Add((byte)(2 + challenge.Length)); //Len
         data.Add(0x80);
         data.Add((byte)challenge.Length);
         data.AddRange(challenge);
     }
     //Add User Information
     data.Add(0xBE);                     //Tag
     data.Add(0x10);                     //Length for AARQ user field
     data.Add(0x04);                     //Coding the choice for user-information (Octet STRING, universal)
     data.Add(0xE);                      //Length
     data.Add(GXCommon.InitialResponce); // Tag for xDLMS-Initiate response
     data.Add(0x00);                     // Usage field for the response allowed component (not used)
     data.Add(6);                        // DLMSVersioNumber
     data.Add(0x5F);
     data.Add(0x1F);
     data.Add(0x04); // length of the conformance block
     data.Add(0x00); // encoding the number of unused bits in the bit string
     data.AddRange(conformanceBlock);
     GXCommon.SetUInt16(maxReceivePDUSize, data);
     //VAA Name VAA name (0x0007 for LN referencing and 0xFA00 for SN)
     if (UseLN)
     {
         GXCommon.SetUInt16(0x0007, data);
     }
     else
     {
         GXCommon.SetUInt16(0xFA00, data);
     }
     data.Insert(1, (byte)(data.Count - 1));
 }
コード例 #15
0
        ///<summary>
        ///EncodeData
        ///</summary>
        internal void EncodeData(byte[] buff, ref int index)
        {
            // Get AARE tag and length
            int tag = buff[index++];

            if (tag != 0x61 && tag != 0x60 && tag != 0x81 && tag != 0x80)
            {
                throw new Exception("Invalid tag.");
            }
            int len  = buff[index++];
            int size = buff.Length - index;

            if (len > size)
            {
                throw new Exception("Not enough data.");
            }
            while (index < buff.Length)
            {
                tag = buff[index];
                if (tag == 0xA1)
                {
                    ApplicationContextName.EncodeData(buff, ref index);
                }
                else if (tag == 0xBE)
                {
                    if (ResultValue != AssociationResult.Accepted && ResultDiagnosticValue != SourceDiagnostic.None)
                    {
                        return;
                    }
                    UserInformation.EncodeData(buff, ref index);
                }
                else if (tag == 0xA2) //Result
                {
                    tag = buff[index++];
                    len = buff[index++];
                    //Choice for result (INTEGER, universal)
                    tag         = buff[index++];
                    len         = buff[index++];
                    ResultValue = (AssociationResult)buff[index++];
                }
                else if (tag == 0xA3) //SourceDiagnostic
                {
                    tag = buff[index++];
                    len = buff[index++];
                    // ACSE service user tag.
                    tag = buff[index++];
                    len = buff[index++];
                    // Result source diagnostic component.
                    tag = buff[index++];
                    len = buff[index++];
                    ResultDiagnosticValue = (SourceDiagnostic)buff[index++];
                }
                else if (tag == 0x8A || tag == 0x88) //Authentication.
                {
                    tag = buff[index++];
                    //Get sender ACSE-requirements field component.
                    if (buff[index++] != 2)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    int val = GXCommon.GetUInt16(buff, ref index);
                    if (val != 0x0780 && val != 0x0680)
                    {
                        throw new Exception("Invalid tag.");
                    }
                }
                else if (tag == 0xAA) //Server Challenge.
                {
                    tag = buff[index++];
                    len = buff[index++];
                    ++index;
                    len = buff[index++];
                    //Get challenge and save it to the PW.
                    Password = new byte[len];
                    Array.Copy(buff, index, Password, 0, len);
                    index += len;
                }
                else if (tag == 0xAC) //Password.
                {
                    tag = buff[index++];
                    len = buff[index++];
                    //Get authentication information.
                    if (buff[index++] != 0x80)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    len = buff[index++];
                    //Get password.
                    Password = new byte[len];
                    Array.Copy(buff, index, Password, 0, len);
                    index += len;
                }
                else if (tag == 0x8B || tag == 0x89) //Authentication.
                {
                    tag = buff[index++];
                    len = buff[index++];
                    if (buff[index++] != 0x60)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff[index++] != 0x85)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff[index++] != 0x74)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff[index++] != 0x05)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff[index++] != 0x08)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    if (buff[index++] != 0x02)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    int tmp = buff[index++];
                    if (tmp < 0 || tmp > 5)
                    {
                        throw new Exception("Invalid tag.");
                    }
                    Authentication = (Authentication)tmp;
                }
                //Unknown tags.
                else
                {
                    tag = buff[index++];
                    len = buff[index++];
                    if (Tags != null)
                    {
                        GXDLMSTag tmp = new GXDLMSTag();
                        tmp.ID   = tag;
                        tmp.Data = new byte[len];
                        tmp.Data = GXCommon.Swap(buff, index, len);
                        Tags.Add(tmp);
                    }
                    index += len;
                }
            }
        }
コード例 #16
0
 /// <summary>
 /// Constructor for AARE error.
 /// </summary>
 internal GXDLMSException(AssociationResult result, SourceDiagnostic diagnostic)
     : base("Connection is " + GetResult(result) + ". " + GetDiagnostic(diagnostic))
 {
     Result = result;
     Diagnostic = diagnostic;
 }