wpa_supplicant C API 未定义的行为

wpa_supplicant C API undefined behavior

我设法让 wpa_supplicant C API 工作。但是每次我重新启动我的程序时它的行为都完全不同。

每次都连接成功。但随后麻烦开始了:

有时 SCAN 回复空字符串,但 return 回复 0 (Ok)。 在另一个 运行 中,它回复 "OK\n" 和 returns 0。当我循环并等待 return 的 0 和 "OK\n"-回复它 运行 永远是空回复和 0 return.

在极少数情况下 SCAN returns 0 和回复 "OK\n" 我继续等待 SCAN_RESULTS 到 return 0。此时它的行为完全随机。有时它会回复整个扫描结果。有时它只回复 return 0 并且扫描结果在我的事件管道中。 或者像大多数情况下那样:它 returns 0 但什么都不做。没有回复,没有事件。没有什么。

为了调试,我将我的代码缩减为这个片段并试图找出问题所在。我完成了,尝试了一切,我对 ctrl 界面的文档感到有些沮丧,它没有定义任何工作流程或提示。我厌倦了逆向工程 wpa_cli.c 来弄清楚它们的流程。

我必须附上,大多数情况下第一个 PING 运行良好。每隔一个 PING 都会产生空字符串。

/* some includes */

wpa_ctrl* _wpac;

static void callback(char* rply, size_t rplylen){
    std::cout << std::string(rply,rplylen) << std::endl;
}

bool ScanResults() {
    if(_wpac)
    {
        char rply[4096]; //same as in wpa_cli.c
        size_t rplylen;
        int retval = wpa_ctrl_request(_wpac,"SCAN_RESULTS",12,rply,&rplylen,callback);

        if(retval == 0) {
            std::string rplystring = std::string(rply,rplylen);
            std::string message = std::string("wpa_ctrl(SCAN_RESULTS) replied: '").append(rplystring).append("' (").append(std::to_string(retval)).append(")");
            std::cout << message << std::cout;
            std::cout << std::string("wpa_ctrl(SCAN_RESULTS): Available (").append(std::to_string(retval)).append(")") << std::endl;
                return true;
        }
        else
            std::cout << std::string("wpa_ctrl(SCAN_RESULTS): Unavailable (").append(std::to_string(retval)).append(")") << std::endl;


        return false;
    }
    return false;
}

bool InitScan() {
    if(_wpac)
    {
        char rply[4096]; //same as in wpa_cli.c
        size_t rplylen;
        int retval = wpa_ctrl_request(_wpac,"SCAN",4,rply,&rplylen,callback);
        if(retval == 0) {
            std::string rplystring = std::string(rply,rplylen);
            std::string message = std::string("wpa_ctrl(SCAN) replied: '").append(rplystring).append("' (").append(std::to_string(retval)).append(")");
            std::cout << message << std::endl;

            if(rplystring == "OK\n") {
                std::string message = std::string("wpa_ctrl(SCAN): Scan initiated (").append(std::to_string(retval)).append(")");
                std::cout << message << std::endl;
                return true;
            }
        }
        std::string message = std::string("wpa_ctrl(SCAN) failed: (").append(std::to_string(retval)).append(")");
        std::cout << message << std::endl;
    }
    return false;
}


int main(){
  std::string connection_string = std::string("/var/run/wpa_supplicant/").append(_interface);
  wpa_ctrl* _wpac = wpa_ctrl_open(connection_string.c_str());
  if(!_wpac)
    return 1;

  /* Well Working Attach to as Eventlistener omitted */

  while(!InitScan())
    sleep(1);
  while(!ScanResults())
    sleep(1)
  return 0;
}

尝试在代码中的适当位置执行类似的操作

    char rply[4096];
    size_t rplylen = sizeof(rply);
    static char cmd[] = "SCAN";   //maybe a bit easier to deal with since you need a command length

    int retval = wpa_ctrl_request(_wpac, cmd, sizeof(cmd)-1, rply, &rplylen, NULL);

NULL,因为我怀疑您真的不需要回调例程。但是如果你想的话就放一个。