public void AddPendingMessgae(Message message)
 {
     lock (_lock)
     {
         PendingMessage.Add(message);
     }
 }
Exemple #2
0
        public async Task <PendingMessageDto> AddNodePendingMessageAsync(long nodeId, object content, TimeSpan lifetime)
        {
            if (nodeId == NodeSettings.Configs?.Node?.Id)
            {
                return(null);
            }
            PendingMessage pendingMessage = new PendingMessage
            {
                Content   = Convert.ToBase64String(ObjectSerializer.ObjectToByteArray(content)),
                ExpiredAt = DateTime.UtcNow.AddSeconds(lifetime.TotalSeconds).ToUnixTime(),
                NodeId    = nodeId,
                SentAt    = DateTime.UtcNow.ToUnixTime()
            };

            using (MessengerDbContext context = contextFactory.Create())
            {
                if (!await context.Nodes.AnyAsync(opt => opt.Id == nodeId).ConfigureAwait(false))
                {
                    return(null);
                }
                await context.PendingMessages.AddAsync(pendingMessage).ConfigureAwait(false);

                await context.SaveChangesAsync().ConfigureAwait(false);
            }
            return(new PendingMessageDto
            {
                Content = pendingMessage.Content,
                ExpiredAt = pendingMessage.ExpiredAt,
                Id = pendingMessage.Id,
                NodeId = pendingMessage.NodeId,
                SentAt = pendingMessage.SentAt
            });
        }
Exemple #3
0
        public async Task <PendingMessageDto> AddUserPendingMessageAsync(long receiverId, object content, Guid?messageId)
        {
            PendingMessage pendingMessage = new PendingMessage
            {
                Content    = ObjectSerializer.ObjectToJson(content),
                ExpiredAt  = DateTime.UtcNow.AddDays(1).ToUnixTime(),
                ReceiverId = receiverId,
                MessageId  = messageId,
                SentAt     = DateTime.UtcNow.ToUnixTime()
            };

            using (MessengerDbContext context = contextFactory.Create())
            {
                await context.PendingMessages.AddAsync(pendingMessage).ConfigureAwait(false);

                await context.SaveChangesAsync().ConfigureAwait(false);
            }
            return(new PendingMessageDto
            {
                Content = pendingMessage.Content,
                ExpiredAt = pendingMessage.ExpiredAt,
                Id = pendingMessage.Id,
                ReceiverId = pendingMessage.ReceiverId.Value,
                SentAt = pendingMessage.SentAt
            });
        }
Exemple #4
0
        //Adds a new payload to the pendingProducers queue if no one is currently waiting in the
        //pending consumers queue.
        public void Enqueue(T payload)
        {
            lock (_monitor)
            {
                PendingMessage pendingMessage;

                ////fast path, check if someone is waiting to receive a payload
                if (_pendingConsumers.Any())
                {
                    pendingMessage = _pendingConsumers.First();
                    _pendingConsumers.RemoveFirst();

                    pendingMessage.CancellationRegistration.Dispose();
                    pendingMessage.Timer.Dispose();

                    pendingMessage.SetResult(payload);
                }

                else
                {
                    pendingMessage = new PendingMessage {
                        Payload = payload
                    };
                    _pendingProducers.AddLast(pendingMessage);
                }
            }
        }
