// ConnectionManager.cpp: implementation of the CConnectionManager class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MgrNVE.h" #include "ConnectionManager.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #pragma comment(lib, "PUBLIB/LIB/Mcl/mcl.lib") ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CConnectionManager::CConnectionManager() { m_pMgrNVE = NULL; m_pMsgMgr = NULL; m_uServerIndex = 0; m_uProcessState = CMN5_PS_INIT; m_bCapture = FALSE; m_pCod5Api = NULL; m_pNet5Api = NULL; m_hCodEvent = NULL; m_hNetEvent = NULL; m_hSensorEvent = NULL; m_hVStatusEvent = NULL; m_bFirstCh = FALSE; m_uProtocol = 0; m_bReconnect = FALSE; m_bRack = FALSE; m_bAudioOut = FALSE; m_bReconnecting = FALSE; ZeroMemory(m_bSetupSuccess, sizeof(m_bSetupSuccess)); ZeroMemory(m_bSetupWait, sizeof(m_bSetupWait)); ZeroMemory(m_MDInfo, sizeof(m_MDInfo)); } CConnectionManager::~CConnectionManager() { } BOOL CConnectionManager::ProcessSetup() { m_bCapture = TRUE; // for seperate Capture and Apply. if (m_uProcessState != CMN5_PS_INIT) { return FALSE; } #if 1 if (!SetupProc()) { ProcessEndup(); return FALSE; } #else for (ULONG i=0;i < NVE_MAX_CHANNEL;i++) { m_uChannel[i] = i; if (!m_SetupThread[i].StartThread(ThreadSetupProcStub, &m_uChannel[i], this, NULL)) { TRACE("ProcessSetup failed. server index[%d], channel[%d]", m_uServerIndex, i); return FALSE; } } #endif m_uProcessState = CMN5_PS_SETUP; return TRUE; } BOOL CConnectionManager::ProcessEndup() { switch(m_uProcessState) { case CMN5_PS_RUN: m_pCod5Api->Cod5Stop(); break; case CMN5_PS_SETUP: m_pCod5Api->Cod5Endup(); break; default: return FALSE; } for (ULONG i=0;i < NVE_MAX_CHANNEL;i++) { if (m_SetupThread[i].GetState() == TS_RUN) { m_SetupThread[i].StopThread(0); } } m_uProcessState = CMN5_PS_INIT; m_bSetupSuccess[0] = FALSE; return TRUE; } BOOL CConnectionManager::ProcessRun() { CMclAutoLock autolock(m_CritSec); if (m_uProcessState != CMN5_PS_SETUP) { return FALSE; } #if 1 if (!RunProc()) { ProcessEndup(); return FALSE; } #else for (ULONG i=0;i < NVE_MAX_CHANNEL;i++) { m_uChannel[i] = i; if (!m_RunThread[i].StartThread(ThreadRunProcStub, &m_uChannel[i], this, NULL)) { TRACE("ProcessRun failed. server index[%d], channel[%d]", m_uServerIndex, i); return FALSE; } } #endif m_uProcessState = CMN5_PS_RUN; return TRUE; } BOOL CConnectionManager::ProcessStop() { CMclAutoLock autolock(m_CritSec); if (m_uProcessState != CMN5_PS_RUN) { return FALSE; } for (ULONG i=0;i < NVE_MAX_CHANNEL;i++) { if (m_RunThread[i].GetState() == TS_RUN) { m_RunThread[i].StopThread(0); } } m_pCod5Api->Cod5Stop(); m_ProcUserData.StopEventThread(); m_bCapture = FALSE; m_uProcessState = CMN5_PS_SETUP; return TRUE; } BOOL CConnectionManager::Init(IUnknown *pUnknown, LPCSTR addr, ULONG uProtocol, LPCTSTR pID, LPCTSTR pPW, ULONG linCh, CMgrNVE *pMgrNVE, ULONG uCh) { strcpy(m_ServerIP, addr); m_uServerIndex = linCh; m_uProtocol = uProtocol; safe_strcpy(m_szUserID, pID); safe_strcpy(m_szUserPW, pPW); m_pMgrNVE = pMgrNVE; m_pMsgMgr = pMgrNVE->GetMsgManager(); if (uCh == 0) { m_bFirstCh = TRUE; } pUnknown->QueryInterface (IID_ICod5,(void**)&m_pCod5Api); pUnknown->QueryInterface (IID_INet5,(void**)&m_pNet5Api); pUnknown->Release(); SetDefaultSettings(); for (ULONG i=0; iNet5ConnectEx(addr, uProtocol, 5)) { m_pMsgMgr->PushErrorCodeF("Net5ConnectEx failed"); m_pMsgMgr->Show(TRUE); return FALSE; } if (!m_pCod5Api->Cod5GetSystemInfo(&m_SystemInfo)) { m_pMsgMgr->PushErrorCodeF("Cod5GetSystemInfo failed"); m_pMsgMgr->Show(TRUE); } CMN5_BOARD_INFO_DESC InfoDesc = { sizeof(COD5_BOARD_INFO), CMN5_BOARD_INFO_VERSION }; if (!m_pCod5Api->Cod5GetBoardInfo(0, &InfoDesc, &m_BoardInfo)) { m_pMsgMgr->PushErrorCodeF("Cod5GetBoardInfo failed"); m_pMsgMgr->Show(TRUE); } CopyMemory(&m_GlobalSettings.SystemInfo, &m_SystemInfo, sizeof(m_SystemInfo)); CopyMemory(&m_GlobalSettings.BoardInfo, &m_BoardInfo, sizeof(m_BoardInfo)); if (!m_pCod5Api->Cod5QueryInfo(CMN5_QIC_GET_HWINFO_STR, 0, m_GlobalSettings.InformationString)) { m_pMsgMgr->PushErrorCodeF("Cod5QueryInfo failed"); m_pMsgMgr->Show(TRUE); } char *pFoundStr = strstr(m_GlobalSettings.InformationString, "BPuPver"); if (pFoundStr) { char szVer[2]; szVer[0] = pFoundStr[strlen("BPuPver")+1]; szVer[1] = 0; ULONG uVer = atoi(szVer); if (uVer >= 1) { m_bRack = TRUE; } } pFoundStr = strstr(m_GlobalSettings.InformationString, "max_audio_out_ch"); if (pFoundStr) { char szName[NVE_MAX_STR_LENGTH], szValue[NVE_SHORT_STR_LENGTH]; sscanf(pFoundStr, "%[a-zA-Z0-9_]=%[a-zA-Z0-9_]", szName, szValue); if (atoi(szValue) > 0) { m_bAudioOut = TRUE; } } if (!m_pNet5Api->Net5Login(pID, pPW)) { m_pMsgMgr->PushErrorCodeF("Net5Login failed"); m_pMsgMgr->Show(TRUE); return FALSE; } return TRUE; } void CConnectionManager::Release() { m_bReconnect = FALSE; if (m_ReconnectThread.GetState() == TS_RUN) { m_ReconnectThread.StopThread(0); } m_ProcUserData.Release(); m_pNet5Api->Net5Logout(); m_pNet5Api->Net5Disconnect(); if(m_pCod5Api){ m_pCod5Api->Release(); m_pCod5Api = NULL; } if(m_pNet5Api){ m_pNet5Api->Release(); m_pNet5Api = NULL; } } BOOL CConnectionManager::IsSameAddress(LPCSTR Addr) { if (!strcmp(m_ServerIP, Addr)) { return TRUE; } return FALSE; } BOOL CConnectionManager::SetupProc() { // temporary static const UCHAR ActivationCode[CMN5_ACTIVATION_CODE_SIZE] = {0,}; if (!m_pCod5Api->Cod5Activate(0, ActivationCode)) { m_pMsgMgr->PushErrorCodeF("Cod5Activate failed"); m_pMsgMgr->Show(TRUE); return FALSE; } if (!m_pCod5Api->Cod5Setup()) { m_pMsgMgr->PushErrorCodeF("Cod5Setup failed"); m_pMsgMgr->Show(TRUE); return FALSE; } for (ULONG i=0; iUpdateMediaInfo(m_uServerIndex+i, &m_MediaSettings[i], m_ServerIP); if (m_pMgrNVE->GetCurDlg()) { m_pMgrNVE->GetCurDlgPtr()->UpdateSetting(); } } if (!m_pCod5Api->Cod5GetEventHandle(CMN5_DT_COD_EX, &m_hCodEvent)) { m_pMsgMgr->PushErrorCodeF("Cod5GetEventHandle(CMN5_DT_COD_EX) failed"); m_pMsgMgr->Show(TRUE); return FALSE; } if (!m_pNet5Api->Net5GetEventHandle(CMN5_DT_NET_EX, &m_hNetEvent)) { m_pMsgMgr->PushErrorCodeF("Net5GetEventHandle(CMN5_DT_NET_EX) failed"); m_pMsgMgr->Show(TRUE); return FALSE; } if (!m_pCod5Api->Cod5GetEventHandle(CMN5_DT_SENSOR, &m_hSensorEvent)) { m_pMsgMgr->PushErrorCodeF("Cod5GetEventHandle(CMN5_DT_SENSOR) failed"); m_pMsgMgr->Show(TRUE); return FALSE; } if (!m_pCod5Api->Cod5GetEventHandle(CMN5_DT_VSTATUS, &m_hVStatusEvent)) { m_pMsgMgr->PushErrorCodeF("Cod5GetEventHandle(CMN5_DT_VSTATUS) failed"); m_pMsgMgr->Show(TRUE); return FALSE; } m_ProcUserData.SetCodEvent(m_hCodEvent); m_ProcUserData.SetNetEvent(m_hNetEvent); m_ProcUserData.SetSensorEvent(m_hSensorEvent); m_ProcUserData.SetVStatusEvent(m_hVStatusEvent); m_bSetupSuccess[0] = TRUE; return TRUE; } BOOL CConnectionManager::RunProc() { if (!m_bCapture) { for (ULONG i=0; iUpdateMediaInfo(m_uServerIndex+i, &m_MediaSettings[i], m_ServerIP); } } if (!m_ProcUserData.StartEventThread()) { TRACE("Cannot start event thread\n"); return FALSE; } if (!m_pCod5Api->Cod5Run()) { m_pMsgMgr->PushErrorCodeF("Cod5Run failed"); m_pMsgMgr->Show(TRUE); return FALSE; } return TRUE; } DWORD WINAPI CConnectionManager::ThreadSetupProcStub(LPVOID lpParameter) { THREAD_PARAM_SET *pParamSet = (THREAD_PARAM_SET*)lpParameter; CConnectionManager *pConnMgr = (CConnectionManager*)pParamSet->pParam3; return static_cast(pConnMgr)->ThreadSetupProc(lpParameter); } DWORD WINAPI CConnectionManager::ThreadSetupProc(LPVOID lpParameter) { TRACE("CConnectionManager::ThreadSetupProc started\n"); THREAD_PARAM_SET *pParamSet = (THREAD_PARAM_SET*)lpParameter; CUserThread *pUserThread; CConnectionManager *pConnMgr; ULONG uChannel; do { pUserThread = (CUserThread*)pParamSet->pParam1; if (!pUserThread) { TRACE("CConnectionManager::ThreadSetupProc: get user thread failed\n"); break; } uChannel = *(ULONG*)pParamSet->pParam2; m_bSetupWait[uChannel] = TRUE; m_bSetupSuccess[uChannel] = TRUE; pConnMgr = (CConnectionManager*)pParamSet->pParam3; if (!pConnMgr) { TRACE("CConnectionManager::ThreadSetupProc: get connection manager failed\n"); break; } if (!SetupProc()) { break; } pUserThread->ReleaseHandle(); m_bSetupWait[uChannel] = FALSE; TRACE("CConnectionManager::ThreadSetupProc stoped\n"); return 0; } while (0); TRACE("CConnectionManager::ThreadSetupProc failed\n"); m_bSetupSuccess[uChannel] = FALSE; ULONG uProcessState; if (m_pCod5Api->Cod5QueryInfo(CMN5_QIC_GET_PROCESS_STATE, NULL, &uProcessState)) { if (uProcessState == CMN5_PS_SETUP) { m_pCod5Api->Cod5Endup(); } } pUserThread->ReleaseHandle(); return 0; } DWORD WINAPI CConnectionManager::ThreadRunProcStub(LPVOID lpParameter) { THREAD_PARAM_SET *pParamSet = (THREAD_PARAM_SET*)lpParameter; CConnectionManager *pConnMgr = (CConnectionManager*)pParamSet->pParam3; return static_cast(pConnMgr)->ThreadRunProc(lpParameter); } DWORD WINAPI CConnectionManager::ThreadRunProc(LPVOID lpParameter) { TRACE("CConnectionManager::ThreadRunProc started\n"); THREAD_PARAM_SET *pParamSet = (THREAD_PARAM_SET*)lpParameter; CUserThread *pUserThread; CConnectionManager *pConnMgr; do { pUserThread = (CUserThread*)pParamSet->pParam1; if (!pUserThread) { TRACE("CConnectionManager::ThreadRunProc: get user thread failed\n"); break; } ULONG uChannel = *(ULONG*)pParamSet->pParam2; while (m_bSetupWait[uChannel] && m_bSetupSuccess[uChannel]) { Sleep(10); } if (!m_bSetupSuccess[uChannel]) { break; } pConnMgr = (CConnectionManager*)pParamSet->pParam3; if (!pConnMgr) { TRACE("CConnectionManager::ThreadRunProc: get connection manager failed\n"); break; } if (!RunProc()) { break; } pUserThread->ReleaseHandle(); TRACE("CConnectionManager::ThreadRunProc stoped\n"); return 0; } while(0); TRACE("CConnectionManager::ThreadRunProc stoped\n"); ULONG uProcessState; if (m_pCod5Api->Cod5QueryInfo(CMN5_QIC_GET_PROCESS_STATE, NULL, &uProcessState)) { switch(uProcessState) { case CMN5_PS_RUN: m_pCod5Api->Cod5Stop(); m_pCod5Api->Cod5Endup(); break; case CMN5_PS_SETUP: m_pCod5Api->Cod5Endup(); break; } } pUserThread->ReleaseHandle(); return 0; } DWORD WINAPI CConnectionManager::ThreadReconnectProcStub(LPVOID lpParameter) { THREAD_PARAM_SET *pParamSet = (THREAD_PARAM_SET*)lpParameter; CConnectionManager *pConnMgr = (CConnectionManager*)pParamSet->pParam2; return static_cast(pConnMgr)->ThreadReconnectProc(lpParameter); } DWORD WINAPI CConnectionManager::ThreadReconnectProc(LPVOID lpParameter) { if (m_bReconnecting) { return 0; } m_bReconnecting = TRUE; BOOL bSuccess = FALSE; m_pMsgMgr->PushErrorCodeF("Reconnect to server[%s]", m_ServerIP); m_pMsgMgr->Show(TRUE); while (m_bReconnect) { ProcessStop(); ProcessEndup(); m_pNet5Api->Net5Logout(); m_pNet5Api->Net5Disconnect(); m_uProcessState = CMN5_PS_INIT; Sleep(1000); TRACE("Reconnect Process[Connect]\n"); if (!m_pNet5Api->Net5ConnectEx(m_ServerIP, m_uProtocol, 5)) { continue; } TRACE("Reconnect Process[Login]\n"); if (!m_pNet5Api->Net5Login(m_szUserID, m_szUserPW)) { continue; } TRACE("Reconnect Process[Setup]\n"); m_uProcessState = CMN5_PS_SETUP; if (!SetupProc()) { continue; } TRACE("Reconnect Process[Run]\n"); m_uProcessState = CMN5_PS_RUN; if (!RunProc()) { continue; } bSuccess = TRUE; break; } if (!bSuccess) { ProcessStop(); ProcessEndup(); m_pNet5Api->Net5Logout(); m_pNet5Api->Net5Disconnect(); m_pMsgMgr->PushErrorCodeF("Cannot reconnect[%s]", m_ServerIP); m_pMsgMgr->Show(TRUE); } else { m_pMsgMgr->PushErrorCodeF("Reconnected[%s]", m_ServerIP); m_pMsgMgr->Show(TRUE); } m_ReconnectThread.ReleaseHandle(); m_bReconnecting = FALSE; return 0; } void CConnectionManager::Reconnect() { m_bReconnect = TRUE; m_ReconnectThread.StartThread(ThreadReconnectProcStub, this, 0, 0); } BOOL CConnectionManager::GetMediaInfo(ULONG uChannel) { if (!GetProperties(uChannel)) { return FALSE; } if (!GetAdjusts(uChannel)) { return FALSE; } return TRUE; } BOOL CConnectionManager::GetProperties(ULONG uChannel) { CMN5_MULTI_COMMAND Cmds[NVE_MAX_MULTI_CMD_COUNT]; ULONG m_uCmdIndex = 0; ULONG i; Cmds[m_uCmdIndex++].uCommand = COD5_CPC_VIDEO_FORMAT; Cmds[m_uCmdIndex++].uCommand = COD5_CPC_VIDEO_IMAGE_SIZE; Cmds[m_uCmdIndex++].uCommand = COD5_CPC_SKIP_FRAME; Cmds[m_uCmdIndex++].uCommand = COD5_CPC_BITRATE; Cmds[m_uCmdIndex++].uCommand = COD5_CPC_GOP_SIZE; Cmds[m_uCmdIndex++].uCommand = COD5_CPC_STREAM_TYPE; Cmds[m_uCmdIndex++].uCommand = COD5_CPC_AUDIO_ATTR; Cmds[m_uCmdIndex++].uCommand = COD5_CPC_CODEC_TYPE; Cmds[m_uCmdIndex++].uCommand = COD5_CPC_DENOISE_FILTER; for (i=0; iCod5GetMultiCodecProperties(m_uCmdIndex, Cmds)) { m_pMsgMgr->PushErrorCodeF("Cod5GetMultiCodecProperties failed"); m_pMsgMgr->Show(TRUE); return FALSE; } for (i=0; iPushErrorCodeF("Cod5GetMultiCodecProperties failed. cmd[0x%08x]", Cmds[i].uCommand); m_pMsgMgr->Show(TRUE); return FALSE; } } for (ULONG j=0; jCod5GetCodecProperty(0, 0, COD5_CPC_MD_PROPERTY, (ULONG*)&MDProp, 0, 0, 0), "Cannot get MD property"); BYTE *pMDInfo = new BYTE[MDProp.uInfoSize]; if (!m_pCod5Api->Cod5GetCodecProperty(0, 0, COD5_CPC_MD_INFO, (ULONG*)pMDInfo, 0, 0, 0)) { delete[] pMDInfo; return FALSE; } ULONG uIndex = 0; for (i=0; iuAreaCount; j++) { ULONG uType = *(ULONG*)(pMDInfo + uIndex); uIndex += sizeof(ULONG); ULONG uSize = *(ULONG*)(pMDInfo + uIndex); uIndex -= sizeof(ULONG); if (uType == COD5_MDT_RECT) { COD5_MD_AREA_RECT *pRect = (COD5_MD_AREA_RECT*)(pMDInfo + uIndex); CROP_BY_MACROBLOCK(pRect->uX, FALSE); CROP_BY_MACROBLOCK(pRect->uY, FALSE); CROP_BY_MACROBLOCK(pRect->uWidth, TRUE); CROP_BY_MACROBLOCK(pRect->uHeight, TRUE); CopyMemory(&m_MDInfo[i].Rect[pRect->uRectID], pRect, uSize); m_MDInfo[i].bRect[pRect->uRectID] = TRUE; } uIndex += uSize; } } delete[] pMDInfo; return TRUE; } BOOL CConnectionManager::GetAdjusts(ULONG uChannel) { CMN5_MULTI_COMMAND Cmds[NVE_MAX_MULTI_CMD_COUNT]; ULONG m_uCmdIndex = 0; Cmds[m_uCmdIndex++].uCommand = COD5_CAC_BRIGHTNESS; Cmds[m_uCmdIndex++].uCommand = COD5_CAC_CONTRAST; Cmds[m_uCmdIndex++].uCommand = COD5_CAC_SATURATION_U; Cmds[m_uCmdIndex++].uCommand = COD5_CAC_SATURATION_V; Cmds[m_uCmdIndex++].uCommand = COD5_CAC_HUE; Cmds[m_uCmdIndex++].uCommand = COD5_CAC_AUDIO_GAIN; Cmds[m_uCmdIndex++].uCommand = COD5_CAC_SHARPNESS; Cmds[m_uCmdIndex++].uCommand = COD5_CAC_STREAM_ENABLE; for (ULONG i=0; iCod5GetMultiCodecAdjusts(m_uCmdIndex, Cmds)) { m_pMsgMgr->PushErrorCodeF("Cod5GetMultiCodecAdjusts failed"); m_pMsgMgr->Show(TRUE); return FALSE; } for (i=0; iPushErrorCodeF("Cod5GetMultiCodecAdjusts failed. cmd[0x%08x]", Cmds[i].uCommand); m_pMsgMgr->Show(TRUE); } } for (ULONG j=0; jIsRestart()) { m_pCod5Api->Cod5Stop(); m_ProcUserData.StopEventThread(); } pDlg->SaveSetting(); if (pDlg->IsRestart()) { for (ULONG i=0; iUpdateMediaInfo(m_uServerIndex+i, &m_MediaSettings[i], m_ServerIP); } if (!m_ProcUserData.StartEventThread()) { TRACE("Cannot start event thread\n"); return FALSE; } if (!m_pCod5Api->Cod5Run()) { m_pMsgMgr->PushErrorCodeF("Cod5Run failed"); m_pMsgMgr->Show(TRUE); return FALSE; } } return TRUE; } BOOL ParseRTSPResponse(char *pszResponse, NVE_RTSP_VALUE *pValue, ULONG uNum) { // cÄÚµå·Î response¸¦ Á¤È®ÇÏ°Ô ºÐ¼®ÇÏ·Á¸é º¹ÀâÇϹǷΠÀÏ´Ü ´Ü¼øÇÏ°Ô ¸¸µç´Ù. BOOL bSet = FALSE; ULONG uIndex = 0; ZeroMemory(pValue, sizeof(NVE_RTSP_VALUE)*uNum); char *pszStr = strstr(pszResponse, "GET"); if (!pszStr) { pszStr = strstr(pszResponse, "SET"); if (!pszStr) { TRACE("Cannot find GET/SET\n"); return FALSE; } bSet = TRUE; } char *pszToken = strtok(pszStr, " "); pszToken = strtok(NULL, " "); char szValueSet[NVE_MAX_RTSP_VALUE][NVE_MAX_STR_LENGTH]; while (pszToken) { pszToken = strtok(NULL, ", "); if (!pszToken) { break; } safe_strcpy(szValueSet[uIndex], pszToken); uIndex++; } uIndex = 0; do { pszToken = strtok(szValueSet[uIndex], "="); if (!pszToken) { break; } safe_strncpy(pValue[uIndex].szName, pszToken, strlen(pszToken)-1); pszToken = strtok(NULL, "="); if (!pszToken) { break; } ULONG uTail = 0; char *pEndReq = strstr(pszToken, "\r\n\r\n"); if (pEndReq) { uTail += 4; } if (pszToken[0] == '\"') { safe_strncpy(pValue[uIndex].pValue, pszToken+1, strlen(pszToken)-1-uTail); } else { safe_strncpy(pValue[uIndex].pValue, pszToken, strlen(pszToken)+1-uTail); } uIndex++; } while(pszToken); return TRUE; } BOOL FindRTSPValue(NVE_RTSP_VALUE *pRtspValue, char *pszName, void *pValue, ULONG uType) { for (ULONG i=0; i