Beispiel #1
0
 public BufferedRreqAttempt(int attemptNo, Rreq rreq, double expirationTime)
 {
     AttemptNo      = attemptNo;
     RetryNo        = 0;
     Rreq           = new Rreq(rreq);
     ExpirationTime = TimeHelper.GetInstance().GetFutureTime(expirationTime);
 }
 public Rreq(Rreq rreq) //Copy constructor
 {
     J                         = rreq.J;
     R                         = rreq.R;
     G                         = rreq.G;
     D                         = rreq.D;
     U                         = rreq.U;
     HopCount                  = rreq.HopCount;
     RouteRequestId            = rreq.RouteRequestId;
     DestinationAddress        = rreq.DestinationAddress;
     DestinationSequenceNumber = rreq.DestinationSequenceNumber;
     OriginatorAddress         = rreq.OriginatorAddress;
     OriginatorSequenceNumber  = rreq.OriginatorSequenceNumber;
 }
        /// <summary>
        /// Generates a new Message, containing a RREQ for the wanted destination.
        /// Implemented according to Section 6.3: Generating Route Requests (RREQ) in the RFC.
        ///
        /// Method also handles buffering of RREQ, to avoid sending a duplicate in next iteration.
        /// </summary>
        /// <param name="destination">String representation of the destination address.</param>
        /// <returns>A Message with the RREQ enclosed. Includes destination address set to broadcast, and TTL adjusted according to the RFC.</returns>
        public Message GenerateInitialRreqMessage(string destination)
        {
            //If RREQ has been sent for this destination by me, and has not yet timed out, dont send a new one
            if (RreqAttemptExist(destination, _localAddress) && _time.CurrentTime < GetBufferedRreqAttempt(destination, _localAddress).ExpirationTime)
            {
                _logger.WriteLine("RREQ has been sent for this destination, and has not yet timed out, so dont send a new one.");
                return(null);
            }

            //Else, no RREQ for this destination waiting for response, send a new one
            RoutingTable.IncrementSequenceNumber();              //Must be incremented before sending a RREQ, per section 6.1 and 6.3

            var knownEntry = RoutingTable.GetEntry(destination); //Get stale entry if it exists

            var rreq = new Rreq
            {
                G                         = _conf.AODV_UseGratuitousRREPs,
                D                         = _conf.AODV_DestinationRespondOnlyFlag,
                U                         = knownEntry == null, //True if no current DSN is known, per section 6.3
                HopCount                  = 0,
                RouteRequestId            = RoutingTable.NextRouteRequestId,
                DestinationAddress        = destination,
                DestinationSequenceNumber = knownEntry?.DestinationSequenceNumber ?? 0, //Known DSN and U=false, or unknown DSN=0 and U=true
                OriginatorAddress         = _localAddress,
                OriginatorSequenceNumber  = RoutingTable.SequenceNumber
            };

            //Any stale routing table entry waiting for a RREP (because of the newly generated RREQ) should not be expunged before current_time + 2 * NET_TRAVERSAL_TIME
            if (knownEntry != null)
            {
                knownEntry.ExpirationTime = _time.GetFutureTime(2 * _aodvParameters.NetTraversalTime);
            }

            //Create Message to send RREQ in, and adjust RREQ
            var msg = new Message(rreq, SimulationConstants.BroadcastAddress, _localAddress, _conf.MessageTtlValue);

            msg.Ttl = knownEntry?.HopCount + _aodvParameters.TtlIncrement ?? _aodvParameters.TtlStart; //Per section 6.4, use last known hopcount as initial TTL + TTL_INCREMENT

            //Buffer RREQ ID and Originator address, pr. section 6.3 (taken from rreq)
            var rreqAttempt = new BufferedRreqAttempt(0, rreq, _conf.AodvConfiguration.PathDiscoveryTime);

            rreqAttempt.ExpirationTime = _time.GetFutureTime(_aodvParameters.PathDiscoveryTime);
            AddBufferedRreqAttempt(rreqAttempt);

            return(msg);
        }