// LogicDriver.cpp : 定义 DLL 应用程序的导出函数。 // //#include "Logger.h" #include "LogicDriver.h" #include "common_api.h" #include "PacketAnalizer.h" #include #define Driver_DeviceID "{66888A95-CDBE-6CA6-B53F-86185E4B9C88}" LogicDriver::LogicDriver() { m_pConfigFile = new ResDataObject(); m_pSubDeviceList = new SubDeviceDescriptList(); m_pConnectionStatus = new BaseJsonDataObject(); m_pConnectionStatus->SetKey("ConnectionStatus"); (*m_pConnectionStatus) = false; m_pReConnectFlag = new BaseJsonDataObject(); m_pReConnectFlag->SetKey("ReConnectFlag"); (*m_pReConnectFlag) = false; m_pReConnectTimePeriod = new BaseJsonDataObject(); m_pReConnectTimePeriod->SetKey("ReConnectTimePeriod"); (*m_pReConnectTimePeriod) = 10*1000; m_pHeartBeatTimePeriod = new BaseJsonDataObject(); m_pHeartBeatTimePeriod->SetKey("HeartBeatTimePeriod"); (*m_pHeartBeatTimePeriod) = 60 * 1000; m_pSelfTestResult = new BaseJsonDataObject(); m_pSelfTestResult->SetKey("SelfTest"); (*m_pSelfTestResult) = 0; m_pConnections = new ResDataObject(); m_pConnections->add("connections", ""); m_DisConnectionStatusEvt = LinuxEvent::CreateEvent(LinuxEvent::MANUAL_RESET,false);//manual,disconnect evt = false m_ReConnectLastTryTime = GetTickCount(); bool ret = true; ret &= m_Actions.add("SelfTest", ""); ret &= m_Actions.add("Connect", ""); ret &= m_Actions.add("DisConnect", ""); ret &= m_Actions.add("SetReConnectOption", ""); ret &= m_Actions.add("SetConnectionParam", ""); ret &= m_Actions.add("SetHeartBeatTimePeriod", ""); ret &= m_Actions.add("GetDriverDictionary", ""); ret &= m_Actions.add("GetDeviceConfig", ""); ret &= m_Actions.add("SetDeviceConfig", ""); return; } LogicDriver::~LogicDriver() { delete m_pConfigFile; delete m_pSubDeviceList; delete m_pConnectionStatus; delete m_pReConnectFlag; delete m_pSelfTestResult; delete m_pReConnectTimePeriod; delete m_pHeartBeatTimePeriod; delete m_pConnections; m_pConfigFile = NULL; m_pSubDeviceList = NULL; m_pConnectionStatus = NULL; m_pReConnectFlag = NULL; m_pReConnectTimePeriod = NULL; m_pHeartBeatTimePeriod = NULL; m_pConnections = NULL; m_pSelfTestResult = NULL; m_DisConnectionStatusEvt = NULL; return; } std::shared_ptr LogicDriver::GetPassiveDisConnectEvtHandle() { return m_DisConnectionStatusEvt; } void LogicDriver::ReSetPassiveDisConnect(bool DisConnect) { if (DisConnect) { m_DisConnectionStatusEvt->SetEvent(); } else { m_DisConnectionStatusEvt->ResetEvent(); } } void TryReadConnections(ResDataObject &config, ResDataObject &connection) { try { ResDataObject Context; if (config.GetFirstOf("connections") >= 0) { const char* pEncode = config["connections"].encode();//cut off \n\r \'\" Context.decode(pEncode); connection.update("connections", Context); } } catch (...) { connection["connections"] = ""; } } bool SYSTEM_CALL LogicDriver::DriverEntry(ResDataObject& PARAM_IN Configuration) { try { ResDataObject Temp; (*m_pConfigFile) = Configuration; if (TryGetValue(Configuration, "ReConnect", Temp)) { (*m_pReConnectFlag) = (bool)Temp; } Temp.clear(); if (TryGetValue(Configuration, "ReConnectTimePeriod", Temp)) { (*m_pReConnectTimePeriod) = ((DWORD)Temp)*1000; } if (TryGetValue(Configuration, "HeartBeatTimePeriod", Temp)) { (*m_pHeartBeatTimePeriod) = ((DWORD)Temp) * 1000; } //try read connections TryReadConnections(Configuration, *m_pConnections); } catch (...) { return false; } return true; } //get device type bool LogicDriver::GetDeviceType(GUID &DevType) { return string_2_guid(Driver_DeviceID, DevType); } //get device resource RET_STATUS LogicDriver::GetDeviceResource(ResDataObject *pDeviceResource) { bool ret = true; //PRINTA_INFO( "GetDeviceResource"); //make device type ret &= pDeviceResource->add("ClientType", DPC_DriverClient); GUID DrvType; string guidstr; GetDeviceType(DrvType); guid_2_string(DrvType, guidstr); ret &= pDeviceResource->add("DeviceType", guidstr.c_str()); //make attributes ResDataObject val; ResDataObject Actions; val.add(m_pConnectionStatus->GetKey(), m_pConnectionStatus->GetVal()); ResDataObject temp; temp = m_pSubDeviceList->GetResVal(); val.add(m_pSubDeviceList->GetKey(), temp); //change val val.add(m_pSelfTestResult->GetKey(), m_pSelfTestResult->GetVal()); val.add(m_pReConnectFlag->GetKey(), m_pReConnectFlag->GetVal()); val.add(m_pReConnectTimePeriod->GetKey(), m_pReConnectTimePeriod->GetVal()); val.add(m_pHeartBeatTimePeriod->GetKey(), m_pHeartBeatTimePeriod->GetVal()); val.add(m_pConnections->GetKey(0), (*m_pConnections)[0]); ResDataObject Diction; if (GetDriverDictionary(Diction) >= RET_SUCCEED) { val.add("DriverDictionary", Diction); } else { val.add("DriverDictionary", ""); } ret &= pDeviceResource->add("Attribute", val); /* ret &= Actions.add("SelfTest", ""); ret &= Actions.add("Connect", ""); ret &= Actions.add("DisConnect", ""); ret &= Actions.add("SetReConnectOption", ""); ret &= Actions.add("SetConnectionParam", ""); ret &= Actions.add("SetHeartBeatTimePeriod", ""); ret &= Actions.add("GetDriverDictionary", ""); ret &= Actions.add("GetDeviceConfig", ""); ret &= Actions.add("SetDeviceConfig", "");*/ if (ret) { pDeviceResource->add("Action", m_Actions); return RET_SUCCEED; } return RET_FAILED; } void SYSTEM_CALL LogicDriver::SetDpcsIdentifyKey(const char *pszIdentifykey) { m_SerialNo = pszIdentifykey; } const char* SYSTEM_CALL LogicDriver::GetDpcsSerialNo() { return (const char *)m_SerialNo; } RET_STATUS LogicDriver::GetSEQResource(ResDataObject PARAM_OUT *pDeviceResource) { ResDataObject Events; Events.add(m_pConnectionStatus->GetKey(), INFINITE); pDeviceResource->update("Event", Events); return RET_SUCCEED; } RET_STATUS DATA_ACTION LogicDriver::SelfTest() { RET_STATUS ret = RET_SUCCEED; if ((*m_pSelfTestResult) != 1) { //发通知 ResDataObject NotifyData; (*m_pSelfTestResult) = 1; PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pSelfTestResult->GetKey(), m_pSelfTestResult->GetVal()); //CmdFromLogicDev(&NotifyData); PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } return ret; } //ResourceCommand Request In and Response Out RET_STATUS LogicDriver::Request(ResDataObject *pRequest, ResDataObject *pResponse) { ResDataObject res; RET_STATUS ret = RET_NOSUPPORT; //1. analize request PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(pRequest); //cmd:get,set,add,del,exe, //ignore open/close //Action和Attr应该做成一个MAP,经过MAP访问这些资源,不应该是switch case //为了快速做一版,先保留switch case!!! string keystr = PacketAnalizer::GetPacketKey(pRequest); //PRINTA_INFO(m_pLogger, "Request is %s", keystr.c_str()); ACTION_SYNC_MODE syncmode = PacketAnalizer::GetPacketSyncMode(pRequest); switch (cmd){ case PACKET_CMD_GET: { if (keystr.size() == 0) { //get resource ret = GetDeviceResource(&res); pResponse->update("CONTEXT", res); } else { //it must be attribute get //Action和Attr应该做成一个MAP,经过MAP访问这些资源 //重新考虑了一遍,这个GET意义不大.因为值的变化总是以Data Notify形式进行同步. assert(0);//NOT FINISHED YET //这点需要应用层的确认,如果应用层没有获取,就没人调用进来 //if(keystr == m_Status.GetKey()) //{ // //yes they want it // //CMD的关键字是否要改成SET??? // pResponse->update("CONTEXT",m_Status.GetVal()); // ret = RET_SUCCEED; // PacketAnalizer::MakeRetCode(ret,pResponse); //} } } break; case PACKET_CMD_EXE: { if (keystr == "Connect") { if (Connect()) { ret = RET_SUCCEED; } else { ret = RET_FAILED; } } else if (keystr == "SelfTest") { ret = SelfTest(); } else if (keystr == "GetDriverDictionary") { ResDataObject obj; obj.add("DriverDictionary", ""); ret = GetDriverDictionary(obj["DriverDictionary"]); if (ret >= RET_SUCCEED) { res.add("P0", obj); //3. 打包 pResponse->update("CONTEXT", res); } } else if (keystr == "DisConnect") { DisConnect(); ret = RET_SUCCEED; } else if (keystr == "SetReConnectOption") { bool result = true; ResDataObject obj1, obj2; result &= PacketAnalizer::GetParam(pRequest, 0, obj1); result &= PacketAnalizer::GetParam(pRequest, 1, obj2); if (result) { ret = SetReConnectOption(obj1, obj2); } } else if (keystr == "SetConnectionParam") { bool result = true; ResDataObject obj1, obj2; result &= PacketAnalizer::GetParam(pRequest, 0, obj1); result &= PacketAnalizer::GetParam(pRequest, 1, obj2); if (result) { ret = SetConnectionParam((const char*)obj1, obj2); } } else if (keystr == "SetHeartBeatTimePeriod") { bool result = true; ResDataObject obj1; result &= PacketAnalizer::GetParam(pRequest, 0, obj1); if (result) { ret = SetHeartBeatTimePeriod((DWORD)obj1); } } else if (keystr == "GetDeviceConfig") { ret = (RET_STATUS)GetDeviceConfig(&res); pResponse->update("CONTEXT", res); } else if (keystr == "SetDeviceConfig") { bool result = true; ResDataObject obj1; result &= PacketAnalizer::GetParam(pRequest, 0, obj1); if (result) { ret = (RET_STATUS)SetDeviceConfig(&obj1); } } } break; default: //对当前设备来讲,其他都是浮云 break; } //return status PacketAnalizer::MakeRetCode(ret, pResponse); return ret; } //notify to lower layer RET_STATUS LogicDriver::CmdToLogicDev(ResDataObject *pCmd) { //这个命令只有一种情况下发生(作为客户端存在的时候) //1.设备的Notify消息 //发往当前客户端的Notify //Data&Action notify!!! //Data Notify分两种 //一种是本数据对象的更新,直接更新 //一种是数据传递给上层,比如图像数据,探测器的剂量需求数据 //Action Notify是发给Owner的 //通知事件,让Owner知道,另外ActionNotify先保留下来 //保留到哪里??? //2.Response //命令Request发出后的反馈 //1. analize request //2. call api //3. check results //put error log here assert(0);//not happening return RET_FAILED; } RET_STATUS LogicDriver::SetHeartBeatTimePeriod(DWORD TimePeriod) { RET_STATUS ret = RET_SUCCEED; if ((*m_pHeartBeatTimePeriod) != TimePeriod) { //发通知 ResDataObject NotifyData; (*m_pHeartBeatTimePeriod) = TimePeriod; PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pHeartBeatTimePeriod->GetKey(), m_pHeartBeatTimePeriod->GetVal()); CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } return ret; } bool LogicDriver::AddDevice(const char *pPath) { //添加设备 if (m_pSubDeviceList->AddDevice(pPath)) { //发通知 ResDataObject NotifyData; ResDataObject theContext; theContext = (pPath); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_ADD, m_pSubDeviceList->GetKey(), theContext); CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); return true; } return false; } bool LogicDriver::DelDevice(const char *pPath) { //删除设备 if (m_pSubDeviceList->DelDevice(pPath)) { //发通知 ResDataObject NotifyData; ResDataObject theContext; theContext = (pPath); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_DEL, m_pSubDeviceList->GetKey(), theContext); CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); return true; } return false; } void SYSTEM_CALL LogicDriver::GetDeviceList(ResDataObject &Object) { Object = (*m_pSubDeviceList).GetResVal(); } void LogicDriver::SetLastDisconnectTime(DWORD LastTick) { if ((*m_pConnectionStatus) == false) { m_ReConnectLastTryTime = LastTick; } } DWORD LogicDriver::GetLastDisconnectTime() { if ((*m_pConnectionStatus) == false) { DWORD ret = m_ReConnectLastTryTime; return ret; } return 0; } RET_STATUS LogicDriver::GetHeartBeatTimePeriod(DWORD &TimePeriod) { TimePeriod = (*m_pHeartBeatTimePeriod); return RET_SUCCEED; } RET_STATUS LogicDriver::GetReConnectOption(bool &Flag, DWORD &TimePeriod) { Flag = (*m_pReConnectFlag); TimePeriod = (*m_pReConnectTimePeriod); return RET_SUCCEED; } bool LogicDriver::GetConnectionStatus() { return (*m_pConnectionStatus); } void LogicDriver::OnSetClientID() { // std::cout << "LogicDriver " << endl; } void LogicDriver::SubscribeSelf() //所有子类必须使用 SubscribeTopic 订阅自身topic及资源topic,如果不知道需要DPC代订阅 { LogicDevice::SubscribeSelf(); if (m_strEBusRoot.length() > 0) SubscribeTopic(m_pMqttConntion, m_strEBusRoot.c_str()); SubscribeActions(); std::cout << "LogicDriver " << endl; //SubscribeTopic(m_pMqttConntion) } RET_STATUS LogicDriver::SetReConnectOption(bool Flag, DWORD TimePeriod) { RET_STATUS ret = RET_SUCCEED; if ((*m_pReConnectFlag) != Flag) { //发通知 ResDataObject NotifyData; (*m_pReConnectFlag) = Flag; PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pReConnectFlag->GetKey(), m_pReConnectFlag->GetVal()); CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } if ((*m_pReConnectTimePeriod) != TimePeriod) { //发通知 ResDataObject NotifyData; (*m_pReConnectTimePeriod) = TimePeriod; PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pReConnectTimePeriod->GetKey(), m_pReConnectTimePeriod->GetVal()); CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } return ret; } bool SYSTEM_CALL LogicDriver::Driver_Probe(ResDataObject& PARAM_OUT DriverInfo) { ResDataObject Config; GetConfiguration(&Config); DriverInfo.add("MajorID", (const char*)Config["MajorID"]); DriverInfo.add("MinorID", (const char*)Config["MinorID"]); DriverInfo.add("VendorID", (const char*)Config["VendorID"]); DriverInfo.add("ProductID", (const char*)Config["ProductID"]); DriverInfo.add("SerialID", (const char*)Config["SerialID"]); return true; } void SYSTEM_CALL LogicDriver::GetConfiguration(ResDataObject *pConfig) { (*pConfig) = (*m_pConfigFile); } ResDataObject& LogicDriver::GetConnectionParam() { return (*m_pConnections)["connections"]; } RET_STATUS LogicDriver::SetConnectionParam(const char *pTitle, ResDataObject &ConnectionContext) { RET_STATUS ret = RET_SUCCEED; try { int idx = (*m_pConnections)[0].GetFirstOf(pTitle); if (idx >= 0) { //update it //check it before set (*m_pConnections)[0][idx] = ConnectionContext; //notify it ResDataObject Context; ResDataObject NotifyData; Context.add(pTitle, ConnectionContext); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pConnections->GetKey(0), Context); CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } } catch (...) { ret = RET_FAILED; } return ret; } bool DATA_ACTION LogicDriver::Connect() { if ((*m_pConnectionStatus) == false) { //发通知 ResDataObject NotifyData; (*m_pConnectionStatus) = true; m_DisConnectionStatusEvt->ResetEvent(); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pConnectionStatus->GetKey(), m_pConnectionStatus->GetVal()); CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); return true; } return false; } void DATA_ACTION LogicDriver::DisConnect() { //if ((*m_pConnectionStatus) == true) { //发通知 ResDataObject NotifyData; (*m_pConnectionStatus) = false; m_DisConnectionStatusEvt->SetEvent(); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pConnectionStatus->GetKey(), m_pConnectionStatus->GetVal()); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); CmdFromLogicDev(&NotifyData); } //发删除设备通知 //for (size_t i = 0; i < m_pSubDeviceList->m_DeviceList.size(); i++) //{ // string DevPath = m_pSubDeviceList->m_DeviceList[i]; // ResDataObject NotifyData; // ResDataObject theContext; // theContext = DevPath.c_str(); // PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_DEL, m_pSubDeviceList->GetKey(), theContext); // CmdFromLogicDev(&NotifyData); // //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); //} ////清除设备列表 //m_pSubDeviceList->m_DeviceList.clear(); //设置时间 SetLastDisconnectTime(GetTickCount()); } bool SYSTEM_CALL LogicDriver::OnHeartBeat() { return true; } RET_STATUS DATA_ACTION LogicDriver::SetDeviceConfig(ResDataObject PARAM_IN *DeviceConfig) { return RET_SUCCEED; } RET_STATUS DATA_ACTION LogicDriver::GetDeviceConfig(ResDataObject PARAM_OUT *pDeviceConfig) { return RET_SUCCEED; }