public void RemoveFragmentationMessage(FragmentationMessage fragmentationMessage) { lock (this) { _fragmentationMessagesArray.Remove(fragmentationMessage); } }
internal uint RegisterItem(long timeoutTick, FragmentationMessage message) { lock (_lock) { TimerItem item = new TimerItem(timeoutTick, message); AddItemToList(item); return item.Id; } }
internal uint RegisterItem(long timeoutTick, FragmentationMessage message) { lock (_lock) { TimerItem item = new TimerItem(timeoutTick, message); AddItemToList(item); return(item.Id); } }
/// <summary> /// Remove all associations and dispose all fragmentation messages. /// </summary> public void Dispose() { lock (this) { int fragmentMessageArrayCount = _fragmentationMessagesArray.Count; for (int i = 0; i < fragmentMessageArrayCount; i++) { FragmentationMessage msg = (FragmentationMessage)_fragmentationMessagesArray[i]; msg.Dispose(); } _fragmentationMessagesArray.Clear(); } }
internal void UnregisterItem(FragmentationMessage message) { lock (_lock) { for (int i = 0; i < _timerItems.Count; i++) { TimerItem item = (TimerItem)_timerItems[i]; if (item.Message == message) { RemoveItemFromList(i); return; } } } }
/// <summary> /// Get the active message associated to a remote node. /// </summary> /// <param name="node"></param> /// <returns></returns> public FragmentationMessage GetFragmentationMessage(UInt16 source, UInt16 destination) { lock (this) { int fragmentMessageArrayCount = _fragmentationMessagesArray.Count; for (int i = 0; i < fragmentMessageArrayCount; i++) { FragmentationMessage msg = (FragmentationMessage)_fragmentationMessagesArray[i]; if ((msg.Source == source) && (msg.Destination == destination)) { return(msg); } } return(null); } }
/// <summary> /// Set the fragmentation message associated to a pair of transmitting nodes. /// </summary> internal void SetFragmentationMessage(UInt16 source, UInt16 destination, FragmentationMessage fragmentationMessage) { if ((source != fragmentationMessage.Source) || (destination != fragmentationMessage.Destination)) { throw new ArgumentException("Inconsistent parameters."); } lock (this) { // first. check whether there is already an active message associated to this node. FragmentationMessage prevFragmentationMessage = GetFragmentationMessage(source, destination); if (prevFragmentationMessage != null) { // there is already one active message associated with the node. // remove this message first. _fragmentationMessagesArray.Remove(prevFragmentationMessage); } _fragmentationMessagesArray.Add(fragmentationMessage); return; } }
internal TimerItem(long timeoutTicks, FragmentationMessage message) { Id = GetNextId(); TimeoutTicks = timeoutTicks; Message = message; }
internal TimeoutEventArgs(FragmentationMessage message) { _message = message; }
public void HandleLowerLayerDataIndication(object sender, ushort originatorShortAddr, ushort targetShortAddr, Frame sdu) { FragmentationMessage fragMsg = null; FragmentHeader header; lock (_lock) { if ((!_started) || (sdu.LengthDataUsed < 2)) { Frame.Release(ref sdu); return; } // extract fragment header. header = FragmentHeader.Decode(sdu.ReadUInt16(0)); sdu.DeleteFromFront(2); FragmentationMessageAssociationSet associations; switch (header.Type) { case FragmentType.DATA: associations = _inboundAssociations; if (associations == null) { Frame.Release(ref sdu); return; } fragMsg = (InboundFragmentationMessage)associations.GetFragmentationMessage(originatorShortAddr, targetShortAddr); if (fragMsg != null) { // there is already one message with this peer. Check freshness. if (fragMsg.MessageNumber != header.MessageSeqNumber) { int sqnOld = (int)fragMsg.MessageNumber; int sqnNew = (int)header.MessageSeqNumber; int diff = (sqnNew > sqnOld) ? sqnNew - sqnOld : sqnNew - sqnOld + 256; if ((header.MessageSeqNumber == 0) || (diff < 128)) { // data received is most recent. fragMsg.Dispose(); fragMsg = null; } else { // data received is old stuff. Frame.Release(ref sdu); return; } } } if (fragMsg == null) { // new message must be started fragMsg = new InboundFragmentationMessage(originatorShortAddr, targetShortAddr, header.MessageSeqNumber, _lowerLayerDataRequest, _lowerMtu, _lowerHead, _lowerTail, _timer); fragMsg.FragmentationMessageTerminated += this.HandleFragmentationMessageTerminated; associations.SetFragmentationMessage(originatorShortAddr, targetShortAddr, fragMsg); } break; case FragmentType.ACK: associations = _outboundAssociations; if (associations == null) { Frame.Release(ref sdu); return; } fragMsg = (OutboundFragmentationMessage)associations.GetFragmentationMessage(targetShortAddr, originatorShortAddr); if ((fragMsg == null) || (fragMsg.MessageNumber != header.MessageSeqNumber)) { //no one waiting for this segment. Discard. #if DEBUG Trace.Print("No one waiting for this segment. Discard."); #endif Frame.Release(ref sdu); return; } break; default: break; } } // release the lock before calling method in FragmentMessage class if (fragMsg != null) { fragMsg.HandleReceivedFragment(header, ref sdu); } }