/// <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> /// Returns the oldest item from the queue (but leaves the item in the queue) /// </summary> /// <param name="targetAddress"></param> /// <param name="item"></param> /// <returns></returns> public bool Peek(UInt16 targetAddress, out DataRequestItem item) { DataRequestQueue queue = GetDataRequestQueue(targetAddress); Object o; item = null; if (queue.Peek(out o)) { if (!(o is DataRequestItem)) { throw new ArgumentException("Bad object type peeked"); } item = o as DataRequestItem; return(true); } return(false); }
/// <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(); } }
/// <summary> /// Add item to the appropriate queue /// </summary> /// <returns>True on success</returns> public bool Add(DataRequestItem item) { DataRequestQueue queue = GetDataRequestQueue(item.TargetShortAddr); return queue.Add(item); }
/// <summary> /// Returns the oldest item from the queue (but leaves the item in the queue) /// </summary> /// <param name="targetAddress"></param> /// <param name="item"></param> /// <returns></returns> public bool Peek(UInt16 targetAddress, out DataRequestItem item) { DataRequestQueue queue = GetDataRequestQueue(targetAddress); Object o; item = null; if (queue.Peek(out o)) { if (!(o is DataRequestItem)) throw new ArgumentException("Bad object type peeked"); item = o as DataRequestItem; return true; } return false; }
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(); } }
/// <summary> /// Add item to the appropriate queue /// </summary> /// <returns>True on success</returns> public bool Add(DataRequestItem item) { DataRequestQueue queue = GetDataRequestQueue(item.TargetShortAddr); return(queue.Add(item)); }