/* * This file implement the Wireless Extensions spy API. * * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved. * * (As all part of the Linux kernel, this file is GPL)
*/
/* Make sure driver is not buggy or using the old API */ if (!spydata) return -EOPNOTSUPP;
/* Disable spy collection while we copy the addresses. * While we copy addresses, any call to libipw_spy_update()
* will NOP. This is OK, as anyway the addresses are changing. */
spydata->spy_number = 0;
/* We want to operate without locking, because libipw_spy_update() * most likely will happen in the interrupt handler, and therefore * have its own locking constraints and needs performance. * The rtnl_lock() make sure we don't race with the other iw_handlers. * This make sure libipw_spy_update() "see" that the spy list
* is temporarily disabled. */
smp_wmb();
/* Are there are addresses to copy? */ if (wrqu->data.length > 0) { int i;
/* Copy addresses */ for (i = 0; i < wrqu->data.length; i++)
memcpy(spydata->spy_address[i], address[i].sa_data,
ETH_ALEN); /* Reset stats */
memset(spydata->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
}
/* Make sure above is updated before re-enabling */
smp_wmb();
/* Send event to user space */
wireless_send_event(dev, SIOCGIWTHRSPY, &wrqu, (char *) &threshold);
}
/* ---------------------------------------------------------------- */ /* * Call for the driver to update the spy data. * For now, the spy data is a simple array. As the size of the array is * small, this is good enough. If we wanted to support larger number of * spy addresses, we should use something more efficient...
*/ void libipw_spy_update(struct net_device * dev, unsignedchar * address, struct iw_quality * wstats)
{ struct iw_spy_data * spydata = get_spydata(dev); int i; int match = -1;
/* Make sure driver is not buggy or using the old API */ if (!spydata) return;
/* Update all records that match */ for (i = 0; i < spydata->spy_number; i++) if (ether_addr_equal(address, spydata->spy_address[i])) {
memcpy(&(spydata->spy_stat[i]), wstats, sizeof(struct iw_quality));
match = i;
}
/* Generate an event if we cross the spy threshold. * To avoid event storms, we have a simple hysteresis : we generate * event only when we go under the low threshold or above the
* high threshold. */ if (match >= 0) { if (spydata->spy_thr_under[match]) { if (wstats->level > spydata->spy_thr_high.level) {
spydata->spy_thr_under[match] = 0;
iw_send_thrspy_event(dev, spydata,
address, wstats);
}
} else { if (wstats->level < spydata->spy_thr_low.level) {
spydata->spy_thr_under[match] = 1;
iw_send_thrspy_event(dev, spydata,
address, wstats);
}
}
}
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.