📄 aodv_routing.pr.c
字号:
/*/* 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; /*/* 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);
if(DEBUG > 1 ) printf(" - Function aodv_data_pk_receive(destination is %d )\n",dest);
// update statsif(previousHop != source) { stats[previousHop].forward_output++; }// check packet final destinationif (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++; }
else
{ // 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 if(DEBUG > 1) printf(" > Check routing table for entry\n"); if(DEBUG > 1) aodv_entry_print(dest); if ((aodv_entry_nextHop_get(dest) != NOT_VALID) && (aodv_entry_nextHop_get(dest) != NON_EXISTENT)) {
// entry available: node forwards the packet
if(DEBUG > 1 ) printf(" > Node has fresh enough active entry\n > Data packet forwarded\n"); // schedule an event if no ack received within the waiting window if(DEBUG > 3) printf(" > Schedule Event if no ack received\n");
aodv_ack_timeout_schedule(data_pk_ptr,dest);
//send to mac
aodv_pk_send_to_mac_layer(data_pk_ptr,aodv_entry_nextHop_get(dest));
// re-active the route timeout (must delay the expiration event
// which has been scheduled for the current entry) aodv_entry_expirationTime_set(dest,op_sim_time()+ACTIVE_ROUTE_TIMEOUT); }
else if(aodv_entry_nextHop_get(dest) == NOT_VALID) {
printf(" > Error @ node %d: No forward route available: no active entry for dest %d\n",node_addr,dest); // insert data packet into buffer and try to repair the broken link if(DEBUG > 1 ) printf(" > Insert packet into buffer\n"); aodv_data_pk_queue(data_pk_ptr); // if no repair pending if(RequestSent[dest].status != WAITING_FOR_REPAIR) { // cancel expiration time aodv_entryPtr_expirationInterrupt_cancel(aodv_routingTable_entry_get(dest)); // attempt to repair if(DEBUG > 1 ) printf(" > Attempt to repair link\n"); aodv_link_repair_attempt(dest, aodv_entry_hopCount_get(source)); } } else // entry does not exist { // generate a rreq aodv_rreq_pk_generate(dest, WAITING_FOR_REPLY); }
}
if(DEBUG > 1 ) printf(" - Function aodv_data_pk_receive() done\n");
}
/***********************************************************/
/***************** INIT ROUTING TABLE ENTRY ****************/
/***********************************************************/
RoutingTableEntry* aodv_entry_create_new()
{
RoutingTableEntry* entryPtr;
/*/* Returns a new routing table entry with the default/* values.*/entryPtr= (RoutingTableEntry*) op_prg_mem_alloc(sizeof(RoutingTableEntry));entryPtr->status = ACTIVE;
entryPtr->dest = -1;entryPtr->nextHop = -1;
entryPtr->destSeqNb = 0; entryPtr->hopCount = -1;entryPtr->lastHopCount = -1;entryPtr->expirationTime = 0;entryPtr->lastExpirationTime = 0;return entryPtr;
}
/////////////////////////////////////////////////////////////////
/*********************** GENERATE ERROR ************************/
/////////////////////////////////////////////////////////////////
void aodv_rerr_pk_generate(int unreachableNode, int n_flag)
{
// vars
RoutingTableEntry * indexEntryError;ErrorContentStruct* newErrorStructPtr;
sObject* object;
Packet* rerr_pk_ptr;int source, dest, destSeqNb, unreachableDest, unreachableDestSeqNb, i;
/*/* Generate a RERR packet containing the list of all/* destinations (and their associated Dest. Seq. Nb.)/* that are now unreachable because of the loss of /* node given in the first parameter (unreachableNode). /* The N flag (n_flag) indicates whether entry should /* be deleted or not.*///init varsobject= routingTable->firstObject;newErrorStructPtr= (ErrorContentStruct *)
op_prg_mem_alloc(sizeof(ErrorContentStruct));
newErrorStructPtr->listOfUnreachableDest=newFifo();
// Beginif(DEBUG > 1) printf(" - Function aodv_rerr_pk_generate(destination %d)\n", unreachableNode);
// Read corresponding entryindexEntryError = aodv_routingTable_entry_get(unreachableNode);// check the non_delete flagif(n_flag == 0) { // If not set, invalidate entry and go through all listOfPrecursors and remove the unreachable
// destination from them: this is done via reverseListOfPrecursors
// invalidate entry (dest seq nb was previously incremented while attempting to repair) // this function will also schedule deletion for the current entry if(DEBUG > 1) printf(" - Invalidate entry\n"); aodv_entry_invalidate(indexEntryError->dest, indexEntryError->destSeqNb, n_flag); if(DEBUG > 1 ) printf(" > Remove unreachable node from all the precursor lists\n");
aodv_listOfPrecursors_node_remove(indexEntryError->dest); }// add the new unreachable destination to the RERR packet
if(DEBUG > 1 ) printf(" > Add destination to RERR packet\n");
// add destination to the list of new unreachable destinations aodv_listOfUnreachableDest_insert(newErrorStructPtr, indexEntryError->dest, indexEntryError->destSeqNb);// If non_delete flag is not set, process the rest of routingTable entries:// go through all entries, and process only those whos nextHop is the unreachable nodeif(DEBUG > 1) printf(" - Look for other lost destinations\n");if(n_flag == 0) { for(i=0;i<getFifoSize(routingTable);i++)
{ // read entry
indexEntryError = (RoutingTableEntry*)(object->data); // Proceed only if the unreachable node is the next hop for this destination if(indexEntryError->nextHop == unreachableNode && indexEntryError->dest != unreachableNode) { // read entry unreachableDest = indexEntryError->dest; unreachableDestSeqNb = indexEntryError->destSeqNb; // invalidate entry if(DEBUG > 1) printf(" > Ivalidate entry %d\n",unreachableDest); // invalidate entry and schedule deletion aodv_entry_invalidate(unreachableDest, unreachableDestSeqNb+1, n_flag); // go through all listOfPrecursors and remove the unreachable
// destination from them: this is done via reverseListOfPrecursors
if(DEBUG > 1 ) printf(" > Remove unreachable node from all the precursor lists\n");
aodv_listOfPrecursors_node_remove(unreachableDest); // add the new unreachable destination to the RERR packet
if(DEBUG > 1 ) printf(" > Add destination to RERR packet\n");
// add destination to the list of new unreachable destinations aodv_listOfUnreachableDest_insert(newErrorStructPtr, unreachableDest, unreachableDestSeqNb); // print entry if(DEBUG) aodv_entryPtr_print(indexEntryError); } else if(DEBUG > 1) printf(" > skip entry %d\n",indexEntryError->dest); object=object->next; }
}// if list of unreachable destinations is not empty, then // generate a RERR packet.if(getFifoSize(newErrorStructPtr->listOfUnreachableDest)>0)
{ // Create RERR packet rerr_pk_ptr = op_pk_create_fmt("AODV_RERR"); // Set N field value op_pk_nfd_set(rerr_pk_ptr,"N", n_flag);
// Set the error structure and add it to packet newErrorStructPtr->destCount = getFifoSize(newErrorStructPtr->listOfUnreachableDest); op_pk_nfd_set(rerr_pk_ptr,"ErrorContent",newErrorStructPtr,op_prg_mem_copy_create,op_prg_mem_free,sizeof(ErrorContentStruct));
if(DEBUG > 1) printf(" > RERR packet has been generated\n");
// Send to mac Layer aodv_pk_send_to_mac_layer(rerr_pk_ptr, BROADCAST); }else { if(DEBUG > 1) printf(" > No unreachable destination caused by link breakage\n");
}
if(DEBUG > 1) printf(" - Function aodv_rerr_pk_generate done !\n");
}
/*****************************************************************/
/************************ handle link breakage ******************/
/*****************************************************************/
void aodv_link_repair_attempt(int dest, int ttl_src)
{// varsRoutingTableEntry* entryPtr;int TTL_REQUEST;/*/* This function checks whether the lost link/* is repairable or not. If so, it generates a /* RREQ with the appropriate TTL. Else, it /* generates a RERR for the lost destination.*/// init varsentryPtr = aodv_routingTable_entry_get(dest);//beginif(DEBUG > 1 ) printf(" - Function aodv_link_repair_attempt(destination %d)\n", dest);
if(entryPtr != OPC_NIL) { // reset request sent repository if(RequestSent[dest].status != WAITING_FOR_REPAIR) { if(RequestSent[dest].status != OFF) aodv_requestSent_repository_reset(dest); // check if destination is no farther than MAX_REPAIR_TTL if(entryPtr->lastHopCount <(MAX_REPAIR_TTL+1)) { if(DEBUG > 1 ) printf(" > Link is repairable: mark entry UNDER_REPAIR\n");
// Set entry status to "UNDER_REPAIR" entryPtr->status = UNDER_REPAIR; // print entry if(DEBUG) aodv_entryPtr_print(entryPtr); // Update the RequestSent repository: // Compute the TTL value to use RequestSent[dest].ttl = max(MIN_REPAIR_TTL, ttl_src)+LOCAL_ADD_TTL; // generate RREQ if(DEBUG > 1 ) printf(" > Generating RREQ\n");
aodv_rreq_pk_generate(dest,WAITING_FOR_REPAIR);
} else { // generate RERR packet for the lost destination if(DEBUG > 1 ) printf(" > Node is too far: generating RERR\n"); aodv_rerr_pk_generate(dest,0); } } else if(DEBUG > 1 ) printf(" > Link already under repair: waiting for reply\n"); }}
/***********************************************************/
/********* aodv_listOfPrecursors_node_remove **************/
/***********************************************************/
void aodv_listOfPrecursors_node_remove(int precursor)
{
// var
int* destPtr;
int dest,size,t;
int* precursorPtr;
RoutingTableEntry* entryPtr;
sFifo* listOfDestination; /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -