提交 2f33bdea authored 作者: blu's avatar blu

new feature: evwifi

上级 b9449edf
......@@ -73,4 +73,7 @@ add_executable(evslicer evslicer.cpp)
target_link_libraries(evslicer PUBLIC dirmon post ${COMM_LIBS} ${AV_LIBS} curl fswatch ${EXTRA_LIBS})
add_executable(evmlmotion evmlmotion.cpp)
target_link_libraries(evmlmotion PUBLIC ${COMM_LIBS} ${AV_LIBS} ${CV_LIBRARIES} ${EXTRA_LIBS})
\ No newline at end of file
target_link_libraries(evmlmotion PUBLIC ${COMM_LIBS} ${AV_LIBS} ${CV_LIBRARIES} ${EXTRA_LIBS})
add_executable(evwifi evwifi.cpp)
target_link_libraries(evwifi PUBLIC database leveldb)
\ No newline at end of file
......@@ -162,6 +162,19 @@ evmgr/fast:
$(MAKE) -f CMakeFiles/evmgr.dir/build.make CMakeFiles/evmgr.dir/build
.PHONY : evmgr/fast
#=============================================================================
# Target rules for targets named evwifi
# Build rule for target.
evwifi: cmake_check_build_system
$(MAKE) -f CMakeFiles/Makefile2 evwifi
.PHONY : evwifi
# fast build rule for target.
evwifi/fast:
$(MAKE) -f CMakeFiles/evwifi.dir/build.make CMakeFiles/evwifi.dir/build
.PHONY : evwifi/fast
#=============================================================================
# Target rules for targets named evdaemon
......@@ -509,6 +522,33 @@ evslicer.cpp.s:
$(MAKE) -f CMakeFiles/evslicer.dir/build.make CMakeFiles/evslicer.dir/evslicer.cpp.s
.PHONY : evslicer.cpp.s
evwifi.o: evwifi.cpp.o
.PHONY : evwifi.o
# target to build an object file
evwifi.cpp.o:
$(MAKE) -f CMakeFiles/evwifi.dir/build.make CMakeFiles/evwifi.dir/evwifi.cpp.o
.PHONY : evwifi.cpp.o
evwifi.i: evwifi.cpp.i
.PHONY : evwifi.i
# target to preprocess a source file
evwifi.cpp.i:
$(MAKE) -f CMakeFiles/evwifi.dir/build.make CMakeFiles/evwifi.dir/evwifi.cpp.i
.PHONY : evwifi.cpp.i
evwifi.s: evwifi.cpp.s
.PHONY : evwifi.s
# target to generate assembly for a file
evwifi.cpp.s:
$(MAKE) -f CMakeFiles/evwifi.dir/build.make CMakeFiles/evwifi.dir/evwifi.cpp.s
.PHONY : evwifi.cpp.s
inc/utils.o: inc/utils.cpp.o
.PHONY : inc/utils.o
......@@ -600,6 +640,7 @@ help:
@echo "... evslicer"
@echo "... evpuller"
@echo "... evmgr"
@echo "... evwifi"
@echo "... evdaemon"
@echo "... evcloudsvc"
@echo "... rebuild_cache"
......@@ -637,6 +678,9 @@ help:
@echo "... evslicer.o"
@echo "... evslicer.i"
@echo "... evslicer.s"
@echo "... evwifi.o"
@echo "... evwifi.i"
@echo "... evwifi.s"
@echo "... inc/utils.o"
@echo "... inc/utils.i"
@echo "... inc/utils.s"
......
......@@ -877,8 +877,9 @@ public:
info["sn"] = sn;
info["lastboot"] = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
LVDB::setSn(info);
ret["data"] = info;
}
res.set_content(this->info.dump(), "text/json");
res.set_content(ret.dump(), "text/json");
});
svr.Get("/config", [this](const Request& req, Response& res) {
......
#include "inc/httplib.h"
#include "inc/zmqhelper.hpp"
#include "inc/json.hpp"
#include "spdlog/spdlog.h"
#include "fmt/format.h"
#include "database.h"
#include <thread>
#include <future>
#include <regex>
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>
std::string exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
using namespace std;
using namespace nlohmann;
using namespace httplib;
class WifiMgr {
private:
json info;
Server srv;
promise<int> p;
thread monitor;
vector<string> ssids;
string wifiSSID;
string wifiPasswd;
int mode, lastMode; // 1: ap; 2: ste
const string apdCfgPath = "/etc/apd.conf";
const string wpaCfgPath = "/etc/wpa_supplicant/wpa_supplicant-wlan1.conf";
json enableMode(int mode){
json ret;
ret["code"] = 0;
ret["msg"] = "ok";
if( mode == 1) {
// ap
// stop all
spdlog::info("prepare to enter AP mode");
exec("systemctl stop wap_supplicant@wlan1");
// exec("systemctl dsiable wap_supplicant@wlan1 ")
string apdContent = fmt::format("interface=wlan1\ndriver=nl80211\nssid=EVB-{}\nhw_mode=g\n"
"channel=6\nmacaddr_acl=0\nignore_broadcast_ssid=0\nwpa=0\n", this->info["sn"].get<string>());
ofstream fileApd(apdCfgPath, ios::out|ios::trunc);
if(fileApd.is_open()){
fileApd << apdContent;
fileApd.close();
// start hostapd
exec("hostapd /etc/apd.conf -B");
// TODO: check result
/// scan wifis
string res = exec("iwlist wlan1 scan|grep ESSID");
ssids.clear();
httplib::detail::split(&res[0], &res[res.size()], '\n', [&](const char *b, const char *e) {
string ssid;
ssid.assign(b,e);
ssids.push_back(ssid);
});
//
}else{
ret["code"] = 1;
string msg = fmt::format("failed to write ap config file to {}", apdCfgPath);
spdlog::error(msg);
ret["msg"] = msg;
return ret;
}
}else if(mode == 2) {
// station mode
spdlog::info("prepare to enter Station mode");
// stop hostapd
exec("pkill hostapd");
string wpaContent = fmt::format("ctrl_interface=/run/wpa_supplicant\nupdate_config=1\nap_scan=1\n"
"network={{\nssid=\"{}\"\npsk=\"{}\"\n}}\n", this->wifiSSID, this->wifiPasswd);
ofstream wpaFile(wpaCfgPath, ios::out|ios::trunc);
if(wpaFile.is_open()){
wpaFile << wpaContent;
wpaFile.close();
// TODO: verify
spdlog::info(exec("systemctl enable wap_supplicant@wlan1"));
spdlog::info(exec("systemctl restart wap_supplicant@wlan1"));
spdlog::info(exec("dhclient wlan1"));
}else{
string msg = fmt::format("failed write wpa config to {}", wpaCfgPath);
ret["code"] = 2;
ret["msg"] = msg;
spdlog::error(msg);
return ret;
}
}
return ret;
}
public:
WifiMgr(){
LVDB::getSn(this->info);
monitor = thread([this](){
// check /etc/systemd/wpa_supplicant@wlan1.service
// get wlan1 status
// get wlan1 ip
// ping outside address
// default is AP mode
this->lastMode = 0;
while(1){
// check modes
this->mode = 1;
if(this->lastMode != this->mode) {
enableMode(this->mode);
}
this->lastMode = this->mode;
this_thread::sleep_for(chrono::seconds(10));
}
});
monitor.detach();
srv.Get("/wifi", [this](const Request& req, Response& res) {
string mode = req.get_param_value("mode");
json ret;
ret["code"] = 0;
ret["msg"] = "ok";
ret["sn"] = this->info["sn"];
if(!mode.empty()){
try{
auto i = stoi(mode);
ret = this->enableMode(i);
}catch(exception &e){
string msg = fmt::format("exception in convert mode {} to int:{}", mode, e.what());
ret["code"] = -1;
ret["msg"] = msg;
spdlog::error(msg);
}
}
res.set_content(ret.dump(), "text/json");
});
srv.listen("0.0.0.0", 80);
}
};
int main(){
WifiMgr mgr;
}
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论