You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
4.3 KiB
160 lines
4.3 KiB
|
|
#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;
|
|
}
|