rk3399_arm_lvds/scanservice/main.cpp

249 lines
5.0 KiB
C++

#include <iostream>
#include <iomanip>
#include <memory>
#include <thread>
#include <chrono>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <sys/file.h>
#include "filetools.h"
#include "stringex.hpp"
#include <functional>
#include "usbservice.h"
#include "ICapturer.h"
#include "Capturer.h"
#include "MonoCapturer.h"
#include "MultiFrameCapture.h"
#include "MultiFrameCapture_8458Color.h"
#include "MultiFrameCapture_8478_HL.h"
#include "motorboard.h"
#include "itransmit.h"
#include "scannerregs.h"
#include "scanner.h"
#include "inotify.h"
#include "memoryex.h"
#include "usbimageprocqueue.h"
#include "imageusbtesthandler.h"
#include "applog.h"
#include "jsonconfig.h"
#include "wakeup.hpp"
#include "StopWatch.h"
using namespace std;
#define MY_PID_FILE "/tmp/scanservice_pid"
#define BUF_LEN_FOR_PID 64
static int write_pid_into_fd(int fd, pid_t pid)
{
int ret = -1;
char buf[BUF_LEN_FOR_PID] = {0};
/* Move cursor to the start of file. */
lseek(fd, 0, SEEK_SET);
sprintf(buf, "%d", pid);
ret = write(fd, buf, strlen(buf));
if (ret <= 0)
{ /* Write fail or write 0 byte */
if (ret == -1)
perror("Write " MY_PID_FILE " fail\n");
ret = -1;
}
else
{
printf("Create " MY_PID_FILE " ok, pid=%d\n", pid);
ret = 0;
}
return ret;
}
static int create_pid_file(pid_t pid)
{
int fd, ret;
char buf[BUF_LEN_FOR_PID] = {0};
fd = open(MY_PID_FILE, O_WRONLY | O_CREAT | O_EXCL, 0666); /* rw-rw-rw- */
if (fd == -1)
{
perror("Create " MY_PID_FILE " fail\n");
return -1;
}
ret = flock(fd, LOCK_EX);
if (ret == -1)
{
perror("flock " MY_PID_FILE " fail\n");
close(fd);
return -1;
}
ret = write_pid_into_fd(fd, pid);
flock(fd, LOCK_UN);
close(fd);
return ret;
}
static int check_pid_file(int fd, pid_t pid)
{
int ret = -1;
pid_t old_pid;
char buf[BUF_LEN_FOR_PID] = {0};
ret = flock(fd, LOCK_EX);
if (ret == -1)
{
perror("flock " MY_PID_FILE " fail\n");
return -1;
}
ret = read(fd, buf, sizeof(buf) - 1);
if (ret < 0)
{ /* read error */
perror("read from " MY_PID_FILE " fail\n");
ret = -1;
}
else if (ret > 0)
{ /* read ok */
old_pid = atol(buf);
/* Check if old_pid is running */
ret = kill(old_pid, 0);
if (ret < 0)
{
if (errno == ESRCH)
{ /* old_pid is not running. */
ret = write_pid_into_fd(fd, pid);
}
else
{
perror("send signal fail\n");
ret = -1;
}
}
else
{ /* running */
printf("Program already exists, pid=%d\n", old_pid);
ret = -1;
}
}
else if (ret == 0)
{ /* read 0 byte from file */
ret = write_pid_into_fd(fd, pid);
}
flock(fd, LOCK_UN);
return ret;
}
static int init_pid_file()
{
pid_t pid;
int fd, ret;
pid = getpid();
fd = open(MY_PID_FILE, O_RDWR);
if (fd == -1)
{ /* open file fail */
if (errno == ENOENT)
{ /* No such file. Create one for this program. */
ret = create_pid_file(pid);
}
else
{
perror("open " MY_PID_FILE " fail\n");
ret = -1;
}
}
else
{ /* pid file already exists */
ret = check_pid_file(fd, pid);
close(fd);
}
return ret;
}
static void sigHandler(int sig)
{
if (sig == SIGINT || sig == SIGTERM)
remove(MY_PID_FILE);
printf("exit now \n");
_exit(0);
}
int main()
{
if (-1 == init_pid_file())
{
exit(-1);
}
/* Ctrl + C */
if (signal(SIGINT, sigHandler) == SIG_ERR)
{
exit(-1);
}
/* kill pid / killall name */
if (signal(SIGTERM, sigHandler) == SIG_ERR)
{
exit(-1);
}
auto wake = std::shared_ptr<WakeUp>(new WakeUp());
// auto cap = std::shared_ptr<ICapturer>(new MonoCapturer());
auto cap = std::shared_ptr<ICapturer>(new MultiFrameCapture());
// auto cap = std::shared_ptr<ICapturer>(new MultiFrameCapture_8458Color());
// auto cap = std::shared_ptr<ICapturer>(new MultiFrameCapture_8478_HL());
auto mt = std::shared_ptr<MotorBoard>(new MotorBoard(wake));
wake->setinitcallback([&mt,&cap]{
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
cap->Fpga_regsAccess_reset(true);
//cap->reset();
mt->init_statecontrol();
},[&mt,&cap]{
mt->release_statecontrol();
cap->Fpga_regsAccess_reset(false);
});
if(wake->get_status() == 0)
{
cap->Fpga_regsAccess_reset(false);
mt->release_statecontrol();
}
auto scanner = std::shared_ptr<Scanner>(new Scanner(cap, mt,wake));
UsbService us(cap->regs(), mt->regs());
auto usbhotplugcall = [&](bool connect){
if(connect){
printf("\nUSB Connect\n");
}else
{
scanner->stop_scan();
mt->release_statecontrol();
printf("USB Disconnect Scanner STOP SCAN\n");
exit(0);
}
};
us.set_onconnect_call(usbhotplugcall);
auto notify = us.notify();
std::shared_ptr<UsbImageProcQueue> usbImage(new UsbImageProcQueue(notify));
auto transfer = us.transmiter();
auto receiver = us.receiver();
std::shared_ptr<IRegsAccess> regs = std::shared_ptr<IRegsAccess>(new ScannerRegAccess(scanner, usbImage, transfer,receiver));
scanner->set_imagehandler(std::shared_ptr<IImageHandler>(new ImageUsbHandler(usbImage)));
us.set_scannerregs(regs);
while(1) {std::this_thread::sleep_for(std::chrono::milliseconds(2000));}
return 0;
}