#include "stdafx.h" #include "FileVersion.hpp" #include "DIOS.Dev.SyncBoxe.2000ST.h" #include "Helper.JSON.hpp" #include "CommonFun.h" #include "common_api.h" using namespace DIOS::Dev::Detail::SYNBOX; namespace nsSYN = DIOS::Dev::Detail::SYNBOX; #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”,可能丢失数据 using namespace DIOS::Dev::Detail::SYNBOX; namespace nsSYN = DIOS::Dev::Detail::SYNBOX; Log4CPP::Logger* mLog::gLogger = nullptr; ////----------------------------------------------------------------------------- //// DynBoxDevice ////----------------------------------------------------------------------------- nsSYN::SyncBoxDevice::SyncBoxDevice(std::shared_ptr center, nsSCF::SCF SCF, string configfile) : super(center, SCF) { assert(EventCenter); m_DynBoxDevice.reset(new DynBoxDevice(center, SCF, configfile)); m_MSGUnit.reset(new nsDetail::MSGUnit(center, SyncConsoleUnitType)); m_CollimatorDevice.reset(new CollimatorDevice(center, SCF)); Register(); OnCallBack(); } nsSYN::SyncBoxDevice::~SyncBoxDevice() { } std::string nsSYN::SyncBoxDevice::GetGUID() const { mLog::FINFO("\n===============GetGUID : {$} ===================\n", SyncConsoleUnitType); return SyncConsoleUnitType; } void nsSYN::SyncBoxDevice::Register() { auto Disp = &Dispatch; m_DynBoxDevice->Register(Disp); m_CollimatorDevice->Register(Disp); Disp->Get.Push(m_MSGUnit->GetKey().c_str(), [this](std::string& out) { out = m_MSGUnit->JSGet(); return RET_STATUS::RET_SUCCEED; }); } void nsSYN::SyncBoxDevice::OnCallBack() { mLog::FINFO("SyncBoxDevice::OnCallBack in"); auto HWNotProcess = [](const char* value, int length) -> void { mLog::FERROR("\n This commands didn't need to process!\n"); }; auto HWSignal = [this](const char* value, int length) -> void { assert(value); char cChannelValue; cChannelValue = value[2]; //status : on /off string strChannel = ((string)value).substr(0, 2); bool bStatus = ChartoInt(cChannelValue); mLog::FINFO("HWSignal:{$}",value); m_DynBoxDevice->DealtheSignal(strChannel.c_str(), bStatus); }; 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(sCmdID, &data_can[4], length - 4); }; // 有部分前缀是包含关系, 长的包含短的, 例如 KVS 包含了 KV. // 因此长的在前面, 短的在后面 // !!! Device 是个短寿命对象, 而 arFrame 是静态变量 !!! // !!! 因此, 在添加到 arFrame 之前, 务必先清零 !!! arFrame.clear(); arFrame.push_back(tFrameMapping("GR", 2, HWCAN)); arFrame.push_back(tFrameMapping("CR", 2, HWCAN)); arFrame.push_back(tFrameMapping("TB", 2, HWSignal)); arFrame.push_back(tFrameMapping("WB", 2, HWSignal)); arFrame.push_back(tFrameMapping("GT", 2, HWSignal)); arFrame.push_back(tFrameMapping("GW", 2, HWSignal)); arFrame.push_back(tFrameMapping("PT", 2, HWSignal)); arFrame.push_back(tFrameMapping("PW", 2, HWSignal)); arFrame.push_back(tFrameMapping("ER", 2, HWSignal)); arFrame.push_back(tFrameMapping("RT", 2, HWSignal)); arFrame.push_back(tFrameMapping("RW", 2, HWSignal)); arFrame.push_back(tFrameMapping("OT", 2, HWSignal)); arFrame.push_back(tFrameMapping("OW", 2, HWSignal)); arFrame.push_back(tFrameMapping("PR", 2, HWSignal)); arFrame.push_back(tFrameMapping("FT", 2, HWSignal)); arFrame.push_back(tFrameMapping("FW", 2, HWSignal)); arFrame.push_back(tFrameMapping("TT", 2, HWSignal)); arFrame.push_back(tFrameMapping("TW", 2, HWSignal)); } //----------------------------------------------------------------------------- // DynBoxDriver //----------------------------------------------------------------------------- nsSYN::DynBoxDriver::DynBoxDriver () { m_bDemoConnected = false; m_pAttribute.reset(new ResDataObject()); m_pDescription.reset(new ResDataObject()); #ifdef _WIN64 g_strAppPath = GetProcessDirectory() + R"(OEMDrivers\SyncBox\2000T\DIOS.Dev.SyncBoxe.2000ST64.dll)"; #else g_strAppPath = GetProcessDirectory() + R"(OEMDrivers\SyncBox\2000T\DIOS.Dev.SyncBoxe.2000ST.dll)"; #endif } nsSYN::DynBoxDriver::~DynBoxDriver () { } auto nsSYN::DynBoxDriver::CreateDevice (int index) -> std::unique_ptr { mLog::FINFO("Enter CreateDevice()"); if (!m_SCF.isConnected()) { mLog::FERROR("CreateDevice but scf no connect"); return nullptr; } if (index == 0) { m_p2000tDevice = new SyncBoxDevice(EventCenter, m_SCF, m_ConfigFileName); auto dev = std::unique_ptr (new IODevice(m_p2000tDevice)); return dev; } return nullptr; } void nsSYN::DynBoxDriver::FireNotify (int code, std::string key, std::string content) { EventCenter->OnNotify (code, key, content); } void nsSYN::DynBoxDriver::Prepare () { string strLogPath = GetProcessDirectory() + R"(\OEMDrivers\SyncBox\Conf\Log4CPP.Config.SYN.xml)"; Log4CPP::GlobalContext::Map::Set(ECOM::Utility::Hash("LogFileName"), "SYN.2000T"); auto rc = Log4CPP::LogManager::LoadConfigFile(strLogPath.c_str()); if (!rc) { printf("\n Load log configfile failed!\n"); } mLog::gLogger = Log4CPP::LogManager::GetLogger("SYN.2000T"); m_SCFDllName = GetConnectDLL(m_ConfigFileName); super::Prepare (); } bool nsSYN::DynBoxDriver::Connect () { ResDataObject Connection = GetConnectParam(m_ConfigFileName); mLog::FINFO("connections:{$}, ConfigFileName: {$}", Connection.encode(), m_ConfigFileName); auto erCode = m_SCF.Connect(Connection.encode(), &nsSYN::DynBoxDriver::callbackPackageProcess, SCF_PACKET_TRANSFER, 3000); mLog::FINFO("scf connect code {$}", erCode); if (erCode != SCF_ERR::SCF_SUCCEED) { mLog::FINFO("connect scf failed"); return false; } mLog::FINFO("Connect: make success"); CanShakeHand(); //Sleep(1000); //SetCANState(true);//open can //Sleep(1000); ReadVersion(); //Sleep(200); auto rc = super::Connect(); if (!rc) return false; mLog::FINFO("connect scf ok"); return true; } void nsSYN::DynBoxDriver::Disconnect() { super::Disconnect(); m_SCF.Disconnect(); m_bDemoConnected = false; } bool nsSYN::DynBoxDriver::isConnected() const { if (super::isConnected()) { 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", "2000T"); 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::FINFO("--Func-- SetDeviceConfig {$}\n", Cfg.c_str()); ResDataObject DeviceConfig; DeviceConfig.decode(Cfg.c_str()); ResDataObject DescriptionTempEx; DescriptionTempEx = DeviceConfig["DeviceConfig"]["Attribute"]; mLog::FDEBUG("Attribute:{$}", DescriptionTempEx.encode()); bool bSaveFile = false; //true:重新保存配置文件 string strAccess = ""; for (int i = 0; i < DescriptionTempEx.size(); i++) { string strKey = DescriptionTempEx.GetKey(i); mLog::FINFO("{$}", 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::FINFO("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::FDEBUG("SetDeviceConfigValue over"); bSaveFile = true; } } else { mLog::FINFO("{$} is not a RW configuration item", strKey.c_str()); } } else { mLog::FINFO("without this attribute {$}", strKey.c_str()); } } catch (ResDataObjectExption& e) { mLog::FERROR("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::FINFO("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::FDEBUG("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::FERROR("SetDriverConfigvalue crashed: {$}", e.what()); return false; } } return true; } std::string nsSYN::DynBoxDriver::GetResource() { mLog::FINFO("Enter 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::FINFO(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::FINFO(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::FINFO(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::FINFO(g_pFPDCtrlLog, "Key {$}: {$}", strTemp.c_str(), atof(strValue.c_str())); } else //其它先按string类型处理 { (*m_pAttribute).add(strTemp.c_str(), strValue.c_str()); //mLog::FINFO(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::FINFO(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::FINFO(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::FINFO(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::FINFO(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::FINFO(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::FINFO(g_pFPDCtrlLog, "{$}: {$}", AttributeDefaultValue, strTemp.c_str()); } strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"]; (*m_pDescription).add(strTemp.c_str(), DescriptionTemp); } } catch (ResDataObjectExption& e) { mLog::FERROR("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(); mLog::FDEBUG("get resource over {$}", DescriptionTempEx.encode()); printf("get resource over : %s \n", DescriptionTempEx.encode()); 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", "2000T"); HardwareInfo.add ("SerialID", "1234"); } string ret = HardwareInfo.encode (); return ret; } void nsSYN::DynBoxDriver::Dequeue (const char * Packet, DWORD Length) { DecodeFrame(Packet, Length); } PACKET_RET nsSYN::DynBoxDriver::callbackPackageProcess (const char * RecData, DWORD nLength, DWORD& PacketLength) { if (nLength < 1) { mLog::FERROR("nLength < 1, nLength=={$} \n", nLength); return PACKET_USELESS; } for (DWORD i = 0; i < nLength - 1; i++) { if (RecData [i] == 0x0d && RecData [i + 1] == 0x0a) { PacketLength = i + 2; char strtemp [100] = { 0 }; memcpy (strtemp, RecData, i); strtemp [PacketLength + 1] = 0; mLog::FINFO("2000T ==IN ==:{$}\n", strtemp); return PACKET_ISPACKET; } else if (RecData [i] == 0x03) { mLog::FERROR("(Hex)0x03 ,len={$} \n", i); PacketLength = i + 1; return PACKET_USELESS; } } 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::FINFO( "[Send:{$}]", strLog.c_str()); mLog::FINFO("CanShakeHand ==OUT==: {$} ", cCmd); int ret = 0; m_SCF.Lock(msTimeOut_Lock) .SendPacket(cCmd, nCmdSize, nTimeout, ret); Sleep(nTimeout); } void nsSYN::DynBoxDriver::ReadVersion() { int nTimeout = 100; char cCmd[MAX_COMMAND_LEN] = "VR?";// "SECA00"; int nCmdSize = 3;// 6; FormatCmd(cCmd, nCmdSize); string strLog; CmdtoString(cCmd, nCmdSize, strLog); mLog::FINFO("[Send:{$}]", strLog.c_str()); mLog::FINFO("CanShakeHand ==OUT==: {$} ", cCmd); int ret = 0; m_SCF.Lock(msTimeOut_Lock) .SendPacket(cCmd, nCmdSize, nTimeout, ret); Sleep(nTimeout); } void nsSYN::DynBoxDriver::SetCANState(bool state) { mLog::FINFO("Enter SetCANState()"); int nTimeout = 100; ResDataObject temp; mLog::FINFO("ConfigFileName [{$}]", m_ConfigFileName); if (!temp.loadFile(m_ConfigFileName.c_str())) return; auto ResDYNConfig = temp["CONFIGURATION"]["DeviceConfig"]; m_Configurations = ResDYNConfig; TransJsonText(m_Configurations); char cCmd[MAX_COMMAND_LEN] = { 0 }; string CANProtocol = (string)m_Configurations["CANPortocol"]; mLog::FINFO("CANProtocol [{$}]", CANProtocol); string CANBaud = (string)m_Configurations["CANBaud"]; mLog::FINFO("CANBaud [{$}]", CANBaud); int nCmdSize = 0; if (CANProtocol == "1") { cCmd[0] = 'G'; } else { cCmd[0] = 'C'; } if (state) { cCmd[1] = 'O'; mLog::FINFO("OpenCAN"); cCmd[2] = CANBaud[0]; string CANFilter = (string)m_Configurations["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; } nCmdSize = 5; } else { cCmd[1] = 'C'; cCmd[2] = '0'; mLog::FINFO("CloseCAN"); nCmdSize = 3; } FormatCmd(cCmd, nCmdSize); string strLog; CmdtoString(cCmd, nCmdSize, strLog); mLog::FINFO("[Send:{$}]", strLog.c_str()); //printf("[Send:%s]\n", strLog.c_str()); mLog::FINFO("SetCANState==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 () // 返回新对象, 调用者必须自行删除此对象 ! { return new nsSYN::DynBoxDriver (); }