/// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="forTarget"></param>
 /// <param name="forCommand"></param>
 /// <param name="forType"></param>
 public GXDLMSLongTransaction(ValueEventArgs[] forTargets, Command forCommand, GXByteBuffer forData)
 {
     targets = forTargets;
     command = forCommand;
     data = new GXByteBuffer();
     data.Set(forData.Data, forData.Position, forData.Size - forData.Position);
 }
 internal static void SetValue(GXByteBuffer buff, object data)
 {
     GXByteBuffer tmp = new GXByteBuffer();
     tmp.Add(data);
     buff.Add((byte)tmp.Size);
     buff.Set(tmp.Array());
 }
Beispiel #3
0
        ///<summary>
        ///Retrieves the string that indicates the level of authentication, if any.
        ///</summary>
        private static void GetAuthenticationString(GXDLMSSettings settings, GXByteBuffer data)
        {
            //If authentication is used.
            if (settings.Authentication != Authentication.None)
            {
                //Add sender ACSE-requirements field component.
                data.SetUInt8((byte)BerType.Context | (byte)PduType.SenderAcseRequirements);
                data.SetUInt8(2);
                data.SetUInt8(BerType.BitString | BerType.OctetString);
                data.SetUInt8(0x80);

                data.SetUInt8((byte)BerType.Context | (byte)PduType.MechanismName);
                //Len
                data.SetUInt8(7);
                // OBJECT IDENTIFIER
                byte[] p = { (byte)0x60, (byte)0x85, (byte)0x74, (byte)0x05, (byte)0x08, (byte)0x02, (byte)settings.Authentication };
                data.Set(p);
                //Add Calling authentication information.
                int len = 0;
                byte[] callingAuthenticationValue = null;
                if (settings.Authentication == Authentication.Low)
                {
                    if (settings.Password != null)
                    {
                        callingAuthenticationValue = settings.Password;
                        len = callingAuthenticationValue.Length;
                    }
                }
                else
                {
                    callingAuthenticationValue = settings.CtoSChallenge;
                    len = callingAuthenticationValue.Length;
                }
                //0xAC
                data.SetUInt8((byte)BerType.Context | (byte)BerType.Constructed | (byte)PduType.CallingAuthenticationValue);
                //Len
                data.SetUInt8((byte)(2 + len));
                //Add authentication information.
                data.SetUInt8((byte)BerType.Context);
                //Len.
                data.SetUInt8((byte)len);
                if (len != 0)
                {
                    data.Set(callingAuthenticationValue);
                }
            }
        }
Beispiel #4
0
 ///<summary>
 ///Convert ASCII string to DLMS bytes.
 ///</summary>
 ///<param name="buff">
 ///Byte buffer where data is write.
 ///</param>
 ///<param name="value">
 ///Added value.
 ///</param>
 private static void SetString(GXByteBuffer buff, object value)
 {
     if (value != null)
     {
         string str = Convert.ToString(value);
         SetObjectCount(str.Length, buff);
         buff.Set(ASCIIEncoding.ASCII.GetBytes(str));
     }
     else
     {
         buff.SetUInt8(0);
     }
 }
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, int index, int selector, object parameters)
 {
     if (index == 1)
     {
         return(this.LogicalName);
     }
     if (index == 2)
     {
         return(GetObjects());
     }
     if (index == 3)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         //Add count
         data.SetUInt8(2);
         data.SetUInt8((byte)DataType.UInt8);
         data.SetUInt16(ClientSAP);
         data.SetUInt8((byte)DataType.UInt16);
         data.SetUInt16(ServerSAP);
         return(data.Array());
     }
     if (index == 4)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         //Add count
         data.SetUInt8(0x7);
         GXCommon.SetData(data, DataType.UInt8, ApplicationContextName.JointIsoCtt);
         GXCommon.SetData(data, DataType.UInt8, ApplicationContextName.Country);
         GXCommon.SetData(data, DataType.UInt16, ApplicationContextName.CountryName);
         GXCommon.SetData(data, DataType.UInt8, ApplicationContextName.IdentifiedOrganization);
         GXCommon.SetData(data, DataType.UInt8, ApplicationContextName.DlmsUA);
         GXCommon.SetData(data, DataType.UInt8, ApplicationContextName.ApplicationContext);
         GXCommon.SetData(data, DataType.UInt8, ApplicationContextName.ContextId);
         return(data.Array());
     }
     if (index == 5)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         data.SetUInt8(6);
         GXCommon.SetData(data, DataType.BitString, XDLMSContextInfo.Conformance);
         GXCommon.SetData(data, DataType.UInt16, XDLMSContextInfo.MaxReceivePduSize);
         GXCommon.SetData(data, DataType.UInt16, XDLMSContextInfo.MaxSendPpuSize);
         GXCommon.SetData(data, DataType.UInt8, XDLMSContextInfo.DlmsVersionNumber);
         GXCommon.SetData(data, DataType.Int8, XDLMSContextInfo.QualityOfService);
         GXCommon.SetData(data, DataType.OctetString, XDLMSContextInfo.CypheringInfo);
         return(data.Array());
     }
     if (index == 6)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         //Add count
         data.SetUInt8(0x7);
         GXCommon.SetData(data, DataType.UInt8, AuthenticationMechanismMame.JointIsoCtt);
         GXCommon.SetData(data, DataType.UInt8, AuthenticationMechanismMame.Country);
         GXCommon.SetData(data, DataType.UInt16, AuthenticationMechanismMame.CountryName);
         GXCommon.SetData(data, DataType.UInt8, AuthenticationMechanismMame.IdentifiedOrganization);
         GXCommon.SetData(data, DataType.UInt8, AuthenticationMechanismMame.DlmsUA);
         GXCommon.SetData(data, DataType.UInt8, AuthenticationMechanismMame.AuthenticationMechanismName);
         GXCommon.SetData(data, DataType.UInt8, AuthenticationMechanismMame.MechanismId);
         return(data.Array());
     }
     if (index == 7)
     {
         return(Secret);
     }
     if (index == 8)
     {
         return(AssociationStatus);
     }
     if (index == 9)
     {
         if (SecuritySetupReference == null)
         {
             return(null);
         }
         return(ASCIIEncoding.ASCII.GetBytes(SecuritySetupReference));
     }
     throw new ArgumentException("GetValue failed. Invalid attribute index.");
 }
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return(GXCommon.LogicalNameToBytes(LogicalName));
     }
     if (e.Index == 2)
     {
         return(GetObjects(settings, e).Array());
     }
     if (e.Index == 3)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         //Add count
         data.SetUInt8(2);
         data.SetUInt8((byte)DataType.Int8);
         data.SetUInt8(ClientSAP);
         data.SetUInt8((byte)DataType.UInt16);
         data.SetUInt16(ServerSAP);
         return(data.Array());
     }
     if (e.Index == 4)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         //Add count
         data.SetUInt8(0x7);
         GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.JointIsoCtt);
         GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.Country);
         GXCommon.SetData(settings, data, DataType.UInt16, ApplicationContextName.CountryName);
         GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.IdentifiedOrganization);
         GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.DlmsUA);
         GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.ApplicationContext);
         GXCommon.SetData(settings, data, DataType.UInt8, ApplicationContextName.ContextId);
         return(data.Array());
     }
     if (e.Index == 5)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         data.SetUInt8(6);
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt32((UInt32)XDLMSContextInfo.Conformance);
         GXCommon.SetData(settings, data, DataType.BitString, bb.SubArray(1, 3));
         GXCommon.SetData(settings, data, DataType.UInt16, XDLMSContextInfo.MaxReceivePduSize);
         GXCommon.SetData(settings, data, DataType.UInt16, XDLMSContextInfo.MaxSendPduSize);
         GXCommon.SetData(settings, data, DataType.UInt8, XDLMSContextInfo.DlmsVersionNumber);
         GXCommon.SetData(settings, data, DataType.Int8, XDLMSContextInfo.QualityOfService);
         GXCommon.SetData(settings, data, DataType.OctetString, XDLMSContextInfo.CypheringInfo);
         return(data.Array());
     }
     if (e.Index == 6)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         //Add count
         data.SetUInt8(0x7);
         GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismName.JointIsoCtt);
         GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismName.Country);
         GXCommon.SetData(settings, data, DataType.UInt16, AuthenticationMechanismName.CountryName);
         GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismName.IdentifiedOrganization);
         GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismName.DlmsUA);
         GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismName.AuthenticationMechanismName);
         GXCommon.SetData(settings, data, DataType.UInt8, AuthenticationMechanismName.MechanismId);
         return(data.Array());
     }
     if (e.Index == 7)
     {
         return(Secret);
     }
     if (e.Index == 8)
     {
         return(AssociationStatus);
     }
     if (e.Index == 9)
     {
         return(GXCommon.LogicalNameToBytes(SecuritySetupReference));
     }
     if (e.Index == 10)
     {
         return(GetUserList(settings, e).Array());
     }
     if (e.Index == 11)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         //Add structure size.
         data.SetUInt8(2);
         GXCommon.SetData(settings, data, DataType.UInt8, CurrentUser.Key);
         GXCommon.SetData(settings, data, DataType.String, CurrentUser.Value);
         return(data.Array());
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return(null);
 }
 private void GetAccessRights(GXDLMSSettings settings, GXDLMSObject item, GXByteBuffer data)
 {
     data.SetUInt8((byte)DataType.Structure);
     data.SetUInt8((byte)3);
     GXCommon.SetData(settings, data, DataType.UInt16, item.ShortName);
     data.SetUInt8((byte)DataType.Array);
     data.SetUInt8((byte)item.Attributes.Count);
     foreach (GXDLMSAttributeSettings att in item.Attributes)
     {
         data.SetUInt8((byte)DataType.Structure); //attribute_access_item
         data.SetUInt8((byte)3);
         GXCommon.SetData(settings, data, DataType.Int8, att.Index);
         GXCommon.SetData(settings, data, DataType.Enum, att.Access);
         GXCommon.SetData(settings, data, DataType.None, null);
     }
     data.SetUInt8((byte)DataType.Array);
     data.SetUInt8((byte)item.MethodAttributes.Count);
     foreach (GXDLMSAttributeSettings it in item.MethodAttributes)
     {
         data.SetUInt8((byte)DataType.Structure); //attribute_access_item
         data.SetUInt8((byte)2);
         GXCommon.SetData(settings, data, DataType.Int8, it.Index);
         GXCommon.SetData(settings, data, DataType.Enum, it.MethodAccess);
     }
 }
        /// <summary>
        /// Add ASN1 object to byte buffer.
        /// </summary>
        /// <param name="bb">Byte buffer where ANS1 object is serialized. </param>
        /// <param name="target">ANS1 object </param>
        /// <returns>Size of object. </returns>
        private static int GetBytes(GXByteBuffer bb, object target)
        {
            GXByteBuffer tmp;
            string       str;
            int          start = bb.Size;
            int          cnt   = 0;

            if (target is GXAsn1Context)
            {
                tmp = new GXByteBuffer();
                foreach (object it in ((GXAsn1Context)target))
                {
                    cnt += GetBytes(tmp, it);
                }
                start = bb.Size;
                bb.SetUInt8(BerType.Constructed | BerType.Context);
                GXCommon.SetObjectCount(cnt, bb);
                cnt += bb.Size - start;
                bb.Set(tmp);
                return(cnt);
            }
            else if (target is object[])
            {
                tmp = new GXByteBuffer();
                foreach (object it in (object[])target)
                {
                    cnt += GetBytes(tmp, it);
                }
                start = bb.Size;
                bb.SetUInt8(BerType.Constructed | BerType.Sequence);
                GXCommon.SetObjectCount(cnt, bb);
                cnt += bb.Size - start;
                bb.Set(tmp);
                return(cnt);
            }
            else if (target is string)
            {
                bb.SetUInt8(BerType.PrintableString);
                GXCommon.SetObjectCount(((string)target).Length, bb);
                bb.Add(target);
            }
            else if (target is sbyte)
            {
                bb.SetUInt8((byte)BerType.Integer);
                GXCommon.SetObjectCount(1, bb);
                bb.Add(target);
            }
            else if (target is short)
            {
                bb.SetUInt8((byte)BerType.Integer);
                GXCommon.SetObjectCount(2, bb);
                bb.Add(target);
            }
            else if (target is int)
            {
                bb.SetUInt8((byte)BerType.Integer);
                GXCommon.SetObjectCount(4, bb);
                bb.Add(target);
            }
            else if (target is GXAsn1Integer)
            {
                bb.SetUInt8((byte)BerType.Integer);
                byte[] b = ((GXAsn1Integer)target).Value;
                GXCommon.SetObjectCount(b.Length, bb);
                bb.Add(b);
            }
            else if (target is long)
            {
                bb.SetUInt8((byte)BerType.Integer);
                GXCommon.SetObjectCount(8, bb);
                bb.Add(target);
            }
            else if (target is byte[])
            {
                bb.SetUInt8(BerType.OctetString);
                GXCommon.SetObjectCount(((byte[])target).Length, bb);
                bb.Add(target);
            }
            else if (target == null)
            {
                bb.SetUInt8(BerType.Null);
                GXCommon.SetObjectCount(0, bb);
            }
            else if (target is bool)
            {
                bb.SetUInt8(BerType.Boolean);
                bb.SetUInt8(1);
                if ((bool)target)
                {
                    bb.SetUInt8(255);
                }
                else
                {
                    bb.SetUInt8(0);
                }
            }
            else if (target is GXAsn1ObjectIdentifier)
            {
                bb.SetUInt8(BerType.ObjectIdentifier);
                byte[] t = ((GXAsn1ObjectIdentifier)target).Encoded;
                GXCommon.SetObjectCount(t.Length, bb);
                bb.Add(t);
            }
            else if (target is KeyValuePair <object, object> )
            {
                KeyValuePair <object, object> e = (KeyValuePair <object, object>)target;
                GXByteBuffer tmp2 = new GXByteBuffer();
                if (e.Value != null)
                {
                    tmp  = new GXByteBuffer();
                    cnt += GetBytes(tmp2, e.Key);
                    cnt += GetBytes(tmp2, e.Value);
                    tmp.SetUInt8(BerType.Constructed | BerType.Sequence);
                    GXCommon.SetObjectCount(cnt, tmp);
                    tmp.Set(tmp2);
                }
                else
                {
                    GetBytes(tmp2, (e.Key as List <object>)[0]);
                    tmp = tmp2;
                }
                // Update len.
                cnt = bb.Size;
                bb.SetUInt8(BerType.Constructed | BerType.Set);
                GXCommon.SetObjectCount(tmp.Size, bb);
                bb.Set(tmp);
                return(bb.Size - cnt);
            }
            else if (target is GXAsn1Utf8String)
            {
                bb.SetUInt8(BerType.Utf8StringTag);
                str = target.ToString();
                GXCommon.SetObjectCount(str.Length, bb);
                bb.Add(str);
            }
            else if (target is GXAsn1Ia5String)
            {
                bb.SetUInt8(BerType.Ia5String);
                str = target.ToString();
                GXCommon.SetObjectCount(str.Length, bb);
                bb.Add(str);
            }
            else if (target is GXAsn1BitString)
            {
                GXAsn1BitString bs = (GXAsn1BitString)target;
                bb.SetUInt8(BerType.BitString);
                GXCommon.SetObjectCount(1 + bs.Value.Length, bb);
                bb.SetUInt8((byte)bs.PadBits);
                bb.Add(bs.Value);
            }
            else if (target is GXAsn1PublicKey)
            {
                GXAsn1PublicKey bs = (GXAsn1PublicKey)target;
                bb.SetUInt8(BerType.BitString);
                // Size is 64 bytes + padding and uncompressed point indicator.
                GXCommon.SetObjectCount(66, bb);
                // Add padding.
                bb.SetUInt8(0);
                // prefixed with the uncompressed point indicator 04
                bb.SetUInt8(4);
                bb.Add(bs.Value);
                // Count is type + size + 64 bytes + padding + uncompressed point
                // indicator.
                return(68);
            }
            else if (target is DateTime)
            {
                // Save date time in UTC.
                bb.SetUInt8(BerType.UtcTime);
                str = DateToString((DateTime)target);
                bb.SetUInt8((byte)str.Length);
                bb.Add(str);
            }
            else if (target is GXAsn1Sequence || target is IList)
            {
                tmp = new GXByteBuffer();
                foreach (object it in (IList)target)
                {
                    cnt += GetBytes(tmp, it);
                }
                start = bb.Size;
                bb.SetUInt8(BerType.Constructed | BerType.Sequence);
                GXCommon.SetObjectCount(cnt, bb);
                cnt += bb.Size - start;
                bb.Set(tmp);
                return(cnt);
            }
            else
            {
                throw new ArgumentException("Invalid type: " + target.GetType().ToString());
            }
            return(bb.Size - start);
        }
Beispiel #9
0
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return(GXCommon.LogicalNameToBytes(LogicalName));
     }
     if (e.Index == 2)
     {
         //If client set new value.
         if (!settings.IsServer && Scaler != 1 && CurrentAverageValue != null)
         {
             Type type = null;
             if (CurrentAverageValue != null)
             {
                 type = CurrentAverageValue.GetType();
             }
             object tmp;
             tmp = Convert.ToDouble(CurrentAverageValue) / Scaler;
             if (type != null)
             {
                 tmp = Convert.ChangeType(tmp, type);
             }
             return(tmp);
         }
         return(CurrentAverageValue);
     }
     if (e.Index == 3)
     {
         //If client set new value.
         if (!settings.IsServer && Scaler != 1 && LastAverageValue != null)
         {
             DataType dt = base.GetDataType(3);
             if (dt == DataType.None && LastAverageValue != null)
             {
                 dt = GXCommon.GetDLMSDataType(LastAverageValue.GetType());
             }
             object tmp;
             tmp = Convert.ToDouble(LastAverageValue) / Scaler;
             if (dt != DataType.None)
             {
                 tmp = Convert.ChangeType(tmp, GXCommon.GetDataType(dt));
             }
             return(tmp);
         }
         return(LastAverageValue);
     }
     if (e.Index == 4)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         data.SetUInt8(2);
         GXCommon.SetData(settings, data, DataType.Int8, scaler);
         GXCommon.SetData(settings, data, DataType.Enum, Unit);
         return(data.Array());
     }
     if (e.Index == 5)
     {
         return(Status);
     }
     if (e.Index == 6)
     {
         return(CaptureTime);
     }
     if (e.Index == 7)
     {
         return(StartTimeCurrent);
     }
     if (e.Index == 8)
     {
         return(Period);
     }
     if (e.Index == 9)
     {
         return(NumberOfPeriods);
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return(null);
 }