Exemple #5
0
        //Receives a new Payload from de pending producers queue if it is not empty or adds a new
        //empty consumer to the pending consumers queue and waits (wait is made by utilizing an incomplete
        //task which will be complete only by a call to queue or timeout/cancellation occurs.
        public Task <T> Dequeue(TimeSpan timeout, CancellationTokenSource cancellationTokenSource)
        {
            lock (_monitor)
            {
                PendingMessage pendingMessage;

                if (_pendingProducers.Any())
                {
                    pendingMessage = _pendingProducers.First();
                    _pendingProducers.RemoveFirst();
                    pendingMessage.SetResult(pendingMessage.Payload);
                    return(pendingMessage.Task);
                }

                pendingMessage = new PendingMessage();

                if (timeout.TotalMilliseconds <= 0)
                {
                    pendingMessage.SetException(new TimeoutException());
                    return(pendingMessage.Task);
                }

                var node = _pendingConsumers.AddLast(pendingMessage);

                pendingMessage.Timer = new Timer(CancelDueToTimeout, node, timeout, new TimeSpan(-1));
                pendingMessage.CancellationRegistration =
                    cancellationTokenSource.Token.Register(CancelDueToCancellationToken, node);

                return(pendingMessage.Task);
            }
        }
        void SaveMessage(Publish message, string clientId, PendingMessageStatus status)
        {
            if (message.QualityOfService == MqttQualityOfService.AtMostOnce)
            {
                return;
            }

            var session = sessionRepository.Get(s => s.ClientId == clientId);

            if (session == null)
            {
                throw new MqttException(string.Format(Properties.Resources.SessionRepository_ClientSessionNotFound, clientId));
            }

            var savedMessage = new PendingMessage {
                Status           = status,
                QualityOfService = message.QualityOfService,
                Duplicated       = message.Duplicated,
                Retain           = message.Retain,
                Topic            = message.Topic,
                PacketId         = message.PacketId,
                Payload          = message.Payload
            };

            session.AddPendingMessage(savedMessage);

            sessionRepository.Update(session);
        }
 public void AddErrorMessgae(Message message)
 {
     lock (_lock)
     {
         PendingMessage.Remove(PendingMessage.Single(a => a.Id == message.Id));
         ErrorMessage.Add(message);
     }
 }
Exemple #8
0
 public void Add(PendingMessage pending)
 {
     if (PendingList.ContainsKey(pending.MessageId))
     {
         return;
     }
     PendingList.TryAdd(pending.MessageId, pending);
 }
        public static PendingMessage ToPendingMessage(this Message self)
        {
            PendingMessage message = new PendingMessage();

            message.Message = self.Data;
            message.Sender  = self.SourceUserId;

            return(message);
        }
Exemple #10
0
 private void ClearPendingMessages(Entry entry)
 {
     while (entry.pendingMessages.Count > 0)
     {
         PendingMessage pm = (PendingMessage)entry.pendingMessages[0];
         entry.pendingMessages.RemoveAt(0);
         _routing.DataRequestTimeout(entry.targetAddr, pm.sduHandle, pm.handler, pm.isControlMsg);
         Frame.Release(ref pm.sdu);
     }
 }
        internal PendingMessage GetPendingMessage(ServiceMessage messageType, AsyncCallback callback, object asyncState)
        {
            uint associationId = GetAssociationId();

            var pendingMessage = new PendingMessage(messageType, associationId, callback, asyncState);

            _pendingMessages.Add(associationId, pendingMessage);

            return pendingMessage;
        }
        public void Load()
        {
            HistoryMessage = RepositoryProvider.GetRepository().Get <List <Message> >($"{_persistIdentity}_HistoryMessage") ?? new List <Message>();
            ErrorMessage   = RepositoryProvider.GetRepository().Get <List <Message> >($"{_persistIdentity}_ErrorMessage") ?? new List <Message>();
            PendingMessage = RepositoryProvider.GetRepository().Get <List <Message> >($"{_persistIdentity}_PendingMessage") ?? new List <Message>();
            PendingMessage.ForEach(QueueMessager.Enqueue);
            var queuedMessages = RepositoryProvider.GetRepository().Get <List <Message> >($"{_persistIdentity}_QueuedMessage") ?? new List <Message>();

            queuedMessages.ForEach(QueueMessager.Enqueue);
        }
        public async Task <int> Insert(int chatID, ExtendedMessage message)
        {
            var p = PendingMessage.FromExtendedMessage(chatID, message);

            if (p == null || await _database.Table <PendingMessage>().Where(f => f.ChatID == p.ChatID && f.PendingID == p.PendingID).CountAsync() > 0)
            {
                return(-1);
            }
            var insertedRows = await _database.InsertAsync(p);

            return(insertedRows == 1 ? p.ID : -1);
        }
