/// <summary>
        /// Decode beacon from frame
        /// </summary>
        /// <param name="frame"></param>
        /// <returns></returns>
        public bool ReadFromFrame(ref Frame frame)
        {
            if (frame == null)
                return false;

            // 7.2.2.1.2 Superframe Specification field
            if (frame.LengthDataUsed < 3)
                return false;
            int i = (int)frame.ReadUInt16(0);
            beaconOrder = (Byte)(i & 0xf);
            superframeOrder = (Byte)((i >> 4) & 0xf);
            finalCapSlot = (Byte)((i >> 8) & 0xf);
            batteryLifeExtension = (Byte)((i >> 12) & 1);
            panCoordinator = (Byte)((i >> 14) & 1);
            associationPermit = (Byte)((i >> 15) & 1);

            // 7.2.2.1.3 GTS Specification field
            i = (int)frame.ReadByte(2);
            gtsLength = (Byte)(i & 7);
            gtsPermit = (Byte)((i >> 7) & 1);

            frame.DeleteFromFront(3);

            // 7.2.2.1.4 GTS Directions field
            gtsDirectionsMask = 0;
            if (gtsLength > 0)
            {
                if (frame.LengthDataUsed < 1)
                    return false;
                i = (int)frame.ReadByte(0);
                gtsDirectionsMask = (Byte)(i & 0x7F);
                frame.DeleteFromFront(1);
            }

            // 7.2.2.1.5 GTS List field
            if (frame.LengthDataUsed < 3 * gtsLength)
                return false;
            gtsDescriptor = new GtsDescriptor[gtsLength];
            for (int k = 0; k < gtsLength; k++)
            {
                gtsDescriptor[k].deviceShortAddr = frame.ReadUInt16(0);
                i = (int)frame.ReadByte(2);
                gtsDescriptor[k].gtsStartingSlot = (Byte)(i & 0xF);
                gtsDescriptor[k].gtsLength = (Byte)((i >> 4) & 0xF);
                frame.DeleteFromFront(3);
            }

            // 7.2.2.1.6 Pending Address Specification field
            if (frame.LengthDataUsed < 1)
                return false;
            i = (int)frame.ReadByte(0);
            pendingShort = (i & 7);
            pendingExt = ((i >> 4) & 7);
            frame.DeleteFromFront(1);

            // 7.2.2.1.7 Address List field
            if (frame.LengthDataUsed < pendingShort * 2 + pendingExt * 8)
                return false;
            shortAddrPending = new UInt16[pendingShort];
            extAddrPending = new UInt64[pendingExt];
            for (int k = 0; k < pendingShort; k++)
            {
                shortAddrPending[k] = frame.ReadUInt16(0);
                frame.DeleteFromFront(2);
            }

            for (int k = 0; k < pendingExt; k++)
            {
                extAddrPending[k] = frame.ReadUInt64(0);
                frame.DeleteFromFront(8);
            }

            // 7.2.2.1.8 Beacon Payload field
            if (frame.LengthDataUsed > 0)
            {
                payload = frame;
                frame = null;
            }
            else
            {
                payload = null;
                Frame.Release(ref frame);
            }

            return true;
        }
Beispiel #2
0
 /// <summary>
 /// Decode DATA fragment payload
 /// </summary>
 /// <param name="payload">payload</param>
 /// <param name="nbFragments">number of fragments in the messge</param>
 /// <param name="fragmentIndex">index of the fragment</param>
 /// <param name="data">payload of the data fragment</param>
 public static void DecodeDataPayload(ref Frame payload, out byte nbFragments, out byte fragmentIndex, out Frame data)
 {
     if (payload.LengthDataUsed < 2)
         throw new ArgumentException("payload content too small", "payload");
     nbFragments = payload.ReadByte(0);
     fragmentIndex = payload.ReadByte(1);
     if (nbFragments == 0)
         throw new ArgumentOutOfRangeException("nbFragments");
     if (fragmentIndex >= nbFragments)
         throw new ArgumentOutOfRangeException("fragmentId");
     payload.DeleteFromFront(2);
     data = payload;
     payload = null;
 }
