00001
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <linux/module.h>
00031 #include <linux/kernel.h>
00032 #include <linux/init.h>
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];
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
00057
00058
00059
00060
00061
00062
00063
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
00075 if (checking_time - (list->timestamp)> timeout)
00076 {
00077 temp=list->next;
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
00110 ATH_LOCK(sc);
00111 IEEE80211_NODE_LOCK(nt);
00112 TAILQ_FOREACH (ni, &nt->nt_node, ni_list)
00113 {
00114 strcpy(mac_addr_temp,ether_sprintf(ni->ni_macaddr));
00115 insert_mac_to_broadcast(mac_addr_temp);
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
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
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
00189 struct task_struct *thread;
00190
00191 struct semaphore startstop_sem;
00192
00193 int terminate;
00194
00195 struct wait_queue *queue;
00196
00197 pid_t pid;
00198 void *data;
00199 }my_threads;
00200
00201
00202 void thread_neighbour(my_threads *thread);
00203
00204
00205 static void launch_thread(void (*func),void *data, my_threads *thread);
00206
00207
00208 static void kill_thread(my_threads *thread);
00209
00210
00211 my_threads neighbour_kthread;
00212
00213
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
00220 kernel_thread(func, (void *)thread, 0);
00221
00222
00223 down(&thread->startstop_sem);
00224 }
00225
00226 static void kill_thread(my_threads *thread)
00227 {
00228 if (thread->thread == NULL)
00229 {
00230
00231 return;
00232 }
00233
00234
00235
00236 init_MUTEX_LOCKED(&thread->startstop_sem);
00237
00238 #ifdef __alpha
00239
00240
00241
00242
00243
00244 mb();
00245 #endif
00246
00247
00248 thread->terminate = 1;
00249 #ifdef __alpha
00250
00251
00252
00253
00254
00255 mb();
00256 #endif
00257 kill_proc(SIGKILL, thread->pid, 1);
00258
00259
00260 down(&thread->startstop_sem);
00261 }
00262
00263 static void setup_thread(my_threads *thread)
00264 {
00265
00266 lock_kernel();
00267
00268
00269 thread->thread = current;
00270
00271
00272 siginitsetinv(¤t->blocked, sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM));
00273
00274
00275 thread->queue = NULL;
00276
00277
00278 thread->terminate = 0;
00279
00280
00281 unlock_kernel();
00282
00283
00284 up(&thread->startstop_sem);
00285
00286 }
00287
00288 static void leave_thread(my_threads *thread)
00289 {
00290
00291
00292
00293 thread->thread = NULL;
00294 #ifdef __alpha
00295 mb();
00296 #endif
00297
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
00326 break;
00327 }
00328 }
00329
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;
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
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;
00375 printk(KERN_ALERT "Init XIAN XNM (XIAN Neighbouring Manager module)\n");
00376
00377
00378 xian_broadcast_neighbour("ath0");
00379
00380
00381 launch_thread(thread_neighbour, param, & neighbour_kthread);
00382
00383
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