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

        }
        public void RemoveFragmentationMessage(FragmentationMessage fragmentationMessage)
        {
            lock (this)
            {

                _fragmentationMessagesArray.Remove(fragmentationMessage);

            }
        }
 internal TimerItem(long timeoutTicks, FragmentationMessage message)
 {
     Id = GetNextId();
     TimeoutTicks = timeoutTicks;
     Message = message;
 }
 internal TimeoutEventArgs(FragmentationMessage message)
 {
     _message = message;
 }
 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;
             }
         }
     }
 }
Example #13
0
        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);
            }
        }
 internal TimerItem(long timeoutTicks, FragmentationMessage message)
 {
     Id           = GetNextId();
     TimeoutTicks = timeoutTicks;
     Message      = message;
 }
 internal TimeoutEventArgs(FragmentationMessage message)
 {
     _message = message;
 }