Beispiel #3
0
        /// <summary>
        /// Decodes a header
        /// </summary>
        /// <param name="frame">The frame containing the header</param>
        /// <param name="removeHeader">If true, the header will be removed from the frame after decoding</param>
        /// <returns>True on success, false on decoding error</returns>
        public bool ReadFromFrameHeader(Frame frame, bool removeHeader)
        {
            int len = 2 + 1; // fcs + seqNo

            // check minimum length
            if (frame.LengthDataUsed < len)
                return false;
            fcs.Value = frame.ReadUInt16Canonical(0);
            seqNo = frame.ReadByte(2);

            // calculate variable length
            len = Length();
            if (frame.LengthDataUsed < len)
                return false;

            AddressingMode dstMode = fcs.DstAddrMode;
            AddressingMode srcMode = fcs.SrcAddrMode;
            bool panIdCompression = fcs.PanIdCompression;
            int offset = 3;
            if (dstMode != AddressingMode.None)
            { // dstPanId
                dstPanId = frame.ReadUInt16Canonical(offset);
                offset += 2;
            }

            if (dstMode == AddressingMode.Short)
            { // dstAddrShort
                dstAddrShort = frame.ReadUInt16Canonical(offset);
                offset += 2;
            }

            if (dstMode == AddressingMode.Extended)
            { // dstAddrShort
                dstAddrExt = frame.ReadUInt64Canonical(offset);
                offset += 8;
            }

            if (srcMode != AddressingMode.None && !panIdCompression)
            { // srcPanId
                srcPanId = frame.ReadUInt16Canonical(offset);
                offset += 2;
            }

            if (srcMode == AddressingMode.Short)
            { // dstAddrShort
                srcAddrShort = frame.ReadUInt16Canonical(offset);
                offset += 2;
            }

            if (srcMode == AddressingMode.Extended)
            { // dstAddrShort
                srcAddrExt = frame.ReadUInt64Canonical(offset);
                offset += 8;
            }

            // FIXME: secHeader

            if (removeHeader)
                frame.DeleteFromFront(len);
            return true;
        }
Beispiel #4
0
        public bool ReadFromFrame(Frame frame)
        {
            if (frame == null || frame.LengthDataUsed < 1)
                return false;
            byte header = frame.ReadByte(0);
            if (header != (byte)Message.Report)
                return false;
            nodeCount = (frame.LengthDataUsed - 1) / 6;
            if (frame.LengthDataUsed != Length())
                return false;
            frame.DeleteFromFront(1);
            nodes = new Node[nodeCount];
            for (int i = 0; i < nodeCount; i++)
            {
                nodes[i].addr = frame.ReadUInt16(0);
                frame.DeleteFromFront(2);
                nodes[i].rxBps = frame.ReadUInt32(0);
                frame.DeleteFromFront(4);
            }

            return true;
        }
Beispiel #5
0
        public bool ReadFromFrame(Frame frame)
        {
            if (frame == null || frame.LengthDataUsed < 1)
                return false;
            byte header = frame.ReadByte(0);
            if (header != (byte)Message.Neighbors)
                return false;
            neighborCount = (frame.LengthDataUsed - 1) / 3;
            if (frame.LengthDataUsed != Length())
                return false;
            frame.DeleteFromFront(1);
            neighbors = new Neighbor[neighborCount];
            for (int i = 0; i < neighborCount; i++)
            {
                neighbors[i].shortAdr = frame.ReadUInt16(0);
                frame.DeleteFromFront(2);
                neighbors[i].lqi = frame.ReadByte(0);
                frame.DeleteFromFront(1);
            }

            return true;
        }
 /// <summary>
 /// Decode command frame
 /// </summary>
 /// <param name="frame">source buffer</param>
 /// <returns>True on success</returns>
 public bool ReadFromFrame(ref Frame frame)
 {
     if (frame == null || frame.LengthDataUsed < _lengthMin || frame.LengthDataUsed > _lengthMax)
         return false;
     if (_type != (Type)frame.ReadByte(0))
         return false;
     frame.DeleteFromFront(1);
     DecodePayload(frame);
     Frame.Release(ref frame);
     return true;
 }