Beispiel #10
0
 ///<summary>
 ///Get data from DLMS frame.
 ///</summary>
 ///<param name="settings">DLMS settings.</param>
 ///<param name="data">Received data.</param>
 ///<param name="info"> Data info.</param>
 ///<returns>Parsed object.</returns>
 ///
 public static object GetData(GXDLMSSettings settings, GXByteBuffer data, GXDataInfo info)
 {
     object value = null;
     int startIndex = data.Position;
     if (data.Position == data.Size)
     {
         info.Complete = false;
         return null;
     }
     info.Complete = true;
     bool knownType = info.Type != DataType.None;
     // Get data type if it is unknown.
     if (!knownType)
     {
         info.Type = (DataType)data.GetUInt8();
     }
     if (info.Type == DataType.None)
     {
         if (info.xml != null)
         {
             info.xml.AppendLine("<" + info.xml.GetDataType(info.Type) + " />");
         }
         return value;
     }
     if (data.Position == data.Size)
     {
         info.Complete = false;
         return null;
     }
     switch (info.Type)
     {
         case DataType.Array:
         case DataType.Structure:
             value = GetArray(data, info, startIndex);
             break;
         case DataType.Boolean:
             value = GetBoolean(data, info);
             break;
         case DataType.BitString:
             value = GetBitString(data, info);
             break;
         case DataType.Int32:
             value = GetInt32(data, info);
             break;
         case DataType.UInt32:
             value = GetUInt32(data, info);
             break;
         case DataType.String:
             value = GetString(data, info, knownType);
             break;
         case DataType.StringUTF8:
             value = GetUtfString(data, info, knownType);
             break;
         case DataType.OctetString:
             value = GetOctetString(data, info, knownType);
             break;
         case DataType.Bcd:
             value = GetBcd(data, info, knownType);
             break;
         case DataType.Int8:
             value = GetInt8(data, info);
             break;
         case DataType.Int16:
             value = GetInt16(data, info);
             break;
         case DataType.UInt8:
             value = GetUInt8(data, info);
             break;
         case DataType.UInt16:
             value = GetUInt16(data, info);
             break;
         case DataType.CompactArray:
             throw new Exception("Invalid data type.");
         case DataType.Int64:
             value = GetInt64(data, info);
             break;
         case DataType.UInt64:
             value = GetUInt64(data, info);
             break;
         case DataType.Enum:
             value = GetEnum(data, info);
             break;
         case DataType.Float32:
             value = Getfloat(data, info);
             break;
         case DataType.Float64:
             value = GetDouble(data, info);
             break;
         case DataType.DateTime:
             value = GetDateTime(settings, data, info);
             break;
         case DataType.Date:
             value = GetDate(data, info);
             break;
         case DataType.Time:
             value = GetTime(data, info);
             break;
         default:
             throw new Exception("Invalid data type.");
     }
     return value;
 }
        /// <summary>
        /// Decrypt data.
        /// </summary>
        /// <param name="p">Decryption parameters</param>
        /// <returns>Decrypted data.</returns>
        public static byte[] DecryptAesGcm(AesGcmParameter p, GXByteBuffer data)
        {
            if (data == null || data.Size < 2)
            {
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            int len;
            Command cmd = (Command)data.GetUInt8();
            switch (cmd)
            {
                case Command.GloGeneralCiphering:
                    len = GXCommon.GetObjectCount(data);
                    p.SystemTitle = new byte[len];
                    data.Get(p.SystemTitle);
                    break;
                case Command.GloInitiateRequest:
                case Command.GloInitiateResponse:
                case Command.GloReadRequest:
                case Command.GloReadResponse:
                case Command.GloWriteRequest:
                case Command.GloWriteResponse:
                case Command.GloGetRequest:
                case Command.GloGetResponse:
                case Command.GloSetRequest:
                case Command.GloSetResponse:
                case Command.GloMethodRequest:
                case Command.GloMethodResponse:
                case Command.GloEventNotificationRequest:
                    break;
                default:
                    throw new ArgumentOutOfRangeException("cryptedData");
            }
            len = Gurux.DLMS.Internal.GXCommon.GetObjectCount(data);
            p.Security = (Gurux.DLMS.Enums.Security)data.GetUInt8();
            p.FrameCounter = data.GetUInt32();
            System.Diagnostics.Debug.WriteLine("Decrypt settings: " + p.ToString());
            System.Diagnostics.Debug.WriteLine("Encrypted: " + GXCommon.ToHex(data.Array(), true));

            byte[] tag = new byte[12];
            byte[] encryptedData;
            int length;
            if (p.Security == Gurux.DLMS.Enums.Security.Authentication)
            {
                length = data.Size - data.Position - 12;
                encryptedData = new byte[length];
                data.Get(encryptedData);
                data.Get(tag);
                // Check tag.
                EncryptAesGcm(p, encryptedData);
                if (!GXDLMSChipperingStream.TagsEquals(tag, p.CountTag))
                {
                    throw new GXDLMSException("Decrypt failed. Invalid tag.");
                }
                return encryptedData;
            }
            byte[] ciphertext = null;
            if (p.Security == Gurux.DLMS.Enums.Security.Encryption)
            {
                length = data.Size - data.Position;
                ciphertext = new byte[length];
                data.Get(ciphertext);
            }
            else if (p.Security == Gurux.DLMS.Enums.Security.AuthenticationEncryption)
            {
                length = data.Size - data.Position - 12;
                ciphertext = new byte[length];
                data.Get(ciphertext);
                data.Get(tag);
            }
            byte[] aad = GetAuthenticatedData(p.Security, p.AuthenticationKey, data.Array());
            byte[] iv = GetNonse(p.FrameCounter, p.SystemTitle);
            GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(p.Security, true, p.BlockCipherKey, aad, iv, tag);
            gcm.Write(ciphertext);
            return gcm.FlushFinalBlock();
        }
Beispiel #12
0
 /// <summary>
 /// Set item count.
 /// </summary>
 /// <param name="count"></param>
 /// <param name="buff"></param>
 internal static void SetObjectCount(int count, GXByteBuffer buff)
 {
     if (count < 0x80)
     {
         buff.SetUInt8((byte)count);
     }
     else if (count < 0x100)
     {
         buff.SetUInt8(0x81);
         buff.SetUInt8((byte)count);
     }
     else if (count < 0x10000)
     {
         buff.SetUInt8(0x82);
         buff.SetUInt16((UInt16)count);
     }
     else
     {
         buff.SetUInt8(0x84);
         buff.SetUInt32((UInt32)count);
     }
 }
Beispiel #13
0
 /// <summary>
 /// Get object count. If first byte is 0x80 or higger it will tell bytes count.
 /// </summary>
 /// <param name="data">Received data.</param>
 /// <returns>Object count.</returns>
 public static int GetObjectCount(GXByteBuffer data)
 {
     int cnt = data.GetUInt8();
     if (cnt > 0x80)
     {
         if (cnt == 0x81)
         {
             return data.GetUInt8();
         }
         else if (cnt == 0x82)
         {
             return data.GetUInt16();
         }
         else if (cnt == 0x84)
         {
             return (int)data.GetUInt32();
         }
         else
         {
             throw new System.ArgumentException("Invalid count.");
         }
     }
     return cnt;
 }
Beispiel #14
0
 /// <summary>
 /// Add string to byte buffer.
 /// </summary>
 /// <param name="value">String to add.</param>
 /// <param name="bb">Byte buffer where string is added.</param>
 public static void AddString(string value, GXByteBuffer bb)
 {
     bb.SetUInt8((byte)DataType.OctetString);
     if (value == null)
     {
         GXCommon.SetObjectCount(0, bb);
     }
     else
     {
         GXCommon.SetObjectCount(value.Length, bb);
         bb.Set(ASCIIEncoding.ASCII.GetBytes(value));
     }
 }
Beispiel #15
0
 /// <summary>
 /// Get HDLC address from byte array.
 /// </summary>
 /// <param name="GXByteBuffer">Byte array.</param>
 /// <returns>HDLC address.</returns>
 public static int GetHDLCAddress(GXByteBuffer buff)
 {
     int size = 0;
     for (int pos = buff.Position; pos != buff.Size; ++pos)
     {
         ++size;
         if ((buff.GetUInt8(pos) & 0x1) == 1)
         {
             break;
         }
     }
     if (size == 1)
     {
         return (byte)((buff.GetUInt8() & 0xFE) >> 1);
     }
     else if (size == 2)
     {
         size = buff.GetUInt16();
         size = ((size & 0xFE) >> 1) | ((size & 0xFE00) >> 2);
         return size;
     }
     else if (size == 4)
     {
         UInt32 tmp = buff.GetUInt32();
         tmp = ((tmp & 0xFE) >> 1) | ((tmp & 0xFE00) >> 2)
               | ((tmp & 0xFE0000) >> 3) | ((tmp & 0xFE000000) >> 4);
         return (int)tmp;
     }
     throw new ArgumentException("Wrong size.");
 }
Beispiel #16
0
 ///<summary>
 ///Convert Bit string to DLMS bytes.
 ///</summary>
 ///<param name="buff">
 ///Byte buffer where data is write.
 ///</param>
 ///<param name="value">
 ///Added value.
 ///</param>
 private static void SetBitString(GXByteBuffer buff, object value)
 {
     if (value is string)
     {
         GXByteBuffer tmp = new GXByteBuffer();
         byte val = 0;
         int index = 0;
         string str = ((string)value);
         SetObjectCount(str.Length, buff);
         foreach (char it in str.Reverse())
         {
             if (it == '1')
             {
                 val |= (byte)(1 << index);
                 ++index;
             }
             else if (it == '0')
             {
                 ++index;
             }
             else
             {
                 throw new Exception("Not a bit string.");
             }
             if (index == 8)
             {
                 index = 0;
                 tmp.SetUInt8(val);
                 val = 0;
             }
         }
         if (index != 0)
         {
             tmp.SetUInt8(val);
         }
         for (int pos = tmp.Size - 1; pos != -1; --pos)
         {
             buff.SetUInt8(tmp.GetUInt8(pos));
         }
     }
     else if (value is sbyte[])
     {
         byte[] arr = (byte[])value;
         SetObjectCount(arr.Length, buff);
         buff.Set(arr);
     }
     else if (value == null)
     {
         buff.SetUInt8(0);
     }
     else
     {
         throw new Exception("BitString must give as string.");
     }
 }
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return(GXCommon.LogicalNameToBytes(LogicalName));
     }
     else if (e.Index == 2)
     {
         return(InitiatorElectricalPhase);
     }
     else if (e.Index == 3)
     {
         return(DeltaElectricalPhase);
     }
     else if (e.Index == 4)
     {
         return(MaxReceivingGain);
     }
     else if (e.Index == 5)
     {
         return(MaxTransmittingGain);
     }
     else if (e.Index == 6)
     {
         return(SearchInitiatorThreshold);
     }
     else if (e.Index == 7)
     {
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt8(DataType.Structure);
         bb.SetUInt8(2);
         GXCommon.SetData(settings, bb, DataType.UInt32, MarkFrequency);
         GXCommon.SetData(settings, bb, DataType.UInt32, SpaceFrequency);
         return(bb.Array());
     }
     else if (e.Index == 8)
     {
         return(MacAddress);
     }
     else if (e.Index == 9)
     {
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt8(DataType.Array);
         if (MacGroupAddresses == null)
         {
             bb.SetUInt8(0);
         }
         else
         {
             GXCommon.SetObjectCount(MacGroupAddresses.Length, bb);
             foreach (UInt16 it in MacGroupAddresses)
             {
                 GXCommon.SetData(settings, bb, DataType.UInt16, it);
             }
         }
         return(bb.Array());
     }
     else if (e.Index == 10)
     {
         return(Repeater);
     }
     else if (e.Index == 11)
     {
         return(RepeaterStatus);
     }
     else if (e.Index == 12)
     {
         return(MinDeltaCredit);
     }
     else if (e.Index == 13)
     {
         return(InitiatorMacAddress);
     }
     else if (e.Index == 14)
     {
         return(SynchronizationLocked);
     }
     else if (e.Index == 15)
     {
         return(TransmissionSpeed);
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return(null);
 }
Beispiel #18
0
        ///<summary>
        ///Get array from DLMS data.
        ///</summary>
        ///<param name="buff">
        ///Received DLMS data.
        ///</param>
        ///<param name="info">
        ///Data info.
        ///</param>
        ///<param name="index">
        ///starting index.
        ///</param>
        ///<returns>Object array.
        ///</returns>
        private static object GetArray(GXByteBuffer buff, GXDataInfo info, int index)
        {
            object value;
            if (info.Count == 0)
            {
                info.Count = GXCommon.GetObjectCount(buff);
            }
            if (info.xml != null)
            {
                info.xml.AppendStartTag(GXDLMS.DATA_TYPE_OFFSET | (int)info.Type, "Qty", info.xml.IntegerToHex(info.Count, 2));
            }

            int size = buff.Size - buff.Position;
            if (info.Count != 0 && size < 1)
            {
                info.Complete = false;
                return null;
            }
            int startIndex = index;
            List<object> arr = new List<object>(info.Count - info.Index);
            // Position where last row was found. Cache uses this info.
            int pos = info.Index;
            for (; pos != info.Count; ++pos)
            {
                GXDataInfo info2 = new GXDataInfo();
                info2.xml = info.xml;
                object tmp = GetData(null, buff, info2);
                if (!info2.Complete)
                {
                    buff.Position = (UInt16)startIndex;
                    info.Complete = false;
                    break;
                }
                else
                {
                    if (info2.Count == info2.Index)
                    {
                        startIndex = buff.Position;
                        arr.Add(tmp);
                    }
                }
            }
            if (info.xml != null)
            {
                info.xml.AppendEndTag(GXDLMS.DATA_TYPE_OFFSET + (int)info.Type);
            }
            info.Index = pos;
            value = arr.ToArray();
            return value;
        }
        /// <summary>
        /// Read DLMS Data from the device.
        /// </summary>
        /// <param name="data">Data to send.</param>
        /// <returns>Received data.</returns>
        public void ReadDLMSPacket(byte[] data, GXReplyData reply)
        {
            if (data == null && !reply.IsStreaming())
            {
                return;
            }
            GXReplyData notify = new GXReplyData();

            reply.Error = 0;
            object eop = (byte)0x7E;

            //In network connection terminator is not used.
            if (Client.InterfaceType == InterfaceType.WRAPPER && Media is GXNet)
            {
                eop = null;
            }
            int  pos       = 0;
            bool succeeded = false;
            ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>()
            {
                Eop      = eop,
                WaitTime = WaitTime,
            };

            if (eop == null)
            {
                p.Count = 8;
            }
            else
            {
                p.Count = 5;
            }
            GXByteBuffer rd = new GXByteBuffer();

            lock (Media.Synchronous)
            {
                while (!succeeded && pos != 3)
                {
                    if (!reply.IsStreaming())
                    {
                        WriteTrace("TX:\t" + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(data, true));
                        Media.Send(data, null);
                    }
                    succeeded = Media.Receive(p);
                    if (!succeeded)
                    {
                        if (++pos >= RetryCount)
                        {
                            throw new Exception("Failed to receive reply from the device in given time.");
                        }
                        //If Eop is not set read one byte at time.
                        if (p.Eop == null)
                        {
                            p.Count = 1;
                        }
                        //Try to read again...
                        System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3");
                    }
                }
                rd = new GXByteBuffer(p.Reply);
                try
                {
                    pos = 0;
                    //Loop until whole COSEM packet is received.
                    while (!Client.GetData(rd, reply, notify))
                    {
                        p.Reply = null;
                        if (notify.Data.Data != null)
                        {
                            //Handle notify.
                            if (!notify.IsMoreData)
                            {
                                //Show received push message as XML.
                                string           xml;
                                GXDLMSTranslator t = new GXDLMSTranslator(TranslatorOutputType.SimpleXml);
                                t.DataToXml(notify.Data, out xml);
                                Console.WriteLine(xml);
                                notify.Clear();
                            }
                            continue;
                        }
                        else if (p.Eop == null)
                        {
                            p.Count = Client.GetFrameSize(rd);
                        }
                        while (!Media.Receive(p))
                        {
                            if (++pos >= RetryCount)
                            {
                                throw new Exception("Failed to receive reply from the device in given time.");
                            }
                            //If echo.
                            if (rd == null || rd.Size == data.Length)
                            {
                                Media.Send(data, null);
                            }
                            //Try to read again...
                            System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3");
                        }
                        rd.Set(p.Reply);
                    }
                }
                catch (Exception ex)
                {
                    WriteTrace("RX:\t" + DateTime.Now.ToLongTimeString() + "\t" + rd);
                    throw ex;
                }
            }
            WriteTrace("RX:\t" + DateTime.Now.ToLongTimeString() + "\t" + rd);
            if (reply.Error != 0)
            {
                if (reply.Error == (short)ErrorCode.Rejected)
                {
                    Thread.Sleep(1000);
                    ReadDLMSPacket(data, reply);
                }
            }
        }
Beispiel #20
0
        ///<summary>
        ///Get time from DLMS data.
        ///</summary>
        ///<param name="buff">
        ///Received DLMS data.
        ///</param>
        ///<param name="info">
        ///Data info.
        ///</param>
        ///<returns>
        ///Parsed time.
        ///</returns>
        private static object GetTime(GXByteBuffer buff, GXDataInfo info)
        {
            object value;
            if (buff.Size - buff.Position < 4)
            {
                // If there is not enough data available.
                info.Complete = false;
                return null;
            }
            if (info.xml != null)
            {
                info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(buff.Data, false, buff.Position, 4));
            }

            // Get time.
            int hour = buff.GetUInt8();
            int minute = buff.GetUInt8();
            int second = buff.GetUInt8();
            int ms = buff.GetUInt8();
            if (ms != 0xFF)
            {
                ms *= 10;
            }
            GXTime dt = new GXTime(hour, minute, second, ms);
            value = dt;
            return value;
        }
