void resetHelloTimer()
        {
            // Set the Hello Timer and insert into the Event Queue
            NodeTimerEvent outputTimer;
            FloodingQueryMessage message = new FloodingQueryMessage(this.id, 0xffff, FloodingQueryMessage.MessageType.hello);
            message.SourceLoc = this.Location;
            MessageEvent e = new MessageEvent(message);
            double Clock = this.EventMgr.CurrentClock;
            Clock += 30;

            outputTimer = new NodeTimerEvent();
            outputTimer.Event = e;
            outputTimer.node = this;
            outputTimer.Time = Clock;
            this.EventMgr.AddEvent(outputTimer);
        }
        void processQueryMessage(FloodingQueryMessage message)
        {
            // Called when a Query Message has been received
            NodeTimerEvent outputTimer;
            MessageEvent outputEvent;

            if (this.isSink) return;

            // Create a string uniquely identifying the message
            string idString = message.OriginatorID.ToString() + "-" + message.MessageID.ToString();

            if (!_messagesHeard.ContainsKey(idString)) // (For fun, get rid of this check and watch the broadcast storm!)
            { // If the _messagesHeard hash table doesn't contain the unique packet identifying string...
                _messagesHeard.Add(idString, null);         // Add the unique message string to the hash table
                if (message.Hops < this.distance)           // If the query we got is better than our previous
                {
                    this.nextHop = message.SourceID;        // Update the path back to the sink
                    this.distance = message.Hops;           // Update the distance back to the sink
                    this.nextHopCheat = ((FloodingQueryMessage)message).SourceLoc;  // ONLY FOR DISPLAY PURPOSES
                    Notify(GenerateDirectionReport());
                }
                message.UpdateSource(this.id);              // Update the message source to be the current node
                message.SourceLoc = this.Location;          // Update the message location to the current node.
                message.IncrementHops();                    // Increment the number of hops back to the sink

                outputEvent = new MessageEvent(message);    // create a new event to send out
                outputEvent.Referrer = this;

                outputTimer = new NodeTimerEvent();
                outputTimer.Event = outputEvent;
                outputTimer.node = this;
                     // Wait up to 2 seconds before sending (stand-off time).
                outputTimer.Time = this.EventMgr.CurrentClock + 2 * this.randomizer.NextDouble();
                this.EventMgr.AddEvent(outputTimer);

                //this.PhysProc.ExecuteAction(outputEvent);   // Send the event to our Physical Processor
            } // ELSE DROP MESSAGE
        }
        void processDataMessage(FloodingQueryMessage message)
        {
            // Called when a Data Message has been received
            NodeTimerEvent outputTimer;
            MessageEvent outputEvent;

            if ((message.DestinationID != this.ID) && (message.DestinationID != 0xffff))
                return;

            if (this.isSink) return;

            // ---- NOTE, NEARLY SAME CODE AS "processQueryMessage"
                if (this.nextHop != int.MaxValue)           // If a next hop exists...
                    message.DestinationID = this.nextHop;   // set the destination ID to the next hop address
                else
                    message.DestinationID = 0xffff;         // otherwise flood <-- this is not efficient!!!
                outputEvent = new MessageEvent(message);    // create a new event
                outputEvent.Referrer = this;

                outputTimer = new NodeTimerEvent();
                outputTimer.Event = outputEvent;
                outputTimer.node = this;
                // Wait up to 2 seconds before sending (stand-off time).
                outputTimer.Time = this.EventMgr.CurrentClock + 2 * this.randomizer.NextDouble();
                this.EventMgr.AddEvent(outputTimer);
        }
        void processApplicationMessage(FloodingQueryApplicationMessage message)
        {
            // When an application message is received, create and send a data message toward the Sink. If no Sink path
            // exists, broadcast the data message.
            FloodingQueryMessage dataMessage;
            MessageEvent outputEvent;
            if (message.IsEventOccurrance)
            {
                if (this.nextHop != int.MaxValue)
                    dataMessage = new FloodingQueryMessage(this.id, this.nextHop, FloodingQueryMessage.MessageType.data,
                        CurrentMessageID, this.id);
                else
                    dataMessage = new FloodingQueryMessage(this.id, 0xffff, FloodingQueryMessage.MessageType.data,
                        CurrentMessageID, this.id);

                dataMessage.SourceLoc = this.Location;

                outputEvent = new MessageEvent(dataMessage);
                outputEvent.Referrer = this;
                this.PhysProc.ExecuteAction(outputEvent);
            }
        }
        public void Initialize()
        {
            Notify(GenerateStaticReport());

            FloodingQueryMessage message = new FloodingQueryMessage(this.id, 0xffff,
                FloodingQueryMessage.MessageType.hello);  // All new nodes create a hello message to be broadcast
            message.SourceLoc = this.Location;
            MessageEvent initialEvent = new MessageEvent(message); // An event is created with the message
            initialEvent.Referrer = this;
            // Initial Hello randomly occurs 0 - 10 minutes after deployment:

            // Create a timer event for the first Hello packet
            NodeTimerEvent helloTimerEvent = new NodeTimerEvent();
            helloTimerEvent.Event = initialEvent;
            helloTimerEvent.node = this;
            helloTimerEvent.Time = this.EventMgr.CurrentClock + this.randomizer.NextDouble() * 10;

            // Add timer to the Event Queue
            this.EventMgr.AddEvent(helloTimerEvent);

            // If this node is a Sink, add a Timer (Query) event to the event queue, starting in 0 - 5 seconds.
            if (this.IsSink)
            {
                // Create the Query Message
                message = new FloodingQueryMessage(this.id, 0xffff, FloodingQueryMessage.MessageType.query,
                    CurrentMessageID, this.id);
                message.SourceLoc = this.Location;
                // Create the MessageEvent
                MessageEvent QueryEvent = new MessageEvent(message);
                QueryEvent.Referrer = this;

                // Create the Timer event
                NodeTimerEvent queryTimerEvent = new NodeTimerEvent();
                queryTimerEvent.Event = QueryEvent;
                queryTimerEvent.node = this;
                queryTimerEvent.Time = this.EventMgr.CurrentClock + this.randomizer.NextDouble() * 5;

                // Add the TimerEvent to the Event Queue
                this.EventMgr.AddEvent(queryTimerEvent);
            }
        }
 public object Clone()
 {
     FloodingQueryMessage clone = new FloodingQueryMessage(this.srcID, this.dstID, this.type);
     clone.data = this.data;
     clone.hopCount = this.hopCount;
     clone.SourceLoc = this.SourceLoc;
     clone.size = this.size;
     return clone;
 }