📄 aodv_routing_nexttwo.pr.c
字号:
aodv_gratuitous_rrep_pk_generate(rreq_pk_ptr)
{
Packet* grat_rrep_pk_ptr;
RoutingTableEntry * forwardEntryPtr;
int dest,
source,
srcSeqNb,
hopCount;
double lifetime;
/*
/* Generate a gratuitous RREP and unicast it to
/* the destination node (node for which RREQ was
/* originally generated).
*/
// Read RREQ packet
op_pk_nfd_get (rreq_pk_ptr,"SRC",&source);
op_pk_nfd_get (rreq_pk_ptr,"DEST",&dest);
op_pk_nfd_get (rreq_pk_ptr,"SrcSeqNb",&srcSeqNb);
op_pk_nfd_get (rreq_pk_ptr,"HopCount",&hopCount);
// read forward entry
forwardEntryPtr = aodv_routingTable_entry_get(dest);
// create a gratuitous rrep packet and unicast it to the next hop toward the Destination
grat_rrep_pk_ptr= op_pk_create_fmt("AODV_RREP_NEXTTWO");
op_pk_nfd_set(grat_rrep_pk_ptr,"SRC",dest);
op_pk_nfd_set(grat_rrep_pk_ptr,"DEST",source);
op_pk_nfd_set(grat_rrep_pk_ptr,"DestSeqNb",srcSeqNb);
op_pk_nfd_set(grat_rrep_pk_ptr,"HopCount",hopCount+1);
op_pk_nfd_set(grat_rrep_pk_ptr,"PreviousTwoHop", -1);
lifetime = forwardEntryPtr->expirationTime - op_sim_time();
if(lifetime <= 0)
lifetime = ACTIVE_ROUTE_TIMEOUT;
op_pk_nfd_set(grat_rrep_pk_ptr,"Lifetime",lifetime);
// send to MAC Layer
aodv_pk_send_to_mac_layer(grat_rrep_pk_ptr,aodv_entry_nextHop_get(dest));
// Refresh timeout
aodv_entry_expirationTime_set(dest,op_sim_time()+ACTIVE_ROUTE_TIMEOUT);
if (DEBUG > 1) printf(" > Gratuitous RREP has been generated: unicast it to destination [next hop is %d]\n", aodv_entry_nextHop_get(dest));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_rrep_pk_generate_from_relay(Packet* ) //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void
aodv_rrep_pk_generate_from_relay(Packet* rreq_pk_ptr)
{
Packet *rrep_pk_ptr;
double lifetime;
RoutingTableEntry *forwardEntryPtr;
RoutingTableEntry *reverseEntryPtr;
int dest;
int source;
int previousHop;
/*
/* This routine is called when an intermediate node
/* receives a RREQ an has fresh enough route to
/* to generate a RREP for the requested destination.
*/
// Read request packet
op_pk_nfd_get (rreq_pk_ptr,"SRC",&source);
op_pk_nfd_get (rreq_pk_ptr,"DEST",&dest);
op_pk_nfd_get (rreq_pk_ptr,"PreviousHop",&previousHop);
// Read forward entry
forwardEntryPtr=aodv_routingTable_entry_get(dest);
// Create reply packet
rrep_pk_ptr = op_pk_create_fmt("AODV_RREP_NEXTTWO");
/* Assign source and dest to the reply packet */
op_pk_nfd_set(rrep_pk_ptr,"SRC",source);
op_pk_nfd_set(rrep_pk_ptr,"DEST",dest);
op_pk_nfd_set(rrep_pk_ptr,"HopCount",forwardEntryPtr->hopCount);
op_pk_nfd_set(rrep_pk_ptr,"PreviousTwoHop",-1);
lifetime = forwardEntryPtr->expirationTime - op_sim_time();
if(lifetime <= 0)
lifetime = ACTIVE_ROUTE_TIMEOUT;
op_pk_nfd_set(rrep_pk_ptr,"Lifetime",lifetime);
op_pk_nfd_set(rrep_pk_ptr,"DestSeqNb",forwardEntryPtr->destSeqNb);
// add previousHop toward "source" to the precursor list of the forward entry
aodv_listOfPrecursors_node_put(forwardEntryPtr,previousHop);
// add nextHop toward "destination" to the precursor list of the reverse entry
reverseEntryPtr=aodv_routingTable_entry_get(source);
aodv_listOfPrecursors_node_put(reverseEntryPtr,forwardEntryPtr->nextHop);
// send reply to mac layer
if(DEBUG > 1 ) printf(" > RREP has been generated from relay: unicast it to source node [next hop is %d]\n",previousHop);
aodv_pk_send_to_mac_layer(rrep_pk_ptr,previousHop);
// Refresh timeout
aodv_entry_expirationTime_set(source,op_sim_time()+ACTIVE_ROUTE_TIMEOUT);
// Destroy rreq
op_pk_destroy(rreq_pk_ptr);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_rreq_pk_forward(Packet* rreq_pk_ptr) //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void
aodv_rreq_pk_forward(Packet* rreq_pk_ptr)
{
int ttl,
hopCount,
previousHop;
/*
/* Node does not have a fresh enough entry
/* (or does not have an entry at all) to answer
/* the received RREQ, so it decides to forward
/* it. Node increments the Hop Count field
/* and decrements the TTL field.
/* Note that packet is sent to mac layer only if
/* TTL > 0.
*/
op_pk_nfd_get (rreq_pk_ptr,"TTL",&ttl);
op_pk_nfd_get (rreq_pk_ptr,"HopCount",&hopCount);
op_pk_nfd_get (rreq_pk_ptr,"PreviousHop",&previousHop);
if(ttl > 1)
{
if(DEBUG > 1 ) printf(" > Node forwards request\n",ttl);
op_pk_nfd_set(rreq_pk_ptr,"TTL",ttl-1);
op_pk_nfd_set(rreq_pk_ptr,"HopCount",hopCount+1);
op_pk_nfd_set(rreq_pk_ptr,"PreviousTwoHop",previousHop);
// send to mac
aodv_pk_send_to_mac_layer(rreq_pk_ptr, BROADCAST);
}
else
{
if(DEBUG > 1 ) printf(" > TTL expired: rreq destroyed\n");
op_pk_destroy(rreq_pk_ptr);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_entry_update_or_create_from_rreq(Packet* ) //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void
aodv_entry_update_or_create_from_rreq(Packet* rreq_pk_ptr)
{
RoutingTableEntry * reverseEntryPtr;
int source,
previousHop,
srcSeqNb,
hopCount,
previousTwoHop;
/*
/* Update or create reverse entry following a RREQ reception.
*/
// Read RREQ packet
op_pk_nfd_get (rreq_pk_ptr,"SRC",&source);
op_pk_nfd_get (rreq_pk_ptr,"PreviousHop",&previousHop);
op_pk_nfd_get (rreq_pk_ptr,"SrcSeqNb",&srcSeqNb);
op_pk_nfd_get (rreq_pk_ptr,"HopCount",&hopCount);
op_pk_nfd_get (rreq_pk_ptr,"PreviousTwoHop",&previousTwoHop);
// Check if any request is pending for this destination
if(RequestSent[source].status != OFF)
aodv_requestSent_repository_reset(source);
// Node creates or updates a REVERSE route
reverseEntryPtr=aodv_routingTable_entry_get(source);
if(reverseEntryPtr != OPC_NIL)
{
//entry already exists
if((srcSeqNb > reverseEntryPtr->destSeqNb) ||
((srcSeqNb == reverseEntryPtr->destSeqNb)
&&((hopCount+1)< reverseEntryPtr->hopCount)) || (reverseEntryPtr->status != ACTIVE) )
{
// entry updated only if (greater seqNb) or
//(same seqNbs but smaller hopCount)
if(DEBUG > 1 ) printf(" > Node updates its reverse route to source node\n");
reverseEntryPtr->destSeqNb=srcSeqNb;
reverseEntryPtr->nextHop= previousHop;
reverseEntryPtr->nextTwoHop = previousTwoHop;
if(reverseEntryPtr->hopCount != INFINITY)
reverseEntryPtr->lastHopCount= reverseEntryPtr->hopCount;
reverseEntryPtr->hopCount=hopCount+1;
}
else
if(DEBUG > 1) printf(" > Node does not need to update its reverse entry\n");
// Refresh entry timeout to max(current expiration time, currentTime+REV_ROUTE_LIFE)
if((op_sim_time()+REV_ROUTE_LIFE) > reverseEntryPtr->expirationTime)
{
aodv_entry_expirationTime_set(source,op_sim_time()+REV_ROUTE_LIFE);
}
else
if(DEBUG > 1) printf(" > Reverse entry timeout does not need to be refreshened\n");
// set entry status
reverseEntryPtr->status = ACTIVE;
}
else
{
//entry doesn't exist: node creates it
if(DEBUG > 1 ) printf(" > Node creates a reverse entry to source node\n");
reverseEntryPtr=aodv_entry_create_new();
reverseEntryPtr->listOfPrecursors=newFifo();
reverseEntryPtr->status = ACTIVE;
reverseEntryPtr->dest=source;
reverseEntryPtr->destSeqNb=srcSeqNb;
reverseEntryPtr->nextHop= previousHop;
reverseEntryPtr->nextTwoHop = previousTwoHop;
reverseEntryPtr->hopCount=hopCount+1;
reverseEntryPtr->lastHopCount = hopCount+1;
// Add the entry to the RoutingTable
aodv_routingTable_entryPtr_put(reverseEntryPtr);
// Refresh entry timeout
aodv_entry_expirationTime_set(source,op_sim_time()+REV_ROUTE_LIFE);
}
// if reverse entry updated or created, then
// Serve buffer if any packet's waiting
if(reverseEntryPtr->hopCount != INFINITY)
aodv_buffer_serve(source);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_rreq_pk_regenerate(int destination) //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void
aodv_rreq_pk_regenerate(int destination)
{
/*
/* This function is called in the Renew_Request state when
/* the previous RREQ didn't receive any RREP and the number
/* of retries is smaller than TTL_RETRIES_TRESHOLD
*/
aodv_rreq_pk_generate(destination, WAITING_FOR_REPLY);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_reverseListOfPrecursors_update(int prec, int dest) //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void
aodv_reverseListOfPrecursors_update(int precursor, int destination)
{
int *destinationPtr;
sFifo *listOfDestination;
/*
/* Each time a node "A" (precursor) is added to the list of precursor of
/* a given destination "B" (detination), this function is called to add
/* "B" in the list of nodes to which "A" is a precursor. Thus, when
/* link to A is no longer available and node wants to expunge it from
/* its routing table, node has only to process entry that are listed
/* within the reverseListOfPrecursol at the entry "A".
*/
// var init
destinationPtr = (int*) op_prg_mem_alloc(sizeof(int));
*destinationPtr = destination;
// begin
if(DEBUG > 3 ) printf(" - Function aodv_reverseListOfPrecursors_update(): precursor = %d || entry = %d\n", precursor,destination);
// check if a reverse entry already exists for PRECURSOR
if(DEBUG > 3 ) printf(" > check if a reverse entry already exists\n");
listOfDestination= (sFifo*) readInFifoMultiplex(reverseListOfPrecursors, precursor);
if(listOfDestination == OPC_NIL) // no entry available
{
if(DEBUG > 3 ) printf(" > No entry available: node has to create a new one\n");
// have to create a new entry
listOfDestination=newFifo();
putInFifo(listOfDestination, destinationPtr);
putInFifoMultiplex(reverseListOfPrecursors,listOfDestination, precursor);
}
else
{
// only add destination to the list of destination
if(DEBUG > 3 ) printf(" > entry already exists: only add destination to the list of destination\n");
putInFifo(listOfDestination, destinationPtr);
}
if(DEBUG > 3 ) printf(" - function aodv_reverseListOfPrecursors_update()... done !\n");
}
///////////////////////////////////////////////////////////
/***************** HANDLE_DATA ***************************/
///////////////////////////////////////////////////////////
void
aodv_data_pk_receive(Packet* data_pk_ptr)
{
// var
int previousHop, source, dest;
int twoHopRepairFlag;
int nextHop_PnodeInfor, nextTwoHop;
RoutingTableEntry * entryPtr, *forwardEntryPtr;
/*
/* This function receives the upcoming data packet from the MAC Layer.
/* Two possibilities:
/* 1. Packet has reached its destination. Packet is then discarded toward
/* the upper_layer.
/* 2. Packet has to be forwarded. Node checks its routing table and
/* either forwards the packet if an entry is available or generates
/* a RERR otherwise.
/*
*/
// Read data packet
op_pk_nfd_get (data_pk_ptr,"PreviousHop",&previousHop);
op_pk_nfd_get (data_pk_ptr,"SRC",&source);
op_pk_nfd_get (data_pk_ptr,"DEST",&dest);
op_pk_nfd_get (data_pk_ptr,"TwoHopRepairFlag",&twoHopRepairFlag);
op_pk_nfd_get (data_pk_ptr,"NextTwoHop",&nextHop_PnodeInfor);
if(DEBUG > 1 ) printf(" - Function aodv_data_pk_receive(destination is %d )\n",dest);
// update stats
if(previousHop != source)
{
stats[previousHop].forward_output++;
}
// check packet final destination
if (dest == node_addr)
{
// pk has reached its destination
if(DEBUG > 1 ) printf(" > Data packet has reached its destination\n");
// send packet to upper layer
if(DEBUG > 1 ) printf(" > Data packet sent to app_manager layer\n");
op_pk_send(data_pk_ptr,DISCARD_STRM);
// update stats
output ++;
stats[source].own_output++;
op_stat_write(global_receive_data_pk_cnt_stathandle, ++global_receive_data_pk_cnt);
}
else//(if (dest == node_addr) )
{
// pk has to be forwarded
if(DEBUG > 1 ) printf(" > Node is a relay: packet has to be routed\n");
// update forward input stat
stats[node_addr].forward_input++;
// check routing table for desired entry
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -