On Thu, 2004-09-16 at 16:10 +0100, Jonathan Andrews wrote: > www.wildpackets.com/elements/ whitepapers/Converting_Signal_Strength.pdf > > If RSSI is converted to a db scale by the driver and the kernel has the > ability to map db back to RSSI then this solves the problems. > > By doing it this way it wouldn't matter how linear the RSSI on the card > is (as the driver can correct). It wouldn't matter how many bits the > card used to represent RSSI internally. It also allows devices that have > a true db reading to map in without (much?) conversion. > > The kernel would then make available a meaningful and consistent RSSI > derived from the db reading its using internally. > > The applications can then read one or both of (db) and (RSSI - the new > strict linux kernel defined one - not the fluffy manufacturers one). > > All thats needed is a conversion from RSSI to db for each device, > simplest place to stick that is in the driver - why complicate life any > further ! One particular problem I referred to was with the Cisco drivers. There are two ways to get strength for an access point, one is through the wireless scan (if the drivers support it) and the other is using iw_get_range()/iw_get_stats() for strength info on the currently associated access point. Atmel drivers currently don't return _any_ quality information from wireless scans. Using iw_get_range/stats, the strength value returned is completely different than the value returned when the same access point shows up in the scan, even if you are associated with it right then. Also on the cisco drivers, there doesn't seem to be a good way to actually determine the signal strength from a scan. For both these methods, you get back an iw_quality structure that has: struct iw_quality { uint8 qual; uint8 level; uint8 noise; } ----- snip from iwlib.c /* People are very often confused by the 8 bit arithmetic happening * here. * All the values here are encoded in a 8 bit integer. 8 bit integers * are either unsigned [0 ; 255], signed [-128 ; +127] or * negative [-255 ; 0]. * Further, on 8 bits, 0x100 == 256 == 0. * * Relative/percent values are always encoded unsigned, between 0 and 255. * Absolute/dBm values are always encoded negative, between -255 and 0. * * How do we separate relative from absolute values ? We use the * range to do that. The range allow to specify the real min/max * of the value. As the range struct only specify one bound of the * value, we assume that the other bound is 0 (zero). * For relative values, range is [0 ; range->max]. * For absolute values, range is [range->max ; 0]. * * Let's take two example : * 1) value is 75%. qual->value = 75 ; range->max_qual.value = 100 * 2) value is -54dBm. noise floor of the radio is -104dBm. * qual->value = -54 = 202 ; range->max_qual.value = -104 = 152 * * Jean II */ ------ Now the "qual" field is kind of ambiguous, and drivers seem to put different values in there (Cisco drivers _always_ set this to 0 for wireless scans). What we're interested in is the level/noise structures. All these values are either Relative or Absolute. Absolute values are in dBm/rssi (drivers seem to mix this up a _lot_) while Relative values are 0-100 as a percentage. The application itself has to figure out which is being used. Next, the dBm values are in the range of 0 - 255 which is in actuality -127 - 128. Cisco drivers only return Noise information when calling iw_get_stats() but not for a wireless scan, and I've found you cannot use the noise value from stats() along with the wireless scan data, which is where this problem lies. Cisco drivers also use some magic numbers here and there that don't quite add up (for example, you'll see the RSSI subtracted from 256 in some places, or subtracted from 321 then divided by two in other places). Devices also have "max" and "average" quality information which may or may not get used at various points. If you are using Relative values, then you need to compare the qual.level against the "max" quality level and the qual.noise against the "max" noise. Different drivers use different methods. So here's what we need to do: 1) DEFINE what quality mode drivers should use (ie Relative/Absolute). As in, all values MUST be in dBm (mandating percentages would deprive userspace of useful data) 2) ENSURE that drivers use consistent information between the iw_get_range()/iw_get_stats() calls and wireless scanning quality data 3) ENSURE that drivers don't use any magic numbers Dan