Example #1
0
 public Message(uint type, FragmentedPacket packet, MemberParser parser)
     : base(packet.Buffer.Memory.Slice(4), 0, parser)
 {
     Type        = type;
     this.packet = packet;
     //Parse();
 }
Example #2
0
 public MessageStruct(Memory <byte> data, int offset, MemberParser parser, int count, MessageStruct parent)
     : this(data, offset, parser)
 {
     Parent     = parent;
     fieldCount = count;
     Parse();
 }
Example #3
0
 protected MessageStruct(Memory <byte> data, int offset, MemberParser parser)
     : this()
 {
     Offset     = offset;
     Data       = data;
     Parser     = parser;
     fieldCount = -1;
 }
Example #4
0
        public static int PopulateFields(MessageStruct messageStruct)
        {
            int           position = 0;
            int           offset   = messageStruct.Offset;
            Memory <byte> buffer   = messageStruct.Data;
            MemberParser  parser   = messageStruct.Parser;

            return(PopulateFields(messageStruct, parser, buffer, offset, ref position));
        }
Example #5
0
        public static int PopulateFields(MessageStruct messageStruct, MemberParser parser, Memory <byte> buffer, int offset, ref int position)
        {
            while (parser != null)
            {
                if (parser.PreAlignment != 0)
                {
                    int align = (position + offset) % parser.PreAlignment;
                    //Debug.WriteLine($"PreAlign {parser.MemberName} offset {offset} position {position} align {align} alignCheck {parser.PreAlignment}");
                    if (align > 0)
                    {
                        position += parser.PreAlignment - align;
                    }
                }

                bool condition = CheckCondition(messageStruct, parser);
                if (condition)
                {
                    int    fieldOffset = position;
                    object value       = GetFieldValue(messageStruct, parser, buffer, ref position);
                    if (value != null)
                    {
                        Field field = new Field();
                        field.Name   = parser.MemberName;
                        field.Offset = fieldOffset;
                        field.Type   = parser.MemberType;
                        field.Value  = value;
                        field.Length = position - fieldOffset;

                        messageStruct.Fields.Add(field);
                        messageStruct.FieldIndex.Add(field.Name, messageStruct.Fields.Count - 1);
                    }
                }

                if (parser.PostAlignment != 0)
                {
                    int align = (offset + position) % parser.PostAlignment;
                    //Debug.WriteLine($"PostAlign {parser.MemberName} offset {offset} position {position} ({offset + position}) align {align} alignCheck {parser.PostAlignment}");
                    if (align > 0)
                    {
                        position += parser.PostAlignment - align;
                    }
                }

                parser = parser.Next;
            }

            return(position);
        }
Example #6
0
 public MemberParser(MemberParser Source)
 {
     this.Next            = Source.Next;
     this.Child           = Source.Child;
     this.MemberType      = Source.MemberType;
     this.MemberName      = Source.MemberName;
     this.Condition       = Source.Condition;
     this.ConditionField  = Source.ConditionField;
     this.ConditionXor    = Source.ConditionXor;
     this.ConditionAnd    = Source.ConditionAnd;
     this.ConditionResult = Source.ConditionResult;
     this.LengthField     = Source.LengthField;
     this.LengthMask      = Source.LengthMask;
     this.LengthDelta     = Source.LengthDelta;
     this.PreAlignment    = Source.PreAlignment;
     this.PostAlignment   = Source.PostAlignment;
 }
Example #7
0
        public static Message Parse(FragmentedPacket packet, MessageDirection direction)
        {
            MemberParser parser = null;
            int          pos    = 0;
            uint         type   = packet.Buffer.Memory.Read <uint>(ref pos);

            if (direction == MessageDirection.Inbound)
            {
                incomingParsers.TryGetValue(type, out parser);
            }
            else
            {
                outgoingParsers.TryGetValue(type, out parser);
            }

            Message msg = new Message(type, packet, parser);

            return(msg);
        }
Example #8
0
        private static bool CheckCondition(MessageStruct messageStruct, MemberParser parser)
        {
            bool   result = true;
            object tmp    = null;

            if (parser.Condition != MemberParserCondition.None)
            {
                tmp = FindFieldValue(messageStruct, parser.ConditionField);
                if (tmp != null)
                {
                    long condCheck = Convert.ToInt64(tmp);
                    condCheck ^= parser.ConditionXor;
                    condCheck &= parser.ConditionAnd;
                    switch (parser.Condition)
                    {
                    case MemberParserCondition.EQ:
                        result = (condCheck == parser.ConditionResult);
                        break;

                    case MemberParserCondition.NE:
                        result = (condCheck != parser.ConditionResult);
                        break;

                    case MemberParserCondition.GE:
                        result = (condCheck >= parser.ConditionResult);
                        break;

                    case MemberParserCondition.GT:
                        result = (condCheck > parser.ConditionResult);
                        break;

                    case MemberParserCondition.LE:
                        result = (condCheck <= parser.ConditionResult);
                        break;

                    case MemberParserCondition.LT:
                        result = (condCheck < parser.ConditionResult);
                        break;
                    }
                }
            }
            return(result);
        }
