|
|
#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; }
|