Beispiel #21
0
        object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
        {
            if (e.Index == 1)
            {
                return(this.LogicalName);
            }
            if (e.Index == 2)
            {
                GXByteBuffer data = new GXByteBuffer();
                data.SetUInt8((byte)DataType.Array);
                data.SetUInt8((byte)Entries.Count);

                /*
                 * foreach (GXScheduleEntry it in Entries)
                 * {
                 *  data.SetUInt8((byte)DataType.Structure);
                 *  data.SetUInt8(10);
                 *  //Add index.
                 *  data.SetUInt8((byte)DataType.UInt8);
                 *  data.SetUInt8(it.Index);
                 *  //Add enable.
                 *  data.SetUInt8((byte)DataType.Boolean);
                 *  data.SetUInt8((byte) (it.Enable ? 1 : 0));
                 *
                 *  //Add logical Name.
                 *  data.SetUInt8((byte)DataType.OctetString);
                 *  data.SetUInt8((byte) it.LogicalName.Length);
                 *  //TODO: data.SetUInt8((byte)it.LogicalName.Length);
                 *
                 *  //Add script selector.
                 *  data.SetUInt8((byte)DataType.UInt8);
                 *  data.SetUInt8(it.ScriptSelector);
                 *
                 *  //Add switch time.
                 *  ret = var_setDateTime(&tmp, &se->switchTime);
                 *  if (ret != 0)
                 *  {
                 *      var_clear(&tmp);
                 *      break;
                 *  }
                 *  ret = var_getBytes(&tmp, &value->byteArr);
                 *  var_clear(&tmp);
                 *  if (ret != 0)
                 *  {
                 *      break;
                 *  }
                 *  //Add validity window.
                 *  data.SetUInt8((byte)DataType.UInt8);
                 *  data.SetUInt8(it.ValidityWindow);
                 *
                 *  //Add exec week days.
                 *  ba_setUInt8(&value->byteArr, DLMS_DATA_TYPE_BIT_STRING);
                 *  setObjectCount(se->execWeekdays.size, &value->byteArr);
                 *  ba_addRange(&value->byteArr, se->execWeekdays.data, bit_getByteCount(se->execWeekdays.size));
                 *
                 *  //Add exec spec days.
                 *  ba_setUInt8(&value->byteArr, DLMS_DATA_TYPE_BIT_STRING);
                 *  setObjectCount(se->execSpecDays.size, &value->byteArr);
                 *  ba_addRange(&value->byteArr, se->execSpecDays.data, bit_getByteCount(se->execSpecDays.size));
                 *
                 *  //Add begin date.
                 *  ret = var_setDateTime(&tmp, &se->beginDate);
                 *  if (ret != 0)
                 *  {
                 *      var_clear(&tmp);
                 *      break;
                 *  }
                 *  ret = var_getBytes(&tmp, &value->byteArr);
                 *  var_clear(&tmp);
                 *  if (ret != 0)
                 *  {
                 *      break;
                 *  }
                 *  //Add end date.
                 *  ret = var_setDateTime(&tmp, &se->endDate);
                 *  if (ret != 0)
                 *  {
                 *      var_clear(&tmp);
                 *      break;
                 *  }
                 *  ret = var_getBytes(&tmp, &value->byteArr);
                 *  var_clear(&tmp);
                 *  if (ret != 0)
                 *  {
                 *      break;
                 *  }
                 * }
                 * */
                return(data.Array());
            }
            e.Error = ErrorCode.ReadWriteDenied;
            return(null);
        }
Beispiel #22
0
 ///<summary>
 ///Get date from DLMS data.
 ///</summary>
 ///<param name="buff">
 ///Received DLMS data.
 ///</param>
 ///<param name="info">
 ///Data info.
 ///</param>
 ///<returns>
 ///Parsed date.
 ///</returns>
 private static object GetDate(GXByteBuffer buff, GXDataInfo info)
 {
     object value;
     if (buff.Size - buff.Position < 5)
     {
         // If there is not enough data available.
         info.Complete = false;
         return null;
     }
     if (info.xml != null)
     {
         info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(buff.Data, false, buff.Position, 5));
     }
     // Get year.
     int year = buff.GetUInt16();
     // Get month
     int month = buff.GetUInt8();
     // Get day
     int day = buff.GetUInt8();
     GXDate dt = new GXDate(year, month, day);
     // Skip week day
     if (buff.GetUInt8() == 0xFF)
     {
         dt.Skip |= DateTimeSkips.DayOfWeek;
     }
     value = dt;
     return value;
 }
Beispiel #23
0
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return(GXCommon.LogicalNameToBytes(LogicalName));
     }
     if (e.Index == 2)
     {
         if (APN != null)
         {
             return(ASCIIEncoding.ASCII.GetBytes(APN));
         }
         return(null);
     }
     if (e.Index == 3)
     {
         return(PINCode);
     }
     if (e.Index == 4)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         //Add count
         data.SetUInt8((byte)2);
         data.SetUInt8((byte)DataType.Structure);
         data.SetUInt8((byte)5);
         if (DefaultQualityOfService != null)
         {
             GXCommon.SetData(settings, data, DataType.UInt8, DefaultQualityOfService.Precedence);
             GXCommon.SetData(settings, data, DataType.UInt8, DefaultQualityOfService.Delay);
             GXCommon.SetData(settings, data, DataType.UInt8, DefaultQualityOfService.Reliability);
             GXCommon.SetData(settings, data, DataType.UInt8, DefaultQualityOfService.PeakThroughput);
             GXCommon.SetData(settings, data, DataType.UInt8, DefaultQualityOfService.MeanThroughput);
         }
         else
         {
             GXCommon.SetData(settings, data, DataType.UInt8, 0);
             GXCommon.SetData(settings, data, DataType.UInt8, 0);
             GXCommon.SetData(settings, data, DataType.UInt8, 0);
             GXCommon.SetData(settings, data, DataType.UInt8, 0);
             GXCommon.SetData(settings, data, DataType.UInt8, 0);
         }
         data.SetUInt8((byte)DataType.Structure);
         data.SetUInt8((byte)5);
         if (RequestedQualityOfService != null)
         {
             GXCommon.SetData(settings, data, DataType.UInt8, RequestedQualityOfService.Precedence);
             GXCommon.SetData(settings, data, DataType.UInt8, RequestedQualityOfService.Delay);
             GXCommon.SetData(settings, data, DataType.UInt8, RequestedQualityOfService.Reliability);
             GXCommon.SetData(settings, data, DataType.UInt8, RequestedQualityOfService.PeakThroughput);
             GXCommon.SetData(settings, data, DataType.UInt8, RequestedQualityOfService.MeanThroughput);
         }
         else
         {
             GXCommon.SetData(settings, data, DataType.UInt8, 0);
             GXCommon.SetData(settings, data, DataType.UInt8, 0);
             GXCommon.SetData(settings, data, DataType.UInt8, 0);
             GXCommon.SetData(settings, data, DataType.UInt8, 0);
             GXCommon.SetData(settings, data, DataType.UInt8, 0);
         }
         return(data.Array());
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return(null);
 }
Beispiel #24
0
        ///<summary>
        ///Get date and time from DLMS data.
        ///</summary>
        ///<param name="settings">DLMS settings.</param>
        ///<param name="buff">Received DLMS data.</param>
        ///<param name="info">Data info.</param>
        ///<returns>
        ///Parsed date and time.
        ///</returns>
        private static object GetDateTime(GXDLMSSettings settings, GXByteBuffer buff, GXDataInfo info)
        {
            // If there is not enough data available.
            if (buff.Size - buff.Position < 12)
            {
                //If time.
                if (buff.Size - buff.Position < 5)
                {
                    return GetTime(buff, info);
                }
                //If date.
                else if (buff.Size - buff.Position < 6)
                {
                    return GetDate(buff, info);
                }

                info.Complete = false;
                return null;
            }
            if (info.xml != null)
            {
                info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(buff.Data, false, buff.Position, 12));
            }

            GXDateTime dt = new GXDateTime();
            //Get year.
            int year = buff.GetUInt16();
            if (year == 0xFFFF || year == 0)
            {
                year = DateTime.Now.Year;
                dt.Skip |= DateTimeSkips.Year;
            }
            //Get month
            int month = buff.GetUInt8();
            if (month == 0 || month == 0xFF || month == 0xFE || month == 0xFD)
            {
                month = 1;
                dt.Skip |= DateTimeSkips.Month;
            }
            int day = buff.GetUInt8();
            if (day < 1 || day == 0xFF)
            {
                day = 1;
                dt.Skip |= DateTimeSkips.Day;
            }
            else if (day == 0xFD || day == 0xFE)
            {
                day = DateTime.DaysInMonth(year, month) + (sbyte)day + 2;
            }
            //Skip week day
            if (buff.GetUInt8() == 0xFF)
            {
                dt.Skip |= DateTimeSkips.DayOfWeek;
            }
            //Get time.
            int hours = buff.GetUInt8();
            if (hours == 0xFF)
            {
                hours = 0;
                dt.Skip |= DateTimeSkips.Hour;
            }
            int minutes = buff.GetUInt8();
            if (minutes == 0xFF)
            {
                minutes = 0;
                dt.Skip |= DateTimeSkips.Minute;
            }
            int seconds = buff.GetUInt8();
            if (seconds == 0xFF)
            {
                seconds = 0;
                dt.Skip |= DateTimeSkips.Second;
            }
            int milliseconds = buff.GetUInt8();
            if (milliseconds != 0xFF)
            {
                milliseconds *= 10;
            }
            else
            {
                milliseconds = 0;
                dt.Skip |= DateTimeSkips.Ms;
            }
            int deviation = buff.GetInt16();
            dt.Status = (ClockStatus)buff.GetUInt8();
            if (settings != null && settings.UtcTimeZone)
            {
                deviation = -deviation;
            }
            dt.Deviation = deviation;
            //0x8000 == -32768
            //deviation = -1 if skipped.
            if (deviation != -1 && deviation != -32768 && year != 1 && (dt.Skip & DateTimeSkips.Year) == 0)
            {
                dt.Value = new DateTimeOffset(new DateTime(year, month, day, hours, minutes, seconds, milliseconds),
                                              new TimeSpan(0, -deviation, 0));
            }
            else //Use current time if deviation is not defined.
            {
                dt.Skip |= DateTimeSkips.Devitation;
                DateTime tmp = new DateTime(year, month, day, hours, minutes, seconds, milliseconds, DateTimeKind.Local);
                dt.Value = new DateTimeOffset(tmp, TimeZoneInfo.Local.GetUtcOffset(tmp));
            }
            return dt;
        }
 byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e)
 {
     //Check reply_to_HLS_authentication
     if (e.Index == 1)
     {
         UInt32 ic = 0;
         byte[] secret;
         if (settings.Authentication == Authentication.HighGMAC)
         {
             secret = settings.SourceSystemTitle;
             GXByteBuffer bb = new GXByteBuffer(e.Parameters as byte[]);
             bb.GetUInt8();
             ic = bb.GetUInt32();
         }
         else
         {
             secret = Secret;
         }
         byte[] serverChallenge = GXSecure.Secure(settings, settings.Cipher, ic, settings.StoCChallenge, secret);
         byte[] clientChallenge = (byte[])e.Parameters;
         if (serverChallenge != null && clientChallenge != null && GXCommon.Compare(serverChallenge, clientChallenge))
         {
             if (settings.Authentication == Authentication.HighGMAC)
             {
                 secret = settings.Cipher.SystemTitle;
                 ic     = settings.Cipher.InvocationCounter;
             }
             else
             {
                 secret = Secret;
             }
             settings.Connected = ConnectionState.Dlms;
             AssociationStatus  = AssociationStatus.Associated;
             return(GXSecure.Secure(settings, settings.Cipher, ic, settings.CtoSChallenge, secret));
         }
         else //If the password does not match.
         {
             AssociationStatus   = AssociationStatus.NonAssociated;
             settings.Connected &= ~ConnectionState.Dlms;
             return(null);
         }
     }
     else if (e.Index == 2)
     {
         byte[] tmp = e.Parameters as byte[];
         if (tmp == null || tmp.Length == 0)
         {
             e.Error = ErrorCode.ReadWriteDenied;
         }
         else
         {
             Secret = tmp;
         }
     }
     else if (e.Index == 3)
     {
         //Add COSEM object.
         GXDLMSObject obj = GetObject(settings, e.Parameters as object[]);
         //Unknown objects are not add.
         if (obj is IGXDLMSBase)
         {
             if (ObjectList.FindByLN(obj.ObjectType, obj.LogicalName) == null)
             {
                 ObjectList.Add(obj);
             }
             if (settings.Objects.FindByLN(obj.ObjectType, obj.LogicalName) == null)
             {
                 settings.Objects.Add(obj);
             }
         }
     }
     else if (e.Index == 4)
     {
         //Remove COSEM object.
         GXDLMSObject obj = GetObject(settings, e.Parameters as object[]);
         //Unknown objects are not removed.
         if (obj is IGXDLMSBase)
         {
             GXDLMSObject t = ObjectList.FindByLN(obj.ObjectType, obj.LogicalName);
             if (t != null)
             {
                 ObjectList.Remove(t);
             }
             //Item is not removed from all objects. It might be that use wants remove object only from association view.
         }
     }
     else if (e.Index == 5)
     {
         object[] tmp = e.Parameters as object[];
         if (tmp == null || tmp.Length != 2)
         {
             e.Error = ErrorCode.ReadWriteDenied;
         }
         else
         {
             UserList.Add(new KeyValuePair <byte, string>(Convert.ToByte(tmp[0]), Convert.ToString(tmp[1])));
         }
     }
     else if (e.Index == 6)
     {
         object[] tmp = e.Parameters as object[];
         if (tmp == null || tmp.Length != 2)
         {
             e.Error = ErrorCode.ReadWriteDenied;
         }
         else
         {
             UserList.Remove(new KeyValuePair <byte, string>(Convert.ToByte(tmp[0]), Convert.ToString(tmp[1])));
         }
     }
     else
     {
         e.Error = ErrorCode.ReadWriteDenied;
     }
     return(null);
 }
Beispiel #26
0
 ///<summary>
 ///Get float value from DLMS data.
 ///</summary>
 ///<param name="buff">
 ///Received DLMS data.
 ///</param>
 ///<param name="info">
 ///Data info.
 ///</param>
 ///<returns>
 ///Parsed float value.
 ///</returns>
 private static object Getfloat(GXByteBuffer buff, GXDataInfo info)
 {
     // If there is not enough data available.
     if (buff.Size - buff.Position < 4)
     {
         info.Complete = false;
         return null;
     }
     float value = buff.GetFloat();
     if (info.xml != null)
     {
         GXByteBuffer tmp = new GXByteBuffer();
         SetData(null, tmp, DataType.Float32, value);
         info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(tmp.Data, false, 1, tmp.Size - 1));
     }
     return value;
 }
Beispiel #27
0
 ///<summary>
 ///Convert Octet string to DLMS bytes.
 ///</summary>
 ///<param name="buff">
 ///Byte buffer where data is write.
 ///</param>
 ///<param name="value">
 ///Added value.
 ///</param>
 private static void SetOctetString(GXByteBuffer buff, object value)
 {
     // Example Logical name is octet string, so do not change to
     // string...
     if (value is string)
     {
         string[] items = ((string)value).Split('.');
         // If data is string.
         if (items.Length == 1)
         {
             byte[] tmp = ASCIIEncoding.ASCII.GetBytes((string)value);
             SetObjectCount(tmp.Length, buff);
             buff.Set(tmp);
         }
         else
         {
             SetObjectCount(items.Length, buff);
             foreach (string it in items)
             {
                 buff.SetUInt8(Convert.ToByte(it));
             }
         }
     }
     else if (value is sbyte[])
     {
         SetObjectCount(((byte[])value).Length, buff);
         buff.Set((byte[])value);
     }
     else if (value == null)
     {
         SetObjectCount(0, buff);
     }
     else
     {
         throw new Exception("Invalid data type.");
     }
 }
Beispiel #28
0
 ///<summary>
 ///Get UInt16 value from DLMS data.
 ///</summary>
 ///<param name="buff">
 ///Received DLMS data.
 ///</param>
 ///<param name="info">
 ///Data info.
 ///</param>
 ///<returns>
 ///Parsed UInt16 value.
 ///</returns>
 private static object GetUInt16(GXByteBuffer buff, GXDataInfo info)
 {
     // If there is not enough data available.
     if (buff.Size - buff.Position < 2)
     {
         info.Complete = false;
         return null;
     }
     UInt16 value = buff.GetUInt16();
     if (info.xml != null)
     {
         info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", info.xml.IntegerToHex(value, 4));
     }
     return value;
 }
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (ObjectList == null)
     {
         ObjectList = new GXDLMSObjectCollection();
     }
     if (e.Index == 1)
     {
         return this.LogicalName;
     }
     else if (e.Index == 2)
     {
         return GetObjects(settings, e).Array();
     }
     else if (e.Index == 3)
     {
         bool lnExists = ObjectList.FindBySN(this.ShortName) != null;
         //Add count
         int cnt = ObjectList.Count;
         if (!lnExists)
         {
             ++cnt;
         }
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         GXCommon.SetObjectCount(cnt, data);
         foreach (GXDLMSObject it in ObjectList)
         {
             GetAccessRights(settings, it, data);
         }
         if (!lnExists)
         {
             GetAccessRights(settings, this, data);
         }
         return data.Array();
     }
     else if (e.Index == 4)
     {
         GXByteBuffer data = new GXByteBuffer();
         GXCommon.SetData(settings, data, DataType.OctetString, SecuritySetupReference);
         return data.Array();
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return null;
 }
