#include #include #include #include "DevUtil.h" #include "Motor.h" #include #include #include "gvideo.h" #include "FpgaComm.h" #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_usb; 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); } init_get_CISType_GPIO(); 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) { StopWatch sw; sw.reset(); if (!m_scanner->is_connect()) { printf("USB DISCONNECT DISCONNECT DISCONNECT DISCONNECT DISCONNECT DISCONNECT DISCONNECT\n"); b_runloop = false; m_scanner->StopScan(); stop_countdown(); break; } 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)) system("cpufreq-set -g ondemand"); 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: { HG_JpegCompressInfo info = m_scanner->GetImage(); //sw.reset(); if (info.pJpegData != nullptr && info.DataLength != 0) { int tt = m_scanner->write_bulk((void*)&info, sizeof(int)*7); //int tt = m_scanner->write_bulk(info.pJpegData, info.DataLength); //free(info.pJpegData); //break; //tt = m_scanner->write_bulk(info.mat.data, info.DataLength); //free(info.pJpegData); //break; //LOG("GET_IMAGE info.pJpegData =%p info.DataLength=%d \n", info.pJpegData, info.DataLength); int index = 0; int total = info.DataLength; while (total > 0) { int dstlength = 1024 * 512; if (total <= dstlength) { dstlength = total; total = 0; // jpeg图像小于1MB 则一次传输 } else //压缩大于1MB的图像 分包传输 { total -= dstlength; } int tt = m_scanner->write_bulk(info.pJpegData + index, dstlength); //printf("write_bulk info.pJpegData+index = %p index = %d dstlength =%d tt = %d \n", info.pJpegData + index, index, dstlength, tt); if (tt <= -1) { LOG("FAIL GET_IMAGE write bulk data error\n"); //writesyslog(LOG_WARNING, "usb write_bulk error,lost image!"); break; } else index += tt; } //free(info.pJpegData); tjFree(info.pJpegData); LOG("Free info.pJpegData done\n"); //printf("TIME!!!!!!!!!!!!! :%f info.DataLength:%d\r\n",sw.elapsed_ms(),info.DataLength); } } break; case USBCommand::START_COMMAND: { system("cpufreq-set -g performance"); LOG("start scan scancount = %d\n", usbcb.Data); m_scanner->StartScan(usbcb.Data); std::string loginfo = "start scan dst scan num = " + to_string(usbcb.Data) + "\n"; writesyslog(LOG_INFO, loginfo); } 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"; writesyslog(LOG_INFO, loginfo); 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: { writesyslog(LOG_INFO, "start updating system\n"); LOG("start PRE_UPGRADE \n"); updatePkg.open("/usr/local/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: { LOG("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("cp /usr/local/update.zip /userdata/update.zip -f"); system("rm -rf /usr/local/update.zip"); // m_scanner->SetLEDStatus(LedStatus::Ready); // this_thread::sleep_for(std::chrono::seconds(3)); // total_length = 0; // writesyslog(LOG_INFO, "update system finished\n"); // system("reboot"); } break; case USBCommand::REBOOT: { writesyslog(LOG_INFO, "scanservices aquired reboot\n"); 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"); writesyslog(LOG_WARNING, "usb write_bulk error,lost log data!"); break; } else index += tt; } logzipfiles.close(); delete[] bufferlog; } } break; case USBCommand::GET_UPDATE_RESULT: { fstream updateResult("/userdata/md5_result.log"); if (!updateResult.is_open()) usbcb.Data = 0; else { updateResult >> usbcb.Data; updateResult.close(); } m_scanner->write_bulk(&usbcb, sizeof(usbcb)); this_thread::sleep_for(std::chrono::milliseconds(1000)); if (usbcb.Data == 2) system("reboot"); else if (usbcb.Data == 3) system("update ota /userdata/updatefile/update.img"); } break; case USBCommand::CLEAR_LOG_FILES: { system("echo \"\" > /var/log/syslog"); writesyslog(LOG_WARNING, "clear /var/log/syslog contents!"); } 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: { usbcb.Data = 0x10; m_scanner->write_bulk(&usbcb, sizeof(usbcb)); } 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); string usbvidpid = "/etc/mdfusbconfig " + to_string(t_vidpid.VID) + " " + to_string(t_vidpid.PID); LOG("SET_USB_INFOR_VIDPID + %s \n", usbvidpid.c_str()); system(usbvidpid.c_str()); } 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; default: break; } } m_scanner->ClearErrorEvents(); m_scanner->ClearImages(); //清空内存 释放压缩数据 避免内存堆积 m_scanner.reset(); LOG("reset scanner \n"); LOG("reset usb \n"); LOG("scanservice exit \n"); writesyslog(LOG_INFO, "usb disconnect! scanservices exit now"); return 0; }