Exemple #1
0
 ///<summary>
 ///Retrieves the string that indicates the level of authentication, if any.
 ///</summary>
 internal void GetAuthenticationString(List <byte> data)
 {
     //If authentication is used.
     if (this.Authentication != Authentication.None)
     {
         //Add sender ACSE-requirements field component.
         data.Add(0x8A);
         data.Add(2);
         GXCommon.SetUInt16(0x0780, data);
         data.Add(0x8B);
         data.Add(7);
         byte[] p = { (byte)0x60, (byte)0x85, (byte)0x74, (byte)0x05, (byte)0x08, (byte)0x02, (byte)this.Authentication };
         data.AddRange(p);
         //Add Calling authentication information.
         int len = 0;
         if (Password != null)
         {
             len = Password.Length;
         }
         data.Add(0xAC);
         data.Add((byte)(2 + len));
         //Add authentication information.
         data.Add((byte)0x80);
         data.Add((byte)len);
         if (len != 0)
         {
             data.AddRange(Password);
         }
     }
 }
Exemple #2
0
        /// <summary>
        /// Reserved for internal use.
        /// </summary>
        /// <param name="buff"></param>
        /// <param name="type"></param>
        /// <param name="value"></param>
        public static void SetData(List <byte> buff, DataType type, object value)
        {
            bool        reverse = true;
            List <byte> tmp     = new List <byte>();

            //If byte array is added do not add type.
            if ((type == DataType.Array || type == DataType.Structure) && value is byte[])
            {
                buff.AddRange((byte[])value);
                return;
            }
            if (type == DataType.None)
            {
                value = null;
            }
            else if (type == DataType.Boolean)
            {
                value = (byte)(Convert.ToBoolean(value) ? 1 : 0);
            }
            else if (type == DataType.BitString)
            {
                byte val   = 0;
                int  index = 0;
                if (value is string)
                {
                    string str = value as string;
                    SetObjectCount(str.Length, tmp);
                    foreach (char it in str)
                    {
                        if (it == '1')
                        {
                            val |= (byte)(1 << index++);
                        }
                        else if (it == '0')
                        {
                            index++;
                        }
                        else
                        {
                            throw new ArgumentException("Not a bit string.");
                        }
                        if (index == 8)
                        {
                            index = 0;
                            tmp.Add(val);
                            val = 0;
                        }
                    }
                    if (index != 0)
                    {
                        tmp.Add(val);
                    }
                    value   = tmp.ToArray();
                    reverse = false;
                }
                else if (value is byte[])
                {
                    byte[] arr = value as byte[];
                    SetObjectCount(arr.Length, tmp);
                    tmp.AddRange(arr);
                    value   = tmp.ToArray();
                    reverse = false;
                }
                else if (value is bool[])
                {
                    bool[] arr = value as bool[];
                    SetObjectCount(arr.Length, tmp);
                    foreach (bool it in arr)
                    {
                        if (it)
                        {
                            val |= (byte)(1 << index++);
                        }
                        else
                        {
                            ++index;
                        }
                        if (index == 8)
                        {
                            index = 0;
                            tmp.Add(val);
                            val = 0;
                        }
                    }
                    if (index != 0)
                    {
                        tmp.Add(val);
                    }
                    value   = tmp.ToArray();
                    reverse = false;
                }
                else if (value == null)
                {
                    tmp.Add(0);
                    value   = tmp.ToArray();
                    reverse = false;
                }
                else
                {
                    throw new Exception("BitString must give as string.");
                }
            }
            else if (type == DataType.Int32)
            {
                value = Convert.ToInt32(value);
            }
            else if (type == DataType.UInt32)
            {
                value = Convert.ToUInt32(value);
            }
            else if (type == DataType.String)
            {
                if (value != null)
                {
                    string str = value.ToString();
                    SetObjectCount(str.Length, tmp);
                    tmp.AddRange(ASCIIEncoding.ASCII.GetBytes(str));
                }
                else
                {
                    SetObjectCount(0, tmp);
                }
                value   = tmp.ToArray();
                reverse = false;
            }
            else if (type == DataType.StringUTF8)
            {
                if (value != null)
                {
                    string str  = value.ToString();
                    byte[] tmp1 = ASCIIEncoding.UTF8.GetBytes(str);
                    SetObjectCount(tmp1.Length, tmp);
                    tmp.AddRange(tmp1);
                }
                else
                {
                    SetObjectCount(0, tmp);
                }
                value   = tmp.ToArray();
                reverse = false;
            }
            else if (type == DataType.Array || type == DataType.Structure)
            {
                if (value != null)
                {
                    Array arr = (Array)value;
                    SetObjectCount(arr.Length, tmp);
                    foreach (object it in arr)
                    {
                        SetData(tmp, GetValueType(it), it);
                    }
                }
                else
                {
                    SetObjectCount(0, tmp);
                }
                value   = tmp.ToArray();
                reverse = false;
            }
            else if (type == DataType.OctetString)
            {
                reverse = false;
                if (value is string)
                {
                    if ((value as string) == "")
                    {
                        SetObjectCount(0, tmp);
                        value = tmp.ToArray();
                    }
                    else
                    {
                        string[] items = (value as string).Split('.');
                        tmp.Clear();
                        SetObjectCount(items.Length, tmp);
                        foreach (string it in items)
                        {
                            tmp.Add(byte.Parse(it));
                        }
                        value = tmp.ToArray();
                    }
                }
                else if (value == null)
                {
                    SetObjectCount(0, tmp);
                    value = tmp.ToArray();
                }
                else if (value is byte[])
                {
                    SetObjectCount((value as byte[]).Length, tmp);
                    tmp.AddRange(value as byte[]);
                    value = tmp.ToArray();
                }
                else if (value is GXDateTime)
                {
                    value = GetDateTime(value as GXDateTime);
                }
                else if (value is DateTime)
                {
                    value = GetDateTime(new GXDateTime(Convert.ToDateTime(value)));
                }
                else
                {
                    value = Convert.ToString(value);
                }
            }
            else if (type == DataType.BinaryCodedDesimal)
            {
                if (!(value is string))
                {
                    throw new Exception("BCD value must give as string.");
                }
                string str = value.ToString().Trim();
                int    len = str.Length;
                if (len % 2 != 0)
                {
                    str = "0" + str;
                    ++len;
                }
                len /= 2;
                List <byte> val = new List <byte>(len);
                val.Add((byte)(len));
                for (int pos = 0; pos != len; ++pos)
                {
                    byte ch1 = byte.Parse(str.Substring(2 * pos, 1));
                    byte ch2 = byte.Parse(str.Substring(2 * pos + 1, 1));
                    val.Add((byte)(ch1 << 4 | ch2));
                }
                reverse = false;
                value   = val.ToArray();
            }
            else if (type == DataType.Int8)
            {
                value = Convert.ToSByte(value);
            }
            else if (type == DataType.Int16)
            {
                value = (short)Convert.ToInt32(value);
            }
            else if (type == DataType.UInt8)
            {
                value = Convert.ToByte(value);
            }
            else if (type == DataType.UInt16)
            {
                value = Convert.ToUInt16(value);
            }
            else if (type == DataType.CompactArray)
            {
                throw new Exception("Invalid data type.");
            }
            else if (type == DataType.Int64)
            {
                value = Convert.ToInt64(value);
            }
            else if (type == DataType.UInt64)
            {
                value = Convert.ToUInt64(value);
            }
            else if (type == DataType.Enum)
            {
                value = Convert.ToByte(value);
            }
            else if (type == DataType.Float32)
            {
                value = Convert.ToSingle(value);
            }
            else if (type == DataType.Float64)
            {
                value = Convert.ToDouble(value);
            }
            else if (type == DataType.DateTime)
            {
                type = DataType.OctetString;
                if (value is GXDateTime)
                {
                    value = GetDateTime(value as GXDateTime);
                }
                else
                {
                    value = GetDateTime(new GXDateTime(Convert.ToDateTime(value)));
                }
                reverse = false;
            }
            else if (type == DataType.Date)
            {
                GXDateTime dt;
                if (value is GXDateTime)
                {
                    dt = value as GXDateTime;
                }
                else if (value is DateTime)
                {
                    dt = new GXDateTime((DateTime)value);
                }
                else
                {
                    throw new Exception("Invalid date format.");
                }
                type = DataType.OctetString;
                //Add size
                tmp.Add(5);
                //Add year.
                if ((dt.Skip & DateTimeSkips.Year) != 0)
                {
                    GXCommon.SetUInt16(0xFFFF, tmp);
                }
                else
                {
                    GXCommon.SetUInt16((ushort)dt.Value.Year, tmp);
                }
                //Add month.
                if (dt.DaylightSavingsBegin)
                {
                    tmp.Add(0xFE);
                }
                else if (dt.DaylightSavingsEnd)
                {
                    tmp.Add(0xFD);
                }
                else if ((dt.Skip & DateTimeSkips.Month) != 0)
                {
                    tmp.Add(0xFF);
                }
                else
                {
                    tmp.Add((byte)dt.Value.Month);
                }

                if ((dt.Skip & DateTimeSkips.Day) != 0)
                {
                    tmp.Add(0xFF);
                }
                else
                {
                    tmp.Add((byte)dt.Value.Day);
                }
                //Week day is not spesified.
                tmp.Add(0xFF);
                value   = tmp.ToArray();
                reverse = false;
            }
            else if (type == DataType.Time)
            {
                GXDateTime dt;
                if (value is GXDateTime)
                {
                    dt = value as GXDateTime;
                }
                else if (value is DateTime)
                {
                    dt = new GXDateTime((DateTime)value);
                }
                else
                {
                    throw new Exception("Invalid date format.");
                }
                type = DataType.OctetString;
                //Add size
                tmp.Add(4);
                //Add time.
                if ((dt.Skip & DateTimeSkips.Hour) != 0)
                {
                    tmp.Add(0xFF);
                }
                else
                {
                    tmp.Add((byte)dt.Value.Hour);
                }

                if ((dt.Skip & DateTimeSkips.Minute) != 0)
                {
                    tmp.Add(0xFF);
                }
                else
                {
                    tmp.Add((byte)dt.Value.Minute);
                }

                if ((dt.Skip & DateTimeSkips.Second) != 0)
                {
                    tmp.Add(0xFF);
                }
                else
                {
                    tmp.Add((byte)dt.Value.Second);
                }
                tmp.Add((byte)0xFF); //Hundredths of second is not used.
                value   = tmp.ToArray();
                reverse = false;
            }
            else
            {
                throw new Exception("Invalid data type.");
            }
            buff.Add((byte)type);
            if (value != null)
            {
                byte[] data = Gurux.Shared.GXCommon.GetAsByteArray(value);
                if (reverse)
                {
                    Array.Reverse(data);
                }
                buff.AddRange(data);
            }
        }
