SIOCGIWFREQ ioctl返回错误22 EINVAL -无效的参数,为什么

SIOCGIWFREQ ioctl returning error 22 EINVAL - Invalid argument, why?

本文关键字:无效 参数 为什么 EINVAL ioctl 返回 错误 SIOCGIWFREQ      更新时间:2023-10-16

我正在努力使用以下Qt/C++方法使用Linux库的无线扩展工具读取Wifi卡的当前频率通道:

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

现在,iw_get_ext总是返回-1, errno被设置为22的值。我已经看了errno.h和搜索错误22,我有以下错误声明:
#define EINVAL 22 /* Invalid argument */
为什么我在试图用ioctl查询网卡的当前频率通道时得到Invalid argument错误?我已经启动了应用程序,其中包含普通用户和root用户的代码,任何时候都是相同的结果:

static const UeTypeCurrentFrequencyChannel& UeNetworkManager::ueCurrentFrequencyChannel(const QString&) error(iw_get_ext): 22

为什么,我错过了什么?

附录# 1:
如果我从终端使用iwlist 扫描WiFi卡和网络,我得到所有需要的信息,无论我是作为普通用户还是根用户运行它。

附录# 2:代码已经升级,iw_get_range_info()可以正常工作。

附录# 3:情况变得很奇怪;偶尔我也会成功:

static const UeTypeCurrentFrequencyChannel& UeNetworkManager::ueCurrentFrequencyChannel(const QString&) success - current channel: QPair(QVariant(double, 2.412e+09),QVariant(int, 1))  

iwlist scan output:

相同
wlan0     Scan completed :
          Cell 01 - Address: 64:6E:EA:22:21:D4
                    Channel:1
                    Frequency:2.412 GHz (Channel 1)

经过一段时间的编程/测试应用程序,bug再次出现,但iwlist scan仍然工作。我使用Ubuntu 16.04.1 LTS内核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
是否可能问题与WiFiPower Management有关?

查看cfg80211_wext_giwfreq。这就是为什么如果你的 Wi-Fi卡没有使用任何连接模式,你会得到当前通道的EINVALiwlist scan命令之所以有效,是因为Wi-Fi卡会在扫描时间切换到AP client mode