Browse Source

init

master
zhaohe 3 months ago
parent
commit
f32b0eff13
  1. 2
      CMakeLists.txt
  2. 4
      resources/iflytophald.service
  3. 184
      src/components/channel/data_channel_mgr.cpp
  4. 32
      src/components/channel/data_channel_mgr.hpp
  5. 160
      src/components/channel/gpio_key_channel.cpp
  6. 85
      src/components/channel/gpio_key_channel.hpp
  7. 50
      src/components/channel/idata_channel.hpp
  8. 200
      src/components/channel/uart_channel.cpp
  9. 54
      src/components/channel/uart_channel.hpp
  10. 57
      src/components/channel/zexcan_channel.cpp
  11. 47
      src/components/channel/zexcan_channel.hpp
  12. 117
      src/components/config_template/config_template.hpp
  13. 161
      src/components/uart/uart.cpp
  14. 28
      src/components/uart/uart.hpp
  15. 2
      src/configs/version.hpp
  16. 8
      src/main.cpp
  17. 9
      src/service/app_config_service.cpp
  18. 30
      src/service/app_config_service.hpp
  19. 214
      src/service/extapi_service.cpp
  20. 53
      src/service/extapi_service.hpp
  21. 85
      src/service/wbesocket_connect_mgr_service.cpp
  22. 65
      src/service/wbesocket_connect_mgr_service.hpp
  23. 14
      tools/deply.sh
  24. 6
      tools/packet.sh

2
CMakeLists.txt

