libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
LibXR::LinuxWifiClient Class Reference

Linux Wi-Fi 客户端实现 / Linux Wi-Fi client implementation. More...

#include <linux_wifi_client.hpp>

Inheritance diagram for LibXR::LinuxWifiClient:
[legend]
Collaboration diagram for LibXR::LinuxWifiClient:
[legend]

Public Member Functions

 LinuxWifiClient (const char *ifname=nullptr)
 构造客户端对象 / Construct client object
 
 ~LinuxWifiClient () override
 析构函数 / Destructor
 
bool Enable () override
 启用网络接口(WiFi) / Enable the network interface
 
void Disable () override
 禁用网络接口(WiFi) / Disable the network interface
 
bool IsConnected () const override
 检查是否已连接 / Check if currently connected
 
IPAddressRaw GetIPAddress () const override
 获取当前 IP 地址 / Get current IP address
 
MACAddressRaw GetMACAddress () const override
 获取当前 MAC 地址 / Get MAC address
 
WifiError Connect (const Config &config) override
 连接到指定 WiFi 网络 / Connect to a WiFi network
 
WifiError Disconnect () override
 断开当前 WiFi 连接 / Disconnect from the WiFi network
 
WifiError Scan (ScanResult *out_list, size_t max_count, size_t &out_found) override
 扫描可用网络 / Scan for available WiFi networks
 
int GetRSSI () const override
 获取当前 WiFi 信号强度(RSSI) / Get current signal strength
 
- Public Member Functions inherited from LibXR::WifiClient
virtual ~WifiClient ()=default
 析构函数 / Destructor
 
- Public Member Functions inherited from LibXR::NetworkInterface

Additional Inherited Members

- Public Types inherited from LibXR::WifiClient
enum class  WifiError {
  NONE , ALREADY_ENABLED , NOT_ENABLED , CONNECTION_TIMEOUT ,
  AUTHENTICATION_FAILED , DHCP_FAILED , SSID_NOT_FOUND , INVALID_CONFIG ,
  HARDWARE_FAILURE , SCAN_FAILED , UNKNOWN
}
 WiFi 错误码 / Enumeration of WiFi error codes. More...
 
enum class  Security { OPEN , WPA2_PSK , WPA2_ENTERPRISE , UNKNOWN }
 WiFi 安全类型 / WiFi security types. More...
 
using WifiCallback = LibXR::Callback<WifiError>
 WiFi 状态回调类型 / Callback type for WiFi status.
 

Detailed Description

Linux Wi-Fi 客户端实现 / Linux Wi-Fi client implementation.

Definition at line 25 of file linux_wifi_client.hpp.

Constructor & Destructor Documentation

◆ LinuxWifiClient()

LibXR::LinuxWifiClient::LinuxWifiClient ( const char * ifname = nullptr)
inline

构造客户端对象 / Construct client object

Parameters
ifname网卡名,空则自动探测 / Interface name, auto-detect when null

Definition at line 32 of file linux_wifi_client.hpp.

33 {
34 if (ifname)
35 {
36 strncpy(ifname_cstr_, ifname, sizeof(ifname_cstr_) - 1);
37 }
38 else
39 {
40 std::string iface = DetectWifiInterface();
41 if (iface.empty())
42 {
43 XR_LOG_ERROR("Wi-Fi interface not found");
44 REQUIRE(false);
45 }
46 else
47 {
48 strncpy(ifname_cstr_, iface.c_str(), sizeof(ifname_cstr_) - 1);
49 }
50 }
51
52 socket_path_ = "/var/run/wpa_supplicant/" + std::string(ifname_cstr_);
53 }

◆ ~LinuxWifiClient()

LibXR::LinuxWifiClient::~LinuxWifiClient ( )
inlineoverride

析构函数 / Destructor

Definition at line 58 of file linux_wifi_client.hpp.

59 {
60 Disconnect();
61 if (ctrl_)
62 {
63 wpa_ctrl_close(ctrl_);
64 }
65 }
WifiError Disconnect() override
断开当前 WiFi 连接 / Disconnect from the WiFi network

Member Function Documentation

◆ Connect()

WifiError LibXR::LinuxWifiClient::Connect ( const Config & config)
inlineoverridevirtual

连接到指定 WiFi 网络 / Connect to a WiFi network

Parameters
[in]configWiFi 连接配置 / Configuration parameters
Returns
WifiError 连接结果 / Error code

Implements LibXR::WifiClient.

Definition at line 151 of file linux_wifi_client.hpp.