Example #9
0
        private static void LoadMessages(XElement element)
        {
            XAttribute attr = element.Attribute(XName.Get("type"));

            if (attr == null)
            {
                return;
            }

            uint type = uint.Parse(attr.Value, NumberStyles.HexNumber);

            bool inbound  = true;
            bool outbound = false;

            attr = element.Attribute(XName.Get("direction"));
            if (attr != null)
            {
                if (string.Compare(attr.Value, "outbound", true, CultureInfo.CurrentCulture) == 0)
                {
                    inbound  = false;
                    outbound = true;
                }
                else if (string.Compare(attr.Value, "both", true, CultureInfo.CurrentCulture) == 0)
                {
                    outbound = true;
                }
            }
            if ((inbound && !incomingParsers.ContainsKey(type) ||
                 outbound && !outgoingParsers.ContainsKey(type)))
            {
                MemberParser parser = ParseStruct(element.Elements());

                if (inbound)
                {
                    incomingParsers.TryAdd(type, parser);
                }
                if (outbound)
                {
                    outgoingParsers.TryAdd(type, parser);
                }
            }
        }
Example #10
0
        public static int CountFields(MemberParser parser)
        {
            int result = 0;

            MemberParser itr = parser;

            while (itr != null)
            {
                if (itr.MemberType == MemberParserType.Case)
                {
                    result += CountFields(itr.Child);
                }
                else
                {
                    result++;
                }
            }

            return(result);
        }
Example #11
0
        private static void LoadTypes(XElement element)
        {
            XAttribute attr = element.Attribute(XName.Get("name"));

            if (attr == null)
            {
                return;
            }

            string name = attr.Value;

            MemberParser parser = null;

            if (typeParsers.TryGetValue(name, out parser))
            {
                return;
            }

            parser = new MemberParser();
            typeParsers.Add(name, parser);

            attr = element.Attribute(XName.Get("primitive"));
            if (attr != null && bool.Parse(attr.Value))
            {
                parser.MemberType = (MemberParserType)Enum.Parse(typeof(MemberParserType), name);
            }
            else
            {
                attr = element.Attribute(XName.Get("parent"));
                if (attr != null)
                {
                    parser.MemberType = (MemberParserType)Enum.Parse(typeof(MemberParserType), attr.Value);
                }
                else
                {
                    parser.MemberType = MemberParserType.Struct;
                    parser.Child      = ParseStruct(element.Elements());
                }
            }
        }
Example #12
0
        private static MemberParser ParseStruct(IEnumerable <XElement> elements)
        {
            MemberParser root    = new MemberParser();
            MemberParser current = root;
            MemberParser temp    = null;

            XAttribute attr;
            XAttribute value;
            long       longVal;

            foreach (XElement element in elements)
            {
                longVal = 0;
                XAttribute name = element.Attribute(XName.Get("name"));
                switch (element.Name.LocalName.ToLowerInvariant())
                {
                case "field":
                    attr = element.Attribute(XName.Get("type"));
                    if (attr != null && typeParsers.TryGetValue(attr.Value, out temp))
                    {
                        current.Next       = new MemberParser(temp);
                        current            = current.Next;
                        current.MemberName = name.Value;
                    }
                    break;

                case "mask":
                    value = element.Attribute(XName.Get("value"));
                    if (value != null)
                    {
                        current.Next         = new MemberParser();
                        current              = current.Next;
                        current.MemberType   = MemberParserType.Case;
                        current.ConditionAnd = long.Parse(value.Value.Substring(2), NumberStyles.HexNumber);
                        current.Child        = ParseStruct(element.Elements());
                    }
                    break;

                case "maskmap":
                    attr = element.Attribute(XName.Get("xor"));
                    if (attr != null)
                    {
                        longVal = long.Parse(attr.Value.Substring(2), NumberStyles.HexNumber);
                    }
                    current.Next = ParseStruct(element.Elements());
                    while (current.Next != null)
                    {
                        current                 = current.Next;
                        current.Condition       = MemberParserCondition.NE;
                        current.ConditionResult = 0;
                        current.ConditionField  = name.Value;
                        current.ConditionXor    = longVal;
                    }
                    break;

                case "case":
                    value = element.Attribute(XName.Get("value"));
                    if (value != null)
                    {
                        current.Next            = new MemberParser();
                        current                 = current.Next;
                        current.MemberType      = MemberParserType.Case;
                        current.ConditionResult = long.Parse(value.Value.Substring(2), NumberStyles.HexNumber);
                        current.Child           = ParseStruct(element.Elements());
                    }
                    break;

                case "switch":
                    attr    = element.Attribute(XName.Get("mask"));
                    longVal = -1;
                    if (attr != null)
                    {
                        longVal = long.Parse(attr.Value.Substring(2), NumberStyles.HexNumber);
                    }
                    current.Next = ParseStruct(element.Elements());
                    while (current.Next != null)
                    {
                        current                = current.Next;
                        current.Condition      = MemberParserCondition.EQ;
                        current.ConditionField = name.Value;
                        current.ConditionAnd   = longVal;
                    }
                    break;

                case "vector":
                    current.Next       = new MemberParser();
                    current            = current.Next;
                    current.MemberType = MemberParserType.Vector;
                    current.MemberName = name.Value;

                    attr = element.Attribute(XName.Get("length"));
                    current.LengthField = attr.Value;

                    attr    = element.Attribute(XName.Get("mask"));
                    longVal = -1;
                    if (attr != null)
                    {
                        longVal = long.Parse(attr.Value.Substring(2), NumberStyles.HexNumber);
                    }
                    current.LengthMask = longVal;

                    attr    = element.Attribute(XName.Get("skip"));
                    longVal = 0;
                    if (attr != null)
                    {
                        longVal = long.Parse(attr.Value);
                    }
                    current.LengthDelta = -(int)longVal;
                    current.Child       = ParseStruct(element.Elements());
                    break;

                case "align":
                    attr = element.Attribute(XName.Get("type"));
                    switch (attr.Value.ToLowerInvariant())
                    {
                    case "word":
                        current.PostAlignment = 2;
                        break;

                    case "dword":
                        current.PostAlignment = 4;
                        break;

                    case "qword":
                        current.PostAlignment = 8;
                        break;
                    }
                    break;
                }
            }

            if (root.PostAlignment != 0 && root.Next != null)
            {
                root.Next.PreAlignment = root.PostAlignment;
            }

            return(root.Next);
        }
