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.