152 {
153 std::string out;
154 SendCommand("REMOVE_NETWORK all", out);
155 SendCommand("ADD_NETWORK", out);
156 int netid = atoi(out.c_str());
157 if (netid < 0)
158 {
159 XR_LOG_ERROR("ADD_NETWORK failed: %s", out.c_str());
161 }
162
163 std::stringstream cmd;
164 cmd << "SET_NETWORK " << netid << " ssid \"" << config.ssid << "\"";
165 if (!SendCommand(cmd.str().c_str(), out) || out.find("OK") == std::string::npos)
166 {
167 XR_LOG_ERROR("SET_NETWORK ssid failed: %s", out.c_str());
169 }
170
171 cmd.str("");
172 cmd << "SET_NETWORK " << netid << " psk \"" << config.password << "\"";
173 if (!SendCommand(cmd.str().c_str(), out) || out.find("OK") == std::string::npos)
174 {
175 XR_LOG_ERROR("SET_NETWORK psk failed: %s", out.c_str());
177 }
178
179 std::vector<std::string> cleanup_cmds = {
180 "key_mgmt WPA-PSK", "eap NONE", "phase1 \"\"", "identity \"\"", "password \"\"",
181 };
182 for (const auto& line : cleanup_cmds)
183 {
184 cmd.str("");
185 cmd << "SET_NETWORK " << netid << " " << line;
186 SendCommand(cmd.str().c_str(), out);
187 }
188
189 cmd.str("");
190 cmd << "ENABLE_NETWORK " << netid;
191 if (!SendCommand(cmd.str().c_str(), out) || out.find("OK") == std::string::npos)
192 {
193 XR_LOG_ERROR("ENABLE_NETWORK failed: %s", out.c_str());
195 }
196
197 cmd.str("");
198 cmd << "SELECT_NETWORK " << netid;
199 SendCommand(cmd.str().c_str(), out);
200
201 const int TIMEOUT_MS = 30000;
202 const int INTERVAL_MS = 300;
203 int elapsed = 0;
204
205 while (elapsed < TIMEOUT_MS)
206 {
207 std::string status;
208 SendCommand("STATUS", status);
209
210 if (status.find("wpa_state=COMPLETED") != std::string::npos)
211 {
212 XR_LOG_PASS("Wi-Fi Connected to SSID: %s", config.ssid);
213 return WifiError::NONE;
214 }
215
216 if (status.find("wpa_state=INACTIVE") != std::string::npos)
217 {
218 XR_LOG_ERROR("Wi-Fi Connection failed: %s", status.c_str());
220 }
221
222 LibXR::Thread::Sleep(INTERVAL_MS);
223 elapsed += INTERVAL_MS;
224 }
225
226 XR_LOG_ERROR("Wi-Fi Connection timeout");
228 }
static void Sleep(uint32_t milliseconds)
让线程进入休眠状态 Puts the thread to sleep
Definition thread.cpp:15
@ AUTHENTICATION_FAILED
身份验证失败 / Authentication failed
@ HARDWARE_FAILURE
硬件故障 / Hardware failure
@ NONE
无错误 / No error
@ CONNECTION_TIMEOUT
连接超时 / Connection timeout

◆ Disable()

void LibXR::LinuxWifiClient::Disable ( )
inlineoverridevirtual

禁用网络接口(WiFi) / Disable the network interface

Implements LibXR::WifiClient.

Definition at line 83 of file linux_wifi_client.hpp.

84 {
85 Disconnect();
86 if (ctrl_)
87 {
88 wpa_ctrl_close(ctrl_);
89 ctrl_ = nullptr;
90 }
91 }

◆ Disconnect()

WifiError LibXR::LinuxWifiClient::Disconnect ( )
inlineoverridevirtual

断开当前 WiFi 连接 / Disconnect from the WiFi network

Returns
WifiError 断开结果 / Error code

Implements LibXR::WifiClient.

Definition at line 230 of file linux_wifi_client.hpp.

231 {
232 std::string out;
233 SendCommand("DISCONNECT", out);
234 SendCommand("REMOVE_NETWORK all", out);
235 if (IsConnected())
236 {
237 return WifiError::UNKNOWN;
238 }
239 return WifiError::NONE;
240 }
bool IsConnected() const override
检查是否已连接 / Check if currently connected
@ UNKNOWN
未知错误 / Unknown error

◆ Enable()

bool LibXR::LinuxWifiClient::Enable ( )
inlineoverridevirtual

启用网络接口(WiFi) / Enable the network interface

Returns
true 表示成功 / true if enabled successfully

Implements LibXR::WifiClient.

Definition at line 67 of file linux_wifi_client.hpp.

68 {
69 if (ctrl_)
70 {
71 return true;
72 }
73 ctrl_ = wpa_ctrl_open(socket_path_.c_str());
74 if (ctrl_)
75 {
76 XR_LOG_PASS("Wi-Fi enabled: %s", socket_path_.c_str());
77 return true;
78 }
79 XR_LOG_ERROR("Wi-Fi enable failed: %s", socket_path_.c_str());
80 return false;
81 }

◆ GetIPAddress()

