【问题标题】:SIOCGIWFREQ ioctl returning error 22 EINVAL - Invalid argument, why?SIOCGIWFREQ ioctl 返回错误 22 EINVAL - 参数无效,为什么?
【发布时间】:2017-02-05 18:27:48
【问题描述】:

我正在努力使用 Wireless Extension Tools for Linux library 和以下 Qt/C++ 方法读取 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 卡和网络,我会得到所有需要的信息,无论我是以 普通用户 还是 root 身份运行它>。

附录 #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)

经过一段时间的编程/测试应用程序,错误再次出现,但 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
问题是否可能与WiFi card Power Management 有关?

【问题讨论】:

  • 测试这段代码时使用哪种连接方式?
  • 我没有连接到任何 WiFi 网络,我只想将可用的 WiFi 网络属性收集到单个数据结构中(SSID、可用信道/频率、当前信道/频率、接入点强度、安全模式) - 基本上是iwlist scancell info
  • 扫描后执行你的函数有问题,不是吗?你能得到更多关于你做什么的信息吗?
  • 看看cfg80211_wext_giwfreq。这就是为什么如果您的 Wi-Fi 未使用任何连接模式,您会得到当前频道的 EINVAL。
  • 命令 iwlist scan 有效,因为 Wi-Fi 卡在扫描时切换到 AP 客户端模式。

标签: c++ linux wifi ioctl


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-26
    • 1970-01-01
    • 1970-01-01
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-16
    相关资源
    最近更新 更多