#include "stdafx.h" #include #include #include #include "All.h" #include "MACHINE_DPC.h" #include "MACHINE_Logical.h" #include "PacketAnalizer.h" #ifdef CMD_ANSYNC #include "RingBuffer.h" #endif #ifdef _WIN64 #ifdef _DEBUG const string SCFFile = "SerialSCFX64D.dll"; #else const string SCFFile = "SerialSCFX64.dll"; #endif #else #ifdef _DEBUG const string SCFFile = "SerialSCFD.dll"; #else const string SCFFile = "SerialSCF.dll"; #endif #endif #define MACHINERY_TID "DetectorToTableDistance" #define MACHINERY_SID "DistanceSourcetoDetector" #define MACHINERY_ENTRANCE "DistanceSourcetoEntrance" #define MACHINERY_PROJECTIONNUM "ProjectionNum" #define MACHINERY_MAXANGLE "ProjectionMaxAngle" #define MACHINERY_DIRECTION "ProjectionDirection" ///////////////////////////////////////////////////////////////////////// #define FUNNAME_CREATE_SCF TEXT("GetSCF") #define FUNNAME_RELEASE_SCF TEXT("ReleseSCF") #define OFFSET_CLASSNAME_DOSE 14 #define OFFSET_CLASSNAME_DOSE_SP 22 #define OFFSET_CLASSNAME_LOGIC 17 #define OFFSET_CLASSNAME_LOGIC_SP 25 #define CMD_LEN_MAX 128 #define TIMEOUTVALUE 1000 const int STX = 0x02; const int ETX = 0x03; CMACHINE_DPC::CMACHINE_DPC() { m_pWorkpath = new std::string(); m_SCFDllFileHandle = LoadLibrary(SCFFile.c_str()); if (m_SCFDllFileHandle) { m_fpGetSCF = (GetSCF)GetProcAddress(m_SCFDllFileHandle, "GetSCF"); m_pSCFServer = m_fpGetSCF(); m_pSCFServer->SetPassiveDisconnectEvt(GetPassiveDisConnectEvtHandle()); } else { DWORD errNo = GetLastError(); } m_DetectorToTableDistance.add(MACHINERY_TID, (FLOAT)0.0); m_DistanceSourcetoDetector.add(MACHINERY_SID, (FLOAT)1.0); m_DistanceSourcetoEntrance.add(MACHINERY_ENTRANCE, (FLOAT)15.0); m_ProjectionNum.add(MACHINERY_PROJECTIONNUM, (INT)15); m_ProjectionMaxAngle.add(MACHINERY_MAXANGLE, (FLOAT)15.0); m_ProjectionDirection.add(MACHINERY_DIRECTION, (INT)-1); m_pSendPacket = (SCFPacket *)MallocSCFPacket(); m_pReceivePacket = (SCFPacket *)MallocSCFPacket(); } CMACHINE_DPC::~CMACHINE_DPC() { ReleaseSCFPacket(m_pSendPacket); ReleaseSCFPacket(m_pReceivePacket); delete m_pWorkpath; } //bool CMACHINE_DPC::DpcEntry(ResDataObject &Configuration) //{ // try // { // m_DeviceConfig = Configuration; // } // catch (...) // { // PRINTA_INFO(m_pLog, "Can't get the Configuration for Device"); // } // PRINTA_INFO(m_pLog, "DpcEntry Configuration"); // // return true; //} // //ResDataObject CMACHINE_DPC::GetConnectionType() //{ // return ResDataObject(); //} // //bool CMACHINE_DPC::Connect(ResDataObject &Connection) //{ // m_pSCFServer = m_fpGetSCF(); // // int Result = m_pSCFServer->Connect(Connection, &CMACHINE_DPC::PackageProcess, SCF_PACKET_TRANSFER); // if (Result != SCF_SUCCEED) // { // return false; // } // // return true; //} // //bool CMACHINE_DPC::Probe(ResDataObject &HardwareInfo) //{ //#ifdef ENV_DIOS // HardwareInfo.add("MajorID", "Generator"); // HardwareInfo.add("MinorID", "DR"); // HardwareInfo.add("VendorID", "CPI"); // HardwareInfo.add("ProductID", "SHF"); // HardwareInfo.add("SerialID", "1234"); //#endif // return true; //} // //bool CMACHINE_DPC::SetWorkPath(const char *pWorkPath) //{ // m_strWorkPath = pWorkPath; // return true; //} // //PVOID CMACHINE_DPC::LoadLogicDevices() //{ // DevTree *pTree = new DevTree(); // LogicDevice * pLD = NULL; // // //Load DOSE Logic unit // m_pGenDose = new CMACHINE_Dose(); // m_pGenDose->DPCPoint(this); // pLD = (LogicDevice *)m_pGenDose; // pTree->Add((PVOID)pLD, TYPE_DEVICE); // // //Load SyncGen // m_pGenLogical = new CMACHINE_Logical(); // m_pGenLogical->DPCPoint(this); // pLD = (LogicDevice *)m_pGenLogical; // pTree->Add((PVOID)pLD, TYPE_DEVICE); // //#if 0 // try{ // m_pGenDose->m_DeviceConfig.nTable = (int)(m_DeviceConfig["Table"]); // m_pGenDose->m_DeviceConfig.nWall = (int)(m_DeviceConfig["Wall"]); // m_pGenDose->m_DeviceConfig.nFree = (int)(m_DeviceConfig["Free"]); // m_pGenDose->m_DeviceConfig.nTomo = (int)(m_DeviceConfig["Tomo"]); // m_pGenDose->m_DeviceConfig.nConventional = (int)(m_DeviceConfig["Conventional"]); // } // catch (...) // { // printf("Get Gen config item Crash.\n"); // } //#endif // return (PVOID)pTree; //} // //void CMACHINE_DPC::UnloadLogicDevices(/*LogicDevice*/PVOID p) //{ //#ifdef ENV_DIOS // DevTree *pTree = (DevTree*)p; // size_t Size = pTree->size(); // for (size_t i = 0; i < Size; i++) // { // DevTreeNode node = (*pTree)[i]; // if (node.m_NodeType == TYPE_DEVICE) // { // LogicDevice *pdev = (LogicDevice*)node.m_pObject; // delete pdev; // } // else // { // //tree dev // //do not copy this!!!! // UnloadLogicDevices(node.m_pObject); // } // } // // delete pTree; //#endif //} // //bool CMACHINE_DPC::DisConnect() //{ // m_pSCFServer->Disconnect(); // m_fpReleaseSCF(m_pSCFServer); // return true; //} // //bool CMACHINE_DPC::OnNotify(HANDLE ExitNotify) //{ // Work(); // return true; //} bool CMACHINE_DPC::DriverEntry(ResDataObject &Configuration) { try { m_DeviceConfig = Configuration; } catch (...) { PRINTA_INFO(m_pLog, "Can't get the Configuration for Device"); } PRINTA_INFO(m_pLog, "DpcEntry Configuration"); return LogicDriver::DriverEntry(Configuration); } bool CMACHINE_DPC::Driver_Probe(ResDataObject &HardwareInfo) { HardwareInfo.add("MajorID", "Machine"); HardwareInfo.add("MinorID", "DR"); HardwareInfo.add("VendorID", "SiemensTOMO"); HardwareInfo.add("ProductID", "TOMO"); HardwareInfo.add("SerialID", "DRVOBJ"); return true; } bool SYSTEM_CALL CMACHINE_DPC::SetDriverWorkPath(const char * PARAM_IN pWorkPath) { return true; } PVOID SYSTEM_CALL CMACHINE_DPC::LoadDriver() { return NULL; } void SYSTEM_CALL CMACHINE_DPC::UnloadDriver() { } bool CMACHINE_DPC::Connect() { ResDataObject Connection = GetConnectionParam(); PRINTA_INFO(m_pLog, "Connection[0]= %s", Connection[0].encode()); printf("Connection[0]= %s", Connection[0].encode()); int Result = m_pSCFServer->Connect(Connection[0], &CMACHINE_DPC::PackageProcess, SCF_PACKET_TRANSFER); if (Result != SCF_SUCCEED) { LogicDriver::DisConnect(); return false; } if (!OnHeartBeat()) { LogicDriver::DisConnect(); return false; } //Load Command Send Thread LogicDriver::Connect();//make sure it's connected return true; } bool CMACHINE_DPC::Device_Probe(ResDataObject &HardwareInfo) { HardwareInfo.add("MajorID", "Machine"); HardwareInfo.add("MinorID", "DR"); HardwareInfo.add("VendorID", "SiemensTOMO"); HardwareInfo.add("ProductID", "TOMO"); HardwareInfo.add("SerialID", "1234"); return true; } bool CMACHINE_DPC::SetDeviceWorkPath(const char *pWorkPath) { (*m_pWorkpath) = pWorkPath; //要把读取单一硬件属性的过程放到此处 return true; } PVOID CMACHINE_DPC::LoadLogicDevices() { DevTree *pTree = (DevTree *)GetDeviceTree(); m_pGenLogical = new CMACHINE_Logical(); m_pGenLogical->DPCPoint(this); LogicDevice *pret = (LogicDevice *)m_pGenLogical; pTree->Add((PVOID)pret, TYPE_DEVICE); m_bStatusFlag = true; return (PVOID)pTree; } void CMACHINE_DPC::UnloadLogicDevices() { m_bStatusFlag = false; DevTree *pTree = (DevTree *)GetDeviceTree(); size_t Size = pTree->size(); for (size_t i = 0; i < Size; i++) { DevTreeNode node = (*pTree)[i]; if (node.m_NodeType == TYPE_DEVICE) { LogicDevice *pdev = (LogicDevice*)node.m_pObject; delete pdev; } else { //tree dev //do not copy this!!!! //UnloadLogicDevices(node.m_pObject); } } pTree->clear(); PRINTA_INFO(m_pLog, "UnLoad Over"); } void CMACHINE_DPC::DisConnect() { m_pSCFServer->Disconnect(); //unload dpc ReleaseSCF dpcSCFfunc = (ReleaseSCF)GetProcAddress(m_SCFDllFileHandle, "ReleseSCF"); if (dpcSCFfunc) { dpcSCFfunc(m_pSCFServer); } LogicDriver::DisConnect(); } bool SYSTEM_CALL CMACHINE_DPC::OnHeartBeat() { return true; } RET_STATUS SYSTEM_CALL CMACHINE_DPC::GetDeviceResource(ResDataObject PARAM_OUT *pDeviceResource) { RET_STATUS rs = LogicDriver::GetDeviceResource(pDeviceResource); bool ret = true; ResDataObject val = (*pDeviceResource)["Attribute"]; //val.add(MACHINERY_READY, m_MachineryReady[MACHINERY_READY]); val.add(MACHINERY_TID, m_DetectorToTableDistance[MACHINERY_TID]); val.add(MACHINERY_SID, m_DistanceSourcetoDetector[MACHINERY_SID]); val.add(MACHINERY_ENTRANCE, m_DistanceSourcetoEntrance[MACHINERY_ENTRANCE]); val.add(MACHINERY_PROJECTIONNUM, m_ProjectionNum[MACHINERY_PROJECTIONNUM]); val.add(MACHINERY_MAXANGLE, m_ProjectionMaxAngle[MACHINERY_MAXANGLE]); val.add(MACHINERY_DIRECTION, m_ProjectionDirection[MACHINERY_DIRECTION]); ret &= pDeviceResource->update("Attribute", val); if (ret) { return RET_SUCCEED; } return RET_FAILED; } DWORD SYSTEM_CALL CMACHINE_DPC::OnNotify(HANDLE evtList[], DWORD count) { char pPacket[MAX_STRING] = { 0 }; char pTempPacket[MAX_STRING] = { 0 }; int nLength = MAX_STRING; int nTimeout = 1000; int nPacketLen = 0; string strTempCmd; HANDLE hSCFHandle = m_pSCFServer->GetScfNotifyHandle(); HANDLE pHandlArray[MAXIMUM_WAIT_OBJECTS] = { 0 }; DWORD HandleCount = 0; for (HandleCount = 0; HandleCount < count; HandleCount++) { pHandlArray[HandleCount] = evtList[HandleCount]; } pHandlArray[HandleCount++] = hSCFHandle; DWORD dwResult = WaitForMultipleObjects(HandleCount, pHandlArray, FALSE, INFINITE); if ((dwResult >= WAIT_OBJECT_0) && (dwResult < WAIT_OBJECT_0 + HandleCount - 1)) { PRINTA_INFO(m_pLog, "OnNotify Platform"); return dwResult - WAIT_OBJECT_0; } else { if (LogicDriver::GetConnectionStatus() && true == m_bStatusFlag) { char Command[VALUELENGTH_MAX]; int PacketLength = VALUELENGTH_MAX; memset(Command, 0, VALUELENGTH_MAX); while (m_pSCFServer && (PacketLength = m_pSCFServer->DeQueNotifyPacket(Command, VALUELENGTH_MAX, TIMEOUTVALUE))>0) { OnCallback(Command, PacketLength); } } } return 1; } PACKET_RET CMACHINE_DPC::PackageProcess(const char * RecData, DWORD nLength, DWORD& PacketLength) { //判断是否是整包 /* 这个是回调函数,我收到的数据会需要这个回调函数帮我判断是否是整个的包; 如果有整个的包,返回值为true,在PacketLength处返回给我整个包的长度,我再截取后放入缓存供上层使用; 如果缓存中的数据没有整个的数据包,那么返回false */ if (nLength < 2) { return PACKET_NOPACKET; } unsigned char chsend, chend; chsend = 0x0d; chend = 0x0a; for (size_t i = 0; i < nLength; i++) { if ((RecData[i] == chsend) && (RecData[i + 1] == chend)) { PacketLength = i + 2; /*char szContext[40] = { 0 }; memset(szContext, 0, 40); memcpy(szContext, RecData, PacketLength); printf("Got Packet:%s\n", szContext);*/ return PACKET_ISPACKET; } } return PACKET_NOPACKET; } bool CMACHINE_DPC::SetupStitching(int nImageCount, int nDirection, int nInitialHeight, int nStitchLength, int nStepLength, int nSID, int nStitchType) { m_nImageCount = nStitchLength / nStepLength; m_nCurrentImage = 1; //code begin 20101125 if (m_nImageCount < 2) { m_nImageCount = 2; TPRINTA_WARN("The image count is not correct"); } else if (m_nImageCount > 4) { m_nImageCount = 4; TPRINTA_WARN("The image count is not correct"); } //code end 20101125 if (nDirection)//up down, now just support two direction { nDirection = 1; } else { nDirection = 2;//down up } if (nStitchType == 0) { nStitchType = 0;//line } else { nStitchType = 1;// Angle } TPRINTA_INFO("Image index = %d, total images %d", m_nCurrentImage, m_nImageCount); char strcommand[100]{""}; sprintf_s(strcommand, "USP%02d%02d%d%02d%03d%03d%03d", m_nImageCount, nDirection, nStitchType, nStepLength, nInitialHeight, nSID, nStitchLength); SendCommandWithoutAck(strcommand); return true; } int CMACHINE_DPC::SendCommandWithoutAck(char* strCommand, int nTimeOut) { int len = strlen(strCommand); if (len <= 0) { return -1; } int sum = 0; for (int i = 0; i < len; i++) { sum += strCommand[i]; } sum = sum + (0x02) + (0x03); char xorResult = sum & 0xFF; char strSendCommand[100] = { 0 }; strSendCommand[0] = STX; for (int i = 0; i < len; i++) { strSendCommand[i + 1] = strCommand[i]; } strSendCommand[len + 1] = ETX; strSendCommand[len + 2] = xorResult; //增加SCF发送机制 //SCFPacket* SCFCommand; //SCFCommand = new SCFPacket(); m_pSendPacket->SetPacket(strSendCommand, strlen(strSendCommand)); int bResult; PRINTA_TRACE(m_pLog, "== OUT ==: Begin: %s, Time: %d\n", strCommand, GetTickCount()); if (m_pSCFServer) { m_pSCFServer->SCFLock(TIMEOUTVALUE); m_strCurrentCommand = strCommand; bResult = m_pSCFServer->SendPacket(m_pSendPacket, nTimeOut); m_pSCFServer->SCFUnLock(); Sleep(50); PRINTA_TRACE(m_pLog, "== OUT ==: End: %s, Time: %d\n", strCommand, GetTickCount()); } return bResult; } ///////////////////////////////////////////////////////////////////////// RET_STATUS SYSTEM_CALL CMACHINE_DPC::GetDriverDictionary(ResDataObject& PARAM_OUT DriverInfo) { DriverInfo.add("DriverType", "PositionMachine"); DriverInfo.add("DeviceName", "SiemensTOMO"); DriverInfo.add("DateOfManufacture", "2019.4.12"); DriverInfo.add("SoftwareVersion", "Alpha1.0"); DriverInfo.add("HardwareVersion", "Alpha1.0"); DriverInfo.add("Description", "None"); DriverInfo.add("Properties", "None"); return RET_SUCCEED; } struct tFrameMapping { static const int MaxLen = 5; // 前缀不能超超过 5 个字符 ! using cbFun = std::function ; char strHead[MaxLen]; int NbOfCharOfHead; cbFun fun; tFrameMapping(char * str, int len, cbFun f) { assert(len < MaxLen); for (int i = 0; i < len; i++) strHead[i] = str[i]; NbOfCharOfHead = len; fun = f; } }; static std::list arFrame; static bool DecodeFrame(const char* strFrame, int length); size_t CMACHINE_DPC::OnCallback(const char * strPackage, size_t nLength) { auto HWNotProcess = [](const char * value, int length) -> void { TPRINTA_WARN("This commands didn't need to process!"); }; auto HWExitStitch = [this](const char * value, int length) -> void { int ret = atoi(value); if (ret) { m_bStitchingInProgress = false; TPRINTA_INFO("Exit stitching state!"); } else { TPRINTA_ERROR("Exit stitching failed!"); } }; auto HWERROR = [this](const char* value, int length) { assert(value); int nValue = atoi(value); if (nValue != 0) { char ErrorCode[10]{ "" }; sprintf_s(ErrorCode, "OTC_ERROR_MSG_%03d", nValue); int level = 1; AddErrorMessage(ErrorCode, level, ""); } else { int level = 1; char ErrorCode[10]{ "" }; DelErrorMessage(ErrorCode, level, ""); } }; auto HWWARN = [this](const char* value, int length) { assert(value); int nValue = atoi(value); if (nValue != 0) { char ErrorCode[10]{ "" }; sprintf_s(ErrorCode, "OTC_WARN_MSG_%03d", nValue); int level = 1; AddErrorMessage(ErrorCode, level, "",1); } else { int level = 1; char ErrorCode[10]{ "" }; DelErrorMessage(ErrorCode, level, "",1); } }; auto HWExtraImage = [this](const char * value, int length) -> void { int ret = atoi(value); if (ret) { m_pGenLogical->MechStitch::NewExtraView(); TPRINTA_INFO("Extra image number!"); } else { TPRINTA_ERROR("Extra image number failed!"); } }; auto HWAcceptImage = [this](const char * value, int length) -> void { m_pGenLogical->MechStitch::AcceptStitchingImage(); }; auto HWRejectImage = [this](const char * value, int length) -> void { m_pGenLogical->MechStitch::RejectStitchingImage(); }; auto HWCurrentImage = [this](const char * value, int length) -> void { m_nCurrentImage = atoi(value); m_pGenLogical->MechStitch::UpdateCurrentImage(m_nCurrentImage); }; auto HWImageCount = [this](const char * value, int length) -> void { m_nImageCount = atoi(value); m_pGenLogical->MechStitch::UpdateImageCount(m_nImageCount); }; auto HWDriction = [this](const char * value, int length) -> void { int nStitchDirection = atoi(value); if (1 == nStitchDirection) { nStitchDirection = UP_TO_DOWN; } else if (2 == nStitchDirection) { nStitchDirection = DOWN_TO_UP; } else { //default nStitchDirection = UP_TO_DOWN; } m_pGenLogical->MechStitch::UpdateStitchDirection(nStitchDirection); }; auto HWStartStitch = [this](const char * value, int length) -> void { string strvalue = value; m_nImageCount = atoi(strvalue.substr(0,2).c_str()); m_nCurrentImage = 1; m_bStitchingInProgress = true; m_pGenLogical->MechStitch::UpdateImageCount(m_nImageCount); m_pGenLogical->MechStitch::UpdateCurrentImage(m_nCurrentImage); }; auto HWStitchState = [this](const char * value, int length) -> void { int nTemp = atoi(value); switch (nTemp) { case 1: { if (m_bStitchingInProgress == false) { m_bStitchingInProgress = true; //g_pLogFile->WriteLog("First image, SETUP_AVAIABLE;",LOG_INFORMATION,LOG_DEBUG,true); //::PostMessage(m_hWnd,MSG_STITCHING_PARAM,STITCH_PARAM_SETUP_AVAIABLE,NULL); } TPRINTA_INFO("First image, SETUP_AVAIABLE;"); break; } case 2: { if (m_bStitchingInProgress) { TPRINTA_INFO("Need move to the position !"); } break; } case 3: { if (m_bStitchingInProgress) { //::PostMessage(m_hWnd, MSG_STITCHING_PARAM, STITCH_PARAM_HW_STATUS, HW_NOT_READY); if (m_nCurrentImage == 1) { TPRINTA_INFO("First image, SETUP_MOVING;"); //::PostMessage(m_hWnd, MSG_STITCHING_PARAM, STITCH_PARAM_SETUP_MOVING, NULL); } else { TPRINTA_INFO("Moving to next position ;"); //::PostMessage(m_hWnd, MSG_STITCHING_PARAM, STITCH_PARAM_MOVING_STEP, NULL); } } break; } case 4: { if (m_bStitchingInProgress) { //::PostMessage(m_hWnd, MSG_STITCHING_PARAM, STITCH_PARAM_HW_STATUS, HW_READY); TPRINTA_INFO("Ready for exposure ;"); //::PostMessage(m_hWnd, MSG_STITCHING_PARAM, STITCH_PARAM_EXP_READY, NULL); } break; } case 5: { if (m_bStitchingInProgress) { m_bStitchingInProgress = false; } break; } case 6: { if (m_bStitchingInProgress == false) { m_bStitchingInProgress = true; //g_pLogFile->WriteLog("First image, SETUP_AVAIABLE;",LOG_INFORMATION,LOG_DEBUG,true); //::PostMessage(m_hWnd,MSG_STITCHING_PARAM,STITCH_PARAM_SETUP_AVAIABLE,NULL); } //::PostMessage(m_hWnd, MSG_STITCHING_PARAM, STITCH_PARAM_SETUP_RECEIVED, NULL); break; } case 7: { if (m_bStitchingInProgress == false) { m_bStitchingInProgress = true; //g_pLogFile->WriteLog("First image, SETUP_AVAIABLE;",LOG_INFORMATION,LOG_DEBUG,true); //::PostMessage(m_hWnd,MSG_STITCHING_PARAM,STITCH_PARAM_SETUP_AVAIABLE,NULL); } TPRINTA_INFO("First image, SETUP_AVAIABLE;"); //::PostMessage(m_hWnd, MSG_STITCHING_PARAM, STITCH_PARAM_SETUP_AVAIABLE, NULL); break; } case 8: { break; } case 9: { if (m_bStitchingInProgress) { //::PostMessage(m_hWnd, MSG_STITCHING_PARAM, STITCH_PARAM_HW_STATUS, HW_READY); TPRINTA_INFO("Setup position reached ,Send SS to start produce;"); //::PostMessage(m_hWnd, MSG_STITCHING_PARAM, STITCH_PARAM_SETUP_REACHED, NULL); } break; } case 10: { if (m_bStitchingInProgress) { TPRINTA_INFO(" Position reached;"); //::PostMessage(m_hWnd, MSG_STITCHING_PARAM, STITCH_PARAM_POSITION_REACHED, NULL); } break; } case 11: { if (m_bStitchingInProgress) { TPRINTA_INFO(" Extra image reached;"); //::PostMessage(m_hWnd, MSG_STITCHING_PARAM, STITCH_PARAM_EXTRA_IMAGE_REACHED, NULL); } break; } default: break; } }; // arFrame.clear(); arFrame.push_back(tFrameMapping("UCS", 3, HWExitStitch)); arFrame.push_back(tFrameMapping("USE", 3, HWExitStitch)); arFrame.push_back(tFrameMapping("UER", 3, HWERROR)); arFrame.push_back(tFrameMapping("UEX", 3, HWExtraImage)); arFrame.push_back(tFrameMapping("USA", 3, HWAcceptImage)); arFrame.push_back(tFrameMapping("USC", 3, HWCurrentImage)); arFrame.push_back(tFrameMapping("USD", 3, HWDriction)); arFrame.push_back(tFrameMapping("USJ", 3, HWRejectImage)); arFrame.push_back(tFrameMapping("USR", 3, HWNotProcess)); arFrame.push_back(tFrameMapping("USM", 3, HWNotProcess)); arFrame.push_back(tFrameMapping("USN", 3, HWImageCount)); arFrame.push_back(tFrameMapping("USP", 3, HWStartStitch)); arFrame.push_back(tFrameMapping("USS", 3, HWNotProcess)); arFrame.push_back(tFrameMapping("UST", 3, HWStitchState)); arFrame.push_back(tFrameMapping("UWN", 3, HWWARN)); return nLength; } //----------------------------------------------------------------------------- // DecodeFrame //----------------------------------------------------------------------------- static bool DecodeFrame(const char* strFrame, int length) { auto pr = [strFrame, length](const tFrameMapping& Item) { for (int i = 0; i < Item.NbOfCharOfHead; i++) { if (strFrame[i] != Item.strHead[i]) { return false; } } return true; }; auto found = std::find_if(arFrame.begin(), arFrame.end(), pr); if (found == arFrame.end()) { return false; } const auto& Item = *found; auto pc = strFrame; pc += Item.NbOfCharOfHead; Item.fun(pc, length - Item.NbOfCharOfHead); return true; }