IPAddressRaw LibXR::LinuxWifiClient::GetIPAddress ( ) const
inlineoverridevirtual

获取当前 IP 地址 / Get current IP address

Returns
当前 IP 地址(结构形式) / Current IP address in raw form

Implements LibXR::WifiClient.

Definition at line 103 of file linux_wifi_client.hpp.

104 {
105 char cmd[128];
106 auto ans = snprintf(cmd, sizeof(cmd), "ip -4 addr show %s | grep inet", ifname_cstr_);
107 UNUSED(ans);
108 FILE* fp = popen(cmd, "r");
109 if (!fp)
110 {
111 return {};
112 }
113
114 char buf[64] = {};
115 IPAddressRaw ip = {};
116 if (fgets(buf, sizeof(buf), fp))
117 {
118 char ip_str[32] = {};
119 auto ret = sscanf(buf, " inet %[^/]", ip_str);
120 UNUSED(ret);
121 ip = IPAddressRaw::FromString(ip_str);
122 }
123 pclose(fp);
124 return ip;
125 }

◆ GetMACAddress()

MACAddressRaw LibXR::LinuxWifiClient::GetMACAddress ( ) const
inlineoverridevirtual

获取当前 MAC 地址 / Get MAC address

Returns
当前 MAC 地址(结构形式) / Current MAC address in raw form

Implements LibXR::WifiClient.

Definition at line 127 of file linux_wifi_client.hpp.

128 {
129 char path[128];
130 auto ans = snprintf(path, sizeof(path), "/sys/class/net/%s/address", ifname_cstr_);
131 UNUSED(ans);
132 FILE* fp = fopen(path, "r");
133 if (!fp)
134 {
135 return {};
136 }
137
138 char mac_str[32] = {};
139 if (!fgets(mac_str, sizeof(mac_str), fp))
140 {
141 auto ans = fclose(fp);
142 UNUSED(ans);
143 return {};
144 }
145 auto ret = fclose(fp);
146 UNUSED(ret);
147 mac_str[strcspn(mac_str, "\n")] = 0;
148 return MACAddressRaw::FromString(mac_str);
149 }

◆ GetRSSI()

int LibXR::LinuxWifiClient::GetRSSI ( ) const
inlineoverridevirtual

获取当前 WiFi 信号强度(RSSI) / Get current signal strength

Returns
信号强度(dBm) / Signal strength in dBm

Implements LibXR::WifiClient.

Definition at line 274 of file linux_wifi_client.hpp.

275 {
276 std::string out;
277 SendCommand("SIGNAL_POLL", out);
278 auto pos = out.find("RSSI=");
279 return pos != std::string::npos ? atoi(out.c_str() + pos + 5) : 0;
280 }

◆ IsConnected()

bool LibXR::LinuxWifiClient::IsConnected ( ) const
inlineoverridevirtual

检查是否已连接 / Check if currently connected

Returns
true 如果连接上了 / true if connected

Implements LibXR::WifiClient.

Definition at line 93 of file linux_wifi_client.hpp.

94 {
95 std::string out;
96 if (!SendCommand("STATUS", out))
97 {
98 return false;
99 }
100 return out.find("wpa_state=COMPLETED") != std::string::npos;
101 }

◆ Scan()

WifiError LibXR::LinuxWifiClient::Scan ( ScanResult * out_list,
size_t max_count,
size_t & out_found )
inlineoverridevirtual

扫描可用网络 / Scan for available WiFi networks

Parameters
[out]out_list扫描结果数组 / Output list buffer
[in]max_count最大可填入数量 / Max result count
[out]out_found实际找到数量 / Number found
Returns
WifiError 错误码 / Scan result code

Implements LibXR::WifiClient.

Definition at line 242 of file linux_wifi_client.hpp.

243 {
244 std::string out;
245 SendCommand("SCAN", out);
246 sleep(2);
247 SendCommand("SCAN_RESULTS", out);
248
249 std::istringstream ss(out);
250 std::string line;
251 out_found = 0;
252 std::getline(ss, line);
253 while (std::getline(ss, line) && out_found < max_count)
254 {
255 std::istringstream ls(line);
256 std::string bssid, freq, signal, flags, ssid;
257 ls >> bssid >> freq >> signal >> flags;
258 std::getline(ls, ssid);
259 if (!ssid.empty() && ssid[0] == '\t')
260 {
261 ssid.erase(0, 1);
262 }
263
264 auto& r = out_list[out_found++];
265 strncpy(r.ssid, ssid.c_str(), sizeof(r.ssid) - 1);
266 r.rssi = atoi(signal.c_str());
267 r.security =
268 (flags.find("WPA2") != std::string::npos) ? Security::WPA2_PSK : Security::OPEN;
269 }
270
271 return WifiError::NONE;
272 }
@ OPEN
开放网络 / Open network

The documentation for this class was generated from the following file: