#include "stdafx.h" #include "GScanO400.h" #include "UsbScanEx.h" #include "StopWatch.h" #include "scn_config.h" #include "ImageMatQueue.h" #include "ImageProcess/ImageApplyDogEarDetection.h" #include "filetools.h" #include "GetMemoryUsage.h" #include "G400ScanConfig.h" //u32_CMD typedef enum tagUsbKeyWords : UINT32 { //无命令 NO_COMMAND = 0, //获取dsp 状态 GET_DSP_STATUS = 1, //取图 GET_IMAGE = 2, //销毁DSP中驻存的图 POP_IMAGE = 3, //开始扫描命令 START_COMMAND = 4, //停止扫描命令 STOP = 5, //获取扫描仪扫描模式 GET_SCAN_MODE = 6, //获取固件版本号 GET_FW_VERSION = 7, //返回PC端的状态 SEND_STATUS_PC = 8, //下发扫描配置参数 CONFIGURED_DATA = 9, //下发固件信息 SEND_FW = 10, //获取扫描参数 GET_CONFIG_DATA = 11, //获取扫描总张数 GET_SCANN_NUM = 12, //获取有无纸的状态 GET_PAPERFEEDER_STATUS = 13, //DSP初始化 INIT_HARDWARE_SYS = 14, //获取有无纸的状态 GET_PAPER_STATUS = 0x0d, //下发元器件配置参数(灰度,LED R曝光时间) SEND_COMPONENTS_GR = 15, //下发元器件配置参数(LED G/B曝光时间) SEND_COMPONENTS_GB = 16, //下发扫描模式 SEND_SCAN_MODE = 17, //开始进行平场矫正 START_FLAT = 18, //停止平场矫正 STOP_FLAT = 19, //下发200dpi彩色平场矫正参数 SEND_200_COLOR_FLAT_DATA = 20, //下发300dpi彩色平场矫正参数 SEND_300_COLOR_FLAT_DATA = 21, //获取200dpi彩色平场矫正参数 GET_200_COLOR_FLAT_DATA = 22, //获取300dpi彩色平场矫正参数 GET_300_COLOR_FLAT_DATA = 23, //下发200dpi灰度平场校正参数 SEND_200_GRAY_FLAT_DATA = 24, //下发300dpi灰度平场校正参数 SEND_300_GRAY_FLAT_DATA = 25, //获取200DPI灰度平场校正参数 GET_200_GRAY_FLAT_DATA = 26, //获取300DPI灰度平场校正参数 GET_300_GRAY_FLAT_DATA = 27, //下发序列号命令 SEND_SERIAL = 28, //获取序列号命令 GET_SERIAL = 29, //获取滚轴数 GET_ROLLER_NUM = 0x1e, //清零滚轴数 CLR_ROLLER_NUM = 0x1f, //清除扫描总张数 CLR_SCAN_NUM = 0x20, //准备更新固件 PRE_UPGRADE = 0X21, //开始更新固件 START_UPGRADE = 0x22, //彩色的AD参数 RGB_ADI_PARA = 0x23, //灰度的AD参数 ADI_PARA = 0x24, //获取CIS参数(曝光时间,ad参数) GET_CIS_PARA = 0x25, //扫描张数 START_COMMAND_COUNT = 0x26, //下发休眠时间 SET_SLEEP_TIME = 0x27, //获取休眠时间 GET_SLEEP_TIME = 0x28, //清除缓存 CLR_CACHE = 0x29, //下发速度模式 SET_SPEED_MODE = 0x2a, //获取扫描速度模式 GET_SPEED_MODE = 0X2b, //设置固件版本一共8个字节 SET_FW_VERSION = 0X2c, //获取DSP版本 GET_DSP_VERSION = 0X2d, //采集板FPGA固件版本 GET_SCANFPGA_VERSION = 0x2e, //电机板FPGA固件版本 GET_MOTORFPGA_VERSION = 0X2f, //设置制造商信息 SET_USB_INFOR_MANUFACTURE = 0X30, //获取制造商信息 GET_USB_INFOR_MANUFACTURE = 0X31, //设置产品型号信息 SET_USB_INFOR_MODEL_NAME = 0X32, //获取产品型号信息 GET_USB_INFOR_MODEL_NAME = 0X33, //设置USB PID / VID信息 SET_USB_INFOR_VIDPID = 0X34, GET_USB_INFOR_VIDPID = 0X35, //设置卡纸急停检测灵敏度 SET_JAM_DETECT_SENSITIVE = 0X36, //获取卡纸急停检测灵敏度 GET_JAM_DETECT_SENSITIVE = 0X37, //设置横向畸变系数 SET_JUST_COF_H = 0x38, //读取横向畸变系数 GET_JUST_COF_H = 0x39, CLEAR_HWERROR = 0x40,//G400 清除硬件异常 //设置纵向畸变系数 SET_JUST_COF_V = 0x41, //读取纵向畸变系数 GET_JUST_COF_V = 0x42, //设置扫描仪编码 GET_CODE_G400 = 0x59, //读取扫描仪编码 SET_CODE_G400 = 0x60, //设置扫描仪编码 SET_CODE_G200 = 0x63, //读取扫描仪编码 GET_CODE_G200 = 0x64, } UsbKeyWords, * PUsbKeyWords; GScanO400::GScanO400() : huagods(NULL), image_num(0), m_bread_fixed_ratio_fromDSP(false) { m_pImages.reset(new ImageMatQueue()); auto getimgnum = [&](bool isadd, int num) { isadd ? image_num += num : image_num -= num; }; m_pImages->SetGetimgnumcall(getimgnum); } GScanO400::~GScanO400() { if (m_threadUsb && m_threadUsb->joinable()) { devState = DEV_STOP; m_threadUsb->join(); m_threadUsb.reset(); } if (m_usb.get()) m_usb.reset(); } void GScanO400::DogEar_callback(std::function fun) { m_pImages->SetDogEarCallback(fun); } void GScanO400::open(int vid, int pid) { auto usbs = UsbScan_List::find_vid_pid(vid, pid); if (!usbs.empty()) { m_usb = *usbs.begin(); m_usb->set_usbhotplug_callback(usbhotplug_callback, this); bool ret = m_usb->open(); if (notifyscan() < 1) { Set_ErrorCode(SLEEPING); return; } USBCB status = { GET_DSP_STATUS ,0,0 }; if (m_usb.get() && m_usb->is_connected()) { GetFWVersion(); } } } void GScanO400::regist_deviceevent_callback(deviceevent_callback callback, void* usrdata) { huagods = usrdata; dev_callback = callback; } int GScanO400::aquire_bmpdata(std::vector& bmpdata) { StopWatch sw; while (true) { if (m_pImages->empty()) { DoEvents(); this_thread::sleep_for(chrono::milliseconds(1)); if (sw.elapsed_s() > 60.00) { int roller_num_new = Get_Roller_num(); if (m_threadUsb && m_threadUsb->joinable()) { devState = DEV_STOP; m_threadUsb->join(); m_threadUsb.reset(); FileTools::writelog(log_ERROR, "aquire_bmpdata m_threadUsb.reset()"); } Stop_scan();//停止扫描 ResetScanner(); set_scannum(abs(roller_num_new - roller_num)); return HARDWARE_ERROR; } if (!is_scan()) { int roller_num_new = Get_Roller_num(); set_scannum(abs(roller_num_new - roller_num)); if (devState == DEV_WRONG) { return get_ErrorCode(); } return -1; } } else { if (m_pImages->valid()) { bmpdata = *(m_pImages->popBmpdata()); UpdateScanInfo(get_imgnReaded(), countNTransfered()); return 0; } DoEvents(); this_thread::sleep_for(chrono::milliseconds(2)); } } } BOOL GScanO400::IsConnected() { return m_usb.get() && m_usb->is_connected(); } std::string GScanO400::GetFWVersion() { if (m_usb.get() && m_usb->is_connected()) { //lock_guard< mutex> lock(m_imgLocker); if (fwVersion.empty()) { fwVersion.resize(10); USBCB cmd = { GET_FW_VERSION,fwVersion.size(),0, }; m_usb->write_bulk(&cmd, sizeof(cmd)); std::this_thread::sleep_for(chrono::milliseconds(10)); if (m_usb.get() && m_usb->is_connected()) m_usb->read_bulk(&fwVersion[0], fwVersion.size()); std::this_thread::sleep_for(chrono::milliseconds(10)); } return fwVersion; } return ""; } std::string GScanO400::GetSerialNum() { //return "G20018000298"; if (m_usb.get() && m_usb->is_connected()) { std::lock_guard lck(m_imgLocker); if (SerialNum.empty()) { SerialNum.resize(14); USBCB usbcb = { GET_SERIAL,SerialNum.size(),0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); if (m_usb.get() && m_usb->is_connected()) m_usb->read_bulk(&SerialNum[0], SerialNum.size()); } return SerialNum; } return ""; } std::uint32_t GScanO400::GetMotorFPGA() { if (m_usb.get() && m_usb->is_connected()) { std::lock_guard lck(m_imgLocker); USBCB usbcb = { GET_MOTORFPGA_VERSION,0,sizeof(MotorFpga) }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); MotorFpga = usbcb.u32_Data; return MotorFpga; } return 0; } std::uint32_t GScanO400::GetScanFPGA() { if (m_usb.get() && m_usb->is_connected()) { std::lock_guard lck(m_imgLocker); USBCB usbcb = { GET_SCANFPGA_VERSION,0,4 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); ScanFpga = usbcb.u32_Data; return ScanFpga; } return 0; } bool GScanO400::is_scan() { //std::lock_guard lck(m_imgLocker); return devState == DEV_ISRUNNING; } BOOL GScanO400::Get_Scanner_PaperOn() { if (!(m_usb.get() && m_usb->is_open())) { Set_ErrorCode(USB_DISCONNECTED); return true; } USBCB usbcb = { GET_PAPER_STATUS ,2,0 }; std::lock_guard lck(m_imgLocker); m_usb->write_bulk(&usbcb, sizeof(usbcb)); if (m_usb.get() && m_usb->is_connected()) { m_usb->read_bulk(&usbcb, sizeof(usbcb)); if (usbcb.u32_Data == 2) { Set_ErrorCode(USB_DISCONNECTED); return true; } } else { Set_ErrorCode(USB_DISCONNECTED); return true; } return usbcb.u32_Data != 0; } int GScanO400::Get_Roller_num() { if (!(m_usb.get() && m_usb->is_open())) return false; USBCB usbcb = { GET_SCANN_NUM ,0,4 }; std::lock_guard lck(m_imgLocker); m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); if (usbcb.u32_CMD != GET_SCANN_NUM) { FileTools::writelog(log_ERROR, "get roller usb bulk error"); } FileTools::writelog(log_INFO, "get roller num " + to_string(usbcb.u32_Data)); return usbcb.u32_Data; } void GScanO400::config_params(GScanCap& params) { if (m_usb.get() && m_usb->is_connected()) { G400ScanConfig cfg = G400ScanConfig(params); UINT32 cfgdata = cfg.GetData(); auto fw = GetFWVersion(); //if (atoi(fw.substr(4, 6).c_str()) >= 220117) //{ // if (params.papertype == 52 || params.papertype == 54 || params.papertype == 131 || params.papertype == 0) // cfgdata = (cfgdata & 0xffffffe0) + 18; //} #ifdef G400 if (atoi(fw.substr(4, 6).c_str()) >= 220117) { int dpi = 1; if (params.is_high_imagequality) { if (params.resolution_dst < 300) { params.resolution_native = 200.0f; dpi = 1; } else if (params.resolution_dst >= 300 && params.resolution_dst < 500) { params.resolution_native = 300.0f; dpi = 2; } else { params.resolution_native = 600.0f; dpi = 3; } cfgdata = (cfgdata & 0xffffff3f) + (dpi << 6); } else { if (params.resolution_dst <500) { params.resolution_native = 200.0f; dpi = 1; } else { params.resolution_native = 300.0f; dpi = 2; } cfgdata = (cfgdata & 0xffffff3f) + (dpi << 6); } } else params.resolution_native = 200.0f; #elif defined(G300) if (atoi(fw.substr(4, 6).c_str()) >= 221106) { int dpi = 1; if (params.is_high_imagequality) { if (params.resolution_dst < 300) { params.resolution_native = 200.0f; dpi = 1; } else if (params.resolution_dst >= 300 && params.resolution_dst < 500) { params.resolution_native = 300.0f; dpi = 2; } else { params.resolution_native = 600.0f; dpi = 3; } cfgdata = (cfgdata & 0xffffff3f) + (dpi << 6); } else { if (params.resolution_dst < 500) { params.resolution_native = 200.0f; dpi = 1; } else { params.resolution_native = 300.0f; dpi = 2; } cfgdata = (cfgdata & 0xffffff3f) + (dpi << 6); } } else params.resolution_native = 200.0f; #endif //G300 gcap = params; USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 }; FileTools::writelog(log_INFO, "config hardware param" + to_string(cfgdata)); m_usb->write_bulk(&usbcb, sizeof(USBCB)); this_thread::sleep_for(std::chrono::milliseconds(200)); m_pImages->setparam(params); } } void GScanO400::Scanner_StartScan(UINT16 count) { scanfalg = false; Set_ErrorCode(0); roller_num = Get_Roller_num(); std::lock_guard lck(m_imgLocker); if (m_threadUsb && m_threadUsb->joinable()) { devState = DEV_STOP; m_threadUsb->join(); } USBCB status = { GET_DSP_STATUS ,0,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&status, sizeof(status)); if (m_usb.get() && m_usb->is_connected()) m_usb->read_bulk(&status, sizeof(status)); switch (status.u32_Data) { case COUNT_MODE: case NO_FEED: case OPEN_COVER: case FEED_IN_ERROR: case PAPER_JAM: case DETECT_DOUBLE_FEED: case DETECT_STAPLE: case PAPER_SKEW: case HARDWARE_ERROR: case PC_SCAN_BUSY_or_ERROR: m_pImages->setscanflags(false); devState = DEV_WRONG; Set_ErrorCode(status.u32_Data); if (huagods) dev_callback(status.u32_Data, huagods); return; default: break; } int readlenght = 0; USBCB paperstatus = { GET_PAPER_STATUS ,0,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&paperstatus, sizeof(paperstatus)); if (m_usb.get() && m_usb->is_connected()) readlenght = m_usb->read_bulk(&paperstatus, sizeof(paperstatus)); if (paperstatus.u32_Data == 0) { m_pImages->setscanflags(false); devState = DEV_WRONG; int errorcode = 0; readlenght == 0 ? errorcode = USB_DISCONNECTED : errorcode = NO_FEED; Set_ErrorCode(errorcode); if (huagods) dev_callback(errorcode, huagods); return; } m_pImages->reset_DogEar(); if (gcap.is_duplex) count = count == 65535 ? 65535 : count / 2; USBCB usbcb = { START_COMMAND,(UINT32)count ,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&usbcb, sizeof(usbcb)); this_thread::sleep_for(std::chrono::milliseconds(200)); if (m_usb.get() && m_usb->is_connected()) { m_pImages->setscanflags(true); m_threadUsb.reset(new std::thread(&GScanO400::usbmain, this)); m_pImages->run(); } } int GScanO400::notifyscan() { if (!m_usb.get() && !m_usb->is_connected()) return -1; USBCB notify = { 0x100,0,0 }; m_usb->write_bulk(¬ify, sizeof(notify)); m_usb->read_bulk(¬ify, sizeof(notify)); if ((notify.u32_Data != 0x10 && GetFWVersion().length() < 10) || notify.u32_Data == 0x100) { std::string text = msgs[UsbSupported::SLEEPING]; ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString((text).c_str()), NULL, SW_HIDE); return -1; } return 1; } void GScanO400::Stop_scan() { std::lock_guard lck(m_imgLocker); USBCB usbcb = { STOP ,0,0 }; if (m_usb.get() && m_usb->is_connected()) { m_usb->write_bulk(&usbcb, sizeof(usbcb)); scanfalg = true; FileTools::writelog(log_INFO, "user stop scan"); } } void GScanO400::ResetScanner() { if (!(m_usb.get() && m_usb->is_connected())) return; std::lock_guard lck(m_imgLocker); USBCB usbcb = { INIT_HARDWARE_SYS ,0,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&usbcb, sizeof(usbcb)); } bool GScanO400::Get_IsImageQueueEmpty() { return m_pImages->empty(); } void GScanO400::reset() { while (!m_pImages->empty()) m_pImages->clear(); } UINT32 GScanO400::get_ErrorCode() { return Error_Code; } void GScanO400::Set_ErrorCode(UINT32 value) { Error_Code = value; } int GScanO400::get_scanned_num() { std::lock_guard lck(m_imgLocker); USBCB usbcb = { GET_SCANN_NUM ,0,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&usbcb, sizeof(usbcb)); return usbcb.u32_Count; } void GScanO400::clear_hwerror() { std::lock_guard lck(m_imgLocker); USBCB usbcb = { CLEAR_HWERROR ,0,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&usbcb, sizeof(usbcb)); } void GScanO400::set_sleep_time(int mode) { return; } bool GScanO400::set_scannercode(std::string str) { if (str.size() != 32) return false; if (!(m_usb.get() && m_usb->is_connected())) return false; for (int i = 0; i < str.size(); i += 4) { USBCB usbcb = { SET_CODE_G400,UINT32(str[i]) + ((UINT32(str[i + 1])) << 8) + (((UINT32)str[i + 2]) << 16) + (((UINT32)str[i + 3]) << 24),i }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); } return true; } std::string GScanO400::get_scannercode() { if (!(m_usb.get() && m_usb->is_connected())) return NULL; //return "12345678901234567890123456789012"; USBCB usb{ GET_CODE_G400,0,32 }; m_usb->write_bulk(&usb, sizeof(USBCB)); std::this_thread::sleep_for(std::chrono::milliseconds(20)); scannercode.resize(32); m_usb->read_bulk(&scannercode[0], 32); return scannercode.c_str(); } void GScanO400::usbhotplug_callback(bool isconnect, void* userdata) { GScanO400* This = (GScanO400*)userdata; This->usbhotplug(isconnect); } void GScanO400::usbhotplug(bool isleft) { FileTools::writelog(log_ERROR, "enable usb callback "); if (isleft) { devState = DEV_WRONG; Error_Code = USB_DISCONNECTED; m_pImages->setscanflags(false); if (m_usb.get()) m_usb.reset(); if (huagods) dev_callback(USB_DISCONNECTED, huagods); } } std::string GScanO400::GetMacAdder() { return "The firmware version does not support reading"; } void GScanO400::updateHVRatio() { if (!(m_usb.get() && m_usb->is_connected())) return; if (m_bread_fixed_ratio_fromDSP) { USBCB usbcb = { GET_JUST_COF_H ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); float hratio = *((float*)(&usbcb.u32_Data)); usbcb = { GET_JUST_COF_V ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); float vratio = *((float*)(&usbcb.u32_Data)); m_pImages->updatefixratio(hratio, vratio); } } #ifdef UV static int indeximg = 0; #endif void GScanO400::usbmain() { std::shared_ptr> imgData; devState = DEV_ISRUNNING; bool haveError = false; try { StopWatch sw; while (devState == DEV_ISRUNNING) { if (!(m_usb.get() && m_usb->is_connected())) { this_thread::sleep_for(chrono::milliseconds(200)); break; } if (sw.elapsed_ms() > 60000) { m_pImages->setscanflags(false); Set_ErrorCode(AQUIRE_IMAGE_TIMEOUT); devState = DevState::DEV_WRONG; //devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP; FileTools::writelog(log_ERROR, "USBmain aquire image timeout"); return; } USBCB usbcb = Get_Scanner_Status(); switch (usbcb.u32_Data) { case HAVE_IMAGE: { int totalNum = usbcb.u32_Count; std::this_thread::sleep_for(std::chrono::milliseconds(20)); m_usb->set_timeout(2000); imgData = Get_Img_Data(totalNum); m_usb->set_timeout(200); if (!imgData->size()) { Stop_scan(); FileTools::writelog(log_ERROR, "imgData->size() error"); break; } FileTools::writelog(log_INFO, " get image data size " + to_string(totalNum)); if (imgData->size() != totalNum) { FileTools::writelog(log_ERROR, " get image data size error totalnum " + to_string(totalNum) + " imgdata size " + to_string(imgData->size())); } if (!m_pImages->get_isDogEar()) m_pImages->pushMat(std::shared_ptr(new G400Decode(imgData))); #ifdef UV if (gcap.hardwarecaps.en_uv) { if (indeximg % 2 == 0) { UpdateScanInfo(countNReaded(), get_imgTransfered()); } } else { UpdateScanInfo(countNReaded(), get_imgTransfered()); } indeximg++; #else UpdateScanInfo(countNReaded(), get_imgTransfered()); #endif Pop_Image(); FileTools::writelog(log_INFO, "从扫描仪接收" + to_string(get_imgnReaded()) + "份文件。耗时 " + to_string(sw.elapsed_ms())); sw.reset(); break; } case STOP_SCAN: { m_pImages->setscanflags(false); std::this_thread::sleep_for(std::chrono::milliseconds(500)); devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP; break; } case COUNT_MODE: case NO_FEED: case OPEN_COVER: case FEED_IN_ERROR: case PAPER_JAM: case DETECT_DOUBLE_FEED: case DETECT_STAPLE: case PAPER_SKEW: case HARDWARE_ERROR: case PC_SCAN_BUSY_or_ERROR: case SIZE_ERROR: case USB_BULK_ERROR: if (!haveError) { haveError = true; Set_ErrorCode(usbcb.u32_Data); if (huagods) dev_callback(usbcb.u32_Data, huagods); } break; case NORMAL: break; default: break; } this_thread::sleep_for(chrono::milliseconds(10)); } } catch (const std::exception& e) { FileTools::writelog(log_ERROR, e.what()); } } /////////////////////////////////////////////////////////////////////////// USBCB GScanO400::Get_Scanner_Status() { if (!(m_usb.get() && m_usb->is_connected())) { return { NO_COMMAND ,PC_SCAN_BUSY_or_ERROR ,0 }; } USBCB usbcb = { GET_DSP_STATUS ,0,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&usbcb, sizeof(usbcb)); if (m_usb.get() && m_usb->is_connected()) m_usb->read_bulk(&usbcb, sizeof(usbcb)); return usbcb; } std::shared_ptr> GScanO400::Get_Img_Data(int bufferSize) { try { if (!(m_usb.get() && m_usb->is_connected())) return std::shared_ptr>(new std::vector()); std::shared_ptr> imData(new std::vector(bufferSize)); StopWatch sw; int readed = 0; USBCB usbcb = { GET_IMAGE,0,bufferSize }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); int totalength = 1024 * 1024; int startindex = 0; std::this_thread::sleep_for(std::chrono::microseconds(20)); while (startindex < bufferSize) { startindex += m_usb->read_bulk(imData->data() + startindex, (bufferSize - startindex) < totalength ? (bufferSize - startindex) : totalength); //数据接收量必须小于等于管道内数据量,否则会接收失败 std::this_thread::sleep_for(std::chrono::microseconds(10)); FileTools::writelog(log_ERROR, "usb read buffer "+to_string(startindex)); } if (sw.elapsed_ms() > 5000) { FileTools::writelog(log_ERROR, "Usb read data timeout\n"); } return imData; } catch (const std::exception& e) { FileTools::writelog(log_ERROR, e.what()); } } /////////////////////////////////////////////////////////////////////////// void GScanO400::Pop_Image() { if (!(m_usb.get() && m_usb->is_open())) return; USBCB usbcb = { POP_IMAGE ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); }