/home/tai/chorist/xian-1.2/src/xnm.c

Go to the documentation of this file.
00001 /*
00013  *  Copyright (C) 2006 THALES Communications
00014  *
00015  *  This file is part of XIAN software.
00016  *
00017  *  XIAN is free software; you can redistribute it and/or modify it
00018  *  under the terms of the GNU General Public License as published by
00019  *  the Free Software Foundation.
00020  *
00021  *  XIAN software is distributed in the hope that it will be useful,
00022  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024  *  GNU General Public License for more details.
00025  *
00026  *  You should have received a copy of the GNU General Public License
00027  *  along with XIAN software; if not, write to the Free Software
00028  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00029  * ************************************************************************************************************** */
00030 #include <linux/module.h> // needed by all the modules
00031 #include <linux/kernel.h>
00032 #include <linux/init.h> // for the macros
00033 #include <linux/netdevice.h>
00034 #include <linux/time.h>
00035 #include "include/xian_proto.h"
00036 #include "include/ksi.h"
00037 MODULE_DESCRIPTION("XIAN - Module XNM : XIAN Neighbouring  Manager module");
00038 MODULE_LICENSE("GPL");
00039 
00040 char dev_name[IFNAMESIZ+1];
00041 char macadd[IEEE80211_MAC_ADDR_LEN+1];
00042 
00043 unsigned char my_mac[IEEE80211_MAC_ADDR_LEN+1]; //@MAC of the node
00044 
00045 struct  neighbour_table *xian_table;
00046 
00047 struct neighbour_conf{
00048   unsigned int freq_update;
00049 };
00050 struct neighbour_conf *param;
00051 unsigned int metric = NODE_RSSI;
00052 
00053 
00054 
00055 /************************************************************************************************************//*
00056  *This function check the timestamp of the active neighbors of the considered node and delete the neighbor entry 
00057  * from the xian_table when its timestamp is timeout in the neighbortable.
00058  *
00059  *@param* list a pointer to the neighbor_table 
00060  *@param timeout the value of the timeout
00061  *
00062  *@return a pointer to the neighbor_table struct corresponding to the XIAN_table of active XIAN neighbors or
00063  *  NULL if not found.
00064  ****************************************************************************************************************/
00065 struct neighbour_table* xian_timeout( struct neighbour_table* list, long timeout)
00066 {
00067   long checking_time;
00068   struct neighbour_table* temp;
00069   if (list==NULL)
00070   {
00071         return NULL;
00072   }
00073   checking_time=jiffies_to_msecs(get_jiffies_64());
00074 // if the considered neighbour should be deleted
00075         if (checking_time - (list->timestamp)> timeout)
00076         {
00077         temp=list->next; // memorisation of the address of the next element
00078         kfree(list);
00079         printk("timeout of this node in the neighbour_table %s\n", list->macaddr);
00080         temp=xian_timeout(temp, timeout);
00081         return (temp);
00082         }
00083         else
00084         {       
00085         list->next = xian_timeout(list->next, timeout);
00086         return(list);
00087         } 
00088 }
00089 
00090 /*************************************************************************************************************/
00096 void xian_broadcast_neighbour(char * dev_name)
00097 {
00098   unsigned char mac_addr_temp[IEEE80211_MAC_ADDR_LEN+1];
00099   struct net_device *dev= dev_get_by_name(dev_name);
00100   if (dev)
00101     {
00102       
00103       struct ath_softc *sc= dev->priv;
00104       struct ieee80211com *ic = &sc->sc_ic;
00105       struct ieee80211_node_table *nt = &ic->ic_sta;
00106       struct ieee80211_node *ni;
00107      
00108       free_mac_to_broadcast();
00109      /* access to mad_wifi structure */       
00110       ATH_LOCK(sc);
00111       IEEE80211_NODE_LOCK(nt);
00112       TAILQ_FOREACH (ni, &nt->nt_node, ni_list) /* on traverse le tail queue forward */
00113         {          
00114           strcpy(mac_addr_temp,ether_sprintf(ni->ni_macaddr));
00115           insert_mac_to_broadcast(mac_addr_temp);  // constitution of the tab_mac_to_broadcast  
00116         }
00117       IEEE80211_NODE_UNLOCK(nt);
00118       ATH_UNLOCK(sc);
00119     }
00120 }
00121 XIAN_EXPORT_SYMBOL(xian_broadcast_neighbour);
00122 
00123 /*************************************************************************************************************/
00129 void xian_update_neighbour(char * dev_name)
00130 {
00131   xian_broadcast_neighbour(dev_name); 
00132   xian_table= xian_timeout(xian_table, 1000);           
00133 }
00134 XIAN_EXPORT_SYMBOL(xian_update_neighbour);
00135 
00136 
00137 /***************************************************************************************************************/
00142 void xian_get_xian_neighbour (unsigned char *saddr)
00143 {
00144   struct neighbour_table *temp_pt, *temp;
00145   temp_pt = xian_table;
00146   if (xian_table== NULL)
00147     {
00148       printk("adding the first node %s\n ", saddr);
00149       xian_table= kmalloc(sizeof(struct neighbour_table), GFP_ATOMIC);
00150       if (xian_table!= NULL)
00151       {   
00152       strncpy(xian_table->macaddr,saddr,IEEE80211_MAC_ADDR_LEN+1);
00153       xian_table->timestamp=jiffies_to_msecs(get_jiffies_64());
00154       xian_table->next=NULL;
00155       }
00156     }
00157   else
00158     {
00159       while (temp_pt!=NULL)
00160         {
00161           // if macaddr of the sending node is already contained in the xian table,the timestamp will be updated
00162           if (strncmp(temp_pt->macaddr,saddr,IEEE80211_MAC_ADDR_LEN+1)==0) 
00163             {
00164               temp_pt-> timestamp=  jiffies_to_msecs(get_jiffies_64());
00165               return;
00166             }
00167           else
00168             {
00169             // if macaddr of the sending node is not contained in the xian table, it will be added
00170             temp_pt=temp_pt->next;
00171             }
00172         }
00173       printk("adding the node with the MAC address %s to the xian table \n", saddr);
00174       temp= kmalloc(sizeof(struct neighbour_table), GFP_ATOMIC);          
00175       strncpy(temp->macaddr,saddr,IEEE80211_MAC_ADDR_LEN+1);
00176       temp->timestamp= jiffies_to_msecs(get_jiffies_64());
00177       temp->next=xian_table;
00178       xian_table = temp;                     
00179                         
00180 }       
00181 }
00182 XIAN_EXPORT_SYMBOL(xian_get_xian_neighbour);
00183 
00184 /****************************************************************************************************/
00186 typedef struct
00187 {
00188   /* Linux task structure of thread */
00189   struct task_struct *thread;
00190   /* semaphore needed on start and creation of thread */
00191   struct semaphore   startstop_sem;
00192   /* flag to tell thread whether to die or not */
00193   int terminate;
00194   /* queue thread is waiting on */
00195   struct wait_queue *queue;
00196   /* process id of the thread */
00197   pid_t pid;
00198   void *data;
00199 }my_threads;
00200 
00201 /* prototype of our function thread */
00202 void thread_neighbour(my_threads *thread);
00203 
00204 /* prototype to create a new thread */
00205 static void launch_thread(void (*func),void *data, my_threads *thread);
00206 
00207 /* prototype to kill a running thread */
00208 static void kill_thread(my_threads *thread);
00209 
00210 /* the variable that contains the thread data */
00211 my_threads neighbour_kthread;
00212 
00213 /* create a new kernel thread */
00214 static void launch_thread(void (*func),void *data, my_threads *thread)
00215 {
00216   init_MUTEX_LOCKED(&thread->startstop_sem);
00217   thread->data=data;
00218 
00219   /* create the new thread */
00220   kernel_thread(func, (void *)thread, 0);
00221   
00222   /* wait till it has reached the setup_thread routine */
00223   down(&thread->startstop_sem);
00224 }
00225 
00226 static void kill_thread(my_threads *thread)
00227 {
00228   if (thread->thread == NULL)
00229     {
00230       //printk("[XIAN Metric MANAGER] Killing non existing thread!\n");
00231       return;
00232     }
00233   
00234   /* get the global lock to prevent a race in the
00235      fall-asleep phase of the thread */
00236   init_MUTEX_LOCKED(&thread->startstop_sem);
00237   
00238 #ifdef __alpha
00239   /* on Alpha platfrom we need to do a memory barrier
00240      here to be sure that the flags are visible on
00241      all CPUs. This is not portable, we should e.g.
00242      use atomic_t here for passing the information.
00243   */
00244   mb();
00245 #endif
00246   
00247   /* set flag to request thread termination */
00248   thread->terminate = 1;
00249 #ifdef __alpha
00250   /* on Alpha platfrom we need to do a memory barrier
00251      here to be sure that the flags are visible on
00252      all CPUs. This is not portable, we should e.g.
00253      use atomic_t here for passing the information.
00254   */
00255   mb();
00256 #endif
00257   kill_proc(SIGKILL, thread->pid, 1);
00258   
00259   /* block till thread terminated */
00260   down(&thread->startstop_sem);
00261 }
00262 
00263 static void setup_thread(my_threads *thread)
00264 {
00265   /* lock the kernel */
00266   lock_kernel();
00267   
00268   /* fill in thread structure */
00269   thread->thread = current;
00270   
00271   /* set signal mask to what we want to respond */
00272   siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM));
00273   
00274   /* initialise wait queue */
00275   thread->queue = NULL;
00276   
00277   /* initialise termination flag */
00278   thread->terminate = 0;
00279   
00280   /* let others run */
00281   unlock_kernel();
00282   
00283   /* tell the creator that we are ready and let him run */
00284   up(&thread->startstop_sem);
00285   
00286 }
00287 
00288 static void leave_thread(my_threads *thread)
00289 {
00290   /* we are terminating */
00291   
00292   /* lock the kernel, the exit will unlock it */
00293   thread->thread = NULL;
00294 #ifdef __alpha
00295   mb();
00296 #endif
00297   /* notify the kill_thread() routine that we are terminating. */
00298   up(&thread->startstop_sem);
00299 }
00300 
00301 /****************************************************************/
00305 void thread_neighbour(my_threads *thread)
00306 {
00307  
00308   struct neighbour_conf *report_config;
00309   unsigned int jiffies;
00310   report_config= (struct neighbour_conf *)thread->data;
00311   jiffies= ((HZ * (report_config->freq_update) +999) / 1000)+1;
00312   printk("XNM KThread wake up\n");
00313   setup_thread(thread);
00314   printk(" XIAN Neighbouring Manager : updated of lists of XIAN active neighbours every %d\n ", report_config->freq_update);
00315   while(1)
00316       {
00317         if (report_config->freq_update >0)
00318           { 
00319             set_current_state(TASK_UNINTERRUPTIBLE);
00320             jiffies= schedule_timeout(jiffies);
00321             xian_update_neighbour("ath0");          
00322           }
00323         if (thread->terminate)
00324           {
00325             /* we received a request to terminate ourself */
00326             break;
00327           }
00328       }
00329   /* in case of terminaison of the thread */
00330     leave_thread(thread);
00331 }
00332 
00333 
00334 /*************************************************************/
00343 void treatment_neighbour(unsigned char *saddr, struct metric_msg *metric){
00344  
00345    xian_get_xian_neighbour(saddr);
00346    
00347 }
00348 EXPORT_SYMBOL(treatment_neighbour);
00349 
00350 /************************************************************************************************************************/
00356 void config(unsigned int metric)
00357 {
00358   int freq=500; //millisecond  frequency og the xian message containing the metric
00359   void (*pf)(unsigned char * saddr, struct metric_msg *metric);
00360   pf=&treatment_neighbour;  
00361   strcpy(my_mac, "FF:FF:FF:FF:FF:FF");
00362   register_id(metric, metric, "ath0", my_mac, freq, pf);  
00363 }
00364 
00365 
00366 /************************************************************************************************************************
00367 MODULE XIAN NEIGHBOUR
00368 ************************************************************************************************************************/
00369 
00370 int xian_neighbour_init(void)
00371 {
00372   xian_table=NULL;
00373   param=kmalloc(sizeof(struct neighbour_conf), GFP_KERNEL);
00374   param-> freq_update=2000; // frequency of the update of the neighbour table and tab_mac_to_broadcast 
00375   printk(KERN_ALERT "Init  XIAN XNM (XIAN Neighbouring Manager module)\n");
00376   
00377   // first polling to constitute the tab_mac_to_broadcast
00378   xian_broadcast_neighbour("ath0"); 
00379  
00380   // update of the tab_mac_to_broadcast (thread 1)
00381   launch_thread(thread_neighbour, param, & neighbour_kthread);     
00382     
00383   // configuration of the metric with its frequency and the invoked treatment at the reception (thread 2)
00384   config(metric);  
00385   return(0);
00386  
00387 }
00388 
00389 
00390 void xian_neighbour_exit(void)
00391 {
00392   kill_thread(&neighbour_kthread);
00393   printk(KERN_ALERT "Unload XIAN XNM (XIAN Neighbouring Manager module)\n");
00394   unregister_id(metric, metric);   
00395   kfree (xian_table);
00396   kfree(param);
00397 }
00398 
00399 module_init(xian_neighbour_init);
00400 module_exit(xian_neighbour_exit);
00401 
00402 

Generated on Mon Jan 21 12:31:46 2008 for XIAN by  doxygen 1.5.3