Exemple #14
0
 private T DequeueMessage <T>(short packetId) where T : PendingMessage
 {
     lastMessage = pendingMessages.Dequeue();
     Debug.Assert(lastMessage is T && lastMessage.PacketId == packetId);
     //Signal we still have messages if someone is waiting.
     if (pendingMessages.Count > 0 && pendingMessageCompletionSource != null)
     {
         TaskCompletionSource <PendingMessage> source = pendingMessageCompletionSource;
         pendingMessageCompletionSource = null;
         source.SetResult(pendingMessages.Peek());
     }
     return((T)lastMessage);
 }
Exemple #15
0
 public bool TryLookup(UniqueId messageId, out DependencyTelemetry telemetry)
 {
     telemetry = null;
     lock (this.lockObject)
     {
         PendingMessage pending = null;
         if (pendingMessages.TryGetValue(messageId.ToString(), out pending))
         {
             pendingMessages.Remove(messageId.ToString());
             telemetry = pending.Telemetry;
             pending.Dispose();
             return(true);
         }
     }
     return(false);
 }
        protected void RemovePendingMessage(string clientId, ushort packetId)
        {
            ClientSession session = sessionRepository.Read(clientId);

            if (session == null)
            {
                throw new MqttException(ClientProperties.SessionRepository_ClientSessionNotFound(clientId));
            }

            PendingMessage pendingMessage = session
                                            .GetPendingMessages()
                                            .FirstOrDefault(p => p.PacketId.HasValue && p.PacketId.Value == packetId);

            session.RemovePendingMessage(pendingMessage);

            sessionRepository.Update(session);
        }
Exemple #17
0
        public void CheckMessages()
        {
            GlobalConfiguration.Configuration.Logger.Info("Check pending started");

            while (!m_Terminated)
            {
                var waitHandles = new WaitHandle[] { m_Terminate };
                int result      = ManualResetEvent.WaitAny(waitHandles, 60 * 1000, false);
                if (result == 0)
                {
                    m_Terminated = true;
                    break;
                }

                if (PendingList.Count == 0)
                {
                    continue;
                }

                GlobalConfiguration.Configuration.Logger.Info($"Check sent for {PendingList.Count} emails");

                var messageToRemoveList = new List <string>();
                foreach (var item in PendingList.Keys)
                {
                    try
                    {
                        System.Threading.Thread.Sleep(5 * 500);
                        var messageId = CheckPendingMessage(item);
                        if (messageId != null)
                        {
                            messageToRemoveList.Add(messageId);
                        }
                    }
                    catch (Exception ex)
                    {
                        GlobalConfiguration.Configuration.Logger.Error(ex);
                    }
                }

                foreach (var item in messageToRemoveList)
                {
                    PendingMessage pm = null;
                    PendingList.TryRemove(item, out pm);
                }
            }
        }
        public void CreateLookupKey_WhenInvoke_ResultShouldBeUsedInSortedSetCorrectly()
        {
            // Act.
            var lookup1 = PendingMessage.CreateLookupKey(0, 11);
            var lookup2 = PendingMessage.CreateLookupKey(5, 11);
            var lookup3 = PendingMessage.CreateLookupKey(6, 0);

            // Assert.
            var set = new SortedSet <PendingMessage>()
            {
                this.subject,
                lookup1,
                lookup2,
                lookup3,
            };

            Assert.Equal(new[] { lookup1, this.subject, lookup2, lookup3 }, set);
        }
