#include "scannerregs.h" #include #include #include "scanner.h" #include "usbimageprocqueue.h" #include "filetools.h" #include "stringex.hpp" #include "applog.h" #include #include "memoryex.h" #include "jsonconfig.h" #include "hgutils.h" #include "base64.hpp" #include "deviceconfig.h" unsigned long getfilesize(const char *filename) { struct stat buf; if (stat(filename, &buf) < 0) return 0; return (unsigned long)buf.st_size; } void get_system_output(char *cmd, char *output, int size) { FILE *fp = NULL; fp = popen(cmd, "r"); if (fp) { if (fgets(output, size, fp) != NULL) { if (output[strlen(output) - 1] == '\n') output[strlen(output) - 1] = '\0'; } pclose(fp); } } static const std::string loggername = "ScannerRegAccess"; ScannerRegAccess::ScannerRegAccess(std::shared_ptr scanner, std::shared_ptr usbimages, std::shared_ptr transmit, std::shared_ptr receiv) { LOG_INIT(); this->scanner = scanner; this->usbimages = usbimages; this->transmit = transmit; this->recieve = receiv; this->m_upstautus = Start_updata; this->scanner->set_paprent(this); } ScannerRegAccess::~ScannerRegAccess() { } bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) { // printf("write(0x%x, 0x%x), sizeof(unsigned int) = %d, sizeof(long) = %d, sizeof(long long) = %d\n", addr, val // , sizeof(unsigned int), sizeof(long), sizeof(long long)); printf("ScannerRegAccess::write(%d, %d)\n", addr, val); switch (addr) { case SR_CMD: return cmd(val); case SR_IM_CLEAR: while (!usbimages->empty()) usbimages->pop(); return true; case SR_IM_TYPE: return true; case SR_IM_TX: { // if (val != 1 && (transmit->is_writing() || usbimages->empty())) // return false; // if (!usbimages->size()) // return false; auto img = usbimages->front(); if (img.get()) { transmit->write(img); } else { LOG_TRACE(string_format("\nimage pop data is empty")); scanner->add_scansever({.From = V4L2, .Code = 1}); } return true; } case SR_NOTIFY_SLEEP: if(scanner->get_sleepstatus() == 0) scanner->set_sleepstatus(true); return true; case SR_IM_POP: usbimages->pop(); return true; case SR_IM_ABORT: transmit->cannel(); return true; case SR_CONFIG_SCAN_PARAM: scanner->configparam(*((HGScanConfig *)&val)); return true; case SR_CONFIF_IMGPROCPARAM: { printf("\nSR_CONFIF_IMGPROCPARAM size =%d",val); std::vector data(val); if(val==0) data.resize(116); auto lin = recieve->read_bulk(data.data(), data.size()); char capdata[sizeof(GScanCap)]{0}; printf("\n gcap size = %d \n",sizeof(GScanCap)); memcpy(capdata,data.data(),std::min(sizeof(GScanCap),data.size())); GScanCap cap = *(GScanCap *)capdata; scanner->set_hgimgconfig(cap); return true; } case SR_GET_FWVERSION: { std::string fw(FWVersion); printf("Firmware version(%p): %s\n", transmit.get(), fw.c_str()); int sent = transmit->write_bulk(&fw[0], fw.length()); printf("Firmware version sent: %d!\n", sent); //printf((fw + "%d\n").c_str(), fw.length()); return true; } case SC_AUTOCORRECT: scanner->test_autocorrect(val); return true; case SC_GET_CORRECT_PARAM: { auto param = getcisparams(); transmit->write_bulk(¶m, sizeof(param)); return true; } case SC_SET_CORRECT_PARAM: { auto cisparam = getcisparams(); switch (val) { case 0: //correct color { recieve->read_bulk(&cisparam.colorCorrect, sizeof(HGCISConfig)); for (int i = 0; i < 6; i++) { if (i < 3) { printf("colorCorrect.expF[%d] = %d \n", i, cisparam.colorCorrect.expF[i]); printf("colorCorrect.expB[%d] = %d \n", i, cisparam.colorCorrect.expB[i]); } printf("colorCorrect.GainsF[%d] = %d \n", i, cisparam.colorCorrect.gainF[i]); printf("colorCorrect.GainsB[%d] = %d \n", i, cisparam.colorCorrect.gainB[i]); printf("colorCorrect.offsetsF[%d] = %d \n", i, cisparam.colorCorrect.offsetsF[i]); printf("colorCorrect.offsetsB[%d] = %d \n", i, cisparam.colorCorrect.offsetsB[i]); } savecisparams(cisparam); break; } case 1: //color { recieve->read_bulk(&cisparam.color, sizeof(HGCISConfig)); for (int i = 0; i < 6; i++) { if (i < 3) { printf("color.expF[%d] = %d \n", i, cisparam.color.expF[i]); printf("color.expB[%d] = %d \n", i, cisparam.color.expB[i]); } printf("color.GainsF[%d] = %d \n", i, cisparam.color.gainF[i]); printf("color.GainsB[%d] = %d \n", i, cisparam.color.gainB[i]); printf("color.offsetsF[%d] = %d \n", i, cisparam.color.offsetsF[i]); printf("color.offsetsB[%d] = %d \n", i, cisparam.color.offsetsB[i]); } savecisparams(cisparam); } break; case 2: //correct gray recieve->read_bulk(&cisparam.grayCorrect, sizeof(HGCISConfig)); savecisparams(cisparam); break; case 3: //gray recieve->read_bulk(&cisparam.gray, sizeof(HGCISConfig)); savecisparams(cisparam); break; default: break; } return true; } case SR_UPDATA_START: { scanner->set_sleepstatus(false); int currlenght = 0; std::vector buff; std::fstream fd; if (access("/home/updata.zip", 4) == 0) remove("/home/updata.zip"); fd.open("/home/updata.zip", std::ios::out | std::ios::binary); if (val < 512 * 1024) { buff.resize(val); recieve->read_bulk(buff.data(), val); if (fd.is_open()) { m_upstautus = Download_file; fd.write(buff.data(), val); fd.close(); m_upstautus = Download_file_finish; } else m_upstautus = Download_file_error; } else { buff.resize(512 * 1024); if (fd.is_open()) { int readnum = 0; m_upstautus = Download_file; while (val > currlenght) { readnum = recieve->read_bulk(buff.data(), ((val - currlenght) > 512 * 1024) ? (512 * 1024) : (val - currlenght)); fd.write(buff.data(), readnum); fd.seekp(0, std::ios::end); currlenght += readnum; printf("\nresvice data lenght =%d ", currlenght); } fd.close(); m_upstautus = Download_file_finish; } else m_upstautus = Download_file_finish; } if (m_upstautus = Download_file_finish) { system("cp /home/updata.zip /userdata/update.zip -f"); system("rm -rf /home/updata.zip"); system("echo 5 > /userdata/md5_result.log"); } return true; } case SR_REBOOT: { system("reboot"); return true; } case SR_POWEROFF: { system("poweroff"); return true; } case SR_SET_H_RATIO: case SR_SET_V_RATIO: case SR_SET_SERIALNUM: case SR_GET_SERIALNUM: { unsigned int value = val; return procscannerinfo(addr, value); } case SR_SET_GRAY_SP: { auto info = jsonconfig().getscannerinfo(); #ifdef G200 if(info.speedmode==100||info.speedmode==110||info.speedmode==120||info.speedmode==130) info.gray_sp= val; #else if(info.speedmode==70||info.speedmode==80||info.speedmode==90 || info.speedmode == 110) info.gray_sp = val; #endif printf(" \n SR_SET_GRAY_SP %d ", val); jsonconfig().savescannerinfo(info); return true; } case SR_SET_COLOR_SP: { auto info = jsonconfig().getscannerinfo(); #ifdef G200 if(info.speedmode==100||info.speedmode==110||info.speedmode==120||info.speedmode==130) info.color_sp = val; #else if(info.speedmode==70||info.speedmode==80||info.speedmode==90||info.speedmode==110) info.color_sp = val; #endif printf(" \n SR_SET_COLOR_SP %d ", val); jsonconfig().savescannerinfo(info); return true; } case SR_SET_SLEEPTIME: { int value = (*((int *)&val)); if(value>=60 || value == -1){ scanner->resettime(); scanner->set_sleeptime(value); } return true; } case SR_FLAT_CLR_MAX_BRIGHT: case SR_FLAT_GRAY_MAX_BRIGHT: { auto snp = getscannerinfo(); addr == SR_FLAT_CLR_MAX_BRIGHT ? snp.clr_maxbright = val : snp.gray_maxbright = val; savescannerinfo(snp); return true; } case SR_GET_KERNEL_VERSION: { std::string cmd = "uname -a"; char version[1024]; get_system_output(const_cast(cmd.c_str()), version, sizeof(version)); std::string str_version(version); transmit->write_bulk(const_cast(str_version.c_str()), str_version.length()); return true; } case SR_SET_SPEEDMODE: { auto info = getscannerinfo(); #ifdef G200 if (val == 100 || val == 140 || val == 110 || val == 120 || val == 130) info.speedmode = val; #else if (val == 100 || val == 70 || val == 80 || val == 90 || val == 110) info.speedmode = val; #endif savescannerinfo(info); return true; } case SR_GET_IPADDR: { char buf[1024]={0}; get_system_output("sudo ifconfig eth0 | awk '/inet /{print substr($2,1)}'",buf,sizeof(buf)); std::string ip = std::string(buf); transmit->write_bulk(&ip[0],ip.length()); return true; } case SR_GET_MACADDR: { char buf[1024]={0}; get_system_output("sudo ifconfig eth0 | awk '/ether /{print substr($2,1)}'",buf,sizeof(buf)); std::string ip = std::string(buf); transmit->write_bulk(&ip[0],ip.length()); return true; } case SR_GET_MBVERSION: { transmit->write_bulk(&scanner->getmbversion()[0],scanner->getmbversion().length()); return true; } case SR_SET_USBVIDPID: { USBVIDPID vidpid=*(USBVIDPID*)&val; auto info = getscannerinfo(); printf("set vid = %d pid = %d \n",vidpid.param.VID,vidpid.param.PID); if(vidpid.param.VID!=0 && vidpid.param.PID!=0) { info.Vid = vidpid.param.VID; info.Pid = vidpid.param.PID; std::string cmd = "/etc/mdfusbconfig " + std::to_string(vidpid.param.VID)+" "+std::to_string(vidpid.param.PID); system(cmd.c_str()); savescannerinfo(info); } else printf("error vid pid value\n"); break; } case SR_SET_JSON_PATH: { std::string path; path.resize(val); recieve->read_bulk(&path[0],val); jsonpath = path; printf("\n %s size =%d",path.c_str(),val); return true; } case SR_GET_JSON: { std::fstream i; i.open(jsonpath.c_str(),std::ios::in|std::ios::binary); std::string buff; int bufsize = val < 512*1024 ? val : 512*1024; int touch = 0; buff.resize(val); i.seekp(file_pos,std::ios::beg); while(touch < val) { i.read(&buff[0],bufsize); transmit->write_bulk(&buff[0],bufsize); touch += bufsize; bufsize = bufsize > val -touch ? val -touch : bufsize; printf("\nget file size =%d ",touch); } i.close(); return true; } case SR_SET_JSON: { std::string buff; std::fstream out; out.open(jsonpath.c_str(),std::ios::out|std::ios::binary); buff.resize(val); int bufsize = val < 512*1024 ? val : 512*1024; int touch = 0; out.seekg(file_pos,std::ios::beg); while(touch < val){ recieve->read_bulk(&buff[0],bufsize); out.write(&buff[0],bufsize); touch += bufsize; bufsize = bufsize > val -touch ? val -touch : bufsize; printf("\nget file size =%d ",touch); } out.close(); return true; } case SR_SET_FILE_POS: { file_pos = val; return true; } case SR_SET_LOCK_STATES: { printf("\n SR_SET_LOCK_STATES %d",val); DeviceConfig tmp; auto param = tmp.GetParam(); param.is_lock = val == 1 ? true : false; tmp.SaveParam(param); return true; } case SR_SET_TOKEN: { if(val < 1) return true; std::string token; token.resize(val); recieve->read_bulk(&token[0],val); auto decode_token = Base64().Decode(token.c_str(),token.length()); printf("\n SR_SET_TOKEN %s",decode_token.c_str()); if(decode_token.length()<2) return true; for(int i =1;iread_bulk(&token[0],val); m_token = token; printf("\n token = "); for(int i =0;iwrite_bulk(&tmp[0],val); return true; } default: break; } return false; } bool ScannerRegAccess::read(unsigned int addr, unsigned int &val) { printf("ScannerRegAccess::read(%d, %d)\n", addr, val); switch (addr) { case SR_STATUS: val = scanner->is_runscan() | ((!usbimages->empty()) << 1) | scanner->paper_ready() << 2; LOG_TRACE(string_format("run status:%d", val)); return true; case SR_SCAN_COUNT: val = scanner->count(); return true; case SR_GET_MBSTATUS: val = scanner->getmbstatus(); return true; case SR_GET_IMAGEPROCESSDONE: val = scanner->getimageprocedone(); return true; case SR_OS: val = scanner->mode(); return true; case SR_IM_COUNT: val = usbimages->size(); //printf("\nusbimages->size =%d",val); return true; case SR_IM_FRONT_SIZE: if (!usbimages->size()) { LOG_TRACE("\nGet image size , USBimage size =0"); return false; } val = usbimages->front_datasize(); return true; case SR_IM_TXING: val = transmit->is_writing(); return true; case SR_UPDATA_STAUTUS: val = (int)m_upstautus; printf("\nm_upstautus value =%d", m_upstautus); return true; case SR_UPDATA_MD5_RELUST: { std::fstream updateResult("/userdata/md5_result.log"); if (!updateResult.is_open()) val = 0; else { updateResult >> val; updateResult.close(); } if (val == 2) m_upstautus = Updata_Stautus::MD5_Rboot; else if (val == 3) m_upstautus = Updata_Stautus::MD5_Reovery; else m_upstautus = Updata_Stautus::MD5_Error; return true; } case SR_UPDATA_RECOVERY: { if (m_upstautus == Updata_Stautus::MD5_Reovery) { system("update ota /userdata/updatefile/update.img"); } return true; } case SR_UPDATA_REBOOT: { if (m_upstautus == MD5_Rboot) { system("reboot"); } return true; } case SR_GET_CUO_ERROR: { jsonconfig js; auto info = js.getscannerinfo(); val = info.FeedErrorTimes; return true; } case SR_GET_DOU_ERROR: { jsonconfig js; auto info = js.getscannerinfo(); val = info.DoubleFeedTimes; return true; } case SR_GET_JAM_ERROR: { jsonconfig js; auto info = js.getscannerinfo(); val = info.JamTimes; return true; } case SR_GET_SCANN_NUM: { jsonconfig js; auto info = js.getscannerinfo(); val = info.TotalScanned; return true; } case SR_CLR_ROLLER_NUM: { jsonconfig js; auto info = js.getscannerinfo(); info.RollerNum = 0; js.savescannerinfo(info); return true; } case SR_GET_ROLLER_NUM: { jsonconfig js; auto info = js.getscannerinfo(); val = info.RollerNum; printf(" info.RollerNum =%d", info.RollerNum); return true; } case SR_CLR_SCANN_NUM: { jsonconfig js; auto info = js.getscannerinfo(); info.RollerNum = 0; js.savescannerinfo(info); return true; } case SR_GET_SERIAL_LEN: case SR_GET_H_RATIO: case SR_GET_V_RATIO: { return procscannerinfo(addr, val); } case SR_GET_GRAY_SP: { val = jsonconfig().getscannerinfo().gray_sp; return true; } case SR_GET_COLOR_SP: { val = jsonconfig().getscannerinfo().color_sp; return true; } case SR_GET_SLEEPTIME: { val = scanner->get_sleeptime(); return true; } case SR_GET_SLEEP_STAUTUS: { val = scanner->get_sleepstatus(); return true; } case SR_GET_KEEP_LAST_PAPER: { val = scanner->get_keeplastpaper(); printf("\nget_keeplastpaper =%d ", val); return true; } case SR_FLAT_CLR_MAX_BRIGHT: case SR_FLAT_GRAY_MAX_BRIGHT: { auto snp = getscannerinfo(); val = addr == SR_FLAT_CLR_MAX_BRIGHT ? snp.clr_maxbright : snp.gray_maxbright; return true; } case SR_KERNEL_VERSION_INFO_LENGTH: { std::string cmd = "uname -a"; char version[1024]; get_system_output(const_cast(cmd.c_str()), version, sizeof(version)); std::string str_version(version); val = str_version.length(); return true; } case SR_GET_PAPERON: val = scanner->getpaperon(); return true; case SR_GET_SPEEDMODE: { val = getscannerinfo().speedmode; printf("\n SR_GET_SPEEDMODE %d ",val); return true; } case SR_GET_IPADDR_LENGHT: { char buf[1024]={0}; get_system_output("sudo ifconfig eth0 | awk '/inet /{print substr($2,1)}'",buf,sizeof(buf)); val= std::string(buf).length(); printf("\n ip = %s lenght =%d",buf,val); return true; } case SR_GET_MBVERSION_LENGHT: { val = scanner->getmbversion().length(); return true; } case SR_GET_USBVIDPID: { auto info = getscannerinfo(); USBVIDPID vidpid; vidpid.param.VID = info.Vid; vidpid.param.PID = info.Pid; val = vidpid.value; return true; } case SR_GET_JOSN_SIZE: { struct stat buff; val = 0; printf("\n json path =%s ",jsonpath.c_str()); if (stat(jsonpath.c_str(), &buff) == 0)//存在 { val = buff.st_size; printf("\n json size =%d ",val); } return true; } case SR_GET_FILE_POS: { val = file_pos; return true; } case SR_GET_LOCK_STATES: { val = DeviceConfig().GetParam().is_lock; return true; } case SR_GET_TOKEN_LENGHT: { auto tmp = DeviceConfig().GetParam().token; tmp = Base64().Encode((const uchar*)tmp.c_str(),tmp.length()); val = tmp.length(); return true; } break; default: break; } return false; } bool ScannerRegAccess::cmd(const unsigned int val) { switch (val) { case SC_START: scanner->try_scan(m_token); m_token = "null"; return true; case SC_STOP: scanner->stop_scan(); return true; case SC_CLEAR: scanner->clear_error(); return true; default: break; } return false; } bool ScannerRegAccess::procscannerinfo(unsigned int addr, unsigned int &value) { bool ret = true; auto info = getscannerinfo(); switch (addr) { case SR_SET_SERIALNUM: { printf("SR_SET_SERIALNUM length = %d \n", value); std::string serial; if (value > 0) { serial.resize(value); recieve->read_bulk(&serial[0], value); info.SerialNum = serial; } else ret = false; break; } case SR_GET_SERIALNUM: transmit->write_bulk(&info.SerialNum[0], info.SerialNum.length()); break; case SR_GET_SERIAL_LEN: value = info.SerialNum.length(); break; case SR_GET_H_RATIO: value = info.H_ratio; break; case SR_SET_H_RATIO: { float fx = *((float *)&value); if (fx > 1.2f || fx < 0.8f) break; info.H_ratio = value; break; } case SR_GET_V_RATIO: value = info.V_ratio; break; case SR_SET_V_RATIO: { float fy = *((float *)&value); if (fy > 1.2f || fy < 0.8f) break; info.V_ratio = value; break; } default: ret = false; break; } savescannerinfo(info); return ret; } void ScannerRegAccess::write_info(std::string info) { if (transmit.get()) { auto ret = transmit->write_bulk(const_cast(info.c_str()), info.length()); LOG_TRACE(string_format("write info error !with info =%s ", info.c_str())); } }