#include "mod_recorder.h" #ifdef RVC_OS_WIN #include "stdafx.h" #else #include #include #include #include #endif // RVC_OS_WIN #include "Event.h" #include "y2k_time.h" #include #include "filecryption.h" #include "mod_facetracking/sysvar.h" #include "mod_interactivecontrol/Event.h" #include "mod_mediacontroller/Event.h" #include "mod_sipphone/Event.h" using namespace Recorder; #ifndef RVC_MAX_VIDEO_NAME_LEN #define RVC_MAX_VIDEO_NAME_LEN 256 #endif #ifndef RVC_FILEENC_STR #define RVC_FILEENC_STR "enc_" #endif #ifndef MAX_LOG_LEN #define MAX_LOG_LEN 512 #endif #ifndef RVC_TRANSATCION_RECORD_SUFFIX #define RVC_TRANSATCION_RECORD_SUFFIX "B_" #endif // !RVC_TRANSATCION_RECORD_SUFFIX #ifndef RVC_ENCRYPT_TRANSATCION_RECORD_SUFFIX #define RVC_ENCRYPT_TRANSATCION_RECORD_SUFFIX "enc_B_" #endif // !RVC_ENCRYPT_TRANSATCION_RECORD_SUFFIX #ifndef RVC_MIN_RECORD_FILESIZE #define RVC_MIN_RECORD_FILESIZE 1024 #endif static unsigned long GetFileSize(const char* pfilename) { #ifdef RVC_OS_WIN unsigned long usize = 0; if (NULL == pfilename) { return usize; } FILE* pFile = fopen(pfilename, "rb"); if (pFile) { fseek(pFile, 0, SEEK_END); usize = ftell(pFile); fclose(pFile); } return usize; #else struct stat statbuf; if (0 == stat(pfilename, &statbuf)) { return statbuf.st_size; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("errno info is %s.", strerror(errno)); return 0; } #endif } static const char* GetFileName(const char* pfilename) { if (NULL == pfilename) { return NULL; } return strstr(pfilename, RVC_TRANSATCION_RECORD_SUFFIX); } static void LogRecordFileInfo(const char* pszMessage) { unsigned long ufilesize = GetFileSize(pszMessage); char strhash[MAX_PATH] = { 0 }; get_file_sm3digest(strhash, MAX_PATH, pszMessage); LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_VIDEO_INFO, CSimpleStringA::Format("%s file size is %u byte,sm3 digest is %s.", pszMessage, ufilesize, strhash).GetData()); } static void rvcDbg(filecrypt_loglevel elevel, const char* fmt, ...) { LOG_LEVEL_E eloglevel = LOG_LEVEL_DEBUG; if (FILECRYPT_LOG_INFO <= elevel) { eloglevel = LOG_LEVEL_INFO; } va_list arg; va_start(arg, fmt); int n = vsnprintf(NULL, 0, fmt, arg); if (n >= MAX_LOG_LEN) { char* buf = (char*)malloc((size_t)(n + 1)); vsnprintf(buf, n + 1, fmt, arg); DbgWithLink(eloglevel, LOG_TYPE_SYSTEM)("%s", buf); free(buf); } else{ char strlog[MAX_LOG_LEN] = {0}; vsnprintf(strlog, MAX_LOG_LEN, fmt, arg); DbgWithLink(eloglevel, LOG_TYPE_SYSTEM)("%s", strlog); } va_end(arg); } static bool rvcMoveFile(const char* strSrcFile, const char* strDstFile) { bool bRet = false; if (NULL == strSrcFile || NULL == strDstFile) { return bRet; } #ifdef RVC_OS_WIN bRet = MoveFile(strSrcFile, strDstFile); #else if (0 == rename(strSrcFile, strDstFile)) { bRet = true; } #endif // RVC_OS_WIN return bRet; } static bool RvcDeleteFile(const char* strSrcFile) { bool bRet = false; if (NULL == strSrcFile) { return bRet; } #ifdef RVC_OS_WIN bRet = DeleteFile(strSrcFile); #else if (0 == remove(strSrcFile)) { bRet = true; } #endif // RVC_OS_WIN return bRet; } void RecordServiceSession::Handle_StartTransactionRecord(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); if (m_pEntity->GetStartFlag()) { m_pEntity->StopRecord(); } m_pEntity->SetRecordSessionID(ctx->Req.VideoName.GetData()); m_pEntity->StartRecord(CSimpleStringA::Format("%s%s", RVC_TRANSATCION_RECORD_SUFFIX, ctx->Req.VideoName.GetData()).GetData()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start video record %s.", ctx->Req.VideoName.GetData()); ctx->Answer(Error_Succeed); } void RecordServiceSession::Handle_StopTransactionRecord(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->StopRecord(); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop video record %s.", ctx->Req.VideoName.GetData()); ctx->Answer(Error_Succeed); } void CRecorderEntity::OnPreStart(CAutoArray strArgs,CSmartPointer pTransactionContext) { ErrorCodeEnum Error = __OnStart(Error_Succeed); pTransactionContext->SendAnswer(Error); } void CRecorderEntity::OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer pTransactionContext) { ErrorCodeEnum Error = __OnClose(Error_Succeed); pTransactionContext->SendAnswer(Error); } ErrorCodeEnum CRecorderEntity::__OnStart(ErrorCodeEnum preOperationError) { ErrorCodeEnum Error = Error_Succeed; m_eDeviceType = RvcGetDeviceType(); if (preOperationError != Error_Succeed) { return preOperationError; } m_iActiveCamera = CAMERA_TYPE_ENV; m_iCameraState = 'N'; InitRecorder(); int i = 0; m_arrListener.Init(8); GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, EVENT_MOD_PAUSE_RECORD, NULL, false); GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, EVENT_MOD_CONTINUE_RECORD, NULL, false); GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_RECORDER_SECTION_FINISHED, NULL, false); GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_RECORDER_WHOLE_FINISHED, NULL, false); GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_START_BUSINESSRECORD_FAILED, NULL, false); GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_MEDIACONTROLLER_CAMERA_STARTED, NULL, false); GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_MEDIACONTROLLER_CAMERA_STOPPED, NULL, false); GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_RETURNMENU, NULL, false); GetFunction()->RegistSysVarEvent(SYSVAR_ACTIVETRACKINGCAMERA,this); GetFunction()->RegistSysVarEvent(SYSVAR_CAMERASTATE,this); CSimpleStringA strValue; GetFunction()->GetSysVar(SYSVAR_CAMERASTATE, strValue); m_iCameraState = strValue[0]; if (strValue[0] == 'E'){ m_iActiveCamera = CAMERA_TYPE_OPT; if (eStand1SPlusType == m_eDeviceType){ m_iActiveCamera = CAMERA_TYPE_ERROR; } } else if (strValue[0] == 'O'){ m_iActiveCamera = CAMERA_TYPE_ENV; } else if(strValue[0] == 'B'){ m_iActiveCamera = CAMERA_TYPE_ERROR; } else if (strValue[0] == 'N'){ m_iActiveCamera = CAMERA_TYPE_ENV; } Error = GetFunction()->GetPath("Temp", m_TempDir); if (Error != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get global record temp path failed!"); } if (m_TempDir.GetLength() > 0 && m_TempDir[m_TempDir.GetLength()-1] != SPLIT_SLASH) { m_TempDir += SPLIT_SLASH_STR; } Error = GetFunction()->GetPath("UploadVideo", m_RecordSaveDir); if (Error != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get global record save path failed!"); } if (m_RecordSaveDir.GetLength() > 0 && m_RecordSaveDir[m_RecordSaveDir.GetLength()-1] != SPLIT_SLASH) { m_RecordSaveDir += SPLIT_SLASH_STR; } return Error; } void CRecorderEntity::OnStarted() { CSystemStaticInfo si; ErrorCodeEnum Error = GetFunction()->GetSystemStaticInfo(si); if (Error == Error_Succeed) { m_strAppVersion = si.InstallVersion.ToString(); m_strTerminalId = si.strTerminalID; } LoadEntityConfig(); //DeleteExceptionLogFiles(); SaveExceptionRecordVideos(); if (m_vRecordList.size() > 0) { HandleExceptionRecordVideos(); PostVideoRecordInfos(); } } bool CRecorderEntity::InitRecorder() { bool bRet = false; if (eStand1SPlusType == m_eDeviceType) { m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE, NULL); } else { m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE, REC_COMMON_VIDEO_OPT_SHM_RTP_QUEUE); } return bRet; } bool CRecorderEntity::ReleaseRecorder() { if (m_pRecorder) { delete m_pRecorder; m_pRecorder = NULL; } return true; } ErrorCodeEnum CRecorderEntity::__OnClose(ErrorCodeEnum preOperationError) { if (preOperationError != Error_Succeed) { return preOperationError; } for (int i = 0; i < m_arrListener.GetCount(); ++i) { GetFunction()->UnsubscribeLog(m_arrListener[i]); } GetFunction()->UnregistSysVarEvent(SYSVAR_ACTIVETRACKINGCAMERA); GetFunction()->UnregistSysVarEvent(SYSVAR_CAMERASTATE); StopRecord(); return Error_Succeed; } CServerSessionBase* CRecorderEntity::OnNewSession(const char* pszRemoteEntityName, const char* pszClass) { return new RecordServiceSession(this); } void CRecorderEntity::Debug(record_loglevel elevel, const char *fmt, ...) { if (RECORD_LOG_INFO <= elevel) { va_list arg; va_start(arg, fmt); int n = vsnprintf(NULL, 0, fmt, arg); if (n >= MAX_LOG_LEN) { char* buf = (char*)malloc((size_t)(n + 1)); vsnprintf(buf, n + 1, fmt, arg); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf); free(buf); } else{ char strlog[MAX_LOG_LEN] = {0}; vsnprintf(strlog, MAX_LOG_LEN, fmt, arg); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog); } va_end(arg); } } void CRecorderEntity::vDebug(record_loglevel elevel, const char* str, va_list list) { if (RECORD_LOG_INFO <= elevel) { int n = vsnprintf(NULL, 0, str, list); if (n >= MAX_LOG_LEN) { char* buf = (char*)malloc((size_t)(n + 1)); vsnprintf(buf, n + 1, str, list); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf); free(buf); } else { char strlog[MAX_LOG_LEN] = { 0 }; vsnprintf(strlog, MAX_LOG_LEN, str, list); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog); } } } int CRecorderEntity::GetRecordCamera() { return m_iActiveCamera; } ErrorCodeEnum CRecorderEntity::LoadEntityConfig() { ErrorCodeEnum Error = Error_Succeed; int iTimeOut = RVC_HTTPTIMEOUT; int iStopEncflag = 0; CSimpleStringA strHttpServerAddr(""); CSmartPointer spConfig; CSmartPointer spFunction = GetFunction(); if (spFunction->OpenConfig(Config_CenterSetting, spConfig) == Error_Succeed) { spConfig->ReadConfigValue("Recorder", "http_video_record_addr", strHttpServerAddr); spConfig->ReadConfigValueInt("Recorder", "http_timeout", iTimeOut); spConfig->ReadConfigValueInt("Recorder", "stopencflag", iStopEncflag); } else { Error = Error_Failed; } if (strHttpServerAddr.GetLength() > 0) { m_strHttpServerAddr = strHttpServerAddr; } if (iTimeOut > 0 && iTimeOut < 20 * RVC_HTTPTIMEOUT) { m_iHttpTimeOut = iTimeOut; } if (1 == iStopEncflag) { m_bEncFlag = false; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("m_bEncFlag is %s.", m_bEncFlag ? "true":"false"); return Error; } ErrorCodeEnum CRecorderEntity::PostVideoRecordInfos() { ErrorCodeEnum Error = Error_Failed; char strtimenow[MAX_PATH] = { 0 }; y2k_time_t nowtime = y2k_time_now(); y2k_to_string(nowtime, strtimenow, MAX_PATH); video_record_info_t video_params; video_params.strServerURL = m_strHttpServerAddr; video_params.strAPI = m_strHttpServerAPI; video_params.strAppVersion = m_strAppVersion; video_params.strRecordEndTime = strtimenow; video_params.strTerminalNo = m_strTerminalId; video_params.iBusinessStatus = (int)m_eBusinessStatus; if (eFailed == m_eBusinessStatus) { if (m_vRecordList.size() > 0) { video_params.iBusinessStatus = eInterrupt; } } video_params.strRecordID = m_strRecordName; for (vector::iterator it = m_vRecordList.begin(); it < m_vRecordList.end(); ++it) { video_params.vRecordList.push_back(*it); } unsigned int uposttime = 0; CSimpleStringA strErrorMsg(""); if (0 == post_video_recordinfo_list(uposttime, strErrorMsg, &video_params, m_iHttpTimeOut, false)) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_POST_RECORDINFO_COST_TIME, CSimpleStringA::Format("post video record infos cost time is %ums.", uposttime).GetData()); Error = Error_Succeed; } else { LogWarn(Severity_Middle, Error_Exception, LOG_EVT_POST_RECORDINFO_FAILED, strErrorMsg.GetData()); } m_vRecordList.clear(); return Error; } ErrorCodeEnum CRecorderEntity::HandleExceptionRecordVideos() { ErrorCodeEnum Error = Error_Failed; const char* videofilename = m_vRecordList[0].file_path.c_str(); if (NULL == videofilename) { return Error; } char strSession[RVC_MAX_VIDEO_NAME_LEN] = { 0 }; int iSeriesNum = -1; char strFormat[RVC_MAX_VIDEO_NAME_LEN] = { 0 }; if (-1 == GetRecordVideoInfo(videofilename, strSession, RVC_MAX_VIDEO_NAME_LEN, &iSeriesNum, strFormat, RVC_MAX_VIDEO_NAME_LEN)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[%s] get record video info failed.", videofilename); return Error; } SetRecordSessionID(strSession + strlen(RVC_TRANSATCION_RECORD_SUFFIX)); Error = Error_Succeed; return Error; } ErrorCodeEnum CRecorderEntity::AddToVideoRecordList(const char* videofilename) { ErrorCodeEnum Error = Error_Failed; if (NULL == videofilename) { return Error; } record_item_t* item = new record_item_t(); item->file_path = videofilename; item->file_length = (int)GetFileSize(videofilename); const char* strfilename = GetFileName(videofilename); if (strfilename) { item->file_name = strfilename; } m_vRecordList.push_back(*item); Error = Error_Succeed; return Error; } void CRecorderEntity::OnRecordFailed(eRvcRecordFailedCase eCase, const char *pszMessage, bool bRecordDevFault) { m_eBusinessStatus = eFailed; if (!bRecordDevFault){ LogEvent(Severity_Middle,LOG_EVT_RECORDFAILED,"0"); LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORDING_FAILED, CSimpleStringA::Format("%s 本地录音录像失败,已停止!", pszMessage ? pszMessage : " ").GetData()); } else{ LogEvent(Severity_Middle,LOG_EVT_RECORDFAILED,"1"); LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORDING_FAILED, CSimpleStringA::Format("%s 本地录音录像设备故障,尝试恢复中(预计10s内),请稍等", pszMessage ? pszMessage : " ").GetData()); } } void CRecorderEntity::OnRecordEntityExcption() { LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORD_ENTITY_EXCEPTION, "OnRecordEntityExcption!"); } void CRecorderEntity::OnRecordFinished() { } int CRecorderEntity:: GetCameraState() { return m_iCameraState; } void CRecorderEntity::OnASectionFinished(const char *pszMessage, int iSerialNum, bool bfinished) { if (false == bfinished){ LogEvent(Severity_Middle, LOG_EVT_RECORDER_SECTION_FINISHED, pszMessage); } else{ LogEvent(Severity_Middle, LOG_EVT_RECORDER_WHOLE_FINISHED, pszMessage); } } void CRecorderEntity::OnLog(const CAutoArray &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel, const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID, const CAutoArray &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage, const linkContext& pLinkInfo) { switch (dwUserCode) { case EVENT_MOD_PAUSE_RECORD: m_pRecorder->PauseRecord(); if (m_bStarted) { m_pRecorder->CloseVideoFile(); } break; case EVENT_MOD_CONTINUE_RECORD: m_pRecorder->ContinueRecord(); break; case LOG_EVT_RECORDER_SECTION_FINISHED: { unsigned long uSize = GetFileSize(pszMessage); if (RVC_MIN_RECORD_FILESIZE < uSize) { if (m_bEncFlag) { HandleEncryptVideoRecord(pszMessage); } HandleSaveVideoRecord(pszMessage); } else { LogWarn(Severity_Low, Error_Debug, LOG_EVT_INVALID_RECORD_FILE, CSimpleStringA::Format("invalid record file %s, delelte it.", pszMessage).GetData()); RvcDeleteFile(pszMessage); } } break; case LOG_EVT_RECORDER_WHOLE_FINISHED: { unsigned long uSize = GetFileSize(pszMessage); if (RVC_MIN_RECORD_FILESIZE < uSize) { if (m_bEncFlag) { HandleEncryptVideoRecord(pszMessage); } HandleFinishedVideoRecord(pszMessage); PostVideoRecordInfos(); } else { LogWarn(Severity_Low, Error_Debug, LOG_EVT_INVALID_RECORD_FILE, CSimpleStringA::Format("invalid record file %s, delelte it.", pszMessage).GetData()); RvcDeleteFile(pszMessage); } } break; case LOG_EVT_START_BUSINESSRECORD_FAILED: m_eBusinessStatus = eFailed; PostVideoRecordInfos(); break; case LOG_EVT_MEDIACONTROLLER_CAMERA_STARTED: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv LOG_EVT_MEDIACONTROLLER_CAMERA_STARTED event"); break; case LOG_EVT_MEDIACONTROLLER_CAMERA_STOPPED: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv LOG_EVT_MEDIACONTROLLER_CAMERA_STOPPED event"); break; case LOG_EVT_UI_RETURNMENU: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv LOG_EVT_UI_RETURNMENU event"); break; default: break; } } void CRecorderEntity::OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName) { if (_stricmp(pszKey, SYSVAR_CAMERASTATE) == 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("OnSysVarEvent Key = %s, Value = %s.", pszKey, pszValue); m_iCameraState = pszValue[0]; if (pszValue[0] == 'E'){ m_iActiveCamera = CAMERA_TYPE_OPT; } else if (pszValue[0] == 'O'){ m_iActiveCamera = CAMERA_TYPE_ENV; } else if(pszValue[0] == 'B'){ m_iActiveCamera = CAMERA_TYPE_ERROR; } else if (pszValue[0] == 'N'){ m_iActiveCamera = CAMERA_TYPE_ENV; } } else if (_stricmp(pszKey, SYSVAR_ACTIVETRACKINGCAMERA) == 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("OnSysVarEvent Key = %s, Value = %s.", pszKey, pszValue); if (m_iCameraState == 'N'){ if (pszValue[0] == 'E'){ m_iActiveCamera = CAMERA_TYPE_ENV; } else if (pszValue[0] == 'O'){ m_iActiveCamera = CAMERA_TYPE_OPT; } } } } void CRecorderEntity::OnSelfTest(EntityTestEnum eTestType,CSmartPointer pTransactionContext) { if (Test_ShakeHand == eTestType){ pTransactionContext->SendAnswer(Error_Succeed); } } void CRecorderEntity::StartRecord(const char *videofilename) { int fps = 5; Rvc_RecordAudioParam_t tAudioParams; tAudioParams.eRecordType = eSingleSide; tAudioParams.eOutPutType = eLowDefinition; tAudioParams.bIsNsOn = true; tAudioParams.iNsPolicy = 2; tAudioParams.iAudioOutBitRate = 8; tAudioParams.bIsTransOn = false; tAudioParams.iAudioChannels = 1; CSmartPointer Func = GetFunction(); CSimpleStringA strValue(""); Func->GetSysVar(SYSVAR_SOUNDCARDSTATE, strValue); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Sound Card State is %s.", strValue.GetData()); if ('N' == strValue[0] || 'P' == strValue[0]) { tAudioParams.bMuteAudioMode = false; } else { tAudioParams.bMuteAudioMode = true; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("handfree audio is error, tansaction record use mute audio mode."); } if (m_pRecorder->StartVideoRecord(fps, 75, eMP4, &tAudioParams, NULL, false, true, m_TempDir.GetData(), m_RecordSaveDir.GetLength(), videofilename, strlen(videofilename))) { m_bStarted = true; m_eBusinessStatus = eSuccess; } } void CRecorderEntity::StopRecord() { if (m_bStarted) { m_pRecorder->StopVideoRecord(); m_bStarted = false; } } void CRecorderEntity::SetRecordSessionID(const char* strRecordID) { if (NULL != strRecordID) { memset(m_strRecordName, 0 , MAX_PATH); snprintf(m_strRecordName, MAX_PATH, "%s", strRecordID); } } void CRecorderEntity::GetRecordSessionID(char* strRecordID, size_t uLen) { if (NULL != strRecordID) { snprintf(strRecordID, uLen, "%s", m_strRecordName); } } DeviceTypeEnum CRecorderEntity::RvcGetDeviceType() { DeviceTypeEnum eType = eStand2sType; CSmartPointer spFunction = GetFunction(); CSystemStaticInfo stStaticinfo; spFunction->GetSystemStaticInfo(stStaticinfo); if (_stricmp(stStaticinfo.strMachineType.GetData(), "RVC.Stand1SPlus") == 0) { eType = eStand1SPlusType; } else if (_stricmp(stStaticinfo.strMachineType.GetData(), "RVC.CardStore") == 0 || _stricmp(stStaticinfo.strMachineType.GetData(), "RVC.CardPrinter") == 0) { eType = eCardStore; } else { eType = eStand2sType; } if (eType >= 0 && eType < sizeof(Device_Type_Table) / sizeof(char*)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("device type is %s.", Device_Type_Table[eType]); } m_terminalNo = stStaticinfo.strTerminalID; return eType; } int CRecorderEntity::HandleFinishedVideoRecord(const char* videofilename) { int iRet = -1; if (NULL == videofilename){ return iRet; } char strSession[RVC_MAX_VIDEO_NAME_LEN] = {0}; int iSeriesNum = -1; char strFormat[RVC_MAX_VIDEO_NAME_LEN] = {0}; if (-1 == GetRecordVideoInfo(videofilename, strSession, RVC_MAX_VIDEO_NAME_LEN, &iSeriesNum, strFormat, RVC_MAX_VIDEO_NAME_LEN)){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[%s] get record video info failed.", videofilename); return iRet; } CSimpleStringA srcfile = CSimpleStringA::Format("%s%s_%d_end.%s", m_TempDir.GetData(), strSession, iSeriesNum, strFormat); CSimpleStringA dstfile = CSimpleStringA::Format("%s%s_%d_end.%s", m_RecordSaveDir.GetData(), strSession, iSeriesNum, strFormat); bool bRet = false; if (ExistsFile(srcfile.GetData())){ LogRecordFileInfo(srcfile.GetData()); bRet = rvcMoveFile(srcfile.GetData(), dstfile.GetData()); if(!bRet) { #ifdef RVC_OS_WIN LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("Error Code %u while move %s ", GetLastError(), srcfile.GetData()).GetData()); #else LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("%s(%d) while move %s ", strerror(errno), errno, srcfile.GetData()).GetData()); #endif // RVC_OS_WIN } else { AddToVideoRecordList(dstfile.GetData()); } } srcfile = CSimpleStringA::Format("%s%s_%d.%s",m_TempDir.GetData(), strSession, iSeriesNum-1, strFormat); dstfile = CSimpleStringA::Format("%s%s_%d.%s",m_RecordSaveDir.GetData(), strSession, iSeriesNum-1, strFormat); if (ExistsFile(srcfile.GetData())){ bRet = rvcMoveFile(srcfile.GetData(), dstfile.GetData()); if(!bRet) { #ifdef RVC_OS_WIN LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("Error Code %u while move %s ", GetLastError(), srcfile.GetData()).GetData()); #else LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("%s(%d) while move %s ", strerror(errno), errno, srcfile.GetData()).GetData()); #endif // RVC_OS_WIN } else { AddToVideoRecordList(dstfile.GetData()); } } iRet = 0; return iRet; } int CRecorderEntity::HandleEncryptVideoRecord(const char* videofilename) { int iRet = -1; if (NULL == videofilename){ return iRet; } if (!ExistsFile(videofilename)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("File %s is not exist.", videofilename); return iRet; } filecryption_callback_t cb = {0}; cb.dbg = &rvcDbg; char strOutFile[MAX_PATH] = {0}; int iresult = encryption_file(strOutFile, MAX_PATH, videofilename, &cb, eVerB); if (0 != iresult){ LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORDER_ENCRYPT_FAILED, CSimpleStringA::Format("encryption file %s failed, delete out temp file %s!", videofilename, strOutFile).GetData()); if (ExistsFile(strOutFile)) { if (!RvcDeleteFile(strOutFile)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("DeleteFile file %s failed!", strOutFile); } } return iRet; } bool bRet = RvcDeleteFile(videofilename); if(!bRet) { #ifdef RVC_OS_WIN LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORDER_DELETE_FAILED, CSimpleStringA::Format("Error Code %lu while delete %s, delete out temp file[%s]!", GetLastError(), videofilename, strOutFile).GetData()); #else LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORDER_DELETE_FAILED, CSimpleStringA::Format("%s(%d) while delete %s, delete out temp file[%s]!", strerror(errno), errno, videofilename, strOutFile).GetData()); #endif // RVC_OS_WIN if (!RvcDeleteFile(strOutFile)){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("DeleteFile file %s failed!", strOutFile); } return iRet; } else{ if (rvcMoveFile(strOutFile, videofilename)){ DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("after encryption rename %s to %s Success!",strOutFile, videofilename); iRet = 0; } else{ #ifdef RVC_OS_WIN LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORDER_RENAME_FAILED, CSimpleStringA::Format("Error Code %lu while rename %s.", GetLastError(), strOutFile).GetData()); #else LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORDER_RENAME_FAILED, CSimpleStringA::Format("%s(%d) while rename %s.", strerror(errno), errno, strOutFile).GetData()); #endif // RVC_OS_WIN } } #if 0 char strdecFile[MAX_PATH] = { 0 }; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("begin decrypt file %s.", videofilename); iresult = decryption_file(strdecFile, MAX_PATH, videofilename, &cb, eVerB); if (0 == iresult) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("decrypt file %s -> %s success!", videofilename, strdecFile); } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("decrypt file %s -> %s failed!", videofilename, strdecFile); } #endif return iRet; } int CRecorderEntity::HandleSaveVideoRecord(const char* videofilename) { int iRet = -1; if (NULL == videofilename){ return iRet; } char strSession[RVC_MAX_VIDEO_NAME_LEN] = {0}; int iSeriesNum = -1; char strFormat[RVC_MAX_VIDEO_NAME_LEN] = {0}; if (-1 == GetRecordVideoInfo(videofilename, strSession, RVC_MAX_VIDEO_NAME_LEN, &iSeriesNum, strFormat, RVC_MAX_VIDEO_NAME_LEN)){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[%s] get record video info failed.", videofilename); return iRet; } CSimpleStringA srcfile = CSimpleStringA::Format("%s%s_%d.%s", m_TempDir.GetData(), strSession, iSeriesNum, strFormat); CSimpleStringA dstfile = CSimpleStringA::Format("%s%s_%d.%s", m_RecordSaveDir.GetData(), strSession, iSeriesNum, strFormat); if (ExistsFile(srcfile.GetData())) { LogRecordFileInfo(srcfile.GetData()); bool bRet = rvcMoveFile(srcfile.GetData(), dstfile.GetData()); if (!bRet) { #ifdef RVC_OS_WIN LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("Error Code %u while move %s ", GetLastError(), srcfile.GetData())); #else LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("%s(%d) while move %s ", strerror(errno), errno, srcfile.GetData())); #endif // RVC_OS_WIN } else { AddToVideoRecordList(dstfile.GetData()); } } iRet = 0; return iRet; } int CRecorderEntity::GetRecordVideoInfo(const char* videofilename, char* strSession, size_t uSessionLen, int* iSeriesNum, char* strFormat, size_t uFormatLen) { int iRet = -1; char strFileName[RVC_MAX_VIDEO_NAME_LEN] = {0}; size_t uLen = strlen(videofilename); if (uLen <= RVC_MAX_VIDEO_NAME_LEN){ const char *pIndex = strrchr(videofilename, SPLIT_SLASH); if (pIndex){ snprintf(strFileName, RVC_MAX_VIDEO_NAME_LEN, "%s", pIndex + 1); } } else{ return iRet; } int ioffset = 0; if (0 == memcmp(strFileName, RVC_TRANSATCION_RECORD_SUFFIX, strlen(RVC_TRANSATCION_RECORD_SUFFIX))) { ioffset = strlen(RVC_TRANSATCION_RECORD_SUFFIX); } char* pNum = strstr(strFileName+ioffset, "_"); if (pNum){ *pNum = 0; strcpy(strSession, strFileName); pNum++; } else{ return iRet; } char* pend = strstr(pNum, "_end"); if (pend){ *pend = 0; *iSeriesNum = atoi(pNum); pNum = pend + 1; } char* pFormat = strstr(pNum, "."); if (pFormat){ *pFormat = 0; pFormat++; strcpy(strFormat, pFormat); } else{ return iRet; } if (NULL == pend){ *iSeriesNum = atoi(pNum); } iRet = 0; return iRet; } int CRecorderEntity::SaveExceptionRecordVideos() { int iRet = -1; #ifdef RVC_OS_WIN WIN32_FIND_DATA FindFileData; HANDLE hFind; bool fFinished = false; char strVideoFormat[MAX_PATH] = { 0 }; char srcFilePath[MAX_PATH] = { 0 }; _snprintf(strVideoFormat, MAX_PATH, "%s", RECORD_MP4_SUFFIX); _snprintf(srcFilePath, MAX_PATH, "%s*.%s", m_TempDir.GetData(), strVideoFormat); hFind = FindFirstFile(srcFilePath, &FindFileData); if (INVALID_HANDLE_VALUE != hFind) { while (!fFinished){ if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes){ goto on_next; } if (0 == memcmp(FindFileData.cFileName, RVC_TRANSATCION_RECORD_SUFFIX, strlen(RVC_TRANSATCION_RECORD_SUFFIX)) || 0 == memcmp(FindFileData.cFileName, RVC_ENCRYPT_TRANSATCION_RECORD_SUFFIX, strlen(RVC_ENCRYPT_TRANSATCION_RECORD_SUFFIX))){ CSimpleStringA srcfile = CSimpleStringA::Format("%s%s",m_TempDir.GetData(), FindFileData.cFileName); unsigned long uSize = GetFileSize(srcfile.GetData()); if (RVC_MIN_RECORD_FILESIZE >= uSize) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_INVALID_RECORD_FILE, CSimpleStringA::Format("invalid record file %s, delelte it.", srcfile.GetData()).GetData()); RvcDeleteFile(srcfile.GetData()); goto on_next; } if (m_bEncFlag){ filecryption_callback_t cb = {0}; cb.dbg = &rvcDbg; if (false == is_file_encrypted(srcfile.GetData(), &cb)){ if (strstr(FindFileData.cFileName, RVC_FILEENC_STR)) { RvcDeleteFile(srcfile.GetData()); goto on_next; } if (is_file_completed(srcfile.GetData(), &cb)) { HandleEncryptVideoRecord(srcfile.GetData()); } } else{ char* pIndex = NULL; if (pIndex = strstr(FindFileData.cFileName, RVC_FILEENC_STR)){ char strname[MAX_PATH] = {0}; memcpy(strname, pIndex + strlen(RVC_FILEENC_STR), strlen(pIndex+strlen(RVC_FILEENC_STR))); CSimpleStringA tempsrcfile = CSimpleStringA::Format("%s%s", m_TempDir.GetData(), strname); if (rvcMoveFile(srcfile.GetData(),tempsrcfile.GetData())){ srcfile = tempsrcfile; memset(FindFileData.cFileName, 0, MAX_PATH); memcpy(FindFileData.cFileName, strname, strlen(strname)); } else{ LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_RENAME_FAILED, CSimpleStringA::Format("Error Code %lu while rename %s, delete it.", GetLastError(), srcfile.GetData()).GetData()); RvcDeleteFile(srcfile.GetData()); goto on_next; } } } } if (strstr(srcfile.GetData(), RVC_FILEENC_STR)) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_ABNORMAL_RECORD_FILE, CSimpleStringA::Format("abnormal file %s, delete it.", srcfile.GetData()).GetData()); RvcDeleteFile(srcfile.GetData()); goto on_next; } CSimpleStringA dstfile = CSimpleStringA::Format("%s%s",m_RecordSaveDir.GetData(), FindFileData.cFileName); bool bRet = rvcMoveFile(srcfile.GetData(), dstfile.GetData()); if(!bRet) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("Error Code %u while move %s -> %s", GetLastError(), srcfile.GetData(), dstfile.GetData()).GetData()); } else{ AddToVideoRecordList(dstfile.GetData()); iRet = 0; } } on_next: if (!FindNextFile(hFind, &FindFileData)){ if (GetLastError() == ERROR_NO_MORE_FILES){ fFinished = true; } else{ break; } } } FindClose(hFind); } #else struct dirent* ptr; DIR* dir = opendir(m_TempDir.GetData()); while ((ptr = readdir(dir)) != NULL) { if (ptr->d_type & DT_DIR) { continue; } if (0 == memcmp(ptr->d_name, RVC_TRANSATCION_RECORD_SUFFIX, strlen(RVC_TRANSATCION_RECORD_SUFFIX)) || 0 == memcmp(ptr->d_name, RVC_ENCRYPT_TRANSATCION_RECORD_SUFFIX, strlen(RVC_ENCRYPT_TRANSATCION_RECORD_SUFFIX))) { CSimpleStringA srcfile = CSimpleStringA::Format("%s%s", m_TempDir.GetData(), ptr->d_name); unsigned long uSize = GetFileSize(srcfile.GetData()); if (RVC_MIN_RECORD_FILESIZE >= uSize) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_INVALID_RECORD_FILE, CSimpleStringA::Format("invalid record file %s, delelte it.", srcfile.GetData()).GetData()); RvcDeleteFile(srcfile.GetData()); continue; } if (m_bEncFlag) { filecryption_callback_t cb = { 0 }; cb.dbg = &rvcDbg; if (false == is_file_encrypted(srcfile.GetData(), &cb)) { if (strstr(ptr->d_name, RVC_FILEENC_STR)) { RvcDeleteFile(srcfile.GetData()); continue; } if (is_file_completed(srcfile.GetData(), &cb)) { HandleEncryptVideoRecord(srcfile.GetData()); } } else { char* pIndex = NULL; if (pIndex = strstr(ptr->d_name, RVC_FILEENC_STR)) { char strname[MAX_PATH] = { 0 }; memcpy(strname, pIndex + strlen(RVC_FILEENC_STR), strlen(pIndex + strlen(RVC_FILEENC_STR))); CSimpleStringA tempsrcfile = CSimpleStringA::Format("%s%s", m_TempDir.GetData(), strname); if (rvcMoveFile(srcfile.GetData(), tempsrcfile.GetData())) { srcfile = tempsrcfile; memset(ptr->d_name, 0, MAX_PATH); memcpy(ptr->d_name, strname, strlen(strname)); } else { LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_RENAME_FAILED, CSimpleStringA::Format("%s(%d) while rename %s.", strerror(errno), errno, srcfile.GetData()).GetData()); RvcDeleteFile(srcfile.GetData()); continue; } } } } if (strstr(srcfile.GetData(), RVC_FILEENC_STR)) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_ABNORMAL_RECORD_FILE, CSimpleStringA::Format("abnormal file %s, delete it.", srcfile.GetData()).GetData()); RvcDeleteFile(srcfile.GetData()); continue; } CSimpleStringA dstfile = CSimpleStringA::Format("%s%s", m_RecordSaveDir.GetData(), ptr->d_name); bool bRet = rvcMoveFile(srcfile.GetData(), dstfile.GetData()); if (!bRet) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("Error Code %u while move %s -> %s", GetLastError(), srcfile.GetData(), dstfile.GetData()).GetData()); } else { AddToVideoRecordList(dstfile.GetData()); iRet = 0; } } } closedir(dir); #endif // RVC_OS_WIN return iRet; } SP_BEGIN_ENTITY_MAP() SP_ENTITY(CRecorderEntity) SP_END_ENTITY_MAP()