Exemple #19
0
        private Task <bool> EnqueueMessage(OutputHeader message, NodeConnection connection)
        {
            ushort connectionAddress = connection.NodeAddress;

            TaskCompletionSource <bool> result = new TaskCompletionSource <bool>();

            lock (thisLock)
            {
                var            currentQueue = this.pendingMessagesQueue[connectionAddress];
                PendingMessage newMsg       = new PendingMessage(result, message);
                int            index        = 0;
                foreach (PendingMessage pendingMsg in currentQueue)
                {
                    if (newMsg.Message.Priority > pendingMsg.Message.Priority)
                    {
                        currentQueue.Insert(index, newMsg);
                        break;
                    }
                    index++;
                }
                if (index == currentQueue.Count)
                {
                    currentQueue.Add(newMsg);
                }

                // If the new message is alone in the queue
                if (currentQueue.Count == 1)
                {
                    // Connection is bussy. We need to wait
                    if (!this.CheckForSend(connectionAddress))
                    {
                        Debug.Print(newMsg.Id + " waiting (1)...");
                    }
                }
                else
                {
                    Debug.Print(newMsg.Id + " waiting (" + (index + 1) + ")...");
                }
            }

            return(result.Task);
        }
        internal async Task <PendingMessage> SendMessage(RequestMessage requestMessage)
        {
            var data = Serializer.Serialize(requestMessage);

            var result = default(PendingMessage);

            if (!requestMessage.IsNotification)
            {
                result = new PendingMessage
                {
                    Name = requestMessage.Name,
                };

                PendingMessages[requestMessage.Id] = result;
            }

            await Client.SendAsync(data);

            return(result);
        }
Exemple #21
0
        private void OnOutgoingQueueReady(object sender, NetMQQueueEventArgs <OutgoingMessage> e)
        {
            var outgoingMessage = m_outgoingQueue.Dequeue();

            //var bodySegment = m_serializer.Serialize(outgoingMessage.Message);
            //byte[] body = new byte[bodySegment.Count];
            //Buffer.BlockCopy(bodySegment.Array, bodySegment.Offset, body, 0, bodySegment.Count);

            UInt64 messageId = ++m_nextMessageId;

            m_nextMessageId = messageId;

            //string subject = m_serializer.GetObjectSubject(outgoingMessage.Message);
            //Console.WriteLine("Codec.Message.RelatedMessageId: " + messageId + " ; " + Codec.Error.RelatedMessageId);


            Codec.Id = Codec.MessageId.Message;
            Codec.Message.MessageId        = messageId;
            Codec.Message.Service          = outgoingMessage.Service;
            Codec.Message.Subject          = "";
            Codec.Message.Body             = outgoingMessage.Message;
            Codec.Message.RelatedMessageId = 0;

            // one way message
            if (outgoingMessage.Oneway)
            {
                Codec.Message.OneWay = 1;
            }
            else
            {
                Codec.Message.OneWay = 0;
                // add to pending requests dictionary
                // TODO: we might want to create a pending message structure that will not hold reference to the message (can lead to GC second generation)
                var msg = new PendingMessage(messageId, outgoingMessage.TaskCompletionSource);
                m_pendingRequests.Add(messageId, msg);
                GC.KeepAlive(msg);
                GC.KeepAlive(outgoingMessage);
            }

            Codec.Send(m_clientSocket);
        }
Exemple #22
0
    static void AddPendingMessage(object message, PendingMessage.PrintStyle printStyle, Object sender)
    {
        PendingMessage newPendingMessage;

        if (!sender)
        {
            newPendingMessage = new PendingMessage(message, printStyle);
        }
        else
        {
            newPendingMessage = new PendingMessage(message, printStyle, sender);
        }
        pendingMessages.Add(newPendingMessage);

        // Start waiting for the mainCam.
        if (waitingForValidCam == null)
        {
            waitingForValidCam = WaitForValidCam();
            CoroutineStarter.StartCoroutine(waitingForValidCam);
        }
    }
Exemple #23
0
        public void SentFail(PendingMessage pending, string status, string message = null)
        {
            var sentFail = new SentFail();

            sentFail.Stack      = status;
            sentFail.Message    = message;
            sentFail.MessageId  = pending.MessageId;
            sentFail.Recipients = pending.Recipients;
            sentFail.Subject    = pending.Subject;

            var contentString = Newtonsoft.Json.JsonConvert.SerializeObject(sentFail);

            var path = System.IO.Path.GetDirectoryName(this.GetType().Assembly.Location);

            path = System.IO.Path.Combine(path, $"fails/{status.Replace("sendinblue:", "")}-{Guid.NewGuid()}.json");
            System.IO.File.WriteAllText(path, contentString);

            var failQueueName = GlobalConfiguration.Configuration.SentFailQueueName;

            Bus.Send(failQueueName, sentFail);
        }
