/// <summary> /// Computes CRC-CCITT for the frame /// </summary> /// <param name="frame"></param> /// <returns></returns> public static UInt16 CalcCrc16Ccitt(Frame frame) { UInt16 crc = 0; // initial value int n = frame.LengthDataUsed; for (int i = 0; i < n; i++) { crc = (UInt16)(_crc16CcitTable[(crc ^ frame.ReadByte(i)) & 0xff] ^ (crc >> 8)); } return crc; }
/// <summary> /// Computes CRC-CCITT for the frame /// </summary> /// <param name="frame"></param> /// <returns></returns> public static UInt16 CalcCrc16Ccitt(Frame frame) { UInt16 crc = 0; // initial value int n = frame.LengthDataUsed; for (int i = 0; i < n; i++) { crc = (UInt16)(_crc16CcitTable[(crc ^ frame.ReadByte(i)) & 0xff] ^ (crc >> 8)); } return(crc); }
/// <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; }
/// <summary> /// Decode an ACK fragment payload /// </summary> /// <param name="payload">payload</param> /// <param name="lastFragmentSeqNumberReceived">last fragment sequence number received</param> /// <param name="fragmentMissingTable">table of indices of the missing fragments</param> public static void DecodeAckPayload(ref Frame payload, out byte lastFragmentSeqNumberReceived, out BitArray fragmentMissingTable) { if (payload.LengthDataUsed < 2) throw new ArgumentException("payload content too small", "payload"); lastFragmentSeqNumberReceived = payload.ReadByte(0); int nbFragments = (int)payload.ReadByte(1); byte[] byteArray = new byte[payload.LengthDataUsed - 2]; payload.ReadBytes(byteArray, 0, 2, payload.LengthDataUsed - 2); fragmentMissingTable = BitArray.FromByteArray(nbFragments, byteArray); Frame.Release(ref payload); }
/// <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; }
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; }
private void DataIndicationHandler( object sender, UInt16 source, UInt16 targetShortAddr, Frame frame) { lock (_msgReport) { Message msg = (Message)frame.ReadByte(0); switch (msg) { case Message.Data: { if (_testMode) { _monitor.Print("received frame from 0x" + HexConverter.ConvertUintToHex(source, 4) + ", sduHandle=" + frame.ReadByte(1) + ", len=" + frame.LengthDataUsed + " bytes"); } for (int i = 0; i < _msgReport.nodeCount; i++) { if (_msgReport.nodes[i].addr == source) { _msgReport.nodes[i].rxBps += (UInt32)frame.LengthDataUsed; return; } } if (_msgReport.nodeCount < _msgReport.nodes.Length) { _msgReport.nodes[_msgReport.nodeCount].addr = source; _msgReport.nodes[_msgReport.nodeCount].rxBps = (UInt32)frame.LengthDataUsed; _msgReport.nodeCount++; } break; } case Message.Report: { MsgReport rep = new MsgReport(); if (rep.ReadFromFrame(frame)) { if (_testMode) { _monitor.Print("Report from node 0x" + HexConverter.ConvertUintToHex(source, 4) + ":"); for (int i = 0; i < rep.nodeCount; i++) { _monitor.Print(" " + rep.nodes[i].rxBps + " bytes per second from 0x" + HexConverter.ConvertUintToHex(rep.nodes[i].addr, 4)); } } if (_coordinator) { StatusHandleReport(source, rep); } } break; } case Message.Neighbors: { MsgNeighbors neigh = new MsgNeighbors(); if (neigh.ReadFromFrame(frame)) { if (_testMode) { _monitor.Print("Neighbors from node 0x" + HexConverter.ConvertUintToHex(source, 4) + ":"); for (int i = 0; i < neigh.neighborCount; i++) { _monitor.Print(" 0x" + HexConverter.ConvertUintToHex(neigh.neighbors[i].shortAdr, 4) + ": " + neigh.neighbors[i].lqi); } } if (_coordinator) { StatusHandleNeighbors(source, neigh); } } break; } } } Frame.Release(ref frame); }
protected override void DecodePayload(Frame frame) { capabilities.FromByte(frame.ReadByte(0)); }
/// <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; }
/// <summary> /// Get type of frame containing Mac command frame /// </summary> /// <param name="frame"></param> /// <returns></returns> public static Type DecodeType(Frame frame) { if (frame == null || frame.LengthDataUsed == 0) return Type.reserved; return (Type)frame.ReadByte(0); }
protected override void DecodePayload(Frame frame) { byte b = frame.ReadByte(0); gtsLength = (byte)(b & 0xF); gtsDirection = (byte)((b >> 4) & 1); characteristicsType = (byte)((b >> 5) & 1); }
protected override void DecodePayload(Frame frame) { panId = frame.ReadUInt16(0); coordinatorShortAddr = frame.ReadUInt16(2); channel = frame.ReadByte(4); shortAddr = frame.ReadUInt16(5); if (frame.LengthDataUsed == 8) { channelPage = frame.ReadByte(7); channelPagePresent = true; } else { channelPagePresent = false; } }
protected override void DecodePayload(Frame frame) { reason = (Reason)frame.ReadByte(0); }
protected override void DecodePayload(Frame frame) { shortAddr = frame.ReadUInt16(0); status = (Status)frame.ReadByte(2); }
/// <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; }
void phy_DataIndicationDump(IPhyDataSap sender, Frame frame, byte linkQuality) { leds.color = Leds.Color.Green; string s = "recv: "; for (int i = 0; i < frame.LengthDataUsed; i++) { byte b = frame.ReadByte(i); s += HexConverter.ConvertUintToHex(b, 2) + " "; } Debug.Print(s); Frame.Release(ref frame); leds.color = Leds.Color.Off; }
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; }