📄 timer_queue.c
字号:
/* Kernel AODV v2.0National Institute of Standards and Technology Luke Klein-Berndt----------------------------------------------------- Version 2.0 new features: * Updated to AODV draft version 11 * Managed internet gatewaying * Monitor wireles signal strength * Many bug fixes!-----------------------------------------------------Originally based upon MadHoc code. I am notsure how much of it is left anymore, but MadHocproved to be a great starting point.MadHoc was written by - Fredrik Lilieblad,Oskar Mattsson, Petra Nylund, Dan Ouchterlonyand Anders Roxenhag Mail: mad-hoc@flyinglinux.netThis software is Open Source under the GNU General Public Licence.*/#include "timer_queue.h"/**************************************************** timer_queue----------------------------------------------------A queue of timed events****************************************************/struct timer_queue_entry *timer_queue=NULL;extern struct route_table_entry *g_my_entry;extern u_int32_t g_broadcast_ip;extern u_int32_t g_my_ip;/**************************************************** read_timer_queue_proc----------------------------------------------------Prints out the current queue into a buffer whenever the proc file its read****************************************************/int read_timer_queue_proc(char *buffer, char **buffer_location, off_t offset, int buffer_length,int *eof,void *data){ struct timer_queue_entry *tmp;u_int64_t remainder, numerator; u_int64_t tmp_time; int len; static char *my_buffer; char temp_buffer[80]; my_buffer=buffer; sprintf(my_buffer,"\nTimer Queue\n---------------------------------\n"); tmp = timer_queue; while (tmp != NULL) { tmp_time=tmp->tv-getcurrtime(); //This is a fix for an error that occurs on ARM Linux Kernels because they do 64bits differently //Thanks to S. Peter Li for coming up with this fix! numerator = (tmp_time); remainder = do_div( numerator, 1000 ); sprintf(temp_buffer,"sec/msec: %lu/%lu\t id:%s\t retries: %u\t ttl: %u\t Type: %d\n", (unsigned long)numerator, (unsigned long)remainder, inet_ntoa(tmp->id), tmp->retries, tmp->ttl,tmp->flags); strcat(my_buffer,temp_buffer); tmp = tmp->next; } sprintf(temp_buffer,"\n---------------------------------\n"); strcat(my_buffer,temp_buffer); len = strlen(my_buffer); if (len <= offset+buffer_length) *eof = 1; *buffer_location = my_buffer + offset; len -= offset; if (len>buffer_length) len = buffer_length; if (len<0) len = 0; return len;}/**************************************************** print_timer----------------------------------------------------prints the contents of the timer queue to theconsole screen****************************************************/void print_timer_queue(){ struct timer_queue_entry *tmp; u_int64_t tmp_time; u_int64_t remainder, numerator; tmp = timer_queue; while (tmp != NULL) { tmp_time=tmp->tv-getcurrtime(); //This is a fix for an error that occurs on ARM Linux Kernels because they do 64bits differently //Thanks to S. Peter Li for coming up with this fix! numerator = tmp_time; remainder = do_div( numerator, 1000 ); printk("sec/msec: %lu/%lu id:%lu size: %d retries: %u ttl: %u\n", (unsigned long)numerator, (unsigned long)remainder, (unsigned long)tmp->id, tmp->size, tmp->retries, tmp->ttl); tmp = tmp->next; }}/**************************************************** timer_rreq----------------------------------------------------Handles the resendinf of RREQ if a routereply is not recieved in a certian amount of time****************************************************/int timer_rreq(struct timer_queue_entry *tmp_entry){ struct route_table_entry *tmp_route; struct rreq *tmp_rreq; u_int64_t currtime; tmp_rreq=tmp_entry->data;#ifdef TRACE printk("TIMER_QUEUE: Timer RREQ entered \n");#endif /* Check how may time we have sent it already */ if (tmp_entry->retries >= RREQ_RETRIES) { /* Sent it maximum times */#ifdef TRACE printk("TIMER_QUEUE: Timer RREQ exiting... retries used up! \n");#endif ipq_drop_ip(tmp_rreq->dst_ip); kfree(tmp_entry->data); /* Return error */ return 1; } else { /* Increment nr of retries */ tmp_entry->retries++; /* Check new TTL */ if (tmp_entry->ttl > TTL_THRESHOLD) tmp_entry->ttl = NET_DIAMETER; else tmp_entry->ttl += TTL_INCREMENT; tmp_route = (find_interface_by_ip(tmp_rreq->src_ip))->route_entry; (tmp_route->rreq_id)++; if (insert_rreq_id_queue_entry(tmp_rreq->src_ip, tmp_rreq->dst_ip,tmp_route->rreq_id,getcurrtime() + tmp_entry->ttl * 2 * NODE_TRAVERSAL_TIME) == 1) /* Couldn't add to broadcast list */ return 1; /* Send packet again */ local_broadcast( tmp_entry->ttl,tmp_rreq, tmp_entry->size); /* Set a new timer */ currtime = getcurrtime(); insert_timer_queue_entry(currtime + NET_TRAVERSAL_TIME, tmp_rreq,tmp_entry->size,tmp_rreq->dst_ip,tmp_entry->retries,tmp_entry->ttl, EVENT_RREQ);#ifdef TRACE printk("TIMER_QUEUE: Timer RREQ all done! \n");#endif } return 0;}void timer_neighbor(struct timer_queue_entry *timer_entry){ struct neighbor_list_entry *tmp_entry; struct route_table_entry *tmp_route; tmp_entry = find_neighbor_list_entry(timer_entry->id); if (tmp_entry!=NULL) { tmp_route=find_route_table_entry(tmp_entry->ip); if (tmp_route!=NULL) {#ifdef TRACE printk("TIMER_QUEUE: The link to Neighbor: %s \n",inet_ntoa(tmp_entry->ip));#endif //link_break(tmp_entry->ip); we can't delete it directly because that would trigger an error because you are making changes to the route table on an interupt!!! tmp_route->lifetime=0; insert_event_queue_entry(g_my_ip,g_my_ip,NULL,NULL,EVENT_CLEANUP,0,NULL,0); delete_neighbor_list_entry(tmp_entry->ip); } }}/**************************************************** hello_resend----------------------------------------------------Handles the resending of the Hello message andalso places the hello message back on thequeue so it will be called again****************************************************/int hello_resend(struct timer_queue_entry *tmp_entry){ struct rrep *tmp_rrep; struct interface_list_entry *tmp_interface; u_int64_t curr_time=getcurrtime(); u_int16_t random_number; tmp_rrep=tmp_entry->data; // we want to update the stats once every hello period if (g_my_ip==tmp_rrep->dst_ip) get_wireless_stats();#ifdef TRACE printk("TIMER: Hello RESEND!\n");#endif tmp_interface=find_interface_by_ip(tmp_rrep->dst_ip); if (tmp_interface==NULL) {#ifndef NO_ERROR printk("HELLO_RESEND: error retrieveing interface\n");#endif return 0; } tmp_rrep->dst_seq = htonl(tmp_interface->route_entry->dst_seq); local_broadcast(1,tmp_rrep, sizeof(struct rrep)); get_random_bytes(&random_number,sizeof(u_int16_t)); random_number=random_number%20; tmp_interface->last_hello=curr_time; insert_timer_queue_entry(tmp_entry->tv + HELLO_INTERVAL-random_number, tmp_rrep,tmp_entry->size,tmp_rrep->dst_ip,tmp_entry->retries,tmp_entry->ttl, EVENT_HELLO);#ifdef TRACE printk("TIMER: Hello RESEND! - all done!\n");#endif return 0;}/**************************************************** timer_cleanup----------------------------------------------------Gets rid of everything in the timer queue.Should be called before you shutdown the module****************************************************/void timer_cleanup(){#ifdef TRACE printk("timer cleanup entered!\n");#endif insert_event_queue_entry(g_my_ip,g_my_ip,NULL,NULL,EVENT_CLEANUP,0,NULL,0); insert_timer_queue_entry(getcurrtime() + ACTIVE_ROUTE_TIMEOUT, NULL,0,g_my_ip,0,0, EVENT_CLEANUP);#ifdef TRACE printk("timer cleanup exited!\n");#endif}/**************************************************** init_timer_queue----------------------------------------------------Initalizes the timer queue... duh!****************************************************/int init_timer_queue(){ init_timer(&aodv_timer); timer_queue=NULL; return 0;}/**************************************************** update_timer_queue----------------------------------------------------Sets the system alarm for the first event in thetimer queue****************************************************/static unsigned long tvtojiffies(struct timeval *value){ unsigned long sec = (unsigned) value->tv_sec; unsigned long usec = (unsigned) value->tv_usec;u_int64_t numerator, numerator1; //This is a fix for an error that occurs on ARM Linux Kernels because they do 64bits differently //Thanks to S. Peter Li for coming up with this fix! numerator = ULONG_MAX; do_div( numerator, HZ ); if (sec > (unsigned long) numerator) return ULONG_MAX; numerator = 1000000; do_div( numerator, HZ ); usec += numerator - 1; numerator1 = usec; do_div( numerator1, numerator ); usec = numerator1; return HZ*sec+usec;}void update_timer_queue(){ struct timeval delay_time; u_int64_t currtime; u_int64_t tv;u_int64_t remainder, numerator; delay_time.tv_sec = 0; delay_time.tv_usec = 0;#ifdef TRACE printk("PQ_UPDATETIMER: entered\n");#endif if (timer_queue == NULL) { // No event to set timer for delay_time.tv_sec = 0; delay_time.tv_usec = 0; } else { //* Get the first time value tv = timer_queue->tv; currtime = getcurrtime(); if (tv <= currtime)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -