249 lines
5.0 KiB
C++
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;
|
||
|
}
|