Beispiel #30
0
        /// <summary>
        /// Decrypt data.
        /// </summary>
        /// <param name="p">Decryption parameters</param>
        /// <returns>Decrypted data.</returns>
        public static byte[] DecryptAesGcm(AesGcmParameter p, GXByteBuffer data)
        {
            if (data == null || data.Size < 2)
            {
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            byte[]  tmp;
            int     len;
            Command cmd = (Command)data.GetUInt8();

            switch (cmd)
            {
            case Command.GeneralGloCiphering:
            case Command.GeneralDedCiphering:
                len = GXCommon.GetObjectCount(data);
                if (len != 0)
                {
                    p.SystemTitle = new byte[len];
                    data.Get(p.SystemTitle);
                    if (p.Xml != null && p.Xml.Comments)
                    {
                        p.Xml.AppendComment(GXCommon.SystemTitleToString(Standard.DLMS, p.SystemTitle, true));
                    }
                }
                if (p.SystemTitle == null || p.SystemTitle.Length != 8)
                {
                    if (p.Xml == null)
                    {
                        throw new ArgumentNullException("Invalid sender system title.");
                    }
                    else
                    {
                        p.Xml.AppendComment("Invalid sender system title.");
                    }
                }
                break;

            case Command.GeneralCiphering:
            case Command.GloInitiateRequest:
            case Command.GloInitiateResponse:
            case Command.GloReadRequest:
            case Command.GloReadResponse:
            case Command.GloWriteRequest:
            case Command.GloWriteResponse:
            case Command.GloGetRequest:
            case Command.GloGetResponse:
            case Command.GloSetRequest:
            case Command.GloSetResponse:
            case Command.GloMethodRequest:
            case Command.GloMethodResponse:
            case Command.GloEventNotification:
            case Command.DedInitiateRequest:
            case Command.DedInitiateResponse:
            case Command.DedGetRequest:
            case Command.DedGetResponse:
            case Command.DedSetRequest:
            case Command.DedSetResponse:
            case Command.DedMethodRequest:
            case Command.DedMethodResponse:
            case Command.DedEventNotification:
            case Command.DedReadRequest:
            case Command.DedReadResponse:
            case Command.DedWriteRequest:
            case Command.DedWriteResponse:
            case Command.GloConfirmedServiceError:
            case Command.DedConfirmedServiceError:
                break;

            default:
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            int          value         = 0;
            GXPrivateKey key           = null;
            GXPublicKey  pub           = null;
            GXByteBuffer transactionId = null;

            if (cmd == Command.GeneralCiphering)
            {
                transactionId = new GXByteBuffer();
                len           = GXCommon.GetObjectCount(data);
                GXCommon.SetObjectCount(len, transactionId);
                transactionId.Set(data, len);
                p.TransactionId = transactionId.GetUInt64(1);
                len             = GXCommon.GetObjectCount(data);
                if (len != 0)
                {
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.SystemTitle = tmp;
                }
                if (p.SystemTitle == null || p.SystemTitle.Length != 8)
                {
                    if (p.Xml == null)
                    {
                        throw new ArgumentNullException("Invalid sender system title.");
                    }
                    else
                    {
                        p.Xml.AppendComment("Invalid sender system title.");
                    }
                }
                len = GXCommon.GetObjectCount(data);
                tmp = new byte[len];
                data.Get(tmp);
                p.RecipientSystemTitle = tmp;
                // Get date time.
                len = GXCommon.GetObjectCount(data);
                if (len != 0)
                {
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.DateTime = tmp;
                }
                // other-information
                len = data.GetUInt8();
                if (len != 0)
                {
                    tmp = new byte[len];
                    data.Get(tmp);
                    p.OtherInformation = tmp;
                }
                // KeyInfo OPTIONAL
                len = data.GetUInt8();
                // AgreedKey CHOICE tag.
                data.GetUInt8();
                // key-parameters
                len             = data.GetUInt8();
                value           = data.GetUInt8();
                p.KeyParameters = value;
                if (value == (int)KeyAgreementScheme.OnePassDiffieHellman)
                {
                    // key-ciphered-data
                    len = GXCommon.GetObjectCount(data);
                    GXByteBuffer bb = new GXByteBuffer();
                    bb.Set(data, len);
                    if (p.Xml != null)
                    {
                        p.KeyCipheredData = bb.Array();
                        //Find key agreement key using subject.
                        string subject = GXAsn1Converter.SystemTitleToSubject(p.SystemTitle);
                        foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it in p.Settings.Keys)
                        {
                            if (it.Key != null && it.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it.Value.Subject.Contains(subject))
                            {
                                key = it.Key.PrivateKey;
                                //Get recipient Ephemeral public key.
                                subject = GXAsn1Converter.SystemTitleToSubject(p.RecipientSystemTitle);
                                foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it2 in p.Settings.Keys)
                                {
                                    if (it2.Value != null && it2.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it2.Value.Subject.Contains(subject))
                                    {
                                        pub = it2.Value.PublicKey;
                                        break;
                                    }
                                }
                                break;
                            }
                        }
                        if (key == null)
                        {
                            //Find key agreement key using subject.
                            subject = GXAsn1Converter.SystemTitleToSubject(p.RecipientSystemTitle);
                            foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it in p.Settings.Keys)
                            {
                                if (it.Key != null && it.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it.Value.Subject.Contains(subject))
                                {
                                    key = it.Key.PrivateKey;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        key = p.Settings.Cipher.KeyAgreementKeyPair.Key;
                    }
                    if (key != null && pub == null)
                    {
                        //Get Ephemeral public key.
                        int keySize = len / 2;
                        pub = GXPublicKey.FromRawBytes(bb.SubArray(0, keySize));
                    }
                }
                else if (value == (int)KeyAgreementScheme.StaticUnifiedModel)
                {
                    len = GXCommon.GetObjectCount(data);
                    if (len != 0)
                    {
                        throw new ArgumentException("Invalid key parameters");
                    }
                    if (p.Xml != null)
                    {
                        //Find key agreement key using subject.
                        string subject = GXAsn1Converter.SystemTitleToSubject(p.RecipientSystemTitle);
                        foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it in p.Settings.Keys)
                        {
                            if (it.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it.Value.Subject.Contains(subject))
                            {
                                key = it.Key.PrivateKey;
                                break;
                            }
                        }
                        if (key != null)
                        {
                            //Find key agreement key using subject.
                            subject = GXAsn1Converter.SystemTitleToSubject(p.Settings.SourceSystemTitle);
                            foreach (KeyValuePair <GXPkcs8, GXx509Certificate> it in p.Settings.Keys)
                            {
                                if (it.Value.KeyUsage == ASN.Enums.KeyUsage.KeyAgreement && it.Value.Subject.Contains(subject))
                                {
                                    pub = it.Value.PublicKey;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        key = p.Settings.Cipher.KeyAgreementKeyPair.Key;
                        pub = p.Settings.Cipher.KeyAgreementKeyPair.Value;
                    }
                }
                else
                {
                    throw new ArgumentException("key-parameters");
                }
            }
            len = GXCommon.GetObjectCount(data);
            if (len > data.Available)
            {
                throw new Exception("Not enought data.");
            }
            p.CipheredContent = data.Remaining();
            byte sc = data.GetUInt8();

            p.SecuritySuite = (SecuritySuite)(sc & 0x3);
            p.Security      = (Security)(sc & 0x30);
            if ((sc & 0x80) != 0)
            {
                System.Diagnostics.Debug.WriteLine("Compression is used.");
            }
            if ((sc & 0x40) != 0)
            {
                System.Diagnostics.Debug.WriteLine("Error: Key_Set is used.");
            }
            if ((sc & 0x20) != 0)
            {
                System.Diagnostics.Debug.WriteLine("Encryption is applied.");
            }
            if (key != null)
            {
                if (value == (int)KeyAgreementScheme.OnePassDiffieHellman)
                {
                    GXEcdsa c = new GXEcdsa(key);
                    //Get Ephemeral signing key and verify it.
                    byte[] z = c.GenerateSecret(pub);
                    System.Diagnostics.Debug.WriteLine("Originator ephemeral public key: " + pub.ToHex());
                    System.Diagnostics.Debug.WriteLine("Recipient private agreement key: " + key.ToHex());
                    System.Diagnostics.Debug.WriteLine("Shared secret:" + GXCommon.ToHex(z, true));

                    GXByteBuffer kdf = new GXByteBuffer();
                    kdf.Set(GXSecure.GenerateKDF(p.SecuritySuite, z,
                                                 p.SecuritySuite == SecuritySuite.Ecdsa256 ? AlgorithmId.AesGcm128 : AlgorithmId.AesGcm256,
                                                 p.SystemTitle,
                                                 p.RecipientSystemTitle,
                                                 null, null));
                    System.Diagnostics.Debug.WriteLine("KDF:" + kdf.ToString());
                    p.BlockCipherKey = kdf.SubArray(0, 16);
                }
                else if (value == (int)KeyAgreementScheme.StaticUnifiedModel)
                {
                    GXEcdsa c = new GXEcdsa(key);
                    byte[]  z = c.GenerateSecret(pub);
                    System.Diagnostics.Debug.WriteLine("Shared secret:" + GXCommon.ToHex(z, true));
                    GXByteBuffer kdf = new GXByteBuffer();
                    kdf.Set(GXSecure.GenerateKDF(p.SecuritySuite, z,
                                                 p.SecuritySuite == SecuritySuite.Ecdsa256 ? AlgorithmId.AesGcm128 : AlgorithmId.AesGcm256,
                                                 p.SystemTitle,
                                                 transactionId.Array(),
                                                 p.RecipientSystemTitle,
                                                 null));
                    System.Diagnostics.Debug.WriteLine("KDF:" + kdf.ToString());
                    p.BlockCipherKey = kdf.SubArray(0, 16);
                }
                else
                {
                    throw new ArgumentOutOfRangeException("Invalid Key-id value.");
                }
            }
            UInt32 invocationCounter = data.GetUInt32();

            p.InvocationCounter = invocationCounter;
            System.Diagnostics.Debug.WriteLine("Decrypt settings: " + p.ToString());
            System.Diagnostics.Debug.WriteLine("Encrypted: " + GXCommon.ToHex(data.Data,
                                                                              false, data.Position, data.Size - data.Position));
            byte[] tag = new byte[12];
            byte[] encryptedData;
            int    length;

            if (p.Security == Security.Authentication)
            {
                length        = data.Size - data.Position - 12;
                encryptedData = new byte[length];
                data.Get(encryptedData);
                data.Get(tag);
                // Check tag.
                EncryptAesGcm(p, encryptedData);
                if (!GXDLMSChipperingStream.TagsEquals(tag, p.CountTag))
                {
                    if (p.Xml == null)
                    {
                        throw new GXDLMSException("Decrypt failed. Invalid tag.");
                    }
                    else
                    {
                        p.Xml.AppendComment("Decrypt failed. Invalid tag.");
                    }
                }
                return(encryptedData);
            }
            byte[] ciphertext = null;
            if (p.Security == Security.Encryption)
            {
                length     = data.Size - data.Position;
                ciphertext = new byte[length];
                data.Get(ciphertext);
            }
            else if (p.Security == Security.AuthenticationEncryption)
            {
                length     = data.Size - data.Position - 12;
                ciphertext = new byte[length];
                data.Get(ciphertext);
                data.Get(tag);
            }
            byte[] aad = GetAuthenticatedData(p, ciphertext),
            iv = GetNonse(invocationCounter, p.SystemTitle);
            GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(p.Security, true,
                                                                    p.BlockCipherKey, aad, iv, tag);

            gcm.Write(ciphertext);
            byte[] decrypted = gcm.FlushFinalBlock();
            System.Diagnostics.Debug.WriteLine("Decrypted: " + GXCommon.ToHex(decrypted, true));
            if (p.Security != Security.Encryption)
            {
                if (!GXCommon.Compare(gcm.GetTag(), tag))
                {
                    if (p.Xml == null)
                    {
                        throw new Exception("Decrypt failed. Invalid authentication tag.");
                    }
                    p.Xml.AppendComment("Decrypt failed. Invalid authentication tag.");
                }
            }
            return(decrypted);
        }
Beispiel #31
0
 /// <summary>
 /// Constructor value.
 /// </summary>
 /// <param name="value">Byte array Data in MSB format.</param>
 public GXBigInteger(GXByteBuffer value)
 {
     FromByteBuffer(value);
 }
Beispiel #32
0
        static internal byte[] EncryptAesGcm(AesGcmParameter param, byte[] plainText)
        {
            System.Diagnostics.Debug.WriteLine("Encrypt settings: " + param.ToString());
            param.CountTag = null;
            GXByteBuffer data = new GXByteBuffer();

            if (param.Type == CountType.Packet)
            {
                data.SetUInt8((byte)((byte)param.Security | (byte)param.SecuritySuite));
            }
            byte[] tmp = BitConverter.GetBytes((UInt32)param.InvocationCounter).Reverse().ToArray();
            byte[] aad = GetAuthenticatedData(param, plainText);
            GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(param.Security, true, param.BlockCipherKey,
                                                                    aad, GetNonse((UInt32)param.InvocationCounter, param.SystemTitle), null);

            // Encrypt the secret message
            if (param.Security != Security.Authentication)
            {
                gcm.Write(plainText);
            }
            byte[] ciphertext = gcm.FlushFinalBlock();
            if (param.Security == Security.Authentication)
            {
                if (param.Type == CountType.Packet)
                {
                    data.Set(tmp);
                }
                if ((param.Type & CountType.Data) != 0)
                {
                    data.Set(plainText);
                }
                if ((param.Type & CountType.Tag) != 0)
                {
                    param.CountTag = gcm.GetTag();
                    data.Set(param.CountTag);
                }
            }
            else if (param.Security == Security.Encryption)
            {
                if (param.Type == CountType.Packet)
                {
                    data.Set(tmp);
                }
                data.Set(ciphertext);
            }
            else if (param.Security == Security.AuthenticationEncryption)
            {
                if (param.Type == CountType.Packet)
                {
                    data.Set(tmp);
                }
                if ((param.Type & CountType.Data) != 0)
                {
                    data.Set(ciphertext);
                }
                if ((param.Type & CountType.Tag) != 0)
                {
                    param.CountTag = gcm.GetTag();
                    data.Set(param.CountTag);
                }
            }
            else
            {
                throw new ArgumentOutOfRangeException("security");
            }
            if (param.Type == CountType.Packet)
            {
                GXByteBuffer tmp2 = new GXByteBuffer((ushort)(10 + data.Size));
                tmp2.SetUInt8(param.Tag);
                if (param.Tag == (int)Command.GeneralGloCiphering ||
                    param.Tag == (int)Command.GeneralDedCiphering ||
                    param.Tag == (int)Command.DataNotification)
                {
                    if (!param.IgnoreSystemTitle)
                    {
                        GXCommon.SetObjectCount(param.SystemTitle.Length, tmp2);
                        tmp2.Set(param.SystemTitle);
                    }
                    else
                    {
                        tmp2.SetUInt8(0);
                    }
                }
                GXCommon.SetObjectCount(data.Size, tmp2);
                tmp2.Set(data.Array());
                return(tmp2.Array());
            }
            byte[] crypted = data.Array();
            System.Diagnostics.Debug.WriteLine("Crypted: " + GXCommon.ToHex(crypted, true));
            return(crypted);
        }
 void IGXDLMSBase.SetValue(GXDLMSSettings settings, int index, object value)
 {
     if (index == 1)
     {
         if (value is string)
         {
             LogicalName = value.ToString();
         }
         else
         {
             LogicalName = GXDLMSClient.ChangeType((byte[])value, DataType.OctetString).ToString();
         }
     }
     else if (index == 2)
     {
         ObjectList.Clear();
         if (value != null)
         {
             foreach (Object[] item in (Object[])value)
             {
                 ObjectType   type    = (ObjectType)Convert.ToInt32(item[0]);
                 int          version = Convert.ToInt32(item[1]);
                 String       ln      = GXDLMSObject.ToLogicalName((byte[])item[2]);
                 GXDLMSObject obj     = null;
                 if (settings.Objects != null)
                 {
                     obj = settings.Objects.FindByLN(type, ln);
                 }
                 if (obj == null)
                 {
                     obj             = Gurux.DLMS.GXDLMSClient.CreateObject(type);
                     obj.LogicalName = ln;
                     obj.Version     = version;
                 }
                 //Unknown objects are not shown.
                 if (obj is IGXDLMSBase)
                 {
                     UpdateAccessRights(obj, (Object[])item[3]);
                     ObjectList.Add(obj);
                 }
             }
         }
     }
     else if (index == 3)
     {
         if (value != null)
         {
             ClientSAP = Convert.ToByte(((Object[])value)[0]);
             ServerSAP = Convert.ToUInt16(((Object[])value)[1]);
         }
     }
     else if (index == 4)
     {
         //Value of the object identifier encoded in BER
         if (value is byte[])
         {
             GXByteBuffer arr = new GXByteBuffer(value as byte[]);
             if (arr.GetUInt8(0) == 0x60)
             {
                 ApplicationContextName.JointIsoCtt = 0;
                 ++arr.Position;
                 ApplicationContextName.Country = 0;
                 ++arr.Position;
                 ApplicationContextName.CountryName = 0;
                 ++arr.Position;
                 ApplicationContextName.IdentifiedOrganization = arr.GetUInt8();
                 ApplicationContextName.DlmsUA             = arr.GetUInt8();
                 ApplicationContextName.ApplicationContext = arr.GetUInt8();
                 ApplicationContextName.ContextId          = arr.GetUInt8();
             }
             else
             {
                 //Get Tag and Len.
                 if (arr.GetUInt8() != (int)BerType.Integer && arr.GetUInt8() != 7)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.JointIsoCtt = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.Country = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x12)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.CountryName = arr.GetUInt16();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.IdentifiedOrganization = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.DlmsUA = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.ApplicationContext = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.ContextId = arr.GetUInt8();
             }
         }
         else if (value != null)
         {
             Object[] arr = (Object[])value;
             ApplicationContextName.JointIsoCtt            = Convert.ToByte(arr[0]);
             ApplicationContextName.Country                = Convert.ToByte(arr[1]);
             ApplicationContextName.CountryName            = Convert.ToUInt16(arr[2]);
             ApplicationContextName.IdentifiedOrganization = Convert.ToByte(arr[3]);
             ApplicationContextName.DlmsUA             = Convert.ToByte(arr[4]);
             ApplicationContextName.ApplicationContext = Convert.ToByte(arr[5]);
             ApplicationContextName.ContextId          = Convert.ToByte(arr[6]);
         }
     }
     else if (index == 5)
     {
         if (value != null)
         {
             Object[] arr = (Object[])value;
             XDLMSContextInfo.Conformance       = arr[0].ToString();
             XDLMSContextInfo.MaxReceivePduSize = Convert.ToUInt16(arr[1]);
             XDLMSContextInfo.MaxSendPpuSize    = Convert.ToUInt16(arr[2]);
             XDLMSContextInfo.DlmsVersionNumber = Convert.ToByte(arr[3]);
             XDLMSContextInfo.QualityOfService  = Convert.ToSByte(arr[4]);
             XDLMSContextInfo.CypheringInfo     = (byte[])arr[5];
         }
     }
     else if (index == 6)
     {
         //Value of the object identifier encoded in BER
         if (value is byte[])
         {
             GXByteBuffer arr = new GXByteBuffer(value as byte[]);
             if (arr.GetUInt8(0) == 0x60)
             {
                 AuthenticationMechanismMame.JointIsoCtt = 0;
                 ++arr.Position;
                 AuthenticationMechanismMame.Country = 0;
                 ++arr.Position;
                 AuthenticationMechanismMame.CountryName = 0;
                 ++arr.Position;
                 AuthenticationMechanismMame.IdentifiedOrganization = arr.GetUInt8();
                 AuthenticationMechanismMame.DlmsUA = arr.GetUInt8();
                 AuthenticationMechanismMame.AuthenticationMechanismName = arr.GetUInt8();
                 AuthenticationMechanismMame.MechanismId = (Authentication)arr.GetUInt8();
             }
             else
             {
                 //Get Tag and Len.
                 if (arr.GetUInt8() != (int)BerType.Integer && arr.GetUInt8() != 7)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismMame.JointIsoCtt = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismMame.Country = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x12)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismMame.CountryName = arr.GetUInt16();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismMame.IdentifiedOrganization = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismMame.DlmsUA = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismMame.AuthenticationMechanismName = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismMame.MechanismId = (Authentication)arr.GetUInt8();
             }
         }
         else if (value != null)
         {
             Object[] arr = (Object[])value;
             AuthenticationMechanismMame.JointIsoCtt            = Convert.ToByte(arr[0]);
             AuthenticationMechanismMame.Country                = Convert.ToByte(arr[1]);
             AuthenticationMechanismMame.CountryName            = Convert.ToUInt16(arr[2]);
             AuthenticationMechanismMame.IdentifiedOrganization = Convert.ToByte(arr[3]);
             AuthenticationMechanismMame.DlmsUA = Convert.ToByte(arr[4]);
             AuthenticationMechanismMame.AuthenticationMechanismName = Convert.ToByte(arr[5]);
             AuthenticationMechanismMame.MechanismId = (Authentication)Convert.ToByte(arr[6]);
         }
     }
     else if (index == 7)
     {
         Secret = (byte[])value;
     }
     else if (index == 8)
     {
         if (value == null)
         {
             AssociationStatus = AssociationStatus.NonAssociated;
         }
         else
         {
             AssociationStatus = (AssociationStatus)Convert.ToInt32(value);
         }
     }
     else if (index == 9)
     {
         SecuritySetupReference = GXDLMSClient.ChangeType((byte[])value, DataType.OctetString).ToString();
     }
     else
     {
         throw new ArgumentException("SetValue failed. Invalid attribute index.");
     }
 }
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return(GXCommon.LogicalNameToBytes(LogicalName));
     }
     if (e.Index == 2)
     {
         return(MaxHops);
     }
     if (e.Index == 3)
     {
         return(WeakLqiValue);
     }
     if (e.Index == 4)
     {
         return(SecurityLevel);
     }
     if (e.Index == 5)
     {
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt8((byte)DataType.Array);
         if (PrefixTable == null)
         {
             bb.SetUInt8(0);
         }
         else
         {
             GXCommon.SetObjectCount(PrefixTable.Length, bb);
             foreach (var it in PrefixTable)
             {
                 GXCommon.SetData(settings, bb, GXDLMSConverter.GetDLMSDataType(it), it);
             }
         }
         return(bb.Array());
     }
     if (e.Index == 6)
     {
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt8((byte)DataType.Array);
         if (RoutingConfiguration == null)
         {
             bb.SetUInt8(0);
         }
         else
         {
             GXCommon.SetObjectCount(RoutingConfiguration.Count, bb);
             foreach (GXDLMSRoutingConfiguration it in RoutingConfiguration)
             {
                 bb.SetUInt8((byte)DataType.Structure);
                 bb.SetUInt8(14);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.NetTraversalTime);
                 GXCommon.SetData(settings, bb, DataType.UInt16, it.RoutingTableEntryTtl);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.Kr);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.Km);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.Kc);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.Kq);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.Kh);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.Krt);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.RreqRetries);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.RreqRerrWait);
                 GXCommon.SetData(settings, bb, DataType.UInt16, it.BlacklistTableEntryTtl);
                 GXCommon.SetData(settings, bb, DataType.Boolean, it.UnicastRreqGenEnable);
                 GXCommon.SetData(settings, bb, DataType.Boolean, it.RlcEnabled);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.AddRevLinkCost);
             }
         }
         return(bb.Array());
     }
     if (e.Index == 7)
     {
         return(BroadcastLogTableEntryTtl);
     }
     if (e.Index == 8)
     {
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt8((byte)DataType.Array);
         if (RoutingTable == null)
         {
             bb.SetUInt8(0);
         }
         else
         {
             GXCommon.SetObjectCount(RoutingTable.Count, bb);
             foreach (GXDLMSRoutingTable it in RoutingTable)
             {
                 bb.SetUInt8((byte)DataType.Structure);
                 bb.SetUInt8(6);
                 GXCommon.SetData(settings, bb, DataType.UInt16, it.DestinationAddress);
                 GXCommon.SetData(settings, bb, DataType.UInt16, it.NextHopAddress);
                 GXCommon.SetData(settings, bb, DataType.UInt16, it.RouteCost);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.HopCount);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.WeakLinkCount);
                 GXCommon.SetData(settings, bb, DataType.UInt16, it.ValidTime);
             }
         }
         return(bb.Array());
     }
     if (e.Index == 9)
     {
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt8((byte)DataType.Array);
         if (ContextInformationTable == null)
         {
             bb.SetUInt8(0);
         }
         else
         {
             GXCommon.SetObjectCount(ContextInformationTable.Count, bb);
             foreach (GXDLMSContextInformationTable it in ContextInformationTable)
             {
                 bb.SetUInt8((byte)DataType.Structure);
                 bb.SetUInt8(5);
                 GXCommon.SetData(settings, bb, DataType.BitString, it.CID);
                 if (it.Context == null)
                 {
                     GXCommon.SetData(settings, bb, DataType.UInt8, 0);
                 }
                 else
                 {
                     GXCommon.SetData(settings, bb, DataType.UInt8, it.Context.Length);
                 }
                 GXCommon.SetData(settings, bb, DataType.OctetString, it.Context);
                 GXCommon.SetData(settings, bb, DataType.Boolean, it.Compression);
                 GXCommon.SetData(settings, bb, DataType.UInt16, it.ValidLifetime);
             }
         }
         return(bb.Array());
     }
     if (e.Index == 10)
     {
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt8((byte)DataType.Array);
         if (BlacklistTable == null)
         {
             bb.SetUInt8(0);
         }
         else
         {
             GXCommon.SetObjectCount(BlacklistTable.Count, bb);
             foreach (var it in BlacklistTable)
             {
                 bb.SetUInt8((byte)DataType.Structure);
                 bb.SetUInt8(2);
                 GXCommon.SetData(settings, bb, DataType.UInt16, it.Key);
                 GXCommon.SetData(settings, bb, DataType.UInt16, it.Value);
             }
         }
         return(bb.Array());
     }
     if (e.Index == 11)
     {
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt8((byte)DataType.Array);
         if (BroadcastLogTable == null)
         {
             bb.SetUInt8(0);
         }
         else
         {
             GXCommon.SetObjectCount(BroadcastLogTable.Count, bb);
             foreach (GXDLMSBroadcastLogTable it in BroadcastLogTable)
             {
                 bb.SetUInt8((byte)DataType.Structure);
                 bb.SetUInt8(3);
                 GXCommon.SetData(settings, bb, DataType.UInt16, it.SourceAddress);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.SequenceNumber);
                 GXCommon.SetData(settings, bb, DataType.UInt16, it.ValidTime);
             }
         }
         return(bb.Array());
     }
     if (e.Index == 12)
     {
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt8((byte)DataType.Array);
         if (GroupTable == null)
         {
             bb.SetUInt8(0);
         }
         else
         {
             GXCommon.SetObjectCount(GroupTable.Length, bb);
             foreach (UInt16 it in GroupTable)
             {
                 GXCommon.SetData(settings, bb, DataType.UInt16, it);
             }
         }
         return(bb.Array());
     }
     if (e.Index == 13)
     {
         return(MaxJoinWaitTime);
     }
     if (e.Index == 14)
     {
         return(PathDiscoveryTime);
     }
     if (e.Index == 15)
     {
         return(ActiveKeyIndex);
     }
     if (e.Index == 16)
     {
         return(MetricType);
     }
     if (e.Index == 17)
     {
         return(CoordShortAddress);
     }
     if (e.Index == 18)
     {
         return(DisableDefaultRouting);
     }
     if (e.Index == 19)
     {
         return(DeviceType);
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return(null);
 }
        object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
        {
            GXByteBuffer bb;

            switch (e.Index)
            {
            case 1:
                return(GXCommon.LogicalNameToBytes(LogicalName));

            case 2:
                if (string.IsNullOrEmpty(Operator))
                {
                    return(null);
                }
                return(ASCIIEncoding.ASCII.GetBytes(Operator));

            case 3:
                return(Status);

            case 4:
                return(CircuitSwitchStatus);

            case 5:
                return(PacketSwitchStatus);

            case 6:
                bb = new GXByteBuffer();
                bb.SetUInt8(DataType.Structure);
                if (Version == 0)
                {
                    bb.SetUInt8(4);
                    GXCommon.SetData(settings, bb, DataType.UInt16, CellInfo.CellId);
                }
                else
                {
                    bb.SetUInt8(7);
                    GXCommon.SetData(settings, bb, DataType.UInt32, CellInfo.CellId);
                }
                GXCommon.SetData(settings, bb, DataType.UInt16, CellInfo.LocationId);
                GXCommon.SetData(settings, bb, DataType.UInt8, CellInfo.SignalQuality);
                GXCommon.SetData(settings, bb, DataType.UInt8, CellInfo.Ber);
                if (Version > 0)
                {
                    GXCommon.SetData(settings, bb, DataType.UInt16, CellInfo.MobileCountryCode);
                    GXCommon.SetData(settings, bb, DataType.UInt16, CellInfo.MobileNetworkCode);
                    GXCommon.SetData(settings, bb, DataType.UInt32, CellInfo.ChannelNumber);
                }
                return(bb.Array());

            case 7:
                bb = new GXByteBuffer();
                bb.SetUInt8(DataType.Array);
                if (AdjacentCells == null)
                {
                    bb.SetUInt8(0);
                }
                else
                {
                    bb.SetUInt8((byte)AdjacentCells.Count);
                }
                foreach (AdjacentCell it in AdjacentCells)
                {
                    bb.SetUInt8(DataType.Structure);
                    bb.SetUInt8(2);
                    GXCommon.SetData(settings, bb, Version == 0 ? DataType.UInt16 : DataType.UInt32, it.CellId);
                    GXCommon.SetData(settings, bb, DataType.UInt8, it.SignalQuality);
                }
                return(bb.Array());

            case 8:
                return(CaptureTime);
            }
            e.Error = ErrorCode.ReadWriteDenied;
            return(null);
        }
