private void HandleFragmentationMessageTerminated(object sender, FragmentationMessageTerminatedEventArgs args) { if (sender is InboundFragmentationMessage) { if ((args.FinalState != FragmentationMessageState.Final) || (args.FinalStatus != Status.Success)) { // do nothing. return; } InboundFragmentationMessage inMsg = sender as InboundFragmentationMessage; Frame receivedMessage = inMsg.RetrieveData(); if (receivedMessage != null) { DataIndicationHandler handler = _dataIndicationHandler; if (handler != null) { handler.Invoke(this, inMsg.Source, inMsg.Destination, receivedMessage); } else { Frame.Release(ref receivedMessage); } } } else if (sender is OutboundFragmentationMessage) { OutboundFragmentationMessage outMsg, newOutMsg; lock (_lock) { outMsg = sender as OutboundFragmentationMessage; ushort previousDestination = outMsg.Destination; _transmissionCharacteristicStorage.UpdateTransmissionCharacteristic(outMsg.Destination, outMsg.TimeoutForResending, outMsg.MaxFragmentsBeforeAck); // remove active message from repository _outboundAssociations.RemoveFragmentationMessage(outMsg); // try to start new message (if possible) DataRequestItem newItem; newOutMsg = null; if (_dataRequestQueueSet.Dequeue(previousDestination, out newItem)) { newOutMsg = CreateNewOutboundMessage(newItem); } } // after releasing the lock, call method in FragmentationMessage class. outMsg.NotifySender(args.FinalState, args.FinalStatus); outMsg.Dispose(); if (newOutMsg != null) { newOutMsg.SendNextDataFragment(true); } } }
public void HandleDataIndication6Low(UInt16 origAddr, UInt16 targetAddr, ref Frame sdu) { DataIndicationHandler ind = _dataIndicationHandler6Low; if (ind != null) { ind.Invoke(this, origAddr, targetAddr, sdu); sdu = null; } }
public void HandleDataIndication(UInt16 origAddr, UInt16 targetAddr, ref Frame sdu) { #if USE_FRAG _frag.HandleLowerLayerDataIndication(this, origAddr, targetAddr, sdu); sdu = null; #else DataIndicationHandler ind = _dataIndicationHandler; if (ind != null) { ind.Invoke(this, origAddr, targetAddr, sdu); sdu = null; } #endif }
public void DataRequest(ushort targetShortAddr, ref Frame sdu, byte sduHandle, DataConfirmHandler handler) { if (!_started) { if (handler != null) { handler.Invoke(this, sduHandle, Status.NotRunning); } return; } if (targetShortAddr == _localShortAddress) { // deliver frame to ourself if (handler != null) { handler.Invoke(this, sduHandle, Status.Success); } DataIndicationHandler ind = _dataIndicationHandler; if (ind != null) { ind.Invoke(this, targetShortAddr, targetShortAddr, sdu); sdu = null; } return; } DataRequestItem newItem = new DataRequestItem(targetShortAddr, ref sdu, sduHandle, handler); OutboundFragmentationMessage outMsg = null; bool queueFull = false; lock (_lock) { // check if one can send directly the message. if (null == _outboundAssociations.GetFragmentationMessage(_localShortAddress, targetShortAddr)) { outMsg = CreateNewOutboundMessage(newItem); } else { // there is already a message being sent to this address. Store to queue. if (!_dataRequestQueueSet.Add(newItem)) { queueFull = true; } } } // release the lock before calling method in FragmentMessage class if (outMsg != null) { outMsg.SendNextDataFragment(true); } else if (queueFull) { // queue is full. if (handler != null) { handler.Invoke(this, sduHandle, Status.Busy); } newItem.Dispose(); } }
private void ReceiveData( Header hdr, ref Frame frame, Byte linkQuality) { MacAddress srcAddr = new MacAddress(); // default: NoAddress MacAddress dstAddr = new MacAddress(); // default: NoAddress UInt16 srcPanId = State.cBroadcastPanId; UInt16 dstPanId = State.cBroadcastPanId; bool drop = (hdr.fcs.Version != Microsoft.SPOT.Wireless.IEEE_802_15_4.Mac.Frames.Version.IEEE2003 && hdr.fcs.Version != Microsoft.SPOT.Wireless.IEEE_802_15_4.Mac.Frames.Version.IEEE2006); if (!drop) { switch (hdr.fcs.DstAddrMode) { case AddressingMode.None: if (!_state.macPromiscousMode && !_state.panCoordinator) { drop = true; } break; case AddressingMode.Short: if (!_state.macPromiscousMode && ((hdr.dstAddrShort != _state.macShortAddr && hdr.dstAddrShort != State.cBroadcastShortAddr) || (hdr.dstPanId != _state.macPanId && hdr.dstPanId != State.cBroadcastPanId))) { drop = true; } else { dstAddr.ShortAddress = hdr.dstAddrShort; dstPanId = hdr.dstPanId; } break; case AddressingMode.Extended: if (!_state.macPromiscousMode && ((hdr.dstAddrExt != _state.aExtendedAddress || (hdr.dstPanId != _state.macPanId && hdr.dstPanId != State.cBroadcastPanId)))) { drop = true; } else { dstAddr.ExtendedAddress = hdr.dstAddrExt; dstPanId = hdr.dstPanId; } break; case AddressingMode.Reserved: drop = true; break; } } if (!drop) { bool havePanId = false; switch (hdr.fcs.SrcAddrMode) { case AddressingMode.None: if (dstAddr.Mode == MacAddressingMode.NoAddress) { drop = true; // at least one address must be valid } break; case AddressingMode.Short: srcAddr.ShortAddress = hdr.srcAddrShort; havePanId = true; break; case AddressingMode.Extended: srcAddr.ExtendedAddress = hdr.srcAddrExt; havePanId = true; break; case AddressingMode.Reserved: drop = true; break; } if (havePanId) { if (hdr.fcs.PanIdCompression) { if (dstAddr.Mode == MacAddressingMode.NoAddress) { drop = true; } else { srcPanId = dstPanId; } } else { srcPanId = hdr.srcPanId; } } } if (!drop) { DataIndicationHandler ind = _DataIndication; if (ind != null) { // synchronous from dataIndicationThread try { ind.Invoke(this, srcAddr, srcPanId, dstAddr, dstPanId, frame, linkQuality, hdr.seqNo, 0, new SecurityOptions()); } catch (Exception) { } frame = null; } } }
private void ReceiveThread() { while (!_rxThreadStop) { _rxEvent.WaitOne(); lock (_hal) { if (_activityLeds) { _ledRx.enabled = true; } while (_hal._fifopInterrupt.Read()) { if (_hal._fifoPort.Read()) { // get frame length, rxFrame is single byte _hal.WriteRead(_rxReadCmd, _rxFrame, 1); byte len = _rxFrame[0]; if (len > 0 && len < HALCC2420.FIFOSize) { // get frame byte[] buf = new byte[len]; _hal.WriteRead(_rxReadCmd, buf, 1); Frame frame = Frame.GetFrame(2, len + 1); // len + LQI byte. Reserve 2 bytes for header in case this exact frame is resent later on. frame.WriteToBack(buf); // buf = null; // dispose bool ok = true; int lqi = 0; if (_hal.AutoFCS) { // since we are using AutoCRC, MAC FCS is replaced with: // - RSSI (first byte) // - LQI (7 bits, lsb) // - CRC ok (1 bit, msb) // LQI needs to be scaled from 50..110 to 0..255 [CC.24] int i = frame.ReadByte(len - 1); if ((i & 0x80) == 0 || len < 3) { // CRC error ok = false; } else { // calculate LQI i &= 0x7f; // should be 50..110 if (i < 50) { i = 50; } if (i > 110) { i = 110; } // is 50..110 i -= 50; // 0..60 lqi = (i * 255) / 60; // 0..255 (well, within that range at least) frame.DeleteFromBack(2); // remove FCS } } else { lqi = GetNormalizedRSSI(); } if (ok) { DataIndicationHandler ind = _DataIndication; if (ind == null || frame.LengthDataUsed == 0) { Frame.Release(ref frame); } else { try { ind.Invoke(this, frame, (byte)lqi); // if (buf[2] == 0) { DateTime curTime = DateTime.Now; Debug.Print("Get Frm " + buf[2] + " Len " + len.ToString() + " Data " + ":" + GetHex(buf, 16) + " at " + curTime.Second + ":" + curTime.Millisecond); } } catch (Exception) { } } } else { Frame.Release(ref frame); } } else { _hal.Command(HALCC2420.Cmd.SFlushRX); _hal.Command(HALCC2420.Cmd.SFlushRX); } } else // !m_hal.m_fifoPort.Read() { _hal.Command(HALCC2420.Cmd.SFlushRX); _hal.Command(HALCC2420.Cmd.SFlushRX); } } if (_activityLeds) { _ledRx.enabled = false; } } } }