Exemple #3
0
        static byte[] GetDateTime(GXDateTime dt)
        {
            if (dt.Value == DateTime.MinValue)
            {
                dt.Value = DateTime.SpecifyKind(new DateTime(2000, 1, 1).Date, DateTimeKind.Utc);
            }
            else if (dt.Value == DateTime.MaxValue)
            {
                dt.Value = DateTime.SpecifyKind(DateTime.Now.AddYears(1).Date, DateTimeKind.Utc);
            }
            DateTime tm;

            //If used normal time.
            if ((dt.Skip & DateTimeSkips.Devitation) == 0)
            {
                tm = dt.Value;
            }
            else //If devitation is skipped.
            {
                //If value is given as UTC time.
                if (TimeZone.CurrentTimeZone.GetUtcOffset(dt.Value).TotalMinutes == 0)
                {
                    tm = dt.Value;
                }
                else
                {
                    tm = dt.Value.ToUniversalTime();
                }
            }
            List <byte> tmp = new List <byte>();

            //Add size
            tmp.Add(12);
            if ((dt.Skip & DateTimeSkips.Year) == 0)
            {
                GXCommon.SetUInt16((ushort)tm.Year, tmp);
            }
            else
            {
                GXCommon.SetUInt16((ushort)0xFFFF, tmp);
            }
            if ((dt.Skip & DateTimeSkips.Month) == 0)
            {
                if (dt.DaylightSavingsBegin)
                {
                    tmp.Add(0xFE);
                }
                else if (dt.DaylightSavingsEnd)
                {
                    tmp.Add(0xFD);
                }
                else
                {
                    tmp.Add((byte)tm.Month);
                }
            }
            else
            {
                tmp.Add(0xFF);
            }
            if ((dt.Skip & DateTimeSkips.Day) == 0)
            {
                tmp.Add((byte)tm.Day);
            }
            else
            {
                tmp.Add(0xFF);
            }
            //Week day is not spesified.
            //Standard defines. tmp.Add(0xFF);
            tmp.Add(0xFF);
            //Add time.
            if ((dt.Skip & DateTimeSkips.Hour) == 0)
            {
                tmp.Add((byte)tm.Hour);
            }
            else
            {
                tmp.Add(0xFF);
            }

            if ((dt.Skip & DateTimeSkips.Minute) == 0)
            {
                tmp.Add((byte)tm.Minute);
            }
            else
            {
                tmp.Add(0xFF);
            }
            if ((dt.Skip & DateTimeSkips.Second) == 0)
            {
                tmp.Add((byte)tm.Second);
            }
            else
            {
                tmp.Add(0xFF);
            }

            if ((dt.Skip & DateTimeSkips.Ms) == 0)
            {
                tmp.Add((byte)(tm.Millisecond / 10));
            }
            else
            {
                tmp.Add((byte)0xFF); //Hundredths of second is not used.
            }
            //Add deviation.
            if ((dt.Skip & DateTimeSkips.Devitation) == 0)
            {
                short devitation = (short)TimeZone.CurrentTimeZone.GetUtcOffset(dt.Value).TotalMinutes;
                GXCommon.SetInt16(devitation, tmp);
            }
            else //deviation not used.
            {
                tmp.Add((byte)0x00);
                tmp.Add((byte)0x00);
            }
            //Add clock_status
            tmp.Add((byte)dt.Status);
            return(tmp.ToArray());
        }