@ -51,7 +51,7 @@ file(GLOB_RECURSE VAR_APP_SOURCE #
message("VAR_APP_SOURCE: ${VAR_APP_SOURCE}")
zadd_executable(
TARGET
iflytophald #
iflytopzexcand #
INSTALL
./app/
#

4
resources/iflytophald.service

@ -6,10 +6,10 @@ Wants = network.target
[Service]
Type = simple
ExecStart = /iflytopd/iflytophald/iflytophald
ExecStart = /iflytopd/iflytopzexcand/iflytopzexcand
Restart=always
RestartSec=2
WorkingDirectory=/iflytopd/iflytophald/
WorkingDirectory=/iflytopd/iflytopzexcand/
[Install]
WantedBy = multi-user.target

184
src/components/channel/data_channel_mgr.cpp

@ -1,184 +0,0 @@
#include "data_channel_mgr.hpp"
#include <toml++/toml.hpp>
using namespace iflytop;
using namespace std;
static IDataChannel::OnData_t s_ondata;
static map<string, IDataChannel *> s_channelMap;
static list<IDataChannel *> s_channelList;
// s_channelMap[ch->getChannelName()] = ch;
// if (!ch->getAlias().empty()) s_channelMap[ch->getAlias()] = ch;
// s_channelList.push_back(ch);
static IDataChannel *create_zexcan_ch(toml::table &config, string type, int choff) {
auto logger = GET_LOGGER(DataChannelMgr);
string name = config["channels"][choff]["name"].value_or("zcan");
string alias = config["channels"][choff]["alias"].value_or("");
string ifname = config["channels"][choff]["ifname"].value_or("can0");
int baudrate = config["channels"][choff]["baudrate"].value_or(500000);
bool enable = config["channels"][choff]["enable"].value_or(true);
if (!enable) {
logger->warn("skip channel: {}, enable=false", name);
return nullptr;
}
logger->info("==================create channel {}=================", name);
logger->info("create channel: {}, type={}, ifname={}, baudrate={}", name, type, ifname, baudrate);
ZExCanChannel *ch = new ZExCanChannel(name, ifname, baudrate);
ch->setAlias(alias);
ch->initialize();
ch->registerOnDataCallback([](IDataChannel *ch, bool binary, const char *data, size_t len) {
if (s_ondata) s_ondata(ch, binary, data, len);
});
logger->info("");
return ch;
}
static IDataChannel *create_uart_ch(toml::table &config, string type, int choff) {
auto logger = GET_LOGGER(DataChannelMgr);
string name = config["channels"][choff]["name"].value_or("");
string alias = config["channels"][choff]["alias"].value_or("");
string ifname = config["channels"][choff]["ifname"].value_or("");
int baudrate = config["channels"][choff]["baudrate"].value_or(115200);
bool enable = config["channels"][choff]["enable"].value_or(true);
int32_t rxovertime = config["channels"][choff]["rxovertime"].value_or(3);
bool hexch = config["channels"][choff]["hexch"].value_or(true);
if (!enable) {
logger->warn("skip channel: {}, enable=false", name);
return nullptr;
}
logger->info("==================create channel {}=================", name);
logger->info("create channel: {}, type={}, ifname={}, baudrate={}, hexch={}, rxovertime={}", name, type, ifname, baudrate, hexch, rxovertime);
if (name.empty()) {
logger->error("ch-{} name is empty", choff);
exit(1);
}
if (ifname.empty()) {
logger->error("ch-{} ifname is empty", choff);
exit(1);
}
UartChannel *ch = new UartChannel(name, ifname, baudrate, hexch, rxovertime);
ch->setAlias(alias);
ch->initialize();
ch->registerOnDataCallback([](IDataChannel *ch, bool binary, const char *data, size_t len) {
if (s_ondata) s_ondata(ch, binary, data, len);
});
logger->info("");
return ch;
}
static IDataChannel *create_gpiokey_ch(toml::table &config, string type, int choff) {
auto logger = GET_LOGGER(DataChannelMgr);
if (!config["channels"][choff]["pins"].is_array()) {
logger->error("ch-{} pins is not array", choff);
exit(1);
}
string name = config["channels"][choff]["name"].value_or("");
bool enable = config["channels"][choff]["enable"].value_or(true);
string alias = config["channels"][choff]["alias"].value_or("");
vector<string> pins;
for (size_t i = 0; i < config["channels"][choff]["pins"].as_array()->size(); i++) {
pins.push_back(config["channels"][choff]["pins"][i].value_or(""));
}
vector<bool> mirror;
if (config["channels"][choff]["mirror"].is_array()) {
for (size_t i = 0; i < config["channels"][choff]["mirror"].as_array()->size(); i++) {
mirror.push_back(config["channels"][choff]["mirror"][i].value_or(false));
}
}
vector<string> pinalias;
if (config["channels"][choff]["pinalias"].is_array()) {
for (size_t i = 0; i < config["channels"][choff]["pinalias"].as_array()->size(); i++) {
pinalias.push_back(config["channels"][choff]["pinalias"][i].value_or(""));
}
}
if (!enable) {
logger->warn("skip channel: {}, enable=false", name);
return nullptr;
}
logger->info("==================create channel {}=================", name);
logger->info("create channel: {}, type={}, pins={} mirror={}", name, type, pins, mirror);
if (name.empty()) {
logger->error("ch-{} name is empty", choff);
exit(1);
}
if (pins.empty()) {
logger->error("ch-{} pinnum is empty", choff);
exit(1);
}
GpioKeyChannel *ch = new GpioKeyChannel(name, pins, pinalias, mirror);
ch->setAlias(alias);
ch->initialize();
ch->registerOnDataCallback([](IDataChannel *ch, bool binary, const char *data, size_t len) {
if (s_ondata) s_ondata(ch, binary, data, len);
});
logger->info("");
return ch;
}
static IDataChannel *createCh(toml::table &config, string type, int choff) {
auto logger = GET_LOGGER(DataChannelMgr);
logger->info("create channel: {}, type={}", choff, type);
if (type == "zexcan") {
return create_zexcan_ch(config, type, choff);
} else if (type == "uart") {
return create_uart_ch(config, type, choff);
} else if (type == "gpio-key") {
return create_gpiokey_ch(config, type, choff);
} else {
logger->error("unknown channel type: {}", type);
exit(1);
}
}
void DataChannelMgr::initChannels(toml::table &config) {
auto logger = GET_LOGGER(DataChannelMgr);
try {
if (auto channels = config["channels"].as_array()) {
for (size_t i = 0; i < channels->size(); i++) {
string type = config["channels"][i]["type"].value_or("");
IDataChannel *newch = createCh(config, type, i);
if (!newch) continue;
s_channelMap[newch->getChannelName()] = newch;
if (!newch->getAlias().empty()) s_channelMap[newch->getAlias()] = newch;
s_channelList.push_back(newch);
usleep(100 * 1000);
}
}
} catch (const toml::parse_error &err) {
logger->error("parse config error, {}", err);
}
}
void DataChannelMgr::regOnChannelData(IDataChannel::OnData_t ondata) { s_ondata = ondata; }
list<IDataChannel *> DataChannelMgr::getChannels() { return s_channelList; }
IDataChannel *DataChannelMgr::findByChannel(string name) {
if (s_channelMap.find(name) != s_channelMap.end()) {
return s_channelMap[name];
}
return nullptr;
}

32
src/components/channel/data_channel_mgr.hpp

@ -1,32 +0,0 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
//
#include <toml++/toml.hpp>
#include "gpio_key_channel.hpp"
#include "idata_channel.hpp"
#include "uart_channel.hpp"
#include "zexcan_channel.hpp"
namespace iflytop {
using namespace std;
class DataChannelMgr {
public:
static void initChannels(toml::table &config);
static void regOnChannelData(IDataChannel::OnData_t ondata);
static list<IDataChannel *> getChannels();
static IDataChannel *findByChannel(string name);
};
} // namespace iflytop

160
src/components/channel/gpio_key_channel.cpp

@ -1,160 +0,0 @@
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
//
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
//
#include <map>
#include <set>
#include <string>
#include "gpio_key_channel.hpp"
#include "utils/stringutils.hpp"
using namespace nlohmann;
using namespace iflytop;
using namespace std;
void GpioKeyChannel::execCmd(string cmd) {
logger->info("execCmd {}", cmd);
system(cmd.c_str());
}
GpioKeyChannel::GpioKeyChannel(string chname, vector<string> pins, vector<string> alias, vector<bool> mirror) {
logger = LoggerFactory.createRotatingFileLogger(chname);
m_chname = chname;
m_pins = pins;
m_mirror = mirror;
m_alias = alias;
}
void GpioKeyChannel::initialize() {
// vector<GPIO> m_gpios;
if (m_mirror.size() != m_pins.size()) {
logger->error("mirror size not match with pins size");
exit(1);
}
if (m_alias.size() != m_pins.size()) {
logger->error("alias size not match with pins size");
exit(1);
}
int offset = 0;
for (auto pinstr : m_pins) {
// GPIO3_A2
auto result = LinuxGpioUitils::parseGpioStr(pinstr);
GPIO gpio;
gpio.blank = result.blank;
gpio.port = result.port;
gpio.pin = result.pin;
gpio.linuxIndex = result.linuxIndex;
gpio.offset = offset;
if (gpio.linuxIndex == -1) {
logger->error("parse gpio {} failed", pinstr);
exit(1);
} else {
logger->info("parse gpio {} --> gpio{}", pinstr, gpio.linuxIndex);
m_gpios.push_back(gpio);
}
offset++;
}
if (m_mirror.size() != 0) {
for (size_t i = 0; i < m_gpios.size(); i++) {
m_gpios[i].mirror = m_mirror[i];
m_gpios[i].alias = m_alias[i];
}
}
// init gpio
for (auto& gpio : m_gpios) {
execCmd(fmt::format("echo {} > /sys/class/gpio/export", gpio.linuxIndex));
execCmd(fmt::format("echo in > /sys/class/gpio/gpio{}/direction", gpio.linuxIndex));
gpio.fd = open(fmt::format("/sys/class/gpio/gpio{}/value", gpio.linuxIndex).c_str(), O_RDONLY);
if (gpio.fd < 0) {
logger->error("open gpio{} failed", gpio.linuxIndex);
exit(1);
}
}
// read gpio
m_rxthread.reset(new Thread(fmt::format("{}-rxthread", m_chname), [this]() {
logger->info("{} rxthread start", m_chname);
ThisThread thisThread;
int syncCount = 0;
while (!thisThread.getExitFlag()) {
for (auto& gpio : m_gpios) {
char value;
lseek(gpio.fd, 0, SEEK_SET);
read(gpio.fd, &value, 1);
bool nowstate = value == '1' ? true : false;
nowstate = gpio.mirror ? !nowstate : nowstate;
gpio.laststate = gpio.state;
gpio.state = nowstate;
if (gpio.laststate != gpio.state) {
gpio.duration = 0;
} else {
gpio.duration += 20;
if (gpio.duration <= 0) gpio.duration = INT32_MAX;
}
}
// report
for (auto& gpio : m_gpios) {
bool reportthisloop = false;
if (gpio.duration == 0 || syncCount % 50 == 0) {
json report;
report["name"] = gpio.alias;
report["index"] = gpio.linuxIndex;
report["state"] = (bool)gpio.state;
report["duration"] = gpio.duration;
report["event"] = gpio.state == gpio.laststate ? "sync" : (gpio.state ? "press" : "release");
string reportstr = report.dump();
if (m_ondata) m_ondata(this, false, reportstr.data(), reportstr.size());
if (gpio.duration == 0) {
logger->info("{}", reportstr);
}
}
}
usleep(20 * 1000);
syncCount++;
} // end while
}));
return;
}
void GpioKeyChannel::senddata(bool binary, const char* data, size_t len) {}
void GpioKeyChannel::registerOnDataCallback(OnData_t ondata) { m_ondata = ondata; }
void GpioKeyChannel::callcmd(string cmd, unordered_map<string, string> param, json& receipt) {}
list<string> GpioKeyChannel::getCmdList() {
list<string> cmdlist;
return cmdlist;
}
json GpioKeyChannel::getChannelInfo() {
json info;
info["name"] = m_chname;
info["alias"] = getAlias();
info["type"] = "gpio-key";
info["pins"] = m_pins;
info["pinAlias"] = m_alias;
info["mirror"] = m_mirror;
return info;
}

85
src/components/channel/gpio_key_channel.hpp

@ -1,85 +0,0 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "components/linux_gpio_utils.hpp"
#include "components/thread/thread.hpp"
#include "idata_channel.hpp"
namespace iflytop {
using namespace std;
using namespace nlohmann;
using namespace core;
class GpioKeyChannel : public IDataChannel {
private:
/* data */
class GPIO {
public:
int offset = 0;
int blank = 0; // 1,2,3,4
char port = 0; // A,B,C,D
int pin = 0; // 1,2,3,4
int linuxIndex = 0;
int fd = -1;
bool state =false;
bool laststate =false;
bool mirror = false;
int duration = 0;
string alias;
public:
string tostring() {
if (blank == 0) {
return "GPIO" + to_string(pin);
} else {
return "GPIO" + to_string(blank) + "_" + port + to_string(pin);
}
}
};
iflytop::core::logger_t logger;
OnData_t m_ondata;
string m_chname;
vector<string> m_pins;
vector<bool> m_mirror;
vector<string> m_alias;
unique_ptr<Thread> m_rxthread;
bool m_errorFlag = false;
string m_errorMsg;
bool m_syncstateflag = false;
vector<GPIO> m_gpios;
public:
GpioKeyChannel(string chname, vector<string> pins, vector<string> alias, vector<bool> mirror);
virtual string getChannelName() { return m_chname; }
void initialize();
virtual void senddata(bool binary, const char* data, size_t len) override;
virtual void registerOnDataCallback(OnData_t ondata) override;
virtual void callcmd(string cmd, unordered_map<string, string> param, json& receipt) override;
virtual json getChannelInfo() override;
virtual list<string> getCmdList();
private:
void execCmd(string cmd);
};
} // namespace iflytop

50
src/components/channel/idata_channel.hpp

@ -1,50 +0,0 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "thirdlib/nlohmann/json.hpp"
namespace iflytop {
using namespace nlohmann;
using namespace std;
class IDataChannel {
private:
/* data */
public:
typedef std::function<void(IDataChannel* ch, bool binary, const char* data, size_t len)> OnData_t;
string alias;
public:
virtual string getChannelName() = 0;
virtual list<string> getCmdList() = 0;
virtual void senddata(bool binary, const char* data, size_t len) = 0;
virtual void registerOnDataCallback(OnData_t ondata) = 0;
virtual void callcmd(string cmd, unordered_map<string, string> param, json& receipt) = 0;
virtual json getChannelInfo() = 0;
virtual ~IDataChannel() {}
virtual string getAlias() { return alias; }
virtual void setAlias(string alias) { this->alias = alias; }
protected:
string paramToString(const unordered_map<string, string>& param) {
string ret;
for (auto& [key, value] : param) {
ret += key + "=" + value + "&";
}
return ret;
}
};
} // namespace iflytop

200
src/components/channel/uart_channel.cpp

@ -1,200 +0,0 @@
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
//
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
//
#include <map>
#include <set>
#include <string>
#include "uart_channel.hpp"
#include "utils/stringutils.hpp"
using namespace nlohmann;
using namespace iflytop;
static map<int, uint32_t> g_baundmap = {
{0, 0000000}, {50, 0000001}, {75, 0000002}, {110, 0000003}, //
{134, 0000004}, {150, 0000005}, {200, 0000006}, {300, 0000007}, //
{600, 0000010}, {1200, 0000011}, {1800, 0000012}, {2400, 0000013}, //
{4800, 0000014}, {9600, 0000015}, {19200, 0000016}, {38400, 0000017}, //
{57600, 0010001}, {115200, 0010002}, {230400, 0010003}, {460800, 0010004}, //
{500000, 0010005}, {576000, 0010006}, {921600, 0010007}, {1000000, 0010010}, //
{1152000, 0010011}, {1500000, 0010012}, {2000000, 0010013}, {2500000, 0010014}, //
{3000000, 0010015}, {3500000, 0010016}, {4000000, 0010017},
};
int findBaudrate(int baudrate) {
auto baundrate_find_result = g_baundmap.find(baudrate);
if (baundrate_find_result == g_baundmap.end()) {
return -1;
}
return baundrate_find_result->second;
}
UartChannel::UartChannel(string chname, string ifname, int baudrate, bool hexch, int rxovertime) {
logger = LoggerFactory.createRotatingFileLogger(chname);
m_chname = chname;
m_ifname = ifname;
m_baudrate = baudrate;
m_hexch = hexch;
m_rxovertime = rxovertime;
if (m_rxovertime == 0) {
m_rxovertime = 1;
}
}
void UartChannel::initialize() {
m_uartHandler.name = (char*)m_ifname.c_str();
m_uartHandler.rate = findBaudrate(m_baudrate);
if (m_uartHandler.rate == -1) {
logger->error("unsupport baudrate:{}", m_baudrate);
m_errorFlag = true;
m_errorMsg = "unsupport baudrate";
return;
}
int suc = uartStart(&m_uartHandler);
if (suc != 0) {
logger->error("uartStart fail");
m_errorFlag = true;
m_errorMsg = "uart open fail";
return;
}
m_rxthread.reset(new Thread(fmt::format("{}-rxthread", m_chname), [this]() {
logger->info("{} rxthread start", m_chname);
ThisThread thisThread;
char rxcache[4096] = {0};
int rxlen = 0;
while (!thisThread.getExitFlag()) {
int ret = uartReceive(&m_uartHandler, &rxcache[rxlen], 1024); // send the received text over UART
if (ret < 0) {
logger->error("uartReceive fail, ret:{}", ret);
thisThread.sleepForMs(1000);
continue;
}
if (ret > 0) {
rxlen += ret;
::usleep(m_rxovertime * 1000);
continue;
}
if (rxlen != 0 && ret == 0) {
if (m_hexch) { // hex channel
string rxhexstr = StringUtils().bytesToString((uint8_t*)rxcache, rxlen);
logger->info("{} RX:-> {}({})", m_chname, rxhexstr, rxlen);
if (m_ondata) m_ondata(this, true, rxcache, rxlen);
} else { // str channel
string rxstr(rxcache, rxlen);
logger->info("{} RX:-> {}({})", m_chname, rxstr, rxlen);
if (m_ondata) m_ondata(this, false, rxcache, rxlen);
}
rxlen = 0;
}
::usleep(m_rxovertime * 1000);
//
} // end while
}));
return;
}
void UartChannel::senddata(bool binary, const char* data, size_t len) {
string txdata(data, len);
if ((m_hexch ^ binary)) {
logger->warn("{} Skip Tx | data format error, channel is a {} channel", m_chname, m_hexch ? "hex" : "str");
return;
}
if (m_errorFlag) {
logger->warn("{} Skip Tx, due to errorflag", m_chname, txdata, len);
return;
}
string txdatastr;
if (binary) {
txdatastr = StringUtils().bytesToString((uint8_t*)data, len);
} else {
txdatastr = txdata;
}
logger->info("{} TX:-> {}({})", m_chname, txdatastr, len);
int txlen = 0;
if (binary) {
txlen = uartSend(&m_uartHandler, (char*)data, len);
if (txlen != (int)len) logger->warn("tx fail");
} else {
txlen = uartSend(&m_uartHandler, txdatastr.c_str(), txdatastr.size());
if (txlen != (int)txdatastr.size()) logger->warn("tx fail");
}
}
void UartChannel::registerOnDataCallback(OnData_t ondata) { m_ondata = ondata; }
void UartChannel::callcmd(string cmd, unordered_map<string, string> param, json& receipt) {
logger->info("{} callcmd {} {}", m_chname, cmd, paramToString(param));
if (cmd == "setBaudrate") {
int rate = atoi(param["baudrate"].c_str());
if (rate == 0) {
logger->error("rate is 0");
receipt["status"] = -1;
receipt["msg"] = "rate is not support";
return;
}
int setrate = findBaudrate(rate);
if (setrate == -1) {
logger->error("unsupport baudrate:{}", m_baudrate);
receipt["status"] = -1;
receipt["msg"] = "unsupport baudrate";
return;
}
int suc = uartSetRate(&m_uartHandler, setrate);
if (suc != 0) {
logger->error("uartSetRate fail ,ecode = {}", strerror(errno));
receipt["status"] = -1;
receipt["msg"] = fmt::format("uartSetRate fail ,ecode = {}", strerror(errno));
return;
}
m_baudrate = rate;
receipt["status"] = 0;
receipt["msg"] = "ok";
} else if (cmd == "getBaudrate") {
receipt["status"] = 0;
receipt["data"]["baudrate"] = m_baudrate;
} else {
logger->error("unsupport cmd:{}", cmd);
receipt["status"] = -1;
receipt["msg"] = "unsupport cmd";
}
}
list<string> UartChannel::getCmdList() {
list<string> cmdlist;
return cmdlist;
}
json UartChannel::getChannelInfo() {
json info;
info["name"] = m_chname;
info["alias"] = getAlias();
info["type"] = "uart";
info["ifname"] = m_ifname;
info["baudrate"] = m_baudrate;
info["hexch"] = m_hexch;
info["rxovertime"] = m_rxovertime;
info["error"]["status"] = m_errorFlag;
info["error"]["msg"] = m_errorMsg;
return info;
}

54
src/components/channel/uart_channel.hpp

@ -1,54 +0,0 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "components/thread/thread.hpp"
#include "components/uart/uart.hpp"
#include "components/zcanreceiver/zcanreceiverhost.hpp"
#include "components/zservice_container/zservice_container.hpp"
#include "idata_channel.hpp"
namespace iflytop {
using namespace std;
using namespace nlohmann;
using namespace core;
class UartChannel : public IDataChannel {
private:
/* data */
iflytop::core::logger_t logger;
OnData_t m_ondata;
string m_chname;
string m_ifname;
int m_baudrate = 0;
int m_rxovertime = 3;
bool m_hexch = false;
struct UartDevice m_uartHandler;
unique_ptr<Thread> m_rxthread;
bool m_errorFlag = false;
string m_errorMsg;
public:
UartChannel(string chname, string ifname, int baudrate, bool hexch, int rxovertime);
virtual string getChannelName() { return m_chname; }
void initialize();
virtual void senddata(bool binary, const char* data, size_t len) override;
virtual void registerOnDataCallback(OnData_t ondata) override;
virtual void callcmd(string cmd, unordered_map<string, string> param, json& receipt) override;
virtual json getChannelInfo() override;
virtual list<string> getCmdList();
};
} // namespace iflytop

57
src/components/channel/zexcan_channel.cpp

@ -1,57 +0,0 @@
#include "zexcan_channel.hpp"
#include "utils/stringutils.hpp"
using namespace nlohmann;
using namespace iflytop;
ZExCanChannel::ZExCanChannel(string name, string can_if_name, int baudrate) {
logger = LoggerFactory.createRotatingFileLogger(name);
m_chname = name;
m_can_if_name = can_if_name;
m_baudrate = baudrate;
}
void ZExCanChannel::initialize() {
m_zcanreceiverhost.reset(new ZCanReceiverHost());
m_zcanreceiverhost->initialize(m_can_if_name, m_baudrate);
m_zcanreceiverhost->registerListener([this](uint8_t fromboardid, uint8_t* packet, size_t packetlen) {
string hexStr = StringUtils().bytesToString((uint8_t*)packet, packetlen);
logger->info("RX:<- {}({})", m_chname, hexStr, hexStr.size());
if (m_ondata) m_ondata(this, false, (const char*)hexStr.data(), hexStr.size());
});
}
void ZExCanChannel::senddata(bool binary, const char* data, size_t len) {
string txdata = string(data, len);
logger->info("{} TX:-> {}({})", m_chname, txdata, len);
vector<uint8_t> txbyte;
StringUtils().hexStringToBytes(txdata, "", txbyte);
m_zcanreceiverhost->sendPacket(txbyte.data(), txbyte.size());
}
void ZExCanChannel::registerOnDataCallback(OnData_t ondata) { m_ondata = ondata; }
void ZExCanChannel::callcmd(string cmd, unordered_map<string, string> param, json& receipt) {
logger->info("{} callcmd {} {}", m_chname, cmd, paramToString(param));
if (cmd == "restart") {
m_zcanreceiverhost->restartCanInterface();
}
}
list<string> ZExCanChannel::getCmdList() {
list<string> cmdlist;
cmdlist.push_back("restart");
return cmdlist;
}
json ZExCanChannel::getChannelInfo() {
json info;
info["name"] = m_chname;
info["alias"] = getAlias();
info["type"] = "zexcan";
info["ifname"] = m_can_if_name;
info["baudrate"] = m_baudrate;
return info;
}

47
src/components/channel/zexcan_channel.hpp

@ -1,47 +0,0 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "components/zcanreceiver/zcanreceiverhost.hpp"
#include "components/zservice_container/zservice_container.hpp"
#include "idata_channel.hpp"
namespace iflytop {
using namespace std;
using namespace nlohmann;
using namespace core;
class ZExCanChannel : public IDataChannel {
private:
/* data */
iflytop::core::logger_t logger;
shared_ptr<ZCanReceiverHost> m_zcanreceiverhost;
OnData_t m_ondata;
string m_chname;
string m_can_if_name;
int m_baudrate;
public:
ZExCanChannel(string name, string can_if_name, int baudrate);
virtual string getChannelName() { return m_chname; }
void initialize();
virtual void senddata(bool binary, const char* data, size_t len) override;
virtual void registerOnDataCallback(OnData_t ondata) override;
virtual void callcmd(string cmd, unordered_map<string, string> param, json& receipt) override;
virtual json getChannelInfo() override;
virtual list<string> getCmdList();
};
} // namespace iflytop

117
src/components/config_template/config_template.hpp

@ -1,117 +0,0 @@
//
// Created by zhaohe on 19-5-30.
//
#pragma once
#include <exception>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <string>
#include <vector>
// #include "zwtimecpp/core/core.hpp"
// #include "zwtimecpp/core/exception/base_exception.hpp"
// #include "zwtimecpp/core/exception/base_exception.hpp"
// #include "zwtimecpp/core/exception/null_expection.hpp"
// #include "zwtimecpp/core/logger/logger_factory.hpp"
// #include "zwtimecpp/core/utils/data.hpp"
#include "components/fileutils.hpp"
#include "components/marco/data.hpp"
#include "nlohmann/json.hpp"
#include "spdlogfactory/logger_factory.hpp"
#include "components/zexception/zexception.hpp"
// #include "zwtimecpp/core/utils/zmath.hpp"
// ConfigurationService的实现
/*----------------------------------------------------------------*/
#define ConfigServiceENABLE_GET_AND_SET2(type, propertyName, defaultValue) \
private: \
type propertyName = defaultValue; \
\
public: \
virtual const type &get_##propertyName() const { \
lock_guard<recursive_mutex> lock(lock_); \
return propertyName; \
} \
virtual void set_##propertyName(const type &propertyName) { \
lock_guard<recursive_mutex> lock(lock_); \
this->propertyName = propertyName; \
flushConfigToFile(); \
}
#define configTemplateGET_CONFIG2(type, propertyName, defaultValue) \
try { \
j3.at(#propertyName).get_to(propertyName); \
} catch (const std::exception &e) { \
onParseConfigFail(#propertyName, e); \
}
#define configTemplateSAVE_CONFIG2(type, propertyName, defaultValue) j[#propertyName] = propertyName;
#define configTemplateDEFILE_CONFIG_SERVICE2(name, configList, configfilePath, onParseFiale) \
namespace iflytop { \
using namespace std; \
using namespace core; \
using namespace nlohmann; \
class name { \
ENABLE_LOGGER(name) \
string configFile; \
\
mutable recursive_mutex lock_; \
bool forTest = false; \
\
public: \
name() {} \
\
public: \
void initialize(string configFile = configfilePath) { \
logger->debug("initialize"); \
\
this->configFile = configFile; \
json j3; \
\
string config; \
if (!FileUtils().exist(configFile)) { \
logger->error("can't find configfile ,create default config:{}", configFile); \
auto defaultConfigFile = FileUtils().openTrunc(configFile); \
defaultConfigFile->write("{}", 2); \
} \
config = FileUtils().readFileAsString(configFile); \
if (config.empty()) { \
flushConfigToFile(); \
config = FileUtils().readFileAsString(configFile); \
} \
\
try { \
j3 = json::parse(config); \
} catch (const std::exception &e) { \
throw zexception("Parse config fail......" + string(e.what())); \
} \
configList(configTemplateGET_CONFIG2); \
flushConfigToFile(); \
} \
configList(ConfigServiceENABLE_GET_AND_SET2); \
\
public: \
private: \
void flushConfigToFile() { \
json j; \
configList(configTemplateSAVE_CONFIG2); \
bool flushSuccess = FileUtils().writeToFile(configFile, j.dump(2)); \
if (!flushSuccess) { \
logger->error("flush config to logfile fail"); \
} \
}; \
static shared_ptr<name> &instance() { \
static shared_ptr<name> value; \
return value; \
} \
void onParseConfigFail(string file_name, const std::exception &e) { onParseFiale; }; \
}; \
}

161
src/components/uart/uart.cpp

@ -1,161 +0,0 @@
/*
* uart.c
*
* Created on: Aug 5, 2019
* Author: Cristian Fatu
* Implements basic UART functionality, over Uart Lite linux driver, using termios.
* After booting linux, a device like "/dev/ttyUL1" must be present.
* These functions work in both canonic and not canonic modes.
* In the canonic communication mode, the received chars can be retrieved by read only after \n is detected.
* In the non canonic communication mode, the received chars can be retrieved by read as they are received.
*/
#include "uart.hpp"
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
/*
Parameters:
struct UartDevice* dev - pointer to the UartDevice struct
unsigned char canonic - communication mode
1 - canonic communication (chars are only received after \n is detected).
0 - non canonic communication (chars are received as they arrive over UART).
Return value:
UART_FAILURE -1 failure
UART_SUCCESS 0 success
Description:
Initializes the UART device.
When calling the function, the device name (usually "/dev/ttyUL1") must be filled in dev->name and the baud rate must be filled in dev->rate.
The canonic function parameter indicates communication mode (canonic or not).
In the canonic communication mode, the received chars can be retrieved by read only after \n is detected.
In the non canonic communication mode, the received chars can be retrieved by read as they are received, as the non canonic mode is configured with no
wait.
*/
int uartStart(struct UartDevice* dev) {
struct termios* tty;
int fd;
fd = open(dev->name, O_RDWR | O_NOCTTY);
if (fd < 0) {
printf("%s: failed to open file descriptor for file %s\r\n", __func__, dev->name);
return UART_FAILURE;
}
tty = (struct termios*)calloc(1, sizeof(*dev->tty));
if (!tty) {
printf("%s: failed to allocate tty instance\r\n", __func__);
return UART_FAILURE;
}
dev->fd = fd;
dev->tty = tty;
return uartSetRate(dev, dev->rate);
}
int uartSetRate(struct UartDevice* dev, int rate) {
// memset(tty, 0, sizeof(struct termios));
/*
BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
CRTSCTS : output hardware flow control (only used if the cable has
all necessary lines. See sect. 7 of Serial-HOWTO)
CS8 : 8n1 (8bit,no parity,1 stopbit)
CLOCAL : local connection, no modem contol
CREAD : enable receiving characters
*/
// tty->c_cflag = dev->rate | CRTSCTS | CS8 | CLOCAL | CREAD;
dev->rate = rate;
dev->tty->c_cflag = dev->rate | CS8 | CLOCAL | CREAD;
// not canonic
/*
IGNPAR : ignore bytes with parity errorsc_cc[VTIME]
*/
dev->tty->c_iflag = IGNPAR;
/* set input mode (non-canonical, no echo,...) */
dev->tty->c_lflag = 0;
/* Do not wait for data */
dev->tty->c_cc[VTIME] = 0; /* inter-character timer unused */
dev->tty->c_cc[VMIN] = 0; /* blocking read until 5 chars received */
/*
Raw output.
*/
dev->tty->c_oflag = 0;
dev->rate = rate;
/* Flush port */
tcflush(dev->fd, TCIFLUSH);
/* Apply attributes */
int rc = tcsetattr(dev->fd, TCSANOW, dev->tty);
if (rc) {
printf("%s: failed to set TCSANOW attr\r\n", __func__);
return UART_FAILURE;
}
return UART_SUCCESS;
}
/*
Parameters:
struct UartDevice* dev - pointer to the UartDevice struct
char *data - pointer to the array of chars to be sent over UART
int size
positive value - number of chars to be sent over UART
-1 - indicates that all the chars until string terminator \0 will be sent
Return value:
number of chars sent over UART
Description:
This function sends a number of chars over UART.
If the size function parameter is -1 then all the characters until string terminator \0 will be sent.
*/
int uartSend(struct UartDevice* dev, const char* data, int size) {
int sent = 0;
if (size == -1) {
size = strlen(data);
}
sent = write(dev->fd, data, size);
#ifdef DEBUG
printf("%s: sent %d characters\r\n", __func__, sent);
#endif
return sent;
}
/*
Parameters:
struct UartDevice* dev - pointer to the UartDevice struct
char *data - pointer to the array of chars to hold the cars revceived over UART
int size_max - the maximum number of characters to be received
Return value:
number of chars received over UART
Description:
This function receives characters over UART.
In the canonic communication mode, the received chars will be retrieved by read only after \n is detected.
In the non canonic communication mode, the received chars will be retrieved by read as they are received, as the non canonic mode is configured with no
wait.
*/
int uartReceive(struct UartDevice* dev, char* data, int size_max) {
int received = 0;
#ifdef DEBUG
// printf("%s: receiving characters %d\r\n", __func__, size_max);
#endif
received = read(dev->fd, data, size_max - 1);
data[received] = '\0';
#ifdef DEBUG
// if(received > 0)
// printf("%s: received %d characters\r\n", __func__, received);
// else
// printf("%s: r%d/%d\r\n", __func__, received, size_max);
#endif
return received;
}
int uartStop(struct UartDevice* dev) {
free(dev->tty);
return UART_SUCCESS;
}

28
src/components/uart/uart.hpp

@ -1,28 +0,0 @@
/*
* uart.h
*
* Created on: Aug 5, 2019
* Author: cristian
*/
#include <termios.h>
#include <unistd.h>
#ifndef SRC_UART_H_
#define SRC_UART_H_
#define UART_FAILURE -1
#define UART_SUCCESS 0
// #define DEBUG
struct UartDevice {
char* name;
int rate;
int fd;
struct termios* tty;
};
int uartStart(struct UartDevice* dev);
int uartSend(struct UartDevice* dev, const char* data, int size);
int uartReceive(struct UartDevice* dev, char* data, int size_max);
int uartStop(struct UartDevice* dev);
int uartSetRate(struct UartDevice* dev,int rate);
#endif /* SRC_UART_H_ */

2
src/configs/version.hpp

@ -1,2 +1,2 @@
#pragma once
#define VERSION "2.4"
#define VERSION "1.0"

8
src/main.cpp

@ -1,15 +1,12 @@
#include <signal.h>
#include <sqlite3.h>
//
#include "configs/version.hpp"
#include "utils/stringutils.hpp"
#include "spdlogfactory/logger_factory.hpp"
//
//
#include "service/extapi_service.hpp"
//
#include "service/app_config_service.hpp"
using namespace iflytop;
using namespace core;
@ -26,8 +23,7 @@ int main(int argc, char *argv[]) {
spdlog::info("# version:{}", VERSION);
spdlog::info("#");
BUILD_AND_REG_SERRVICE(ExtAPIService);
GET_SERVICE(ExtAPIService)->initialize();
while (true) {
sleep(1);

9
src/service/app_config_service.cpp

@ -1,9 +0,0 @@
#include "app_config_service.hpp"
using namespace iflytop;
void AppConfigService::initialize() {
}

30
src/service/app_config_service.hpp

@ -1,30 +0,0 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <toml++/toml.hpp>
#include <vector>
//
#include "spdlogfactory/logger.hpp"
namespace iflytop {
using namespace std;
using namespace core;
class AppConfigService {
ENABLE_LOGGER(AppConfigService);
private:
/* data */
public:
void initialize();
};
} // namespace iflytop

214
src/service/extapi_service.cpp

@ -1,214 +0,0 @@
#include "extapi_service.hpp"
#include "configs/version.hpp"
#include "ixwebsocket/IXWebSocketServer.h"
#include "utils/stringutils.hpp"
#include "utils/urlparser.hpp"
#include "wbesocket_connect_mgr_service.hpp"
// #include "iflytop/components/zcanreceiver/zcanreceiverhost.hpp"
// #include "iflytop/core/components/stringutils.hpp"
// #include "iflytop/core/core.hpp"
#include <toml++/toml.hpp>
#include "components/channel/data_channel_mgr.hpp"
using namespace iflytop;
using namespace core;
using namespace std;
using namespace nlohmann;
using namespace ix;
namespace iflytop {};
void ExtAPIService::initialize() {
toml::table config;
int wsport = 0;
int cmdport = 0;
try {
config = toml::parse_file("config.ini");
cmdport = config["server"]["cmdport"].value_or(19004);
wsport = config["server"]["wsport"].value_or(19005);
} catch (const toml::parse_error &err) {
logger->error("parse config error, {}", err);
exit(1);
}
DataChannelMgr::initChannels(config);
logger->info("new httpServer listen on {}", cmdport);
m_httpServer.reset(new HttpServer(cmdport, "0.0.0.0"));
m_httpServer->setOnConnectionCallback( //
[this](HttpRequestPtr request, std::shared_ptr<ConnectionState> connectionState) -> HttpResponsePtr {
HTTP_URL httpurl = URLParser::Parse(request->uri);
json receipt;
receipt["status"] = 0;
receipt["msg"] = "success";
// path: /channelName/xxxxxx
if (httpurl.path.size() == 2) {
string channelName = httpurl.path[0];
string cmd = httpurl.path[1];
auto params = httpurl.query;
// path: /server/restart
if (channelName == "server") {
if (cmd == "restart") {
exit(0);
} else if (cmd == "getStatus" || cmd == "get-status") {
receipt["status"] = 0;
for (auto it : DataChannelMgr::getChannels()) {
if (it->getAlias().empty()) {
receipt["data"][it->getChannelName()] = it->getChannelInfo();
} else {
receipt["data"][it->getAlias()] = it->getChannelInfo();
}
}
} else if (cmd == "getVersion") {
receipt["status"] = 0;
receipt["data"]["version"] = VERSION;
} else if (cmd == "getConnections") {
receipt["status"] = 0;
receipt["data"] = WbesocketConnectMgrService::getConnectionList();
}
}
else {
auto channel = DataChannelMgr::findByChannel(channelName);
if (channel) {
channel->callcmd(cmd, params, receipt);
} else {
receipt["status"] = 1;
receipt["msg"] = "channel not found";
}
}
}
return std::make_shared<HttpResponse>(200, "", HttpErrorCode::Ok, WebSocketHttpHeaders(), receipt.dump(0));
});
if (!m_httpServer->listen().first) {
logger->error("httpServer listen failed");
exit(1);
}
m_httpServer->start();
/**
*
* protocol: websocket
* port : 19005
* descript: CAN数据
*
*/
logger->info("new webSocketServer listen on {}", wsport);
m_wsServer.reset(new WebSocketServer(wsport, "0.0.0.0"));
m_wsServer->setOnClientMessageCallback(
[this](std::shared_ptr<ix::ConnectionState> connectionState, ix::WebSocket &webSocket, const ix::WebSocketMessagePtr &msg) {
if (msg->type == ix::WebSocketMessageType::Open) {
logger->info("new connect ip: {}", connectionState->getRemoteIp());
// path: /channelName
logger->info(" uri: {}", msg->openInfo.uri);
webSocket.setUrl(msg->openInfo.uri);
logger->info(" headers:");
for (auto it : msg->openInfo.headers) {
logger->info("\t{}: {}", it.first, it.second);
}
string chname = webSocket.getUrl().substr(1);
static int id;
auto cinfo = make_shared<WebSocketConnectInfo>( //
msg->openInfo.uri, // url
connectionState->getRemoteIp(), // ip
chname, // chanme
fmt::format("{}{}({})", chname, id++, connectionState->getRemoteIp()) //
);
WbesocketConnectMgrService::insertNewClient(chname, findws(&webSocket), cinfo);
} else if (msg->type == ix::WebSocketMessageType::Message) {
string chname = webSocket.getUrl().substr(1);
auto channel = DataChannelMgr::findByChannel(chname);
if (channel) {
channel->senddata(msg->binary, msg->str.data(), msg->str.size());
} else {
logger->error("channel not found: {}", chname);
}
} else if (msg->type == ix::WebSocketMessageType::Close) {
string chname = webSocket.getUrl().substr(1);
logger->info("close connect ip: {},url: {}, channel:{}", connectionState->getRemoteIp(), webSocket.getUrl(), chname);
WbesocketConnectMgrService::removeClient(chname, findws(&webSocket));
}
});
// On Data From Channel
DataChannelMgr::regOnChannelData([this](IDataChannel *fromch, bool binary, const char *data, size_t len) {
list<shared_ptr<WebSocket>> clients;
WbesocketConnectMgrService::findClientByName(fromch->getChannelName(), clients);
WbesocketConnectMgrService::findClientByName(fromch->getAlias(), clients);
for (auto ch : clients) {
if (ch) {
shared_ptr<WebSocketConnectInfo> cinfo = WbesocketConnectMgrService::findwsinfo(ch);
WebSocketSendInfo sendInfo;
if (binary) {
sendInfo = ch->sendBinary(string(data, len));
} else {
sendInfo = ch->sendText(string(data, len));
}
if (sendInfo.success) {
logger->debug("send data to client {} {} success", cinfo->getConnUniqueId(), binary ? StringUtils().bytesToString(data, len) : string(data, len));
} else {
logger->error("send data to client {} failed", cinfo->getConnUniqueId());
}
}
}
});
if (!m_wsServer->listenAndStart()) {
logger->error("WebSocketServer listenAndStart failed");
exit(1);
}
//
logger->info("ExtAPIService initialize success");
logger->info("");
logger->info("");
logger->info("==================Support Channel List=================");
logger->info("=\t{}", "server");
logger->info("=\t http:/0.0.0.0:19004/{}/{}", "server", "get-status");
logger->info("=");
auto channels = DataChannelMgr::getChannels();
for (auto ch : channels) {
logger->info("=\t{}", ch->getChannelName());
logger->info("=\t ws://0.0.0.0:19905/{}", ch->getChannelName());
if (!ch->getAlias().empty()) {
logger->info("=\t alias_ws: ws://0.0.0.0:19905/{}", ch->getAlias());
}
for (auto cmd : ch->getCmdList()) {
logger->info("=\t http:/0.0.0.0:19004/{}/{}", ch->getChannelName(), cmd);
}
logger->info("=");
}
logger->info("======================================================");
};
shared_ptr<WebSocket> ExtAPIService::findws(WebSocket *ws) {
if (!ws) return nullptr;
auto clients = m_wsServer->getClients();
for (auto it : clients) {
if (it.get() == ws) {
return it;
}
}
return nullptr;
}

53
src/service/extapi_service.hpp

@ -1,53 +0,0 @@
//
// Created by zwsd
//
#pragma once
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
//
#include "components/zcanreceiver/zcanreceiverhost.hpp"
#include "components/zservice_container/zservice_container.hpp"
//
#include "ixwebsocket/IXHttp.h"
#include "ixwebsocket/IXHttpServer.h"
#include "ixwebsocket/IXWebSocketServer.h"
#include "spdlogfactory/logger.hpp"
//
//
#include <mutex>
/**
* @brief
*
* service:
*
*/
namespace iflytop {
using namespace std;
using namespace core;
using namespace ix;
class ExtAPIService {
ENABLE_LOGGER(ExtAPIService);
shared_ptr<ix::WebSocketServer> m_wsServer; // 19005
shared_ptr<HttpServer> m_httpServer; // 19004
public:
ExtAPIService() {};
void initialize();
private:
shared_ptr<WebSocket> findws(WebSocket* ws);
};
} // namespace iflytop

85
src/service/wbesocket_connect_mgr_service.cpp

@ -1,85 +0,0 @@
#include "wbesocket_connect_mgr_service.hpp"
using namespace iflytop;
using namespace core;
using namespace std;
using namespace nlohmann;
using namespace ix;
// static map<string,
static map<string, list<shared_ptr<WebSocket>>> wsClients;
static map<void *, shared_ptr<WebSocketConnectInfo>> wsClientsInfo;
static std::mutex wsClientsLock;
shared_ptr<WebSocketConnectInfo> WbesocketConnectMgrService::findwsinfo(shared_ptr<WebSocket> client) {
if (client == nullptr) return nullptr;
auto it = wsClientsInfo.find((void *)client.get());
if (it == wsClientsInfo.end()) return nullptr;
return it->second;
}
void WbesocketConnectMgrService::insertNewClient(string chname, shared_ptr<WebSocket> client, shared_ptr<WebSocketConnectInfo> connectInfo) {
lock_guard<mutex> lock(wsClientsLock);
if (client == nullptr) return;
if (chname.empty()) return;
if (wsClients.find(chname) == wsClients.end()) {
wsClients[chname] = list<shared_ptr<WebSocket>>();
}
wsClients[chname].push_back(client);
wsClientsInfo[(void *)client.get()] = connectInfo;
GET_LOGGER(WSConnectMgr)->info("new client: {} {}, channel: {}", client->getUrl(), (void *)client.get(), chname);
}
void WbesocketConnectMgrService::removeClient(string chname, shared_ptr<WebSocket> client) {
lock_guard<mutex> lock(wsClientsLock);
if (client == nullptr) {
return;
}
if (wsClients.find(chname) != wsClients.end()) {
wsClients[chname].remove(client);
wsClientsInfo.erase((void *)client.get());
GET_LOGGER(WSConnectMgr)->info("remove client: {} {}, channel: {}", client->getUrl(), (void *)client.get(), chname);
}
}
void WbesocketConnectMgrService::findClientByName(string chname, list<shared_ptr<WebSocket>> &clients) {
lock_guard<mutex> lock(wsClientsLock);
auto it = wsClients.find(chname);
if (it == wsClients.end()) {
return;
}
list<shared_ptr<WebSocket>> rmoveClients;
for (auto ch : it->second) {
if (ch->getReadyState() == ix::ReadyState::Closed || ch->getReadyState() == ix::ReadyState::Closing) {
rmoveClients.push_back(ch);
continue;
}
clients.push_back(ch);
}
for (auto ch : rmoveClients) {
it->second.remove(ch);
wsClientsInfo.erase((void *)ch.get());
GET_LOGGER(WSConnectMgr)->info("remove client: {} {}, channel: {}", ch->getUrl(), (void *)ch.get(), chname);
}
}
json WbesocketConnectMgrService::getConnectionList() {
lock_guard<mutex> lock(wsClientsLock);
json j;
for (auto it : wsClients) {
json jlist;
jlist["channelName"] = it.first;
for (auto ch : it.second) {
json chj;
chj["uri"] = ch->getUrl();
chj["ptr"] = (int64_t)(void *)ch.get();
chj["remoteIp"] = findwsinfo(ch) ? findwsinfo(ch)->getRemoteIp() : "null";
jlist["connections"].push_back(chj);
}
j.push_back(jlist);
}
return j;
}

65
src/service/wbesocket_connect_mgr_service.hpp

@ -1,65 +0,0 @@
//
// Created by zwsd
//
#pragma once
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
//
#include "components/zcanreceiver/zcanreceiverhost.hpp"
#include "components/zservice_container/zservice_container.hpp"
//
#include "ixwebsocket/IXHttp.h"
#include "ixwebsocket/IXHttpServer.h"
#include "ixwebsocket/IXWebSocketServer.h"
#include "spdlogfactory/logger.hpp"
//
//
#include <mutex>
namespace iflytop {
using namespace std;
using namespace nlohmann;
using namespace ix;
class WebSocketConnectInfo {
string url;
string remoteIp;
string chname;
string connUniqueId;
public:
WebSocketConnectInfo() {}
WebSocketConnectInfo(string url, string remoteIp, string chname, string connUniqueId) {
this->url = url;
this->remoteIp = remoteIp;
this->chname = chname;
this->connUniqueId = connUniqueId;
}
string getRemoteIp() { return remoteIp; }
string getUrl() { return url; }
string getChannelName() { return chname; }
string getConnUniqueId() { return connUniqueId; }
};
class WbesocketConnectMgrService {
public:
static void insertNewClient(string chname, shared_ptr<WebSocket> client, shared_ptr<WebSocketConnectInfo> connectInfo);
static void removeClient(string chname, shared_ptr<WebSocket> client);
static void findClientByName(string chname, list<shared_ptr<WebSocket>> &clients);
static json getConnectionList();
static void updateConnectList();
static shared_ptr<WebSocketConnectInfo> findwsinfo(shared_ptr<WebSocket> client);
};
} // namespace iflytop

14
tools/deply.sh

@ -8,10 +8,10 @@ if [ $# -ne 1 ]; then
fi
server=$1
ssh $server 'mkdir -p /iflytopd/iflytophald/'
ssh $server 'systemctl stop iflytophald'
scp ./build/app/iflytophald $server:/iflytopd/iflytophald/
# scp ./resources/iflytophald.service $server:/lib/systemd/system/
# scp ./resources/config.ini $server:/iflytopd/iflytophald/
scp ./resources/spd_logger_cfg.json $server:/iflytopd/iflytophald/
ssh $server 'systemctl start iflytophald'
ssh $server 'mkdir -p /iflytopd/iflytopzexcand/'
ssh $server 'systemctl stop iflytopzexcand'
scp ./build/app/iflytopzexcand $server:/iflytopd/iflytopzexcand/
# scp ./resources/iflytopzexcand.service $server:/lib/systemd/system/
# scp ./resources/config.ini $server:/iflytopd/iflytopzexcand/
scp ./resources/spd_logger_cfg.json $server:/iflytopd/iflytopzexcand/
ssh $server 'systemctl start iflytopzexcand'

6
tools/packet.sh

@ -10,17 +10,17 @@ if [ $# -ne 1 ]; then
fi
version=$1
packetname=iflytophald
packetname=iflytopzexcand
workdir=$(pwd)
echo "workdir: $workdir"
mkdir -p /tmp/$packetname
cp -r ./build/app/iflytophald /tmp/$packetname/
cp -r ./build/app/iflytopzexcand /tmp/$packetname/
cp -r ./resources/spd_logger_cfg.json /tmp/$packetname/
cp -r ./resources/*.ini /tmp/$packetname/
cp -r ./resources/iflytophald.service /tmp/$packetname/
cp -r ./resources/iflytopzexcand.service /tmp/$packetname/
echo "Version: $version" > /tmp/$packetname/version

Loading…
Cancel
Save