Exemple #24
0
 public void Add(UniqueId messageId, DependencyTelemetry telemetry, TimeSpan timeout)
 {
     if (messageId == null)
     {
         throw new ArgumentNullException(nameof(messageId));
     }
     if (telemetry == null)
     {
         throw new ArgumentNullException(nameof(telemetry));
     }
     lock ( lockObject )
     {
         if (disposed)
         {
             throw new ObjectDisposedException(nameof(MessageCorrelator));
         }
         var pending = new PendingMessage(messageId, telemetry);
         pendingMessages[messageId.ToString()] = pending;
         pending.Start(timeout, this.OnTimeout);
     }
 }
Exemple #25
0
        /// <summary>
        /// Sends the message and waits for the response.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="timeout">The timeout in milliseconds.</param>
        /// <returns>The response to the message.</returns>
        public async Task <Response> SendMessageAsync(Message message, CancellationToken cancellationToken, int timeout = 30000)
        {
            var tcs = new TaskCompletionSource <Response>();

            using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
            {
                if (timeout != Timeout.Infinite)
                {
                    cts.CancelAfter(timeout);
                }

                using (cts.Token.Register(() => tcs.SetCanceled(), false))
                {
                    var pendingMessage = new PendingMessage(tcs);
                    PendingMessages.AddOrUpdate(message.Id, (_) => pendingMessage, (_1, _2) => pendingMessage);

                    SendNotification(message);

                    return(await tcs.Task);
                }
            }
        }
Exemple #26
0
        async Task <PendingMessage> IMqttSession.NextPending(PendingMessage lastMessage, int timeoutMilliseconds)
        {
            if (pendingMessages.Count > 0 && pendingMessages.Peek() != lastMessage)
            {
                return(pendingMessages.Peek());
            }
            else
            {
                if (pendingMessageCompletionSource == null)
                {
                    pendingMessageCompletionSource = new TaskCompletionSource <PendingMessage>();
                }
                else
                {
                    Debug.Assert(false);
                }
                TaskCompletionSource <PendingMessage> currentCompletion = pendingMessageCompletionSource;
                if (pendingMessages.Count == 0)
                {
                    return(await pendingMessageCompletionSource.Task);
                }
                else
                {
                    Task delayTask = Task.Delay(timeoutMilliseconds);
                    Task <PendingMessage> nextTask = pendingMessageCompletionSource.Task;
                    Task result = await Task.WhenAny(delayTask, nextTask);

                    if (result == delayTask)
                    {
                        if (pendingMessages.Count > 0 && pendingMessages.Peek() == lastMessage)
                        {
                            pendingMessageCompletionSource = null;
                            return(lastMessage);
                        }
                    }
                    return(await nextTask);
                }
            }
        }
Exemple #27
0
 private void sendMessage(String message)
 {
     int id = Interlocked.Increment(ref SMSIM.smsId);
     string timestamp = "[" + DateTime.Now.ToString("HH:mm:ss") + "] ";
     int startIndex = messageBox.Text.Length;
     int length = (timestamp + "You: " + message + "\n").Length;
     this.Invoke(new MethodInvoker(delegate {
         messageBox.AppendText(timestamp + "You: " + message + "\n");
         messageBox.ScrollToCaret();
         messageBox.Select(startIndex, length);
         messageBox.SelectionColor = Color.Gray;
     }));
     PendingMessage pendingMessage = new PendingMessage();
     pendingMessage.id = id;
     pendingMessage.length = length;
     pendingMessage.startIndex = startIndex;
     pendingMessages.Add(pendingMessage);
     parent.sendMessage("SMS:" + id + ":" + this.number + ":" + message);
 }
 public PendingMessageTests()
 {
     this.subject = new PendingMessage(5, 10);
 }
