提交 4b804b0f authored 作者: blu's avatar blu

feature: LED & key trigger support

上级 c765eaa6
...@@ -50,10 +50,11 @@ private: ...@@ -50,10 +50,11 @@ private:
mutex eventQLock; mutex eventQLock;
thread thMsgProcessor; thread thMsgProcessor;
int buildIpcStatus(json &conf) { int buildIpcStatus(json &conf)
{
int ret = 0; int ret = 0;
string msg; string msg;
for(auto &[k,v]: conf.items()){ for(auto &[k,v]: conf.items()) {
try { try {
json &ipcs = v["ipcs"]; json &ipcs = v["ipcs"];
int ipcIdx = 0; int ipcIdx = 0;
...@@ -118,7 +119,8 @@ private: ...@@ -118,7 +119,8 @@ private:
if(shad["expected"].count(modGid) != 0) { if(shad["expected"].count(modGid) != 0) {
//multiple mod with same class //multiple mod with same class
spdlog::error("{} configuration for ipc {} in dev {} having multiple modules {}. ignored that extra module", devSn, ipcSn, k, modGid); spdlog::error("{} configuration for ipc {} in dev {} having multiple modules {}. ignored that extra module", devSn, ipcSn, k, modGid);
}else{ }
else {
shad["expected"][modGid] = enabled; shad["expected"][modGid] = enabled;
shad["current"][modGid] = false; shad["current"][modGid] = false;
} }
...@@ -132,10 +134,11 @@ private: ...@@ -132,10 +134,11 @@ private:
// merge // merge
auto &ipcStatus = peerData["ipcStatus"]; auto &ipcStatus = peerData["ipcStatus"];
for(auto &[k,v]: shadowObj.items()){ for(auto &[k,v]: shadowObj.items()) {
if(ipcStatus.count(k) == 0) { if(ipcStatus.count(k) == 0) {
ipcStatus[k] = v; ipcStatus[k] = v;
}else{ }
else {
auto &newCurr = v["current"]; auto &newCurr = v["current"];
auto &oldCurr = ipcStatus[k]["current"]; auto &oldCurr = ipcStatus[k]["current"];
auto &newExpected = v["expected"]; auto &newExpected = v["expected"];
...@@ -143,7 +146,7 @@ private: ...@@ -143,7 +146,7 @@ private:
vector<string> modRemove; vector<string> modRemove;
for(auto &[m,n]: oldCurr.items()){ for(auto &[m,n]: oldCurr.items()) {
if(newCurr.count(m) == 0) { if(newCurr.count(m) == 0) {
modRemove.push_back(m); modRemove.push_back(m);
} }
...@@ -160,7 +163,7 @@ private: ...@@ -160,7 +163,7 @@ private:
} }
} }
for(auto &[m,n]: newCurr.items()){ for(auto &[m,n]: newCurr.items()) {
oldExpected[m] = newExpected[m]; oldExpected[m] = newExpected[m];
if(oldCurr.count(m) == 0|| (oldCurr[m] == true && newExpected[m] == false)) { if(oldCurr.count(m) == 0|| (oldCurr[m] == true && newExpected[m] == false)) {
oldCurr[m] = newCurr[m]; oldCurr[m] = newCurr[m];
...@@ -371,7 +374,8 @@ private: ...@@ -371,7 +374,8 @@ private:
if(shad["expected"].count(modGid) != 0) { if(shad["expected"].count(modGid) != 0) {
//multiple mod with same class //multiple mod with same class
spdlog::error("{} configuration for ipc {} in dev {} having multiple modules {}. ignored that extra module", devSn, ipcSn, k, modGid); spdlog::error("{} configuration for ipc {} in dev {} having multiple modules {}. ignored that extra module", devSn, ipcSn, k, modGid);
}else{ }
else {
shad["expected"][modGid] = enabled; shad["expected"][modGid] = enabled;
shad["current"][modGid] = false; shad["current"][modGid] = false;
} }
...@@ -574,10 +578,11 @@ private: ...@@ -574,10 +578,11 @@ private:
// update ipcStatus // update ipcStatus
if(peerData["mgr2ipc"].count(selfId) != 0) { if(peerData["mgr2ipc"].count(selfId) != 0) {
for(auto &[k,v]: peerData["mgr2ipc"][selfId].items()){ for(auto &[k,v]: peerData["mgr2ipc"][selfId].items()) {
if(peerData["ipcStatus"].count(k) == 0){ if(peerData["ipcStatus"].count(k) == 0) {
spdlog::error("{} no ipcStatus config for camera {}", devSn, k); spdlog::error("{} no ipcStatus config for camera {}", devSn, k);
}else{ }
else {
auto &ipcStatus = peerData["ipcStatus"][k]; auto &ipcStatus = peerData["ipcStatus"][k];
if(ipcStatus["issues"].count(selfId) != 0) { if(ipcStatus["issues"].count(selfId) != 0) {
ipcStatus["issues"].erase(selfId); ipcStatus["issues"].erase(selfId);
...@@ -591,10 +596,11 @@ private: ...@@ -591,10 +596,11 @@ private:
peerData["online"][selfId] = 0; peerData["online"][selfId] = 0;
spdlog::warn("{} peer disconnected: {}", devSn, selfId); spdlog::warn("{} peer disconnected: {}", devSn, selfId);
if(peerData["mgr2ipc"].count(selfId) != 0) { if(peerData["mgr2ipc"].count(selfId) != 0) {
for(auto &[k,v]: peerData["mgr2ipc"][selfId].items()){ for(auto &[k,v]: peerData["mgr2ipc"][selfId].items()) {
if(peerData["ipcStatus"].count(k) == 0){ if(peerData["ipcStatus"].count(k) == 0) {
spdlog::error("{} no ipcStatus config for camera {}", devSn, k); spdlog::error("{} no ipcStatus config for camera {}", devSn, k);
}else{ }
else {
auto &ipcStatus = peerData["ipcStatus"][k]; auto &ipcStatus = peerData["ipcStatus"][k];
for(auto &[m,n]:ipcStatus["current"].items()) { for(auto &[m,n]:ipcStatus["current"].items()) {
n = false; n = false;
...@@ -609,7 +615,7 @@ private: ...@@ -609,7 +615,7 @@ private:
data["level"] = EV_MSG_META_VALUE_REPORT_LEVEL_ERROR; data["level"] = EV_MSG_META_VALUE_REPORT_LEVEL_ERROR;
data["time"] = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count(); data["time"] = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
data["status"] = "active"; data["status"] = "active";
if(ipcStatus["issues"].count(selfId) == 0){ if(ipcStatus["issues"].count(selfId) == 0) {
ipcStatus["issues"][selfId] = json(); ipcStatus["issues"][selfId] = json();
} }
ipcStatus["issues"][selfId][EV_MSG_REPORT_CATID_AVMGROFFLINE] = data; ipcStatus["issues"][selfId][EV_MSG_REPORT_CATID_AVMGROFFLINE] = data;
...@@ -619,7 +625,8 @@ private: ...@@ -619,7 +625,8 @@ private:
} }
} }
} }
}else{ }
else {
spdlog::error("{} no such dev {} for disconnect", devSn, selfId); spdlog::error("{} no such dev {} for disconnect", devSn, selfId);
} }
...@@ -635,18 +642,21 @@ private: ...@@ -635,18 +642,21 @@ private:
// data["level"] = EV_MSG_META_VALUE_REPORT_LEVEL_ERROR; // data["level"] = EV_MSG_META_VALUE_REPORT_LEVEL_ERROR;
// data["time"] = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count(); // data["time"] = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
// data["status"] = "active"; // data["status"] = "active";
void processReportMsg(string peerId, json &data) { void processReportMsg(string peerId, json &data)
{
json modIds; json modIds;
if(data["modId"].is_array()) { if(data["modId"].is_array()) {
modIds = data["modId"]; modIds = data["modId"];
}else if(data["modId"].is_string()) { }
else if(data["modId"].is_string()) {
modIds.push_back(data["modId"].get<string>()); modIds.push_back(data["modId"].get<string>());
} }
for(const string &modId: modIds){ for(const string &modId: modIds) {
if(peerData["mod2ipc"].count(modId) == 0) { if(peerData["mod2ipc"].count(modId) == 0) {
spdlog::error("{} received report from {} modId {} having no related ipc: {}", devSn, peerId, modId, data.dump()); spdlog::error("{} received report from {} modId {} having no related ipc: {}", devSn, peerId, modId, data.dump());
}else{ }
else {
string ipcSn = peerData["mod2ipc"][modId]; string ipcSn = peerData["mod2ipc"][modId];
string status = data["status"]; string status = data["status"];
string catId = data["catId"]; string catId = data["catId"];
...@@ -656,10 +666,11 @@ private: ...@@ -656,10 +666,11 @@ private:
if(peerData["ipcStatus"].count(ipcSn) != 0) { if(peerData["ipcStatus"].count(ipcSn) != 0) {
auto &ipcStatus = peerData["ipcStatus"][ipcSn]; auto &ipcStatus = peerData["ipcStatus"][ipcSn];
// log report, filter out ping // log report, filter out ping
if(catId == EV_MSG_REPORT_CATID_AVMODOFFLINE && status == "recover"){ if(catId == EV_MSG_REPORT_CATID_AVMODOFFLINE && status == "recover") {
// nop // nop
}else{ }
if(ipcStatus.count("lastNReports") == 0){ else {
if(ipcStatus.count("lastNReports") == 0) {
ipcStatus["lastNReports"] = json(); ipcStatus["lastNReports"] = json();
} }
ipcStatus["lastNReports"].push_back(data); ipcStatus["lastNReports"].push_back(data);
...@@ -675,12 +686,13 @@ private: ...@@ -675,12 +686,13 @@ private:
} }
if(ipcStatus["current"][modId] != ipcStatus["expected"][modId]) { if(ipcStatus["current"][modId] != ipcStatus["expected"][modId]) {
if(ipcStatus["issues"].count(modId) == 0){ if(ipcStatus["issues"].count(modId) == 0) {
ipcStatus["issues"][modId] = json(); ipcStatus["issues"][modId] = json();
} }
ipcStatus["issues"][modId][catId] = data; ipcStatus["issues"][modId][catId] = data;
} }
}else{ }
else {
// recover // recover
if(ipcStatus["issues"].count(modId) != 0 && if(ipcStatus["issues"].count(modId) != 0 &&
ipcStatus["issues"][modId].count(catId) != 0) { ipcStatus["issues"][modId].count(catId) != 0) {
...@@ -694,7 +706,8 @@ private: ...@@ -694,7 +706,8 @@ private:
ipcStatus["current"][modId] = true; ipcStatus["current"][modId] = true;
} }
} }
}else{ }
else {
spdlog::error("{} can't find ipc for report mod {}", devSn, modId); spdlog::error("{} can't find ipc for report mod {}", devSn, modId);
} }
} }
...@@ -780,7 +793,7 @@ private: ...@@ -780,7 +793,7 @@ private:
else { else {
// message to evcloudsvc // message to evcloudsvc
// spdlog::info("evcloudsvc {} subsystem report msg received: {}; {}; {}", devSn, zmqhelper::body2str(body[0]), zmqhelper::body2str(body[1]), zmqhelper::body2str(body[2])); // spdlog::info("evcloudsvc {} subsystem report msg received: {}; {}; {}", devSn, zmqhelper::body2str(body[0]), zmqhelper::body2str(body[1]), zmqhelper::body2str(body[2]));
try{ try {
if(meta == "pong"||meta == "ping") { if(meta == "pong"||meta == "ping") {
if(meta=="ping") { if(meta=="ping") {
auto ts = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count(); auto ts = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
...@@ -793,7 +806,8 @@ private: ...@@ -793,7 +806,8 @@ private:
} }
this->peerData["info"]["nocfg"][selfId]["lastConn"] = ts; this->peerData["info"]["nocfg"][selfId]["lastConn"] = ts;
this->peerData["info"]["nocfg"][selfId]["ips"] = data["ips"]; this->peerData["info"]["nocfg"][selfId]["ips"] = data["ips"];
}else{ }
else {
if(this->peerData["info"]["nocfg"].count(selfId) != 0) { if(this->peerData["info"]["nocfg"].count(selfId) != 0) {
this->peerData["info"]["nocfg"].erase(selfId); this->peerData["info"]["nocfg"].erase(selfId);
} }
...@@ -1303,28 +1317,32 @@ public: ...@@ -1303,28 +1317,32 @@ public:
string sn = req.get_param_value("sn"); string sn = req.get_param_value("sn");
try { try {
if(!sn.empty() && sn != "all") { if(!sn.empty() && sn != "all") {
if(this->peerData["ipcStatus"].count(sn) != 0){ if(this->peerData["ipcStatus"].count(sn) != 0) {
json j; json j;
j[sn] = this->peerData["ipcStatus"][sn]; j[sn] = this->peerData["ipcStatus"][sn];
detail = j; detail = j;
}else{ }
else {
ret["msg"] = "ipc not found"; ret["msg"] = "ipc not found";
ret["code"] = 1; ret["code"] = 1;
} }
}else if(sn == "all"){ }
else if(sn == "all") {
detail = this->peerData["ipcStatus"]; detail = this->peerData["ipcStatus"];
}else{ }
else {
// nop // nop
} }
ret["data"]["detail"] = detail; ret["data"]["detail"] = detail;
// get a copy to build summary // get a copy to build summary
json ipcsData = this->peerData["ipcStatus"]; json ipcsData = this->peerData["ipcStatus"];
for(auto &[k,v]: ipcsData.items()){ for(auto &[k,v]: ipcsData.items()) {
json diff = json::diff(v["expected"], v["current"]); json diff = json::diff(v["expected"], v["current"]);
if(diff.size() != 0) { if(diff.size() != 0) {
summary["problematic"].push_back(k); summary["problematic"].push_back(k);
}else{ }
else {
summary["ok"].push_back(k); summary["ok"].push_back(k);
} }
} }
...@@ -1347,15 +1365,16 @@ public: ...@@ -1347,15 +1365,16 @@ public:
json summary; json summary;
json stats; json stats;
vector<string> tags = {"E0C0", "E0C1", "E1C0", "E1C1"}; vector<string> tags = {"E0C0", "E0C1", "E1C0", "E1C1"};
for(auto &[k,v]: ipcsData.items()){ for(auto &[k,v]: ipcsData.items()) {
json diff = json::diff(v["expected"], v["current"]); json diff = json::diff(v["expected"], v["current"]);
if(diff.size() != 0) { if(diff.size() != 0) {
summary["problematic"].push_back(k); summary["problematic"].push_back(k);
}else{ }
else {
summary["ok"].push_back(k); summary["ok"].push_back(k);
} }
for(auto &[m, n]: v["current"].items()){ for(auto &[m, n]: v["current"].items()) {
auto x = v["expected"][m].get<bool>(); auto x = v["expected"][m].get<bool>();
int c = n?1:0; int c = n?1:0;
int e = x?1:0; int e = x?1:0;
......
...@@ -89,14 +89,15 @@ private: ...@@ -89,14 +89,15 @@ private:
data["reports"] = json(); data["reports"] = json();
json modIdsOnline; json modIdsOnline;
json modIdsOffline; json modIdsOffline;
for(auto &[k,v]: this->peerData["status"].items()){ for(auto &[k,v]: this->peerData["status"].items()) {
// ignore evmgr // ignore evmgr
if(k.find("evmgr") != string::npos) { if(k.find("evmgr") != string::npos) {
continue; continue;
} }
if(v != 0 && v != -1 && v != 1 && v != 2) { if(v != 0 && v != -1 && v != 1 && v != 2) {
modIdsOnline.push_back(k); modIdsOnline.push_back(k);
}else{ }
else {
modIdsOffline.push_back(k); modIdsOffline.push_back(k);
} }
} }
...@@ -133,7 +134,7 @@ private: ...@@ -133,7 +134,7 @@ private:
} }
vector<string> modIdsLoopRecover; vector<string> modIdsLoopRecover;
for(auto &[k,v] :peerData["contConn"].items()){ for(auto &[k,v] :peerData["contConn"].items()) {
if(v > 4) { if(v > 4) {
// not offline // not offline
if(peerData["status"].count(k) != 0 && peerData["status"][k] != -1 && peerData["status"][k] != 2 && peerData["status"][k] != 1) { if(peerData["status"].count(k) != 0 && peerData["status"][k] != -1 && peerData["status"][k] != 2 && peerData["status"][k] != 1) {
...@@ -460,7 +461,8 @@ private: ...@@ -460,7 +461,8 @@ private:
return ret; return ret;
} }
void sendModConnectedMsg(json &modIds){ void sendModConnectedMsg(json &modIds)
{
json meta; json meta;
json data; json data;
string msg = fmt::format("evdaemon {} detects modules {} booted up", this->devSn, modIds.dump()); string msg = fmt::format("evdaemon {} detects modules {} booted up", this->devSn, modIds.dump());
...@@ -477,7 +479,8 @@ private: ...@@ -477,7 +479,8 @@ private:
} }
void sendModOfflineMsg(json &modIds){ void sendModOfflineMsg(json &modIds)
{
json meta; json meta;
json data; json data;
string msg = fmt::format("evdaemon {} detects modules {} offline", this->devSn, modIds.dump()); string msg = fmt::format("evdaemon {} detects modules {} offline", this->devSn, modIds.dump());
......
...@@ -105,7 +105,8 @@ private: ...@@ -105,7 +105,8 @@ private:
if(config.count("portRouter") != 0) { if(config.count("portRouter") != 0) {
portRouter = to_string(config["portRouter"]); portRouter = to_string(config["portRouter"]);
}else if(config.count("port-router") != 0) { }
else if(config.count("port-router") != 0) {
portRouter = to_string(config["port-router"]); portRouter = to_string(config["port-router"]);
} }
......
...@@ -533,7 +533,8 @@ private: ...@@ -533,7 +533,8 @@ private:
return 0; return 0;
} }
void makeEvent(string evtType, int ts) { void makeEvent(string evtType, int ts)
{
json p; json p;
p["type"] = EV_MSG_TYPE_AI_MOTION; p["type"] = EV_MSG_TYPE_AI_MOTION;
p["gid"] = selfId; p["gid"] = selfId;
......
...@@ -865,7 +865,8 @@ protected: ...@@ -865,7 +865,8 @@ protected:
return ret; return ret;
} }
void reportUploadFailure(string modId, bool fail, string reason){ void reportUploadFailure(string modId, bool fail, string reason)
{
string modifier = fail?"failed": "successfully"; string modifier = fail?"failed": "successfully";
string status = fail?"active":"recover"; string status = fail?"active":"recover";
string msg = fmt::format("evslicer {} {} upload videos: {}", selfId, modifier, reason); string msg = fmt::format("evslicer {} {} upload videos: {}", selfId, modifier, reason);
...@@ -1141,7 +1142,7 @@ public: ...@@ -1141,7 +1142,7 @@ public:
} }
} }
if(resp.count("code") != 0 && resp["code"] == 0){ if(resp.count("code") != 0 && resp["code"] == 0) {
if(bUploadFailed) { if(bUploadFailed) {
bUploadFailed = false; bUploadFailed = false;
reportUploadFailure(selfId, false, strResp); reportUploadFailure(selfId, false, strResp);
......
...@@ -15,7 +15,83 @@ ...@@ -15,7 +15,83 @@
#include <string> #include <string>
#include <array> #include <array>
std::string exec(const char* cmd) {
// ilabservice hardware, non-portable code
#define EMBED_HW_ILS
#ifdef EMBED_HW_ILS
#include <signal.h>
#include <fcntl.h>
#include <fcntl.h>
#define DEV_NAME "/dev/int_gpio_1"
typedef struct _key_msg {
int key_id;
unsigned long time;
int count;
} key_msg, *KEY_MSG;
mutex mutLed;
static char lightLed(bool on)
{
static int fd = 0;
int size;
const char *path = "/sys/class/gpio_sw/PL10/light";
lock_guard<mutex> lg(mutLed);
if(fd <= 0) {
fd = open(path, O_RDWR);
if (fd<0) {
spdlog::error("failed to open {}", path);
return -1;
}
}
char buf[] = "0";
if(on) {
buf[0] = '1';
}
size = write(fd, buf, strlen(buf));
if (size<0) {
spdlog::error("failed to write led", path);
return -1;
}
return 0;
}
list<string> ledPattList;
void ledPattDefault(){
ledPattList.push_back("1");
}
void ledPattAPMode(){
ledPattList.push_back("10");
}
void ledNoNetwork(){
ledPattList.push_back("1000");
}
#else
void ledPattDefault(){
}
void ledPattAPMode(){
}
void ledNoNetwork(){
}
#endif
std::string exec(const char* cmd)
{
std::array<char, 128> buffer; std::array<char, 128> buffer;
std::string result; std::string result;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose); std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
...@@ -35,7 +111,7 @@ using namespace httplib; ...@@ -35,7 +111,7 @@ using namespace httplib;
class WifiMgr { class WifiMgr {
private: private:
json info; json info;
string devSn; string devSn;
string baseDir = "web/main/dist"; string baseDir = "web/main/dist";
...@@ -49,7 +125,8 @@ class WifiMgr { ...@@ -49,7 +125,8 @@ class WifiMgr {
const string apdCfgPath = "/etc/apd.conf"; const string apdCfgPath = "/etc/apd.conf";
const string wpaCfgPath = "/etc/wpa_supplicant/wpa_supplicant-wlan1.conf"; const string wpaCfgPath = "/etc/wpa_supplicant/wpa_supplicant-wlan1.conf";
void scanWifi(){ void scanWifi()
{
lock_guard<mutex> lk(mutMode); lock_guard<mutex> lk(mutMode);
/// get sn /// get sn
...@@ -61,12 +138,14 @@ class WifiMgr { ...@@ -61,12 +138,14 @@ class WifiMgr {
auto ip = exec("ifconfig wlan1|grep -v inet6|grep inet|awk '{print $2}'"); auto ip = exec("ifconfig wlan1|grep -v inet6|grep inet|awk '{print $2}'");
if(ip.size() > 1) { if(ip.size() > 1) {
ip = ip.substr(0, ip.size() -1); ip = ip.substr(0, ip.size() -1);
}else{ }
else {
ip = ""; ip = "";
} }
if(mac.size() > 1) { if(mac.size() > 1) {
mac = mac.substr(0, mac.size() -1); mac = mac.substr(0, mac.size() -1);
}else{ }
else {
mac = ""; mac = "";
} }
wifiData["wifi"]["ip"] = ip; wifiData["wifi"]["ip"] = ip;
...@@ -74,13 +153,14 @@ class WifiMgr { ...@@ -74,13 +153,14 @@ class WifiMgr {
spdlog::info("evwifi {} ip: {}, mac: {}", this->devSn, ip, mac); spdlog::info("evwifi {} ip: {}, mac: {}", this->devSn, ip, mac);
/// get connected wifi ssid /// get connected wifi ssid
if(!ip.empty() && ip != "192.168.0.1"){ if(!ip.empty() && ip != "192.168.0.1") {
auto ssid = exec("grep ssid /etc/wpa_supplicant/wpa_supplicant-wlan1.conf 2> /dev/null|awk '{print substr($1, 6)}'"); auto ssid = exec("grep ssid /etc/wpa_supplicant/wpa_supplicant-wlan1.conf 2> /dev/null|awk '{print substr($1, 6)}'");
if(ssid.size() >=4) { if(ssid.size() >=4) {
ssid = ssid.substr(1, ssid.size() - 3); ssid = ssid.substr(1, ssid.size() - 3);
wifiData["wifi"]["ssid"] = ssid; wifiData["wifi"]["ssid"] = ssid;
spdlog::info("evwifi {} ssid: {}", this->devSn, ssid); spdlog::info("evwifi {} ssid: {}", this->devSn, ssid);
}else{ }
else {
if(wifiData["wifi"].count("ssid") != 0) { if(wifiData["wifi"].count("ssid") != 0) {
wifiData["wifi"].erase("ssid"); wifiData["wifi"].erase("ssid");
} }
...@@ -91,12 +171,14 @@ class WifiMgr { ...@@ -91,12 +171,14 @@ class WifiMgr {
password = password.substr(1, password.size() - 3); password = password.substr(1, password.size() - 3);
wifiData["wifi"]["password"] = password; wifiData["wifi"]["password"] = password;
spdlog::info("evwifi {} password: {}", this->devSn, password); spdlog::info("evwifi {} password: {}", this->devSn, password);
}else{ }
else {
if(wifiData["wifi"].count("password") != 0) { if(wifiData["wifi"].count("password") != 0) {
wifiData["wifi"].erase("password"); wifiData["wifi"].erase("password");
} }
} }
}else{ }
else {
if(wifiData["wifi"].count("ssid") != 0) { if(wifiData["wifi"].count("ssid") != 0) {
wifiData["wifi"].erase("ssid"); wifiData["wifi"].erase("ssid");
} }
...@@ -112,7 +194,9 @@ class WifiMgr { ...@@ -112,7 +194,9 @@ class WifiMgr {
}); });
} }
json enableMode(int mode){ public:
json enableMode(int mode)
{
lock_guard<mutex> lk(mutMode); lock_guard<mutex> lk(mutMode);
json ret; json ret;
ret["code"] = 0; ret["code"] = 0;
...@@ -127,23 +211,26 @@ class WifiMgr { ...@@ -127,23 +211,26 @@ class WifiMgr {
string apdContent = fmt::format("interface=wlan1\ndriver=nl80211\nssid=EVB-{}\nhw_mode=g\n" 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>()); "channel=6\nmacaddr_acl=0\nignore_broadcast_ssid=0\nwpa=0\n", this->info["sn"].get<string>());
ofstream fileApd(apdCfgPath, ios::out|ios::trunc); ofstream fileApd(apdCfgPath, ios::out|ios::trunc);
if(fileApd.is_open()){ if(fileApd.is_open()) {
fileApd << apdContent; fileApd << apdContent;
fileApd.close(); fileApd.close();
// start hostapd // start hostapd
auto t = thread([this](){ auto t = thread([this]() {
system("pkill hostapd;systemctl stop wpa_supplicant@wlan1;ifconfig wlan1 down;" system("pkill hostapd;systemctl stop wpa_supplicant@wlan1;ifconfig wlan1 down;"
"ifconfig wlan1 up;ifconfig wlan1 192.168.0.1;hostapd /etc/apd.conf -B"); "ifconfig wlan1 up;ifconfig wlan1 192.168.0.1;hostapd /etc/apd.conf -B");
// TODO: check result // TODO: check result
}); });
t.detach(); t.detach();
}else{ ledPattAPMode();
}
else {
ret["code"] = 1; ret["code"] = 1;
string msg = fmt::format("failed to write ap config file to {}", apdCfgPath); string msg = fmt::format("failed to write ap config file to {}", apdCfgPath);
spdlog::error("evwifi {} {}", devSn,msg); spdlog::error("evwifi {} {}", devSn,msg);
ret["msg"] = msg; ret["msg"] = msg;
} }
}else if(mode == 2) { }
else if(mode == 2) {
// station mode // station mode
this->mode = 2; this->mode = 2;
spdlog::info("evwifi {} prepare to enter Station mode", devSn); spdlog::info("evwifi {} prepare to enter Station mode", devSn);
...@@ -154,15 +241,15 @@ class WifiMgr { ...@@ -154,15 +241,15 @@ class WifiMgr {
ret["msg"] = msg; ret["msg"] = msg;
ret["code"] = 3; ret["code"] = 3;
} }
else{ else {
string wpaContent = fmt::format("ctrl_interface=/run/wpa_supplicant\nupdate_config=1\nap_scan=1\n" string wpaContent = fmt::format("ctrl_interface=/run/wpa_supplicant\nupdate_config=1\nap_scan=1\n"
"network={{\nssid=\"{}\"\npsk=\"{}\"\n}}\n", this->wifiData["wifi"]["ssid"].get<string>(), this->wifiData["wifi"]["password"].get<string>()); "network={{\nssid=\"{}\"\npsk=\"{}\"\n}}\n", this->wifiData["wifi"]["ssid"].get<string>(), this->wifiData["wifi"]["password"].get<string>());
ofstream wpaFile(wpaCfgPath, ios::out|ios::trunc); ofstream wpaFile(wpaCfgPath, ios::out|ios::trunc);
if(wpaFile.is_open()){ if(wpaFile.is_open()) {
wpaFile << wpaContent; wpaFile << wpaContent;
wpaFile.close(); wpaFile.close();
// TODO: verify // TODO: verify
auto t = thread([this](){ auto t = thread([this]() {
// delay for rest return (ifdown caused no networking available) // delay for rest return (ifdown caused no networking available)
this_thread::sleep_for(chrono::seconds(1)); this_thread::sleep_for(chrono::seconds(1));
system("pkill hostapd; pkill dhclient;systemctl enable wpa_supplicant@wlan1;systemctl restart wpa_supplicant@wlan1;" system("pkill hostapd; pkill dhclient;systemctl enable wpa_supplicant@wlan1;systemctl restart wpa_supplicant@wlan1;"
...@@ -173,13 +260,17 @@ class WifiMgr { ...@@ -173,13 +260,17 @@ class WifiMgr {
spdlog::error("evwifi {} failed to connect to wifi {} with password {}. initiazing AP mode", this->devSn, spdlog::error("evwifi {} failed to connect to wifi {} with password {}. initiazing AP mode", this->devSn,
this->wifiData["wifi"]["ssid"].get<string>(), this->wifiData["wifi"]["password"].get<string>()); this->wifiData["wifi"]["ssid"].get<string>(), this->wifiData["wifi"]["password"].get<string>());
this->mode = 0; this->mode = 0;
}else{ ledNoNetwork();
}
else {
system("systemctl restart evdaemon"); system("systemctl restart evdaemon");
spdlog::info("evwifi {} successfully connected to wifi {}", this->devSn, this->wifiData["wifi"]["ssid"].get<string>()); spdlog::info("evwifi {} successfully connected to wifi {}", this->devSn, this->wifiData["wifi"]["ssid"].get<string>());
ledPattDefault();
} }
}); });
t.detach(); t.detach();
}else{ }
else {
string msg = fmt::format("failed write wpa config to {}", wpaCfgPath); string msg = fmt::format("failed write wpa config to {}", wpaCfgPath);
ret["code"] = 2; ret["code"] = 2;
ret["msg"] = msg; ret["msg"] = msg;
...@@ -191,8 +282,15 @@ class WifiMgr { ...@@ -191,8 +282,15 @@ class WifiMgr {
return ret; return ret;
} }
public: public:
WifiMgr(){
void run()
{
srv.listen("0.0.0.0", 80);
};
WifiMgr()
{
LVDB::getSn(this->info); LVDB::getSn(this->info);
devSn = this->info["sn"]; devSn = this->info["sn"];
mode = 0; mode = 0;
...@@ -202,8 +300,8 @@ class WifiMgr { ...@@ -202,8 +300,8 @@ class WifiMgr {
//wifiData["wifi"]["ssid"] = string; //wifiData["wifi"]["ssid"] = string;
//wifiData["wifi"]["password"] = string; //wifiData["wifi"]["password"] = string;
monitor = thread([this](){ monitor = thread([this]() {
while(1){ while(1) {
/// background wifi scanning /// background wifi scanning
if(this->mode != 2) { if(this->mode != 2) {
this->scanWifi(); this->scanWifi();
...@@ -230,21 +328,25 @@ class WifiMgr { ...@@ -230,21 +328,25 @@ class WifiMgr {
if(this->mode == 0) { if(this->mode == 0) {
spdlog::info("evwifi {} detects no wifi connection, enabling AP mode", this->devSn); spdlog::info("evwifi {} detects no wifi connection, enabling AP mode", this->devSn);
this->enableMode(1); this->enableMode(1);
}else if(this->mode == 1) { }
else if(this->mode == 1) {
// maybe give it a try to switch into mode2 is not a bad idea // maybe give it a try to switch into mode2 is not a bad idea
this->mode1Cnt++; this->mode1Cnt++;
if(!ssid.empty() && !password.empty() && mode1Cnt % 600){ if(!ssid.empty() && !password.empty() && mode1Cnt % 600) {
spdlog::info("evwifi {} give it a try to mode2, since configuration exists.", this->devSn); spdlog::info("evwifi {} give it a try to mode2, since configuration exists.", this->devSn);
this->enableMode(2); this->enableMode(2);
} }
} }
}else{ }
else {
// having wifi ip // having wifi ip
if(ip == "192.168.0.1"){ if(ip == "192.168.0.1") {
this->mode = 1; this->mode = 1;
}else if(!ssid.empty() && !password.empty()){ }
else if(!ssid.empty() && !password.empty()) {
this->mode = 2; this->mode = 2;
}else{ }
else {
spdlog::info("evwifi {} invalid state(having wifi IP but no config), switch to AP mode", this->devSn); spdlog::info("evwifi {} invalid state(having wifi IP but no config), switch to AP mode", this->devSn);
this->enableMode(1); this->enableMode(1);
} }
...@@ -267,28 +369,30 @@ class WifiMgr { ...@@ -267,28 +369,30 @@ class WifiMgr {
ret["code"] = 0; ret["code"] = 0;
ret["msg"] = "ok"; ret["msg"] = "ok";
string scan = req.get_param_value("scan"); string scan = req.get_param_value("scan");
if(!scan.empty()){ if(!scan.empty()) {
if(scan == "true"){ if(scan == "true") {
this->scanWifi(); this->scanWifi();
ret["wifiData"] = this->wifiData; ret["wifiData"] = this->wifiData;
}else{ }
else {
ret["wifiData"] = this->wifiData; ret["wifiData"] = this->wifiData;
} }
} }
if(scan.empty() && !mode.empty()){ if(scan.empty() && !mode.empty()) {
try{ try {
auto i = stoi(mode); auto i = stoi(mode);
if(i == 2) { if(i == 2) {
lock_guard<mutex> lk(mutMode); lock_guard<mutex> lk(mutMode);
string ssid = req.get_param_value("ssid"); string ssid = req.get_param_value("ssid");
string password = req.get_param_value("password"); string password = req.get_param_value("password");
if(ssid.empty()||password.empty()){ if(ssid.empty()||password.empty()) {
string msg = fmt::format("no valid ssid/password provided"); string msg = fmt::format("no valid ssid/password provided");
spdlog::error("evwifi {} {}", this->devSn, msg); spdlog::error("evwifi {} {}", this->devSn, msg);
ret["msg"] = msg; ret["msg"] = msg;
ret["code"] = 3; ret["code"] = 3;
}else{ }
else {
this->mode = 2; this->mode = 2;
this->wifiData["wifi"]["ssid"] = ssid; this->wifiData["wifi"]["ssid"] = ssid;
this->wifiData["wifi"]["password"] = password; this->wifiData["wifi"]["password"] = password;
...@@ -299,7 +403,8 @@ class WifiMgr { ...@@ -299,7 +403,8 @@ class WifiMgr {
ret = this->enableMode(i); ret = this->enableMode(i);
} }
}catch(exception &e){ }
catch(exception &e) {
string msg = fmt::format("exception in convert mode {} to int:{}", mode, e.what()); string msg = fmt::format("exception in convert mode {} to int:{}", mode, e.what());
ret["code"] = -1; ret["code"] = -1;
ret["msg"] = msg; ret["msg"] = msg;
...@@ -312,11 +417,83 @@ class WifiMgr { ...@@ -312,11 +417,83 @@ class WifiMgr {
res.set_content(ret.dump(), "text/json"); res.set_content(ret.dump(), "text/json");
}); });
srv.listen("0.0.0.0", 80);
} }
}; };
int main(){
WifiMgr mgr; WifiMgr mgr;
#ifdef EMBED_HW_ILS
static int key_event_fd;
key_msg key_event_msg;
void hand_sig(int sig) {
read(key_event_fd, &key_event_msg, sizeof(key_event_msg));
spdlog::info("key event id {}, time {}, count {}", key_event_msg.key_id, key_event_msg.time, key_event_msg.count);
if(key_event_msg.count == 5) {
// switch AP mode
mgr.enableMode(1);
}else if(key_event_msg.count == 5 && key_event_msg.time * 10 >= 10 * 1000){
// clear SN && restart evdaemon
system("rm -fr /opt/lvldb && systemctl restart evdaemon");
}else if((key_event_msg.count == 1 && key_event_msg.time * 10 >= 10 * 1000)){
// restart evdaemon only
system("systemctl restart evdaemon");
}
}
#endif
int main()
{
#ifdef EMBED_HW_ILS
int flags;
key_event_fd = open(DEV_NAME, O_RDWR);
if (key_event_fd<0) {
printf("open %s error \n", DEV_NAME);
return -1;
}
signal(SIGIO, hand_sig);
fcntl(key_event_fd, F_SETOWN, getpid());
flags = fcntl(key_event_fd, F_GETFL);
fcntl(key_event_fd, F_SETFL, flags|FASYNC);
// LED
auto tLed = thread([&]() {
string lastPatt = "1";
char lastMode = '0';
while(1) {
if(ledPattList.size() != 0) {
lastPatt = ledPattList.front();
ledPattList.pop_front();
}
for(auto &c: lastPatt) {
if(c == lastMode){
//skip
}else{
if(c == '1'){
// on
lightLed(true);
}else{
lightLed(false);
}
lastMode = c;
}
this_thread::sleep_for(chrono::milliseconds(500));
}
this_thread::sleep_for(chrono::milliseconds(500));
}
});
tLed.detach();
#endif
mgr.run();
#ifdef EMBED_HW_ILS
close(key_event_fd);
#endif
} }
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论