Ejemplo n.º 1
0
        private static void updatePassword(GXDLMSSettings settings, GXByteBuffer buff, GXDLMSTranslatorStructure xml)
        {
            int len = buff.GetUInt8();
            // Get authentication information.
            if (buff.GetUInt8() != 0x80)
            {
                throw new Exception("Invalid tag.");
            }
            len = buff.GetUInt8();
            if (settings.Authentication == Authentication.Low)
            {
                settings.Password = new byte[len];
                buff.Get(settings.Password);
            }
            else
            {
                settings.CtoSChallenge = new byte[len];
                buff.Get(settings.CtoSChallenge);
            }

            if (xml != null)
            {
                if (xml.OutputType == TranslatorOutputType.SimpleXml)
                {
                    if (settings.Authentication == Authentication.Low)
                    {
                        xml.AppendLine(TranslatorGeneralTags.CallingAuthentication,
                                       "Value",
                                       GXCommon.ToHex(settings.Password, false));
                    }
                    else
                    {
                        xml.AppendLine(TranslatorGeneralTags.CallingAuthentication,
                                       "Value",
                                       GXCommon.ToHex(settings.CtoSChallenge, false));
                    }
                }
                else
                {
                    xml.AppendStartTag(
                        TranslatorGeneralTags.CallingAuthentication);
                    xml.AppendStartTag(TranslatorGeneralTags.CharString);
                    if (settings.Authentication == Authentication.Low)
                    {
                        xml.Append(GXCommon.ToHex(settings.Password, false));
                    }
                    else
                    {
                        xml.Append(
                            GXCommon.ToHex(settings.CtoSChallenge, false));
                    }
                    xml.AppendEndTag(TranslatorGeneralTags.CharString);
                    xml.AppendEndTag(TranslatorGeneralTags.CallingAuthentication);
                }
            }
        }
Ejemplo n.º 2
0
        ///<summary>
        ///Parse APDU.
        ///</summary>
        static internal SourceDiagnostic ParsePDU(GXDLMSSettings settings, GXICipher cipher,
                GXByteBuffer buff, GXDLMSTranslatorStructure xml)
        {
            // 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.");
            }
            //Opening tags
            if (xml != null)
            {
                if (settings.IsServer)
                {
                    xml.AppendStartTag(Command.Aarq);
                }
                else
                {
                    xml.AppendStartTag(Command.Aare);
                }
            }
            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, xml))
                        {
                            throw new GXDLMSException(AssociationResult.PermanentRejected, SourceDiagnostic.ApplicationContextNameNotSupported);
                        }
                        break;
                    case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CalledApTitle://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();
                        if (xml != null)
                        {
                            xml.AppendLine(TranslatorGeneralTags.AssociationResult, "Value", xml.IntegerToHex((int)resultComponent, 2));
                            xml.AppendStartTag(TranslatorGeneralTags.ResultSourceDiagnostic);
                        }
                        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();
                        if (xml != null)
                        {
                            xml.AppendLine(TranslatorGeneralTags.ACSEServiceUser, "Value", xml.IntegerToHex((int)resultDiagnosticValue, 2));
                            xml.AppendEndTag(TranslatorGeneralTags.ResultSourceDiagnostic);
                        }
                        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);
                        if (xml != null)
                        {
                            //RespondingAPTitle
                            xml.AppendLine(TranslatorGeneralTags.RespondingAPTitle, "Value", GXCommon.ToHex(settings.SourceSystemTitle, false));
                        }
                        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);
                        if (xml != null)
                        {
                            //CallingAPTitle
                            xml.AppendLine(TranslatorGeneralTags.CallingAPTitle, "Value", GXCommon.ToHex(settings.SourceSystemTitle, false));
                        }
                        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);
                        AppendServerSystemTitleToXml(settings, xml, tag);
                        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.");
                        }
                        //SenderACSERequirements
                        if (xml != null)
                        {
                            xml.AppendLine(tag, "Value", "1");
                        }
                        break;
                    case (byte)BerType.Context | (byte)PduType.MechanismName://0x8B
                    case (byte)BerType.Context | (byte)PduType.CallingAeInvocationId://0x89
                        UpdateAuthentication(settings, buff);
                        if (xml != null)
                        {
                            if (xml.OutputType == TranslatorOutputType.SimpleXml)
                            {
                                xml.AppendLine(tag, "Value", settings.Authentication.ToString());
                            }
                            else
                            {
                                xml.AppendLine(tag, "Value", ((int)settings.Authentication).ToString());
                            }
                        }
                        break;
                    case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CallingAuthenticationValue://0xAC
                        updatePassword(settings, buff, xml);
                        break;
                    case (byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.UserInformation:
                        //0xBE
                        if (xml == null && resultComponent != AssociationResult.Accepted && resultDiagnosticValue != SourceDiagnostic.None)
                        {
                            throw new GXDLMSException(resultComponent, resultDiagnosticValue);
                        }
                        ParseUserInformation(settings, cipher, buff, xml);
                        break;
                    default:
                        //Unknown tags.
                        System.Diagnostics.Debug.WriteLine("Unknown tag: " + tag + ".");
                        if (buff.Position < buff.Size)
                        {
                            len = buff.GetUInt8();
                            buff.Position += (UInt16)len;
                        }
                        break;
                }
            }
            //Closing tags
            if (xml != null)
            {
                if (settings.IsServer)
                {
                    xml.AppendEndTag(Command.Aarq);
                }
                else
                {
                    xml.AppendEndTag(Command.Aare);
                }
            }
            return resultDiagnosticValue;
        }
