#ifndef WIFI_UTIL_H #define WIFI_UTIL_H #include #include #include #include #include #include "Application.h" #include "util/SystemInfo.h" namespace Util { class WifiUtil { private: public: static constexpr const char* frpcConfigPathName = "/customer/frp/frpc.toml"; static constexpr const char* frpcPathName = "/customer/frp/frpc"; public: static Poco::JSON::Object::Ptr wifiStaStatus(const std::string& interfaceName) { Poco::JSON::Object::Ptr statusMap = new Poco::JSON::Object; try { std::string retStr; bool retFlag = Util::SystemInfo::executeCommand("wpa_cli -i " + interfaceName + " status", 10, retStr); if (retFlag) { Poco::StringTokenizer lines(retStr, "\n", Poco::StringTokenizer::TOK_TRIM); for (const auto& line : lines) { size_t eqPos = line.find('='); if (eqPos != std::string::npos) { std::string key = line.substr(0, eqPos); std::string value = line.substr(eqPos + 1); statusMap->set(key, value); } } } } catch (const std::exception& e) { logger().error("wifiStaStatus failed: %s", std::string(e.what())); } return statusMap; } static bool wifiStaScan(const std::string& interfaceName, bool wifiEnable = false) { try { return Util::SystemInfo::executeCommand("/customer/customer-network.sh " + interfaceName + " scan"); } catch (const std::exception& e) { logger().error("wifiStaScan failed: %s", std::string(e.what())); } return false; } static Poco::JSON::Array::Ptr wifiStaScanResults(const std::string& interfaceName) { Poco::JSON::Array::Ptr jsonArray = new Poco::JSON::Array; std::string retStr; bool retFlag = Util::SystemInfo::executeCommand("wpa_cli -i " + interfaceName + " scan_results", 10, retStr); if (!retFlag) { return jsonArray; } Poco::StringTokenizer lines(retStr, "\n", Poco::StringTokenizer::TOK_TRIM); for (size_t i = 1; i < lines.count(); ++i) { Poco::StringTokenizer tokens(lines[i], "\t", Poco::StringTokenizer::TOK_TRIM); if (tokens.count() < 4) continue; Poco::JSON::Object::Ptr netObj = new Poco::JSON::Object; netObj->set("bssid", tokens[0]); netObj->set("frequency", std::stoi(tokens[1])); netObj->set("signal_level", std::stoi(tokens[2])); if (tokens.count() == 4 && tokens[3].find('[') == std::string::npos) { netObj->set("flags", "OPEN"); netObj->set("ssid", convertHexEscape(tokens[3])); } else { netObj->set("flags", tokens[3]); netObj->set("ssid", tokens.count() > 4 ? convertHexEscape(tokens[4]) : ""); } jsonArray->add(netObj); } return jsonArray; } static bool wifiStaConnect(const std::string& interfaceName, int status) { if (status == 1) { return Util::SystemInfo::executeCommand("/customer/customer-network.sh " + interfaceName + " up"); } else if (status == 0) { return Util::SystemInfo::executeCommand("/customer/customer-network.sh " + interfaceName + " down"); } return false; } static Poco::JSON::Array::Ptr wifiGetApClients(const std::string& interfaceName) { Poco::JSON::Array::Ptr jsonArray = new Poco::JSON::Array; std::string retStr; bool retFlag = Util::SystemInfo::executeCommand( "ip neigh show dev " + interfaceName + " nud reachable | awk '{print $1, $3}'", 10, retStr); if (!retFlag) { return jsonArray; } Poco::StringTokenizer lines(retStr, "\n", Poco::StringTokenizer::TOK_TRIM); for (size_t i = 0; i < lines.count(); ++i) { if (lines[i].empty()) continue; Poco::StringTokenizer tokens(lines[i], " ", Poco::StringTokenizer::TOK_TRIM); if (tokens.count() < 2) { continue; } std::string ip = tokens[0], mac = tokens[1]; Poco::JSON::Object::Ptr netObj = new Poco::JSON::Object; netObj->set("ip", ip); netObj->set("mac", mac); jsonArray->add(netObj); } return jsonArray; } static std::string convertHexEscape(const std::string& input) { std::stringstream ss; for (size_t i = 0; i < input.length();) { if (input.substr(i, 2) == "\\x" && i + 3 < input.length()) { ss << static_cast(std::stoi(input.substr(i + 2, 2), nullptr, 16)); i += 4; } else { ss << input[i]; i++; } } return ss.str(); } }; } #endif