Example #13
0
        private static object GetFieldValue(MessageStruct current, MemberParser parser, Memory <byte> buffer, ref int position)
        {
            switch (parser.MemberType)
            {
            case MemberParserType.BYTE:
                return(buffer.Read <byte>(ref position));

            case MemberParserType.WORD:
                return(buffer.Read <short>(ref position));

            case MemberParserType.PackedWORD:
            {
                short tmp = buffer.Read <byte>(ref position);
                if ((tmp & 0x80) != 0)
                {
                    tmp = (short)(((tmp & 0x7f) << 8) | buffer.Read <byte>(ref position));
                }
                return(tmp);
            }

            case MemberParserType.DWORD:
                return(buffer.Read <int>(ref position));

            case MemberParserType.PackedDWORD:
            {
                int tmp = buffer.Read <short>(ref position);
                if ((tmp & 0x8000) != 0)
                {
                    tmp = ((tmp & 0x7fff) << 16) + buffer.Read <short>(ref position);
                }
                return(tmp);
            }

            case MemberParserType.QWORD:
                return(buffer.Read <long>(ref position));

            case MemberParserType.@float:
                return(buffer.Read <float>(ref position));

            case MemberParserType.@double:
                return(buffer.Read <double>(ref position));

            case MemberParserType.String:
            {
                //Debug.WriteLine($"Extracting String value {parser.MemberName}");
                // strings need to be a multiple of 4 including length
                int lenlen = 2;
                int length = buffer.Read <short>(ref position);
                if (length == -1)
                {
                    lenlen += 4;
                    length  = buffer.Read <int>(ref position);
                }

                Memory <byte> tmp = buffer.Slice(position, length);
                position += length;

                int align = (position + current.Offset) % 4;
                if (align > 0)
                {
                    position += (4 - align);
                }

                return(System.Text.Encoding.ASCII.GetString(tmp.Span));
            }

            case MemberParserType.WString:
            {
                int lenlen = 1;
                int length = buffer.Read <byte>(ref position);
                if ((length & 0x80) != 0)
                {
                    lenlen++;
                    length = ((length & 0x7f) << 8) | buffer.Read <byte>(ref position);
                }

                Memory <byte> tmp = buffer.Slice(position, length * 2);

                position += length * 2;

                return(System.Text.Encoding.Unicode.GetString(tmp.Span));
            }

            case MemberParserType.Struct:
            {
                Memory <byte> tmp = buffer.Slice(position);
                MessageStruct ms  = new MessageStruct(tmp, current.Offset + position, parser.Child, current);
                position += ms.Length;
                return(ms);
            }

            case MemberParserType.Vector:
            {
                object tmp    = FindFieldValue(current, parser.LengthField);
                long   length = 0;
                if (tmp != null)
                {
                    length = Convert.ToInt64(tmp);
                }
                long mask = parser.LengthMask;
                length &= mask;
                if (mask != 0)
                {
                    while ((mask & 0x1) == 0)
                    {
                        length >>= 1;
                        mask   >>= 1;
                    }
                }

                Memory <byte> tmpData = buffer.Slice(position);
                MessageStruct ms      = new MessageStruct(tmpData, current.Offset + position, parser.Child, (int)(length + parser.LengthDelta), current);
                position += ms.Length;
                return(ms);
            }

            case MemberParserType.Case:
                PopulateFields(current, parser.Child, buffer, current.Offset, ref position);
                break;

            default:
                System.Diagnostics.Debug.WriteLine($"Invalid MemberParserType {parser.MemberType}");
                break;
            }

            return(null);
        }