I am struggling to read current frequency channel of Wifi card using Wireless Extension Tools for Linux library with following Qt/C++
method:
const UeTypeCurrentFrequencyChannel& UeNetworkManager::ueCurrentFrequencyChannel(const QString& interfaceName) { static UeTypeCurrentFrequencyChannel result=UeTypeCurrentFrequencyChannel(); iwreq wrq; iw_range range; int kernelSocket=iw_sockets_open(); if(iw_get_range_info(kernelSocket, interfaceName.toLocal8Bit().constData(), &range)>=0) { if(iw_get_ext(kernelSocket, interfaceName.toLocal8Bit().constData(), SIOCGIWFREQ, &wrq)>=0) { //BUG current frequency and channel is not read, it might be becuase of nonroot credentials - it returns error 22 (EINVAL - Invalid argument), why? result.first=iw_freq2float(&(wrq.u.freq)); result.second=iw_freq_to_channel(result.first.toDouble(), &range); qDebug() << Q_FUNC_INFO << "success - current channel:" << result; } else { result.first=QString(interfaceName); result.second=QString(tr("current channel read failed.")); qDebug() << Q_FUNC_INFO << "error (iw_get_ext):" << errno; } // if } else { result.first=QString(interfaceName); result.second=QString(tr("current channel read failed.")); qDebug() << Q_FUNC_INFO << "error (iw_get_range_info):" << errno; } // if iw_sockets_close(kernelSocket); return result; } // ueCurrentFrequencyChannel
Now, iw_get_ext
always returns -1
and errno
is set to value of 22
. I’ve taken a look at the errno.h and search for error 22
and I’ve got following error declaration:
#define EINVAL 22 /* Invalid argument */
.
Why am I getting Invalid argument
error while trying to query current frequency channel of network adapter with ioctl
? I’ve launched application containing this code as normal user and as root, same result any time:
static const UeTypeCurrentFrequencyChannel& UeNetworkManager::ueCurrentFrequencyChannel(const QString&) error(iw_get_ext): 22
Why, what am I missing?
Addendum #1:
If I scan WiFi cards and networks using iwlist
from terminal, I get all needed info, regardless if I run it as normal user or root.
Addendum #2:
The code has been upgraded, iw_get_range_info()
works.
Addendum #3: The situation have just got weired; On random occasions, I get succes:
static const UeTypeCurrentFrequencyChannel& UeNetworkManager::ueCurrentFrequencyChannel(const QString&) success - current channel: QPair(QVariant(double, 2.412e+09),QVariant(int, 1))
which same as iwlist scan output
:
wlan0 Scan completed : Cell 01 - Address: 64:6E:EA:22:21:D4 Channel:1 Frequency:2.412 GHz (Channel 1)
After some time of programming/testing app, bug reappears, however iwlist scan
still works. I am using Ubuntu 16.04.1 LTS
with kernel Linux workstation 4.4.0-38-generic #57-Ubuntu SMP Tue Sep 6 15:42:33 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
.
Is it maybe possible the problem has to something to do with WiFi
card Power Management
?
Advertisement
Answer
Look at cfg80211_wext_giwfreq. That is why you get EINVAL
of current channel if your Wi-Fi
card is not used any connection mode.
The command iwlist
scan works because Wi-Fi card switches to AP client mode
on the scan time.