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