Ejemplo n.º 3
0
 private static void AppendServerSystemTitleToXml(
     GXDLMSSettings settings, GXDLMSTranslatorStructure xml,
     int tag)
 {
     if (xml != null)
     {
         // RespondingAuthentication
         if (xml.OutputType == TranslatorOutputType.SimpleXml)
         {
             xml.AppendLine(tag, "Value", GXCommon.ToHex(settings.StoCChallenge, false));
         }
         else
         {
             xml.Append(tag, true);
             xml.Append((int)TranslatorGeneralTags.CharString, true);
             xml.Append(GXCommon.ToHex(settings.StoCChallenge, false));
             xml.Append((int)TranslatorGeneralTags.CharString, false);
             xml.Append(tag, false);
             xml.Append("\r\n");
         }
     }
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Parse application context name.
 /// </summary>
 /// <param name="settings">DLMS settings.</param>
 /// <param name="buff">Received data.</param>
 private static bool ParseApplicationContextName(GXDLMSSettings settings, GXByteBuffer buff, GXDLMSTranslatorStructure xml)
 {
     //Get length.
     int len = buff.GetUInt8();
     if (buff.Size - buff.Position < len)
     {
         throw new Exception("Encoding failed. Not enough data.");
     }
     if (buff.GetUInt8() != 0x6)
     {
         throw new Exception("Encoding failed. Not an Object ID.");
     }
     if (settings.IsServer && settings.Cipher != null)
     {
         settings.Cipher.Security = Gurux.DLMS.Enums.Security.None;
     }
     //Object ID length.
     len = buff.GetUInt8();
     if (xml != null)
     {
         if (buff.Compare(GXCommon.LogicalNameObjectID))
         {
             if (xml.OutputType == TranslatorOutputType.SimpleXml)
             {
                 xml.AppendLine(TranslatorGeneralTags.ApplicationContextName,
                                "Value", "LN");
             }
             else
             {
                 xml.AppendLine(
                     TranslatorGeneralTags.ApplicationContextName,
                     null, "1");
             }
             settings.UseLogicalNameReferencing = true;
         }
         else if (buff.Compare(GXCommon.LogicalNameObjectIdWithCiphering))
         {
             if (xml.OutputType == TranslatorOutputType.SimpleXml)
             {
                 xml.AppendLine(TranslatorGeneralTags.ApplicationContextName,
                                "Value", "LN_WITH_CIPHERING");
             }
             else
             {
                 xml.AppendLine(
                     TranslatorGeneralTags.ApplicationContextName,
                     null, "3");
             }
             settings.UseLogicalNameReferencing = true;
         }
         else if (buff.Compare(GXCommon.ShortNameObjectID))
         {
             if (xml.OutputType == TranslatorOutputType.SimpleXml)
             {
                 xml.AppendLine(TranslatorGeneralTags.ApplicationContextName,
                                "Value", "SN");
             }
             else
             {
                 xml.AppendLine(
                     TranslatorGeneralTags.ApplicationContextName,
                     null, "2");
             }
             settings.UseLogicalNameReferencing = false;
         }
         else if (buff.Compare(GXCommon.ShortNameObjectIdWithCiphering))
         {
             if (xml.OutputType == TranslatorOutputType.SimpleXml)
             {
                 xml.AppendLine(TranslatorGeneralTags.ApplicationContextName,
                                "Value", "SN_WITH_CIPHERING");
             }
             else
             {
                 xml.AppendLine(
                     TranslatorGeneralTags.ApplicationContextName,
                     null, "4");
             }
             settings.UseLogicalNameReferencing = false;
         }
         else
         {
             return false;
         }
         return true;
     }
     if (settings.UseLogicalNameReferencing)
     {
         if (buff.Compare(GXCommon.LogicalNameObjectID))
         {
             return true;
         }
         // If ciphering is used.
         return buff.Compare(GXCommon.LogicalNameObjectIdWithCiphering);
     }
     if (buff.Compare(GXCommon.ShortNameObjectID))
     {
         return true;
     }
     // If ciphering is used.
     return buff.Compare(GXCommon.ShortNameObjectIdWithCiphering);
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Parse User Information from PDU.
        /// </summary>
        public static void ParseUserInformation(GXDLMSSettings settings, GXICipher cipher, GXByteBuffer data, GXDLMSTranslatorStructure xml)
        {
            byte len = data.GetUInt8();
            GXByteBuffer tmp2 = new GXByteBuffer();
            tmp2.SetUInt8(0);
            if (data.Size - data.Position < len)
            {
                throw new Exception("Not enough data.");
            }
            if (xml != null && xml.OutputType == TranslatorOutputType.StandardXml)
            {
                len = (byte)(data.Size - data.Position);
                xml.AppendLine(Command.InitiateRequest, null, GXCommon
                               .ToHex(data.Data, false, data.Position, len));
                data.Position = data.Position + len;
                return;
            }
            //Excoding the choice for user information
            int tag = data.GetUInt8();
            if (tag != 0x4)
            {
                throw new Exception("Invalid tag.");
            }
            len = data.GetUInt8();
            //Tag for xDLMS-Initate.response
            tag = data.GetUInt8();
            if (tag == (byte)Command.GloInitiateResponse)
            {
                if (xml != null)
                {
                    int cnt = GXCommon.GetObjectCount(data);
                    byte[] tmp = new byte[cnt];
                    data.Get(tmp);
                    //<glo_InitiateResponse>
                    xml.AppendLine(Command.GloInitiateResponse, "Value", GXCommon.ToHex(tmp, false));
                    return;
                }
                --data.Position;
                cipher.Security = cipher.Decrypt(settings.SourceSystemTitle, data);
                tag = data.GetUInt8();
            }
            else if (tag == (byte)Command.GloInitiateRequest)
            {
                if (xml != null)
                {
                    int cnt = GXCommon.GetObjectCount(data);
                    byte[] tmp = new byte[cnt];
                    data.Get(tmp);
                    //<glo_InitiateRequest>
                    xml.AppendLine(Command.GloInitiateRequest, "Value", GXCommon.ToHex(tmp, false));
                    return;
                }
                --data.Position;
                cipher.Security = cipher.Decrypt(settings.SourceSystemTitle, data);
                tag = data.GetUInt8();
            }
            bool response = tag == (byte)Command.InitiateResponse;
            if (response)
            {
                if (xml != null)
                {
                    //<InitiateResponse>
                    xml.AppendStartTag(Command.InitiateResponse);
                }
                //Optional usage field of the negotiated quality of service component
                tag = data.GetUInt8();
                len = 0;
                if (tag != 0)//Skip if used.
                {
                    len = data.GetUInt8();
                    data.Position += len;
                    if (len == 0 && xml != null)
                    {
                        //NegotiatedQualityOfService
                        xml.AppendLine(TranslatorGeneralTags.NegotiatedQualityOfService, "Value", "00");
                    }
                }
            }
            else if (tag == (byte)Command.InitiateRequest)
            {
                if (xml != null)
                {
                    //<InitiateRequest>
                    xml.AppendStartTag(Command.InitiateRequest);
                }
                //Optional usage field of the negotiated quality of service component
                tag = data.GetUInt8();
                //CtoS.
                if (tag != 0)
                {
                    len = data.GetUInt8();
                    settings.CtoSChallenge = new byte[len];
                    data.Get(settings.CtoSChallenge);
                }
                //Optional usage field of the negotiated quality of service component
                tag = data.GetUInt8();
                if (tag != 0)//Skip if used.
                {
                    len = data.GetUInt8();
                    data.Position += len;
                }
                //Optional usage field of the proposed quality of service component
                tag = data.GetUInt8();
                if (tag != 0)//Skip if used.
                {
                    len = data.GetUInt8();
                    data.Position += len;
                }
            }
            else
            {
                throw new Exception("Invalid tag.");
            }
            //Get DLMS version number.
            if (!response)
            {
                if (data.GetUInt8() != 6)
                {
                    throw new Exception("Invalid DLMS version number.");
                }
                //ProposedDlmsVersionNumber
                if (xml != null)
                {
                    xml.AppendLine(TranslatorGeneralTags.ProposedDlmsVersionNumber, "Value", xml.IntegerToHex(settings.DLMSVersion, 2));
                }
            }
            else
            {
                if (data.GetUInt8() != 6)
                {
                    throw new Exception("Invalid DLMS version number.");
                }
                if (xml != null)
                {
                    xml.AppendLine(TranslatorGeneralTags.NegotiatedDlmsVersionNumber, "Value", xml.IntegerToHex(settings.DLMSVersion, 2));
                }
            }

            //Tag for conformance block
            tag = data.GetUInt8();
            if (tag != 0x5F)
            {
                throw new Exception("Invalid tag.");
            }
            //Old Way...
            if (data.GetUInt8(data.Position) == 0x1F)
            {
                data.GetUInt8();
            }
            len = data.GetUInt8();
            //The number of unused bits in the bit string.
            tag = data.GetUInt8();
            if (!response)
            {
                //ProposedConformance
                if (xml != null)
                {
                    xml.AppendStartTag(TranslatorGeneralTags.ProposedConformance);
                }
                data.Get(settings.ConformanceBlock);
                tmp2.Set(settings.ConformanceBlock);
            }
            else
            {
                //NegotiatedConformance
                if (xml != null)
                {
                    xml.AppendStartTag(TranslatorGeneralTags.NegotiatedConformance);
                }
                if (settings.UseLogicalNameReferencing)
                {
                    data.Get(settings.LnSettings.ConformanceBlock);
                    tmp2.Set(settings.LnSettings.ConformanceBlock);
                }
                else
                {
                    data.Get(settings.SnSettings.ConformanceBlock);
                    tmp2.Set(settings.SnSettings.ConformanceBlock);
                }
            }
            if (xml != null)
            {
                GetConformance(tmp2.GetUInt32(), xml);
            }
            if (!response)
            {
                //Proposed max PDU size.
                settings.MaxPduSize = data.GetUInt16();
                if (xml != null)
                {
                    //ProposedConformance closing
                    xml.AppendEndTag(TranslatorGeneralTags.ProposedConformance);
                    //ProposedMaxPduSize
                    xml.AppendLine(TranslatorGeneralTags.ProposedMaxPduSize, "Value", xml.IntegerToHex(settings.MaxPduSize, 4));
                }
                //If client asks too high PDU.
                if (settings.MaxPduSize > settings.MaxServerPDUSize)
                {
                    settings.MaxPduSize = settings.MaxServerPDUSize;
                }
            }
            else
            {
                //Max PDU size.
                settings.MaxPduSize = data.GetUInt16();
                if (xml != null)
                {
                    //NegotiatedConformance closing
                    xml.AppendEndTag(TranslatorGeneralTags.NegotiatedConformance);
                    //NegotiatedMaxPduSize
                    xml.AppendLine(TranslatorGeneralTags.NegotiatedMaxPduSize, "Value", xml.IntegerToHex(settings.MaxPduSize, 4));
                }
            }
            if (response)
            {
                //VAA Name
                tag = data.GetUInt16();
                if (xml != null)
                {
                    xml.AppendLine(TranslatorGeneralTags.VaaName, "Value", xml.IntegerToHex(tag, 4));
                }
                if (tag == 0x0007)
                {
                    // If LN
                    if (!settings.UseLogicalNameReferencing)
                    {
                        throw new ArgumentException("Invalid VAA.");
                    }
                }
                else if (tag == 0xFA00)
                {
                    // If SN
                    if (settings.UseLogicalNameReferencing)
                    {
                        throw new ArgumentException("Invalid VAA.");
                    }
                }
                else
                {
                    // Unknown VAA.
                    throw new ArgumentException("Invalid VAA.");
                }
                if (xml != null)
                {
                    //<InitiateResponse>
                    xml.AppendEndTag(Command.InitiateResponse);
                }
            }
            else if (xml != null)
            {
                //</InitiateRequest>
                xml.AppendEndTag(Command.InitiateRequest);
            }
        }
Ejemplo n.º 6
0
 private static void GetConformance(UInt32 value, GXDLMSTranslatorStructure xml)
 {
     foreach (var it in Enum.GetValues(typeof(Conformance)))
     {
         if (((int)it & value) != 0)
         {
             xml.AppendLine(TranslatorGeneralTags.ConformanceBit, "Name", it.ToString());
         }
     }
 }