2024-10-19 16:02:41 +08:00
|
|
|
|
#include "wpa_client.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
#include <unistd.h>
|
2024-10-23 19:51:01 +08:00
|
|
|
|
#include <zlog.h>
|
2024-10-19 16:02:41 +08:00
|
|
|
|
|
2024-10-23 20:33:05 +08:00
|
|
|
|
extern zlog_category_t *zct;
|
|
|
|
|
|
|
2024-10-19 16:02:41 +08:00
|
|
|
|
namespace wifi {
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
size_t strlcpy(char *dst, const char *src, size_t dst_sz) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
size_t n;
|
|
|
|
|
|
|
|
|
|
|
|
for (n = 0; n < dst_sz; n++) {
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if ((*dst++ = *src++) == '\0') break;
|
2024-10-19 16:02:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (n < dst_sz) return n;
|
|
|
|
|
|
if (n > 0) *(dst - 1) = '\0';
|
|
|
|
|
|
return n + strlen(src);
|
2024-10-19 16:02:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static std::string to_string(int val) {
|
2024-10-22 19:04:25 +08:00
|
|
|
|
char *buf = NULL;
|
2024-10-19 16:02:41 +08:00
|
|
|
|
int size;
|
|
|
|
|
|
int temp;
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (val < 0) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
temp = -val;
|
|
|
|
|
|
size = 2;
|
2024-10-22 19:04:25 +08:00
|
|
|
|
} else {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
temp = val;
|
|
|
|
|
|
size = 1;
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
for (; temp > 0; temp = temp / 10, size++)
|
|
|
|
|
|
;
|
|
|
|
|
|
size++;
|
2024-10-19 16:02:41 +08:00
|
|
|
|
|
|
|
|
|
|
buf = (char *)malloc(size);
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (buf == NULL) {
|
|
|
|
|
|
return "";
|
2024-10-19 16:02:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
memset(buf, 0, size);
|
|
|
|
|
|
sprintf(buf, "%d", val);
|
|
|
|
|
|
std::string re(buf);
|
|
|
|
|
|
free(buf);
|
|
|
|
|
|
return re;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
MXDHCP::MXDHCP() { pstream = NULL; }
|
2024-10-19 16:02:41 +08:00
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
MXDHCP::~MXDHCP() {
|
|
|
|
|
|
if (pstream != NULL) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
pclose(pstream);
|
|
|
|
|
|
pstream = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
|
|
|
|
|
|
bool MXDHCP::Start(const std::string &net_interface) {
|
|
|
|
|
|
if (pstream != NULL) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
pclose(pstream);
|
|
|
|
|
|
pstream = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
std::string cmd = "udhcpc -b -i " + net_interface + " &";
|
|
|
|
|
|
system("killall -9 udhcpc &");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
mssleep(1000 * 100);
|
|
|
|
|
|
pstream = popen(cmd.data(), "r");
|
|
|
|
|
|
if (pstream == NULL) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
|
2024-10-19 16:02:41 +08:00
|
|
|
|
/*
|
|
|
|
|
|
* dhcp 这个类的主要原理是通过读取udhcpc 的输出来判断是否拿到了ip地址,实际情况中可以使用别的方法
|
|
|
|
|
|
*/
|
2024-10-22 19:04:25 +08:00
|
|
|
|
bool MXDHCP::GetDHCPStatus() {
|
|
|
|
|
|
if (pstream == NULL) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
int len = 1024;
|
2024-10-22 19:04:25 +08:00
|
|
|
|
char *buff = (char *)malloc(sizeof(char) * len);
|
|
|
|
|
|
if (buff == NULL) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
int res = fread(buff, sizeof(char), len, pstream);
|
|
|
|
|
|
if (res <= 0) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
free(buff);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!CheckString(buff, res)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
free(buff);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
pclose(pstream);
|
|
|
|
|
|
pstream = NULL;
|
|
|
|
|
|
free(buff);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
|
|
|
|
|
|
bool MXDHCP::CheckString(char *buf, int len) {
|
|
|
|
|
|
if (strstr(buf, "adding dns") == NULL) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
|
|
|
|
|
|
WPAClient::WPAClient(const std::string &wpa_control_path) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
wpa_context_ = NULL;
|
|
|
|
|
|
wpa_control_path_ = wpa_control_path;
|
|
|
|
|
|
SetConnStatus(STEP_SCAN);
|
|
|
|
|
|
Init();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
WPAClient::~WPAClient() { Close(wpa_context_); }
|
|
|
|
|
|
|
|
|
|
|
|
bool WPAClient::Init() {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
wpa_context_ = Open(wpa_control_path_);
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (wpa_context_ == NULL) {
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_error(zct, "open wpa failed");
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
SetConnStatus(STEP_SCAN);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
std::string WPAClient::GetCurrentSSID() {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
std::string cmd = "STATUS";
|
|
|
|
|
|
std::string ssid_key = "\nssid=";
|
|
|
|
|
|
std::string recv;
|
|
|
|
|
|
std::string ssid = "";
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!Request(wpa_context_, cmd, recv)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
char temp[1024] = {0};
|
|
|
|
|
|
strcpy(temp, recv.data());
|
|
|
|
|
|
char *key = NULL;
|
|
|
|
|
|
key = strstr(temp, ssid_key.data());
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (key == NULL) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
key += ssid_key.length();
|
2024-10-22 19:04:25 +08:00
|
|
|
|
for (; (*key != '\0') && (*key != '\n') && (*key != '\r'); key++) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
ssid += *key;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ssid;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
std::string WPAClient::GetNetSsid() {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
std::string cmd = "SCAN";
|
|
|
|
|
|
std::string recv;
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!Request(wpa_context_, cmd, recv)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
recv.clear();
|
|
|
|
|
|
cmd = "SCAN_RESULTS";
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!Request(wpa_context_, cmd, recv)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return "";
|
2024-10-22 19:04:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
return recv;
|
2024-10-19 16:02:41 +08:00
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
int WPAClient::GetWiFiRssi() {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
std::string cmd = "SIGNAL_POLL";
|
|
|
|
|
|
std::string rssi_key = "RSSI";
|
|
|
|
|
|
std::string recv;
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!Request(wpa_context_, cmd, recv)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
char temp[1024] = {0};
|
|
|
|
|
|
strcpy(temp, recv.data());
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_info(zct, "recv = %s\n", recv.c_str());
|
2024-10-19 16:02:41 +08:00
|
|
|
|
char *key = NULL;
|
|
|
|
|
|
key = strstr(temp, rssi_key.data());
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (key == NULL) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
for (; (*key != '\0') && (*key != '\n') && (*key != '\r'); key++) {
|
|
|
|
|
|
if ((*key >= '0') && (*key <= '9')) {
|
|
|
|
|
|
return atoi(key);
|
|
|
|
|
|
}
|
2024-10-19 16:02:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
bool WPAClient::ConnectWiFi(const std::string &ssid, const std::string &password) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
int net_id;
|
|
|
|
|
|
SetConnStatus(STEP_SCAN);
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!CleanAllWiFi()) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_info(zct, "CleanAllWiFi ");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!AddWiFi(net_id)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_info(zct, "AddWiFi ");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!SetSSID(ssid, net_id)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_info(zct, "SetSSID ");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!SetPassword(password, 0)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!SetProtocol(net_id, 1)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_info(zct, "SetProtocol");
|
2024-10-19 16:02:41 +08:00
|
|
|
|
SetScanSSID(net_id);
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!EnableWiFi(net_id)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_info(zct, "EnableWiFi");
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return CheckCommandWithOk("SAVE_CONFIG");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
// return true;
|
2024-10-19 16:02:41 +08:00
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
|
|
|
|
|
|
bool WPAClient::ConnectWiFiWithNoPassword(const std::string &ssid) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
int net_id;
|
|
|
|
|
|
SetConnStatus(STEP_SCAN);
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!CleanAllWiFi()) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_info(zct, "CleanAllWiFi");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!AddWiFi(net_id)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_info(zct, "AddWiFi");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!SetSSID(ssid, net_id)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_info(zct, "SetSSID");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!SetProtocol(net_id, 0)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_info(zct, "SetProtocol");
|
2024-10-19 16:02:41 +08:00
|
|
|
|
SetScanSSID(net_id);
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!EnableWiFi(net_id)) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_info(zct, "EnableWiFi");
|
2024-10-19 16:02:41 +08:00
|
|
|
|
|
|
|
|
|
|
return CheckCommandWithOk("SAVE_CONFIG");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
bool WPAClient::ConnectWiFiWithLast() {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
SetConnStatus(STEP_SCAN);
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (!CheckCommandWithOk("ENABLE_NETWORK all")) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
|
2024-10-19 16:02:41 +08:00
|
|
|
|
bool WPAClient::GetConnectStatus() {
|
|
|
|
|
|
std::string cmd = "STATUS";
|
|
|
|
|
|
std::string recv;
|
2024-10-22 19:04:25 +08:00
|
|
|
|
int addr;
|
|
|
|
|
|
switch (step_) {
|
|
|
|
|
|
case STEP_SCAN:
|
|
|
|
|
|
if (!Request(wpa_context_, cmd, recv)) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
addr = recv.find("COMPLETED");
|
|
|
|
|
|
if (addr == -1) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
SetConnStatus(STEP_CONNECT_AP_OK);
|
|
|
|
|
|
case STEP_CONNECT_AP_OK:
|
|
|
|
|
|
if (!dhcp_.Start("wlan0")) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
SetConnStatus(STEP_DHCP_IP);
|
|
|
|
|
|
case STEP_DHCP_IP:
|
|
|
|
|
|
if (!dhcp_.GetDHCPStatus()) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
SetConnStatus(STEP_SUCCESS);
|
|
|
|
|
|
case STEP_SUCCESS: return true;
|
|
|
|
|
|
default: return false;
|
2024-10-19 16:02:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
void WPAClient::SetConnStatus(ConnectStatus status) { step_ = status; }
|
|
|
|
|
|
|
|
|
|
|
|
void WPAClient::wifiup() {
|
|
|
|
|
|
system("ifconfig mlan0 up");
|
|
|
|
|
|
system("ifconfig mlan0 up");
|
|
|
|
|
|
system("ifconfig mlan0 up");
|
2024-10-19 16:02:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
bool WPAClient::CleanWifi() {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
bool flag = CleanAllWiFi();
|
|
|
|
|
|
CheckCommandWithOk("SAVE_CONFIG");
|
|
|
|
|
|
return flag;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
int WPAClient::GetConnStatus() { return step_; }
|
|
|
|
|
|
|
|
|
|
|
|
WPAContext *WPAClient::Open(const std::string &path) {
|
|
|
|
|
|
struct WPAContext *ctrl;
|
|
|
|
|
|
ctrl = (struct WPAContext *)malloc(sizeof(struct WPAContext));
|
|
|
|
|
|
if (ctrl == NULL) {
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_error(zct, "malloc failed");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
memset(ctrl, 0, sizeof(struct WPAContext));
|
|
|
|
|
|
static int counter = 0;
|
|
|
|
|
|
int ret;
|
|
|
|
|
|
int tries = 0;
|
|
|
|
|
|
size_t res;
|
|
|
|
|
|
ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
|
|
|
|
|
|
if (ctrl->s < 0) {
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_error(zct, "socket failed");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
free(ctrl);
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
ctrl->local.sun_family = AF_UNIX;
|
|
|
|
|
|
counter++;
|
2024-10-19 16:02:41 +08:00
|
|
|
|
try_again:
|
2024-10-22 19:04:25 +08:00
|
|
|
|
ret = snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path), "/tmp"
|
|
|
|
|
|
"/"
|
|
|
|
|
|
"wpa_ctrl_"
|
|
|
|
|
|
"%d-%d",
|
|
|
|
|
|
(int)getpid(), counter);
|
|
|
|
|
|
if (ret < 0 || (size_t)ret >= sizeof(ctrl->local.sun_path)) {
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_error(zct, "snprintf failed");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
close(ctrl->s);
|
|
|
|
|
|
free(ctrl);
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
tries++;
|
|
|
|
|
|
if (bind(ctrl->s, (struct sockaddr *)&ctrl->local, sizeof(ctrl->local)) < 0) {
|
|
|
|
|
|
if (errno == EADDRINUSE && tries < 2) {
|
|
|
|
|
|
/*
|
|
|
|
|
|
* getpid() returns unique identifier for this instance
|
|
|
|
|
|
* of wpa_ctrl, so the existing socket file must have
|
|
|
|
|
|
* been left by unclean termination of an earlier run.
|
|
|
|
|
|
* Remove the file and try again.
|
|
|
|
|
|
*/
|
|
|
|
|
|
unlink(ctrl->local.sun_path);
|
|
|
|
|
|
goto try_again;
|
|
|
|
|
|
}
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_error(zct, "bind failed");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
close(ctrl->s);
|
|
|
|
|
|
free(ctrl);
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
ctrl->dest.sun_family = AF_UNIX;
|
|
|
|
|
|
res = strlcpy(ctrl->dest.sun_path, wpa_control_path_.data(), sizeof(ctrl->dest.sun_path));
|
|
|
|
|
|
if (res >= sizeof(ctrl->dest.sun_path)) {
|
|
|
|
|
|
close(ctrl->s);
|
|
|
|
|
|
free(ctrl);
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (connect(ctrl->s, (struct sockaddr *)&ctrl->dest, sizeof(ctrl->dest)) < 0) {
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_error(zct, "connect failed");
|
2024-10-22 19:04:25 +08:00
|
|
|
|
close(ctrl->s);
|
|
|
|
|
|
unlink(ctrl->local.sun_path);
|
|
|
|
|
|
free(ctrl);
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
return ctrl;
|
2024-10-19 16:02:41 +08:00
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
|
|
|
|
|
|
void WPAClient::Close(WPAContext *context) {
|
|
|
|
|
|
if (context == NULL) return;
|
|
|
|
|
|
unlink(context->local.sun_path);
|
|
|
|
|
|
if (context->s >= 0) close(context->s);
|
|
|
|
|
|
free(context);
|
2024-10-19 16:02:41 +08:00
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
|
|
|
|
|
|
bool WPAClient::Request(WPAContext *context, const std::string &cmd, std::string &reply) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
int res;
|
2024-10-22 19:04:25 +08:00
|
|
|
|
fd_set rfds;
|
2024-10-19 16:02:41 +08:00
|
|
|
|
struct timeval tv;
|
|
|
|
|
|
const char *_cmd;
|
|
|
|
|
|
char *cmd_buf = NULL;
|
|
|
|
|
|
size_t _cmd_len;
|
|
|
|
|
|
_cmd = cmd.data();
|
|
|
|
|
|
_cmd_len = cmd.length();
|
|
|
|
|
|
if (wpa_context_ == NULL) {
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_error(zct, "wpa_context_ is null");
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (send(wpa_context_->s, _cmd, _cmd_len, 0) < 0) {
|
|
|
|
|
|
free(cmd_buf);
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
free(cmd_buf);
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
|
tv.tv_sec = 10;
|
|
|
|
|
|
tv.tv_usec = 0;
|
|
|
|
|
|
FD_ZERO(&rfds);
|
|
|
|
|
|
FD_SET(wpa_context_->s, &rfds);
|
|
|
|
|
|
res = select(wpa_context_->s + 1, &rfds, NULL, NULL, &tv);
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (res < 0) return false;
|
2024-10-19 16:02:41 +08:00
|
|
|
|
if (FD_ISSET(wpa_context_->s, &rfds)) {
|
|
|
|
|
|
char temp[1024] = {0};
|
|
|
|
|
|
int temp_len = 1024;
|
|
|
|
|
|
res = recv(wpa_context_->s, temp, temp_len, 0);
|
2024-10-22 19:04:25 +08:00
|
|
|
|
if (res < 0) return false;
|
2024-10-19 16:02:41 +08:00
|
|
|
|
if (res > 0 && temp[0] == '<') {
|
2024-10-22 19:04:25 +08:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
reply = temp;
|
2024-10-19 16:02:41 +08:00
|
|
|
|
break;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool WPAClient::CheckCommandWithOk(const std::string cmd) {
|
|
|
|
|
|
std::string recv;
|
|
|
|
|
|
if (!Request(wpa_context_, cmd, recv)) {
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_error(zct, "send cmd falied");
|
2024-10-19 16:02:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-10-23 20:33:05 +08:00
|
|
|
|
zlog_error(zct, "recv cmd %s", recv.data());
|
2024-10-19 16:02:41 +08:00
|
|
|
|
if (strstr(recv.data(), "OK") == NULL) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 19:04:25 +08:00
|
|
|
|
bool WPAClient::AddWiFi(int &id) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
std::string add_cmd = "ADD_NETWORK";
|
|
|
|
|
|
std::string recv;
|
|
|
|
|
|
if (!Request(wpa_context_, add_cmd, recv)) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
id = atoi(recv.data());
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
|
2024-10-19 16:02:41 +08:00
|
|
|
|
bool WPAClient::SetScanSSID(int id) {
|
|
|
|
|
|
std::string cmd = "SET_NETWORK " + to_string(id) + " scan_ssid 1";
|
|
|
|
|
|
return CheckCommandWithOk(cmd);
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
bool WPAClient::SetSSID(const std::string &ssid, int id) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
std::string cmd = "SET_NETWORK " + to_string(id) + " ssid " + "\"" + ssid + "\"";
|
|
|
|
|
|
return CheckCommandWithOk(cmd);
|
|
|
|
|
|
}
|
2024-10-22 19:04:25 +08:00
|
|
|
|
bool WPAClient::SetPassword(const std::string &password, int id) {
|
2024-10-19 16:02:41 +08:00
|
|
|
|
std::string cmd = "SET_NETWORK " + to_string(id) + " psk " + "\"" + password + "\"";
|
|
|
|
|
|
return CheckCommandWithOk(cmd);
|
|
|
|
|
|
}
|
|
|
|
|
|
bool WPAClient::SetProtocol(int id, int en_crypt) {
|
|
|
|
|
|
std::string cmd = "SET_NETWORK " + to_string(id);
|
|
|
|
|
|
if (en_crypt) {
|
|
|
|
|
|
cmd += " key_mgmt WPA-PSK";
|
|
|
|
|
|
return CheckCommandWithOk(cmd);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
cmd += " key_mgmt NONE";
|
|
|
|
|
|
return CheckCommandWithOk(cmd);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
bool WPAClient::CleanAllWiFi() {
|
|
|
|
|
|
CheckCommandWithOk("REMOVE_NETWORK all");
|
|
|
|
|
|
CheckCommandWithOk("DISABLE_NETWORK all");
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
bool WPAClient::EnableWiFi(int id) {
|
|
|
|
|
|
std::string cmd = "ENABLE_NETWORK " + to_string(id);
|
|
|
|
|
|
return CheckCommandWithOk(cmd);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool WPAClient::ReconnectWiFi() {
|
|
|
|
|
|
std::string cmd = "RECONNECT";
|
|
|
|
|
|
return CheckCommandWithOk(cmd);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|