Exemple #29
0
        public string CheckPendingMessage(string messageId)
        {
            PendingMessage pending = null;

            PendingList.TryGetValue(messageId, out pending);
            if (pending == null)
            {
                return(null);
            }

            if (pending.CheckCount > 10)
            {
                return(pending.MessageId);
            }

            // Every 20 minutes or first time
            if (!pending.LastCheckDate.HasValue ||
                pending.LastCheckDate.Value.AddMinutes(20) < DateTime.Now)
            {
                var client = new SendInBlueClient(ApiKey);
                pending.CheckCount++;
                pending.LastCheckDate = DateTime.Now;
                Models.EmailEventReport result = null;
                try
                {
                    result = client.GetMessageHistory(pending.SendInBlueMessageId);
                }
                catch (Exception ex)
                {
                    GlobalConfiguration.Configuration.Logger.Error($"Get history fail with email {pending.Email}/{pending.Subject}");
                    GlobalConfiguration.Configuration.Logger.Error(ex);
                    SentFail(pending, "sendinblue:historyFail", "Status code error");
                }

                if (result == null)
                {
                    return(null);
                }

                if (result.Events == null || result.Events.Count == 0)
                {
                    return(null);
                }

                var item = result.Events.Last();

                if (item.Event == EmailEventReportEvent.EventEnum.Clicks ||
                    item.Event == EmailEventReportEvent.EventEnum.Opened ||
                    item.Event == EmailEventReportEvent.EventEnum.Delivered)
                {
                    GlobalConfiguration.Configuration.Logger.Debug($"email {pending.Email}/{pending.Subject} was sent with status {item.Event}");
                    return(pending.MessageId);
                }
                else if (item.Event == EmailEventReportEvent.EventEnum.Bounces ||
                         item.Event == EmailEventReportEvent.EventEnum.HardBounces ||
                         item.Event == EmailEventReportEvent.EventEnum.SoftBounces)
                {
                    GlobalConfiguration.Configuration.Logger.Warn($"email {pending.Email}/{pending.Subject} was bounces");
                    SentFail(pending, "sendinblue:bounce", item.Reason);
                    return(pending.MessageId);
                }
                else if (item.Event == EmailEventReportEvent.EventEnum.Blocked)
                {
                    GlobalConfiguration.Configuration.Logger.Warn($"email {pending.Email}/{pending.Subject} was blocked");
                    SentFail(pending, "sendinblue:blocked");
                }
                else if (item.Event == EmailEventReportEvent.EventEnum.Requests)
                {
                    return(null);
                }
                else if (item.Event == EmailEventReportEvent.EventEnum.Spam)
                {
                    GlobalConfiguration.Configuration.Logger.Warn($"email {pending.Email}/{pending.Subject} marked as spam");
                    SentFail(pending, "sendinblue:spam");
                    return(pending.MessageId);
                }
                else if (item.Event == EmailEventReportEvent.EventEnum.Unsubscribed)
                {
                    GlobalConfiguration.Configuration.Logger.Warn($"email {pending.Email}/{pending.Subject} need unsubscribe");
                    SentFail(pending, "sendinblue:unsubscribe");
                    return(pending.MessageId);
                }
                else if (item.Event == EmailEventReportEvent.EventEnum.Invalid)
                {
                    GlobalConfiguration.Configuration.Logger.Warn($"email {pending.Email}/{pending.Subject} was invalid");
                    SentFail(pending, "sendinblue:invalid");
                    return(pending.MessageId);
                }
            }

            return(null);
        }
