Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wireless.h How do I print out the signal level?

Tags:

c

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??

like image 580
bubbly Avatar asked Jan 26 '26 19:01

bubbly


2 Answers

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.

like image 189
AShelly Avatar answered Jan 28 '26 12:01

AShelly


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!

like image 42
bubbly Avatar answered Jan 28 '26 11:01

bubbly