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.
TermApp/app/src/main/cpp/GPIOControl.cpp

494 lines
12 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"
4 months ago
#include <LogThread.h>
1 year ago
#ifdef _DEBUG
#include <AndroidHelper.h>
#endif
#define IOT_PARAM_WRITE 0xAE
#define IOT_PARAM_READ 0xAF
std::mutex GpioControl::m_locker;
CSemaphore GpioControl::m_semaphore;
std::vector<GpioControl::ITEM> GpioControl::m_items;
std::thread GpioControl::m_thread;
bool GpioControl::m_exitSignal = false;
bool GpioControl::m_cameraPowerStatus = false;
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, 0, 0, now};
m_items.push_back(item);
SetCamerastatus(param.cmd, true);
}
if (oldRef == 0)
{
fd = open(GPIO_NODE_MP, O_RDONLY);
if( fd > 0 )
{
res = ioctl(fd, IOT_PARAM_WRITE, &param);
close(fd);
#ifdef OUTPUT_DBG_INFO
XYLOG(XYLOG_SEVERITY_INFO, "setInt cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
#endif
}
7 months ago
#ifdef _DEBUG
ALOGI("PWR TurnOn cmd=%d,result=%d ref=%u\r\n",param.cmd, param.result, (uint32_t)references);
7 months ago
#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;
int fd = open(GPIO_NODE_MP, O_RDONLY);
if (fd > 0)
{
int res = ioctl(fd, IOT_PARAM_WRITE, &param);
close(fd);
4 months ago
#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);
#endif
}
}
int GpioControl::getInt(int cmd)
{
10 months ago
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, &param);
1 year ago
#ifdef _DEBUG
ALOGI("getInt cmd=%d,value=%d,result=%d",param.cmd, param.value, param.result);
1 year ago
#endif
close(fd);
return param.value;
}
return -1;
}
void GpioControl::setLong(int cmd, long value)
{
10 months ago
int fd = open(GPIO_NODE_MP, O_RDONLY);
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);
if( fd > 0 )
{
ioctl(fd, IOT_PARAM_WRITE, &param);
// LOGE("set_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
close(fd);
}
}
long GpioControl::getLong(int cmd)
{
10 months ago
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, &param);
// LOGE("get_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
close(fd);
return param.value2;
}
return -1;
}
void GpioControl::setString(int cmd, const std::string& value)
{
IOT_PARAM param;
10 months ago
int fd = open(GPIO_NODE_MP, O_RDONLY);
int len = MAX_STRING_LEN < value.size() ? MAX_STRING_LEN : value.size();
param.cmd = cmd;
memset(param.str, 0, MAX_STRING_LEN);
memcpy(param.str, value.c_str(), len);
// LOGE("set_string fd=%d,cmd=%d,str=%s\r\n",fd, param.cmd, param.str);
if( fd > 0 )
{
ioctl(fd, IOT_PARAM_WRITE, &param);
// LOGE("set_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
close(fd);
}
return;
}
std::string GpioControl::getString(int cmd)
{
10 months ago
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, &param);
// LOGE("get_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
close(fd);
return std::string(param.str);
}
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)
{
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)
{
ref = it->references;
it->closeCmds++;
it->closeTime = ts;
break;
}
}
m_locker.unlock();
m_semaphore.release();
#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;
m_locker.lock();
for (it = m_items.begin(); it != m_items.end(); ++it)
{
if (it->cmd == cmd)
{
ref = it->references;
it->closeCmds++;
if (ts > it->closeTime)
{
it->closeTime = ts;
}
break;
}
}
m_locker.unlock();
m_semaphore.release();
7 months ago
#ifdef _DEBUG
ALOGI("PWR TurnOff cmd=%d ref=%u", cmd, (uint32_t)ref);
7 months ago
#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;
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)
{
it->closeCmds++;
if (ts > it->closeTime)
{
it->closeTime = ts;
}
break;
}
}
}
m_locker.unlock();
m_semaphore.release();
7 months ago
return 0;
}
size_t GpioControl::TurnOff(const std::vector<std::pair<int, uint32_t> >& cmds)
{
time_t ts = time(NULL);
time_t ts2;
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)
{
it->closeCmds++;
if (itCmd->second != 0)
{
ts2 = itCmd->second + ts;
if (ts2 > it->closeTime)
{
it->closeTime = ts2;
}
}
break;
}
}
}
m_locker.unlock();
m_semaphore.release();
return 0;
}
bool GpioControl::SetCamerastatus(int cmd, bool status)
{
#ifdef USING_N938
if(cmd == CMD_SET_PIC1_POWER)
m_cameraPowerStatus = status;
#endif
#ifdef USING_PLZ
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;
#ifdef USING_N938
cmd = CMD_SET_PIC1_POWER;
#endif
#ifdef USING_PLZ
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->openTime!=0 && (now - it->openTime >= wait_time))
{
return true;//自检完成
}
}
return false;
}
void GpioControl::PowerControlThreadProc()
{
time_t ts = 0;
std::vector<ITEM>::iterator it;
std::vector<int> items;
time_t minDelayTime = 0;
time_t delayTime = 0;
int fd = -1;
int res = -1;
m_cameraPowerStatus = 0;
while(1)
{
// Check if there is close cmd
ts = time(NULL);
minDelayTime = std::numeric_limits<time_t>::max();
m_locker.lock();
for (it = m_items.begin(); it != m_items.end(); ++it)
{
if (it->references == 0 && it->closeCmds == 0 && it->closeTime == 0)
{
#ifdef _DEBUG
ALOGI("PWR THREAD cmd=%d ref=%u closeCmds=%u", it->cmd, (uint32_t)it->references, (uint32_t)it->closeCmds);
#endif
continue;
}
if (it->closeCmds > 0)
{
if (it->references <= it->closeCmds)
{
it->references = 0;
}
else
{
it->references -= it->closeCmds;
if(it->references < 0)
it->references = 0;
}
it->closeCmds = 0;
}
if (it->references == 0)
{
// Should turn off the power
if ((it->closeTime == 0) || (it->closeTime <= ts))
{
// close it directly
setInt(it->cmd, 0);
it->closeTime = 0;
it->openTime = 0;
#ifdef _DEBUG
ALOGI("PWR THREAD DO TurnOff cmd=%d", it->cmd);
#endif
SetCamerastatus(it->cmd, false);
}
else
{
// Check Time
delayTime = ts - it->closeTime;
if (delayTime < minDelayTime)
{
minDelayTime = delayTime;
}
}
}
#ifdef _DEBUG
ALOGI("PWR THREAD cmd=%d ref=%u closeCmds=%u", it->cmd, (uint32_t)it->references, (uint32_t)it->closeCmds);
#endif
}
m_locker.unlock();
if (minDelayTime < std::numeric_limits<time_t>::max())
{
m_semaphore.try_acquire_for(std::chrono::seconds(1));
}
else
{
m_semaphore.acquire();
}
if (m_exitSignal)
{
break;
}
}
}
bool GpioControl::Startup()
{
// if (m_thread.)
m_exitSignal = false;
m_thread = std::thread(PowerControlThreadProc);
#ifdef _DEBUG
pthread_t nativeHandle = m_thread.native_handle();
pthread_setname_np(nativeHandle, "gpioclose");
#endif
return true;
}
void GpioControl::Stop()
{
// Notify
m_exitSignal = true;
m_semaphore.release();
m_thread.detach();
7 months ago
}