Exemple #30
0
        /// <summary>
        /// To send sdu from local node
        /// </summary>
        /// <param name="tgtAddrExt"></param>
        /// <param name="sduHandle"></param>
        /// <param name="sdu"></param>
        /// <param name="handler"></param>
        public void DataRequest(
            UInt16 targetAddr,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler,
            bool isControlMsg)
        {
            lock (_lock)
            {
                int   i = FindTargetAddr(targetAddr);
                Entry entry;
                if (i == -1)
                {
                    // create new entry
                    entry = AddEntry(targetAddr);
                }
                else
                {
                    entry = _table[i] as Entry;
                }

                bool doRouteRequest = false;

                if (entry.nextHopAddr == cInvalidAddr || entry.routeHasError)
                { // no route to targetAddr
                    // queue this message
                    if (entry.pendingMessages.Count == cMaxPendingMsg)
                    { // delete oldest waiting msg
                        PendingMessage pmOld = (PendingMessage)entry.pendingMessages[0];
                        entry.pendingMessages.RemoveAt(0);
                        _routing.DataRequestTimeout(targetAddr, pmOld.sduHandle, pmOld.handler, pmOld.isControlMsg);
                        Frame.Release(ref pmOld.sdu);
                    }

                    PendingMessage pm = new PendingMessage();
                    pm.sdu          = sdu;
                    sdu             = null;
                    pm.sduHandle    = sduHandle;
                    pm.handler      = handler;
                    pm.isControlMsg = isControlMsg;
                    entry.pendingMessages.Add(pm);

                    doRouteRequest = true;
                }
                else
                {
                    entry.routeInUse = true;
                    _routing.DataRequest(targetAddr, entry.nextHopAddr, ref sdu, sduHandle, handler, isControlMsg);

                    if (entry.routeHasError)
                    {
                        doRouteRequest      = true;
                        entry.routeHasError = false;
                    }
                }

                if (doRouteRequest)
                {
                    // initiate route request
                    if (!entry.routePending)
                    {
                        // we haven't asked for a route yet, start now
                        entry.routePending    = true;
                        entry.requestRetryCnt = cRouteRequestRetryCnt;
                        entry.timeOutSet      = cRouteRequestWaitTime;
                        _timerEvent.Set();
                        Trace.Print("Sending route request for 0x" + HexConverter.ConvertUintToHex(entry.targetAddr, 4) + " for data");
                        _routing.RouteRequest(targetAddr);
                    } // else: wait for ongoing request
                }
            }
        }
