GetUInt16() private static method

Get UInt16 value from DLMS data.
private static GetUInt16 ( GXByteBuffer buff, GXDataInfo info ) : object
buff GXByteBuffer ///Received DLMS data. ///
info GXDataInfo ///Data info. ///
return object
コード例 #1
0
        /// <summary>
        /// Reserved for internal use.
        /// </summary>
        internal static object GetData(byte[] buff, ref int pos, ActionType action, out int count, out int index, ref DataType type, ref int cachePosition)
        {
            count = 0;
            index = 0;
            object value = null;

            if (pos == buff.Length)
            {
                pos = -1;
                return(null);
            }
            bool knownType = type != DataType.None;

            if (!knownType)
            {
                type = (DataType)buff[pos++];
            }
            if (type == DataType.None)
            {
                return(value);
            }
            if (pos == buff.Length)
            {
                pos = -1;
                return(null);
            }
            int size = buff.Length - pos;

            if (type == DataType.Array ||
                type == DataType.Structure)
            {
                count = GXCommon.GetObjectCount(buff, ref pos);
                if (action == ActionType.Count)
                {
                    return(value); //Don't go further. Only object's count is resolved.
                }
                if (cachePosition > pos)
                {
                    pos = cachePosition;
                }
                size = buff.Length - pos;
                if (count != 0 && size < 1)
                {
                    pos = -1;
                    return(null);
                }
                List <object> arr = new List <object>(count);
                for (index = 0; index != count; ++index)
                {
                    DataType itemType = DataType.None;
                    int      colCount, colIndex;
                    int      tmpPos = 0;
                    object   tmp    = GetData(buff, ref pos, ActionType.None, out colCount, out colIndex, ref itemType, ref tmpPos);
                    if (colCount == colIndex && pos != -1)
                    {
                        arr.Add(tmp);
                    }
                    if (pos == -1)
                    {
                        break;
                    }
                    else
                    {
                        cachePosition = pos;
                    }
                }
                if (index == count && pos != -1)
                {
                    cachePosition = buff.Length;
                }
                value = arr.ToArray();
            }
            else if (type == DataType.Boolean)
            {
                value = buff[pos++] != 0;
            }
            else if (type == DataType.BitString)
            {
                int oldPos = pos;
                int cnt    = GetObjectCount(buff, ref pos);
                size -= pos - oldPos;
                double t = cnt;
                t /= 8;
                if (cnt % 8 != 0)
                {
                    ++t;
                }
                int byteCnt = (int)Math.Floor(t);
                if (size < byteCnt) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                string str = "";
                while (cnt > 0)
                {
                    str += ToBitString(buff[pos++], cnt);
                    cnt -= 8;
                }
                value = str;
            }
            else if (type == DataType.Int32)
            {
                if (size < 4) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.GetInt32(buff, ref pos);
            }
            else if (type == DataType.UInt32)
            {
                if (size < 4) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.GetUInt32(buff, ref pos);
            }
            else if (type == DataType.StringUTF8)
            {
                int len = 0;
                if (knownType)
                {
                    len = buff.Length;
                }
                else
                {
                    len = GXCommon.GetObjectCount(buff, ref pos);
                    if (buff.Length - pos < len) //If there is not enough data available.
                    {
                        pos = -1;
                        return(null);
                    }
                }
                if (len > 0)
                {
                    value = ASCIIEncoding.UTF8.GetString(GXCommon.RawData(buff, ref pos, len));
                }
                else
                {
                    value = "";
                }
            }
            else if (type == DataType.String)
            {
                int len = 0;
                if (knownType)
                {
                    len = buff.Length;
                }
                else
                {
                    len = GXCommon.GetObjectCount(buff, ref pos);
                    if (buff.Length - pos < len) //If there is not enough data available.
                    {
                        pos = -1;
                        return(null);
                    }
                }
                if (len > 0)
                {
                    bool octetString = false;
                    if (knownType)
                    {
                        //Check that this is not octet string.
                        foreach (byte it in buff)
                        {
                            if (it != 0 && it < 0x20)
                            {
                                octetString = true;
                                break;
                            }
                        }
                    }
                    if (octetString)
                    {
                        StringBuilder sb = new StringBuilder(3 * buff.Length);
                        foreach (byte it in buff)
                        {
                            sb.Append(it);
                            sb.Append('.');
                        }
                        sb.Remove(sb.Length - 1, 1);
                        value = sb.ToString();
                    }
                    else
                    {
                        //Remove '\0' from string if used.
                        while (len > 0 && buff[len - 1] == 0)
                        {
                            --len;
                        }
                        value = ASCIIEncoding.ASCII.GetString(GXCommon.RawData(buff, ref pos, len));
                    }
                }
            }
            //Example Logical name is octet string, so do not change to string...
            else if (type == DataType.OctetString)
            {
                int len = 0;
                if (knownType)
                {
                    len = buff.Length;
                }
                else
                {
                    len = GXCommon.GetObjectCount(buff, ref pos);
                    if (buff.Length - pos < len) //If there is not enough data available.
                    {
                        pos = -1;
                        return(null);
                    }
                }
                value = GXCommon.RawData(buff, ref pos, len);
            }
            else if (type == DataType.BinaryCodedDesimal)
            {
                int len;
                if (knownType)
                {
                    len = buff.Length;
                }
                else
                {
                    len = GXCommon.GetObjectCount(buff, ref pos);
                }
                StringBuilder bcd = new StringBuilder(len * 2);
                for (int a = 0; a != len; ++a)
                {
                    int idHigh = buff[pos] >> 4;
                    int idLow  = buff[pos] & 0x0F;
                    ++pos;
                    bcd.Append(string.Format("{0}{1}", idHigh, idLow));
                }
                return(bcd.ToString());
            }
            else if (type == DataType.Int8)
            {
                value = (sbyte)buff[pos++];
            }
            else if (type == DataType.Int16)
            {
                if (size < 2) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.GetInt16(buff, ref pos);
            }
            else if (type == DataType.UInt8)
            {
                value = buff[pos++];
            }
            else if (type == DataType.UInt16)
            {
                if (size < 2) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.GetUInt16(buff, ref pos);
            }
            else if (type == DataType.CompactArray)
            {
                throw new Exception("Invalid data type.");
            }
            else if (type == DataType.Int64)
            {
                if (size < 8) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.GetInt64(buff, ref pos);
            }
            else if (type == DataType.UInt64)
            {
                if (size < 8) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.GetUInt64(buff, ref pos);
            }
            else if (type == DataType.Enum)
            {
                if (size < 1) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = buff[pos++];
            }
            else if (type == DataType.Float32)
            {
                if (size < 4) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.ToFloat(buff, ref pos);
            }
            else if (type == DataType.Float64)
            {
                if (size < 8) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                value = GXCommon.ToDouble(buff, ref pos);
            }
            else if (type == DataType.DateTime)
            {
                if (size < 12) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                GXDateTime dt = new GXDateTime();
                //Get year.
                int year = GXCommon.GetUInt16(buff, ref pos);
                if (year == 0xFFFF || year == 0)
                {
                    year     = DateTime.MinValue.Year;
                    dt.Skip |= DateTimeSkips.Year;
                }
                //Get month
                int month = buff[pos++];
                if (month == 0 || month == 0xFF || month == 0xFE || month == 0xFD)
                {
                    month    = 1;
                    dt.Skip |= DateTimeSkips.Month;
                }
                int day = buff[pos++];
                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
                ++pos;
                //Get time.
                int hours = buff[pos++];
                if (hours == 0xFF)
                {
                    hours    = 0;
                    dt.Skip |= DateTimeSkips.Hour;
                }
                int minutes = buff[pos++];
                if (minutes == 0xFF)
                {
                    minutes  = 0;
                    dt.Skip |= DateTimeSkips.Minute;
                }
                int seconds = buff[pos++];
                if (seconds == 0xFF)
                {
                    seconds  = 0;
                    dt.Skip |= DateTimeSkips.Second;
                }
                int milliseconds = buff[pos++];
                if (milliseconds != 0xFF && milliseconds != 0)
                {
                    milliseconds *= 10;
                }
                else
                {
                    milliseconds = 0;
                    dt.Skip     |= DateTimeSkips.Ms;
                }
                int deviation = GXCommon.GetInt16(buff, ref pos);
                dt.Status = (ClockStatus)buff[pos++];
                if ((deviation & 0xFFFF) != 0x8000 && year != 1)
                {
                    dt.Value = DateTime.SpecifyKind(new DateTime(year, month, day, hours, minutes, seconds, milliseconds), DateTimeKind.Utc);
                    dt.Value = dt.Value.AddMinutes(deviation);
                    dt.Value = dt.Value.ToLocalTime();
                }
                else //Use current time if deviation is not defined.
                {
                    dt.Value = new DateTime(year, month, day, hours, minutes, seconds, milliseconds);
                }
                value = dt;
            }
            else if (type == DataType.Date)
            {
                if (size < 5) //If there is not enough data available.
                {
                    pos = 0xFF;
                    return(null);
                }
                //Get year.
                int year = GXCommon.GetUInt16(buff, ref pos);
                //IskraEmeco meter returns bytes in wrong order.
                if (year != 0xFFFF && year > 2100)
                {
                    pos -= 2;
                    year = buff[pos++] | buff[pos++] << 8;
                    //If Actaris SL 7000 and ACE 6000 returns invalid date.
                    if (year == 0x5C13)
                    {
                        year = -1;
                    }
                }
                //Get month
                int month = buff[pos++];
                int day   = buff[pos++];
                //Skip week day
                int DayOfWeek = buff[pos++];
                //If day of week are not used.
                GXDateTime dt = new GXDateTime(year, month, day, -1, -1, 1, -1);
                return(dt);
            }
            else if (type == DataType.Time)
            {
                if (size < 4) //If there is not enough data available.
                {
                    pos = -1;
                    return(null);
                }
                //Get time.
                int        hours        = buff[pos++];
                int        minutes      = buff[pos++];
                int        seconds      = buff[pos++];
                int        milliseconds = buff[pos++];
                GXDateTime dt           = new GXDateTime(-1, -1, -1, hours, minutes, seconds, milliseconds);
                value = dt;
            }
            else
            {
                throw new Exception("Invalid data type.");
            }
            return(value);
        }
コード例 #2
0
        ///<summary>
        ///EncodeData
        ///</summary>
        internal void EncodeData(byte[] buff, ref int index)
        {
            // Get AARE tag and length
            int tag = buff[index++];

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

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