You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
519 lines
13 KiB
C++
519 lines
13 KiB
C++
//
|
|
// Created by Matthew on 2023/12/27.
|
|
//
|
|
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/mman.h>
|
|
#include <unistd.h>
|
|
|
|
#include <climits>
|
|
|
|
#include "GPIOControl.h"
|
|
|
|
#ifdef _DEBUG
|
|
#include <AndroidHelper.h>
|
|
#endif
|
|
|
|
#define IOT_PARAM_WRITE 0xAE
|
|
#define IOT_PARAM_READ 0xAF
|
|
|
|
std::mutex GpioControl::m_locker;
|
|
std::mutex GpioControl::m_gpioLocker;
|
|
std::vector<GpioControl::ITEM> GpioControl::m_items;
|
|
bool GpioControl::m_cameraPowerStatus = false;
|
|
|
|
#define ENABLE_GPIO_TRACING
|
|
|
|
#ifdef ENABLE_GPIO_TRACING
|
|
class GpioDebugLogger
|
|
{
|
|
public:
|
|
GpioDebugLogger(int cmd, int value)
|
|
{
|
|
m_startTime = GetMicroTimeStamp();
|
|
m_path = std::string("/sdcard/com.xypower.mpapp/tmp/") + std::to_string(cmd) + std::string("_") + std::to_string(m_startTime) + "_val." + std::to_string(value);
|
|
|
|
CreateEmptyFile(m_path + ".enter");
|
|
}
|
|
|
|
GpioDebugLogger(int cmd)
|
|
{
|
|
m_startTime = GetMicroTimeStamp();
|
|
m_path = std::string("/sdcard/com.xypower.mpapp/tmp/") + std::to_string(cmd) + std::string("_") + std::to_string(m_startTime) + "_get";
|
|
|
|
CreateEmptyFile(m_path + ".enter");
|
|
}
|
|
|
|
~GpioDebugLogger()
|
|
{
|
|
uint64_t ts = (GetMicroTimeStamp() - m_startTime);
|
|
if (ts > 1000)
|
|
{
|
|
CreateEmptyFile(m_path + ".leave." + std::to_string(ts));
|
|
}
|
|
else
|
|
{
|
|
std::string path = m_path + ".enter";
|
|
std::remove(path.c_str());
|
|
}
|
|
}
|
|
|
|
private:
|
|
std::string m_path;
|
|
uint64_t m_startTime;
|
|
};
|
|
#endif
|
|
|
|
size_t GpioControl::turnOnImpl(const IOT_PARAM& param)
|
|
{
|
|
size_t oldRef = 0;
|
|
size_t references = 1;
|
|
std::vector<ITEM>::iterator it;
|
|
int res = 0;
|
|
int fd = -1;
|
|
time_t now = time(NULL);
|
|
|
|
// check res???
|
|
for (it = m_items.begin(); it != m_items.end(); ++it)
|
|
{
|
|
if (it->cmd == param.cmd)
|
|
{
|
|
oldRef = it->references;
|
|
it->references++;
|
|
// it->closeTime = 0;
|
|
references = it->references;
|
|
if(it->openTime == 0)
|
|
it->openTime = now;
|
|
SetCamerastatus(it->cmd, true);
|
|
break;
|
|
}
|
|
}
|
|
if (it == m_items.end())
|
|
{
|
|
oldRef = 0;
|
|
ITEM item = {param.cmd, references, now};
|
|
m_items.push_back(item);
|
|
SetCamerastatus(param.cmd, true);
|
|
}
|
|
|
|
if (oldRef == 0/* || param.cmd != CMD_SET_3V3_PWR_EN*/)
|
|
{
|
|
#ifdef ENABLE_GPIO_TRACING
|
|
GpioDebugLogger logger(param.cmd, param.value);
|
|
#endif
|
|
m_gpioLocker.lock();
|
|
fd = open(GPIO_NODE_MP, O_RDONLY);
|
|
if( fd > 0 )
|
|
{
|
|
res = ioctl(fd, IOT_PARAM_WRITE, ¶m);
|
|
close(fd);
|
|
#ifdef OUTPUT_DBG_INFO
|
|
// int realVal = getInt(param.cmd);
|
|
// XYLOG(XYLOG_SEVERITY_INFO, "setInt cmd=%d,value=%d,result=%d RealVal=%d",param.cmd, param.value, param.result/*, realVal*/);
|
|
XYLOG(XYLOG_SEVERITY_DEBUG, "setInt cmd=%d,value=%d,result=%d",param.cmd, param.value, param.result);
|
|
#endif
|
|
}
|
|
m_gpioLocker.unlock();
|
|
#ifdef _DEBUG
|
|
ALOGI("PWR TurnOn cmd=%d,result=%d ref=%u\r\n",param.cmd, param.result, (uint32_t)references);
|
|
#endif
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
}
|
|
|
|
return references;
|
|
}
|
|
|
|
void GpioControl::setInt(int cmd, int value)
|
|
{
|
|
IOT_PARAM param = { cmd, value, 0 };
|
|
// param.cmd = cmd;
|
|
// param.value = value;
|
|
|
|
#ifdef ENABLE_GPIO_TRACING
|
|
GpioDebugLogger logger(cmd, value);
|
|
#endif
|
|
m_gpioLocker.lock();
|
|
int fd = open(GPIO_NODE_MP, O_RDONLY);
|
|
if (fd > 0)
|
|
{
|
|
int res = ioctl(fd, IOT_PARAM_WRITE, ¶m);
|
|
close(fd);
|
|
#ifdef OUTPUT_DBG_INFO
|
|
// int realVal = getInt(param.cmd);
|
|
// XYLOG(XYLOG_SEVERITY_INFO, "setInt cmd=%d,value=%d,result=%d RealVal=%d",param.cmd, value, param.result/*, realVal*/);
|
|
XYLOG(XYLOG_SEVERITY_DEBUG, "setInt cmd=%d,value=%d,result=%d",param.cmd, value, param.result);
|
|
#endif
|
|
}
|
|
m_gpioLocker.unlock();
|
|
}
|
|
|
|
int GpioControl::getInt(int cmd)
|
|
{
|
|
#ifdef ENABLE_GPIO_TRACING
|
|
GpioDebugLogger logger(cmd);
|
|
#endif
|
|
m_gpioLocker.lock();
|
|
int fd = open(GPIO_NODE_MP, O_RDONLY);
|
|
// LOGE("get_int fd=%d,cmd=%d\r\n",fd, cmd);
|
|
if( fd > 0 )
|
|
{
|
|
IOT_PARAM param;
|
|
param.cmd = cmd;
|
|
ioctl(fd, IOT_PARAM_READ, ¶m);
|
|
#ifdef _DEBUG
|
|
ALOGI("getInt cmd=%d,value=%d,result=%d",param.cmd, param.value, param.result);
|
|
#endif
|
|
close(fd);
|
|
m_gpioLocker.unlock();
|
|
return param.value;
|
|
}
|
|
m_gpioLocker.unlock();
|
|
return -1;
|
|
}
|
|
|
|
void GpioControl::setLong(int cmd, long value)
|
|
{
|
|
IOT_PARAM param;
|
|
param.cmd = cmd;
|
|
param.value2 = value;
|
|
// LOGE("set_long fd=%d,cmd=%d,value2=%ld\r\n",fd, param.cmd, param.value2);
|
|
|
|
m_gpioLocker.lock();
|
|
int fd = open(GPIO_NODE_MP, O_RDONLY);
|
|
if( fd > 0 )
|
|
{
|
|
ioctl(fd, IOT_PARAM_WRITE, ¶m);
|
|
// LOGE("set_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
|
|
close(fd);
|
|
}
|
|
m_gpioLocker.unlock();
|
|
}
|
|
|
|
long GpioControl::getLong(int cmd)
|
|
{
|
|
m_gpioLocker.lock();
|
|
int fd = open(GPIO_NODE_MP, O_RDONLY);
|
|
// LOGE("get_long fd=%d,cmd=%d\r\n",fd, cmd);
|
|
if( fd > 0 )
|
|
{
|
|
IOT_PARAM param;
|
|
param.cmd = cmd;
|
|
ioctl(fd, IOT_PARAM_READ, ¶m);
|
|
// LOGE("get_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
|
|
close(fd);
|
|
m_gpioLocker.unlock();
|
|
return param.value2;
|
|
}
|
|
m_gpioLocker.unlock();
|
|
return -1;
|
|
}
|
|
|
|
void GpioControl::setString(int cmd, const std::string& value)
|
|
{
|
|
IOT_PARAM param;
|
|
param.cmd = cmd;
|
|
memset(param.str, 0, MAX_STRING_LEN);
|
|
int len = MAX_STRING_LEN < value.size() ? MAX_STRING_LEN : value.size();
|
|
memcpy(param.str, value.c_str(), len);
|
|
// LOGE("set_string fd=%d,cmd=%d,str=%s\r\n",fd, param.cmd, param.str);
|
|
|
|
m_gpioLocker.lock();
|
|
int fd = open(GPIO_NODE_MP, O_RDONLY);
|
|
if( fd > 0 )
|
|
{
|
|
ioctl(fd, IOT_PARAM_WRITE, ¶m);
|
|
// LOGE("set_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
|
|
close(fd);
|
|
}
|
|
m_gpioLocker.unlock();
|
|
return;
|
|
}
|
|
|
|
std::string GpioControl::getString(int cmd)
|
|
{
|
|
m_gpioLocker.lock();
|
|
int fd = open(GPIO_NODE_MP, O_RDONLY);
|
|
// LOGE("get_string fd=%d,cmd=%d\r\n",fd, cmd);
|
|
if( fd > 0 )
|
|
{
|
|
IOT_PARAM param;
|
|
param.cmd = cmd;
|
|
ioctl(fd, IOT_PARAM_READ, ¶m);
|
|
// LOGE("get_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
|
|
close(fd);
|
|
m_gpioLocker.unlock();
|
|
return std::string(param.str);
|
|
}
|
|
m_gpioLocker.unlock();
|
|
return "";
|
|
}
|
|
|
|
/////////////////////////// Power Control /////////////////////////////////
|
|
|
|
size_t GpioControl::TurnOn(int cmd)
|
|
{
|
|
IOT_PARAM param = { cmd, 1, 0 };
|
|
// param.cmd = cmd;
|
|
// param.value = value;
|
|
|
|
m_locker.lock();
|
|
size_t ref = turnOnImpl(param);
|
|
m_locker.unlock();
|
|
return ref;
|
|
}
|
|
|
|
size_t GpioControl::TurnOn(const std::vector<int>& cmds)
|
|
{
|
|
IOT_PARAM param = { 0, 1, 0 };
|
|
// param.cmd = cmd;
|
|
// param.value = value;
|
|
|
|
std::vector<int>::const_iterator it;
|
|
m_locker.lock();
|
|
for (it = cmds.cbegin(); it != cmds.cend(); ++it)
|
|
{
|
|
if (*it == 0)
|
|
{
|
|
continue;
|
|
}
|
|
param.cmd = *it;
|
|
turnOnImpl(param);
|
|
}
|
|
m_locker.unlock();
|
|
|
|
return 0;
|
|
}
|
|
|
|
size_t GpioControl::TurnOffImmediately(int cmd)
|
|
{
|
|
time_t ts = time(NULL);
|
|
size_t ref = 0;
|
|
std::vector<ITEM>::iterator it;
|
|
m_locker.lock();
|
|
for (it = m_items.begin(); it != m_items.end(); ++it)
|
|
{
|
|
if (it->cmd == cmd)
|
|
{
|
|
if (it->references > 0)
|
|
{
|
|
it->references = 0;
|
|
SetCamerastatus(cmd, false);
|
|
setInt(it->cmd, 0);
|
|
it->openTime = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
m_locker.unlock();
|
|
#ifdef _DEBUG
|
|
ALOGI("PWR TurnOffNow cmd=%d ref=%u", cmd, (uint32_t)ref);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
size_t GpioControl::TurnOff(int cmd, uint32_t delayedCloseTime/* = 0*/)
|
|
{
|
|
time_t ts = 0;
|
|
if (delayedCloseTime > 0)
|
|
{
|
|
ts = time(NULL) + delayedCloseTime;
|
|
}
|
|
size_t ref = 0;
|
|
std::vector<ITEM>::iterator it;
|
|
|
|
if (delayedCloseTime > 0)
|
|
{
|
|
std::shared_ptr<PowerControl> powerCtrl = std::make_shared<PowerControl>(cmd);
|
|
std::thread th([delayedCloseTime, powerCtrl]() mutable {
|
|
std::this_thread::sleep_for(std::chrono::seconds(delayedCloseTime));
|
|
powerCtrl.reset();
|
|
});
|
|
th.detach();
|
|
}
|
|
|
|
m_locker.lock();
|
|
for (it = m_items.begin(); it != m_items.end(); ++it)
|
|
{
|
|
if (it->cmd == cmd)
|
|
{
|
|
if (it->references > 0)
|
|
{
|
|
it->references--;
|
|
if (it->references == 0)
|
|
{
|
|
SetCamerastatus(cmd, false);
|
|
setInt(it->cmd, 0);
|
|
it->openTime = 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
m_locker.unlock();
|
|
#ifdef _DEBUG
|
|
ALOGI("PWR TurnOff cmd=%d ref=%u", cmd, (uint32_t)ref);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
size_t GpioControl::TurnOff(const std::vector<int>& cmds, uint32_t delayedCloseTime/* = 0*/)
|
|
{
|
|
time_t ts = 0;
|
|
if (delayedCloseTime > 0)
|
|
{
|
|
ts = time(NULL) + delayedCloseTime;
|
|
}
|
|
std::vector<ITEM>::iterator it;
|
|
std::vector<int>::const_reverse_iterator itCmd;
|
|
|
|
if (delayedCloseTime > 0)
|
|
{
|
|
std::shared_ptr<PowerControl> powerCtrl = std::make_shared<PowerControl>(cmds);
|
|
std::thread th([delayedCloseTime, powerCtrl]() mutable {
|
|
std::this_thread::sleep_for(std::chrono::seconds(delayedCloseTime));
|
|
powerCtrl.reset();
|
|
});
|
|
th.detach();
|
|
}
|
|
|
|
m_locker.lock();
|
|
// turnOnImpl(param);
|
|
for (itCmd = cmds.crbegin(); itCmd != cmds.crend(); ++itCmd)
|
|
{
|
|
for (it = m_items.begin(); it != m_items.end(); ++it)
|
|
{
|
|
if (it->cmd == *itCmd)
|
|
{
|
|
if (it->references > 0)
|
|
{
|
|
it->references--;
|
|
if (it->references == 0)
|
|
{
|
|
SetCamerastatus(it->cmd, false);
|
|
setInt(it->cmd, 0);
|
|
it->openTime = 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
m_locker.unlock();
|
|
|
|
return 0;
|
|
}
|
|
|
|
size_t GpioControl::TurnOff(const std::vector<std::pair<int, uint32_t> >& cmds)
|
|
{
|
|
for (auto itCmd = cmds.cbegin(); itCmd != cmds.end(); ++itCmd)
|
|
{
|
|
if (itCmd->second > 0)
|
|
{
|
|
uint32_t delayedCloseTime = itCmd->second;
|
|
std::shared_ptr<PowerControl> powerCtrl = std::make_shared<PowerControl>(itCmd->first);
|
|
std::thread th([delayedCloseTime, powerCtrl]() mutable {
|
|
std::this_thread::sleep_for(std::chrono::seconds(delayedCloseTime));
|
|
powerCtrl.reset();
|
|
});
|
|
th.detach();
|
|
}
|
|
}
|
|
|
|
std::vector<ITEM>::iterator it;
|
|
std::vector<std::pair<int, uint32_t> >::const_iterator itCmd;
|
|
m_locker.lock();
|
|
for (itCmd = cmds.cbegin(); itCmd != cmds.end(); ++itCmd)
|
|
{
|
|
for (it = m_items.begin(); it != m_items.end(); ++it)
|
|
{
|
|
if (it->cmd == itCmd->first)
|
|
{
|
|
if (it->references > 0)
|
|
{
|
|
it->references--;
|
|
if (it->references == 0)
|
|
{
|
|
SetCamerastatus(it->cmd, false);
|
|
setInt(it->cmd, 0);
|
|
it->openTime = 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
m_locker.unlock();
|
|
|
|
return 0;
|
|
}
|
|
bool GpioControl::SetCamerastatus(int cmd, bool status)
|
|
{
|
|
#ifdef USING_N938
|
|
if(cmd == CMD_SET_PIC1_POWER)
|
|
m_cameraPowerStatus = status;
|
|
#endif
|
|
#ifdef USING_PTZ
|
|
if(cmd == CMD_SET_PTZ_PWR_ENABLE)
|
|
{
|
|
m_cameraPowerStatus = status;
|
|
}
|
|
|
|
#endif
|
|
return true;
|
|
}
|
|
bool GpioControl::GetCamerastatus()
|
|
{
|
|
return m_cameraPowerStatus;
|
|
}
|
|
|
|
bool GpioControl::GetSelftestStatus(time_t wait_time)
|
|
{
|
|
int cmd = 0;
|
|
#ifdef USING_N938
|
|
cmd = CMD_SET_PIC1_POWER;
|
|
#endif
|
|
#ifdef USING_PTZ
|
|
cmd = CMD_SET_PTZ_PWR_ENABLE;
|
|
#endif
|
|
time_t now = time(NULL);
|
|
std::vector<ITEM>::iterator it;
|
|
for (it = m_items.begin(); it != m_items.end(); ++it)
|
|
{
|
|
if (it->cmd == cmd && it->references > 0 && it->openTime!=0 && (now - it->openTime >= wait_time))
|
|
{
|
|
return true;//自检完成
|
|
}
|
|
}
|
|
return false;
|
|
|
|
}
|
|
|
|
time_t GpioControl::GetSelfTestRemain(time_t wait_time)
|
|
{
|
|
int cmd = 0;
|
|
#ifdef USING_N938
|
|
cmd = CMD_SET_PIC1_POWER;
|
|
#endif
|
|
#ifdef USING_PTZ
|
|
cmd = CMD_SET_PTZ_PWR_ENABLE;
|
|
#endif
|
|
time_t now = time(NULL);
|
|
std::vector<ITEM>::iterator it;
|
|
for (it = m_items.begin(); it != m_items.end(); ++it)
|
|
{
|
|
if (it->cmd == cmd && it->references > 0)
|
|
{
|
|
time_t remaintime = (now - it->openTime);
|
|
remaintime = (wait_time > remaintime) ? (wait_time - remaintime) : 0;
|
|
return remaintime;//自检完成
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|