/// <summary> /// TASK: Execute this dialog by sending the buffer and start reception. /// </summary> /// <param name="buffer">The buffer.</param> /// <param name="rx_filter">The rx_filter.</param> /// <param name="rx_timeout">The rx_timeout.</param> /// <returns></returns> public IEnumerator<ITask> Execute(ReloadMessage reloadMessage, ReloadMessageFilter rx_filter, int rx_timeout) { //m_Transport.Send(this.m_NextHopNode, reloadMessage); Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Node, ReloadMessage>(this.m_NextHopNode, reloadMessage, m_Transport.Send)); m_TimeStart = DateTime.Now; //m_MessageFilter = rx_filter; Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessageFilter, int, String>(rx_filter, rx_timeout, reloadMessage.reload_message_body.RELOAD_MsgCode.ToString(), Receive)); yield break; }
/// <summary> /// TASK: Waits for the reception for max rx_timeout milliseconds. Filters if required. /// </summary> /// <param name="rx_filter">The rx_filter.</param> /// <param name="rx_timeout">The rx_timeout.</param> /// <returns></returns> private IEnumerator<ITask> Receive(ReloadMessageFilter rx_filter, int rx_timeout, String messageCode) { m_DispatcherQueue.EnqueueTimer(TimeSpan.FromMilliseconds(rx_timeout), timeouted); m_fError = false; bool fTimeouted = false; //m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TEST, String.Format("Receiver {0} started", rx_filter.transactionID)); /* there are multiple incoming packets possible, if there wasn't a matching packet so far, * wait for it as long there is no timout condition */ while (!fTimeouted && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit) { yield return Arbiter.Choice( Arbiter.Receive(false, timeouted, to => { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Receiver {0} Rx Timeout after sending {1}", rx_filter.transactionID, messageCode)); fTimeouted = true; }), Arbiter.Receive(false, m_portWaitForRx, trigger => { //m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TEST, String.Format("Receiver {0} released, error is {1}", rx_filter.transactionID, error)); })); if (!fTimeouted && !m_fError) while (m_Queue.Count != 0 && m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit) { ReloadFLMEventArgs args = (ReloadFLMEventArgs)m_Queue.Dequeue(); if (args == null || args.Message == null) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Receive: Args == null")); break; } if (args.Eventtype == ReloadFLMEventArgs.ReloadFLMEventTypes.RELOAD_EVENT_RECEIVE_OK) { ReloadMessage reloadMsg = args.Message; if (reloadMsg == null) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Receive: Dropping invalid packet from {0}", args.ConnectionTableEntry != null ? args.ConnectionTableEntry.NodeID.ToString() : "unknown")); break; } //m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Receiver {0} Queuecount {1} Transactionid: {2}", rx_filter.transactionID, m_Queue.Count, reloadMsg.TransactionID)); if (reloadMsg.IsFragmented() && reloadMsg.IsSingleFragmentMessage() == false && rx_filter != null && reloadMsg.TransactionID == rx_filter.transactionID) { ReloadMessage reassembledMsg = null; lock (fragmentedMessageBuffer) { reassembledMsg = reloadMsg.ReceiveFragmentedMessage(ref fragmentedMessageBuffer); } if (reassembledMsg == null) //not yet all fragments received => not reassembled { Arbiter.Activate(m_DispatcherQueue, new IterativeTask<ReloadMessageFilter, int, String>(rx_filter, rx_timeout, "", Receive)); m_TimeStart = DateTime.Now; yield break; } else reloadMsg = reassembledMsg; //message reassembled => continue as usual } if (args.ConnectionTableEntry != null) m_SourceNodeID = args.ConnectionTableEntry.NodeID; else m_SourceNodeID = reloadMsg.LastHopNodeId; if (rx_filter != null) { // m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TEST, String.Format("Receiver {0} Checking against {1}", rx_filter.transactionID, reloadMsg.TransactionID)); /* Most important part: Do only accept messages with the same transaction id * this ReloadDialog had been registered to and ignore the rest */ if (reloadMsg.TransactionID == rx_filter.transactionID) { if (!reloadMsg.IsRequest()) { //m_ReceivedMessage = args.Message; m_ReceivedMessage = reloadMsg; //--joscha /* just a trick to get out of the parent loop */ fTimeouted = true; break; } else { /* Our Request looped back to us, module Forwarding is handling this */ if (reloadMsg.reload_message_body.RELOAD_MsgCode == RELOAD_MessageCode.Error) { if (((ErrorResponse)reloadMsg.reload_message_body).ErrorCode == RELOAD_ErrorCode.Error_Not_Found) { // --joscha not found response => don't wait for timeout m_ReceivedMessage = null; /* just a trick to get out of the parent loop */ fTimeouted = true; break; } } } } } else { /* No filter specified, deliver every packet */ //m_ReceivedMessage = args.Message; m_ReceivedMessage = reloadMsg; //--joscha; /* just a trick to get out of the parent loop */ fTimeouted = true; break; } } } } m_Transport.ReloadFLMEventHandler -= OVL_ReloadForwardLinkManagementEventHandler; m_fDone.Post(true); }