DrvTree.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. #include "DrvTree.h"
  2. #include "LocalConfig.h"
  3. #include "common_api.h"
  4. #include "PacketAnalizer.h"
  5. #include "BusUnitLogic.h"
  6. #include "HandleManager.h"
  7. #include "LogLocalHelper.h"
  8. #include "Log4CPP.h"
  9. DrvTree g_DrvTree;
  10. //--------------DrvTreeNode-------------
  11. DrvTreeNode::DrvTreeNode()
  12. {
  13. //m_NodeName = new string();
  14. //m_SubNodes = new map<string, DrvTreeNode>();
  15. //m_EndNode = false;
  16. m_ProcId = 0;
  17. m_Address = 0;
  18. return;
  19. }
  20. DrvTreeNode::~DrvTreeNode()
  21. {
  22. //delete m_NodeName;
  23. //delete m_SubNodes;
  24. return;
  25. }
  26. //
  27. //void DrvTreeNode::InitTreeNode(const char *pNodeName, UINT64 ProcId, UINT64 Address)
  28. //{
  29. // (*m_NodeName) = pNodeName;
  30. // m_ProcId = ProcId;
  31. // m_Address = Address;
  32. //
  33. // if (ProcId != 0 && Address != 0)
  34. // {
  35. // m_EndNode = true;
  36. // }
  37. //
  38. //}
  39. //
  40. //const char* DrvTreeNode::GetNodeName()
  41. //{
  42. // return m_NodeName->c_str();
  43. //}
  44. //
  45. //bool DrvTreeNode::Check_AddSubNode(DrvTreeNode &SubNode)
  46. //{
  47. // bool ret = true;
  48. // map<string, DrvTreeNode>::iterator it = m_SubNodes->find(string(SubNode.GetNodeName()));
  49. // if (it != m_SubNodes->end())
  50. // {
  51. // //found same name node
  52. // if (it->second.m_EndNode == true && SubNode.m_EndNode == true)
  53. // {
  54. // //two device to one node
  55. // if ((it->second.m_Address != SubNode.m_Address) || (it->second.m_ProcId != SubNode.m_ProcId))
  56. // {
  57. // //put log here
  58. // return false;
  59. // }
  60. //
  61. // }
  62. //
  63. // //add (subnode::nodes) -> it
  64. // map<string, DrvTreeNode>::iterator subit = SubNode.m_SubNodes->begin();
  65. // while (subit != SubNode.m_SubNodes->end())
  66. // {
  67. //
  68. // ret &= it->second.Check_AddSubNode(subit->second);
  69. // if (ret == false)
  70. // {
  71. // return false;
  72. // }
  73. // ++subit;
  74. // }
  75. //
  76. // }
  77. // else
  78. // {
  79. // if (SubNode.m_NodeName->size() == 0)
  80. // {
  81. // return false;
  82. // }
  83. // }
  84. //
  85. // return ret;
  86. //}
  87. //
  88. //bool DrvTreeNode::AddSubNode(DrvTreeNode &SubNode)
  89. //{
  90. // if (Check_AddSubNode(SubNode))
  91. // {
  92. // map<string, DrvTreeNode>::iterator it = m_SubNodes->find(string(SubNode.GetNodeName()));
  93. // if (it != m_SubNodes->end())
  94. // {
  95. // //add (subnode::nodes) -> it
  96. // map<string, DrvTreeNode>::iterator subit = SubNode.m_SubNodes->begin();
  97. // while (subit != SubNode.m_SubNodes->end())
  98. // {
  99. //
  100. // it->second.AddSubNode(subit->second);
  101. // ++subit;
  102. // }
  103. //
  104. // if (it->second.m_EndNode == false && SubNode.m_EndNode == true)
  105. // {
  106. // it->second.m_EndNode = true;
  107. // it->second.m_ProcId = SubNode.m_ProcId;
  108. // it->second.m_Address = SubNode.m_Address;
  109. // }
  110. // }
  111. // else
  112. // {
  113. // //just insert it
  114. // (*m_SubNodes)[string(SubNode.GetNodeName())] = SubNode;
  115. //
  116. // }
  117. //
  118. // return true;
  119. // }
  120. //
  121. // return false;
  122. //
  123. //
  124. //}
  125. //
  126. ////only way to del subpath is that [current node] have no subnodes,
  127. ////ex,if can't del [end point],then clear [end points] status .
  128. //bool DrvTreeNode::DelSubPath(const char *pSubPath)
  129. //{
  130. // vector<string> nodes;
  131. // if (SplitDevicePath(pSubPath, nodes))
  132. // {
  133. // for (size_t i = 0; i < nodes.size(); i++)
  134. // {
  135. // map<string, DrvTreeNode>::iterator it = m_SubNodes->find(nodes[i]);
  136. // }
  137. //
  138. // }
  139. //
  140. //
  141. //}
  142. //--------------DrvTree-------------
  143. DrvTree::DrvTree()
  144. {
  145. m_DrvTreeMap = new map<string, DrvTreeNode>();
  146. m_LocalProcIdList = new map<UINT64, vector<UINT64>>();
  147. m_rootClient = new LogicClient("DriveTree","driver");
  148. SetName("DriveThree");
  149. }
  150. DrvTree::~DrvTree()
  151. {
  152. if (m_DrvTreeMap)
  153. {
  154. delete m_DrvTreeMap;
  155. m_DrvTreeMap = NULL;
  156. }
  157. if (m_LocalProcIdList)
  158. {
  159. delete m_LocalProcIdList;
  160. m_LocalProcIdList = NULL;
  161. }
  162. }
  163. void DrvTree::Clear()
  164. {
  165. Thread_Lock(INFINITE);
  166. m_rootClient->Close();
  167. m_DrvTreeMap->clear();
  168. m_LocalProcIdList->clear();
  169. Thread_UnLock();
  170. }
  171. bool DrvTree::AddTree(const char *pDevicePath, UINT64 ProcId, UINT64 Address)
  172. {
  173. bool ret = false;
  174. //printf("\r\n *** DevTree AddTree %s procid: 0x%08X address: 0x%08X\r\n\r\n", pDevicePath, ProcId, Address);
  175. Thread_Lock(INFINITE);
  176. map<string, DrvTreeNode>::iterator it = m_DrvTreeMap->find(string(pDevicePath));
  177. //if (it != m_DrvTreeMap->end()) {
  178. // DelTree(pDevicePath);
  179. // it = m_DrvTreeMap->find(string(pDevicePath));
  180. //}
  181. if (it == m_DrvTreeMap->end())
  182. {
  183. //insert it
  184. DrvTreeNode node;
  185. node.m_ProcId = ProcId;
  186. node.m_Address = Address;
  187. map<UINT64, vector<UINT64>>::iterator itp = m_LocalProcIdList->find(ProcId);
  188. if (itp == m_LocalProcIdList->end())
  189. {
  190. //new one
  191. vector<UINT64> sec;
  192. sec.push_back(Address);
  193. (*m_LocalProcIdList)[ProcId] = sec;
  194. }
  195. else
  196. {
  197. //exist one
  198. (*m_LocalProcIdList)[ProcId].push_back(Address);
  199. }
  200. (*m_DrvTreeMap)[string(pDevicePath)] = node;
  201. //for test begin
  202. //printf("drv Loaded.path:%s\n", pDevicePath);
  203. //printf("drv Loaded.PID:%d\n", ProcId);
  204. //printf("drv Loaded.ADDR:%d\n", Address);
  205. //for test end
  206. ret = true;
  207. }
  208. Thread_UnLock();
  209. return ret;
  210. }
  211. bool DrvTree::DelTree(const char *pDevicePath)
  212. {
  213. bool ret = false;
  214. Thread_Lock(INFINITE);
  215. map<string, DrvTreeNode>::iterator it = m_DrvTreeMap->find(string(pDevicePath));
  216. if (it != m_DrvTreeMap->end())
  217. {
  218. //delete it
  219. //1. clear proc map
  220. UINT64 ProcId = it->second.m_ProcId;
  221. UINT64 Address = it->second.m_Address;
  222. //for test begin
  223. //printf("drv UnLoaded.path:%s\n", pDevicePath);
  224. //printf("drv UnLoaded.PID:%d\n", ProcId);
  225. //printf("drv UnLoaded.ADDR:%d\n", Address);
  226. //for test end
  227. map<UINT64, vector<UINT64>>::iterator itp = m_LocalProcIdList->find(ProcId);
  228. if (itp != m_LocalProcIdList->end())
  229. {
  230. g_HandleManager.DeviceDetached(ProcId, Address);
  231. //clear one address in proc
  232. vector<UINT64>::iterator itA = find(itp->second.begin(), itp->second.end(), Address);
  233. if (itA != itp->second.end())
  234. {
  235. itp->second.erase(itA);//erase one addres of proc
  236. }
  237. if (itp->second.size() == 0)
  238. {
  239. m_LocalProcIdList->erase(itp);//erase whole proc
  240. }
  241. }
  242. m_DrvTreeMap->erase(it);
  243. ret = true;
  244. }
  245. Thread_UnLock();
  246. return ret;
  247. }
  248. void DrvTree::PrintExistTree()
  249. {
  250. DWORD idx = 0;
  251. Thread_Lock(INFINITE);
  252. map<string, DrvTreeNode>::iterator it = m_DrvTreeMap->begin();
  253. while (it != m_DrvTreeMap->end())
  254. {
  255. FERROR("Exist Dev[{$}]:{$}", idx++, it->first.c_str());
  256. ++it;
  257. }
  258. Thread_UnLock();
  259. }
  260. bool DrvTree::GetTreeNode(const char *pDevicePath, DrvTreeNode &node)
  261. {
  262. bool ret = false;
  263. Thread_Lock(INFINITE);
  264. map<string, DrvTreeNode>::iterator it = m_DrvTreeMap->find(string(pDevicePath));
  265. if (it != m_DrvTreeMap->end())
  266. {
  267. node = it->second;
  268. ret = true;
  269. }
  270. Thread_UnLock();
  271. return ret;
  272. }
  273. bool DrvTree::CheckNode(UINT64 ProcId,UINT64 Address)
  274. {
  275. bool ret = false;
  276. Thread_Lock(INFINITE);
  277. map<UINT64, vector<UINT64>>::iterator it = m_LocalProcIdList->find(ProcId);
  278. if (it != m_LocalProcIdList->end())
  279. {
  280. vector<UINT64>::iterator itA = find(it->second.begin(), it->second.end(), Address);
  281. if (itA != it->second.end())
  282. {
  283. ret = true;
  284. }
  285. }
  286. Thread_UnLock();
  287. return ret;
  288. }
  289. bool DrvTree::Exec()
  290. {
  291. std::shared_ptr<LinuxEvent> hand = m_rootClient->GetNotifyHandle();
  292. std::vector<std::shared_ptr<LinuxEvent>> vec = { m_ExitFlag, hand };
  293. DWORD wait = LinuxEvent::WaitForMultipleEvents(vec, -1);
  294. //printf("DrvTree---:Thread:%d,hit DrvTree Entry.code:%d\n", GetCurrentThreadId(),wait);
  295. if (wait == WAIT_OBJECT_0)
  296. {
  297. //printf("DrvTree---:Exit Thread\n");
  298. return false;
  299. }
  300. else if (wait == WAIT_OBJECT_0 + 1)
  301. {
  302. //got notify
  303. //printf("DrvTree---:Got Notify\n");
  304. ResDataObject packet, Context;
  305. try {
  306. //printf("Thread:%d,DrvTree Thread Loop\n", GetCurrentThreadId());
  307. if (m_rootClient->IsClosed() == false)
  308. {
  309. PACKET_CMD cmd = PACKET_CMD_NONE;
  310. do {
  311. cmd = m_rootClient->ReadNotify(packet);
  312. //printf("Thread:%d,DrvTree Thread Cmd:%d\n", GetCurrentThreadId(), cmd);
  313. if (cmd == PACKET_CMD_ADD)
  314. {
  315. DeviceDescript dd;
  316. PacketAnalizer::GetPacketContext(&packet, Context);
  317. //printf("DrvTree---:Thread:%d,got PACKET_CMD_ADD Notify\n", GetCurrentThreadId());
  318. //printf("add tree cmd : \n %s \n", (char*)packet.encode());
  319. if (dd.SetResDataObject(Context))
  320. {
  321. //do the add
  322. AddTree(dd.GetKey(), dd.m_ProcId, dd.m_Address);
  323. }
  324. }
  325. else if (cmd == PACKET_CMD_DEL)
  326. {
  327. ResDataObject path;
  328. PacketAnalizer::GetPacketContext(&packet, Context);
  329. path = Context[0];// devicepath:path
  330. //do the del
  331. //printf("DrvTree---:Thread:%d,got PACKET_CMD_DEL Notify\n", GetCurrentThreadId());
  332. DelTree((const char *)path);
  333. }
  334. else
  335. {
  336. //ignore others
  337. //printf("DrvTree---:Thread:%d,DrvTree Thread Ignore %d %s \n", GetCurrentThreadId(), cmd, packet.encode());
  338. }
  339. } while (cmd != PACKET_CMD_NONE);
  340. }
  341. else
  342. {
  343. //printf("DrvTree---:rootClient.IsClosed() true \n");
  344. //no need try,just exit the Thread
  345. return false;
  346. //try once
  347. //if (m_rootClient.Open((const char*)getRootpath(), ALL_ACCESS) == false)
  348. //{
  349. // printf("Thread:%d,Open Failed\n", GetCurrentThreadId());
  350. // return false;
  351. //}
  352. }
  353. }
  354. catch (...)
  355. {
  356. //printf("Thread:%d,Exeption in DrvTree Thread\n", GetCurrentThreadId());
  357. }
  358. }
  359. return true;
  360. }
  361. bool DrvTree::OnStartThread()
  362. {
  363. //printf("========== DrvTree::OnStartThread 0X%08X \n", GetCurrentThreadId());
  364. SetThreadOnTheRun(true);
  365. //printf("TreeMonitor Thread:%d\n", GetCurrentThreadId());
  366. if (m_rootClient->Open((const char*)getRootpath(), ALL_ACCESS, "", 10000) != RET_SUCCEED)
  367. {
  368. //printf("Thread:%d,Open RootDevice Failed\n", GetCurrentThreadId());
  369. //be careful
  370. //it's possible multiple dev in the root
  371. return false;
  372. }
  373. //printf("Thread:%d,Open RootDevice Succeed\n", GetCurrentThreadId());
  374. return true;
  375. }
  376. bool DrvTree::OnEndThread()
  377. {
  378. //printf("========== DrvTree::OnEndThread 0X%08X \n", GetCurrentThreadId());
  379. Clear();
  380. return true;
  381. }