Exemple #4
0
 ///<summary>
 ///Server generates AARE message.
 ///</summary>
 internal void GenerateAARE(List <byte> data, Authentication authentication, byte[] challenge, ushort maxReceivePDUSize, byte[] conformanceBlock, AssociationResult result, SourceDiagnostic diagnostic)
 {
     // Set AARE tag and length
     data.Add(0x61);
     ApplicationContextName.CodeData(data);
     //Result
     data.Add(0xA2);
     data.Add(3);            //len
     data.Add(2);            //Tag
     //Choice for result (INTEGER, universal)
     data.Add(1);            //Len
     data.Add((byte)result); //ResultValue
     //SourceDiagnostic
     data.Add(0xA3);
     data.Add(5);                //len
     data.Add(0xA1);             //Tag
     data.Add(3);                //len
     data.Add(2);                //Tag
     //Choice for result (INTEGER, universal)
     data.Add(1);                //Len
     data.Add((byte)diagnostic); //diagnostic
     if (diagnostic == SourceDiagnostic.AuthenticationRequired)
     {
         //Add server ACSE-requirenents field component.
         data.Add(0x88);
         data.Add(0x02);  //Len.
         GXCommon.SetUInt16(0x0780, data);
         //Add tag.
         data.Add(0x89);
         data.Add(0x07);//Len
         data.Add(0x60);
         data.Add(0x85);
         data.Add(0x74);
         data.Add(0x05);
         data.Add(0x08);
         data.Add(0x02);
         data.Add((byte)authentication);
         //Add tag.
         data.Add(0xAA);
         data.Add((byte)(2 + challenge.Length)); //Len
         data.Add(0x80);
         data.Add((byte)challenge.Length);
         data.AddRange(challenge);
     }
     //Add User Information
     data.Add(0xBE);                     //Tag
     data.Add(0x10);                     //Length for AARQ user field
     data.Add(0x04);                     //Coding the choice for user-information (Octet STRING, universal)
     data.Add(0xE);                      //Length
     data.Add(GXCommon.InitialResponce); // Tag for xDLMS-Initiate response
     data.Add(0x00);                     // Usage field for the response allowed component (not used)
     data.Add(6);                        // DLMSVersioNumber
     data.Add(0x5F);
     data.Add(0x1F);
     data.Add(0x04); // length of the conformance block
     data.Add(0x00); // encoding the number of unused bits in the bit string
     data.AddRange(conformanceBlock);
     GXCommon.SetUInt16(maxReceivePDUSize, data);
     //VAA Name VAA name (0x0007 for LN referencing and 0xFA00 for SN)
     if (UseLN)
     {
         GXCommon.SetUInt16(0x0007, data);
     }
     else
     {
         GXCommon.SetUInt16(0xFA00, data);
     }
     data.Insert(1, (byte)(data.Count - 1));
 }