📄 aodv_routing.pr.c
字号:
/* When a node (precursor) is no longer available, /* the current function is called to remove it from /* any precursor list within the routing table. To /* do so, the function reads the entry corresponding /* to the node "precursor" within the /* reversePrecursorList and gets the list of entries /* where "precursor" is a precursor. It then goes /* through these entries and removes the lost node /* form their precursor lists. */ // begin
if(DEBUG > 3 ) printf(" - Function aodv_listOfPrecursors_node_remove(): precursor = %d\n", precursor);
// check if the unreachableDestination has an entry in the reversePrecursorList
listOfDestination= (sFifo*) readInFifoMultiplex(reverseListOfPrecursors, precursor);
if(listOfDestination != OPC_NIL)
{
size= getFifoSize(listOfDestination); if(DEBUG > 3 ) printf(" > Node is at least on one node\'s precursor list: total = %d\n",size);
for(t=0;t<size;t++)
{
destPtr=getInFifo(listOfDestination);
dest= (*destPtr); // PRECURSOR is present in DEST routing table entry
if(DEBUG > 3 ) printf(" - on entry# %d... ", dest);
op_prg_mem_free(destPtr);
// the entry is read
entryPtr= aodv_routingTable_entry_get( dest);
if(entryPtr != OPC_NIL) { // the PRECURSOR entry is extracted from the list of precursors
precursorPtr= (int*) getInFifoMultiplex(
entryPtr->listOfPrecursors,precursor);
op_prg_mem_free(precursorPtr);
} else { if(DEBUG > 3 ) printf(" - Entry# %d does not exist", dest); } }
}
else if(DEBUG > 3 ) printf(" > Node was not found on any list of precursors !\n"); if(DEBUG > 3 ) printf("\n - Function aodv_listOfPrecursors_node_remove()... done !\n");
}
/////////////////////////////////////////////////////////////////
/******************** update list of precursors ****************/
/////////////////////////////////////////////////////////////////
void aodv_listOfPrecursors_node_put(RoutingTableEntry* forwardEntryPtr,int previousHop) { int *int_ptr, *previousHopPtr; /* /* Add the node "previousHop" to the precursor list of /* the given entry. /* Note that node is put in subqueue whose index equals /* to its MAC address (previousHop). This makes it easier /* to remove the node if it lost. */ // if listOfPrecursors not initialized, then initialize it if(forwardEntryPtr->listOfPrecursors == OPC_NIL) { forwardEntryPtr->listOfPrecursors = newFifo(); } //check if node is already in int_ptr= (int*) readInFifoMultiplex(forwardEntryPtr->listOfPrecursors, previousHop); if(int_ptr != OPC_NIL)
{ if(DEBUG > 3 ) printf(" > Precursor is already on the list !\n"); }
else { if(DEBUG > 3 ) printf(" > Precursor does not exist, function has to add it!\n"); // create a pointer to the node's address value previousHopPtr = (int*) op_prg_mem_alloc(sizeof(int)); *previousHopPtr
= previousHop; // add node to the precursol list if(DEBUG > 3 ) printf(" > Adding precursor %d\n",previousHop); putInFifoMultiplex(forwardEntryPtr->listOfPrecursors,
previousHopPtr, previousHop);
if(DEBUG > 3 ) printf(" > Previous Hop (%d) should have been added to precursor list of entry# %d\n", previousHop, forwardEntryPtr->dest); // update reverse list of precursors aodv_reverseListOfPrecursors_update(previousHop,forwardEntryPtr->dest);
} } /////////////////////////////////////////////////////////////////
/*********************** HANDLE HELLO MESSAGE ******************/
/////////////////////////////////////////////////////////////////
void aodv_hello_msg_receive(Packet* rrep_pk_ptr)
{
// var
int source, dest, hopCount, lastHopCount;
int destSeqNb, previousHop;
double lifetime;RoutingTableEntry * newEntryPtr, * forwardEntryPtr;Boolean request_was_pending =
OPC_FALSE;
/*/* This routine processes the upcoming hello message.*/// begin
// packet read
op_pk_nfd_get (rrep_pk_ptr,"PreviousHop",&previousHop);
op_pk_nfd_get (rrep_pk_ptr,"SRC",&source);
op_pk_nfd_get (rrep_pk_ptr,"DEST",&dest);
op_pk_nfd_get (rrep_pk_ptr,"DestSeqNb",&destSeqNb);
// N.B. hop count field is incremented by 1
at receptionop_pk_nfd_get (rrep_pk_ptr,"HopCount",&hopCount);
op_pk_nfd_set (rrep_pk_ptr,"HopCount",hopCount+1);
op_pk_nfd_get (rrep_pk_ptr,"HopCount",&hopCount);
op_pk_nfd_get (rrep_pk_ptr,"Lifetime",&lifetime);
if(DEBUG > 3) printf(" - Function aodv_hello_msg_receive(from node %d)\n",source);// check if entry already existsforwardEntryPtr=aodv_routingTable_entry_get( dest);// if entry does not exist: create it and add it to table (with default values)if(forwardEntryPtr == OPC_NIL) { // entry does not exist if(DEBUG > 1 ) printf(" > Entry does not exist\n"); forwardEntryPtr=aodv_entry_create_new();
forwardEntryPtr->listOfPrecursors=newFifo(); forwardEntryPtr->dest = source; // add entry to routing table aodv_routingTable_entryPtr_put(forwardEntryPtr); }if(aodv_entryPtr_hopCount_get(forwardEntryPtr) == INFINITY) { // entry is either invalid or under repair or newly created if(DEBUG > 1 ) printf(" > Node creates entry\n"); // Set entry values forwardEntryPtr->dest=dest;
forwardEntryPtr->destSeqNb=destSeqNb; forwardEntryPtr->hopCount=hopCount;
forwardEntryPtr->nextHop=previousHop;
// check whether a request is pending if(RequestSent[dest].status != OFF) { if(DEBUG > 1 ) printf(" > A request was running for the newly created entry\n"); // update requestSent repository aodv_requestSent_repository_reset(dest);
// set serve buffer flag request_was_pending = OPC_TRUE; } }else // entry is active { if(DEBUG > 1 ) printf(" > Active entry already exist\n"); // forward entry already exists if((destSeqNb > forwardEntryPtr->destSeqNb) ||
((destSeqNb==forwardEntryPtr->destSeqNb)&&
(hopCount < forwardEntryPtr->hopCount)))
{ // node updates his entry for the DESTINATION node only if (greater destSeqNb) or (same seqNbs but smaller hopCount) if(DEBUG > 1 ) printf(" > Node updates its entry\n");
forwardEntryPtr->destSeqNb=destSeqNb;
forwardEntryPtr->lastHopCount=forwardEntryPtr->hopCount;
forwardEntryPtr->hopCount=hopCount;
forwardEntryPtr->nextHop=previousHop;
} /* end of if entry has to be udated */ else if(DEBUG > 1 ) printf(" > Entry does not need to be updated\n"); } /* end of if forward entry is active */// Timeout always updatedif((op_sim_time()+lifetime) > forwardEntryPtr->expirationTime) { aodv_entry_expirationTime_set(dest,op_sim_time()+lifetime); }else if(DEBUG > 1) printf(" > Entry timeout does not need to be updated\n");
// set status to activeforwardEntryPtr->status = ACTIVE;// destroy packetop_pk_destroy(rrep_pk_ptr);// serve buffer if neededif( request_was_pending == OPC_TRUE) { // serve buffer aodv_buffer_serve(dest); }if(DEBUG > 1 ) printf(" - Function handleHelloMsg() done\n");} /* end of handleHelloMsg *//////////////////////////////////////////////////////////////////
/*********************** HANDLE REPLY **************************/
/////////////////////////////////////////////////////////////////
void aodv_rrep_pk_receive(Packet* rrep_pk_ptr)
{
// var
Boolean forward_entry_created_or_updated = OPC_FALSE;
int source, dest, destSeqNb, hopCount;
Ici* ici_ptr;
/*/* Receive RREP and decide whether to update or create/* the corresponding entry and whether to forward or /* discard the received RREP.*/// begin
if(DEBUG > 1 ) printf(" - Function aodv_rrep_pk_receive()\n");
// packet read
op_pk_nfd_get (rrep_pk_ptr,"HopCount",&hopCount);
op_pk_nfd_set (rrep_pk_ptr,"HopCount",hopCount+1);
op_pk_nfd_get (rrep_pk_ptr,"SRC",&source);
op_pk_nfd_get (rrep_pk_ptr,"DEST",&dest);
op_pk_nfd_get (rrep_pk_ptr,"DestSeqNb",&destSeqNb);
op_pk_nfd_get (rrep_pk_ptr,"HopCount",&hopCount);
// nodes checks compares his own destSeqNb for this destination to the destSeqNb in the RREP packetif(aodv_entry_destSeqNb_get(dest) <= destSeqNb) { if(DEBUG > 1) printf(" > Reply is fresh enough: node updates its routingTable\n");
forward_entry_created_or_updated = aodv_entry_update_or_create_from_rrep(rrep_pk_ptr); }// if node's relay and a forward route's been updated or created, node forwards RREPif((node_addr != source) && (forward_entry_created_or_updated == OPC_TRUE)) { // node checks his routing table for a reverse entry // if a route's available, node updates its reverse entry (list of precursor) and forwards rrep to nextHop if ((aodv_entry_nextHop_get(source) != NOT_VALID) && (aodv_entry_nextHop_get(source) != NON_EXISTENT)) { // Packet has a reverse entry // add next Hop Toward Source to the precursor list of the forward entry
aodv_listOfPrecursors_node_put(aodv_routingTable_entry_get(dest), aodv_entry_nextHop_get(source)); // node forwards RREP aodv_rrep_pk_forward(rrep_pk_ptr); } else { // no reverse entry was found if(DEBUG > 1 ) printf(" > ERROR @ node %d: No reverse entry was found to forward RREP!\n", node_addr); } }// if a forward entry's been created or updated, node schedule interruption to serve data bufferif(forward_entry_created_or_updated == OPC_TRUE) { if(DEBUG > 1 ) printf(" > Serve the buffer\n");
// serve buffer
aodv_buffer_serve(dest); }if(DEBUG > 1 ) printf(" > Print forward entry if any available\n");if(DEBUG > 1 ) aodv_entry_print(dest);if(DEBUG > 1 ) printf(" > Print reverse entry if any available\n");if(DEBUG > 1 ) aodv_entry_print(source);if(DEBUG > 1 ) printf(" - Function aodv_rrep_pk_receive() done\n");
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// void aodv_rrep_pk_forward(Packet *rrep_pk_ptr) ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//void aodv_rrep_pk_forward(Packet *rrep_pk_ptr) { // vars int source; /* /* Unicast the RREP to next hop along /* the reverse path (next hop toward /* the source that generate the RREQ. */ // init op_pk_nfd_get (rrep_pk_ptr,"SRC",&source); // send to mac layer if(DEBUG > 1 ) printf(" > Forward RREP to source node [next hop is %d]\n",aodv_entry_nextHop_get(source)); aodv_pk_send_to_mac_layer(rrep_pk_ptr,aodv_entry_nextHop_get(source)); // refresh reverse entry's timeout aodv_entry_expirationTime_set(source, op_sim_time()+ ACTIVE_ROUTE_TIMEOUT); }//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// Boolean aodv_entry_update_or_create_from_rrep(Packet *rrep_pk_ptr) ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//Boolean aodv_entry_update_or_create_from_rrep(Packet* rrep_pk_ptr) { // vars Boolean result = OPC_FALSE; RoutingTableEntry * forwardEntryPtr; int source, dest; /* /* when a RREP packet is received, a node either /* creates or updates the corresponding entry in /* its routing table or simply does nothing. /* This function returns the value OPC_TRUE is a /* routing table entry was created or updated. /* */ // init op_pk_nfd_get (rrep_pk_ptr,"DEST",&dest); // begin if(aodv_routingTable_entry_get(dest) == OPC_NIL) { //node creates a new entry
result = aodv_entry_create_from_rrep(rrep_pk_ptr); } else { forwardEntryPtr = aodv_routingTable_entry_get(dest); if(forwardEntryPtr->status == UNDER_REPAIR) { // node checks if entry is repairable
if(DEBUG > 1 ) printf(" > Attempt to repair link from RREP\n"); result = aodv_entry_repair_from_rrep(rrep_pk_ptr); } else { //node updates entry
result = aodv_entry_update_from_rrep(rrep_pk_ptr); } } // if reply's reached its destination, then node destroys it // node also updates its RequestSent repository op_pk_nfd_get (rrep_pk_ptr,"SRC",&source); if(node_addr == source) { // destroy rrep if(DEBUG > 1 ) printf(" > Reply has reached its destination: node destroys it.\n"); op_pk_destroy(rrep_pk_ptr); // reset RequestSent repository if(RequestSent[dest].status != OFF) aodv_requestSent_repository_reset(dest); } return result; }//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// Boolean aodv_entry_repair_from_rrep(Packet *rrep_pk_ptr) ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
Boolean aodv_entry_repair_from_rrep(Packet* rrep_pk_ptr) { // vars RoutingTableEntry * entryPtr; Boolean result = OPC_TRUE; int dest,destSeqNb,hopCount, previousHop, lastHopCount; double
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -