mod_SalesRecorder.cpp 53 KB

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