#include #include #include #include "DevUtil.h" #include "Motor.h" #include #include #include "FsmState.h" #include "Scanner.h" // #include "filetools.h" #include #include #include #include #include #include "HGUsb.h" #include #include "UsbScanner.h" #include "scanservices_utils.h" #include #include "JsonConfig.h" #include #include "utilsfunc.h" #include "correct_ultis.h" #include #include "USBProtocol.h" #include "MotorConfig.h" #include #include "usbdevice.h" using json = nlohmann::json; using namespace std; shared_ptr m_scanner; ofstream updatePkg; static unsigned int total_length = 0; extern int errno; #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 { LOG("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 */ LOG("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); _exit(0); } int menu() { int choice; cout << " **** Menu **** " << endl << endl; cout << "(1) cap regs list." << endl; cout << "(2) test write read regs" << endl; cout << "(0) Quit. " << endl << endl; cout << ": "; cin >> choice; return choice; } void initscanner() { m_scanner.reset(new UsbScanner()); if (!m_scanner.get()) LOG("init m_scanner failed\n"); } bool b_runloop = true; int waittimes = 0; #define WAITCONNECTMAXTIME 50 int main(int argc, char *argv[]) { 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); } creat_sleep_fifo(); initscanner(); start_enter_lowpwoer(); if (argc == 2) { int t_arg1 = atoi(argv[1]); if (t_arg1 == 236) { LOG("onboard start auto correct!\n"); m_scanner->CreatCorrectData(0); while (m_scanner->GetEvent().code != (int)HG_ScannerStatus::AUTO_FLAT_FINISHED) { std::this_thread::sleep_for(chrono::milliseconds(2)); } } else { LOG("onboard unkown command!\n"); } } while (b_runloop) { if (!m_scanner->is_connect()) { printf("USB DISCONNECT DISCONNECT DISCONNECT DISCONNECT DISCONNECT DISCONNECT DISCONNECT\n"); b_runloop = false; m_scanner->StopScan(); stop_countdown(); return 0; } USBCB usbcb = {0}; m_scanner->read_bulk(&usbcb, sizeof(usbcb)); if (usbcb.Command == 0) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); continue; } // printf("Usb command %d \n",usbcb.Command); switch ((USBCommand)usbcb.Command) { case USBCommand::GET_DSP_STATUS: { USBCB sts = {1, 0, 0}; if (m_scanner->IsScanning()) // 队列不为空 { if (m_scanner->GetImagequeueEmpty()) { // LOG("GetImagequeueEmpty\n"); auto evt = m_scanner->GetEventFront(); // if (evt != (int)HG_ScannerStatus::NORMAL && evt != (int)HG_ScannerStatus::STOP_SCAN) if (evt.code != (int)HG_ScannerStatus::NORMAL && evt.code != (int)HG_ScannerStatus::STOP_SCAN) { sts.Data = m_scanner->GetEvent().code; // 确保第一张扫描之前所发生的异常事件能够被通知 } } else { LOG("not GetImagequeueEmpty\n"); int evt = m_scanner->GetEventFront().code; if (evt != (int)HG_ScannerStatus::NORMAL && evt != (int)HG_ScannerStatus::STOP_SCAN) { sts.Data = m_scanner->GetEvent().code; // 扫描中途的事件能够被通知 } else { HG_JpegCompressInfo info = m_scanner->GetFrontImage(); sts.Data = (int)HG_ScannerStatus::HAVE_IMAGE; sts.Length = info.DataLength; } } } else { // LOG("Scanning not scanning \n"); if (!m_scanner->GetImagequeueEmpty()) { HG_JpegCompressInfo info = m_scanner->GetFrontImage(); sts.Data = (int)HG_ScannerStatus::HAVE_IMAGE; sts.Length = info.DataLength; } else { auto data = m_scanner->GetEvent(); if (data.code == (int)(HG_ScannerStatus::STOP_SCAN)) { printf("关闭V4L2 4444\r\n"); m_scanner->close_v4l2(); } sts.Data = data.code; if (data.code == (int)HG_ScannerStatus::AUTO_FLATTING || data.code == (int)HG_ScannerStatus::AUTO_FLAT_FINISHED) { sts.Length = data.msg.length(); m_scanner->write_bulk(&sts, sizeof(sts)); auto msg = data.msg; m_scanner->write_bulk(&msg[0], msg.length()); break; } } } m_scanner->write_bulk(&sts, sizeof(sts)); } break; case USBCommand::GET_IMAGE: { static int indx = 1; HG_JpegCompressInfo info = m_scanner->GetImage(); if (info.pJpegData != nullptr && info.DataLength != 0) { int tt = m_scanner->write_bulk((void *)&info, sizeof(int) * 8); int index = 0; int total = info.DataLength; while (total > 0) { int dstlength = 1024 * 1024; if (total <= dstlength) { dstlength = total; total = 0; // jpeg图像小于1MB 则一次传输 } else // 压缩大于1MB的图像 分包传输 total -= dstlength; int tt = m_scanner->write_bulk(info.pJpegData + index, dstlength); if (tt <= -1) { LOG("FAIL GET_IMAGE write bulk data error\n"); break; } else index += tt; } indx++; } } break; case USBCommand::START_COMMAND: { LOG("start scan scancount = %d\n", usbcb.Data); m_scanner->StartScan(usbcb.Data); } break; case USBCommand::STOP: m_scanner->StopScan(); break; case USBCommand::GET_FW_VERSION: { m_scanner->write_bulk((void *)m_scanner->GetFWVersion().c_str(), m_scanner->GetFWVersion().length()); // DEBUG("usb write bulk fwversion : %s length :%d", m_scanner->GetFWVersion().c_str(), m_scanner->GetFWVersion().length()); } break; case USBCommand::CONFIGURED_DATA: { m_scanner->ClearErrorEvents(); m_scanner->ClearImages(); HG_ScanConfiguration config; config.value = usbcb.Data; m_scanner->ConfigScanParam(config); std::string loginfo = "config scanner config data = " + to_string(usbcb.Data) + "\n"; LOG("CONFIGURED_DATA data = %d \n", config.value); } break; case USBCommand::SEND_FW: // never support break; case USBCommand::GET_PAPERFEEDER_STATUS: { auto feed = m_scanner->FeederLoaded(); USBCB statesfeed = {(int)USBCommand::GET_PAPERFEEDER_STATUS, (feed ? 1 : 0), 0}; // USBCB statesfeed = {(int)USBCommand::GET_PAPERFEEDER_STATUS, 1, 0}; m_scanner->write_bulk(&statesfeed, sizeof(statesfeed)); LOG("GET_PAPERFEEDER_STATUS feeded %s\n", feed ? "TRUE" : "FALSE"); } break; case USBCommand::INIT_HARDWARE_SYS: break; case USBCommand::START_FLAT: m_scanner->CreatCorrectData(usbcb.Data); break; case USBCommand::STOP_FLAT: break; case USBCommand::SEND_SERIAL: if (usbcb.Length == 14) // 长度必须是14 { LOG("SET SEND_SERIAL \n"); std::vector str(14); m_scanner->read_bulk(str.data(), 14); m_scanner->UpdateScanInfo((int)USBCommand::SEND_SERIAL, str.data()); } break; case USBCommand::GET_SERIAL: { LOG("usb write bulk serial : %s length :%d \n", m_scanner->GetSerial().c_str(), m_scanner->GetSerial().length()); m_scanner->write_bulk((void *)m_scanner->GetSerial().c_str(), m_scanner->GetSerial().length()); } break; case USBCommand::CLEAR_HWERROR: m_scanner->ClearHWError(); break; case USBCommand::CLR_ROLLER_NUM: case USBCommand::CLR_SCAN_NUM: case USBCommand::SET_SLEEP_TIME: case USBCommand::SET_SPEED_MODE: { m_scanner->UpdateScanInfo(usbcb.Command, &usbcb.Data); } break; case USBCommand::SET_JUST_COF_H: case USBCommand::SET_JUST_COF_V: { if (usbcb.Length == 0) { LOG("SET_JUST_COF_V -----------------\n"); auto info = GetScanInfoFromJson(); usbcb.Command == (int)USBCommand::SET_JUST_COF_H ? info.HRatio = usbcb.Data : info.VRatio = usbcb.Data; SaveScaninfo(info); } else { auto infoC = GetFpgaparam(usbcb.Length, 1); auto infoG = GetFpgaparam(usbcb.Length, 0); if (usbcb.Command == (int)USBCommand::SET_JUST_COF_H) { infoC.HRatio = usbcb.Data; infoG.HRatio = usbcb.Data; } else { infoC.VRatio = usbcb.Data; infoG.VRatio = usbcb.Data; } SaveFpgaparam(infoC); SaveFpgaparam(infoG); } } break; case USBCommand::SEND_COLOR_FLAT: case USBCommand::SEND_COLORCORRECT_FLAT: case USBCommand::SEND_GRAY_FLAT: case USBCommand::SEND_GRAYCORRECT_FLAT: { int buffer[30] = {0}; m_scanner->read_bulk(&buffer, sizeof(int) * 30); m_scanner->SetFlatParam(usbcb.Command, buffer); } break; // case USBCommand::GET_FLAT_DATA: // { // LOG("enter GET_FLAT_DATA \n"); // int buffer[128]; // auto params = m_scanner->GetCaptureParams(); // LOG("size of params %d \n", sizeof(params)); // memcpy(buffer, ¶ms, sizeof(params)); // m_scanner->write_bulk(&buffer, sizeof(int) * 128); // } // break; case USBCommand::PRE_UPGRADE: { printf("start PRE_UPGRADE \n"); updatePkg.open("/home/root/update.zip", ios::out | ios::binary); m_scanner->SetLEDStatus(LedStatus::Updating); total_length = usbcb.Length; } break; case USBCommand::START_UPGRADE: { LOG("\n-----------START_UPGRADE----------------\n %d %d %d ", usbcb.Command, usbcb.Data, usbcb.Length); USBCB tmpUpdate = {(unsigned int)(USBCommand::START_UPGRADE), 0, 0}; if (usbcb.Length != 0) { LOG("\n-----------read_bulk----------------"); uint ntoReadn = usbcb.Length; char *bufferData = (char *)malloc(ntoReadn * sizeof(char)); if (bufferData) { m_scanner->read_bulk(bufferData, ntoReadn); updatePkg.write(bufferData, ntoReadn); tmpUpdate.Length = ntoReadn; free(bufferData); } } m_scanner->write_bulk(&tmpUpdate, sizeof(tmpUpdate)); } break; case USBCommand::UPDATE_FINISHED: { printf("PRE_UPGRADE finished \n"); if (total_length < (1024 * 1024 * 5)) this_thread::sleep_for(std::chrono::seconds(10)); m_scanner->SetLEDStatus(LedStatus::UpdateDone); updatePkg.close(); //system("sh /mnt/flash-disk/upgrade_firmware.sh &"); printf("PRE_UPGRADE finished exit!!!!!!!!!!!!! \n"); } break; case USBCommand::REBOOT: { if (usbcb.Data == 0) system("reboot"); else system("reboot loader"); } break; case USBCommand::GET_LOG_FILES_INFO: { ifstream logzipfiles; logzipfiles.open("/var/log/syslog", std::ios_base::in | std::ios_base::binary); if (!logzipfiles.is_open()) { usbcb.Length = 0; m_scanner->write_bulk(&usbcb, sizeof(usbcb)); } else { logzipfiles.seekg(0, std::ios::end); size_t length = logzipfiles.tellg(); logzipfiles.seekg(0, std::ios::beg); usbcb.Length = length; m_scanner->write_bulk(&usbcb, sizeof(usbcb)); char *bufferlog = new char[length]; logzipfiles.read(bufferlog, length); m_scanner->write_bulk(bufferlog, length); int index = 0; while (length > 0) { int dstlength = 1024 * 1024; if (length <= dstlength) { dstlength = length; length = 0; // jpeg图像小于1MB 则一次传输 } else // 压缩大于1MB的图像 分包传输 length -= dstlength; int tt = m_scanner->write_bulk(bufferlog + index, dstlength); if (tt == -1) { LOG("GET_LOG_FILES_INFO write bulk data error\n"); break; } else index += tt; } logzipfiles.close(); delete[] bufferlog; } } break; case USBCommand::GET_UPDATE_RESULT: { int ret = get_devs_status("/mnt/flash-disk/update_status.txt"); printf("GET_UPDATE_RESULT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n"); printf("ret:%d\r\n",ret); usbcb.Data = ret; if (ret == -1) { usbcb.Data = 100; } m_scanner->write_bulk(&usbcb, sizeof(usbcb)); if (usbcb.Data == 0) system("reboot"); } break; case USBCommand::CLEAR_LOG_FILES: { system("echo \"\" > /var/log/syslog"); } break; case USBCommand::GET_SCANN_NUM: case USBCommand::GET_ROLLER_NUM: case USBCommand::GET_JUST_COF_H: case USBCommand::GET_JUST_COF_V: case USBCommand::GET_CUO_ERROR: case USBCommand::GET_DOU_ERROR: case USBCommand::GET_JAM_ERROR: case USBCommand::GET_SLEEP_TIME: case USBCommand::GET_SPEED_MODE: { LOG("SET_JsonConfig ------------- \n"); USBCB tmp = {(int)usbcb.Command, 0, 0}; auto info = GetScanInfoFromJson(); if (usbcb.Command == (int)(USBCommand::GET_SCANN_NUM)) tmp.Data = info.TotalScanned; else if (usbcb.Command == (int)(USBCommand::GET_ROLLER_NUM)) tmp.Data = info.RollerNum; else if (usbcb.Command == (int)(USBCommand::GET_JUST_COF_H) || usbcb.Command == (int)(USBCommand::GET_JUST_COF_V)) { if (usbcb.Length == 0) tmp.Data = usbcb.Command == (int)(USBCommand::GET_JUST_COF_H) ? info.HRatio : info.VRatio; else { auto camraparm = GetFpgaparam(usbcb.Length, 0); tmp.Data = usbcb.Command == (int)(USBCommand::GET_JUST_COF_H) ? camraparm.HRatio : camraparm.VRatio; } } else if (usbcb.Command == (int)(USBCommand::GET_CUO_ERROR)) tmp.Data = info.JamInNum; else if (usbcb.Command == (int)(USBCommand::GET_DOU_ERROR)) tmp.Data = info.DoubleNum; else if (usbcb.Command == (int)(USBCommand::GET_JAM_ERROR)) tmp.Data = info.JamOutNum; else if (usbcb.Command == (int)(USBCommand::GET_SLEEP_TIME)) tmp.Data = info.SleepTime; else if (usbcb.Command == (int)(USBCommand::GET_SPEED_MODE)) tmp.Data = info.SpeedMode; m_scanner->write_bulk(&tmp, sizeof(tmp)); } break; case USBCommand::ACTIVE_SCANNER: { int ret = get_devs_status(SLEEP_STATUS_PATH); printf("sleep status :%d\r\n",ret); usbcb.Data = ret == SCANNER_ERR_SLEEP ? 0x100 : 0x10; m_scanner->write_bulk(&usbcb, sizeof(usbcb)); if (ret == SCANNER_ERR_SLEEP) { system("sh /mnt/flash-disk/low_power.sh 0"); } } break; case USBCommand::SET_USB_INFOR_VIDPID: { VIDPID t_vidpid = {0}; t_vidpid.Value = (unsigned int)usbcb.Data; auto info = GetScanInfoFromJson(); info.VID = t_vidpid.VID; info.PID = t_vidpid.PID; SaveScaninfo(info); } break; case USBCommand::GET_USB_INFOR_VIDPID: { auto info = GetScanInfoFromJson(); VIDPID t_vidpid = {info.VID, info.PID}; t_vidpid.VID = info.VID; t_vidpid.PID = info.PID; LOG("GET_USB_INFOR_VIDPID + VID= %04x PID=0x%04x\n", info.VID, info.PID); usbcb.Data = t_vidpid.Value; m_scanner->write_bulk(&usbcb, sizeof(usbcb)); } break; case USBCommand::GETSYSINFO_LEN: { usbcb.Length = m_scanner->GetSysInfo().length(); printf("/usr/local/huago/sysinfo.json length = %d \n", usbcb.Length); m_scanner->write_bulk(&usbcb, sizeof(usbcb)); } break; case USBCommand::GETSYSINFO: { auto str = m_scanner->GetSysInfo(); m_scanner->write_bulk(&str[0], str.length()); } break; case USBCommand::GETMOTORPARAM: { if (usbcb.Length <= 0) break; std::string jsonpath; jsonpath.resize(usbcb.Length); m_scanner->read_bulk(&jsonpath[0], usbcb.Length); LOG("get json path = %s \n", jsonpath.c_str()); if (access(jsonpath.c_str(), F_OK) == 0) // 存在 { ifstream i(jsonpath); json j; i >> j; std::string str_js = j.dump(); USBCB rtinfo = {.Command = (unsigned int)USBCommand::GETMOTORPARMLEN, .Data = 0, .Length = str_js.length()}; m_scanner->write_bulk(&rtinfo, sizeof(rtinfo)); m_scanner->write_bulk(&str_js[0], str_js.length()); } break; } case USBCommand::SETMOTORPARAM: { std::string jspath, jscontent; jspath.resize(usbcb.Data); jscontent.resize(usbcb.Length); m_scanner->read_bulk(&jspath[0], usbcb.Data); LOG("save json path =%s \n", jspath.c_str()); m_scanner->read_bulk(&jscontent[0], usbcb.Length); // LOG("json content =%s \n", jscontent.c_str()); auto j = json::parse(jscontent); ofstream ofs(jspath); ofs << std::setw(4) << j << std::endl; } break; case USBCommand::GET_FLAT_DATA: { FLAT_INFO flatinfo ; flatinfo.value = usbcb.Data; flatinfo.params.status = 100; ////正常状态 unsigned char *lut_buffer; if (flatinfo.params.dpi != 0) { std::ifstream lut_item; int dpi = flatinfo.params.dpi == 0x01 ? 200 : (flatinfo.params.dpi == 0x02 ? 300 : 600); std::string mode = flatinfo.params.colormode ? "clr" : "gray"; std::string is_white_lut = flatinfo.params.is_whiteimage ? "white" : "bw"; std::string lut_path = "/mnt/flash-disk/huago/lut" + std::to_string(dpi) + mode + is_white_lut + ".bmp"; lut_item.open(lut_path, std::ios_base::in | std::ios_base::binary); if (!lut_item.is_open()) { flatinfo.params.datalen = 0; flatinfo.params.status = 1; // 文件打开失败 } else { lut_item.seekg(0, std::ios::end); size_t length = lut_item.tellg(); lut_item.seekg(0, std::ios::beg); flatinfo.params.datalen = length; } if (flatinfo.params.datalen != 0 && flatinfo.params.status == 100) { lut_buffer = new unsigned char[flatinfo.params.datalen]; if (lut_buffer) { lut_item.read((char *)lut_buffer, flatinfo.params.datalen); } else { flatinfo.params.status = 2; // OOM 异常 flatinfo.params.datalen = 0; } } } else { flatinfo.params.datalen = 0; flatinfo.params.status = 3; // 未知dpi } usbcb.Data = flatinfo.value; printf("flatinfo.params.status:%d\r\n" ,flatinfo.params.status); printf("flatinfo.params.datalen:%d\r\n" ,flatinfo.params.datalen); printf("flatinfo.value:%d\r\n",flatinfo.value); m_scanner->write_bulk(&usbcb, sizeof(usbcb)); if (lut_buffer) { m_scanner->write_bulk(lut_buffer, flatinfo.params.datalen); delete[] lut_buffer; lut_buffer = NULL; } } break; case USBCommand::DEVICES_7010: usbcb.Data = 1; m_scanner->write_bulk(&usbcb, sizeof(usbcb)); break; default: break; } } m_scanner->ClearErrorEvents(); m_scanner->ClearImages(); // 清空内存 释放压缩数据 避免内存堆积 m_scanner.reset(); LOG("reset scanner \n"); LOG("reset usb \n"); LOG("scanservice exit \n"); return 0; }