/// <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; }