public PEQTimerInternal(IMessage message, double time, INode referrer)
 {
     MessageEvent msgEvent = new MessageEvent(message);
     msgEvent.Referrer = referrer;
     this.node = referrer;
     this.Time = time;
     this.Event = msgEvent;
 }
 public object Clone()
 {
     IMessage message = (IMessage)this.message.Clone();
     MessageEvent clone = new MessageEvent(message);
     clone.time = time;
     clone.Referrer = Referrer;
     clone.SuppressReport = suppressReport;
     return clone;
 }
        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 processMessageTimer(MessageEvent e)
        {
            // When the timer expires, send the Message
            MessageEvent outputEvent;

            outputEvent = new MessageEvent(e.message);
            outputEvent.Referrer = this;

            this.PhysProc.ExecuteAction(outputEvent);
        }
        void processHelloTimer(MessageEvent e)
        {
            // When the timer expires, send the Hello message and regenerate the timer.
            MessageEvent outputEvent;
            FloodingQueryMessage message = (FloodingQueryMessage)e.message;

            outputEvent = new MessageEvent(message);
            outputEvent.Referrer = this;
            this.PhysProc.ExecuteAction(outputEvent);

            this.resetHelloTimer();
        }
        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 void GenerateEvent(double time, ILocation location)
        {
            // Overloads GenerateEvent to allow the simulation to provide the time the event occurs.
            XYDoubleLocation initalCorner = (XYDoubleLocation)field[0];  // Casting to xyLocation objects. Other
            XYDoubleLocation finalCorner = (XYDoubleLocation)field[1];     // coordinate systems are not supported.

            List<PEQNode> nodesInRange = new List<PEQNode>();

            // Generate the random center location of the event.
            eventCenter = (XYDoubleLocation)location;

            eventCenter.SetField(field);

            Notify(generateStaticReport(time, eventCenter));

            foreach (PEQNode node in nodes.NodeQueue)
            { // Find which nodes are within the effective detection area.
                if (eventCenter.Distance(node.Location) <= eventSize) // if in the event area
                    nodesInRange.Add(node);
            }

            double eventTime = 0;
            for (int i = 0; i < this.numOccurances; i++)
            {
                eventTime = time + i / this.eventFreq;

                foreach (PEQNode node in nodesInRange)
                {
                    PEQMessageApplication appMsg = new PEQMessageApplication(); // Create a new app message
                    appMsg._Data._DataID = _dataID++;
                    MessageEvent msgEvent = new MessageEvent(appMsg); // create a new message event
                    msgEvent.Referrer = node; // set the referrer to the current node

                    PEQDataInfoReport rep = new PEQDataInfoReport(node.ID, eventTime);
                    rep._Sent = 1;
                    rep._DataID = appMsg._Data._DataID;
                    Notify(rep);

                    PEQTimerInternal messageTimer = new PEQTimerInternal(appMsg, eventTime, node);
                    eventMgr.AddEvent(messageTimer);   // add the event to the Event Queue.
                }
            }

            SimulationCompleteEvent simCompleteEvent = new SimulationCompleteEvent(nodes);
            simCompleteEvent.Time = eventTime + 60; // one minute after last event occurs
            eventMgr.AddEvent(simCompleteEvent);
        }
        public void GenerateEvent(double time, ILocation location)
        {
            // Overloads GenerateEvent to allow the simulation to provide the time the event occurs.
            XYDoubleLocation initalCorner = (XYDoubleLocation)field[0];  // Casting to xyLocation objects. Other
            XYDoubleLocation finalCorner = (XYDoubleLocation)field[1];     // coordinate systems are not supported.

            // Generate the random center location of the event.
            eventCenter = (XYDoubleLocation)location;

            eventCenter.SetField(field);

            Notify(generateStaticReport(time, eventCenter));

            foreach (FloodingQueryNode node in nodes.NodeQueue)
            { // Find which nodes are within the effective detection area.
                if (eventCenter.Distance(node.Location) <= eventSize) // if in the event area
                {
                    FloodingQueryApplicationMessage appMsg = new FloodingQueryApplicationMessage(); // Create a new app message
                    MessageEvent msgEvent = new MessageEvent(appMsg); // create a new message event
                    msgEvent.Referrer = node; // set the referrer to the current node

                    NodeTimerEvent timerEvent = new NodeTimerEvent();   // create a timer event
                    timerEvent.Time = time;
                    timerEvent.Event = msgEvent;                        // apply the message event
                    timerEvent.node = node;
                    eventMgr.AddEvent(timerEvent);                      // add the event to the Event Queue.
                }
            }
        }