// DriverThread.cpp : 定义 DLL 应用程序的导出函数。 // #include "stdafx.h" #include "PacketAnalizer.h" #include "DriverThread.h" #include "LocalConfig.h" #include "MsgQueue.h" #include "CDInterface.h" extern Log4CPP::Logger* //mLog::gLogger; //#include "Logger.h" #include Driver_Thread::Driver_Thread(void) { m_pDeviceSysIFMap = new MsgMap(); m_pDeviceSysIFVec = new MsgVector(); } Driver_Thread::~Driver_Thread(void) { m_pDeviceSysIFMap->Clear(); delete m_pDeviceSysIFMap; m_pDeviceSysIFMap = NULL; m_pDeviceSysIFVec->Clear(); delete m_pDeviceSysIFVec; m_pDeviceSysIFVec = NULL; } bool Driver_Thread::HandleClientRequest() { bool ret = false; ResDataObject ReqObj, ResObj; if (PopReqDataObject(ReqObj)) { //find target UINT64 addr = 0; //mLog::FDEBUG("Req->Dev Entry"); ret = true; //get device address if (PacketAnalizer::GetPacketHandleAddr(&ReqObj, addr, true)) { //find obj LogicDeviceSysIF *pDevObj = NULL; if (m_pDeviceSysIFMap->Find(addr, pDevObj)) { //exec it if (pDevObj) { LogicDevice *pDevice = pDevObj->GetLogicDevice(); if (pDevice) { //open&close request //open request PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(&ReqObj); if (cmd == PACKET_CMD_OPEN) { //mLog::FDEBUG(ReqObj,"Got Open Packet:\n"); CcosDevFileHandle handle; //printf("Driver Thread:%d,Got Open Packet\n", GetCurrentThreadId()); //regist handle ResDataObject devRes; if (pDevice->GetDeviceResource(&devRes) == RET_SUCCEED) { pDevice->LogicDevice::GetDeviceResource(&devRes); //update not exist shit //update attr //if (devRes.GetFirstOf("Attribute") < 0) //{ // devRes.add("Attribute", ""); //} if (PacketAnalizer::MakeOpenResponse(ReqObj, ResObj, devRes)) { //printf("Driver Thread:%d,Got Device Resource\n", GetCurrentThreadId()); ResDataObject handleRes; PacketAnalizer::GetPacketHandle(&ResObj, handleRes); handle.SetResDataObject(handleRes); if (CDInterface::GetCDI()->Registhandle((HANDLE)&handle)) { //done here //mLog::FDEBUG("Open Packet Dispatch to Client"); //printf("Driver Thread:%d,Open Response Dispatch to Client\n", GetCurrentThreadId()); } else { //mLog::FERROR("Open Packet already opened"); printf("Driver Thread:%d,Failed Regist Handle.already opened 3\n", GetCurrentThreadId()); PacketAnalizer::MakeRetCode(RET_WARNING, &ResObj, "already opened"); } } else { //mLog::FERROR("Open Packet Failed Make Open Response"); printf("Driver Thread:%d,Failed Make Open Response\n", GetCurrentThreadId()); PacketAnalizer::MakeRetCode(RET_FAILED, &ResObj, "ccos paltform error"); } } else { //mLog::FERROR("Open Packet Failed get Device Resource"); printf("Driver Thread:%d,Failed get Device Resource\n", GetCurrentThreadId()); PacketAnalizer::MakeOpenResponse(ReqObj, ResObj, devRes); PacketAnalizer::MakeRetCode(RET_FAILED, &ResObj, "get Device Resource error"); } if (CDInterface::GetCDI()->ReceivedFromDevice(ResObj)) { //mLog::FDEBUG("Open Packet Dispatch to Client Succeed"); } else { //mLog::FINFO("Open Packet Dispatch to Client Failed"); } } else if (cmd == PACKET_CMD_CLOSE) { //mLog::FDEBUG(ReqObj, "Got Close Request:\n"); if (PacketAnalizer::MakeCloseResponse(ReqObj, ResObj)) { UINT64 crc = 0; PacketAnalizer::GetPacketHandleCrc(&ReqObj, crc); //mLog::FDEBUG("Close Packet UnRegistHandle"); if (CDInterface::GetCDI()->UnRegistHandle(crc)) { //done here //mLog::FDEBUG("Close Packet Not Dispatch to Client"); //printf("Driver Thread:%d,Close Response Not Dispatch to Client\n", GetCurrentThreadId()); //if (GetCommandDispathIF()->ReceivedFromDevice(ResObj)) //{ // //mLog::FDEBUG("Close Packet Dispatch to Client Succeed"); //} //else //{ // //mLog::FINFO("Close Packet Dispatch to Client Failed"); //} } else { //mLog::FERROR("Close Packet Failed UnRegist Handle "); //printf("Driver Thread:%d,Failed UnRegist Handle\n", GetCurrentThreadId()); } } else { //mLog::FERROR("Failed Make Close Resource"); printf("Driver Thread:%d,Failed Make Close Resource\n", GetCurrentThreadId()); } } else { //mLog::FDEBUG(ReqObj,"Got Action Request:\n"); PacketAnalizer::CloneResponse(ResObj, &ReqObj); string keystr = PacketAnalizer::GetPacketKey(&ReqObj); if (keystr == "UpdateDeviceResource") { ResDataObject devRes; Thread_Lock(); if (pDevice->GetDeviceResource(&devRes) == RET_SUCCEED) { pDevice->LogicDevice::GetDeviceResource(&devRes); PacketAnalizer::UpdatePacketContext(ResObj, devRes); PacketAnalizer::MakeRetCode(RET_SUCCEED, &ResObj); } else { PacketAnalizer::MakeRetCode(RET_FAILED, &ResObj); } Thread_UnLock(); } else { RET_STATUS ret = pDevice->Request(&ReqObj, &ResObj); } //send result to owner if (PacketAnalizer::MakePacketContextExistance(&ResObj)) { //mLog::FDEBUG(ResObj,"Action Response Dispatch to Client:\n"); if (CDInterface::GetCDI()->ReceivedFromDevice(ResObj)) { //mLog::FDEBUG("Action Response Dispatch to Client Succeed"); } else { //mLog::FINFO("Action Response Dispatch to Client Failed"); } } } } else { //mLog::FERROR("LogicDev is NULL "); printf("Driver Thread:%d,LogicDev is NULL\n", GetCurrentThreadId()); } } else { //mLog::FERROR("SysIF is NULL"); printf("Driver Thread:%d,SysIF is NULL\n", GetCurrentThreadId()); } } else { printf("Driver Thread:%d,no match drvobj<->Addr\n", GetCurrentThreadId()); } } else { //mLog::FERROR("GetPacket Device Handle Addr Failed"); printf("Driver Thread:%d,GetPacket Device Handle Addr Failed\n", GetCurrentThreadId()); } //mLog::FDEBUG("HandleClientRequest Exit"); } return ret; } bool Driver_Thread::HandleDeviceNotify() { bool ret = false; ResDataObject ResObj; if (PopResDataObject(ResObj)) { //got Notify //check p2p or broardcast //mLog::FDEBUG("Device Notify Entry"); string OwnerBusId; if (PacketAnalizer::GetPacketHandleBusId(&ResObj, OwnerBusId, false)) { if (OwnerBusId.size() > 0) { //p2p //mLog::FDEBUG("p2p dispatch"); //printf("Driver Thread:%d,p2p dispatch\n", GetCurrentThreadId()); // send it ret = CDInterface::GetCDI()->ReceivedFromDevice(ResObj); if (ret) { //mLog::FDEBUG("P2P Notify Dispatch to Client Succeed"); } else { //mLog::FINFO("P2P Notify Dispatch to Client Failed"); } } else { //mLog::FDEBUG("broardcast dispatch"); std::cout << " \n\n ******* what packet " << ResObj.encode() << endl<< endl; //printf("Driver Thread:%d,broardcast dispatch\n", GetCurrentThreadId()); //broardcast //ret = CDInterface::GetCDI()->ReceivedDeviceNotify(ResObj); //从 ..../Notify/#上通知了,无须再次发送 //if (ret) //{ // //mLog::FDEBUG("broardcast Notify Dispatch to Client Succeed"); //} //else //{ // //mLog::FINFO("broardcast Notify Dispatch to Client Failed"); //} } } else { //mLog::FDEBUG("rong Packet,unable get Owner BusId"); printf("Driver Thread:%d,Wrong Packet,unable get Owner BusId\n", GetCurrentThreadId()); } //mLog::FDEBUG("Device Notify Exit"); } return ret; } bool Driver_Thread::Exec(void) { try { while (WaitForInQue()) { //pump In&Out que //check req first //Thread_Lock(); HandleClientRequest(); //Thread_UnLock(); //check res second HandleDeviceNotify(); } } catch (ResDataObjectExption &exp) { //mLog::FERROR( exp.what()); } catch (...) { //mLog::FERROR("Exeption happend in Device Request"); } Thread_UnLock();//incase exeption return true; } bool Driver_Thread::OnStartThread(void) { printf("========== Driver_Thread::OnStartThread 0X%08X \n", GetCurrentThreadId()); //mLog::FINFO("Driver Thread Begin Entry....."); return true; } bool Driver_Thread::OnEndThread(void) { printf("========== Driver_Thread::OnEndThread 0X%08X \n", GetCurrentThreadId()); try { ResDataObject ReqObj, ResObj,Context; while (PopReqDataObject(ReqObj)) { PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(&ReqObj); if (cmd == PACKET_CMD_OPEN) { PacketAnalizer::MakeOpenResponse(ReqObj, ResObj, Context); PacketAnalizer::MakeRetCode(RET_INVALID, &ResObj, "device is invalid"); if (CDInterface::GetCDI()->ReceivedFromDevice(ResObj)) { //mLog::FDEBUG("Open Res Packet Dispatch to Client Succeed"); } else { //mLog::FINFO("Open Res Packet Dispatch to Client Failed"); } ReqObj.clear(); ResObj.clear(); } } } catch (...) { } //mLog::FERROR("Driver Thread End Exit....."); return true; } void Driver_Thread::RegistSysIFObject(LogicDeviceSysIF* pobj) { UINT64 key = (UINT64)pobj; m_pDeviceSysIFVec->PushBack(pobj); m_pDeviceSysIFMap->InMap(key, pobj); } bool Driver_Thread::UnRegistSysIFObject(LogicDeviceSysIF* pobj) { UINT64 key = (UINT64)pobj; bool ret = m_pDeviceSysIFVec->FindAndClear(pobj); ret &= m_pDeviceSysIFMap->DeMap(key, pobj); return ret; } //--------------------------------------------- Notify_Driver_Thread::Notify_Driver_Thread(void) { } Notify_Driver_Thread::~Notify_Driver_Thread(void) { StopThread(); } bool Notify_Driver_Thread::Exec(void) { try { int Idx = WaitForEvent(); if (Idx < 0) { //exit return false; } else if (Idx > 0) { //got device notify //get work here ProcessDeviceEvent((size_t)Idx - 1);//start from 1 } //Idx == 0 //something in the que or pause cmd came //make sure it waits nothing if (CheckForPause()) { //mLog::FDEBUG("Got Pause Evt.Wait Resume"); if (WaitforResume() == false) { //mLog::FDEBUG("Failed Wait Resume Evt.Exit Thread"); return false; } //mLog::FDEBUG("Got Resume Evt.Go Normal"); } while (WaitForInQue(0)) { //pump In&Out que //check req first HandleClientRequest(); //check res second HandleDeviceNotify(); } } catch (ResDataObjectExption &exp) { //mLog::FERROR(exp.what()); } catch (...) { //mLog::FERROR("Exeption happend in Device Notify"); } return true; } bool Notify_Driver_Thread::ProcessDeviceEvent(size_t Idx) { bool ret = false; ((MsgVector*)m_pDeviceSysIFVec)->Lock(); if (((MsgVector*)m_pDeviceSysIFVec)->Size() > Idx) { LogicDevice *pDevice = (*((MsgVector*)m_pDeviceSysIFVec))[Idx]->GetLogicDevice(); if (pDevice) { pDevice->EvtProcedure(); ret = true; } } ((MsgVector*)m_pDeviceSysIFVec)->UnLock(); return ret; } //-1:exit //0:something inque //>0:device evt int Notify_Driver_Thread::WaitForEvent() { int waitCount = 0; HANDLE wait[MAXIMUM_WAIT_OBJECTS] = { 0 }; wait[waitCount++] = m_ExitFlag; wait[waitCount++] = m_PauseEvt; wait[waitCount++] = m_WorkFlag; wait[waitCount++] = ((MsgQueue *)m_pWorkQueReq)->GetNotifyHandle(); wait[waitCount++] = ((MsgQueue *)m_pWorkQueRes)->GetNotifyHandle(); ((MsgVector*)m_pDeviceSysIFVec)->Lock(); size_t size = ((MsgVector*)m_pDeviceSysIFVec)->Size(); if (size > MAXIMUM_WAIT_OBJECTS - 3) { assert(0);//it must stop } for (size_t i = 0; i < size; i++) { LogicDevice *pDevice = (*((MsgVector*)m_pDeviceSysIFVec))[i]->GetLogicDevice(); wait[waitCount++] = pDevice->GetEvtHandle(); } ((MsgVector*)m_pDeviceSysIFVec)->UnLock(); DWORD ret = WaitForMultipleObjects(waitCount, wait, FALSE, INFINITE); if (ret == WAIT_OBJECT_0) { //exit evt return -1; } if (ret == WAIT_OBJECT_0 + 1) { //pause cmd return 0; } if ((ret > WAIT_OBJECT_0 + 1) && (ret < WAIT_OBJECT_0 + 5)) { //work&cmd evt return 0; } if ((ret >= WAIT_OBJECT_0 + 5) && (ret < WAIT_OBJECT_0 + waitCount)) { //index start with 1 return (ret - WAIT_OBJECT_0 - 4); } return -1; }