mod_SalesRecorder.cpp 50 KB

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