Beispiel #1
0
        /// <summary>
        /// Note: caller msut hold the lock _lock
        /// </summary>
        /// <param name="dataRequestItem"></param>
        private OutboundFragmentationMessage CreateNewOutboundMessage(DataRequestItem dataRequestItem)
        {
            byte messageSeqNumber;
            uint timeoutForResending, maxFragmentsBeforeAck;

            if (!_transmissionCharacteristicStorage.GetTransmissionCharacteristic(dataRequestItem.TargetShortAddr, out messageSeqNumber, out timeoutForResending, out maxFragmentsBeforeAck))
            {
                // characteristic not present. Create default one.
                messageSeqNumber      = 0;
                timeoutForResending   = FragmentationMessage.c_defaultTimeoutForResending;
                maxFragmentsBeforeAck = FragmentationMessage.c_defaultMaxFragmentsBeforeAck;
                _transmissionCharacteristicStorage.SetTransmissionCharacteristic(dataRequestItem.TargetShortAddr, messageSeqNumber, timeoutForResending, maxFragmentsBeforeAck);
            }
            else
            {
                // characteristic already present. increment the sequence number.
                messageSeqNumber++;
                if (messageSeqNumber == 0)
                {
                    messageSeqNumber++;
                }                                                  // sequence number = 0 is reserved for new communication
                _transmissionCharacteristicStorage.SetTransmissionCharacteristic(dataRequestItem.TargetShortAddr, messageSeqNumber, timeoutForResending, maxFragmentsBeforeAck);
            }

            Frame sdu = dataRequestItem.Sdu;
            OutboundFragmentationMessage newMsg = new OutboundFragmentationMessage(_localShortAddress,
                                                                                   dataRequestItem.TargetShortAddr, messageSeqNumber, _lowerLayerDataRequest,
                                                                                   ref sdu, dataRequestItem.SduHandle, dataRequestItem.Handler, _lowerMtu, _lowerHead, _lowerTail, _timer);

            newMsg.FragmentationMessageTerminated += HandleFragmentationMessageTerminated;
            newMsg.MaxFragmentsBeforeAck           = maxFragmentsBeforeAck;
            newMsg.TimeoutForResending             = timeoutForResending;
            _outboundAssociations.SetFragmentationMessage(_localShortAddress, dataRequestItem.TargetShortAddr, newMsg);
            return(newMsg);
        }
        /// <summary>
        /// Note: caller msut hold the lock _lock
        /// </summary>
        /// <param name="dataRequestItem"></param>
        private OutboundFragmentationMessage CreateNewOutboundMessage(DataRequestItem dataRequestItem)
        {

            byte messageSeqNumber;
            uint timeoutForResending, maxFragmentsBeforeAck;
            if (!_transmissionCharacteristicStorage.GetTransmissionCharacteristic(dataRequestItem.TargetShortAddr, out messageSeqNumber, out timeoutForResending, out maxFragmentsBeforeAck))
            {
                // characteristic not present. Create default one.
                messageSeqNumber = 0;
                timeoutForResending = FragmentationMessage.c_defaultTimeoutForResending;
                maxFragmentsBeforeAck = FragmentationMessage.c_defaultMaxFragmentsBeforeAck;
                _transmissionCharacteristicStorage.SetTransmissionCharacteristic(dataRequestItem.TargetShortAddr, messageSeqNumber, timeoutForResending, maxFragmentsBeforeAck);
            }
            else
            {
                // characteristic already present. increment the sequence number.
                messageSeqNumber++;
                if (messageSeqNumber == 0) { messageSeqNumber++; } // sequence number = 0 is reserved for new communication
                _transmissionCharacteristicStorage.SetTransmissionCharacteristic(dataRequestItem.TargetShortAddr, messageSeqNumber, timeoutForResending, maxFragmentsBeforeAck);
            }

            Frame sdu = dataRequestItem.Sdu;
            OutboundFragmentationMessage newMsg = new OutboundFragmentationMessage(_localShortAddress,
                dataRequestItem.TargetShortAddr, messageSeqNumber, _lowerLayerDataRequest,
                ref sdu, dataRequestItem.SduHandle, dataRequestItem.Handler, _lowerMtu, _lowerHead, _lowerTail, _timer);
            newMsg.FragmentationMessageTerminated += HandleFragmentationMessageTerminated;
            newMsg.MaxFragmentsBeforeAck = maxFragmentsBeforeAck;
            newMsg.TimeoutForResending = timeoutForResending;
            _outboundAssociations.SetFragmentationMessage(_localShortAddress, dataRequestItem.TargetShortAddr, newMsg);
            return newMsg;
        }
Beispiel #3
0
        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();
            }
        }