#include "DrvTree.h" #include "LocalConfig.h" #include "common_api.h" #include "PacketAnalizer.h" #include "BusUnitLogic.h" #include "HandleManager.h" //#include "Logger.h" DrvTree g_DrvTree; //--------------DrvTreeNode------------- DrvTreeNode::DrvTreeNode() { //m_NodeName = new string(); //m_SubNodes = new map(); //m_EndNode = false; m_ProcId = 0; m_Address = 0; return; } DrvTreeNode::~DrvTreeNode() { //delete m_NodeName; //delete m_SubNodes; return; } // //void DrvTreeNode::InitTreeNode(const char *pNodeName, UINT64 ProcId, UINT64 Address) //{ // (*m_NodeName) = pNodeName; // m_ProcId = ProcId; // m_Address = Address; // // if (ProcId != 0 && Address != 0) // { // m_EndNode = true; // } // //} // //const char* DrvTreeNode::GetNodeName() //{ // return m_NodeName->c_str(); //} // //bool DrvTreeNode::Check_AddSubNode(DrvTreeNode &SubNode) //{ // bool ret = true; // map::iterator it = m_SubNodes->find(string(SubNode.GetNodeName())); // if (it != m_SubNodes->end()) // { // //found same name node // if (it->second.m_EndNode == true && SubNode.m_EndNode == true) // { // //two device to one node // if ((it->second.m_Address != SubNode.m_Address) || (it->second.m_ProcId != SubNode.m_ProcId)) // { // //put log here // return false; // } // // } // // //add (subnode::nodes) -> it // map::iterator subit = SubNode.m_SubNodes->begin(); // while (subit != SubNode.m_SubNodes->end()) // { // // ret &= it->second.Check_AddSubNode(subit->second); // if (ret == false) // { // return false; // } // ++subit; // } // // } // else // { // if (SubNode.m_NodeName->size() == 0) // { // return false; // } // } // // return ret; //} // //bool DrvTreeNode::AddSubNode(DrvTreeNode &SubNode) //{ // if (Check_AddSubNode(SubNode)) // { // map::iterator it = m_SubNodes->find(string(SubNode.GetNodeName())); // if (it != m_SubNodes->end()) // { // //add (subnode::nodes) -> it // map::iterator subit = SubNode.m_SubNodes->begin(); // while (subit != SubNode.m_SubNodes->end()) // { // // it->second.AddSubNode(subit->second); // ++subit; // } // // if (it->second.m_EndNode == false && SubNode.m_EndNode == true) // { // it->second.m_EndNode = true; // it->second.m_ProcId = SubNode.m_ProcId; // it->second.m_Address = SubNode.m_Address; // } // } // else // { // //just insert it // (*m_SubNodes)[string(SubNode.GetNodeName())] = SubNode; // // } // // return true; // } // // return false; // // //} // ////only way to del subpath is that [current node] have no subnodes, ////ex,if can't del [end point],then clear [end points] status . //bool DrvTreeNode::DelSubPath(const char *pSubPath) //{ // vector nodes; // if (SplitDevicePath(pSubPath, nodes)) // { // for (size_t i = 0; i < nodes.size(); i++) // { // map::iterator it = m_SubNodes->find(nodes[i]); // } // // } // // //} //--------------DrvTree------------- DrvTree::DrvTree() { m_DrvTreeMap = new map(); m_LocalProcIdList = new map>(); m_rootClient = new LogicClient("DriveTree","driver"); SetName("DriveThree"); } DrvTree::~DrvTree() { if (m_DrvTreeMap) { delete m_DrvTreeMap; m_DrvTreeMap = NULL; } if (m_LocalProcIdList) { delete m_LocalProcIdList; m_LocalProcIdList = NULL; } } void DrvTree::Clear() { Thread_Lock(INFINITE); m_rootClient->Close(); m_DrvTreeMap->clear(); m_LocalProcIdList->clear(); Thread_UnLock(); } bool DrvTree::AddTree(const char *pDevicePath, UINT64 ProcId, UINT64 Address) { bool ret = false; //printf("\r\n *** DevTree AddTree %s procid: 0x%08X address: 0x%08X\r\n\r\n", pDevicePath, ProcId, Address); Thread_Lock(INFINITE); map::iterator it = m_DrvTreeMap->find(string(pDevicePath)); //if (it != m_DrvTreeMap->end()) { // DelTree(pDevicePath); // it = m_DrvTreeMap->find(string(pDevicePath)); //} if (it == m_DrvTreeMap->end()) { //insert it DrvTreeNode node; node.m_ProcId = ProcId; node.m_Address = Address; map>::iterator itp = m_LocalProcIdList->find(ProcId); if (itp == m_LocalProcIdList->end()) { //new one vector sec; sec.push_back(Address); (*m_LocalProcIdList)[ProcId] = sec; } else { //exist one (*m_LocalProcIdList)[ProcId].push_back(Address); } (*m_DrvTreeMap)[string(pDevicePath)] = node; //for test begin //printf("drv Loaded.path:%s\n", pDevicePath); //printf("drv Loaded.PID:%d\n", ProcId); //printf("drv Loaded.ADDR:%d\n", Address); //for test end ret = true; } Thread_UnLock(); return ret; } bool DrvTree::DelTree(const char *pDevicePath) { bool ret = false; Thread_Lock(INFINITE); map::iterator it = m_DrvTreeMap->find(string(pDevicePath)); if (it != m_DrvTreeMap->end()) { //delete it //1. clear proc map UINT64 ProcId = it->second.m_ProcId; UINT64 Address = it->second.m_Address; //for test begin //printf("drv UnLoaded.path:%s\n", pDevicePath); //printf("drv UnLoaded.PID:%d\n", ProcId); //printf("drv UnLoaded.ADDR:%d\n", Address); //for test end map>::iterator itp = m_LocalProcIdList->find(ProcId); if (itp != m_LocalProcIdList->end()) { g_HandleManager.DeviceDetached(ProcId, Address); //clear one address in proc vector::iterator itA = find(itp->second.begin(), itp->second.end(), Address); if (itA != itp->second.end()) { itp->second.erase(itA);//erase one addres of proc } if (itp->second.size() == 0) { m_LocalProcIdList->erase(itp);//erase whole proc } } m_DrvTreeMap->erase(it); ret = true; } Thread_UnLock(); return ret; } void DrvTree::PrintExistTree() { DWORD idx = 0; Thread_Lock(INFINITE); map::iterator it = m_DrvTreeMap->begin(); while (it != m_DrvTreeMap->end()) { //mLog::FERROR("Exist Dev[{$}]:{$}", idx++, it->first.c_str()); ++it; } Thread_UnLock(); } bool DrvTree::GetTreeNode(const char *pDevicePath, DrvTreeNode &node) { bool ret = false; Thread_Lock(INFINITE); map::iterator it = m_DrvTreeMap->find(string(pDevicePath)); if (it != m_DrvTreeMap->end()) { node = it->second; ret = true; } Thread_UnLock(); return ret; } bool DrvTree::CheckNode(UINT64 ProcId,UINT64 Address) { bool ret = false; Thread_Lock(INFINITE); map>::iterator it = m_LocalProcIdList->find(ProcId); if (it != m_LocalProcIdList->end()) { vector::iterator itA = find(it->second.begin(), it->second.end(), Address); if (itA != it->second.end()) { ret = true; } } Thread_UnLock(); return ret; } bool DrvTree::Exec() { std::shared_ptr hand = m_rootClient->GetNotifyHandle(); std::vector> vec = { m_ExitFlag, hand }; DWORD wait = LinuxEvent::WaitForMultipleEvents(vec, -1); //printf("DrvTree---:Thread:%d,hit DrvTree Entry.code:%d\n", GetCurrentThreadId(),wait); if (wait == WAIT_OBJECT_0) { //printf("DrvTree---:Exit Thread\n"); return false; } else if (wait == WAIT_OBJECT_0 + 1) { //got notify //printf("DrvTree---:Got Notify\n"); ResDataObject packet, Context; try { //printf("Thread:%d,DrvTree Thread Loop\n", GetCurrentThreadId()); if (m_rootClient->IsClosed() == false) { PACKET_CMD cmd = PACKET_CMD_NONE; do { cmd = m_rootClient->ReadNotify(packet); //printf("Thread:%d,DrvTree Thread Cmd:%d\n", GetCurrentThreadId(), cmd); if (cmd == PACKET_CMD_ADD) { DeviceDescript dd; PacketAnalizer::GetPacketContext(&packet, Context); //printf("DrvTree---:Thread:%d,got PACKET_CMD_ADD Notify\n", GetCurrentThreadId()); //printf("add tree cmd : \n %s \n", (char*)packet.encode()); if (dd.SetResDataObject(Context)) { //do the add AddTree(dd.GetKey(), dd.m_ProcId, dd.m_Address); } } else if (cmd == PACKET_CMD_DEL) { ResDataObject path; PacketAnalizer::GetPacketContext(&packet, Context); path = Context[0];// devicepath:path //do the del //printf("DrvTree---:Thread:%d,got PACKET_CMD_DEL Notify\n", GetCurrentThreadId()); DelTree((const char *)path); } else { //ignore others //printf("DrvTree---:Thread:%d,DrvTree Thread Ignore %d %s \n", GetCurrentThreadId(), cmd, packet.encode()); } } while (cmd != PACKET_CMD_NONE); } else { //printf("DrvTree---:rootClient.IsClosed() true \n"); //no need try,just exit the Thread return false; //try once //if (m_rootClient.Open((const char*)getRootpath(), ALL_ACCESS) == false) //{ // printf("Thread:%d,Open Failed\n", GetCurrentThreadId()); // return false; //} } } catch (...) { //printf("Thread:%d,Exeption in DrvTree Thread\n", GetCurrentThreadId()); } } return true; } bool DrvTree::OnStartThread() { //printf("========== DrvTree::OnStartThread 0X%08X \n", GetCurrentThreadId()); SetThreadOnTheRun(true); //printf("TreeMonitor Thread:%d\n", GetCurrentThreadId()); if (m_rootClient->Open((const char*)getRootpath(), ALL_ACCESS, "", 10000) != RET_SUCCEED) { //printf("Thread:%d,Open RootDevice Failed\n", GetCurrentThreadId()); //be careful //it's possible multiple dev in the root return false; } //printf("Thread:%d,Open RootDevice Succeed\n", GetCurrentThreadId()); return true; } bool DrvTree::OnEndThread() { //printf("========== DrvTree::OnEndThread 0X%08X \n", GetCurrentThreadId()); Clear(); return true; }