// DIOS.Dev.GEN.DEMO.cpp : 定义 DLL 应用程序的导出函数。 // #include "stdafx.h" #include "FileVersion.hpp" #include "CommonFun.h" #include "DIOS.Dev.SyncBox.V2COM.h" #include "Helper.JSON.hpp" #include "common_api.h" using namespace DIOS::Dev::Detail::SYNBOX; namespace nsSYN = DIOS::Dev::Detail::SYNBOX; static nsSYN::DynBoxDriver * pIODriver = nullptr; //关闭无关警告 #pragma warning (disable:4244) // warning C4244: “初始化”: 从“double”转换到“float”,可能丢失数据 #pragma warning (disable:4305) // warning C4305: “参数”: 从“double”到“float”截断 #pragma warning (disable:4267) // warning C4267: “初始化”: 从“size_t”转换到“int”,可能丢失数据 #pragma warning (disable:4805) // warning C4805: “!=”: 在操作中将类型“bool”与类型“int”混合不安全 #define C2COM_Com_NormalLen 45 #ifdef _WIN64 #ifdef _DEBUG static const auto COM_SCFDllName = "Dios.Dev.SerialSCFX64D.dll"; #else static const auto COM_SCFDllName = "Dios.Dev.SerialSCFX64.dll"; #endif #endif #ifdef _WIN64 #ifdef _DEBUG static const auto TCP_SCFDllName = "Dios.Dev.TcpipSCFX64D.dll"; #else static const auto TCP_SCFDllName = "Dios.Dev.TcpipSCFX64.dll"; #endif #endif using namespace DIOS::Dev::Detail::SYNBOX; namespace nsSYN = DIOS::Dev::Detail::SYNBOX; #define TIMEOUTVALUE 100 //发送间隔 atomic allSendInterval = TIMEOUTVALUE; //发送间隔 const char cCmd_heartbeat[5] = { 'E','C',0x0d ,0x0a ,0x00 };// "EC 回车 换行"; //vector m_MapChannel; ////----------------------------------------------------------------------------- //// DynBoxDevice ////----------------------------------------------------------------------------- std::unique_ptr nsSYN::SyncBoxDevice::m_pCollDev = nullptr; //遮光器逻辑实体指针 std::unique_ptr nsSYN::SyncBoxDevice::m_pMechDev = nullptr; //机架逻辑实体指针 bool nsSYN::SyncBoxDevice::m_bHeartBeatFlag = false; bool nsSYN::SyncBoxDevice::m_bCANHBFlag = true; nsSYN::SyncBoxDevice::SyncBoxDevice(std::shared_ptr center, nsSCF::SCF SCF, string configfile) : super(center, SCF) { ResDataObject temp; temp.loadFile(configfile.c_str()); m_SYNConfig = temp["CONFIGURATION"]; TransJsonText(m_SYNConfig); m_SynBoxUnit.m_WS.reset(new WORKSTATIONMould("")); m_SynBoxUnit.m_CurrentExpNumber.reset(new CUREXPNUMMould(0, 0, 10000, 1)); m_SynBoxUnit.m_HandSwitchState.reset(new HANDSWITCHMould(0, 0, 10000, 1)); m_SynBoxUnit.m_GenSynState.reset(new GENSYNSTATEMould(0, 0, 10000, 1)); m_SynBoxUnit.m_TotalExpNumber.reset(new TOTALEXPNUMMould(0, 0, 10000, 1)); m_SynBoxUnit.m_DetectorState.reset(new DETECTORSTATUSMould(0, 0, 10000, 1)); m_SynBoxUnit.m_DetectorWindowState.reset(new XWINDOWSTATUSMould(AttrKey::XWINDOW_OFF, AttrKey::XWINDOW_OFF, AttrKey::XWINDOW_ON, 1)); m_SynBoxUnit.m_ExpMode.reset(new EXPMODEMould("")); m_SynBoxUnit.m_GridStatue.reset(new GRIDSYNSTATEMould(0, 0, 20, 1)); m_MSGUnit.reset(new nsDetail::MSGUnit(center, SyncConsoleUnitType)); m_pHardwareThread = nullptr; m_iHeartBeats = 0; m_iConnectFlag = 3; m_bSetBaudOK = false; m_hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hLoopBeginEvent = CreateEvent(NULL, TRUE, TRUE, NULL); m_hLoopEndEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hArrayEvent[0] = m_hExitEvent; m_hArrayEvent[1] = m_hLoopBeginEvent; Register(); OnCallBack(); #if 1 //暂不启用断线检测 StartHardwareThread(); #endif //CAN口日志打印标志 if (m_SYNConfig.GetKeyCount("CanLogEnableFlag") > 0) { m_bCanLogEnableFlag = (int)m_SYNConfig["CanLogEnableFlag"]; } //允许给图像发报文 SetSendMessageEnable(2); //预压迫和全压迫设置信息 int nforePressureLimit = 25, nAllPressureLimit = 55; if (m_SYNConfig.GetKeyCount("ForePressureLimit") > 0 && m_SYNConfig.GetKeyCount("AllPressureLimit") > 0) { nforePressureLimit = (int)m_SYNConfig["ForePressureLimit"]; nAllPressureLimit = (int)m_SYNConfig["AllPressureLimit"]; } SetPressureLimit(nforePressureLimit, nAllPressureLimit); //压迫模式 if (m_SYNConfig.GetKeyCount("OppressiveMode") > 0) { m_bOppressiveMode = (int)m_SYNConfig["OppressiveMode"]; } //振栅模式 if (m_SYNConfig.GetKeyCount("GridMode") > 0) { m_bGridMode = (int)m_SYNConfig["GridMode"]; } //与发生器通信 #if Dios_V3 m_pGenClient = new LogicClient("V2COM_DM", "NSQ", "", false); if (m_pGenClient->Open("diosChannel", ALL_ACCESS)) { mLog::Debug("Dios_V3 Create V2COM_DM Client success"); } #endif //震动栅MS余量 if (m_SYNConfig.GetKeyCount("GridMSMargin") > 0) { string tempValue = m_SYNConfig["GridMSMargin"]; int pos = tempValue.find(','); if (pos != string::npos) { m_iGridMSRadMargin = atoi(tempValue.substr(0, tempValue.find(',')).c_str()); //Rad GridMS m_iGridMSRadMargin = 50; m_iGridMSAECMargin = atoi(tempValue.substr(tempValue.find(',') + 1).c_str()); //AEC GridMS m_iGridMSAECMargin = 50; } } mLog::Debug("GridMSRadMargin[{$}],GridMSAECMargin[{$}]", m_iGridMSRadMargin, m_iGridMSAECMargin); //滤过数值 if (m_SYNConfig.GetKeyCount("FilterMO") > 0) { m_iFilterMO = (int)m_SYNConfig["FilterMO"]; } if (m_SYNConfig.GetKeyCount("FilterRH") > 0) { m_iFilterRH = (int)m_SYNConfig["FilterRH"]; } mLog::Debug("FilterMO[{$}],FilterRH[{$}]", m_iFilterMO, m_iFilterRH); m_SCF.DecodePack(true); } nsSYN::SyncBoxDevice::~SyncBoxDevice() { SetCANState(false); SetEvent(m_hLoopEndEvent); SetEvent(m_hExitEvent); Sleep(2000); if (m_pHardwareThread != NULL) { TerminateThread(m_pHardwareThread, 0); m_pHardwareThread = NULL; } if (!(m_SCF.isConnected())) { mLog::Info("Call UnloadLogicDevices because Lost connect"); //ReConnect(true); } #if Dios_V3 if (m_pGenClient) { if (!m_pGenClient->IsClosed()) { m_pGenClient->Close(); } delete m_pGenClient; m_pGenClient = NULL; } #endif m_pCollDev.release(); m_pCollDev = nullptr; m_pMechDev.release(); m_pMechDev = nullptr; } std::string nsSYN::SyncBoxDevice::GetGUID() const { mLog::Info("===============Device GetGUID : {$} ===================", SyncConsoleUnitType); return SyncConsoleUnitType; } void nsSYN::SyncBoxDevice::Register() { auto Disp = &Dispatch; superSYN::Register(Disp); Disp->Get.Push(m_MSGUnit->GetKey().c_str(), [this](std::string& out) { out = m_MSGUnit->JSGet(); return RET_STATUS::RET_SUCCEED; }); //手动信号调试 auto fun_DebugSignal = [this](auto in, auto& out) { auto value = JSONTo (in); return DebugSignal(value); }; Disp->Action.Push("DebugSignal", fun_DebugSignal); auto fun_SendSignal = [this](auto in, auto& out) { ResDataObject json; json.decode(in.c_str()); auto value = (string)json[0]; return SendSignal(value); }; Disp->Action.Push("SendSignal", fun_SendSignal); //曝光流程 auto fun_SetExposureProcess = [this](auto in, auto& out) { auto value = JSONTo (in); return SetExposureProcess(value); }; Disp->Action.Push("SetExposureProcess", fun_SetExposureProcess); //压迫器手动释放按键 auto fun_SetPressureManualRelease = [this](auto in, auto& out) { return SetPressureManualRelease(); }; Disp->Action.Push("SetPressureManualRelease", fun_SetPressureManualRelease); //震动栅起振 auto fun_StartVibrateGrid = [this](auto in, auto& out) { return StartVibrateGrid(); }; Disp->Action.Push("StartVibrateGrid", fun_StartVibrateGrid); auto fun_StopVibrateGrid = [this](auto in, auto& out) { return StopVibrateGrid(); }; Disp->Action.Push("StopVibrateGrid", fun_StopVibrateGrid); } void nsSYN::SyncBoxDevice::FireNotify(std::string key, std::string content) { EventCenter->OnNotify(1, key, content); } void nsSYN::SyncBoxDevice::FireErrorMessage(const bool Act, const int Code, const char* ResInfo) { string ErrorCode("SYNBOX_ERR_"); ErrorCode += std::to_string(Code); int level = 0; if (Act) { mLog::Error("add {$}:{$}", ErrorCode.c_str(), ResInfo); m_MSGUnit->AddErrorMessage(ErrorCode.c_str(), level, ResInfo); } else { mLog::Error("del {$}:{$}", ErrorCode.c_str(), ResInfo); m_MSGUnit->DelErrorMessage(ErrorCode.c_str(), level, ResInfo); } } RET_STATUS nsSYN::SyncBoxDevice::HWSend(char* strCommand, int nTimeOut) { if (!m_SCF) return RET_STATUS::RET_FAILED; if (strncmp(strCommand, "CS", 2) != 0) mLog::Info("==OUT==:[{$}],len=[{$}]\n", strCommand, strlen((char*)strCommand)); int retLength; m_SCF.Lock(msTimeOut_Lock) .SendPacket((char*)strCommand, strlen((char*)strCommand), nTimeOut, retLength); SetWaitAction(strCommand); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::SendBySCF(const char* chChannelID, bool bStatus) { char cCmd[MAX_COMMAND_LEN] = { 0 }; cCmd[0] = chChannelID[0]; cCmd[1] = chChannelID[1]; if (bStatus) cCmd[2] = '1'; else cCmd[2] = '0'; int nSize = 3; FormatCmd(cCmd, nSize); string strLog; CmdtoString(cCmd, nSize, strLog); mLog::Info("[Send:{$}]", cCmd); if (!m_SCF) { mLog::Error("SCF is NULL"); return RET_STATUS::RET_FAILED; } mLog::Info("==OUT==:[{$}]", cCmd); int ret = 0; m_SCF.Lock(msTimeOut_Lock) .SendPacket(cCmd, nSize, TIMEOUTVALUE, ret); SetWaitAction(cCmd); return RET_STATUS::RET_SUCCEED; } void nsSYN::SyncBoxDevice::SendHeartBeat() { int nTimeout = 100; int ret = 0; if(m_bCanLogEnableFlag) mLog::Info("==OUT==: heartbeat[{$}] ", cCmd_heartbeat); m_SCF.Lock(msTimeOut_Lock) .SendPacket(cCmd_heartbeat, 4, nTimeout, ret); SetWaitAction(cCmd_heartbeat); } bool nsSYN::SyncBoxDevice::StartHardwareThread() { mLog::Info("enter Start HardwareStatus Thread "); if (m_pHardwareThread == NULL) { DWORD m_HardwareStatusID; m_pHardwareThread = CreateThread(0, 0, HardwareStatusThread, this, 0, &m_HardwareStatusID); if (m_pHardwareThread == NULL) { mLog::Error("Start HardwareStatus Thread Failed"); return false; } } return true; } DWORD nsSYN::SyncBoxDevice::HardwareStatusThread(LPVOID pParam) { SyncBoxDevice* pCurSyn = (SyncBoxDevice*)pParam; if (pCurSyn == NULL) { return false; } mLog::Info("HardwareStatusThread start"); if (pCurSyn->m_SYNConfig.GetKeyCount("HeartBeatEnable") > 0) m_bHeartBeatFlag = (int)pCurSyn->m_SYNConfig["HeartBeatEnable"]; if (pCurSyn->m_SYNConfig.GetKeyCount("CANHBEnable") > 0) m_bCANHBFlag = (int)pCurSyn->m_SYNConfig["CANHBEnable"]; mLog::Info("m_bHeartBeatFlag[{$}], m_bCANHBFlag[{$}]", m_bHeartBeatFlag, m_bCANHBFlag); int nGetCANData = 3; DWORD event = 0; bool bExit = false; while (!bExit) { event = WaitForMultipleObjects(2, pCurSyn->m_hArrayEvent, FALSE, INFINITE); switch (event) { case WAIT_OBJECT_0: { mLog::Debug("HardwareStatusThread: exited"); bExit = true; break; }break; case (WAIT_TIMEOUT): { mLog::Warn("HardwareStatusThread: Get loop EVENT timeout"); } case (WAIT_OBJECT_0 + 1): { if (m_bHeartBeatFlag) //心跳检测 { //判断是否断连 if (pCurSyn->m_iConnectFlag == 0) { mLog::Info("V2COM: not Connect,try to reconnect \n"); if (false == pCurSyn->ReConnect()) Sleep(30000); continue; } int tempHeartBeat = pCurSyn->m_iHeartBeats; if (tempHeartBeat > 9) //无返回信息认为连接断开 { pCurSyn->m_iHeartBeats = 0; pCurSyn->m_iConnectFlag = 0; pCurSyn->ReConnect(); pCurSyn->FireErrorMessage(true, 1, "lost Connect"); continue; } else { if (pCurSyn->m_iConnectFlag == 1) { mLog::Info("reconnected: try send HeartBeat"); pCurSyn->m_iConnectFlag = 2; } else if (pCurSyn->m_iConnectFlag == 2) { mLog::Info("reconnected: send HeartBeat filed"); pCurSyn->m_iConnectFlag = 0; continue; } if (pCurSyn->m_SynBoxUnit.m_GenSynState->Get() != AttrKey::GENERATOR_RAD_OFF || pCurSyn->m_SynBoxUnit.m_GenSynState->Get() != AttrKey::GENERATOR_RAD_XRAYOFF) { pCurSyn->SendHeartBeat(); pCurSyn->m_iHeartBeats++; } else { mLog::Debug("In Gen Expo,not Send HeartBeat"); } } } else { //mLog::Debug("stop Serial HeartBeat"); } //定时查询CAN信息 if (m_bCANHBFlag) { if (pCurSyn->m_iConnectFlag == 3) { if (pCurSyn->m_SynBoxUnit.m_GenSynState->Get() == AttrKey::GENERATOR_RAD_OFF || pCurSyn->m_SynBoxUnit.m_GenSynState->Get() == AttrKey::GENERATOR_RAD_XRAYOFF) { if (pCurSyn->m_pCollDev != nullptr || pCurSyn->m_pMechDev != nullptr) pCurSyn->QueryInfo(); } else { mLog::Debug("HardwareStatusThread: In Gen Expo,not Query CAN Info"); } } } else { if (nGetCANData && pCurSyn->m_iConnectFlag == 3) { if (pCurSyn->m_SynBoxUnit.m_GenSynState->Get() == AttrKey::GENERATOR_RAD_OFF || pCurSyn->m_SynBoxUnit.m_GenSynState->Get() == AttrKey::GENERATOR_RAD_XRAYOFF) { if (pCurSyn->m_pCollDev != nullptr || pCurSyn->m_pMechDev != nullptr) { pCurSyn->QueryInfo(); nGetCANData--; } } else { mLog::Debug("HardwareStatusThread: In Gen Expo,not Query CAN Info"); } } } if (WAIT_OBJECT_0 == WaitForSingleObject(pCurSyn->m_hLoopEndEvent,5000)) { mLog::Warn("HardwareStatusThread: stop wait immediately"); } }break; default: { mLog::Debug("HardwareStatusThread: unknown event"); }break; } } pCurSyn->m_pHardwareThread = NULL; mLog::Info("HardwareStatusThread stop"); return true; } bool nsSYN::SyncBoxDevice::ReConnect() { mLog::Info("Enter V2COMBox_reConnect"); //SetCANState(false); m_SCF.Disconnect(); if (!pIODriver) { mLog::Info("V2COMBox_reConnect:Driver null"); } else if (pIODriver->ReConnection(m_SCF)) { mLog::Info("reconnected:build connect, try send HeartBeat"); m_iConnectFlag = 1; return true; } else { mLog::Info("reconnect failed"); } return false; } RET_STATUS nsSYN::SyncBoxDevice::DebugSignal(bool flag) { mLog::Info("DebugSignal:{$}", flag); if (m_bDebugSignal != flag) { m_bDebugSignal = flag; } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::SendSignal(string signal) { mLog::Info("SendSignal:{$}", signal.c_str()); if (m_bDebugSignal) { string strChannel = signal.substr(0, 2); bool bStatus = ChartoInt(signal[2]); SendBySCF(strChannel.c_str(), bStatus); } return RET_STATUS::RET_SUCCEED; } //SYN方法 void nsSYN::SyncBoxDevice::SetCANState(bool state) { int nTimeout = 100; auto ResDYNConfig = m_SYNConfig["DeviceConfig"]; char cCmd[MAX_COMMAND_LEN] = { 0 }; string CANProtocol = (string)ResDYNConfig["CANPortocol"]; string CANBaud = (string)ResDYNConfig["CANBaud"]; int nCmdSize = 0; if (CANProtocol == "1") { cCmd[0] = 'G'; } else { cCmd[0] = 'C'; } if (state) { cCmd[1] = 'O'; mLog::Info("OpenCAN"); cCmd[2] = 4;// CANBaud[0]; //string CANFilter = (string)ResDYNConfig["CANFilter"];// //if (CANFilter.length() >= 4) //{ // cCmd[3] = atoi(CANFilter.substr(0,2).c_str());// // cCmd[4] = atoi(CANFilter.substr(2, 4).c_str());// //} //else //{ // cCmd[3] = 0xFF; // cCmd[4] = 0x00; //} cCmd[3] = 0x00; cCmd[4] = 0xFE; nCmdSize = 5; } else { cCmd[1] = 'C'; cCmd[2] = '0'; mLog::Info("CloseCAN"); nCmdSize = 3; } FormatCmd(cCmd, nCmdSize); string strLog; CmdtoString(cCmd, nCmdSize, strLog); mLog::Info("Send:[{$}]", strLog.c_str()); //printf("[Send:%s]\n", strLog.c_str()); mLog::Info("==OUT==:[{$}]", cCmd); int ret = 0; m_SCF.Lock(msTimeOut_Lock) .SendPacket(cCmd, nCmdSize, nTimeout, ret); Sleep(nTimeout); } RET_STATUS nsSYN::SyncBoxDevice::SetWS(std::string value) { if (ResDYNConfig.GetFirstOf(value.c_str()) >= 0) { m_SynBoxUnit.m_WS->Update(value); string wsSYNValue = (string)ResDYNConfig[value.c_str()]; if (wsSYNValue.find("SYN") != string::npos) { m_strSYNMode = wsSYNValue; } else { m_strSYNMode = "SYN" + wsSYNValue; } } else { m_strSYNMode = "SYN0"; } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::SetExpMode(std::string value) { m_SynBoxUnit.m_ExpMode->Update(value); mLog::Info("SetExpMode {$}", value.c_str()); //add for dcm img hard if (m_pCollDev != nullptr) { mLog::Info("act CollDev ReportMessageToDicom"); m_pCollDev->ReportMessageToDicom(); } if (m_pMechDev != nullptr) { mLog::Info("act MechDev ReportMessageToDicom"); m_pMechDev->ReportMessageToDicom(); } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::Reset() { SetGenAECSignal(0); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::SimulateFootSwitchSignal(int signal) { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::SetValue_PPS(FLOAT fluframerate) { return RET_STATUS::RET_SUCCEED; } //串口处理 int nsSYN::SyncBoxDevice::DealtheSignal(const char* channel, int state) { string strchannel = channel; int nState = -1; string strSignalName = ""; if (ResDYNConfig.GetFirstOf(m_strSYNMode.c_str()) < 0) { mLog::Error("Didn't find SynMode : {$}", m_strSYNMode.c_str()); return -1; } if (ResDYNConfig[m_strSYNMode.c_str()].GetFirstOf(m_SynBoxUnit.m_ExpMode->JSGet().c_str()) < 0) { mLog::Error("Didn't find CurrentExamMode : {$}", m_SynBoxUnit.m_ExpMode->JSGet().c_str()); return -1; } mLog::Info("CurrentExamMode = {$}, strchannel = {$}", m_SynBoxUnit.m_ExpMode->JSGet().c_str(), strchannel.c_str()); int count = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"].size(); for (int i = 0; i < count; i++) { string strKey = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"].GetKey(i); string confchannel = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"][strKey.c_str()]["CHANNEL"]; //mLog::Info("strKey = {$}, confchannel = {$}", strKey.c_str(), confchannel.c_str()); if (confchannel == strchannel) { strSignalName = strKey; nState = state; mLog::Info("Signal Name = {$}, state = {$},GenSynState = {$},AECStatus = {$},GridStatus = {$}", strSignalName.c_str(), nState, m_SynBoxUnit.m_GenSynState->Get(), m_bGenAECStatus.load(), m_iGridStatus.load()); if (strSignalName == "GENPREP") //add by wxx:解决OT1信号在 配置 及 工作流中重复发送的问题 { if (state == 1) //ER1 { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_PREPARE); } else { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_OFF); SetGenAECSignal(3); } } else if (strSignalName == "GENREADY") { if (state == 1) //TB1 { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_READY); } else { if (m_SynBoxUnit.m_GenSynState->Get()!= AttrKey::GENERATOR_RAD_OFF) { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_PREPARE); } } } else if (strSignalName == "XWINDOWSTATUS") { if (state == 1)//PT1 { if (m_bAECSecExpFlag == true) { m_bAECSecExpFlag = false; mLog::Info("send RW0 by RAD.workflows"); SetSignal("GENAECCONTROL", 0); //控制AEC信号高 return 1; } //主动获取发生器的ms if (m_bGenAECStatus < 2 && m_iGridStatus == 1) { #if Dios_V3 if (m_pGenClient != NULL) { if (!m_pGenClient->IsClosed()) { ResDataObject Request, Response; Request.add("P0", 0); m_pGenClient->Action("GetVibrationGridMS", Request, Response, 4993, "DIOS/DEVICE/Generator"); string strMS = (const char*)Response; if(0 == atoi(strMS.c_str())) strMS = (const char*)Response["P0"]; mLog::Debug("get[{$}] exp_time[{$}] from gen", Response.encode(), strMS.c_str()); if (!strMS.empty()) { int ExpTime = atoi(strMS.c_str()); SetVibrateGridExpoTimes(ExpTime + GridMSMargin()); } } else { mLog::Debug("V2COM_DM Client is Close"); } } else { mLog::Debug("V2COM_DM Client is NULL"); } #endif mLog::Info("send OW1 by RAD.workflows"); SetSignal("VIBRATEGRIDSTART", 1); return 1; } //if (m_SynBoxUnit.m_GenSynState->Get() == AttrKey::GENERATOR_RAD_READY) //发送OT1收到PT1 //m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_XRAYON); } else //PT0 { if (m_SynBoxUnit.m_GenSynState->Get()!= AttrKey::GENERATOR_RAD_OFF) { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_XRAYOFF); } if (m_bGenAECStatus < 2 && m_iGridStatus == 1) { mLog::Info("send RW1 by RAD.workflows"); SetSignal("GENAECCONTROL", 1); mLog::Info("send RT0 by RAD.workflows"); SetSignal("GENEXPREQUEST", 0); mLog::Info("send OW0 by RAD.workflows"); SetSignal("VIBRATEGRIDSTART", 0); return 1; } int tempAECStatus = m_bGenAECStatus; if (tempAECStatus) { mLog::Info("in AEC Mode: GenAECStatus[{$}],RT0 will send by workflows", tempAECStatus); return 1; } else { mLog::Info("in rad Mode: GenAECStatus[{$}],RT0 will send after recv PT0", tempAECStatus); } } } else if (strSignalName == "VIBRATEGRIDSTATUS") { if(state == 1) //PW1 { if (m_bGenAECStatus == 1) { mLog::Info("send RW0 by RAD.workflows"); SetSignal("GENAECCONTROL", 0); //控制AEC信号高 return 1; } } else { mLog::Info("send RW1 by RAD.workflows"); SetSignal("GENAECCONTROL", 1); } } if (strSignalName != "" && nState >= 0) { //NotifySignal(strSignalName.c_str(), nState); string strSetEnableSignal = (string)ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"][strSignalName.c_str()]["SETENABLE"]; string strSetDisableSignal = (string)ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"][strSignalName.c_str()]["SETDISABLE"]; if (nState == 1 && strSetEnableSignal != "") { if (strSetEnableSignal == "GENEXPREQUEST") //RT1 { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_XRAYON); } string strRelaySignal = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"][strSignalName.c_str()]["RELAY"]; if (strRelaySignal != "") { mLog::Info("Set Enable Relay_Signal = {$},GenSynState = {$}", strSetEnableSignal.c_str(), m_SynBoxUnit.m_GenSynState->Get()); SetMultipleSignal(strSetEnableSignal.c_str(), nState); } else { mLog::Info("Set Enable Signal = {$},GenSynState = {$}", strSetEnableSignal.c_str(), m_SynBoxUnit.m_GenSynState->Get()); SetSignal(strSetEnableSignal.c_str(), nState); } } else if (nState == 0 && strSetDisableSignal != "") { if (strSetEnableSignal == "GENEXPREQUEST") //RT0 { if (m_bGenAECStatus > 0 && m_SynBoxUnit.m_GenSynState->Get() != AttrKey::GENERATOR_RAD_OFF) { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_READY); } } string strRelaySignal = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"][strSignalName.c_str()]["RELAY"]; if (strRelaySignal != "") { mLog::Info("Set Disable Relay_Signal = {$},GenSynState = {$}", strSetDisableSignal.c_str(), m_SynBoxUnit.m_GenSynState->Get()); SetMultipleSignal(strSetEnableSignal.c_str(), nState); } else { mLog::Info("Set Disable Signal = {$},GenSynState = {$}", strSetDisableSignal.c_str(), m_SynBoxUnit.m_GenSynState->Get()); SetSignal(strSetDisableSignal.c_str(), state); } } } return 1; } } mLog::Debug("finish DealtheSignal"); return 0; } int nsSYN::SyncBoxDevice::NotifySignal(const char* name, int state) { string strname = name; mLog::Info("Send Notify : Name = {$}, State = {$}", name, state); if (strname == "HANDSWITCHPREP") { if (state) { m_SynBoxUnit.m_HandSwitchState->Update(1); FireNotify(m_SynBoxUnit.m_HandSwitchState->GetKey(), m_SynBoxUnit.m_HandSwitchState->JSGet()); } else { m_SynBoxUnit.m_HandSwitchState->Update(0); FireNotify(m_SynBoxUnit.m_HandSwitchState->GetKey(), m_SynBoxUnit.m_HandSwitchState->JSGet()); } } else if (strname == "HANDSWITCHREADY") { if (state) { m_SynBoxUnit.m_HandSwitchState->Update(2); FireNotify(m_SynBoxUnit.m_HandSwitchState->GetKey(), m_SynBoxUnit.m_HandSwitchState->JSGet()); } else { m_SynBoxUnit.m_HandSwitchState->Update(0); FireNotify(m_SynBoxUnit.m_HandSwitchState->GetKey(), m_SynBoxUnit.m_HandSwitchState->JSGet()); } } return 2; } int nsSYN::SyncBoxDevice::SetMultipleSignal(const char* name, int state) //change by wxx:原截取字符串操作有问题 { string strtemp = name; string strName = strtemp; bool lastFlag = false; std::size_t oldPos = 0; while (!strName.empty()) { std::size_t findPos = strtemp.find(",", oldPos); if (findPos != string::npos) { strName = strtemp.substr(oldPos, findPos - oldPos); } else { strName = strtemp.substr(oldPos, strtemp.length() - oldPos); lastFlag = true; } if(strName.compare("GENAECCONTROL") == 0) { if (state) state = 0; else state = 1; } SetSignal(strName.c_str(), state); Sleep(10); if (lastFlag) { break; } else { oldPos = findPos + 1; } } } int nsSYN::SyncBoxDevice::SetSignal(const char* name, int state) { if (ResDYNConfig.GetFirstOf(m_strSYNMode.c_str()) < 0) { mLog::Error("Didn't find SynMode : {$}", m_strSYNMode.c_str()); return -1; } if (ResDYNConfig[m_strSYNMode.c_str()].GetFirstOf(m_SynBoxUnit.m_ExpMode->JSGet().c_str()) < 0) { mLog::Error("Set Signal {$}, state {$} ", name, state); mLog::Error("Didn't find CurrentExamMode : {$}", m_SynBoxUnit.m_ExpMode->JSGet().c_str()); return -1; } string strChannel = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["OUTPUT"][name]["CHANNEL"]; if (strChannel != "") { mLog::Info("Set Signal {$}, state {$} ", name, state); SendBySCF(strChannel.c_str(), state); return 1; } return -1; } void nsSYN::SyncBoxDevice::ClearSignal() { if (ResDYNConfig.GetFirstOf(m_strSYNMode.c_str()) < 0) { mLog::Error("Didn't find SynMode : {$}", m_strSYNMode.c_str()); return; } if (ResDYNConfig[m_strSYNMode.c_str()].GetFirstOf(m_SynBoxUnit.m_ExpMode->JSGet().c_str()) < 0) { mLog::Error("Didn't find CurrentExamMode : {$}", m_SynBoxUnit.m_ExpMode->JSGet().c_str()); return; } int nsize = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["OUTPUT"].size(); for (int i = 0; i < nsize; i++) { string strChannel = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["OUTPUT"][i]["CHANNEL"]; string name = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["OUTPUT"].GetKey(i); mLog::Info("Clear Name :{$},CurrentExamMode ={$}", name.c_str(), m_SynBoxUnit.m_ExpMode->JSGet().c_str()); if (strChannel != "" && "FRAMERATE" != name) { mLog::Info("Clear Signal {$} ", strChannel); SendBySCF(strChannel.c_str(), false); Sleep(10); } } return; } int nsSYN::SyncBoxDevice::SetPWM(float fpps) { return -1; } void nsSYN::SyncBoxDevice::DealtheHB(const char* channel, int state) { if(m_bCanLogEnableFlag) mLog::Info("==IN ==: DealtheHB[{$}] ", m_iConnectFlag.load()); if (m_iConnectFlag == 2) { mLog::Info("reconnected: success"); m_iConnectFlag = 3; FireErrorMessage(false, 1, "lost Connect"); if (m_pCollDev != nullptr || m_pMechDev != nullptr) { mLog::Info("CANDevice ReStart"); SetCANState(true); } } Sleep(1000); m_iHeartBeats = 0; } int nsSYN::SyncBoxDevice::GetConnectFlag() { return m_iConnectFlag; } //发生器方法 RET_STATUS nsSYN::SyncBoxDevice::SetGeneratortoSyncStatus(int state) { string strStateName = ""; int nstate = -1; mLog::Info(" SetGeneratortoSyncStatus :{$}", state); if (state == AttrKey::GENERATOR_FLU_OFF || state == AttrKey::GENERATOR_RAD_OFF)//如果是采集结束的消息,直接恢复同步盒状态 { ClearSignal(); } if (m_SynBoxUnit.m_GenSynState->Get() != state || state == AttrKey::GENERATOR_RAD_XRAYON || state == AttrKey::GENERATOR_RAD_XRAYOFF) { mLog::Info("switch :{$}", state); switch (state) { case AttrKey::GENERATOR_RAD_PREPARE: strStateName = "HANDSWITCHPREPREQUEST"; nstate = 1; break; case AttrKey::GENERATOR_RAD_READY: strStateName = "HANDSWITCHREADYREQUEST"; nstate = 1; break; case AttrKey::GENERATOR_RAD_OFF: /*strStateName = "HANDSWITCHREADYREQUEST"; nstate = 0; ((DYNSyncBox*)GetDrvDPC())->SetSignal(strStateName.c_str(), state); Sleep(30); strStateName = "GENEXPREQUEST"; nstate = 0; ((DYNSyncBox*)GetDrvDPC())->SetSignal(strStateName.c_str(), state); Sleep(30); strStateName = "HANDSWITCHPREPREQUEST"; nstate = 0;*/ break; case AttrKey::GENERATOR_FLU_READY: strStateName = "HANDSWITCHPREPREQUEST"; nstate = 1; SetSignal(strStateName.c_str(), nstate); Sleep(30); strStateName = "HANDSWITCHREADYREQUEST"; nstate = 1; break; case AttrKey::GENERATOR_FLU_OFF: /*strStateName = "HANDSWITCHREADYREQUEST"; nstate = 0; ((DYNSyncBox*)GetDrvDPC())->SetSignal(strStateName.c_str(), nstate); Sleep(30); strStateName = "HANDSWITCHPREPREQUEST";*/ break; case AttrKey::GENERATOR_RAD_XRAYON: strStateName = "GENEXPREQUEST"; nstate = 1; break; case AttrKey::GENERATOR_RAD_XRAYOFF: if (m_SynBoxUnit.m_ExpMode->JSGet() != "ContinueSerial") { strStateName = "GENEXPREQUEST"; nstate = 0; } break; default: strStateName = ""; nstate = -1; break; } if (state == AttrKey::GENERATOR_FLU_OFF || state == AttrKey::GENERATOR_RAD_OFF)//如果是采集结束的消息,直接恢复同步盒状态 { if (!m_bClear) { ClearSignal(); m_bClear = true; } m_SynBoxUnit.m_GenSynState->Update(state); } else if (strStateName != "" && nstate >= 0) { m_bClear = false; SetSignal(strStateName.c_str(), nstate); m_SynBoxUnit.m_GenSynState->Update(state); } } else { mLog::Error("switch :{$}, PreSetGeneratortoSyncStatus=false", state); } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::SetExpEnable() { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::SetExpDisable() { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::SetGenAECSignal(int signal) { mLog::Info("SetGenAECSignal:{$},AECMode:{$},VibrateGridMode:{$}", signal, m_bGenAECStatus.load(), m_iGridStatus.load()); switch (signal) { case -1://用于默认 { m_bGenAECStatus = 0; m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_OFF); mLog::Info("do nothing by workflows"); } break; case 0://用于AEC预曝光初始阶段初始化 { m_bGenAECStatus = 0; mLog::Info("send RW1 by Preview.workflows"); SetSignal("GENAECCONTROL", 1); //控制AEC信号低 mLog::Info("send RT0 by RAD.workflows"); SetSignal("GENEXPREQUEST", 0); mLog::Info("send OT0 by RAD.workflows"); SetSignal("DETREACQREQUEST", 0); mLog::Info("send OW0 by RAD.workflows"); SetSignal("VIBRATEGRIDSTART", 0); } break; case 1://用于VMX AEC预曝光开始 { m_bGenAECStatus = 2; mLog::Info("send RW0 by Preview.workflows"); SetSignal("GENAECCONTROL", 0); //Preview模式控制AEC信号高 } break; case 2://用于VMX AEC预曝光结束 { if (m_bGenAECStatus) { m_bGenAECStatus--; mLog::Info("send RW1 by Preview.workflows"); SetSignal("GENAECCONTROL", 1); //Preview模式控制AEC信号低 if (m_SynBoxUnit.m_GenSynState->Get() != AttrKey::GENERATOR_RAD_OFF) { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_READY); } mLog::Info("send RT0 by RAD.workflows GenSynState = {$}", m_SynBoxUnit.m_GenSynState->Get()); SetSignal("GENEXPREQUEST", 0); } } break; case 3://用于VMX AEC正式曝光开始 { if (m_bGenAECStatus) { mLog::Info("send RW0 by RAD.workflows"); SetSignal("GENAECCONTROL", 0); //控制AEC信号高 } } break; case 4://用于VMX AEC正式曝光结束 { if (m_bGenAECStatus) { m_bGenAECStatus = 0; mLog::Info("send RW1 by RAD.workflows"); SetSignal("GENAECCONTROL", 1); //控制AEC信号低 } mLog::Info("send RT0 by RAD.workflows"); SetSignal("GENEXPREQUEST", 0); } break; case 5://用于PSG-MG5L AEC preview开启AEC { m_bGenAECStatus = 2; mLog::Info("send RW0 by preview.workflows"); SetSignal("GENAECCONTROL", 0); //控制AEC信号高 } break; case 6://用于PSG-MG5L 尝试AEC预曝光关闭 { if (m_bGenAECStatus) { m_bGenAECStatus--; if (m_SynBoxUnit.m_GenSynState->Get()!= AttrKey::GENERATOR_RAD_OFF) { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_READY); } mLog::Info("send RW1 by Preview.workflows GenSynState = {$}", m_SynBoxUnit.m_GenSynState->Get()); SetSignal("GENAECCONTROL", 1); //控制AEC信号低 mLog::Info("send OT0 by Preview.workflows"); SetSignal("DETREACQREQUEST", 0); } } break; case 7://用于PSG-MG5L AEC rad开启AEC { if (m_iGridStatus != 1) { if (m_bGenAECStatus) { //mLog::Info("send RW0 by RAD.workflows"); //SetSignal("GENAECCONTROL", 0); //控制AEC信号高 m_bAECSecExpFlag = true; } } else { mLog::Info("GridStatus is 1,not send RW0 by RAD.workflows"); } } break; case 8://用于PSG-MG5L 尝试AEC正式曝光关闭 { if (m_bGenAECStatus) { m_bGenAECStatus = 0; mLog::Info("send RW1 by RAD.workflows"); SetSignal("GENAECCONTROL", 1); //控制AEC信号低 } mLog::Info("send RT0 by RAD.workflows"); SetSignal("GENEXPREQUEST", 0); mLog::Info("send OT0 by RAD.workflows"); SetSignal("DETREACQREQUEST", 0); mLog::Info("send OW0 by RAD.workflows"); SetSignal("VIBRATEGRIDSTART", 0); mLog::Debug("enable m_hLoopEvent"); SetEvent(m_hLoopBeginEvent); } break; default: mLog::Warn("SetGenAECSignal:can not deal with signal[{$}]", signal); break; } return RET_STATUS::RET_SUCCEED; } //探测器方法 RET_STATUS nsSYN::SyncBoxDevice::PrepareAcquisition() { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::StartWindowRequest() { if (m_SynBoxUnit.m_GenSynState->Get() == AttrKey::GENERATOR_RAD_READY) //add by wxx:解决OT1信号在 配置 及 工作流中重复发送的问题 { mLog::Info("send OT1 by workflows"); Sleep(1000); SetSignal("DETREACQREQUEST", 1); } else { if(m_bGenAECStatus) mLog::Info("there is already send OT1 in this AEC Exposure"); else mLog::Info("there is not start Exposure yet"); } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::StopWindowRequest() { mLog::Info("send OT0 by workflows"); SetSignal("DETREACQREQUEST", 0); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::SetExposureTimes(int nNum) { mLog::Debug("Enter SetExposureTimes:[{$}]", nNum); m_nExpTimes = nNum; if (m_pMechDev != nullptr) { SetVibrateGridExpoTimes(nNum); } else { mLog::Warn("m_pMechDev is null"); } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::SetFrameRate(FLOAT frameRate) { SetPWM(frameRate); return RET_STATUS::RET_SUCCEED; } //机架、遮光器处理 RET_STATUS nsSYN::SyncBoxDevice::SetCollimatorDev(OemCollimator* dev) { if (dev) { m_pCollDev.reset(dev); if (m_pMechDev != nullptr) { mLog::Info("CANDevice start"); SetCANState(true); } //默认SID if (m_SYNConfig.GetKeyCount("DefaultSID") > 0) { m_iConfSID = (int)m_SYNConfig["DefaultSID"]; m_pCollDev->UpdateCollimatorSID(m_iConfSID); } } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::SetMechDev(OemMechanical* dev) { if (dev) { m_pMechDev.reset(dev); if (m_pCollDev != nullptr) { mLog::Info("CANDevice start"); SetCANState(true); } //无效压力闯值 if (m_SYNConfig.GetKeyCount("InvalidPressureThreshold") > 0) { int cfgValue = (int)m_SYNConfig["InvalidPressureThreshold"]; if(m_pMechDev != nullptr) m_pMechDev->UpdateMammo_PressureErrorValue((unsigned int)cfgValue); } } return RET_STATUS::RET_SUCCEED; } //立柱板节点 RET_STATUS nsSYN::SyncBoxDevice::SetConfigInfo(int nPanelType, int nRobotArmAngle) { if (nRobotArmAngle < 30 || nRobotArmAngle > 60) return RET_STATUS::RET_SUCCEED; BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A0 data[3] = 0x08; data[4] = 0x00; data[5] = 0x02; data[6] = nPanelType;//平板选择:1.ANRAD;2.VARIAN;3.CAREVIEW data[7] = nRobotArmAngle;//C臂MLO位:角度30-60 data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; data[14] = 0x0; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } return HWSend((char*)data); } RET_STATUS nsSYN::SyncBoxDevice::SetPhotographyMode(int nExpoMode, int nAECfield, int nAECdensity) { BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A0 data[3] = 0x08; data[4] = 0x00; data[5] = 0x03; data[6] = nExpoMode;//曝光模式:1-4(1-3为自动,4手动);6(48KV);8(校准) data[7] = nAECfield; data[8] = nAECdensity; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; data[14] = 0x0; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } return HWSend((char*)data); } RET_STATUS nsSYN::SyncBoxDevice::SetExposureProcess(int nState) { mLog::Debug("Enter SetExposureProcess:[{$}]", nState); //10 平板准备好 //20 发生器准备好 //30 曝光开始 //40 曝光结束 //50 流程结束 //61 "1:ANRAN平板未准备好; 2:ANRAN平板准备好" BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A0 data[3] = 0x08; data[4] = 0x00; data[5] = 0x04; data[6] = nState; data[7] = 0x00; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; data[14] = 0x0; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } return HWSend((char*)data); } RET_STATUS nsSYN::SyncBoxDevice::SetSendMessageEnable(int enableFlag) { BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A0 data[3] = 0x08; data[4] = 0x01; data[5] = 0x13;//19 data[6] = enableFlag;//1.禁止给图像发报文 2:允许发送 data[7] = 0x00; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; data[14] = 0x0; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } return HWSend((char*)data); } //C臂控制板节点 RET_STATUS nsSYN::SyncBoxDevice::SetPressureLimit(int nforePressureLimit, int nAllPressureLimit) { BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A1 data[3] = 0x28; data[4] = 0x01; data[5] = 0x02; data[6] = nforePressureLimit; data[7] = nAllPressureLimit; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; data[14] = 0x0; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } return HWSend((char*)data); } RET_STATUS nsSYN::SyncBoxDevice::SetAutoTracking(int nAutoTracking) { mLog::Debug("Enter SetAutoTracking:[{$}]", nAutoTracking); int cmdAutoTracking = 0; switch (nAutoTracking)//释放类型:1.自动释放;2.手动释放 { case 0://close cmdAutoTracking = 2; break; case 1://open cmdAutoTracking = 1; break; } BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A1 data[3] = 0x28; data[4] = 0x01; data[5] = 0x03; data[6] = m_bOppressiveMode; data[7] = cmdAutoTracking; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; data[14] = 0x0; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } return HWSend((char*)data); } RET_STATUS nsSYN::SyncBoxDevice::SetGrid(unsigned int GridType) { mLog::Debug("Enter SetGrid:[{$}]", GridType); int cmdGridType = 0; switch (GridType)//振栅状态:1.图像IN;2.图像OUT;3.运动中 { case 0://off cmdGridType = 2; break; case 1://on cmdGridType = 1; break; case 2://soft return RET_STATUS::RET_SUCCEED;; break; } BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A1 data[3] = 0x28; data[4] = 0x01; data[5] = 0x04; data[6] = m_bGridMode;//振栅模式:1.正常模式;2.放大模式 data[7] = cmdGridType; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } data[14] = 0x0; return HWSend((char*)data); } RET_STATUS nsSYN::SyncBoxDevice::SetPressureManualRelease() { mLog::Debug("Enter SetPressureManualRelease");//当作自动释放触发 if (m_pMechDev && m_pMechDev->GetMammo_Depress() == 1) { BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A1 data[3] = 0x28; data[4] = 0x01; data[5] = 0x0B; //11 data[6] = 0x00; data[7] = 0x00; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } data[14] = 0x0; return HWSend((char*)data); } else { mLog::Debug("SetPressureManualRelease:not auto release"); } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::SetRecvMessageEnable(bool enableFlag) { int cmdEnableFlag = 0; switch (enableFlag)//1.禁止给图像发报文 2:允许发送 { case 0://close cmdEnableFlag = 1; break; case 1://open cmdEnableFlag = 2; break; } BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A1 data[3] = 0x28; data[4] = 0x01; data[5] = 0x15; //21 data[6] = cmdEnableFlag; data[7] = 0x00; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } data[14] = 0x0; return HWSend((char*)data); } RET_STATUS nsSYN::SyncBoxDevice::QueryError() { BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A1 data[3] = 0x28; data[4] = 0x01; data[5] = 0x12; //18 data[6] = 0x00; data[7] = 0x00; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } data[14] = 0x0; return HWSend((char*)data); } RET_STATUS nsSYN::SyncBoxDevice::SetFilter(int filter) { mLog::Debug("Enter SetFilter:[{$}]", filter); int cmdFilter = 0; //col滤过类型:1Mo,2Rh if (filter == m_iFilterMO) { cmdFilter = 1; } if (filter == m_iFilterRH) { cmdFilter = 2; } BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A1 data[3] = 0x28; data[4] = 0x01; data[5] = 0x07; data[6] = cmdFilter; data[7] = 0x00; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; data[14] = 0x0; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } return HWSend((char*)data); } RET_STATUS nsSYN::SyncBoxDevice::QueryInfo() { char data[20] = { 0 }; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A1 data[3] = 0x28; data[4] = 0x01; data[5] = 0x08; data[6] = 0x3F; data[7] = 0x3F; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; for (int i = 0; i <= 11; i++) { if (data[i] == 0) data[i] = 0x30; } data[14] = 0x0; return HWSend((char*)data); } //振动栅节点 RET_STATUS nsSYN::SyncBoxDevice::SetVibrateGridExpoTimes(int nTimes) { mLog::Debug("Enter SetVibrateGridExpoTimes:[{$}]", nTimes); if(nTimes < 500 || nTimes > 2000) return RET_STATUS::RET_SUCCEED; //时间(高字节) int gridHeight = nTimes / 256; //时间(低字节) int gridWidth = nTimes % 256; BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A4 data[3] = 0x88; data[4] = 0x04; data[5] = 0x02; data[6] = gridHeight; data[7] = gridWidth; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; data[14] = 0x0; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } return HWSend((char*)data); } RET_STATUS nsSYN::SyncBoxDevice::StartVibrateGrid() { mLog::Debug("Enter StartVibrateGrid"); m_bVibrateGridReady = 0; mLog::Info("send OW1 by workflows"); SetSignal("VIBRATEGRIDSTART", 1); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsSYN::SyncBoxDevice::StopVibrateGrid() { mLog::Debug("Enter StopVibrateGrid"); m_bVibrateGridReady = 0; mLog::Info("send OW0 by workflows"); SetSignal("VIBRATEGRIDSTART", 0); return RET_STATUS::RET_SUCCEED; } int nsSYN::SyncBoxDevice::GridMSMargin() { if (m_bGenAECStatus <= 0) { mLog::Debug("GridMSMargin:NOAEC GridMS[{$}]", m_iGridMSRadMargin); return m_iGridMSRadMargin; } else { mLog::Debug("GridMSMargin:AEC GridMS[{$}]", m_iGridMSRadMargin); return m_iGridMSAECMargin; } return 0; } //CAN口处理 void nsSYN::SyncBoxDevice::DealReceiveData(char* data_can, int length_can_data) { //暂时无用 if (length_can_data == 5)//CO4 { //set baud ok. if (data_can[2] == 0) { m_bSetBaudOK = true; } else { m_bSetBaudOK = false; } } if (length_can_data == 4)//EC { //echo ok } int idHigh = (unsigned char)(data_can[2]); int idLow = (unsigned char)(data_can[3]); int cmdID = idHigh*225+idLow; if (idHigh == 0x80 && idLow == 0xA8)//0x405 cmdID = 0x405; else if (idHigh == 0x84 && idLow == 0xA8)//0x425 cmdID = 0x425; else if (idHigh == 0x90 && idLow == 0xA8)//0x485 cmdID = 0x485; idHigh = (unsigned char)(data_can[4]); idLow = (unsigned char)(data_can[5]); int cmdType = idHigh * 100 + idLow; if(m_bCanLogEnableFlag) mLog::Info("DealReceiveData:id[0x{$:x04}],type[{$},{$}->{$}],data[{$},{$},{$},{$}]", cmdID, (int)data_can[4], (int)data_can[5], cmdType,(int)data_can[6], (int)data_can[7], (int)data_can[8], (int)data_can[9]); if (cmdID == 0x405)//0x405:立柱板节点 { switch (cmdType) { case 1://心跳报文 { //recv 425 heart //if (m_bCanLogEnableFlag) // mLog::Debug("recv 405 : heart beat."); } break; case 2://配置信息-回复 { //平板选择:1.ANRAD;2.VARIAN;3.CAREVIEW int nPanelType = (BYTE)data_can[6]; //C臂MLO位:角度30-60 int nML0Angle = (BYTE)data_can[7]; //if (m_pMechDev) //{ // m_pMechDev->UpdateMammo_MechAngle(nML0Angle); //} if (m_bCanLogEnableFlag) mLog::Debug("recv 405 : panelType[{$}] ,MLOangle[{$}]", nPanelType, nML0Angle); } break; case 3://摄影模式选择-回复 { //曝光模式:1-4(1-3为自动,4手动);6(48KV);8(校准) int nExpoMode = (BYTE)data_can[6]; //AEC区域(不判) int nAECfield = (BYTE)data_can[7]; //AEC浓度(不判) int nAECdensity = (BYTE)data_can[8]; if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : exposure mode[{$}],AECfield[{$}],AECdensity[{$}]", nExpoMode, nAECfield, nAECdensity); } break; case 4://流程状态 { //曝光流程报文 int nFlowsStatus = (BYTE)data_can[6]; switch (nFlowsStatus) { case 10: { if (m_bCanLogEnableFlag) mLog::Debug("recv 405 : exposure workflows[FPD ready]"); } break; case 20: { if (m_bCanLogEnableFlag) mLog::Debug("recv 405 : exposure workflows[GEN ready]"); } break; case 30: { if (m_bCanLogEnableFlag) mLog::Debug("recv 405 : exposure workflows[EXPO begin]"); } break; case 40: { if (m_bCanLogEnableFlag) mLog::Debug("recv 405 : exposure workflows[EXPO end]"); } break; case 50: { if (m_bCanLogEnableFlag) mLog::Debug("recv 405 : exposure workflows[workFlows end]"); } break; case 61://平板状态 { if (m_bCanLogEnableFlag) { int nPanelStatus = (BYTE)data_can[7]; if (nPanelStatus == 1) mLog::Debug("recv 405 : exposure workflows[FPD not ready]"); else mLog::Debug("recv 405 : exposure workflows[FPD ready]"); } } break; default: if (m_bCanLogEnableFlag) mLog::Error("recv 405 : exposure workflows[{$}]Unrecognized", nFlowsStatus); break; } int nValue = (BYTE)data_can[6]; //AEC区域(不判) int nPanelStatus = (BYTE)data_can[7]; if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : [{$}],PanelStatus[{$}]", nValue, nPanelStatus); } break; default: if (m_bCanLogEnableFlag) mLog::Debug("recv 405 : can not deal with[{$}]", cmdType); break; } } else if (cmdID == 0x425)//0x425:C臂控制板节点 { switch (cmdType) { case 101://心跳报文 { //recv 425 heart //if (m_bCanLogEnableFlag) // mLog::Debug("recv 425 : heart beat."); } break; case 102://预压迫和全压迫设置信息-回复 { if (m_pMechDev) { //预压迫压力限制值 int nPreCompPressureLimit = (BYTE)data_can[6]; //全压迫压力限制值 int nAllCompPressureLimit = (BYTE)data_can[7]; if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : PreCompPressureLimit[{$}],AllCompPressureLimit[{$}]", nPreCompPressureLimit, nAllCompPressureLimit); } } break; case 103://压迫和释放信息-回复 { if (m_pMechDev) { //压迫模式:普通压迫(01); 预压迫(10); 全压迫(11) int nCompPressureMode = (BYTE)data_can[6]; //压迫器:自动释放(01); 手动释放(10) int nDepress = (BYTE)data_can[7]; switch ((int)data_can[7])//APP释放类型:1.open;2.close { case 1://自动释放 nDepress = 1; break; case 2://手动释放 nDepress = 0; break; default: nDepress = m_pMechDev->GetMammo_Depress(); } //if (m_bCanLogEnableFlag && m_pMechDev->GetMammo_CompPressureDEC()!=nCompPressureMode && m_pMechDev->GetMammo_Depress()!=nDepress) // mLog::Debug("recv 425 : CompPressureMode[{$}->{$}],Auto release mode[{$}->{$}]", // m_pMechDev->GetMammo_CompPressureDEC(), nCompPressureMode, m_pMechDev->GetMammo_Depress(), nDepress); //m_pMechDev->UpdateMammo_CompPressureDEC(nCompPressureMode);//压缩机压力下降 if (m_bCanLogEnableFlag && m_pMechDev->GetMammo_Depress() != nDepress) mLog::Debug("recv 425 : CompPressureMode[{$}],Auto release mode[{$}->{$}]", nCompPressureMode, m_pMechDev->GetMammo_Depress(), nDepress); m_pMechDev->UpdateMammo_Depress(nDepress);//vmi doc文档中,DF0 DF1 也表示自动释放 } } break; case 104://振栅位置有变化,栅进出位置息-回复 { //振栅模式:1.正常模式;2.放大模式 int nGridMode = (BYTE)data_can[6];//此处更像是mag //振栅状态:1.图像IN;2.图像OUT;3.运动中 int nGridStatus = (BYTE)data_can[7]; switch ((int)data_can[7])//APP振栅状态:0.off;1.on;3.soft { case 1://图像IN nGridStatus = 1; break; case 2://图像OUT nGridStatus = 0; break; case 3://运动中 //m_iGridStatus = 2; default: nGridStatus = m_pMechDev->GetGrid(); break; } if (m_iGridStatus != nGridStatus) { m_iGridStatus = nGridStatus; #if Dios_V3 if (m_pGenClient != NULL) { if (!m_pGenClient->IsClosed()) { ResDataObject Request, Response; Request.add("P0", nGridStatus); m_pGenClient->Action("SetVibrationGrid", Request, Response, 4993, "DIOS/DEVICE/Generator"); mLog::Debug("V2COM_DM Client execute [SetVibrationGrid][{$}]",nGridStatus); } else { mLog::Debug("V2COM_DM Client is Close"); } } else { mLog::Debug("V2COM_DM Client is NULL"); } #endif } if (m_pMechDev) { if (m_bCanLogEnableFlag && m_pMechDev->GetMammo_MAG()!=nGridMode && m_pMechDev->GetGrid()!=nGridStatus) mLog::Debug("recv 425 : grid mode[{$}->{$}],gird status[{$}->{$}]", m_pMechDev->GetMammo_MAG(), nGridMode, m_pMechDev->GetGrid(), nGridStatus); m_pMechDev->UpdateMammo_MAG(nGridMode); m_pMechDev->UpdateGrid(nGridStatus); } } break; case 105://压迫数据 { //压迫厚度 - 用于显示 int nThickness = (BYTE)data_can[6]; //压迫压力-用于显示 int nPressValue = (BYTE)data_can[7]; if (m_pMechDev) { //change by wxx for 万东bug5975:实际设备厚度会超过100,放开限制 //if (nThickness > 100)//add by wxx for 万东:解决压迫厚度超限导致APR参数全为0 //{ // nThickness = 100; //} //else if (nThickness < 0) //{ // nThickness = 0; //} } if (m_pMechDev) { if (m_bCanLogEnableFlag && m_pMechDev->GetMammo_PressureState()!=nThickness && m_pMechDev->GetMammo_PressureValue()!=nPressValue) mLog::Debug("recv 425 : thickness[{$}->{$}], pressvalue[{$}->{$}]", m_pMechDev->GetMammo_PressureState(), nThickness, m_pMechDev->GetMammo_PressureValue(), nPressValue); m_pMechDev->UpdateMammo_PressureState(nThickness);//note :thickness m_pMechDev->UpdateMammo_PressureValue(nPressValue); } } break; case 6://C臂旋转角度 { //C arm angle int angle = (BYTE)data_can[7]; int nSign = (BYTE)data_can[6]; if (nSign == 2) { angle *= -1; } //if (m_bCanLogEnableFlag) // mLog::Debug("recv 425 : CARM angle[{$}]", angle); if (m_pCollDev) { if (m_bCanLogEnableFlag && m_pCollDev->GetCollimatorAngle()!=angle) mLog::Debug("recv 425 : CollimatorAngle[{$}->{$}]", m_pCollDev->GetCollimatorAngle(), angle); m_pCollDev->UpdateCollimatorAngle(angle); } if (m_pMechDev) { if (m_bCanLogEnableFlag && m_pMechDev->GetMammo_MechAngle()!=angle) mLog::Debug("recv 425 : MechAngle[{$}->{$}]", m_pMechDev->GetMammo_MechAngle(), angle); m_pMechDev->UpdateMammo_MechAngle(angle); } } break; case 106://限束器视野有变化 { //光野长-高字节,光野长-低字节 int colHeight = (BYTE)data_can[6] * 256 + (BYTE)data_can[7]; //光野宽-高字节,光野宽-低字节 int colWidth = (BYTE)data_can[8] * 256 + (BYTE)data_can[9]; if (m_pCollDev) { if (m_bCanLogEnableFlag && m_pCollDev->GetCollimatorXSize()!=colWidth && m_pCollDev->GetCollimatorYSize()!=colHeight) mLog::Debug("recv 425 : coll: x[{$}->{$}],y[{$}->{$}]", m_pCollDev->GetCollimatorXSize(), colWidth, m_pCollDev->GetCollimatorYSize(), colHeight); m_pCollDev->UpdateCollimatorXSize(colWidth); m_pCollDev->UpdateCollimatorYSize(colHeight); } } break; case 107://限束器滤过变化MORH-回复 { //col滤过类型:1Mo,2Rh int nFilter = (BYTE)data_can[6]; //if (m_bCanLogEnableFlag) //mLog::Debug("recv 425 : fileter[{$}]", nFilter); if (m_pCollDev) { if (m_bCanLogEnableFlag && m_pCollDev->GetCollimatorFilter()!=nFilter) mLog::Debug("recv 425 : CollimatorFilter[{$}->{$}]", m_pCollDev->GetCollimatorFilter(), nFilter); m_pCollDev->UpdateCollimatorFilter(nFilter); } if (m_pMechDev) { if (m_bCanLogEnableFlag && m_pMechDev->GetMammo_FT() != nFilter) mLog::Debug("recv 425 : MechFilter[{$}->{$}]", m_pMechDev->GetMammo_FT(), nFilter); m_pMechDev->UpdateMammo_FT(nFilter); } } break; case 112://机架状态上报 { int nStatus = (BYTE)data_can[6]; switch (nStatus) { case 0: if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : status[no error]"); break; case 1: if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : status[Compressor initialization not in place]");//压迫器初始化未到位 break; case 2: if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : status[Compressor upper limit error]");//压迫器上限位错误 break; case 3: if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : status[Overvoltage error]");//过压错误 break; case 4: if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : status[Overcurrent error]");//过流错误 break; case 5: if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : status[Automatic release incomplete]");//自动释放未完成 break; case 6: if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : status[Beam limiter initialization successful]");//限束器初始化成功 break; case 7: if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : status[Release of oppression completed]");//压迫释放完成 break; default: if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : status[{$}] can not deal with", nStatus); break; } } break; case 18://收到图像查询错误状态报文后回复 { //1双电位器错误,0无错误 int nError = (BYTE)data_can[6]; if (m_bCanLogEnableFlag) { if (nError == 0) mLog::Debug("recv 425 : no error"); else mLog::Debug("recv 425 : Dual potentiometer error");//双电位器错误 } } break; case 119://压迫板ID { //压迫板类型:1.大压迫板。2.小压迫板。3.放大摄影压迫板 int nPlateID = (BYTE)data_can[6]; std::string strPlateID = ""; if (m_pMechDev) { if (1 == nPlateID) { strPlateID = "Large compression plate"; } else if (2 == nPlateID) { strPlateID = "Small compression plate"; } else if (3 == nPlateID) { strPlateID = "Magnification compression plate"; } if (m_bCanLogEnableFlag) mLog::Info("recv 425 : CompressPaddle type[{$}]", nPlateID); m_pMechDev->UpdateMammo_CompressPaddle(strPlateID); } } break; default: if (m_bCanLogEnableFlag) mLog::Debug("recv 425 : can not deal with[{$}]", cmdType); break; } } else if (cmdID == 0x485)//0x485:振动栅节点 { switch (cmdType) { case 403://故障报文 { //故障状态:0.正确 ;1.初始化错误 int nFailStatus = (BYTE)data_can[6]; if (m_bCanLogEnableFlag) { if(nFailStatus == 0) mLog::Debug("recv 485 : Correct vibration grating");//振动栅正确 else mLog::Debug("recv 485 : Vibration barrier initialization error");//振动栅初始化错误 } } break; default: if (m_bCanLogEnableFlag) mLog::Debug("recv 485 : can not deal with[{$}]", cmdType); break; } } else { if (m_bCanLogEnableFlag) { switch (cmdID) { case 0x740c: break; case 0x70a8: break; default: mLog::Debug("recv [{$:x04}] : can not deal with", cmdID); break; } } } } void nsSYN::SyncBoxDevice::OnCallBack() { mLog::Info("SyncBoxDevice::OnCallBack in"); auto HWDoNothing = [](const char* value, int length) -> void { }; auto HWNotProcess = [](const char* value, int length) -> void { mLog::Warn(" This commands didn't need to process!"); }; auto HWHB = [this](const char* value, int length) -> void { //assert(value && length >= 3); char cChannelValue; cChannelValue = value[2]; //status : on /off string strChannel = ((string)value).substr(0, 2); bool bStatus = ChartoInt(cChannelValue); if (m_bCanLogEnableFlag) mLog::Info("==IN ==:HWHB:{$}", value); DealtheHB(strChannel.c_str(), bStatus); }; auto HWSignal = [this](const char* value, int length) -> void { //assert(value && length >= 3); char cChannelValue; cChannelValue = value[2]; //status : on /off string strChannel = ((string)value).substr(0, 2); bool bStatus = ChartoInt(cChannelValue); mLog::Info("==IN ==:HWSignal:{$:3}",value); if (m_bDebugSignal) { FireNotify("RecvSignal", value); } if (strChannel == "TB") { if (bStatus) { mLog::Debug("disable m_hLoopEvent"); ResetEvent(m_hLoopBeginEvent); SetEvent(m_hLoopEndEvent); } else { //mLog::Debug("enable m_hLoopEvent"); //SetEvent(m_hLoopBeginEvent); } } DealtheSignal(strChannel.c_str(), bStatus); }; /* --485 立柱板节点 43 52 80 A8 30 01 30 30 30 30 30 30 0D 0A --405 heart 振动栅节点 43 52 84 A8 01 01 30 30 30 30 30 30 0D 0A --425 heart C臂控制板节点 43 52 84 A8 01 07 01 30 30 30 30 30 0D 0A --filter 1 43 52 84 A8 01 07 02 30 30 30 30 30 0D 0A --filtr 2 */ auto HWCAN = [this](const char* value, int length) { char data_can[MAX_COMMAND_LEN] = { 0 }; for (int i = 0; i < length; i++) { if (value[i] == 0x30) data_can[i] = 0x0; else if (value[i] == 0x61) data_can[i] = 0x0a; else if (value[i] == 0x64) data_can[i] = 0x0d; else data_can[i] = value[i]; } string strcmd = data_can; string sCmdID = strcmd.substr(2, 2); DealReceiveData(data_can, length); }; // 有部分前缀是包含关系, 长的包含短的, 例如 KVS 包含了 KV. // 因此长的在前面, 短的在后面 // !!! Device 是个短寿命对象, 而 arFrame 是静态变量 !!! // !!! 因此, 在添加到 arFrame 之前, 务必先清零 !!! arFrame.clear(); arFrame["CO"] = tFrameMapping(HWNotProcess, tFrameMapping::OverType_directly, false); arFrame["CS"] = tFrameMapping(HWDoNothing , tFrameMapping::OverType_WaitTime, false, 100); arFrame["EC"] = tFrameMapping(HWHB , tFrameMapping::OverType_WaitTime, false, 100); arFrame["GR"] = tFrameMapping(HWCAN, tFrameMapping::OverType_WaitTime, false, 100); arFrame["CR"] = tFrameMapping(HWCAN, tFrameMapping::OverType_WaitTime, false, 100); arFrame["TB"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["WB"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["GT"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["GW"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["PT"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["PW"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["ER"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["RT"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["RW"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["OT"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["OW"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["PR"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["FT"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["FW"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["TT"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); arFrame["TW"] = tFrameMapping(HWSignal, tFrameMapping::OverType_WaitTime, false, 30); } //----------------------------------------------------------------------------- // DynBoxDriver //----------------------------------------------------------------------------- //SyncBoxDevice* nsSYN::DynBoxDriver::pSDCDevice = nullptr; nsSYN::DynBoxDriver::DynBoxDriver () { m_bConnected = false; m_pAttribute.reset(new ResDataObject()); m_pDescription.reset(new ResDataObject()); #ifdef _WIN64 g_strAppPath = GetProcessDirectory() + R"(\OEMDrivers\SyncBox\V2COM\DIOS.Dev.SyncBox.V2COM64.dll)"; mLog::Fatal("Version: {$} (64-bit)", FileVersion(g_strAppPath.c_str()).GetVersionString()); #else g_strAppPath = GetProcessDirectory() + R"(\OEMDrivers\SyncBox\V2COM\DIOS.Dev.SyncBox.V2COM.dll)"; mLog::Fatal("Version: {$}", FileVersion(g_strAppPath.c_str()).GetVersionString()); #endif //m_MapChannel.push_back("GR"); //m_MapChannel.push_back("CR"); //m_MapChannel.push_back("EC"); //m_MapChannel.push_back("CO"); //m_MapChannel.push_back("TB"); //m_MapChannel.push_back("WB"); //m_MapChannel.push_back("GT"); //m_MapChannel.push_back("GW"); //m_MapChannel.push_back("PT"); //m_MapChannel.push_back("PW"); //m_MapChannel.push_back("ER"); //m_MapChannel.push_back("RT"); //m_MapChannel.push_back("RW"); //m_MapChannel.push_back("OT"); //m_MapChannel.push_back("OW"); //m_MapChannel.push_back("PR"); //m_MapChannel.push_back("FT"); //m_MapChannel.push_back("FW"); //m_MapChannel.push_back("TT"); //m_MapChannel.push_back("TW"); } nsSYN::DynBoxDriver::~DynBoxDriver () { mLog::Info("set pIODriver null"); pIODriver = nullptr; } auto nsSYN::DynBoxDriver::CreateDevice (int index) -> std::unique_ptr { mLog::Info("CreateDevice index ={$}",index); if (!m_SCF.isConnected()) { mLog::Error("CreateDevice but scf no connect"); return nullptr; } //pSDCDevice = new nsSYN::DynBoxDevice(EventCenter,m_SCF); if (index == 0) { pSDCDevice = new SyncBoxDevice(EventCenter, m_SCF, m_ConfigFileName); //auto pSDCDevice = std::unique_ptr (new DynBoxDevice(EventCenter, m_SCF)); auto dev = std::unique_ptr (new IODevice(pSDCDevice)); ResDataObject r_config; if (r_config.loadFile(m_ConfigFileName.c_str())) { pSDCDevice->ResDYNConfig = r_config["CONFIGURATION"]["DeviceConfig"]; //pSDCDevice->m_CollimatorDevice->ResDYNConfig = r_config["CONFIGURATION"]["DeviceConfig"]; mLog::Info("Load config ok"); } return dev; } //ysj++ else if (index == 1) { mLog::Info("Enter CreateDevice COLL"); m_pDriCollDev = new OemCollimator(std::shared_ptr(new IOEventCenter())); auto dev = std::unique_ptr (new IODevice(m_pDriCollDev)); m_pDriCollDev->SetCtrlDev(pSDCDevice); pSDCDevice->SetCollimatorDev(m_pDriCollDev); mLog::Info("Leave CreateDevice COLL"); return dev; } else if (index == 2) { mLog::Info("Enter CreateDevice Mech"); m_pDriMechDev = new OemMechanical(std::shared_ptr(new IOEventCenter())); auto dev = std::unique_ptr (new IODevice(m_pDriMechDev)); m_pDriMechDev->SetCtrlDev(pSDCDevice); pSDCDevice->SetMechDev(m_pDriMechDev); mLog::Info("Leave CreateDevice Mech"); return dev; } return nullptr; } void nsSYN::DynBoxDriver::FireNotify (int code, std::string key, std::string content) { EventCenter->OnNotify (code, key, content); } Log4CPP::Logger* mLog::gLogger = nullptr; void nsSYN::DynBoxDriver::Prepare () { string strLogPath = GetProcessDirectory() + R"(\OEMDrivers\SyncBox\Conf\Log4CPP.Config.SYN.xml)"; //Log4CPP::ThreadContext::Map::Set("LogFileName", "SYN.V2COM"); Log4CPP::GlobalContext::Map::Set(ECOM::Utility::Hash("LogFileName"), "SYN.V2COM"); auto rc = Log4CPP::LogManager::LoadConfigFile(strLogPath.c_str()); if (!rc) { printf("\n Load log configfile failed!\n"); } mLog::gLogger = Log4CPP::LogManager::GetLogger("SYN.V2COM"); //add by wxx:自动获取版本号并更新到日志 string version; if (GetVersion(version, hMyModule)) mLog::Info("--Func-- driver prepare : version:{$}\n", version.c_str()); else mLog::Info("--Func-- driver prepare, v1.0.0.1 \n"); m_SCFDllName = GetConnectDLL(m_ConfigFileName); super::Prepare (); } bool nsSYN::DynBoxDriver::Connect () { ResDataObject Connection = GetConnectParam(m_ConfigFileName); mLog::Info("connections:{$} \n", Connection.encode()); super::DecodePack(false); auto erCode = m_SCF.Connect(Connection.encode(), &nsSYN::DynBoxDriver::callbackPackageProcess, SCF_PACKET_TRANSFER, 3000); if (erCode != SCF_ERR::SCF_SUCCEED) { mLog::Error("scf connect failed"); return false; //return erCode; } mLog::Info("connect success"); Sleep(200); //CanShakeHand(); //SetCANState(true);//open can Sleep(1000); //super::SetThread_Priority(THREAD_PRIORITY_TIME_CRITICAL); auto rc = super::Connect(); if (!rc) { LPVOID lpMsgBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); string msgContent = (TCHAR*)lpMsgBuf; mLog::Debug("super_Connect:error msg[{$}:{$}]", (int)dw, msgContent.c_str()); return false; } else { mLog::Info("connect scf ok"); } return true; //return SCF_ERR::SCF_SUCCEED; } bool nsSYN::DynBoxDriver::ReConnection(nsSCF::SCF& DevSCF) { super::Disconnect(); mLog::Info("ReConnection:SCF Disconnect"); ResDataObject r_config; if (!r_config.loadFile(m_ConfigFileName.c_str())) { mLog::Info("ReConnection:open configFile failed"); return SCF_ERR::SCF_OPEN_FAILED; } ResDataObject Connection = r_config["CONFIGURATION"]["connections"][0]; mLog::Info("ReConnection:{$} \n", Connection.encode()); auto erCode = m_SCF.Connect(Connection.encode(), &nsSYN::DynBoxDriver::callbackPackageProcess, SCF_PACKET_TRANSFER, 3000); if (erCode == SCF_ERR::SCF_SUCCEED) { Sleep(1000); auto rc = super::Connect(); if (!rc) { mLog::Info("ReConnection:super Connect failed"); } else { DevSCF = m_SCF; return true; } } else { mLog::Info("ReConnection failed"); } return false; } void nsSYN::DynBoxDriver::Disconnect() { super::Disconnect(); m_SCF.Disconnect(); pSDCDevice = nullptr; m_bConnected = false; mLog::Info("Disconnect ok"); } bool nsSYN::DynBoxDriver::isConnected() const { if (super::isConnected()) { return true; } else { if (SyncBoxDevice::m_bHeartBeatFlag) //避过平台层的断连检测 return true; else return false; } } std::string nsSYN::DynBoxDriver::DriverProbe () { ResDataObject r_config, HardwareInfo; if (r_config.loadFile (m_ConfigFileName.c_str ())) { HardwareInfo.add ("MajorID", r_config ["CONFIGURATION"] ["MajorID"]); HardwareInfo.add ("MinorID", r_config ["CONFIGURATION"] ["MinorID"]); HardwareInfo.add ("VendorID", r_config ["CONFIGURATION"] ["VendorID"]); HardwareInfo.add ("ProductID", r_config ["CONFIGURATION"] ["ProductID"]); HardwareInfo.add ("SerialID", r_config ["CONFIGURATION"] ["SerialID"]); } else { HardwareInfo.add("MajorID", "SYN"); HardwareInfo.add("MinorID", "Dr"); HardwareInfo.add("VendorID", "ECOM"); HardwareInfo.add("ProductID", "DYN"); HardwareInfo.add("SerialID", "1234"); } string ret = HardwareInfo.encode (); return ret; } bool nsSYN::DynBoxDriver::GetDeviceConfig(std::string& Cfg) { Cfg = m_DeviceConfig.encode(); printf("GetDeviceConfig over : %s \n", Cfg.c_str()); return true; } bool nsSYN::DynBoxDriver::SetDeviceConfig(std::string Cfg) { mLog::Info("--Func-- SetDeviceConfig {$}\n", Cfg.c_str()); ResDataObject DeviceConfig; DeviceConfig.decode(Cfg.c_str()); ResDataObject DescriptionTempEx; DescriptionTempEx = DeviceConfig["DeviceConfig"]["Attribute"]; mLog::Debug("Attribute:{$}", DescriptionTempEx.encode()); bool bSaveFile = false; //true:重新保存配置文件 string strAccess = ""; for (int i = 0; i < DescriptionTempEx.size(); i++) { string strKey = DescriptionTempEx.GetKey(i); mLog::Info("{$}", strKey.c_str()); try { if (m_pAttribute->GetFirstOf(strKey.c_str()) >= 0) { strAccess = (string)(*m_pDescription)[strKey.c_str()]["Access"]; if ("RW" == strAccess) { //修改对应配置,在其他单元的配置项要同时调用其修改函数修改真实值 //1. 修改内存中的值,用于给上层发消息 (*m_pAttribute)[strKey.c_str()] = DescriptionTempEx[i]; //2. 拿到Innerkey int nConfigInfoCount = (int)m_Configurations["ConfigToolInfo"].GetKeyCount("AttributeInfo"); mLog::Info("nConfigInfoCount {$}", nConfigInfoCount); string strTemp = ""; //存储AttributeKey for (int nInfoIndex = 0; nInfoIndex < nConfigInfoCount; nInfoIndex++) { strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"]; if (strTemp == strKey) { strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["InnerKey"]; break; } } //3. 修改配置文件中的值 if (SetDeviceConfigValue(m_Configurations, strTemp.c_str(), 1, DescriptionTempEx[i])) { mLog::Debug("SetDeviceConfigValue over"); bSaveFile = true; } } else { mLog::Info("{$} is not a RW configuration item", strKey.c_str()); } } else { mLog::Info("without this attribute {$}", strKey.c_str()); } } catch (ResDataObjectExption& e) { mLog::Error("SetDriverConfig crashed: {$}", e.what()); return false; } } if (bSaveFile) { //3. 重新保存配置文件 SaveConfigFile(true); } return true; } bool nsSYN::DynBoxDriver::SaveConfigFile(bool bSendNotify) { m_ConfigAll["CONFIGURATION"] = m_Configurations; bool bRt = m_ConfigAll.SaveFile(m_ConfigFileName.c_str()); mLog::Info("SaveConfigFile over {$}", bRt); return true; } bool nsSYN::DynBoxDriver::GetDeviceConfigValue(ResDataObject config, const char* pInnerKey, int nPathID, string& strValue) { strValue = ""; string strTemp = pInnerKey; if (1 == nPathID) //从DriverConfig路径下每个DPC自己的配置文件读取 { int pos = 0; ResDataObject resTemp= config; while ((pos = strTemp.find_first_of(',')) != string::npos) { string Key = strTemp.substr(0, pos); string TempValue = resTemp[Key.c_str()].encode(); resTemp.clear(); resTemp.decode(TempValue.c_str()); strTemp= strTemp.substr(pos+1,strTemp.length()-pos-1); } if (strTemp != "") { strValue=(string)resTemp[strTemp.c_str()]; } else { strValue = (string)resTemp; } } return true; } bool nsSYN::DynBoxDriver::SetDeviceConfigValue(ResDataObject& config, const char* pInnerKey, int nPathID, const char* szValue) { string strTemp = pInnerKey; mLog::Debug("Begin to change {$} item value to {$}", pInnerKey, szValue); if (1 == nPathID) //从DriverConfig路径下每个DPC自己的配置文件读取 { try { int pos = 0; ResDataObject *resTemp = &config; while ((pos = strTemp.find_first_of(',')) != string::npos) { string Key = strTemp.substr(0, pos); resTemp = &(*resTemp)[Key.c_str()]; strTemp = strTemp.substr(pos + 1, strTemp.length() - pos - 1); } if (strTemp != "") { (*resTemp)[strTemp.c_str()]= szValue; } else { *resTemp = szValue; } } catch (ResDataObjectExption& e) { mLog::Error("SetDriverConfigvalue crashed: {$}", e.what()); return false; } } return true; } std::string nsSYN::DynBoxDriver::GetResource () { ResDataObject r_config, temp; if (!temp.loadFile(m_ConfigFileName.c_str())) { return ""; } m_ConfigAll = temp; r_config = temp["CONFIGURATION"]; m_Configurations = r_config; ResDataObject DescriptionTemp; ResDataObject ListTemp; string strTemp = ""; //用于读取字符串配置信息 string strIndex = ""; //用于读取配置信息中的List项 int nTemp = -1; //用于读取整型配置信息 char sstream[10] = { 0 }; //用于转换值 string strValue = ""; //用于存储配置的值 string strType = ""; //用于存储配置的类型 int/float/string... /*** * 1. 通过循环,将所有配置项写到pDeviceConfig * 2. 记录配置项的内部key以及配置类型,类型对应了不同配置文件路径,用于读写真实值 ***/ try { int nConfigInfoCount = (int)m_Configurations["ConfigToolInfo"].GetKeyCount("AttributeInfo"); //mLog::Info(g_pFPDCtrlLog, "ConfigInfo Count: {$}", nConfigInfoCount); m_pAttribute->clear(); m_pDescription->clear(); for (int nInfoIndex = 0; nInfoIndex < nConfigInfoCount; nInfoIndex++) { DescriptionTemp.clear(); ListTemp.clear(); //AttributeType strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["Type"]; DescriptionTemp.add(ConfKey::AttributeType, strTemp.c_str()); //DescriptionTemp= m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]; //mLog::Info(g_pFPDCtrlLog, "--> {$}: {$}", AttributeType, strTemp.c_str()); strType = strTemp; //记录配置项的类型 //AttributeKey //1. 根据AttributeType,内部key和配置路径,拿到当前的真实值 strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["InnerKey"]; nTemp = (int)m_Configurations["ConfigToolInfo"][nInfoIndex]["PathID"]; GetDeviceConfigValue(r_config, strTemp.c_str(), nTemp, strValue); //2. 赋值 strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"]; if ("int" == strType) { (*m_pAttribute).add(strTemp.c_str(), atoi(strValue.c_str())); //mLog::Info(g_pFPDCtrlLog, "Key {$}: {$}", strTemp.c_str(), atoi(strValue.c_str())); } else if ("float" == strType) { (*m_pAttribute).add(strTemp.c_str(), atof(strValue.c_str())); //mLog::Info(g_pFPDCtrlLog, "Key {$}: {$}", strTemp.c_str(), atof(strValue.c_str())); } else //其它先按string类型处理 { (*m_pAttribute).add(strTemp.c_str(), strValue.c_str()); //mLog::Info(g_pFPDCtrlLog, "Key {$}: {$}", strTemp.c_str(), strValue.c_str()); } //AttributeAccess strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["Access"]; DescriptionTemp.add(ConfKey::AttributeAccess, strTemp.c_str()); //mLog::Info(g_pFPDCtrlLog, "{$}: {$}", AttributeAccess, strTemp.c_str()); //AttributeRangeMin strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["RangeMin"]; if (strTemp != "") //不需要的配置项为空 { DescriptionTemp.add(ConfKey::AttributeRangeMin, strTemp.c_str()); //mLog::Info(g_pFPDCtrlLog, "{$}: {$}", AttributeRangeMin, strTemp.c_str()); } //AttributeRangeMax strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["RangeMax"]; if (strTemp != "") //不需要的配置项为空 { DescriptionTemp.add(ConfKey::AttributeRangeMax, strTemp.c_str()); //mLog::Info(g_pFPDCtrlLog, "{$}: {$}", AttributeRangeMax, strTemp.c_str()); } //AttributeList nTemp = m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["ListNum"]; if (nTemp > 0) //ListNum不大于0时说明不需要list配置 { for (int nListIndex = 0; nListIndex < nTemp; nListIndex++) { strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["ListInfo"][nListIndex]; //sprintf_s(sstream, "{$}", nListIndex); auto temKey = std::to_string(nListIndex); ListTemp.add(temKey.c_str(), strTemp.c_str()); //mLog::Info(g_pFPDCtrlLog, "list {$}: {$}", nListIndex, strTemp.c_str()); } DescriptionTemp.add(ConfKey::AttributeList, ListTemp.encode()); } //AttributeRequired strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["Required"]; DescriptionTemp.add(ConfKey::AttributeRequired, strTemp.c_str()); //mLog::Info(g_pFPDCtrlLog, "{$}: {$}", AttributeRequired, strTemp.c_str()); //AttributeDefaultValue strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["DefaultValue"]; if (strTemp != "") //不需要的配置项为空 { DescriptionTemp.add(ConfKey::AttributeDefaultValue, strTemp.c_str()); //mLog::Info(g_pFPDCtrlLog, "{$}: {$}", AttributeDefaultValue, strTemp.c_str()); } strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"]; (*m_pDescription).add(strTemp.c_str(), DescriptionTemp); } } catch (ResDataObjectExption& e) { mLog::Error("Get config error: {$}", e.what()); return ""; } ResDataObject resDeviceResource; resDeviceResource.add(ConfKey::DiosAttribute, (*m_pAttribute)); resDeviceResource.add(ConfKey::DiosDescription, (*m_pDescription)); ResDataObject DescriptionTempEx; DescriptionTempEx.add(ConfKey::DiosConfig, resDeviceResource); m_DeviceConfig.clear(); m_DeviceConfig = DescriptionTempEx; string res = DescriptionTempEx.encode(); #if 0 mLog::Debug("get resource over {$}", DescriptionTempEx.encode()); printf("get resource over : %s \n", DescriptionTempEx.encode()); #endif // 0 return res; } std::string nsSYN::DynBoxDriver::DeviceProbe () { ResDataObject r_config, HardwareInfo; if (r_config.loadFile (m_ConfigFileName.c_str ())) { HardwareInfo.add ("MajorID", r_config ["CONFIGURATION"] ["MajorID"]); HardwareInfo.add ("MinorID", r_config ["CONFIGURATION"] ["MinorID"]); HardwareInfo.add ("VendorID", r_config ["CONFIGURATION"] ["VendorID"]); HardwareInfo.add ("ProductID", r_config ["CONFIGURATION"] ["ProductID"]); HardwareInfo.add ("SerialID", r_config ["CONFIGURATION"] ["SerialID"]); } else { HardwareInfo.add ("MajorID", "SYN"); HardwareInfo.add ("MinorID", "Dr"); HardwareInfo.add ("VendorID", "ECOM"); HardwareInfo.add ("ProductID", "DYN"); HardwareInfo.add ("SerialID", "1234"); } string ret = HardwareInfo.encode (); return ret; } void nsSYN::DynBoxDriver::Dequeue (const char * Packet, DWORD Length) { #if 0 char data[4] = { 0 }; strncpy_s(data, Packet, 3); mLog::Debug("Enter Dequeue[{$}]", data); #endif DecodeFrame (Packet, Length); } PACKET_RET nsSYN::DynBoxDriver::callbackPackageProcess (const char * RecData, DWORD nLength, DWORD& PacketLength) { //判断是否是整包 /* 这个是回调函数,我收到的数据会需要这个回调函数帮我判断是否是整个的包; 如果有整个的包,返回值为true,在PacketLength处返回给我整个包的长度,我再截取后放入缓存供上层使用; 如果缓存中的数据没有整个的数据包,那么返回false */ #if 0 char tempData[3]{ 0 }; tempData[0] = RecData[0]; if(nLength >= 2) tempData[1] = RecData[1]; if(strncmp(tempData, "EC",2) == 0) mLog::Debug("RecData[{$}],lengh[{$}]", tempData, nLength); #endif bool bHasHead = false; if (nLength < 3) { //mLog::Error ("nLength[{$}] < 3", nLength); PacketLength = 0; return PACKET_NOPACKET; } else if (nLength >= C2COM_Com_NormalLen) { mLog::Error("nLength[{$}] > [{$}] ", nLength, C2COM_Com_NormalLen); PacketLength = nLength; return PACKET_USELESS; } #if 0 string cmdHead; cmdHead.push_back(RecData[0]); cmdHead.push_back(RecData[1]); if (find(m_MapChannel.begin(), m_MapChannel.end(), cmdHead) != m_MapChannel.end()) { bHasHead = true; } #else char data[3] = { 0 }; strncpy_s(data, RecData, 2); auto found = arFrame.find(data); if (found != arFrame.end()) { bHasHead = true; } #endif // 0 for (DWORD i = 0; i < nLength-1; i++) { if (RecData [i] == 0x0d && RecData [i + 1] == 0x0a) { PacketLength = i + 2; char strtemp[C2COM_Com_NormalLen] = { 0 }; memcpy(strtemp, RecData, i);//0d 0a 不要了。 strtemp[PacketLength + 1] = 0; if (bHasHead) { //if (pSDCDevice != nullptr && pSDCDevice->GetConnectFlag() != 3) //{ // if (strncmp(RecData, "EC", 2) != 0) // { // mLog::Info("==IN ==:[{$}]discard because lost connect", strtemp); // return PACKET_USELESS; // } // else // { // mLog::Info("==IN ==:[{$}]get reconnectFlag success", strtemp); // return PACKET_ISPACKET; // } //} if (strncmp(RecData, "GR",2) != 0 && strncmp(RecData, "CR", 2) != 0 && strncmp(RecData, "EC", 2) != 0) // && strncmp(RecData, "EC", 2) != 0 { mLog::Info("==IN==:[{$}]", strtemp); found->second.tCheckWaitState(strtemp); mLog::Debug("finish tCheckWaitState"); } return PACKET_ISPACKET; } else { mLog::Error("==IN==:cmd[{$}][{$}] useless", PacketLength, RecData); return PACKET_USELESS; } } } if (bHasHead) { PacketLength = 0; } return PACKET_NOPACKET; } //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- void nsSYN::DynBoxDriver::CanShakeHand() { int nTimeout = 100; char cCmd[MAX_COMMAND_LEN] = "EC";// "SECA00"; int nCmdSize = 2;// 6; FormatCmd(cCmd, nCmdSize); string strLog; CmdtoString(cCmd, nCmdSize, strLog); mLog::Info("[Send:{$}]", strLog.c_str()); //printf("[Send:%s]\n", strLog.c_str()); mLog::Info("CanShakeHand ==OUT==: {$} ", cCmd); int ret = 0; m_SCF.Lock(msTimeOut_Lock) .SendPacket(cCmd, nCmdSize, nTimeout, ret); Sleep(nTimeout); } //----------------------------------------------------------------------------- // GetIODriver & CreateIODriver //----------------------------------------------------------------------------- static nsSYN::DynBoxDriver gIODriver; extern "C" DIOS::Dev::IODriver * __cdecl GetIODriver () // 返回静态对象的引用, 调用者不能删除 ! { return &gIODriver; } extern "C" DIOS::Dev::IODriver * __cdecl CreateIODriver () // 返回新对象, 调用者必须自行删除此对象 ! { pIODriver = new nsSYN::DynBoxDriver(); return pIODriver; }