Using wireless tools for linux in a c program, and I did a network scan wanting to find the signal strength (dBm) of each of the detected networks.
I found the following in the wireless.h:
struct iw_quality
{
__u8 qual; /* link quality (%retries, SNR,
%missed beacons or better...) */
__u8 level; /* signal level (dBm) */
__u8 noise; /* noise level (dBm) */
__u8 updated; /* Flags to know if updated */
};
I print out the "level" in my C program like this:
printf("Transmit power: %lu ", result->stats.qual.level);
also tried %d, but got the same output.
The result I get is numbers that look something like 178, 190, 201, 189 etc...
Is there a chance that these numbers are in Watts? According to a watt->dBm converter, 178 watts is approx. 52.50dBm ?
What should I be getting instead? Because I thought dBm translates to -80dBm or something.
Do I need to convert those numbers? How do I get the right output?
Thanks!!
=======UPDATE=========
I noticed some weird behaviour. When I use the level property of wireless.h through my program, the "strongest" value I have recorded is around -50dBm, whereas with the same router, when I ran "iw wlan0 scan", I receive around -14dBm as the strongest signal.
Does anyone know what causes this difference??
It looks like you found the right answer. For the record, this is what the source (iwlib.c) says about the encoding.
/* 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 between -192 and 63.
* (Note that up to version 28 of Wireless Tools, dBm used to be
* encoded always negative, between -256 and -1).
*
* How do we separate relative from absolute values ?
* The old way is to use the range to do that. As of WE-19, we have
* an explicit IW_QUAL_DBM flag in updated...
* 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 ; 63].
*
* 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
*/
level and noise fall under example 2, and can be decoded with a cast to a signed 8 bit value.
For future record, this was resolved from the comments, thanks to the relevant people.
I simply needed to cast the unsigned int to a signed one and it was solved.
Changed the print line to this:
printf("Transmit power: %d ", (int8_t) result->stats.qual.level);
Now the values that looked like 178, 200 turned to -80, -69 etc!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With