Beispiel #36
0
        /// <summary>
        /// Import server settings and COSEM objects from GXDLMSDirector trace.
        /// </summary>
        /// <param name="server">Server where settings are updated.</param>
        /// <param name="data">GXDLMSDirector trace in byte array.</param>
        public static void Import(GXDLMSServer server, byte[] data)
        {
            GXDLMSTranslator translator = new GXDLMSTranslator(TranslatorOutputType.StandardXml);

            translator.CompletePdu      = true;
            translator.PduOnly          = true;
            translator.OmitXmlNameSpace = translator.OmitXmlDeclaration = true;
            XmlDocument           doc      = new XmlDocument();
            List <ValueEventArgs> targets  = new List <ValueEventArgs>();
            GXDLMSSettings        settings = new GXDLMSSettings(true);
            GXByteBuffer          pdu      = new GXByteBuffer();
            GXByteBuffer          bb       = new GXByteBuffer(data);

            server.InterfaceType = GXDLMSTranslator.GetDlmsFraming(bb);
            bool         lastBlock = true;
            GXByteBuffer val       = new DLMS.GXByteBuffer();

            while (translator.FindNextFrame(bb, pdu, server.InterfaceType))
            {
                String xml = translator.MessageToXml(bb);
                if (xml != "")
                {
                    doc.LoadXml(xml);
                    foreach (XmlNode node in doc.ChildNodes[doc.ChildNodes.Count - 1].ChildNodes)
                    {
                        string name = doc.ChildNodes[doc.ChildNodes.Count - 1].Name;
                        if (name == "get-request")
                        {
                            server.UseLogicalNameReferencing = true;
                            GetLN(settings.Objects, targets, node.ChildNodes);
                        }
                        else if (name == "read-request")
                        {
                            List <short> items = GetSN(node.ChildNodes);

                            server.UseLogicalNameReferencing = false;
                            foreach (short it in items)
                            {
                                GXSNInfo i = GXDLMSSNCommandHandler.FindSNObject(settings.Objects, Convert.ToUInt16((it) & 0xFFFF));
                                targets.Add(new ValueEventArgs(i.Item, i.Index, 0, null));
                            }
                        }
                        else if (name == "read-response" ||
                                 name == "get-response")
                        {
                            if (targets != null)
                            {
                                List <string> items;
                                if (server.UseLogicalNameReferencing)
                                {
                                    items = GetLNValues(doc.ChildNodes[doc.ChildNodes.Count - 1].ChildNodes);
                                }
                                else
                                {
                                    items = GetSNValues(doc.ChildNodes[doc.ChildNodes.Count - 1].ChildNodes);
                                }

                                int pos = 0;
                                foreach (string it in items)
                                {
                                    if ("read-write-denied".Equals(it) ||
                                        "scope-of-access-violated".Equals(it) ||
                                        "object-unavailable".Equals(it))
                                    {
                                        ValueEventArgs ve = targets[pos];
                                        ve.Target.SetAccess(ve.Index, AccessMode.NoAccess);
                                        continue;
                                    }
                                    try
                                    {
                                        if (server.UseLogicalNameReferencing)
                                        {
                                            lastBlock = IsLastBlock(doc.ChildNodes[doc.ChildNodes.Count - 1].ChildNodes);
                                        }
                                        val.Set(translator.XmlToData(it));
                                        if (lastBlock)
                                        {
                                            if (settings.Objects.Count == 0)
                                            {
                                                GXDLMSClient c = new GXDLMSClient();
                                                c.UseLogicalNameReferencing = server.UseLogicalNameReferencing;
                                                settings.Objects            = c.ParseObjects(val, true);
                                                //Update OBIS code description.
                                                GXDLMSConverter converter = new GXDLMSConverter();
                                                converter.UpdateOBISCodeInformation(settings.Objects);
                                            }
                                            else
                                            {
                                                ValueEventArgs ve   = targets[pos];
                                                GXDataInfo     info = new GXDataInfo();
                                                ve.Value = GXCommon.GetData(server.Settings, val, info);
                                                if (ve.Value is byte[])
                                                {
                                                    DataType tp = ve.Target.GetUIDataType(ve.Index);
                                                    if (tp != DataType.None)
                                                    {
                                                        ve.Value = GXDLMSClient.ChangeType((byte[])ve.Value, tp, false);
                                                    }
                                                }
                                                ((IGXDLMSBase)ve.Target).SetValue(settings, ve);
                                            }
                                            val.Clear();
                                        }
                                    }
                                    catch (Exception)
                                    {
                                        ValueEventArgs ve = targets[pos];
                                        ve.Target.SetAccess(ve.Index, AccessMode.NoAccess);
                                    }
                                    ++pos;
                                }
                                if (lastBlock)
                                {
                                    targets.Clear();
                                }
                            }
                        }
                    }
                }
            }
            server.Items.Clear();
            server.Items.AddRange(settings.Objects);
        }
 private static byte[] GetAuthenticatedData(Gurux.DLMS.Enums.Security security, byte[] AuthenticationKey, byte[] plainText)
 {
     if (security == Gurux.DLMS.Enums.Security.Authentication)
     {
         GXByteBuffer tmp2 = new GXByteBuffer();
         tmp2.SetUInt8((byte)security);
         tmp2.Set(AuthenticationKey);
         tmp2.Set(plainText);
         return tmp2.Array();
     }
     else if (security == Gurux.DLMS.Enums.Security.Encryption)
     {
         return AuthenticationKey;
     }
     else if (security == Gurux.DLMS.Enums.Security.AuthenticationEncryption)
     {
         GXByteBuffer tmp2 = new GXByteBuffer();
         tmp2.SetUInt8((byte)security);
         tmp2.Set(AuthenticationKey);
         return tmp2.Array();
     }
     return null;
 }
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return this.LogicalName;
     }
     if (e.Index == 2)
     {
         return (byte)Mode;
     }
     if (e.Index == 3)
     {
         int cnt = ListeningWindow.Count;
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         //Add count
         GXCommon.SetObjectCount(cnt, data);
         if (cnt != 0)
         {
             foreach (var it in ListeningWindow)
             {
                 data.SetUInt8((byte)DataType.Structure);
                 data.SetUInt8((byte)2); //Count
                 GXCommon.SetData(settings, data, DataType.OctetString, it.Key); //start_time
                 GXCommon.SetData(settings, data, DataType.OctetString, it.Value); //end_time
             }
         }
         return data.Array();
     }
     if (e.Index == 4)
     {
         return Status;
     }
     if (e.Index == 5)
     {
         return NumberOfCalls;
     }
     if (e.Index == 6)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         //Add count
         GXCommon.SetObjectCount(2, data);
         GXCommon.SetData(settings, data, DataType.UInt8, NumberOfRingsInListeningWindow);
         GXCommon.SetData(settings, data, DataType.UInt8, NumberOfRingsOutListeningWindow);
         return data.Array();
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return null;
 }
 static internal byte[] EncryptAesGcm(AesGcmParameter param, byte[] plainText)
 {
     System.Diagnostics.Debug.WriteLine("Encrypt settings: " + param.ToString());
     param.CountTag = null;
     GXByteBuffer data = new GXByteBuffer();
     if (param.Type == CountType.Packet)
     {
         data.SetUInt8((byte)param.Security);
     }
     byte[] tmp = BitConverter.GetBytes(param.FrameCounter).Reverse().ToArray();
     byte[] aad = GetAuthenticatedData(param.Security, param.AuthenticationKey, plainText);
     GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(param.Security, true, param.BlockCipherKey,
             aad, GetNonse(param.FrameCounter, param.SystemTitle), null);
     // Encrypt the secret message
     if (param.Security != Gurux.DLMS.Enums.Security.Authentication)
     {
         gcm.Write(plainText);
     }
     byte[] ciphertext = gcm.FlushFinalBlock();
     if (param.Security == Gurux.DLMS.Enums.Security.Authentication)
     {
         if (param.Type == CountType.Packet)
         {
             data.Set(tmp);
         }
         if ((param.Type & CountType.Data) != 0)
         {
             data.Set(plainText);
         }
         if ((param.Type & CountType.Tag) != 0)
         {
             param.CountTag = gcm.GetTag();
             data.Set(param.CountTag);
         }
     }
     else if (param.Security == Gurux.DLMS.Enums.Security.Encryption)
     {
         if (param.Type == CountType.Packet)
         {
             data.Set(tmp);
         }
         data.Set(ciphertext);
     }
     else if (param.Security == Gurux.DLMS.Enums.Security.AuthenticationEncryption)
     {
         if (param.Type == CountType.Packet)
         {
             data.Set(tmp);
         }
         if ((param.Type & CountType.Data) != 0)
         {
             data.Set(ciphertext);
         }
         if ((param.Type & CountType.Tag) != 0)
         {
             param.CountTag = gcm.GetTag();
             data.Set(param.CountTag);
         }
     }
     else
     {
         throw new ArgumentOutOfRangeException("security");
     }
     if (param.Type == CountType.Packet)
     {
         GXByteBuffer tmp2 = new GXByteBuffer((ushort)(10 + data.Size));
         tmp2.SetUInt8(param.Tag);
         GXCommon.SetObjectCount(data.Size, tmp2);
         tmp2.Set(data.Array());
         return tmp2.Array();
     }
     byte[] crypted = data.Array();
     System.Diagnostics.Debug.WriteLine("Crypted: " + GXCommon.ToHex(crypted, true));
     return crypted;
 }