Exemple #31
0
        /// <summary>
        /// Update routing table using given information.
        /// </summary>
        /// <returns>True if new route is superior to old route</returns>
        public bool UpdateRoute(
            UInt16 targetAddr,
            UInt16 nextHopAddr,
            byte seqNo,
            byte hopCount,
            byte minLqi)
        {
            lock (_lock)
            {
                int i = FindTargetAddr(targetAddr);

                Entry entry;
                if (i == -1) // not found, so let's add this entry
                {
                    entry             = AddEntry(targetAddr);
                    entry.nextHopAddr = nextHopAddr;
                    entry.seqNo       = seqNo;
                    entry.hopCount    = hopCount;
                    entry.minLqi      = minLqi;
                    entry.timeOutSet  = cRouteTimeout;
                    _timerEvent.Set();
                    return(true);
                }

                // route was found.
                entry = _table[i] as Entry;

                if (entry.routePending == false && entry.nextHopAddr != cInvalidAddr) // seqNo is valid
                {
                    // some heuristic to balance hop count vs. link quality
                    // the metric has to ensure loop freedom, i.e. be strict monoton
                    int costNew = CalcRouteCost(minLqi, hopCount);
                    int costOld = CalcRouteCost(entry.minLqi, entry.hopCount);

                    // see DYMO 5.2.1 for case differentiation
                    int seqOffset = (SByte)(seqNo - entry.seqNo);
                    if (seqOffset < 0)
                    {
                        // handle reset of seqNo
                        if (seqNo < Routing.cSeqNoWraparound)
                        {
                            entry.seqNo = seqNo;
                            seqOffset   = 1; // accept new route
                        }
                        else
                        {
                            return(false); // new route is stale
                        }
                    }

                    if (seqOffset == 0 &&
                        costNew >= costOld)
                    {
                        return(false); // new route is inferior
                    }
                }

                // update table
                // - update
                entry.nextHopAddr   = nextHopAddr;
                entry.routeHasError = false;
                entry.seqNo         = seqNo;
                entry.hopCount      = hopCount;
                entry.minLqi        = minLqi;

                if (entry.routePending)
                {
                    entry.routePending = false;

                    // transmit all queued messages
                    while (entry.pendingMessages.Count > 0)
                    {
                        PendingMessage pm = (PendingMessage)entry.pendingMessages[0];
                        entry.pendingMessages.RemoveAt(0);
                        _routing.DataRequest(entry.targetAddr, entry.nextHopAddr,
                                             ref pm.sdu, pm.sduHandle, pm.handler, pm.isControlMsg);
                    }
                }

                // set/update route timeout. the greater the hopCount, the shorter the timeout.
                // this ensures that outer nodes of a path refresh the path first, implicityly refreshing
                // the route for all intermediate nodes
                entry.timeOutSet = cRouteTimeout -
                                   hopCount * (cRouteRequestRetryCnt + 1) * cRouteRequestWaitTime;
                _timerEvent.Set();

                return(true);
            }
        }
        internal async Task <TResult> GetAsyncResult <TResult>(PendingMessage pm)
        {
            var result = await pm.CompletionSource.Task;

            return((TResult)result);
        }
        /// <summary>
        /// To send sdu from local node
        /// </summary>
        /// <param name="tgtAddrExt"></param>
        /// <param name="sduHandle"></param>
        /// <param name="sdu"></param>
        /// <param name="handler"></param>
        public void DataRequest(
            UInt16 targetAddr,
            ref Frame sdu,
            Byte sduHandle,
            DataConfirmHandler handler,
            bool isControlMsg)
        {
            lock (_lock)
            {
                int i = FindTargetAddr(targetAddr);
                Entry entry;
                if (i == -1)
                {
                    // create new entry
                    entry = AddEntry(targetAddr);
                }
                else
                {
                    entry = _table[i] as Entry;
                }

                bool doRouteRequest = false;

                if (entry.nextHopAddr == cInvalidAddr || entry.routeHasError)
                { // no route to targetAddr
                    // queue this message
                    if (entry.pendingMessages.Count == cMaxPendingMsg)
                    { // delete oldest waiting msg
                        PendingMessage pmOld = (PendingMessage)entry.pendingMessages[0];
                        entry.pendingMessages.RemoveAt(0);
                        _routing.DataRequestTimeout(targetAddr, pmOld.sduHandle, pmOld.handler, pmOld.isControlMsg);
                        Frame.Release(ref pmOld.sdu);
                    }

                    PendingMessage pm = new PendingMessage();
                    pm.sdu = sdu;
                    sdu = null;
                    pm.sduHandle = sduHandle;
                    pm.handler = handler;
                    pm.isControlMsg = isControlMsg;
                    entry.pendingMessages.Add(pm);

                    doRouteRequest = true;
                }
                else
                {
                    entry.routeInUse = true;
                    _routing.DataRequest(targetAddr, entry.nextHopAddr, ref sdu, sduHandle, handler, isControlMsg);

                    if (entry.routeHasError)
                    {
                        doRouteRequest = true;
                        entry.routeHasError = false;
                    }
                }

                if (doRouteRequest)
                {
                    // initiate route request
                    if (!entry.routePending)
                    {
                        // we haven't asked for a route yet, start now
                        entry.routePending = true;
                        entry.requestRetryCnt = cRouteRequestRetryCnt;
                        entry.timeOutSet = cRouteRequestWaitTime;
                        _timerEvent.Set();
                        Trace.Print("Sending route request for 0x" + HexConverter.ConvertUintToHex(entry.targetAddr, 4) + " for data");
                        _routing.RouteRequest(targetAddr);
                    } // else: wait for ongoing request
                }
            }
        }
        public static void BeginSendMessage(ProtoProxyClient client, object message, uint associationId)
        {
            var pendingMessage = new PendingMessage(client, associationId);

            client.Client.BeginSendMessage(message, null, pendingMessage.EndSendMessage, null);
        }