mod_SalesRecorder.cpp 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948
  1. #include "stdafx.h"
  2. #include "mod_SalesRecorder.h"
  3. #include "Event.h"
  4. #include "rvc_media_common.h"
  5. #include "fileutil.h"
  6. #include "array.h"
  7. #include <memutil.h>
  8. #include <algorithm>
  9. #include "y2k_time.h"
  10. #ifdef RVC_OS_WIN
  11. #include <Windows.h>
  12. #else
  13. #include <dirent.h>
  14. #include <sys/ioctl.h>
  15. #include <sys/stat.h>
  16. #include <sys/fcntl.h>
  17. #endif
  18. #include "mod_customeraware/Event.h"
  19. #include "mod_facetracking/sysvar.h"
  20. #include "mod_mediacontroller/Event.h"
  21. #include <assert.h>
  22. #include "EventCode.h"
  23. #include <string.h>
  24. #include "filecryption.h"
  25. #ifndef RVC_MIN_FILESIZE
  26. #define RVC_MIN_FILESIZE 10240
  27. #endif
  28. #ifndef MAX_LOG_LEN
  29. #define MAX_LOG_LEN 512
  30. #endif
  31. #define MAX_DISK_PERCENT 95 // 磁盘最大占用百分比
  32. static const char* record_failed_case_table[] = {
  33. "[RTA3L01] 启动录像失败,初始化失败",
  34. "[RTA3L02] 启动录像失败,字体为空,添加水印失败",
  35. "[RTA3L03] 开始录像失败,请稍后(约30秒)再试",
  36. "[RTA3L04] 录像失败,摄像头故障,获取不到视频,请联系厂商进行维修",
  37. "[RTA3L05] 录像失败,获取不到远端音频,请检查风险提示音是否正常播放且音量大小是否正常",
  38. "[RTA3L06] 录像失败,麦克风故障,获取不到本地音频,请联系厂商进行维修",
  39. "[RTA3L07] 录像失败,系统不支持当前音频采样率",
  40. "[RTA3L08] 录像失败,音频流写入失败,请稍后(约30秒)再试",
  41. "[RTA3L09] 录像失败,获取不到远端视频,请稍后(约30秒)再试"
  42. };
  43. static BOOL CheckDiskStatus(const char *szRoot, int nPercent, int *pFreeRatio)
  44. {
  45. #ifdef RVC_OS_WIN
  46. _ULARGE_INTEGER lpFreeBytesAvailableToCaller = {}, lpTotalNumberOfBytes = {}, lpTotalNumberOfFreeBytes = {};
  47. BOOL ret = GetDiskFreeSpaceEx(szRoot, &lpFreeBytesAvailableToCaller, &lpTotalNumberOfBytes, &lpTotalNumberOfFreeBytes);
  48. if (ret == 0)
  49. {
  50. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("CheckDiskStatus.GetDiskFreeSpaceEx failed(%d).",GetLastError());
  51. return FALSE;
  52. }
  53. DWORD dwTotal = lpTotalNumberOfBytes.QuadPart/1048576;
  54. DWORD dwTotalFree = lpTotalNumberOfFreeBytes.QuadPart/1048576;
  55. int ratio = dwTotalFree*100/dwTotal;
  56. *pFreeRatio = ratio;
  57. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("free disk %d MB, %d percent free.", dwTotalFree, ratio);
  58. //if (ratio < (100-MAX_DISK_PERCENT))
  59. if (ratio < (100-nPercent))
  60. {
  61. return FALSE;
  62. }
  63. return TRUE;
  64. #else
  65. //todo 调用resourcewatcher
  66. return TRUE;
  67. #endif
  68. }
  69. static int hch2int(char hch)
  70. {
  71. if (hch >= '0' && hch <= '9')
  72. return hch-'0';
  73. else if (hch >= 'a' && hch <= 'f')
  74. return hch-'a'+10;
  75. else if (hch >= 'A' && hch <= 'F')
  76. return hch-'A'+10;
  77. return 0;
  78. }
  79. static long hexstr2int(const char *str, int len)
  80. {
  81. long result = 0;
  82. if (str && len <= strlen(str)) {
  83. for (int i = 0; i < len; ++i) {
  84. result += (hch2int(str[i]) << ((len-i-1) << 2));
  85. }
  86. }
  87. return result;
  88. }
  89. static CSimpleStringA VideoSerialID2TimeString(const char *videoserialid)
  90. {
  91. DWORD nTimeTicks = hexstr2int(videoserialid,8);
  92. return ((CSmallDateTime)nTimeTicks).ToTimeString();
  93. }
  94. static void CStringSplit(char* str, char** result, const char* del)
  95. {
  96. char* pdata = NULL;
  97. char* p = NULL;
  98. #ifdef RVC_OS_WIN
  99. p = strtok_s(str, del, &pdata);
  100. #else
  101. p = strtok_r(str, del, &pdata);
  102. #endif // RVC_OS_WIN
  103. while (p != NULL) {
  104. *result++ = p;
  105. #ifdef RVC_OS_WIN
  106. p = strtok_s(NULL, del, &pdata);
  107. #else
  108. p = strtok_r(NULL, del, &pdata);
  109. #endif
  110. }
  111. }
  112. static bool rvcMoveFile(const char* strSrcFile, const char* strDstFile)
  113. {
  114. bool bRet = false;
  115. if (NULL == strSrcFile || NULL == strDstFile) {
  116. return bRet;
  117. }
  118. #ifdef RVC_OS_WIN
  119. bRet = MoveFile(strSrcFile, strDstFile);
  120. #else
  121. if (0 == rename(strSrcFile, strDstFile)) {
  122. bRet = true;
  123. }
  124. #endif // RVC_OS_WIN
  125. return bRet;
  126. }
  127. static bool RvcDeleteFile(const char* strSrcFile)
  128. {
  129. bool bRet = false;
  130. if (NULL == strSrcFile) {
  131. return bRet;
  132. }
  133. #ifdef RVC_OS_WIN
  134. bRet = DeleteFile(strSrcFile);
  135. #else
  136. if (0 == remove(strSrcFile)) {
  137. bRet = true;
  138. }
  139. #endif // RVC_OS_WIN
  140. return bRet;
  141. }
  142. #ifdef RVC_OS_WIN
  143. // 寻找某目录下与通配符匹配的文件
  144. static bool FindMatchedFile(const char* pstrFindPath, const char* pstrFindFileName, uint32_t & uCountFile)
  145. {
  146. char sPath[MAX_PATH] = {0};
  147. char sFormatFileName[MAX_PATH + 2] = "*";
  148. WIN32_FIND_DATA FindFileData;
  149. HANDLE hFind;
  150. bool fFinished = false;
  151. strcpy(sFormatFileName, pstrFindPath);
  152. if (pstrFindPath[strlen(pstrFindPath) - 1] != SPLIT_SLASH)
  153. {
  154. strcat(sFormatFileName, SPLIT_SLASH_STR);
  155. strcat(sFormatFileName, "*");
  156. }
  157. else
  158. {
  159. strcat(sFormatFileName, "*");
  160. }
  161. strcat(sFormatFileName, pstrFindFileName);
  162. strcat(sFormatFileName, "*");
  163. hFind = FindFirstFile(sFormatFileName, &FindFileData);
  164. if (hFind == INVALID_HANDLE_VALUE)
  165. {
  166. return false;
  167. }
  168. else
  169. {
  170. while (!fFinished)
  171. {
  172. strcpy(sPath, pstrFindPath);
  173. if (sPath[strlen(sPath) - 1] != SPLIT_SLASH)
  174. {
  175. strcat(sPath, SPLIT_SLASH_STR);
  176. }
  177. strcat(sPath, FindFileData.cFileName);
  178. if (!(FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes))
  179. {
  180. ++uCountFile;
  181. }
  182. if (!FindNextFile(hFind, &FindFileData))
  183. {
  184. if (GetLastError() == ERROR_NO_MORE_FILES)
  185. {
  186. fFinished = true;
  187. }
  188. else
  189. {
  190. break;
  191. }
  192. }
  193. }
  194. FindClose(hFind);
  195. }
  196. return true;
  197. }
  198. #else
  199. static bool FindMatchedFile(const char* sFindPath, const char* sFindFileName, uint32_t& uCountFile)
  200. {
  201. bool bRet = false;
  202. DIR* pDir = NULL;
  203. struct dirent* pFile = NULL;
  204. CSimpleStringA tmpFindFileName = sFindFileName;
  205. pDir = opendir(sFindPath);
  206. if (pDir == NULL) {
  207. return bRet;
  208. }
  209. //linux不支持*查找,去掉后缀
  210. char strsuffix[MAX_PATH] = { 0 };
  211. snprintf(strsuffix, MAX_PATH, "*.%s", RECORD_MP4_SUFFIX);
  212. if (tmpFindFileName.IsEndWith(strsuffix)) {
  213. tmpFindFileName = tmpFindFileName.SubString(0, tmpFindFileName.GetLength() - 5);
  214. }
  215. while ((pFile = readdir(pDir)) != NULL) {
  216. if (pFile->d_type & DT_DIR) {
  217. continue;
  218. }
  219. else {
  220. if (0 == _strnicmp(pFile->d_name, tmpFindFileName.GetData(), tmpFindFileName.GetLength())) {
  221. ++uCountFile;
  222. bRet = true;
  223. }
  224. }
  225. }
  226. closedir(pDir);
  227. return bRet;
  228. }
  229. #endif
  230. static CSimpleStringA DecryptString(const char* lpszEncrpyted)
  231. {
  232. if (NULL == lpszEncrpyted) {
  233. return CSimpleStringA("");
  234. }
  235. int iEncrypt = 0;
  236. int len = strlen(lpszEncrpyted);
  237. CSimpleStringA csPlainTxt('\0', (len) / 2 + 1);
  238. int iCh = 0;
  239. for (int i = 0; i < len; i += 2) {
  240. sscanf(lpszEncrpyted + i, "%02X", &iCh);
  241. csPlainTxt[i / 2] = (char)(((char)iCh) ^ (128 | (iEncrypt++ & 127)));
  242. }
  243. return CSimpleStringA((LPCTSTR)csPlainTxt);
  244. }
  245. static unsigned long GetFileSize(const char* pfilename)
  246. {
  247. #ifdef RVC_OS_WIN
  248. unsigned long usize = 0;
  249. if (NULL == pfilename) {
  250. return usize;
  251. }
  252. FILE* pFile = fopen(pfilename, "rb");
  253. if (pFile) {
  254. fseek(pFile, 0, SEEK_END);
  255. usize = ftell(pFile);
  256. fclose(pFile);
  257. }
  258. return usize;
  259. #else
  260. struct stat statbuf;
  261. if (0 == stat(pfilename, &statbuf)) {
  262. return statbuf.st_size;
  263. }
  264. else {
  265. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("errno info is %s.", strerror(errno));
  266. return 0;
  267. }
  268. #endif
  269. }
  270. static void rvcDbg(filecrypt_loglevel elevel, const char* fmt, ...)
  271. {
  272. LOG_LEVEL_E eloglevel = LOG_LEVEL_DEBUG;
  273. if (FILECRYPT_LOG_INFO <= elevel) {
  274. eloglevel = LOG_LEVEL_INFO;
  275. }
  276. va_list arg;
  277. va_start(arg, fmt);
  278. int n = vsnprintf(NULL, 0, fmt, arg);
  279. if (n >= MAX_LOG_LEN) {
  280. char* buf = (char*)malloc((size_t)(n + 1));
  281. vsnprintf(buf, n + 1, fmt, arg);
  282. DbgWithLink(eloglevel, LOG_TYPE_SYSTEM)("%s", buf);
  283. free(buf);
  284. }
  285. else {
  286. char strlog[MAX_LOG_LEN] = { 0 };
  287. vsnprintf(strlog, MAX_LOG_LEN, fmt, arg);
  288. DbgWithLink(eloglevel, LOG_TYPE_SYSTEM)("%s", strlog);
  289. }
  290. va_end(arg);
  291. }
  292. void SalesRecordServiceSession::Handle_GetOFLVideoRecords( SpReqAnsContext<SalesRecorderSerVice_GetOFLVideoRecords_Req, SalesRecorderSerVice_GetOFLVideoRecords_Ans>::Pointer ctx )
  293. {
  294. DbgToBeidou(ctx->link, __FUNCTION__)();
  295. ctx->Answer(Error_Succeed);
  296. }
  297. void SalesRecordServiceSession::Handle_CheckVideoDiskStatus( SpReqAnsContext<SalesRecorderSerVice_CheckVideoDiskStatus_Req, SalesRecorderSerVice_CheckVideoDiskStatus_Ans>::Pointer ctx )
  298. {
  299. DbgToBeidou(ctx->link, __FUNCTION__)();
  300. int nFreeRatio = 0;
  301. int bSufficient = CheckDiskStatus((LPCTSTR)ctx->Req.DriveLetter,m_pEntity->m_max_disk_percent,&nFreeRatio);
  302. ctx->Ans.IsSufficient = bSufficient;
  303. ctx->Ans.FreeRatio = nFreeRatio;
  304. ctx->Answer(Error_Succeed);
  305. }
  306. void SalesRecordServiceSession::Handle_PlayVideo(SpReqAnsContext<SalesRecorderSerVice_PlayVideo_Req, SalesRecorderSerVice_PlayVideo_Ans>::Pointer ctx)
  307. {
  308. DbgToBeidou(ctx->link, __FUNCTION__)();
  309. ctx->Answer(Error_Succeed);
  310. }
  311. void SalesRecordServiceSession::Handle_SaveVideo(SpReqAnsContext<SalesRecorderSerVice_SaveVideo_Req, SalesRecorderSerVice_SaveVideo_Ans>::Pointer ctx)
  312. {
  313. DbgToBeidou(ctx->link, __FUNCTION__)();
  314. ErrorCodeEnum ErrorCode = m_pEntity->HandleSaveVideo();
  315. ctx->Answer(ErrorCode);
  316. }
  317. void SalesRecordServiceSession::Handle_StopRecord(SpReqAnsContext<SalesRecorderSerVice_StopRecord_Req, SalesRecorderSerVice_StopRecord_Ans>::Pointer ctx)
  318. {
  319. DbgToBeidou(ctx->link, __FUNCTION__)();
  320. ErrorCodeEnum ErrorCode = m_pEntity->HandleStopRecord(CSimpleStringW2A(ctx->Req.VideoName).GetData());
  321. ctx->Answer(ErrorCode);
  322. }
  323. void SalesRecordServiceSession::Handle_SetAudioTransFlag(SpReqAnsContext<SalesRecorderSerVice_SetAudioTransFlag_Req, SalesRecorderSerVice_SetAudioTransFlag_Ans>::Pointer ctx)
  324. {
  325. DbgToBeidou(ctx->link, __FUNCTION__)();
  326. ctx->Answer(Error_Succeed);
  327. }
  328. void SalesRecordServiceSession::Handle_StopShowVideo(SpReqAnsContext<SalesRecorderSerVice_StopShowVideo_Req, SalesRecorderSerVice_StopShowVideo_Ans>::Pointer ctx)
  329. {
  330. DbgToBeidou(ctx->link, __FUNCTION__)();
  331. ctx->Answer(Error_Succeed);
  332. }
  333. void SalesRecordServiceSession::Handle_PlaySalesRecord(SpReqAnsContext<SalesRecorderSerVice_PlaySalesRecord_Req, SalesRecorderSerVice_PlaySalesRecord_Ans>::Pointer ctx)
  334. {
  335. DbgToBeidou(ctx->link, __FUNCTION__)();
  336. ctx->Answer(Error_Succeed);
  337. }
  338. void SalesRecordServiceSession::Handle_StartRemoteRecord(SpReqAnsContext<SalesRecorderSerVice_StartRemoteRecord_Req, SalesRecorderSerVice_StartRemoteRecord_Ans>::Pointer ctx)
  339. {
  340. DbgToBeidou(ctx->link, __FUNCTION__)();
  341. ErrorCodeEnum ErrorCode = m_pEntity->HandleStartRecord(ctx->Req.VideoName.GetData(), true);
  342. ctx->Answer(ErrorCode);
  343. }
  344. void SalesRecordServiceSession::Handle_DeleteVideo(SpReqAnsContext<SalesRecorderSerVice_DeleteVideo_Req, SalesRecorderSerVice_DeleteVideo_Ans>::Pointer ctx)
  345. {
  346. DbgToBeidou(ctx->link, __FUNCTION__)();
  347. ErrorCodeEnum ErrorCode = m_pEntity->HandleDeleteVideo();
  348. ctx->Answer(ErrorCode);
  349. }
  350. void SalesRecordServiceSession::Handle_AppendWatermark(SpReqAnsContext<SalesRecorderSerVice_AppendWatermark_Req, SalesRecorderSerVice_AppendWatermark_Ans>::Pointer ctx)
  351. {
  352. DbgToBeidou(ctx->link, __FUNCTION__)();
  353. #ifdef RVC_OS_WIN
  354. ErrorCodeEnum ErrorCode = m_pEntity->HandleVideoAppendWatermark(CSimpleStringW2A(ctx->Req.VideoName).GetData(), CSimpleStringW2A(ctx->Req.Watermark).GetData());
  355. #else
  356. ErrorCodeEnum ErrorCode = m_pEntity->HandleVideoAppendWatermark(CSimpleStringW2A(ctx->Req.VideoName).GetData(), ctx->Req.Watermark.GetData());
  357. #endif
  358. ctx->Answer(ErrorCode);
  359. }
  360. void SalesRecordServiceSession::Handle_SetRecordCamera(SpReqAnsContext<SalesRecorderSerVice_SetRecordCamera_Req, SalesRecorderSerVice_SetRecordCamera_Ans>::Pointer ctx)
  361. {
  362. DbgToBeidou(ctx->link, __FUNCTION__)();
  363. ErrorCodeEnum ErrorCode = m_pEntity->SetRecordCamera(ctx->Req.iCamera);
  364. ctx->Answer(ErrorCode);
  365. }
  366. CServerSessionBase * CSalesRecorderEntity::OnNewSession( const char* pszRemoteEntityName, const char * pszClass )
  367. {
  368. return new SalesRecordServiceSession(this);
  369. }
  370. void CSalesRecorderEntity::OnPreStart( CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext )
  371. {
  372. ErrorCodeEnum Error = __OnStart(Error_Succeed);
  373. pTransactionContext->SendAnswer(Error);
  374. }
  375. ErrorCodeEnum CSalesRecorderEntity::__OnStart( ErrorCodeEnum preOperationError )
  376. {
  377. //MessageBoxA(0,0,0,0);
  378. m_eDeviceType = eStand2sType;
  379. m_bNeedRestart = false;
  380. #ifdef RVC_OS_WIN
  381. m_xIdlePre = m_xKernelPre = m_xUserPre = 0;
  382. if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)) {
  383. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Set Process(%d) RealTime Priority Success.", GetCurrentProcessId());
  384. }
  385. #endif // RVC_OS_WIN
  386. m_eDeviceType = RvcGetDeviceType();
  387. if (preOperationError != Error_Succeed) {
  388. return preOperationError;
  389. }
  390. ErrorCodeEnum Error = Error_Succeed;
  391. m_iActiveCamera = CAMERA_TYPE_ENV;
  392. m_iCameraState = 'N';
  393. m_iRecordCamera = CAMERA_TYPE_ENV;
  394. int i = 0;
  395. m_arrListener.Init(4);
  396. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_RETURNMENU, NULL, false);
  397. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_High, Error_IgnoreAll, LOG_EVT_SALESRECORD_ENTITY_EXCEPTION, NULL, false);
  398. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_SALESRECORD_SECTION_FINISHED, NULL, false);
  399. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_SALESRECORD_WHOLE_FINISHED, NULL, false);
  400. GetFunction()->RegistSysVarEvent(SYSVAR_ACTIVETRACKINGCAMERA,this);
  401. GetFunction()->RegistSysVarEvent(SYSVAR_CAMERASTATE,this);
  402. CSimpleStringA strValue;
  403. GetFunction()->GetSysVar(SYSVAR_CAMERASTATE, strValue);
  404. m_iCameraState = strValue[0];
  405. if (strValue[0] == 'E'){
  406. m_iActiveCamera = CAMERA_TYPE_OPT;
  407. }
  408. else{
  409. m_iActiveCamera = CAMERA_TYPE_ENV;
  410. }
  411. Error = GetFunction()->RegistSysVarEvent("SessionID", this);
  412. if (Error != Error_Succeed) {
  413. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("register sysvar %s failed!", "SessionID");
  414. }
  415. Error = GetFunction()->GetPath("Temp", m_TempDir);
  416. if (Error != Error_Succeed) {
  417. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get global record temp path failed!");
  418. }
  419. if (m_TempDir.GetLength() > 0 && m_TempDir[m_TempDir.GetLength()-1] != SPLIT_SLASH) {
  420. m_TempDir += SPLIT_SLASH_STR;
  421. }
  422. Error = GetFunction()->GetPath("UploadVideo", m_RecordSaveDir);
  423. if (Error != Error_Succeed) {
  424. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get global record save path failed!");
  425. }
  426. if (m_RecordSaveDir.GetLength() > 0 && m_RecordSaveDir[m_RecordSaveDir.GetLength()-1] != SPLIT_SLASH) {
  427. m_RecordSaveDir += SPLIT_SLASH_STR;
  428. }
  429. return Error;
  430. }
  431. void CSalesRecorderEntity::OnStarted()
  432. {
  433. m_eAudioOutQuality = eUltraHD;
  434. m_bIsAudioNsOn = false;
  435. m_iAudioNsPolicy = 2;
  436. m_iAudioChannels = 1;
  437. m_strHttpServerAPI = RVC_UPLOAD_VIDEORECORDING_HTTP_API;
  438. m_iHttpTimeOut = RVC_HTTPTIMEOUT;
  439. m_strHttpServerAddr = RVC_UPLOAD_VIDEORECORDING_HTTP_ADDR;
  440. m_strAppVersion = NULL;
  441. m_strTerminalId = NULL;
  442. m_bPostOn = false;
  443. m_bWholeSection = false;
  444. m_bEncFlag = true;
  445. m_iRemoteRecordType = 0;
  446. CSystemStaticInfo si;
  447. ErrorCodeEnum Error = GetFunction()->GetSystemStaticInfo(si);
  448. if (Error == Error_Succeed) {
  449. m_strAppVersion = si.InstallVersion.ToString();
  450. m_strTerminalId = si.strTerminalID;
  451. }
  452. GetEntityConfig();
  453. #ifndef RVC_OS_WIN
  454. InitSalesRecorder();
  455. #endif
  456. LogEvent(Severity_Middle, LOG_EVT_MOD_SALESRECORDER_STARTED_SUCCESS, "sales recorder entity started successfully.");
  457. }
  458. void CSalesRecorderEntity::OnPreClose( EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext )
  459. {
  460. ErrorCodeEnum Error = __OnClose(Error_Succeed);
  461. pTransactionContext->SendAnswer(Error);
  462. }
  463. ErrorCodeEnum CSalesRecorderEntity::__OnClose( ErrorCodeEnum preOperationError )
  464. {
  465. if (preOperationError != Error_Succeed) {
  466. return preOperationError;
  467. }
  468. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  469. for (int i = 0; i < m_arrListener.GetCount(); ++i) {
  470. spFunction->UnsubscribeLog(m_arrListener[i]);
  471. }
  472. GetFunction()->UnregistSysVarEvent(SYSVAR_ACTIVETRACKINGCAMERA);
  473. GetFunction()->UnregistSysVarEvent(SYSVAR_CAMERASTATE);
  474. StopRecord();
  475. #ifndef RVC_OS_WIN
  476. ReleaseSalesRecorder();
  477. #endif
  478. return Error_Succeed;
  479. }
  480. void CSalesRecorderEntity::OnSelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext)
  481. {
  482. if (Test_ShakeHand == eTestType)
  483. {
  484. if (m_bNeedRestart){
  485. pTransactionContext->SendAnswer(Error_Unexpect);
  486. }
  487. else{
  488. pTransactionContext->SendAnswer(Error_Succeed);
  489. }
  490. }
  491. }
  492. void CSalesRecorderEntity::Debug(record_loglevel elevel, const char* fmt, ...)
  493. {
  494. record_loglevel entitylevel = (m_lowestlevel > m_loglevel) ? m_lowestlevel : m_loglevel;
  495. if (entitylevel <= elevel) {
  496. va_list arg;
  497. va_start(arg, fmt);
  498. int n = vsnprintf(NULL, 0, fmt, arg);
  499. if (n >= MAX_PATH) {
  500. char* buf = (char*)malloc((size_t)(n + 1));
  501. vsnprintf(buf, n + 1, fmt, arg);
  502. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  503. free(buf);
  504. }
  505. else {
  506. char strlog[MAX_PATH] = { 0 };
  507. vsnprintf(strlog, MAX_PATH, fmt, arg);
  508. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  509. }
  510. va_end(arg);
  511. }
  512. }
  513. void CSalesRecorderEntity::vDebug(record_loglevel elevel, const char* str, va_list list)
  514. {
  515. record_loglevel entitylevel = (m_lowestlevel > m_loglevel) ? m_lowestlevel : m_loglevel;
  516. if (entitylevel <= elevel) {
  517. int n = vsnprintf(NULL, 0, str, list);
  518. if (n >= MAX_PATH) {
  519. char* buf = (char*)malloc((size_t)(n + 1));
  520. vsnprintf(buf, n + 1, str, list);
  521. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  522. free(buf);
  523. }
  524. else {
  525. char strlog[MAX_PATH] = { 0 };
  526. vsnprintf(strlog, MAX_PATH, str, list);
  527. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  528. }
  529. }
  530. }
  531. int CSalesRecorderEntity::GetRecordCamera()
  532. {
  533. int iRecordCamera = m_iRecordCamera;
  534. if (1 != m_iRemoteRecordType) {
  535. iRecordCamera = m_iActiveCamera;
  536. }
  537. else {
  538. if (0 == iRecordCamera) {
  539. LogWarn(Severity_Low, Error_Debug, LOG_EVT_SALESRECORD_USE_ENVCAMERA, "remote video record use env camera.");
  540. }
  541. else {
  542. LogWarn(Severity_Low, Error_Debug, LOG_EVT_SALESRECORD_USE_OPTCAMERA, "remote video record use opt camera.");
  543. }
  544. }
  545. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("remote record camera is %d.", iRecordCamera);
  546. return iRecordCamera;
  547. }
  548. int CSalesRecorderEntity::GetCameraState()
  549. {
  550. return m_iCameraState;
  551. }
  552. void CSalesRecorderEntity::OnRecordFailed(eRvcRecordFailedCase eCase, const char* pszMessage, bool bRecordDevFault)
  553. {
  554. #ifdef RVC_OS_WIN
  555. double fCpuUsage = GetSystemCpuUsage();
  556. if (fCpuUsage > 50.0){
  557. LogWarn(Severity_Low, Error_Debug, LOG_EVT_UI_RECORDFAILED_FOR_HIGHCPU, "more than 50 percent.");
  558. }
  559. #endif
  560. if (eCase < eDefault && eCase >= 0){
  561. LogEvent(Severity_Middle, LOG_EVT_UI_RECORDFAILED, record_failed_case_table[eCase]);
  562. }
  563. m_loglevel = RECORD_LOG_INFO;
  564. #ifdef RVC_OS_WIN
  565. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_SALESRECORD_FAILED, CSimpleStringA::Format("{%s} current memory usage is %d, and cpu usage is %f.", pszMessage ? pszMessage : " ", GetSystemMemoryUsage(), fCpuUsage).GetData());
  566. #else
  567. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_SALESRECORD_FAILED, CSimpleStringA::Format("%s", pszMessage ? pszMessage : " ").GetData());
  568. #endif
  569. if (eBeginFailed == eCase) {
  570. m_bNeedRestart = true;
  571. RealSelfCheck();
  572. }
  573. m_eBusinessStatus = eInterrupt;
  574. }
  575. void CSalesRecorderEntity::OnRecordEntityExcption()
  576. {
  577. LogEvent(Severity_High,LOG_EVT_SALESRECORD_ENTITY_EXCEPTION,"现场销售双录出现异常,请稍候重录,系统正在恢复中,预计60秒!");
  578. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORD_ENTITY_EXCEPTION, "sales record entity exception!");
  579. }
  580. void CSalesRecorderEntity::OnRecordFinished()
  581. {
  582. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORD_FINISHED, "现场销售双录已完成.");
  583. }
  584. void CSalesRecorderEntity::OnASectionFinished(const char* pszMessage, int iSerialNum, bool bfinished)
  585. {
  586. if (false == bfinished) {
  587. LogEvent(Severity_Middle, LOG_EVT_SALESRECORD_SECTION_FINISHED, pszMessage);
  588. }
  589. else {
  590. LogEvent(Severity_Middle, LOG_EVT_SALESRECORD_WHOLE_FINISHED, pszMessage);
  591. if (m_bEncFlag) {
  592. HandleEncryptVideoRecord(pszMessage);
  593. }
  594. }
  595. }
  596. void CSalesRecorderEntity::OnTimeout(DWORD dwTimerID)
  597. {
  598. }
  599. void CSalesRecorderEntity::OnSysVarEvent( const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName )
  600. {
  601. if (_stricmp(pszKey, SYSVAR_CAMERASTATE) == 0)
  602. {
  603. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("OnSysVarEvent Key = %s, Value = %s.", pszKey, pszValue);
  604. m_iCameraState = pszValue[0];
  605. if (pszValue[0] == 'E')
  606. {
  607. m_iActiveCamera = CAMERA_TYPE_OPT;
  608. }
  609. else
  610. {
  611. m_iActiveCamera = CAMERA_TYPE_ENV;
  612. }
  613. }
  614. else if (_stricmp(pszKey, SYSVAR_ACTIVETRACKINGCAMERA) == 0)
  615. {
  616. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("OnSysVarEvent Key = %s, Value = %s.", pszKey, pszValue);
  617. if (m_iCameraState == 'N')
  618. {
  619. if (pszValue[0] == 'E')
  620. {
  621. m_iActiveCamera = CAMERA_TYPE_ENV;
  622. }
  623. else if (pszValue[0] == 'O')
  624. {
  625. m_iActiveCamera = CAMERA_TYPE_OPT;
  626. }
  627. }
  628. }
  629. }
  630. void CSalesRecorderEntity::OnLog( const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel, const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID, const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage, const linkContext &pLinkInfo)
  631. {
  632. // 响应客户经理销售录像相关的事件
  633. switch (dwUserCode)
  634. {
  635. case LOG_EVT_UI_RETURNMENU:
  636. HandleReturnMenu();
  637. break;
  638. case LOG_EVT_SALESRECORD_ENTITY_EXCEPTION:
  639. HandleSalesRecordEntityException(pszMessage);
  640. break;
  641. case LOG_EVT_SALESRECORD_SECTION_FINISHED:
  642. {
  643. if (m_bEncFlag) {
  644. HandleEncryptVideoRecord(pszMessage);
  645. }
  646. }
  647. break;
  648. case LOG_EVT_SALESRECORD_WHOLE_FINISHED:
  649. {
  650. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("recv LOG_EVT_SALESRECORD_WHOLE_FINISHED EVENT.");
  651. }
  652. break;
  653. default:
  654. break;
  655. }
  656. }
  657. bool CSalesRecorderEntity::GetStandardQualityOnSiteSalesRecorder()
  658. {
  659. bool bRet = false;
  660. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE,
  661. REC_COMMON_VIDEO_OPT_SHM_SNAPSHOT_QUEUE, REC_COMMON_AUDIO_SALES_SHM_QUEUE, REC_COMMON_VIDEO_REMOTE_SHM_RTP_QUEUE, REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
  662. return bRet;
  663. }
  664. bool CSalesRecorderEntity::GetHighQualityOnSiteSalesRecorder()
  665. {
  666. bool bRet = false;
  667. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE,
  668. REC_COMMON_VIDEO_OPT_SHM_SNAPSHOT_QUEUE, REC_COMMON_AUDIO_SALES_SHM_QUEUE, REC_COMMON_VIDEO_REMOTE_SHM_RTP_QUEUE, REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
  669. return bRet;
  670. }
  671. void CSalesRecorderEntity::StartOnSiteSalesRecord(const int fps, const char* videofilename, int videoquality, int audioOutBitRate, SubtitleParam* subtitleParam, bool bWholeSection, bool bSessionManage, eRvcRecordType eRecordType)
  672. {
  673. #ifdef RVC_OS_WIN
  674. bool bRet = false;
  675. bRet = GetStandardQualityOnSiteSalesRecorder();
  676. if (false == bRet){
  677. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get onsite sales recorder failed.");
  678. return;
  679. }
  680. #endif
  681. Rvc_RecordAudioParam_t tAudioParams;
  682. tAudioParams.eRecordType = eRecordType;
  683. tAudioParams.eOutPutType = m_eAudioOutQuality;
  684. tAudioParams.bIsNsOn = m_bIsAudioNsOn;
  685. tAudioParams.iNsPolicy = m_iAudioNsPolicy;
  686. tAudioParams.iAudioOutBitRate = audioOutBitRate;
  687. tAudioParams.iAudioChannels = m_iAudioChannels;
  688. tAudioParams.bMuteAudioMode = false;
  689. if (eStand2Agent == eRecordType) {
  690. tAudioParams.eOutPutType = eLowDefinition;
  691. tAudioParams.bIsNsOn = false;
  692. }
  693. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("init lib video record success! and record type is %s and output audio quality is %s, audio noise suppression flag is %s. noise suppression policy is %d.", record_type_table[eRecordType], audio_quality_type_table[m_eAudioOutQuality], tAudioParams.bIsNsOn ? "true" : "false", tAudioParams.iNsPolicy);
  694. if (m_pRecorder->StartVideoRecord(fps, videoquality, eMP4, &tAudioParams, subtitleParam, bWholeSection, false, m_TempDir.GetData(),
  695. m_TempDir.GetLength(), videofilename, strlen(videofilename)))
  696. {
  697. m_eBusinessStatus = eSuccess;
  698. m_bStarted = true;
  699. }
  700. else {
  701. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Start VideoRecord failed!");
  702. m_eBusinessStatus = eFailed;
  703. if (m_bPostOn) {
  704. PostSalesRecordInfos();
  705. }
  706. }
  707. }
  708. void CSalesRecorderEntity::StartRecord(const char * pszVideoName, int videoquality, int audioOutBitRate, SubtitleParam *subtitleParam /* = NULL */, bool bWholeSection /* = false */, bool bSessionManage /* = false */, eRvcRecordType eRecordType /* = eSingleSide */)
  709. {
  710. StartOnSiteSalesRecord(10, pszVideoName, videoquality, audioOutBitRate, subtitleParam, bWholeSection, bSessionManage, eRecordType);
  711. }
  712. ErrorCodeEnum CSalesRecorderEntity::StopRecord()
  713. {
  714. ErrorCodeEnum eCode = Error_Succeed;
  715. if (m_bStarted) {
  716. m_pRecorder->StopVideoRecord();
  717. #ifdef RVC_OS_WIN
  718. delete m_pRecorder;
  719. m_pRecorder = NULL;
  720. #endif
  721. m_bStarted = false;
  722. }
  723. else{
  724. eCode = Error_InvalidState;
  725. }
  726. return eCode;
  727. }
  728. void CSalesRecorderEntity::DeleteAllVideo( const char * pszVideoName)
  729. {
  730. if(!m_bStarted)
  731. {
  732. CSimpleStringA strPath;
  733. ErrorCodeEnum Error = GetFunction()->GetPath("Temp", strPath);
  734. if (Error == Error_Succeed) {
  735. if (strPath.GetLength() > 0 && strPath[strPath.GetLength()-1] != SPLIT_SLASH) {
  736. strPath += SPLIT_SLASH_STR;
  737. }
  738. uint32_t uVideoCount = 0;
  739. CSimpleStringA strFindFileName = CSimpleStringA::Format("S_%s*.%s", pszVideoName, RECORD_MP4_SUFFIX);
  740. bool bRet = FindMatchedFile(strPath.GetData(), strFindFileName.GetData(), uVideoCount);
  741. if(bRet)
  742. {
  743. strFindFileName = strFindFileName.SubString(0,strFindFileName.GetLength()-5);
  744. //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("succeed to get sales record count while delete video!");
  745. CSimpleStringA fileName("");
  746. bool bDeleteSucc = true;
  747. for(int i = 0; i != uVideoCount; ++i)
  748. {
  749. fileName = CSimpleStringA::Format("%s%s_%d.%s", strPath.GetData(), strFindFileName.GetData(), i, RECORD_MP4_SUFFIX);
  750. bRet = RvcDeleteFile(fileName.GetData());
  751. if(!bRet) {
  752. bDeleteSucc = false;
  753. #ifdef RVC_OS_WIN
  754. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Error Code %lu while delete %s.", GetLastError(), fileName.GetData());
  755. #else
  756. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s(%d) while delete %s.", strerror(errno), errno, fileName.GetData());
  757. #endif // RVC_OS_WIN
  758. }
  759. }
  760. if (!bDeleteSucc) {
  761. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("failed to delete sales video!");
  762. }
  763. }
  764. }
  765. }
  766. }
  767. ErrorCodeEnum CSalesRecorderEntity::DeleteVideo( const char *videofilename)
  768. {
  769. ErrorCodeEnum ErrorCode = Error_Succeed;
  770. if(!m_bStarted)
  771. {
  772. CSimpleStringA strPath;
  773. ErrorCodeEnum Error = GetFunction()->GetPath("Temp", strPath);
  774. if (Error == Error_Succeed) {
  775. if (strPath.GetLength() > 0 && strPath[strPath.GetLength()-1] != SPLIT_SLASH) {
  776. strPath += SPLIT_SLASH_STR;
  777. }
  778. CSimpleStringA strFindFileName = CSimpleStringA::Format("%s*.%s", videofilename, RECORD_MP4_SUFFIX);
  779. uint32_t uVideoCount = 0;
  780. bool bRet = FindMatchedFile(strPath.GetData(), strFindFileName.GetData(), uVideoCount);
  781. if(bRet)
  782. {
  783. CSimpleStringA fileName;
  784. bool bDeleteSucc = true;
  785. for(int i = 0; i != uVideoCount; ++i)
  786. {
  787. fileName = CSimpleStringA::Format("%s%s_%d.%s", strPath.GetData(), videofilename, i, RECORD_MP4_SUFFIX);
  788. bRet = RvcDeleteFile(fileName.GetData());
  789. if(!bRet) {
  790. bDeleteSucc = false;
  791. #ifdef RVC_OS_WIN
  792. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Error Code %lu while delete %s ", GetLastError(), fileName.GetData());
  793. #else
  794. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s(%d) while delete %s ", strerror(errno), errno, fileName.GetData());
  795. #endif
  796. }
  797. }
  798. if (!bDeleteSucc) {
  799. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("delete videos failed!");
  800. }
  801. }
  802. else
  803. {
  804. ErrorCode = Error_NotExist;
  805. }
  806. }
  807. }
  808. else {
  809. ErrorCode = Error_NotImpl;
  810. }
  811. if (eInterrupt != m_eBusinessStatus) {
  812. m_eBusinessStatus = eCancel;
  813. }
  814. if (m_bPostOn) {
  815. PostSalesRecordInfos();
  816. }
  817. return ErrorCode;
  818. }
  819. /*
  820. SaveVideo包含两步,找到录像和移动录像
  821. Error_Succeed 提交上传成功
  822. Error_NotExist not exist
  823. Error_NotImpl 方法执行失败
  824. */
  825. ErrorCodeEnum CSalesRecorderEntity::SaveVideo( const char * videofilename)
  826. {
  827. ErrorCodeEnum ErrorCode = Error_Succeed;
  828. if (NULL == videofilename || 0 == strlen(videofilename)) {
  829. return Error_Param;
  830. }
  831. if(!m_bStarted)
  832. {
  833. CSimpleStringA sourPath;
  834. ErrorCodeEnum Error = GetFunction()->GetPath("Temp", sourPath);
  835. if(Error == Error_Succeed)
  836. {
  837. if (sourPath.GetLength() > 0 && sourPath[sourPath.GetLength()-1] != SPLIT_SLASH) {
  838. sourPath += SPLIT_SLASH_STR;
  839. }
  840. uint32_t uVideoCount = 0;
  841. CSimpleStringA strFindFileName = CSimpleStringA::Format("S_%s*.%s", videofilename, RECORD_MP4_SUFFIX);
  842. bool bRet = FindMatchedFile(sourPath.GetData(), strFindFileName.GetData(), uVideoCount);
  843. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("FindMatchedFile count is %d.", uVideoCount);
  844. if(bRet)
  845. {
  846. strFindFileName = strFindFileName.SubString(0,strFindFileName.GetLength()-5);
  847. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("strFindFileName is %s.", strFindFileName.GetData());
  848. CSimpleStringA destPath;
  849. Error = GetFunction()->GetPath("UploadVideo", destPath);
  850. if(Error == Error_Succeed)
  851. {
  852. if (destPath.GetLength() > 0 && destPath[destPath.GetLength()-1] != SPLIT_SLASH) {
  853. destPath += SPLIT_SLASH_STR;
  854. }
  855. CSimpleStringA sourFileName(""), destFileName("");
  856. bool bMoveSucc = false;
  857. for(int i = 0; i != uVideoCount; ++i)
  858. {
  859. sourFileName = CSimpleStringA::Format("%s%s_%d.%s", sourPath.GetData(), strFindFileName.GetData(), i, RECORD_MP4_SUFFIX);
  860. destFileName = CSimpleStringA::Format("%s%s_%d.%s", destPath.GetData(), strFindFileName.GetData(), i, RECORD_MP4_SUFFIX);
  861. unsigned long ufilesize = GetFileSize(sourFileName.GetData());
  862. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORD_FILESIZE, CSimpleStringA::Format("%s file size is %u byte.", sourFileName.GetData(), ufilesize).GetData());
  863. bRet = rvcMoveFile(sourFileName.GetData(), destFileName.GetData());
  864. if (!bRet) {
  865. ErrorCode = Error_NotImpl;
  866. #ifdef RVC_OS_WIN
  867. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORD_SAVED_FAILED, CSimpleStringA::Format("Error Code %lu while move %s.", GetLastError(), sourFileName.GetData()).GetData());
  868. if (183 == GetLastError()) {
  869. ErrorCode = Error_InvalidState;
  870. }
  871. #else
  872. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORD_SAVED_FAILED, CSimpleStringA::Format("%s(%d) while move %s.", strerror(errno), errno, sourFileName.GetData()).GetData());
  873. #endif // RVC_OS_WIN
  874. }
  875. else {
  876. bMoveSucc = true;
  877. CSimpleStringA strVideoName = CSimpleStringA::Format("%s_%d.%s", strFindFileName.GetData(), i, RECORD_MP4_SUFFIX);
  878. if (m_bPostOn) {
  879. AddToSalesRecordList(destFileName.GetData(), strVideoName.GetData(), ufilesize);
  880. }
  881. }
  882. if (RVC_MIN_FILESIZE > ufilesize){
  883. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORD_INVALID_FILE, CSimpleStringA::Format("%s file size is %u.", sourFileName.GetData(), ufilesize).GetData());
  884. ErrorCode = Error_Failed;
  885. }
  886. }
  887. if (bMoveSucc) {
  888. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORD_SAVED_SUCCESS, CSimpleStringA::Format("succeed to save sales video, move it from %s to %s.", sourFileName.GetData(), destFileName.GetData()).GetData());
  889. if (m_bPostOn) {
  890. if (Error_Succeed != PostSalesRecordInfos()) {
  891. ErrorCode = Error_Failed;
  892. }
  893. }
  894. }
  895. }
  896. }
  897. else{
  898. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORD_SAVED_FAILED, "sales videos not exist or have been deleted");
  899. ErrorCode = Error_NotExist;
  900. }
  901. }
  902. }
  903. else{
  904. ErrorCode = Error_InvalidState;
  905. }
  906. return ErrorCode;
  907. }
  908. CSimpleStringA CSalesRecorderEntity::GetTerminalStage()
  909. {
  910. CSmartPointer<IEntityFunction> Func = GetFunction();
  911. CSimpleStringA strValue = "";
  912. Func->GetSysVar("TerminalStage", strValue);
  913. return strValue;
  914. }
  915. ErrorCodeEnum CSalesRecorderEntity::HandleStartRecord(const char *pszMessage, const bool bRemoteRecord)
  916. {
  917. ErrorCodeEnum Error = Error_Succeed;
  918. eRvcRecordType eRecordType = eSingleSide;
  919. if (NULL == pszMessage){
  920. return Error_Param;
  921. }
  922. size_t ulen = strlen(pszMessage);
  923. char *tmp = new char[ulen+1];
  924. memset(tmp, 0, ulen + 1);
  925. memcpy(tmp, pszMessage, ulen);
  926. char* result[16] = { 0 };
  927. #ifdef RVC_OS_WIN
  928. auto arr1 = CSimpleStringA2W(tmp).Split('@');
  929. auto arr2 = CAutoArray<CSimpleStringA>(arr1.GetCount());
  930. for (int i = 0; i < arr1.GetCount(); ++i){
  931. arr2[i] = CSimpleStringW2A(arr1[i]);
  932. result[i] = const_cast<char*>(arr2[i].GetData());
  933. }
  934. _snprintf(m_SalesVideoName, MAX_PATH, "%s", result[4]); //录像名:录像类型标志_录像流水号(如S_C13213EF)
  935. #else
  936. CStringSplit(tmp, result, "@");
  937. memset(m_SalesVideoName, 0, MAX_PATH);
  938. if (result[4]) {
  939. snprintf(m_SalesVideoName, MAX_PATH, "%s", result[4]); //录像名:录像类型标志_录像流水号(如S_C13213EF)
  940. }
  941. #endif
  942. int iPostionArr[4][2] = { 0 };
  943. for (int i = 0; i < 4; i++){
  944. sscanf(result[i], "%d|%d", &iPostionArr[i][0], &iPostionArr[i][1]);
  945. }
  946. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("local video frame size is (%d,%d).", iPostionArr[2][0], iPostionArr[3][0]);
  947. if (iPostionArr[2][0] >= iPostionArr[3][0]) {
  948. m_iRecordCamera = CAMERA_TYPE_ENV;
  949. }
  950. else {
  951. m_iRecordCamera = CAMERA_TYPE_OPT;
  952. }
  953. RecordSubTitle subTitle;
  954. memset(&subTitle, 0, sizeof(RecordSubTitle));
  955. if (result[5]) {
  956. CSimpleStringA strCardNo = DecryptString(result[5]);
  957. if (sizeof(subTitle.CustCardNo) > strCardNo.GetLength()) {
  958. _snprintf(subTitle.CustCardNo, sizeof(subTitle.CustCardNo), "%s", strCardNo.GetData());
  959. }
  960. else {
  961. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Invalid CustCardNo.");
  962. }
  963. }
  964. char* pStr = result[6];
  965. if (pStr) {
  966. CSimpleStringW szCustName = CSimpleStringA2W(pStr);
  967. if (szCustName.GetLength() <= 4) {
  968. strcpy(subTitle.CustName, pStr);
  969. }
  970. else {
  971. CSimpleStringW aa = szCustName.SubString(0, 4);
  972. _snprintf(subTitle.CustName, 32, "%s...", CSimpleStringW2A(aa).GetData());
  973. }
  974. }
  975. pStr = result[7];
  976. if (pStr) {
  977. int nProductCodeLen = strlen(pStr);
  978. if (nProductCodeLen <= 10) {
  979. strcpy(subTitle.ProductCode, pStr);
  980. }
  981. else {
  982. char aa[5] = { 0 }, bb[5] = { 0 };
  983. strncpy(aa, pStr, 4);
  984. strncpy(bb, pStr + nProductCodeLen - 4, 4);
  985. _snprintf(subTitle.ProductCode, 32, "%s...%s", aa, bb);
  986. }
  987. }
  988. pStr = result[8];
  989. if (pStr) {
  990. CSimpleStringW szProductName = CSimpleStringA2W(pStr);
  991. if (szProductName.GetLength() <= 5) {
  992. strcpy(subTitle.ProductName, pStr);
  993. }
  994. else {
  995. CSimpleStringW aa = szProductName.SubString(0, 3);
  996. CSimpleStringW bb = szProductName.SubString(szProductName.GetLength() - 2, 2);
  997. _snprintf(subTitle.ProductName, 128, "%s...%s", CSimpleStringW2A(aa).GetData(), CSimpleStringW2A(bb).GetData());
  998. }
  999. }
  1000. if (result[9]) {
  1001. strcpy(subTitle.SapID, result[9]);
  1002. }
  1003. else {
  1004. subTitle.SapID[0] = '\0';
  1005. }
  1006. if (result[10]) {
  1007. pStr = result[10];
  1008. CSimpleStringW szCustManagerName = CSimpleStringA2W(pStr);
  1009. if (szCustManagerName.GetLength() <= 4) {
  1010. strcpy(subTitle.CustManagerName, result[10]);
  1011. }
  1012. else {
  1013. CSimpleStringW aa = szCustManagerName.SubString(0,4);
  1014. _snprintf(subTitle.CustManagerName, 32,"%s...",CSimpleStringW2A(aa).GetData());
  1015. }
  1016. } else {
  1017. subTitle.CustManagerName[0] = '\0';
  1018. }
  1019. delete[] tmp;
  1020. tmp = NULL;
  1021. SubtitleParam subtitleParam;
  1022. memset(&subtitleParam, 0, sizeof(SubtitleParam));
  1023. subtitleParam.bSubtitle = true;
  1024. subtitleParam.bSubtitleSection = true;
  1025. subtitleParam.topSubtitleData[0] = '\0';
  1026. #ifdef RVC_OS_WIN
  1027. if (strlen(subTitle.SapID)>0&&strlen(subTitle.CustManagerName)>0){
  1028. _snprintf(subtitleParam.bottomSubtitleData1, MAX_PATH, "%s %s %s", subTitle.CustCardNo, subTitle.CustName, subTitle.ProductCode);
  1029. _snprintf(subtitleParam.bottomSubtitleData2, MAX_PATH, "%s %s %s", subTitle.ProductName, subTitle.SapID, subTitle.CustManagerName);
  1030. }
  1031. else{
  1032. _snprintf(subtitleParam.bottomSubtitleData1, MAX_PATH, "%s %s", subTitle.CustCardNo, subTitle.CustName);
  1033. _snprintf(subtitleParam.bottomSubtitleData2, MAX_PATH, "%s %s", subTitle.ProductCode, subTitle.ProductName);
  1034. }
  1035. #else
  1036. if (strlen(subTitle.SapID)>0&&strlen(subTitle.CustManagerName)>0){
  1037. swprintf(subtitleParam.bottomSubtitleData1, MAX_PATH, L"%s %s %s", subTitle.CustCardNo, subTitle.CustName, subTitle.ProductCode);
  1038. swprintf(subtitleParam.bottomSubtitleData2, MAX_PATH, L"%s %s %s", subTitle.ProductName, subTitle.SapID, subTitle.CustManagerName);
  1039. }
  1040. else{
  1041. swprintf(subtitleParam.bottomSubtitleData1, MAX_PATH, L"%s %s", subTitle.CustCardNo, subTitle.CustName);
  1042. swprintf(subtitleParam.bottomSubtitleData2, MAX_PATH, L"%s %s", subTitle.ProductCode, subTitle.ProductName);
  1043. }
  1044. #endif
  1045. int i_audio_out_bitrate = m_audio_out_bitrate;
  1046. if (bRemoteRecord){
  1047. if (eStand2sType == m_eDeviceType || eStand1SPlusType == m_eDeviceType) { //如果是大机
  1048. eRecordType = eStand2Agent; //可视柜台大机的双向录像
  1049. }
  1050. if(256 == m_audio_out_bitrate){
  1051. i_audio_out_bitrate = 128;
  1052. }
  1053. }
  1054. StartRecord(m_SalesVideoName, 90, i_audio_out_bitrate, &subtitleParam, m_bWholeSection, false, eRecordType);
  1055. LogWarn(Severity_Low, Error_Debug, LOG_EVT_START_REMOTERECORD, CSimpleStringA::Format("start remote record %s.", m_SalesVideoName).GetData());
  1056. return Error;
  1057. }
  1058. ErrorCodeEnum CSalesRecorderEntity::HandleStopRecord(const char *pszMessage)
  1059. {
  1060. ErrorCodeEnum ErrorCode = StopRecord();
  1061. return ErrorCode;
  1062. }
  1063. ErrorCodeEnum CSalesRecorderEntity::HandleSaveVideo()
  1064. {
  1065. ErrorCodeEnum ErrorCode = Error_Succeed;
  1066. // 将视频从tmp移动到uploadvideo
  1067. ErrorCode = SaveVideo(m_SalesVideoName+2);
  1068. ZeroMemory(m_SalesVideoName,sizeof(m_SalesVideoName));
  1069. return ErrorCode;
  1070. }
  1071. ErrorCodeEnum CSalesRecorderEntity::HandleDeleteVideo()
  1072. {
  1073. ErrorCodeEnum ErrorCode = Error_Succeed;
  1074. // 删除tmp中的视频
  1075. ErrorCode = DeleteVideo(m_SalesVideoName);
  1076. ZeroMemory(m_SalesVideoName,sizeof(m_SalesVideoName));
  1077. return ErrorCode;
  1078. }
  1079. void CSalesRecorderEntity::HandleReturnMenu()
  1080. {
  1081. CSimpleStringA strValue;
  1082. GetFunction()->GetSysVar("DesktopType", strValue);
  1083. if (strValue != CSimpleStringA("U"))
  1084. {
  1085. if (m_bStarted) // 如果正在进行客户经理录像
  1086. {
  1087. // 停止录像
  1088. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop record and return menu!");
  1089. StopRecord();
  1090. }
  1091. // 删除tmp中的视频
  1092. if (strlen(m_SalesVideoName) > 0)
  1093. {
  1094. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("delete sales record!");
  1095. DeleteAllVideo(m_SalesVideoName+2);
  1096. }
  1097. ZeroMemory(m_SalesVideoName,sizeof(m_SalesVideoName));
  1098. }
  1099. }
  1100. #ifdef RVC_OS_WIN
  1101. ErrorCodeEnum CSalesRecorderEntity::HandleVideoAppendWatermark(const char* pszVideoName, const char* pszWaterMark)
  1102. {
  1103. ErrorCodeEnum Error = Error_Failed;
  1104. if (NULL == pszWaterMark) {
  1105. return Error_Param;
  1106. }
  1107. if (m_bStarted && (NULL != m_pRecorder)) {
  1108. if (m_pRecorder->SetRightVideoWaterMark(pszWaterMark)) {
  1109. Error = Error_Succeed;
  1110. }
  1111. }
  1112. return Error;
  1113. }
  1114. #else
  1115. ErrorCodeEnum CSalesRecorderEntity::HandleVideoAppendWatermark(const char* pszVideoName, const wchar_t* pszWaterMark)
  1116. {
  1117. ErrorCodeEnum Error = Error_Failed;
  1118. if (NULL == pszWaterMark){
  1119. return Error_Param;
  1120. }
  1121. if (m_bStarted && (NULL != m_pRecorder)){
  1122. if (m_pRecorder->SetRightVideoWaterMark(pszWaterMark)) {
  1123. Error = Error_Succeed;
  1124. }
  1125. }
  1126. return Error;
  1127. }
  1128. #endif
  1129. ErrorCodeEnum CSalesRecorderEntity::HandleSalesRecordEntityException(const char* pszMessage)
  1130. {
  1131. // 通知到业务中台
  1132. SalesRecordException evt;
  1133. evt.failedmsg = CSimpleStringA2W(pszMessage==NULL?"现场销售双录过程出现异常!":pszMessage);
  1134. SpSendBroadcast(GetFunction(), SP_MSG_OF(SalesRecordException), SP_MSG_SIG_OF(SalesRecordException), evt);
  1135. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[dbg] SalesRecord entity exception broadcast sent!");
  1136. //停止录像
  1137. StopRecord();
  1138. m_bNeedRestart = true;
  1139. //重启实体
  1140. RealSelfCheck();
  1141. return Error_Succeed;
  1142. }
  1143. #ifdef RVC_OS_LINUX
  1144. bool CSalesRecorderEntity::InitSalesRecorder()
  1145. {
  1146. bool bRet = false;
  1147. bRet = GetStandardQualityOnSiteSalesRecorder();
  1148. return bRet;
  1149. }
  1150. bool CSalesRecorderEntity::ReleaseSalesRecorder()
  1151. {
  1152. if (m_pRecorder) {
  1153. delete m_pRecorder;
  1154. m_pRecorder = NULL;
  1155. }
  1156. return true;
  1157. }
  1158. #endif
  1159. ErrorCodeEnum CSalesRecorderEntity::RealSelfCheck()
  1160. {
  1161. ErrorCodeEnum Error = Error_Succeed;
  1162. HealthManagerService_ClientBase* pHMClient = new HealthManagerService_ClientBase(this);
  1163. Error = pHMClient->Connect();
  1164. if (Error != Error_Succeed){
  1165. pHMClient->SafeDelete();
  1166. pHMClient = NULL;
  1167. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pHMClient connect fail!");
  1168. }
  1169. if (pHMClient)
  1170. {
  1171. HealthManagerService_RealCheck_Req req;
  1172. req.name = GetEntityName();
  1173. HealthManagerService_RealCheck_Ans ans;
  1174. DWORD Timeout = 500;
  1175. Error = pHMClient->RealCheck(req,ans,Timeout);
  1176. if (Error!=Error_Succeed){
  1177. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("RealSelfcheck fail!");
  1178. }
  1179. }
  1180. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_ENTITY_RESTART, "sales record entity self restart.");
  1181. return Error;
  1182. }
  1183. #ifdef RVC_OS_WIN
  1184. bool IsMatchedVideo(WIN32_FIND_DATA fileData)
  1185. {
  1186. bool bRet = false;
  1187. if ('S' == fileData.cFileName[0] || 'W' == fileData.cFileName[0]){
  1188. SYSTEMTIME sysTime;
  1189. FileTimeToSystemTime(&fileData.ftCreationTime, &sysTime);
  1190. //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("File %s create data info is %d %d %d.", fileData.cFileName, sysTime.wYear, sysTime.wMonth, sysTime.wDay);
  1191. if ((2020 == sysTime.wYear) && (sysTime.wMonth == 1)){
  1192. if (sysTime.wDay >= 3 && sysTime.wDay <= 10){
  1193. bRet = true;
  1194. }
  1195. }
  1196. }
  1197. return bRet;
  1198. }
  1199. void CSalesRecorderEntity::UploadTempPathVideos()
  1200. {
  1201. CSimpleStringA sourPath;
  1202. CSimpleStringA destPath;
  1203. ErrorCodeEnum Error = GetFunction()->GetPath("Temp", sourPath);
  1204. Error = GetFunction()->GetPath("UploadVideo", destPath);
  1205. if (sourPath.GetLength() > 0 && sourPath[sourPath.GetLength()-1] != SPLIT_SLASH) {
  1206. sourPath += SPLIT_SLASH_STR;
  1207. }
  1208. if (destPath.GetLength() > 0 && destPath[destPath.GetLength()-1] != SPLIT_SLASH) {
  1209. destPath += SPLIT_SLASH_STR;
  1210. }
  1211. if(Error == Error_Succeed)
  1212. {
  1213. char srcFilePath[MAX_PATH]={0};
  1214. WIN32_FIND_DATA FindFileData;
  1215. HANDLE hFind;
  1216. BOOL fFinished = FALSE;
  1217. sprintf_s(srcFilePath, MAX_PATH, "%s*.%s", sourPath, RECORD_MP4_SUFFIX);
  1218. hFind = FindFirstFile(srcFilePath, &FindFileData);
  1219. if (INVALID_HANDLE_VALUE != hFind)
  1220. {
  1221. while (!fFinished)
  1222. {
  1223. if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes)
  1224. {
  1225. continue;
  1226. }
  1227. if (IsMatchedVideo(FindFileData)){
  1228. CSimpleStringA sourFileName = CSimpleStringA::Format("%s%s", (LPCSTR)sourPath, FindFileData.cFileName);
  1229. CSimpleStringA destFileName = CSimpleStringA::Format("%sBAK_%s", (LPCSTR)destPath, FindFileData.cFileName);
  1230. if(!MoveFile((LPCSTR)sourFileName, (LPCSTR)destFileName)) {
  1231. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Error Code %lu while move %s ", GetLastError(), (LPCSTR)sourFileName);
  1232. }
  1233. }
  1234. else{
  1235. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("File (%s) is not matched.", FindFileData.cFileName);
  1236. }
  1237. if (!FindNextFile(hFind, &FindFileData))
  1238. {
  1239. if (GetLastError() == ERROR_NO_MORE_FILES)
  1240. {
  1241. fFinished = TRUE;
  1242. }
  1243. else
  1244. {
  1245. break;
  1246. }
  1247. }
  1248. }
  1249. FindClose(hFind);
  1250. }
  1251. }
  1252. }
  1253. int CSalesRecorderEntity::GetSystemMemoryUsage()
  1254. {
  1255. // Use to convert bytes to KB
  1256. #define DIV 1024
  1257. MEMORYSTATUSEX statex;
  1258. statex.dwLength = sizeof (statex);
  1259. GlobalMemoryStatusEx (&statex);
  1260. return statex.dwMemoryLoad;
  1261. }
  1262. double CSalesRecorderEntity::GetSystemCpuUsage()
  1263. {
  1264. double ratio = 0;
  1265. #define _WIN32_WINNT 0x0601
  1266. FILETIME idleTime,kernelTime,userTime;
  1267. BOOL ret = GetSystemTimes(&idleTime,&kernelTime,&userTime);
  1268. if (ret == 0)
  1269. {
  1270. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("GetSystemCPUStatus.GetSystemTimes failed(%d).",GetLastError());
  1271. return 80.0;
  1272. }
  1273. __int64 xIdle,xKernel,xUser;
  1274. xIdle = idleTime.dwHighDateTime;
  1275. xIdle <<= 32;
  1276. xIdle |= idleTime.dwLowDateTime;
  1277. xKernel = kernelTime.dwHighDateTime;
  1278. xKernel <<= 32;
  1279. xKernel |= kernelTime.dwLowDateTime;
  1280. xUser = userTime.dwHighDateTime;
  1281. xUser <<= 32;
  1282. xUser |= userTime.dwLowDateTime;
  1283. if (m_xIdlePre != 0)
  1284. {
  1285. __int64 xI,xK,xU;
  1286. xI = xIdle - m_xIdlePre;
  1287. xK = xKernel - m_xKernelPre;
  1288. xU = xUser - m_xUserPre;
  1289. if ((xK +xU) != 0)
  1290. ratio = (xK - xI + xU) * 100 / (xK + xU);
  1291. }
  1292. m_xIdlePre = xIdle;
  1293. m_xKernelPre = xKernel;
  1294. m_xUserPre = xUser;
  1295. return ratio;
  1296. }
  1297. #else
  1298. /*
  1299. **time_t转SYSTEMTIME
  1300. */
  1301. SYSTEMTIME Time_tToSystemTime(time_t t)
  1302. {
  1303. tm temptm = *localtime(&t);
  1304. SYSTEMTIME st = { 1900 + temptm.tm_year,
  1305. 1 + temptm.tm_mon,
  1306. temptm.tm_wday,
  1307. temptm.tm_mday,
  1308. temptm.tm_hour,
  1309. temptm.tm_min,
  1310. temptm.tm_sec,
  1311. 0 };
  1312. return st;
  1313. }
  1314. bool IsMatchedVideo(LPCTSTR path, struct dirent* file)
  1315. {
  1316. bool bRet = false;
  1317. if ((file->d_reclen > 0) && ('S' == file->d_name[0] || 'W' == file->d_name[0])){
  1318. struct stat fileInfo;
  1319. char ttp[256];
  1320. bzero(ttp, sizeof(ttp));
  1321. strcat(ttp, path);
  1322. if (strcmp(ttp, "/") != 0)strcat(ttp, "/");//如果是根目录不需要加
  1323. strcat(ttp, file->d_name);
  1324. if (stat(ttp, &fileInfo) == 0) {
  1325. SYSTEMTIME sysTime;
  1326. sysTime = Time_tToSystemTime(fileInfo.st_mtime);
  1327. if ((2020 == sysTime.wYear) && (sysTime.wMonth == 1)) {
  1328. if (sysTime.wDay >= 3 && sysTime.wDay <= 10) {
  1329. bRet = true;
  1330. }
  1331. }
  1332. }
  1333. }
  1334. return bRet;
  1335. }
  1336. void CSalesRecorderEntity::UploadTempPathVideos() {
  1337. CSimpleStringA sourPath;
  1338. CSimpleStringA destPath;
  1339. ErrorCodeEnum Error = GetFunction()->GetPath("Temp", sourPath);
  1340. Error = GetFunction()->GetPath("UploadVideo", destPath);
  1341. if (sourPath.GetLength() > 0 && sourPath[sourPath.GetLength() - 1] != SPLIT_SLASH) {
  1342. sourPath += SPLIT_SLASH_STR;
  1343. }
  1344. if (destPath.GetLength() > 0 && destPath[destPath.GetLength() - 1] != SPLIT_SLASH) {
  1345. destPath += SPLIT_SLASH_STR;
  1346. }
  1347. if (Error == Error_Succeed)
  1348. {
  1349. char srcFilePath[MAX_PATH] = { 0 };
  1350. DIR* pDir = NULL;
  1351. struct dirent* pFile = NULL;
  1352. snprintf(srcFilePath, MAX_PATH, "%s*.%s", sourPath, RECORD_MP4_SUFFIX);
  1353. pDir = opendir(sourPath);
  1354. if (pDir == NULL) return ;
  1355. while ((pFile = readdir(pDir)) != NULL) {
  1356. if (pFile->d_type & DT_DIR) {
  1357. continue;
  1358. }
  1359. else {
  1360. if (IsMatchedVideo((LPCSTR)sourPath, pFile)) {
  1361. CSimpleStringA sourFileName = CSimpleStringA::Format("%s%s", (LPCSTR)sourPath, pFile->d_name);
  1362. CSimpleStringA destFileName = CSimpleStringA::Format("%sBAK_%s", (LPCSTR)destPath, pFile->d_name);
  1363. if (rename(sourFileName.GetData(), destFileName.GetData())) {
  1364. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Error Code %lu while move %s.", errno, sourFileName.GetData());
  1365. }
  1366. }
  1367. else {
  1368. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("File (%s) is not matched.", pFile->d_name);
  1369. }
  1370. }
  1371. }
  1372. closedir(pDir);
  1373. }
  1374. }
  1375. #endif
  1376. ErrorCodeEnum CSalesRecorderEntity::SetRecordAudioQuality(int iAudioQuality)
  1377. {
  1378. ErrorCodeEnum eRet = Error_Succeed;
  1379. switch (iAudioQuality)
  1380. {
  1381. case 1:
  1382. m_eAudioOutQuality = eLowDefinition;
  1383. break;
  1384. case 2:
  1385. m_eAudioOutQuality = eStandardDefinition;
  1386. break;
  1387. case 3:
  1388. m_eAudioOutQuality = eHighDefinition;
  1389. break;
  1390. case 4:
  1391. m_eAudioOutQuality = eUltraHD;
  1392. break;
  1393. default:
  1394. m_eAudioOutQuality = eUltraHD;
  1395. break;
  1396. }
  1397. return eRet;
  1398. }
  1399. ErrorCodeEnum CSalesRecorderEntity::SetRecordAudioNsPolicy(int iNsPolicy)
  1400. {
  1401. ErrorCodeEnum eRet = Error_Succeed;
  1402. if (1 == iNsPolicy || 3 == iNsPolicy){
  1403. m_iAudioNsPolicy = iNsPolicy;
  1404. }
  1405. else{
  1406. m_iAudioNsPolicy = 2;
  1407. }
  1408. return eRet;
  1409. }
  1410. ErrorCodeEnum CSalesRecorderEntity::SetRecordAudioChannles(int iAudioChannles)
  1411. {
  1412. ErrorCodeEnum eRet = Error_Succeed;
  1413. m_iAudioChannels = 2;
  1414. return eRet;
  1415. }
  1416. DeviceTypeEnum CSalesRecorderEntity::RvcGetDeviceType()
  1417. {
  1418. DeviceTypeEnum eType = eStand2sType;
  1419. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  1420. CSystemStaticInfo stStaticinfo;
  1421. spFunction->GetSystemStaticInfo(stStaticinfo);
  1422. m_terminalNo = stStaticinfo.strTerminalID;
  1423. if (_stricmp(stStaticinfo.strMachineType, "RVC.Stand1SPlus") == 0) {
  1424. eType = eStand1SPlusType;
  1425. }
  1426. else if (stricmp(stStaticinfo.strMachineType, "RVC.CardStore") == 0 || stricmp(stStaticinfo.strMachineType, "RVC.CardPrinter") == 0) {
  1427. eType = eCardStore;
  1428. }
  1429. else {
  1430. eType = eStand2sType;
  1431. }
  1432. if (eType >= 0 && eType < sizeof(Device_Type_Table) / sizeof(char*)) {
  1433. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("device type is %s.", Device_Type_Table[eType]);
  1434. }
  1435. return eType;
  1436. }
  1437. ErrorCodeEnum CSalesRecorderEntity::AddToSalesRecordList(const char* videopath, const char* strfilename, unsigned long ufilesize)
  1438. {
  1439. ErrorCodeEnum Error = Error_Failed;
  1440. if (NULL == videopath || NULL == strfilename) {
  1441. return Error;
  1442. }
  1443. record_item_t* item = new record_item_t();
  1444. item->file_path = videopath;
  1445. item->file_length = (int)ufilesize;
  1446. item->file_name = strfilename;
  1447. m_vRecordList.push_back(*item);
  1448. Error = Error_Succeed;
  1449. return Error;
  1450. }
  1451. ErrorCodeEnum CSalesRecorderEntity::PostSalesRecordInfos()
  1452. {
  1453. ErrorCodeEnum Error = Error_Failed;
  1454. char strtimenow[MAX_PATH] = { 0 };
  1455. y2k_time_t nowtime = y2k_time_now();
  1456. y2k_to_string(nowtime, strtimenow, MAX_PATH);
  1457. video_record_info_t video_params;
  1458. video_params.strServerURL = m_strHttpServerAddr;
  1459. video_params.strAPI = m_strHttpServerAPI;
  1460. video_params.strAppVersion = m_strAppVersion;
  1461. video_params.strRecordEndTime = strtimenow;
  1462. video_params.strTerminalNo = m_strTerminalId;
  1463. video_params.iBusinessStatus = (int)m_eBusinessStatus;
  1464. if (eFailed == m_eBusinessStatus) {
  1465. if (m_vRecordList.size() > 0) {
  1466. video_params.iBusinessStatus = eInterrupt;
  1467. }
  1468. }
  1469. video_params.strRecordID = m_SalesVideoName + strlen(RVC_SALES_RECORD_SUFFIX);
  1470. for (vector<record_item_t>::iterator it = m_vRecordList.begin(); it < m_vRecordList.end(); ++it) {
  1471. video_params.vRecordList.push_back(*it);
  1472. }
  1473. unsigned int uposttime = 0;
  1474. CSimpleStringA strErrorMsg("");
  1475. if (0 == post_video_recordinfo_list(uposttime, strErrorMsg, &video_params, m_iHttpTimeOut, false)) {
  1476. LogWarn(Severity_Low, Error_Debug, LOG_EVT_POST_SALESRECORD_INFO_COST_TIME, CSimpleStringA::Format("post video record infos cost time is %ums.", uposttime).GetData());
  1477. Error = Error_Succeed;
  1478. }
  1479. else {
  1480. LogWarn(Severity_Middle, Error_Exception, LOG_EVT_POST_SALESRECORD_INFO_FAILED, strErrorMsg.GetData());
  1481. }
  1482. m_vRecordList.clear();
  1483. return Error;
  1484. }
  1485. int CSalesRecorderEntity::HandleEncryptVideoRecord(const char* videofilename)
  1486. {
  1487. int iRet = -1;
  1488. if (NULL == videofilename) {
  1489. return iRet;
  1490. }
  1491. if (!ExistsFile(videofilename)) {
  1492. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("File %s is not exist.", videofilename);
  1493. return iRet;
  1494. }
  1495. filecryption_callback_t cb = { 0 };
  1496. cb.dbg = &rvcDbg;
  1497. char strOutFile[MAX_PATH] = { 0 };
  1498. int iresult = encryption_file(strOutFile, MAX_PATH, videofilename, &cb, eVerB);
  1499. if (0 != iresult) {
  1500. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_SALESRECORD_ENCRYPT_FAILED, CSimpleStringA::Format("encryption file %s failed, delete out temp file %s!", videofilename, strOutFile).GetData());
  1501. if (ExistsFile(strOutFile)) {
  1502. if (!RvcDeleteFile(strOutFile)) {
  1503. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("DeleteFile file %s failed!", strOutFile);
  1504. }
  1505. }
  1506. return iRet;
  1507. }
  1508. bool bRet = RvcDeleteFile(videofilename);
  1509. if (!bRet) {
  1510. #ifdef RVC_OS_WIN
  1511. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_SALESRECORD_DELETE_FAILED, CSimpleStringA::Format("Error Code %lu while delete %s, delete out temp file[%s]!", GetLastError(), videofilename, strOutFile).GetData());
  1512. #else
  1513. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_SALESRECORD_DELETE_FAILED, CSimpleStringA::Format("%s(%d) while delete %s, delete out temp file[%s]!", strerror(errno), errno, videofilename, strOutFile).GetData());
  1514. #endif // RVC_OS_WIN
  1515. if (!RvcDeleteFile(strOutFile)) {
  1516. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("DeleteFile file %s failed!", strOutFile);
  1517. }
  1518. return iRet;
  1519. }
  1520. else {
  1521. if (rvcMoveFile(strOutFile, videofilename)) {
  1522. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("rename %s to %s Success!", strOutFile, videofilename);
  1523. iRet = 0;
  1524. }
  1525. else {
  1526. #ifdef RVC_OS_WIN
  1527. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_SALESRECORD_RENAME_FAILED, CSimpleStringA::Format("Error Code %lu while rename %s.", GetLastError(), strOutFile).GetData());
  1528. #else
  1529. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_SALESRECORD_RENAME_FAILED, CSimpleStringA::Format("%s(%d) while rename %s.", strerror(errno), errno, strOutFile).GetData());
  1530. #endif // RVC_OS_WIN
  1531. }
  1532. }
  1533. #if 0
  1534. char strdecFile[MAX_PATH] = { 0 };
  1535. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("begin decrypt file %s.", videofilename);
  1536. iresult = decryption_file(strdecFile, MAX_PATH, videofilename, &cb, eVerB);
  1537. if (0 == iresult) {
  1538. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("decrypt file %s -> %s success!", videofilename, strdecFile);
  1539. }
  1540. else {
  1541. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("decrypt file %s -> %s failed!", videofilename, strdecFile);
  1542. }
  1543. #endif
  1544. return iRet;
  1545. }
  1546. ErrorCodeEnum CSalesRecorderEntity::SetRecordCamera(int iCamera)
  1547. {
  1548. ErrorCodeEnum Error = Error_Succeed;
  1549. if (CAMERA_TYPE_OPT == iCamera) {
  1550. m_iRecordCamera = CAMERA_TYPE_OPT;
  1551. }
  1552. else {
  1553. m_iRecordCamera = CAMERA_TYPE_ENV;
  1554. }
  1555. return Error;
  1556. }
  1557. ErrorCodeEnum CSalesRecorderEntity::GetEntityConfig()
  1558. {
  1559. ErrorCodeEnum Error = Error_Succeed;
  1560. int iAudioQuality = 3;
  1561. int iAudioNsPolicy = 2;
  1562. int iIsAudioNsOn = 0;
  1563. int iAudioChannels = 1;
  1564. int iLogLevel = 1;
  1565. int iLowestLevel = 1;
  1566. int iTimeOut = RVC_HTTPTIMEOUT;
  1567. CSimpleStringA strHttpServerAddr("");
  1568. int iPostOn = 0;
  1569. m_max_disk_percent = MAX_DISK_PERCENT;
  1570. m_audio_samplerate = 8;
  1571. int iStopEncflag = 0;
  1572. int iRemoteRecordType = 0;
  1573. CSmartPointer<IConfigInfo> spConfig;
  1574. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  1575. if (spFunction->OpenConfig(Config_CenterSetting, spConfig) == Error_Succeed) {
  1576. spConfig->ReadConfigValueInt("SalesRecorder", "MaxDiskPercent", m_max_disk_percent);
  1577. spConfig->ReadConfigValueInt("SalesRecorder", "AudioSampleRate", m_audio_samplerate);
  1578. spConfig->ReadConfigValueInt("SalesRecorder", "AudioBitRate", m_audio_out_bitrate);
  1579. spConfig->ReadConfigValueInt("SalesRecorder", "AudioNsPolicy", iAudioNsPolicy);
  1580. spConfig->ReadConfigValueInt("SalesRecorder", "IsAudioNsOn", iIsAudioNsOn);
  1581. spConfig->ReadConfigValueInt("SalesRecorder", "AudioQuality", iAudioQuality);
  1582. spConfig->ReadConfigValueInt("SalesRecorder", "AudioChannels", iAudioChannels);
  1583. spConfig->ReadConfigValueInt("SalesRecorder", "LogLevel", iLogLevel);
  1584. spConfig->ReadConfigValueInt("SalesRecorder", "LowestLevel", iLowestLevel);
  1585. spConfig->ReadConfigValueInt("SalesRecorder", "post_salesrecord_info_on", iPostOn);
  1586. spConfig->ReadConfigValue("Recorder", "http_video_record_addr", strHttpServerAddr);
  1587. spConfig->ReadConfigValueInt("Recorder", "http_timeout", iTimeOut);
  1588. spConfig->ReadConfigValueInt("SalesRecorder", "stopencflag", iStopEncflag);
  1589. spConfig->ReadConfigValueInt("InteractiveControl", "RemoteRecordType", iRemoteRecordType);
  1590. }
  1591. if (m_max_disk_percent <= 0 || m_max_disk_percent >= 100) {
  1592. m_max_disk_percent = MAX_DISK_PERCENT;
  1593. }
  1594. if (iLogLevel <= RECORD_LOG_ERROR && iLogLevel > 0) {
  1595. m_loglevel = (record_loglevel)iLogLevel;
  1596. }
  1597. if (iLowestLevel <= RECORD_LOG_ERROR && iLowestLevel > 0) {
  1598. m_lowestlevel = (record_loglevel)iLowestLevel;
  1599. }
  1600. if (strHttpServerAddr.GetLength() > 0) {
  1601. m_strHttpServerAddr = strHttpServerAddr;
  1602. }
  1603. if (iTimeOut > 0 && iTimeOut < 20 * RVC_HTTPTIMEOUT) {
  1604. m_iHttpTimeOut = iTimeOut;
  1605. }
  1606. if (1 == iPostOn) {
  1607. m_bPostOn = true;
  1608. }
  1609. SetRecordAudioQuality(iAudioQuality);
  1610. SetRecordAudioNsPolicy(iAudioNsPolicy);
  1611. SetRecordAudioChannles(iAudioChannels);
  1612. if (0 != iIsAudioNsOn) {
  1613. m_bIsAudioNsOn = true;
  1614. }
  1615. if (1 == iStopEncflag) {
  1616. m_bEncFlag = false;
  1617. }
  1618. if (1 == iRemoteRecordType) {
  1619. m_iRemoteRecordType = 1;
  1620. }
  1621. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("m_bEncFlag is %s, m_iRemoteRecordType is %d.", m_bEncFlag ? "true" : "false", m_iRemoteRecordType);
  1622. if (m_bWholeSection != 0 && m_bWholeSection != 1) {
  1623. m_bWholeSection = false;
  1624. }
  1625. return Error;
  1626. }
  1627. SP_BEGIN_ENTITY_MAP()
  1628. SP_ENTITY(CSalesRecorderEntity)
  1629. SP_END_ENTITY_MAP()