Beispiel #40
0
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return(GXCommon.LogicalNameToBytes(LogicalName));
     }
     if (e.Index == 2)
     {
         return(GXCommon.LogicalNameToBytes(DataLinkLayerReference));
     }
     if (e.Index == 3)
     {
         return(FromAddressString(IPAddress));
     }
     if (e.Index == 4)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         if (MulticastIPAddress == null)
         {
             //Object count is zero.
             data.SetUInt8(0);
         }
         else
         {
             GXCommon.SetObjectCount(MulticastIPAddress.Length, data);
             foreach (string it in MulticastIPAddress)
             {
                 GXCommon.SetData(settings, data, DataType.UInt32, FromAddressString(it));
             }
         }
         return(data.Array());
     }
     if (e.Index == 5)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         if (IPOptions == null)
         {
             //Object count is zero.
             data.SetUInt8(0);
         }
         else
         {
             GXCommon.SetObjectCount(IPOptions.Length, data);
             foreach (GXDLMSIp4SetupIpOption it in IPOptions)
             {
                 data.SetUInt8((byte)DataType.Structure);
                 data.SetUInt8(3);
                 GXCommon.SetData(settings, data, DataType.UInt8, it.Type);
                 GXCommon.SetData(settings, data, DataType.UInt8, it.Length);
                 GXCommon.SetData(settings, data, DataType.OctetString, it.Data);
             }
         }
         return(data.Array());
     }
     if (e.Index == 6)
     {
         //If subnet mask is not given.
         return(FromAddressString(SubnetMask));
     }
     if (e.Index == 7)
     {
         return(FromAddressString(GatewayIPAddress));
     }
     if (e.Index == 8)
     {
         return(this.UseDHCP);
     }
     if (e.Index == 9)
     {
         return(FromAddressString(PrimaryDNSAddress));
     }
     if (e.Index == 10)
     {
         return(FromAddressString(SecondaryDNSAddress));
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return(null);
 }
        private static void GetValue(GXByteBuffer bb, IList <object> objects, GXAsn1Settings s)
        {
            int            len;
            short          type;
            IList <object> tmp;

            byte[] tmp2;
            type = bb.GetUInt8();
            len  = GXCommon.GetObjectCount(bb);
            if (len > bb.Available)
            {
                throw new OutOfMemoryException("GXAsn1Converter.GetValue");
            }
            int connectPos = 0;

            if (s != null)
            {
                connectPos = s.XmlLength;
            }
            int    start     = bb.Position;
            string tagString = null;

            if (s != null)
            {
                s.AppendSpaces();
                if (type == (byte)BerType.Integer)
                {
                    if (len == 1 || len == 2 || len == 4 || len == 8)
                    {
                        tagString = s.GetTag((short)-len);
                    }
                    else
                    {
                        tagString = s.GetTag((byte)BerType.Integer);
                    }
                }
                else
                {
                    tagString = s.GetTag(type);
                }
                s.Append("<" + tagString + ">");
            }

            switch (type)
            {
            case (byte)(BerType.Constructed | BerType.Context):
            case ((byte)(BerType.Constructed | BerType.Context) | 1):
            case ((byte)(BerType.Constructed | BerType.Context) | 2):
            case ((byte)(BerType.Constructed | BerType.Context) | 3):
                if (s != null)
                {
                    s.Increase();
                }
                tmp = new GXAsn1Context();
                ((GXAsn1Context)tmp).Index = type & 0xF;
                objects.Add(tmp);
                while (bb.Position < start + len)
                {
                    GetValue(bb, tmp, s);
                }
                if (s != null)
                {
                    s.Decrease();
                }
                break;

            case (byte)(BerType.Constructed | BerType.Sequence):
                if (s != null)
                {
                    s.Increase();
                }
                tmp = new GXAsn1Sequence();
                objects.Add(tmp);
                int cnt = 0;
                while (bb.Position < start + len)
                {
                    ++cnt;
                    GetValue(bb, tmp, s);
                }
                if (s != null)
                {
                    // Append comment.
                    s.AppendComment(connectPos, Convert.ToString(cnt) + " elements.");
                    s.Decrease();
                }
                break;

            case (byte)(BerType.Constructed | BerType.Set):
                if (s != null)
                {
                    s.Increase();
                }
                tmp = new List <object>();
                GetValue(bb, tmp, s);
                if (tmp[0] is GXAsn1Sequence)
                {
                    tmp = (GXAsn1Sequence)tmp[0];
                    objects.Add(new KeyValuePair <object, object>(tmp[0], tmp[1]));
                }
                else
                {
                    KeyValuePair <object, object> e = new KeyValuePair <object, object>(tmp, null);
                    objects.Add(e);
                }
                if (s != null)
                {
                    s.Decrease();
                }
                break;

            case (byte)BerType.ObjectIdentifier:
                GXAsn1ObjectIdentifier oi = new GXAsn1ObjectIdentifier(bb, len);
                objects.Add(oi);
                if (s != null)
                {
                    string str = oi.Description;
                    if (str != null)
                    {
                        s.AppendComment(connectPos, str);
                    }
                    s.Append(oi.ToString());
                }

                break;

            case (byte)BerType.PrintableString:
                objects.Add(bb.GetString(len));
                if (s != null)
                {
                    s.Append(Convert.ToString(objects[objects.Count - 1]));
                }

                break;

            case (byte)BerType.Utf8StringTag:
                objects.Add(new GXAsn1Utf8String(bb.GetString(bb.Position, len)));
                bb.Position = bb.Position + len;
                if (s != null)
                {
                    s.Append(Convert.ToString(objects[objects.Count - 1]));
                }

                break;

            case (byte)BerType.Ia5String:
                objects.Add(new GXAsn1Ia5String(bb.GetString(len)));
                if (s != null)
                {
                    s.Append(Convert.ToString(objects[objects.Count - 1]));
                }
                break;

            case (byte)BerType.Integer:
                if (len == 1)
                {
                    objects.Add(bb.GetInt8());
                }
                else if (len == 2)
                {
                    objects.Add(bb.GetInt16());
                }
                else if (len == 4)
                {
                    objects.Add(bb.GetInt32());
                }
                else
                {
                    tmp2 = new byte[len];
                    bb.Get(tmp2);
                    objects.Add(new GXAsn1Integer(tmp2));
                }
                if (s != null)
                {
                    s.Append(Convert.ToString(objects[objects.Count - 1]));
                }
                break;

            case (byte)BerType.Null:
                objects.Add(null);
                break;

            case (byte)BerType.BitString:
                GXAsn1BitString tmp3 = new GXAsn1BitString(bb.SubArray(bb.Position, len));
                objects.Add(tmp3);
                bb.Position = bb.Position + len;
                if (s != null)
                {
                    // Append comment.
                    s.AppendComment(connectPos, Convert.ToString(tmp3.Length) + " bit.");
                    s.Append(tmp3.asString());
                }
                break;

            case (byte)BerType.UtcTime:
                tmp2 = new byte[len];
                bb.Get(tmp2);
                objects.Add(GetUtcTime(ASCIIEncoding.ASCII.GetString(tmp2)));
                if (s != null)
                {
                    s.Append(((DateTimeOffset)objects[objects.Count - 1]).UtcDateTime.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture));
                }
                break;

            case (byte)BerType.GeneralizedTime:
                tmp2 = new byte[len];
                bb.Get(tmp2);
                objects.Add(GXCommon.GetGeneralizedTime(ASCIIEncoding.ASCII.GetString(tmp2)));
                if (s != null)
                {
                    s.Append(Convert.ToString(objects[objects.Count - 1]));
                }
                break;

            case (byte)BerType.Context:
            case (byte)BerType.Context | 1:
                tmp2 = new byte[len];
                bb.Get(tmp2);
                objects.Add(tmp2);
                if (s != null)
                {
                    s.Append(GXCommon.ToHex(tmp2, false));
                }
                break;

            case (byte)BerType.OctetString:
                int t = bb.GetUInt8(bb.Position);
                switch (t)
                {
                case (byte)(BerType.Constructed | BerType.Sequence):
                case (byte)BerType.BitString:
                    if (s != null)
                    {
                        s.Increase();
                    }
                    GetValue(bb, objects, s);
                    if (s != null)
                    {
                        s.Decrease();
                    }
                    break;

                default:
                    tmp2 = new byte[len];
                    bb.Get(tmp2);
                    objects.Add(tmp2);
                    if (s != null)
                    {
                        s.Append(GXCommon.ToHex(tmp2, false));
                    }
                    break;
                }
                break;

            case (byte)BerType.Boolean:
                bool b = bb.GetUInt8() != 0;
                objects.Add(b);
                if (s != null)
                {
                    s.Append(Convert.ToString(b));
                }
                break;

            default:
                throw new System.ArgumentException("Invalid type: " + type);
            }
            if (s != null)
            {
                s.Append("</" + tagString + ">\r\n");
            }
        }
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return(GXCommon.LogicalNameToBytes(LogicalName));
     }
     if (e.Index == 2)
     {
         return(GXCommon.LogicalNameToBytes(PHYReference));
     }
     if (e.Index == 3)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         if (LCPOptions == null)
         {
             data.SetUInt8(0);
         }
         else
         {
             data.SetUInt8((byte)LCPOptions.Length);
             foreach (GXDLMSPppSetupLcpOption it in LCPOptions)
             {
                 data.SetUInt8((byte)DataType.Structure);
                 data.SetUInt8((byte)3);
                 GXCommon.SetData(settings, data, DataType.UInt8, it.Type);
                 GXCommon.SetData(settings, data, DataType.UInt8, it.Length);
                 GXCommon.SetData(settings, data, GXCommon.GetValueType(it.Data), it.Data);
             }
         }
         return(data.Array());
     }
     if (e.Index == 4)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Array);
         if (IPCPOptions == null)
         {
             data.SetUInt8(0);
         }
         else
         {
             data.SetUInt8((byte)IPCPOptions.Length);
             foreach (GXDLMSPppSetupIPCPOption it in IPCPOptions)
             {
                 data.SetUInt8((byte)DataType.Structure);
                 data.SetUInt8((byte)3);
                 GXCommon.SetData(settings, data, DataType.UInt8, it.Type);
                 GXCommon.SetData(settings, data, DataType.UInt8, it.Length);
                 GXCommon.SetData(settings, data, GXCommon.GetValueType(it.Data), it.Data);
             }
         }
         return(data.Array());
     }
     else if (e.Index == 5)
     {
         GXByteBuffer data = new GXByteBuffer();
         data.SetUInt8((byte)DataType.Structure);
         data.SetUInt8(2);
         GXCommon.SetData(settings, data, DataType.OctetString, UserName);
         GXCommon.SetData(settings, data, DataType.OctetString, Password);
         return(data.Array());
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return(null);
 }
 /// <summary>
 /// Convert ASN.1 PDU bytes to XML.
 /// </summary>
 /// <param name="value">Bytes to convert. </param>
 /// <returns> Converted XML. </returns>
 public static string PduToXml(GXByteBuffer value)
 {
     return(PduToXml(value, false));
 }
        object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
        {
            GXByteBuffer buff = new GXByteBuffer();
            object       ret;

            switch (e.Index)
            {
            case 1:
                ret = GXCommon.LogicalNameToBytes(LogicalName);
                break;

            case 2:
                ret = GetPushObjectList(settings);
                break;

            case 3:
                buff.SetUInt8(DataType.Structure);
                buff.SetUInt8(3);
                GXCommon.SetData(settings, buff, DataType.Enum, Service);
                if (Destination != null)
                {
                    GXCommon.SetData(settings, buff, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(Destination));
                }
                else
                {
                    GXCommon.SetData(settings, buff, DataType.OctetString, null);
                }
                GXCommon.SetData(settings, buff, DataType.Enum, Message);
                ret = buff.Array();
                break;

            case 4:
                buff.SetUInt8(DataType.Array);
                GXCommon.SetObjectCount(CommunicationWindow.Count, buff);
                foreach (KeyValuePair <GXDateTime, GXDateTime> it in CommunicationWindow)
                {
                    buff.SetUInt8(DataType.Structure);
                    buff.SetUInt8(2);
                    GXCommon.SetData(settings, buff, DataType.OctetString, it.Key);
                    GXCommon.SetData(settings, buff, DataType.OctetString, it.Value);
                }
                ret = buff.Array();
                break;

            case 5:
                ret = RandomisationStartInterval;
                break;

            case 6:
                ret = NumberOfRetries;
                break;

            case 7:
                ret = RepetitionDelay;
                break;

            default:
                e.Error = ErrorCode.ReadWriteDenied;
                ret     = null;
                break;
            }
            return(ret);
        }
Beispiel #45
0
        private void Init(byte[] data)
        {
            Attributes = new List <KeyValuePair <PkcsObjectIdentifier, object[]> >();
            GXAsn1Sequence seq = (GXAsn1Sequence)GXAsn1Converter.FromByteArray(data);

            if (seq.Count < 3)
            {
                throw new System.ArgumentException("Wrong number of elements in sequence.");
            }
            /////////////////////////////
            // CertificationRequestInfo ::= SEQUENCE {
            // version INTEGER { v1(0) } (v1,...),
            // subject Name,
            // subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
            // attributes [0] Attributes{{ CRIAttributes }}
            // }

            GXAsn1Sequence reqInfo = (GXAsn1Sequence)seq[0];

            Version = (CertificateVersion)(sbyte)reqInfo[0];
            Subject = GXAsn1Converter.GetSubject((GXAsn1Sequence)reqInfo[1]);
            // subject Public key info.
            GXAsn1Sequence subjectPKInfo = (GXAsn1Sequence)reqInfo[2];

            if (reqInfo.Count > 3)
            {
                //PkcsObjectIdentifier
                foreach (GXAsn1Sequence it in (GXAsn1Context)reqInfo[3])
                {
                    List <object> values = new List <object>();
                    foreach (object v in (List <object>)((KeyValuePair <object, object>)it[1]).Key)
                    {
                        values.Add(v);
                    }
                    Attributes.Add(new KeyValuePair <PkcsObjectIdentifier, object[]>(PkcsObjectIdentifierConverter.FromString(it[0].ToString()), values.ToArray()));
                }
            }
            GXAsn1Sequence tmp = (GXAsn1Sequence)subjectPKInfo[0];

            Algorithm = X9ObjectIdentifierConverter.FromString(tmp[0].ToString());
            if (Algorithm != X9ObjectIdentifier.IdECPublicKey)
            {
                object algorithm = Algorithm;
                if (Algorithm == X9ObjectIdentifier.None)
                {
                    algorithm = PkcsObjectIdentifierConverter.FromString(tmp[0].ToString());
                    if ((PkcsObjectIdentifier)algorithm == PkcsObjectIdentifier.None)
                    {
                        algorithm = tmp[0].ToString();
                    }
                }
                throw new Exception("Invalid PKCS #10 certificate algorithm. " + algorithm);
            }
            PublicKey = GXPublicKey.FromRawBytes(((GXAsn1BitString)subjectPKInfo[1]).Value);
            GXEcdsa.Validate(PublicKey);
            /////////////////////////////
            // signatureAlgorithm
            GXAsn1Sequence sign = (GXAsn1Sequence)seq[1];

            SignatureAlgorithm = HashAlgorithmConverter.FromString(sign[0].ToString());
            if (SignatureAlgorithm != HashAlgorithm.Sha256WithEcdsa && SignatureAlgorithm != HashAlgorithm.Sha384WithEcdsa)
            {
                throw new GXDLMSCertificateException("Invalid signature algorithm. " + sign[0].ToString());
            }
            if (sign.Count != 1)
            {
                SignatureParameters = sign[1];
            }
            /////////////////////////////
            // signature
            Signature = ((GXAsn1BitString)seq[2]).Value;
            GXEcdsa        e    = new GXEcdsa(PublicKey);
            GXAsn1Sequence tmp2 = (GXAsn1Sequence)GXAsn1Converter.FromByteArray(Signature);
            GXByteBuffer   bb   = new GXByteBuffer();
            int            size = SignatureAlgorithm == HashAlgorithm.Sha256WithEcdsa ? 32 : 48;

            //Some implementations might add extra byte. It must removed.
            bb.Set(((GXAsn1Integer)tmp2[0]).Value, ((GXAsn1Integer)tmp2[0]).Value.Length == size ? 0 : 1, size);
            bb.Set(((GXAsn1Integer)tmp2[1]).Value, ((GXAsn1Integer)tmp2[1]).Value.Length == size ? 0 : 1, size);
            if (!e.Verify(bb.Array(), GXAsn1Converter.ToByteArray(reqInfo)))
            {
                throw new ArgumentException("Invalid Signature.");
            }
        }
