mod_SalesRecorder.cpp 53 KB

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