private void processMessageTimer(PEQTimerMessage timer)
        {
            if (_busyCount > 0)
            {
                timer.Time = _eventManager.CurrentClock
                    + _randomValue.NextDouble() * _TIMER_RANDOM_WAIT_SEND;
                _eventManager.AddEvent(timer);
            }
            else
            {
                MessageEvent msgEve = (MessageEvent)timer.Event;
                PEQMessage msg = (PEQMessage)msgEve.message;
                if (msg._DestinationID == new VarID(msg._DestinationID.SizeOf()))
                    msgEve.Directed = false;
                else
                {
                    msgEve.Directed = true;
                    msgEve.NextHopID = msg._DestinationID.GetID();
                    if (msg is PEQMessageNotify)    // Also, directed subscription message when implemented
                        expectAck(msg);
                }

                if (_NODE_REPORTS)
                    Notify(GeneratePEQNodeInfoReport(true, msg));
                if (_HELLO_SUPPRESS_REPORT && (msg is PEQMessageHello))
                    msgEve.SuppressReport = true;

                _physicalProcessor.ExecuteAction(msgEve);
            }
        }
        /*       / \
         *     // | \\
         *    /   |   \
         *        |           */
        public void Initialize()
        {
            Notify(GenerateStaticReport());  // For Visualization

            // Set initial hello timer to random value
            PEQTimerHello timer =
                new PEQTimerHello(_randomValue.NextDouble() * _TIMER_HELLO, this);
            _eventManager.AddEvent(timer);

            if (_isSink)
            {
                // Send build tree (at future time...)
                PEQMessageBuildTree msgBT = new PEQMessageBuildTree(new VarID(_NUM_ID_BYTES), _id,
                    _sequenceNumber++, _id, 0x00);
                double time = _randomValue.NextDouble() * _TIMER_BUILDTREE;
                msgBT._nextHopCheat = _location;
                PEQTimerMessage outputTimer = new PEQTimerMessage(msgBT, time, this);
                _eventManager.AddEvent(outputTimer);

                // Add to BT to subscription table (this is early........)
                PEQTableEntrySubscription sub = new PEQTableEntrySubscription();
                sub._SinkID = _id;
                sub._nextHopCheat = _location;
                sub._HopCount = 0;
                sub._DestinationID = _id;
                sub._CriteriaType = 0x0000;
                sub._Valid = true;
                _tableSubscription.Add(sub);

                // Send subscription (at future time...)
                PEQMessageSubscribe msgSub = new PEQMessageSubscribe(new VarID(_NUM_ID_BYTES), _id,
                    _sequenceNumber++, _id, 0x00,
                    new PEQSubscriptionInfo(0x0001,
                        new PEQSubscriptionCriteria()));
                time = time + _TIMER_SUBSCRIBE;
                msgSub._nextHopCheat = _location;
                outputTimer = new PEQTimerMessage(msgSub, time, this);
                _eventManager.AddEvent(outputTimer);

                // Add subscription to subscription table (this is very early........)
                sub = new PEQTableEntrySubscription();
                sub._SinkID = _id;
                sub._nextHopCheat = _location;
                sub._HopCount = 0;
                sub._DestinationID = _id;
                sub._CriteriaType = 0x0001;
                sub._Valid = true;
                _tableSubscription.Add(sub);

                updateRoutingTable();
            }
        }
        private void processHelloTimer(PEQTimerHello timer)
        {
            PEQMessageHello msg = new PEQMessageHello(_id);
            msg._nextHopCheat = _location;

            PEQTimerMessage timerEvent = new PEQTimerMessage(msg,
                _eventManager.CurrentClock + _TIMER_WAIT_SEND, this);
            _eventManager.AddEvent(timerEvent);

            resetHelloTimer();
        }
        private void sendSubscribe(PEQMessageSubscribe msg)
        {
            PEQMessageSubscribe newMsg = (PEQMessageSubscribe)msg.Clone();
            newMsg._SenderID = _id;
            newMsg._SequenceNumber = 0x00;
            newMsg._HopCount = (byte)(msg._HopCount + 1);
            newMsg._nextHopCheat = _location;

            PEQTimerMessage timerEvent = new PEQTimerMessage(newMsg,
                _eventManager.CurrentClock + _TIMER_WAIT_SEND, this);
            _eventManager.AddEvent(timerEvent);
        }
        private void sendSearch(VarID SinkID, int searchCount)
        {
            PEQMessageSearch msg = new PEQMessageSearch(new VarID(SinkID.SizeOf()), _id,
                _sequenceNumber++, SinkID);

            msg._nextHopCheat = _location;

            PEQTimerMessage timerEvent = new PEQTimerMessage(msg,
                _eventManager.CurrentClock + _TIMER_RANDOM_WAIT_SEND * _randomValue.NextDouble(), this);
            _eventManager.AddEvent(timerEvent);

            PEQTimerSearch searchTimer
                = new PEQTimerSearch(_eventManager.CurrentClock +
                    _physicalProcessor.MaximumRange * _TIMER_SEARCH /
                    _physicalProcessor.PropagationSpeed, this);
            searchTimer._SinkID = SinkID;
            searchTimer._Count = ++searchCount;

            _eventManager.AddEvent(searchTimer);
        }
        private void sendResponse(PEQTableEntrySubscription Subscription,
            PEQMessageSearch msg)
        {
            PEQMessageResponse newMsg = new PEQMessageResponse(msg._SenderID,
                _id, msg._SequenceNumber, Subscription._HopCount,
                msg._SinkID);
            newMsg._nextHopCheat = _location;

            PEQTimerMessage timerEvent = new PEQTimerMessage(newMsg,
                _eventManager.CurrentClock + _TIMER_RANDOM_WAIT_SEND
                * RandomValue.NextDouble(), this);
            _eventManager.AddEvent(timerEvent);
        }
        private void sendNotify(PEQTableEntryRouting Route, PEQMessageNotify msg)
        {
            PEQMessageNotify newMsg = (PEQMessageNotify)msg.Clone();
            newMsg._SenderID = _id;
            newMsg._SequenceNumber = _sequenceNumber++;
            newMsg._DestinationID = Route._DestinationID;
            newMsg._nextHopCheat = _location;
            newMsg._Data._NumHops++;
            newMsg._Data._TotalDistance += _location.Distance(msg._nextHopCheat);

            PEQTimerMessage timerEvent = new PEQTimerMessage(newMsg,
                _eventManager.CurrentClock + _TIMER_WAIT_SEND, this);
            _eventManager.AddEvent(timerEvent);
        }
        private void sendAck(PEQMessage msg)
        {
            if (msg._DestinationID == msg._SenderID)
                return;

            PEQMessageAck ackMessage = new PEQMessageAck(msg._SenderID,
                msg._DestinationID, msg._SequenceNumber);

            ackMessage._nextHopCheat = _location;   // Just add this to all msgs

            PEQTimerMessage timerEvent = new PEQTimerMessage(ackMessage,
                _eventManager.CurrentClock + _TIMER_WAIT_SEND, this);
            _eventManager.AddEvent(timerEvent);
        }