Beispiel #46
0
        ///<summary>
        /// Chipher text.
        ///</summary>
        ///<param name="settings">
        ///DLMS settings.
        ///</param>
        ///<param name="cipher">
        ///Cipher.
        ///</param>
        ///<param name="ic">
        ///Invocation counter.
        ///</param>
        ///<param name="data">
        ///Text to chipher.
        ///</param>
        ///<param name="secret">
        ///Secret.
        ///</param>
        ///<returns>
        ///Chiphered text.
        ///</returns>
        public static byte[] Secure(GXDLMSSettings settings, GXICipher cipher, UInt32 ic, byte[] data, byte[] secret)
        {
            byte[] tmp;
            if (settings.Authentication == Authentication.High)
            {
                int len = secret.Length;
                if (len % 16 != 0)
                {
                    len += 16 - (secret.Length % 16);
                }
                byte[] p = new byte[len];
                byte[] s = new byte[16];
                byte[] x = new byte[16];
                int    i;
                data.CopyTo(p, 0);
                secret.CopyTo(s, 0);
                for (i = 0; i < p.Length; i += 16)
                {
                    Buffer.BlockCopy(p, i, x, 0, 16);
                    GXAes128.Encrypt(x, s);
                    Buffer.BlockCopy(x, 0, p, i, 16);
                }
                Buffer.BlockCopy(p, 0, x, 0, 16);
                return(x);
            }
            // Get server Challenge.
            GXByteBuffer challenge = new GXByteBuffer();

            // Get shared secret
            if (settings.Authentication == Authentication.HighGMAC)
            {
                challenge.Set(data);
            }
            else
            {
                challenge.Set(data);
                challenge.Set(secret);
            }
            tmp = challenge.Array();
            if (settings.Authentication == Authentication.HighMD5)
            {
#if !WINDOWS_UWP
                using (MD5 md5Hash = MD5.Create())
                {
                    tmp = md5Hash.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighSHA1)
            {
#if !WINDOWS_UWP
                using (SHA1 sha = new SHA1CryptoServiceProvider())
                {
                    tmp = sha.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighSHA256)
            {
                //Windows UWP, IOS ad Android don't support this.
#if !WINDOWS_UWP && !__IOS__ && !__ANDROID__
                using (SHA256 sha = new SHA256CryptoServiceProvider())
                {
                    tmp = sha.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighGMAC)
            {
                //SC is always Security.Authentication.
                AesGcmParameter p = new AesGcmParameter(0, Enums.Security.Authentication, ic,
                                                        secret, cipher.BlockCipherKey, cipher.AuthenticationKey);
                p.Type = CountType.Tag;
                challenge.Clear();
                challenge.SetUInt8((byte)Enums.Security.Authentication);
                challenge.SetUInt32((UInt32)p.InvocationCounter);
                challenge.Set(GXDLMSChippering.EncryptAesGcm(p, tmp));
                tmp = challenge.Array();
                return(tmp);
            }
            return(data);
        }
Beispiel #47
0
 ///<summary>
 /// Chipher text.
 ///</summary>
 ///<param name="settings">
 ///DLMS settings. 
 ///</param>
 ///<param name="cipher">
 ///Cipher. 
 ///</param>
 ///<param name="ic">
 ///Invocation counter.
 ///</param>
 ///<param name="data">
 ///Text to chipher. 
 ///</param>
 ///<param name="secret">
 ///Secret. 
 ///</param>
 ///<returns>
 ///Chiphered text.
 ///</returns>
 public static byte[] Secure(GXDLMSSettings settings, GXICipher cipher, UInt32 ic, byte[] data, byte[] secret)
 {
     byte[] tmp;
     if (settings.Authentication == Authentication.High)
     {
         int len = secret.Length;
         if (len % 16 != 0)
         {
             len += 16 - (secret.Length % 16);
         }
         byte[] p = new byte[len];
         byte[] s = new byte[16];
         byte[] x = new byte[16];
         int i;
         data.CopyTo(p, 0);
         secret.CopyTo(s, 0);
         for (i = 0; i < p.Length; i += 16)
         {
             Buffer.BlockCopy(p, i, x, 0, 16);
             GXAes128.Encrypt(x, s);
             Buffer.BlockCopy(x, 0, p, i, 16);
         }
         Buffer.BlockCopy(p, 0, x, 0, 16);
         return x;
     }
     // Get server Challenge.
     GXByteBuffer challenge = new GXByteBuffer();
     // Get shared secret
     if (settings.Authentication == Authentication.HighGMAC)
     {
         challenge.Set(data);              
     }
     else
     {
         challenge.Set(data);
         challenge.Set(secret);
     }
     tmp = challenge.Array();
     if (settings.Authentication == Authentication.HighMD5)
     {
         using (MD5 md5Hash = MD5.Create())
         {
             tmp = md5Hash.ComputeHash(tmp);
             return tmp;
         }
     }
     else if (settings.Authentication == Authentication.HighSHA1)
     {
         using (SHA1 sha = new SHA1CryptoServiceProvider())
         {
             tmp = sha.ComputeHash(tmp);
             return tmp;
         }
     }
     else if (settings.Authentication == Authentication.HighGMAC)
     {
         //SC is always Security.Authentication.
         AesGcmParameter p = new AesGcmParameter(0, Security.Authentication, ic,
             secret, cipher.BlockCipherKey, cipher.AuthenticationKey);
         p.Type = CountType.Tag;
         challenge.Clear();
         challenge.SetUInt8((byte)Security.Authentication);
         challenge.SetUInt32(p.FrameCounter);
         challenge.Set(GXDLMSChippering.EncryptAesGcm(p, tmp));
         tmp = challenge.Array();
         return tmp;
     }
     return data;
 }
 void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         LogicalName = GXCommon.ToLogicalName(e.Value);
     }
     else if (e.Index == 2)
     {
         if (e.Value is byte[] v)
         {
             if (IsSec() || !GXByteBuffer.IsAsciiString(v))
             {
                 CalendarNameActive = GXCommon.ToHex(v, false);
             }
             else
             {
                 CalendarNameActive = ASCIIEncoding.ASCII.GetString(v);
             }
         }
         else
         {
             CalendarNameActive = Convert.ToString(e.Value);
         }
     }
     else if (e.Index == 3)
     {
         SeasonProfileActive = SetSeasonProfile(settings, e.Value);
     }
     else if (e.Index == 4)
     {
         WeekProfileTableActive = SetWeekProfileTable(settings, e.Value);
     }
     else if (e.Index == 5)
     {
         DayProfileTableActive = SetDayProfileTable(settings, e.Value);
     }
     else if (e.Index == 6)
     {
         if (e.Value is byte[] v)
         {
             if (IsSec() || !GXByteBuffer.IsAsciiString(v))
             {
                 CalendarNamePassive = GXCommon.ToHex(v, false);
             }
             else
             {
                 CalendarNamePassive = ASCIIEncoding.ASCII.GetString(v);
             }
         }
         else
         {
             CalendarNamePassive = Convert.ToString(e.Value);
         }
     }
     else if (e.Index == 7)
     {
         SeasonProfilePassive = SetSeasonProfile(settings, e.Value);
     }
     else if (e.Index == 8)
     {
         WeekProfileTablePassive = SetWeekProfileTable(settings, e.Value);
     }
     else if (e.Index == 9)
     {
         DayProfileTablePassive = SetDayProfileTable(settings, e.Value);
     }
     else if (e.Index == 10)
     {
         if (e.Value is byte[])
         {
             Time = (GXDateTime)GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime);
         }
         else
         {
             Time = new GXDateTime(Convert.ToDateTime(e.Value));
         }
     }
     else
     {
         e.Error = ErrorCode.ReadWriteDenied;
     }
 }
        private void GetAccessRights(GXDLMSSettings settings, GXDLMSObject item, GXDLMSServer server, GXByteBuffer data)
        {
            data.SetUInt8((byte)DataType.Structure);
            data.SetUInt8((byte)2);
            data.SetUInt8((byte)DataType.Array);
            int cnt = (item as IGXDLMSBase).GetAttributeCount();

            data.SetUInt8((byte)cnt);
            ValueEventArgs e;

            if (server != null)
            {
                e = new DLMS.ValueEventArgs(server, item, 0, 0, null);
            }
            else
            {
                e = new DLMS.ValueEventArgs(settings, item, 0, 0, null);
            }
            for (int pos = 0; pos != cnt; ++pos)
            {
                e.Index = pos + 1;
                AccessMode m;
                if (server != null)
                {
                    m = server.NotifyGetAttributeAccess(e);
                }
                else
                {
                    m = AccessMode.ReadWrite;
                }
                //attribute_access_item
                data.SetUInt8((byte)DataType.Structure);
                data.SetUInt8((byte)3);
                GXCommon.SetData(settings, data, DataType.Int8, e.Index);
                GXCommon.SetData(settings, data, DataType.Enum, m);
                GXCommon.SetData(settings, data, DataType.None, null);
            }
            data.SetUInt8((byte)DataType.Array);
            cnt = (item as IGXDLMSBase).GetMethodCount();
            data.SetUInt8((byte)cnt);
            for (int pos = 0; pos != cnt; ++pos)
            {
                e.Index = pos + 1;
                MethodAccessMode m;
                if (server != null)
                {
                    m = server.NotifyGetMethodAccess(e);
                }
                else
                {
                    m = MethodAccessMode.Access;
                }
                //attribute_access_item
                data.SetUInt8((byte)DataType.Structure);
                data.SetUInt8((byte)2);
                GXCommon.SetData(settings, data, DataType.Int8, pos + 1);
                GXCommon.SetData(settings, data, DataType.Enum, m);
            }
        }
Beispiel #50
0
        object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
        {
            if (e.Index == 1)
            {
                return(GXCommon.LogicalNameToBytes(LogicalName));
            }
            GXByteBuffer buff = new GXByteBuffer();

            if (e.Index == 2)
            {
                buff.SetUInt8(DataType.Array);
                GXCommon.SetObjectCount(PushObjectList.Count, buff);
                foreach (KeyValuePair <GXDLMSObject, GXDLMSCaptureObject> it in PushObjectList)
                {
                    buff.SetUInt8(DataType.Structure);
                    buff.SetUInt8(4);
                    GXCommon.SetData(settings, buff, DataType.UInt16, it.Key.ObjectType);
                    GXCommon.SetData(settings, buff, DataType.OctetString, GXCommon.LogicalNameToBytes(it.Key.LogicalName));
                    GXCommon.SetData(settings, buff, DataType.Int8, it.Value.AttributeIndex);
                    GXCommon.SetData(settings, buff, DataType.UInt16, it.Value.DataIndex);
                }
                return(buff.Array());
            }
            if (e.Index == 3)
            {
                buff.SetUInt8(DataType.Structure);
                buff.SetUInt8(3);
                GXCommon.SetData(settings, buff, DataType.UInt8, Service);
                if (Destination != null)
                {
                    GXCommon.SetData(settings, buff, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(Destination));
                }
                else
                {
                    GXCommon.SetData(settings, buff, DataType.OctetString, null);
                }
                GXCommon.SetData(settings, buff, DataType.UInt8, Message);
                return(buff.Array());
            }
            if (e.Index == 4)
            {
                buff.SetUInt8(DataType.Array);
                GXCommon.SetObjectCount(CommunicationWindow.Count, buff);
                foreach (KeyValuePair <GXDateTime, GXDateTime> it in CommunicationWindow)
                {
                    buff.SetUInt8(DataType.Structure);
                    buff.SetUInt8(2);
                    GXCommon.SetData(settings, buff, DataType.OctetString, it.Key);
                    GXCommon.SetData(settings, buff, DataType.OctetString, it.Value);
                }
                return(buff.Array());
            }
            if (e.Index == 5)
            {
                return(RandomisationStartInterval);
            }
            if (e.Index == 6)
            {
                return(NumberOfRetries);
            }
            if (e.Index == 7)
            {
                return(RepetitionDelay);
            }
            e.Error = ErrorCode.ReadWriteDenied;
            return(null);
        }
 void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         LogicalName = GXCommon.ToLogicalName(e.Value);
     }
     else if (e.Index == 2)
     {
         ObjectList.Clear();
         if (e.Value != null)
         {
             foreach (Object[] item in (Object[])e.Value)
             {
                 GXDLMSObject obj = GetObject(settings, item);
                 //Unknown objects are not shown.
                 if (obj is IGXDLMSBase)
                 {
                     ObjectList.Add(obj);
                 }
             }
         }
     }
     else if (e.Index == 3)
     {
         if (e.Value != null)
         {
             ClientSAP = Convert.ToByte(((Object[])e.Value)[0]);
             ServerSAP = Convert.ToUInt16(((Object[])e.Value)[1]);
         }
     }
     else if (e.Index == 4)
     {
         //Value of the object identifier encoded in BER
         if (e.Value is byte[])
         {
             GXByteBuffer arr = new GXByteBuffer(e.Value as byte[]);
             if (arr.GetUInt8(0) == 0x60)
             {
                 ApplicationContextName.JointIsoCtt            = arr.GetUInt8();
                 ApplicationContextName.Country                = arr.GetUInt8();
                 ApplicationContextName.CountryName            = arr.GetUInt8();
                 ApplicationContextName.IdentifiedOrganization = arr.GetUInt8();
                 ApplicationContextName.DlmsUA             = arr.GetUInt8();
                 ApplicationContextName.ApplicationContext = arr.GetUInt8();
                 ApplicationContextName.ContextId          = (ApplicationContextName)arr.GetUInt8();
             }
             else
             {
                 //Get Tag and Len.
                 if (arr.GetUInt8() != (int)BerType.Integer && arr.GetUInt8() != 7)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.JointIsoCtt = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.Country = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x12)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.CountryName = arr.GetUInt16();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.IdentifiedOrganization = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.DlmsUA = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.ApplicationContext = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 ApplicationContextName.ContextId = (ApplicationContextName)arr.GetUInt8();
             }
         }
         else if (e.Value != null)
         {
             Object[] arr = (Object[])e.Value;
             ApplicationContextName.JointIsoCtt            = Convert.ToByte(arr[0]);
             ApplicationContextName.Country                = Convert.ToByte(arr[1]);
             ApplicationContextName.CountryName            = Convert.ToUInt16(arr[2]);
             ApplicationContextName.IdentifiedOrganization = Convert.ToByte(arr[3]);
             ApplicationContextName.DlmsUA             = Convert.ToByte(arr[4]);
             ApplicationContextName.ApplicationContext = Convert.ToByte(arr[5]);
             ApplicationContextName.ContextId          = (ApplicationContextName)Convert.ToByte(arr[6]);
         }
     }
     else if (e.Index == 5)
     {
         if (e.Value != null)
         {
             Object[]     arr = (Object[])e.Value;
             GXByteBuffer bb  = new GXByteBuffer();
             GXCommon.SetBitString(bb, arr[0]);
             bb.SetUInt8(0, 0);
             XDLMSContextInfo.Conformance       = (Conformance)bb.GetUInt32();
             XDLMSContextInfo.MaxReceivePduSize = Convert.ToUInt16(arr[1]);
             XDLMSContextInfo.MaxSendPduSize    = Convert.ToUInt16(arr[2]);
             XDLMSContextInfo.DlmsVersionNumber = Convert.ToByte(arr[3]);
             XDLMSContextInfo.QualityOfService  = Convert.ToSByte(arr[4]);
             XDLMSContextInfo.CypheringInfo     = (byte[])arr[5];
         }
     }
     else if (e.Index == 6)
     {
         //Value of the object identifier encoded in BER
         if (e.Value is byte[])
         {
             GXByteBuffer arr = new GXByteBuffer(e.Value as byte[]);
             if (arr.GetUInt8(0) == 0x60)
             {
                 AuthenticationMechanismName.JointIsoCtt            = arr.GetUInt8();
                 AuthenticationMechanismName.Country                = arr.GetUInt8();
                 AuthenticationMechanismName.CountryName            = arr.GetUInt8();
                 AuthenticationMechanismName.IdentifiedOrganization = arr.GetUInt8();
                 AuthenticationMechanismName.DlmsUA = arr.GetUInt8();
                 AuthenticationMechanismName.AuthenticationMechanismName = arr.GetUInt8();
                 AuthenticationMechanismName.MechanismId = (Authentication)arr.GetUInt8();
             }
             else
             {
                 //Get Tag and Len.
                 if (arr.GetUInt8() != (int)BerType.Integer && arr.GetUInt8() != 7)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.JointIsoCtt = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.Country = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x12)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.CountryName = arr.GetUInt16();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.IdentifiedOrganization = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.DlmsUA = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.AuthenticationMechanismName = arr.GetUInt8();
                 //Get tag
                 if (arr.GetUInt8() != 0x11)
                 {
                     throw new ArgumentOutOfRangeException();
                 }
                 AuthenticationMechanismName.MechanismId = (Authentication)arr.GetUInt8();
             }
         }
         else if (e.Value != null)
         {
             Object[] arr = (Object[])e.Value;
             AuthenticationMechanismName.JointIsoCtt            = Convert.ToByte(arr[0]);
             AuthenticationMechanismName.Country                = Convert.ToByte(arr[1]);
             AuthenticationMechanismName.CountryName            = Convert.ToUInt16(arr[2]);
             AuthenticationMechanismName.IdentifiedOrganization = Convert.ToByte(arr[3]);
             AuthenticationMechanismName.DlmsUA = Convert.ToByte(arr[4]);
             AuthenticationMechanismName.AuthenticationMechanismName = Convert.ToByte(arr[5]);
             AuthenticationMechanismName.MechanismId = (Authentication)Convert.ToByte(arr[6]);
         }
     }
     else if (e.Index == 7)
     {
         Secret = (byte[])e.Value;
     }
     else if (e.Index == 8)
     {
         if (e.Value == null)
         {
             AssociationStatus = AssociationStatus.NonAssociated;
         }
         else
         {
             AssociationStatus = (AssociationStatus)Convert.ToInt32(e.Value);
         }
     }
     else if (e.Index == 9)
     {
         SecuritySetupReference = GXCommon.ToLogicalName(e.Value);
     }
     else if (e.Index == 10)
     {
         UserList.Clear();
         if (e.Value != null)
         {
             foreach (Object[] item in (Object[])e.Value)
             {
                 UserList.Add(new KeyValuePair <byte, string>(Convert.ToByte(item[0]), Convert.ToString(item[1])));
             }
         }
     }
     else if (e.Index == 11)
     {
         if (e.Value != null)
         {
             Object[] tmp = (Object[])e.Value;
             CurrentUser = new KeyValuePair <byte, string>(Convert.ToByte(tmp[0]), Convert.ToString(tmp[1]));
         }
         else
         {
             CurrentUser = new KeyValuePair <byte, string>(0, null);
         }
     }
     else
     {
         e.Error = ErrorCode.ReadWriteDenied;
     }
 }
Beispiel #52
0
        object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
        {
            object ret;

            switch (e.Index)
            {
            case 1:
                ret = GXCommon.LogicalNameToBytes(LogicalName);
                break;

            case 2:
                ret = InitiatorElectricalPhase;
                break;

            case 3:
                ret = DeltaElectricalPhase;
                break;

            case 4:
                ret = MaxReceivingGain;
                break;

            case 5:
                ret = MaxTransmittingGain;
                break;

            case 6:
                ret = SearchInitiatorThreshold;
                break;

            case 7:
            {
                GXByteBuffer bb = new GXByteBuffer();
                bb.SetUInt8(DataType.Structure);
                bb.SetUInt8(2);
                GXCommon.SetData(settings, bb, DataType.UInt32, MarkFrequency);
                GXCommon.SetData(settings, bb, DataType.UInt32, SpaceFrequency);
                ret = bb.Array();
                break;
            }

            case 8:
                ret = MacAddress;
                break;

            case 9:
            {
                GXByteBuffer bb = new GXByteBuffer();
                bb.SetUInt8(DataType.Array);
                if (MacGroupAddresses == null)
                {
                    bb.SetUInt8(0);
                }
                else
                {
                    GXCommon.SetObjectCount(MacGroupAddresses.Length, bb);
                    foreach (ushort it in MacGroupAddresses)
                    {
                        GXCommon.SetData(settings, bb, DataType.UInt16, it);
                    }
                }
                ret = bb.Array();
                break;
            }

            case 10:
                ret = Repeater;
                break;

            case 11:
                ret = RepeaterStatus;
                break;

            case 12:
                ret = MinDeltaCredit;
                break;

            case 13:
                ret = InitiatorMacAddress;
                break;

            case 14:
                ret = SynchronizationLocked;
                break;

            case 15:
                ret = TransmissionSpeed;
                break;

            default:
                e.Error = ErrorCode.ReadWriteDenied;
                ret     = null;
                break;
            }
            return(ret);
        }
    byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e)
    {
        //Check reply_to_HLS_authentication
        if (e.Index == 8)
        {
            UInt32 ic = 0;
            byte[] secret;
            if (settings.Authentication == Authentication.HighGMAC)
            {
                secret = settings.SourceSystemTitle;
                GXByteBuffer bb = new GXByteBuffer(e.Parameters as byte[]);
                bb.GetUInt8();
                ic = bb.GetUInt32();
            }
            else
            {
                secret = HlsSecret;
            }
            byte[] serverChallenge = GXSecure.Secure(settings, settings.Cipher, ic, settings.StoCChallenge, secret);
            byte[] clientChallenge = (byte[])e.Parameters;
            if (GXCommon.Compare(serverChallenge, clientChallenge))
            {
                if (settings.Authentication == Authentication.HighGMAC)
                {
                    secret = settings.Cipher.SystemTitle;
                    ic = settings.Cipher.FrameCounter;
                }
                else
                {
                    secret = HlsSecret;
                }
                settings.Connected = true;
                return GXSecure.Secure(settings, settings.Cipher, ic, settings.CtoSChallenge, secret);
            }
            else
            {
                // If the password does not match.
                settings.Connected = false;
                return null;
            }

        }
        else
        {
            e.Error = ErrorCode.ReadWriteDenied;
            return null;
        }
    }
Beispiel #54
0
 Gurux.DLMS.Enums.Security GXICipher.Decrypt(byte[] title, GXByteBuffer data)
 {
     AesGcmParameter p = new AesGcmParameter(title, BlockCipherKey, AuthenticationKey);
     byte[] tmp = GXDLMSChippering.DecryptAesGcm(p, data);
     data.Clear();
     data.Set(tmp);
     return p.Security;
 }
 /// <summary>
 /// Returns Association View.
 /// </summary>
 private GXByteBuffer GetObjects(GXDLMSSettings settings, ValueEventArgs e)
 {
     int cnt = ObjectList.Count;
     GXByteBuffer data = new GXByteBuffer();
     //Add count only for first time.
     if (settings.Index == 0)
     {
         settings.Count = (UInt16)cnt;
         data.SetUInt8((byte)DataType.Array);
         GXCommon.SetObjectCount(cnt, data);
     }
     ushort pos = 0;
     foreach (GXDLMSObject it in ObjectList)
     {
         ++pos;
         if (!(pos <= settings.Index))
         {
             data.SetUInt8((byte)DataType.Structure);
             //Count
             data.SetUInt8((byte)4);
             //base address.
             GXCommon.SetData(settings, data, DataType.Int16, it.ShortName);
             //ClassID
             GXCommon.SetData(settings, data, DataType.UInt16, it.ObjectType);
             //Version
             GXCommon.SetData(settings, data, DataType.UInt8, 0);
             //LN
             GXCommon.SetData(settings, data, DataType.OctetString, it.LogicalName);
             ++settings.Index;
             //If PDU is full.
             if (!e.SkipMaxPduSize && data.Size >= settings.MaxPduSize)
             {
                 break;
             }
         }
     }
     return data;
 }
Beispiel #56
0
 ///<summary>
 ///Convert Array to DLMS bytes.
 ///</summary>
 ///<param name="buff">
 ///Byte buffer where data is write.
 ///</param>
 ///<param name="value">
 ///Added value.
 ///</param>
 private static void SetArray(GXDLMSSettings settings, GXByteBuffer buff, object value)
 {
     if (value != null)
     {
         object[] arr = (object[])value;
         SetObjectCount(arr.Length, buff);
         foreach (object it in arr)
         {
             SetData(settings, buff, GetValueType(it), it);
         }
     }
     else
     {
         SetObjectCount(0, buff);
     }
 }
Beispiel #57
0
        object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
        {
            if (e.Index == 1)
            {
                return(this.LogicalName);
            }
            else if (e.Index == 2)
            {
                GXByteBuffer data = new GXByteBuffer();
                data.SetUInt8((byte)DataType.Structure);
                data.SetUInt8(3);
                if (MonitoredValue == null)
                {
                    GXCommon.SetData(settings, data, DataType.Int16, 0);
                    GXCommon.SetData(settings, data, DataType.OctetString, "0.0.0.0.0.0");
                    GXCommon.SetData(settings, data, DataType.UInt8, 0);
                }
                else
                {
                    GXCommon.SetData(settings, data, DataType.Int16, MonitoredValue.ObjectType);
                    GXCommon.SetData(settings, data, DataType.OctetString, MonitoredValue.LogicalName);
                    GXCommon.SetData(settings, data, DataType.UInt8, MonitoredAttributeIndex);
                }
                return(data.Array());
            }
            else if (e.Index == 3)
            {
                return(ThresholdActive);
            }
            else if (e.Index == 4)
            {
                return(ThresholdNormal);
            }
            else if (e.Index == 5)
            {
                return(ThresholdEmergency);
            }
            else if (e.Index == 6)
            {
                return(MinOverThresholdDuration);
            }
            else if (e.Index == 7)
            {
                return(MinUnderThresholdDuration);
            }
            else if (e.Index == 8)
            {
                GXByteBuffer data = new GXByteBuffer();
                data.SetUInt8((byte)DataType.Structure);
                data.SetUInt8(3);
                GXCommon.SetData(settings, data, DataType.UInt16, EmergencyProfile.ID);
                GXCommon.SetData(settings, data, DataType.OctetString, EmergencyProfile.ActivationTime);
                GXCommon.SetData(settings, data, DataType.UInt32, EmergencyProfile.Duration);
                return(data.Array());
            }
            else if (e.Index == 9)
            {
                GXByteBuffer data = new GXByteBuffer();
                data.SetUInt8((byte)DataType.Array);
                if (EmergencyProfileGroupIDs == null)
                {
                    data.SetUInt8(0);
                }
                else
                {
                    data.SetUInt8((byte)EmergencyProfileGroupIDs.Length);
                    foreach (object it in EmergencyProfileGroupIDs)
                    {
                        GXCommon.SetData(settings, data, DataType.UInt16, it);
                    }
                }

                return(data.Array());
            }
            else if (e.Index == 10)
            {
                return(EmergencyProfileActive);
            }
            else if (e.Index == 11)
            {
                GXByteBuffer data = new GXByteBuffer();
                data.SetUInt8((byte)DataType.Structure);
                data.SetUInt8(2);
                data.SetUInt8((byte)DataType.Structure);
                data.SetUInt8(2);
                GXCommon.SetData(settings, data, DataType.OctetString, ActionOverThreshold.LogicalName);
                GXCommon.SetData(settings, data, DataType.UInt16, ActionOverThreshold.ScriptSelector);
                data.SetUInt8((byte)DataType.Structure);
                data.SetUInt8(2);
                GXCommon.SetData(settings, data, DataType.OctetString, ActionUnderThreshold.LogicalName);
                GXCommon.SetData(settings, data, DataType.UInt16, ActionUnderThreshold.ScriptSelector);
                return(data.Array());
            }
            e.Error = ErrorCode.ReadWriteDenied;
            return(null);
        }
Beispiel #58
0
 ///<summary>
 ///Convert UTC string to DLMS bytes.
 ///</summary>
 ///<param name="buff">
 ///Byte buffer where data is write.
 ///</param>
 ///<param name="value">
 ///Added value.
 ///</param>
 private static void SetUtcString(GXByteBuffer buff, object value)
 {
     if (value != null)
     {
         byte[] tmp = ASCIIEncoding.UTF8.GetBytes(Convert.ToString(value));
         SetObjectCount(tmp.Length, buff);
         buff.Set(tmp);
     }
     else
     {
         buff.SetUInt8(0);
     }
 }
Beispiel #59
0
        /// <summary>
        /// Import server settings and COSEM objects from GXDLMSDirector trace.
        /// </summary>
        /// <param name="server">Server where settings are updated.</param>
        /// <param name="data">GXDLMSDirector trace in byte array.</param>
        public static void Import(GXDLMSServer server, byte[] data)
        {
            GXDLMSTranslator translator = new GXDLMSTranslator(TranslatorOutputType.StandardXml);
            translator.CompletePdu = true;
            translator.PduOnly = true;
            XmlDocument doc = new XmlDocument();
            List<ValueEventArgs> targets = new List<ValueEventArgs>();
            GXDLMSSettings settings = new GXDLMSSettings(true);
            GXByteBuffer pdu = new GXByteBuffer();
            GXByteBuffer bb = new GXByteBuffer(data);
            server.InterfaceType = GXDLMSTranslator.GetDlmsFraming(bb);
            bool lastBlock = true;
            GXByteBuffer val = new DLMS.GXByteBuffer();
            while (translator.FindNextFrame(bb, pdu, server.InterfaceType))
            {
                String xml = translator.MessageToXml(bb);
                if (xml != "")
                {
                    doc.LoadXml(xml);
                    foreach (XmlNode node in doc.ChildNodes[doc.ChildNodes.Count - 1].ChildNodes)
                    {
                        if (node.Name == "x:get-request")
                        {
                            server.UseLogicalNameReferencing = true;
                            GetLN(settings.Objects, targets, node.ChildNodes);
                        }
                        else if (node.Name == "x:readRequest")
                        {
                            List<short> items = GetSN(node.ChildNodes);

                            server.UseLogicalNameReferencing = false;
                            foreach (short it in items)
                            {
                                GXSNInfo i = GXDLMSSNCommandHandler.FindSNObject(settings.Objects, Convert.ToUInt16((it) & 0xFFFF));
                                targets.Add(new ValueEventArgs(i.Item, i.Index, 0, null));
                            }
                        }
                        else if (node.Name == "x:readResponse" ||
                                 node.Name == "x:get-response")
                        {
                            if (targets != null)
                            {
                                List<string> items;
                                if (server.UseLogicalNameReferencing)
                                {
                                    items = GetLNValues(node.ChildNodes);
                                }
                                else
                                {
                                    items = GetSNValues(node.ChildNodes);
                                }

                                int pos = 0;
                                foreach (string it in items)
                                {
                                    if ("read-write-denied".Equals(it) ||
                                            "scope-of-access-violated".Equals(it) ||
                                            "object-unavailable".Equals(it))
                                    {
                                        ValueEventArgs ve = targets[pos];
                                        ve.Target.SetAccess(ve.Index, AccessMode.NoAccess);
                                        continue;
                                    }
                                    try
                                    {
                                        if (server.UseLogicalNameReferencing)
                                        {
                                            lastBlock = IsLastBlock(node.ChildNodes);
                                        }
                                        val.Set(translator.XmlToData(it));
                                        if (lastBlock)
                                        {
                                            if (settings.Objects.Count == 0)
                                            {
                                                GXDLMSClient c = new GXDLMSClient();
                                                c.UseLogicalNameReferencing = server.UseLogicalNameReferencing;
                                                settings.Objects = c.ParseObjects(val, true);
                                                //Update OBIS code description.
                                                GXDLMSConverter converter = new GXDLMSConverter();
                                                converter.UpdateOBISCodeInformation(settings.Objects);
                                            }
                                            else
                                            {
                                                ValueEventArgs ve = targets[pos];
                                                GXDataInfo info = new GXDataInfo();
                                                ve.Value = GXCommon.GetData(server.Settings, val, info);
                                                if (ve.Value is byte[])
                                                {
                                                    DataType tp = ve.Target.GetUIDataType(ve.Index);
                                                    if (tp != DataType.None)
                                                    {
                                                        ve.Value = GXDLMSClient.ChangeType((byte[])ve.Value, tp);
                                                    }
                                                }
                                                ((IGXDLMSBase)ve.Target).SetValue(settings, ve);
                                            }
                                            val.Clear();
                                        }
                                    }
                                    catch (Exception)
                                    {
                                        ValueEventArgs ve = targets[pos];
                                        ve.Target.SetAccess(ve.Index, AccessMode.NoAccess);

                                    }
                                    ++pos;
                                }
                                if (lastBlock)
                                {
                                    targets.Clear();
                                }
                            }

                        }
                    }
                }
            }
            server.Items.Clear();
            server.Items.AddRange(settings.Objects);
        }
Beispiel #60
0
 object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e)
 {
     if (e.Index == 1)
     {
         return(GXCommon.LogicalNameToBytes(LogicalName));
     }
     if (e.Index == 2)
     {
         return(ShortAddress);
     }
     if (e.Index == 3)
     {
         return(RcCoord);
     }
     if (e.Index == 4)
     {
         return(PANId);
     }
     if (e.Index == 5)
     {
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt8((byte)DataType.Array);
         if (KeyTable == null)
         {
             bb.SetUInt8(0);
         }
         else
         {
             GXCommon.SetObjectCount(KeyTable.Count, bb);
             foreach (GXKeyValuePair <byte, byte[]> it in KeyTable)
             {
                 bb.SetUInt8((byte)DataType.Structure);
                 bb.SetUInt8(2);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.Key);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.Value);
             }
         }
         return(bb.Array());
     }
     if (e.Index == 6)
     {
         return(FrameCounter);
     }
     if (e.Index == 7)
     {
         return(ToneMask);
     }
     if (e.Index == 8)
     {
         return(TmrTtl);
     }
     if (e.Index == 9)
     {
         return(MaxFrameRetries);
     }
     if (e.Index == 10)
     {
         return(NeighbourTableEntryTtl);
     }
     if (e.Index == 11)
     {
         GXByteBuffer bb = new GXByteBuffer();
         bb.SetUInt8((byte)DataType.Array);
         if (NeighbourTable == null)
         {
             bb.SetUInt8(0);
         }
         else
         {
             GXCommon.SetObjectCount(NeighbourTable.Length, bb);
             foreach (GXDLMSNeighbourTable it in NeighbourTable)
             {
                 bb.SetUInt8((byte)DataType.Structure);
                 bb.SetUInt8(11);
                 GXCommon.SetData(settings, bb, DataType.UInt16, it.ShortAddress);
                 GXCommon.SetData(settings, bb, DataType.Boolean, it.Enabled);
                 GXCommon.SetData(settings, bb, DataType.BitString, it.ToneMap);
                 GXCommon.SetData(settings, bb, DataType.Enum, it.Modulation);
                 GXCommon.SetData(settings, bb, DataType.Int8, it.TxGain);
                 GXCommon.SetData(settings, bb, DataType.Enum, it.TxRes);
                 GXCommon.SetData(settings, bb, DataType.BitString, it.TxCoeff);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.Lqi);
                 GXCommon.SetData(settings, bb, DataType.Int8, it.PhaseDifferential);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.TMRValidTime);
                 GXCommon.SetData(settings, bb, DataType.UInt8, it.NeighbourValidTime);
             }
         }
         return(bb.Array());
     }
     if (e.Index == 12)
     {
         return(HighPriorityWindowSize);
     }
     if (e.Index == 13)
     {
         return(CscmFairnessLimit);
     }
     if (e.Index == 14)
     {
         return(BeaconRandomizationWindowLength);
     }
     if (e.Index == 15)
     {
         return(A);
     }
     if (e.Index == 16)
     {
         return(K);
     }
     if (e.Index == 17)
     {
         return(MinCwAttempts);
     }
     if (e.Index == 18)
     {
         return(CenelecLegacyMode);
     }
     if (e.Index == 19)
     {
         return(FccLegacyMode);
     }
     if (e.Index == 20)
     {
         return(MaxBe);
     }
     if (e.Index == 21)
     {
         return(MaxCsmaBackoffs);
     }
     if (e.Index == 22)
     {
         return(MinBe);
     }
     e.Error = ErrorCode.ReadWriteDenied;
     return(null);
 }