hspscannerimpl.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. #include "hspscannerimpl.h"
  2. #include "SSocket.h"
  3. #define ERR_NO_DEVICE -1
  4. #define ERR_NOT_OPENED -2
  5. #define ERR_OPEN_FAIL -3
  6. #define ERR_VIEW_FAIL -4
  7. #define ERR_DEVICE_CHG -5
  8. /////////////////////////////////////////////////////////////////////
  9. HSPSClassImpl::HSPSClassImpl()
  10. {
  11. m_sLibPath[0] = 0;
  12. m_bIsOpen = false;
  13. HSPSCall = NULL;
  14. m_hThreadID = 0;
  15. m_bThreadExit = true;
  16. }
  17. HSPSClassImpl::~HSPSClassImpl()
  18. {
  19. if (m_hThreadID)
  20. {
  21. m_bThreadExit = true;
  22. Sleep(100);
  23. }
  24. }
  25. ErrorCodeEnum HSPSClassImpl::DevOpen()
  26. {
  27. LOG4VTM_FUNCTION();
  28. GetCurLibsPath(m_sLibPath, NULL);
  29. char sTemp[400];
  30. if (HSPSCall == NULL)
  31. {
  32. sprintf(sTemp, "%s/cw/libCmbServConn.cw.so", m_sLibPath);
  33. void *hlib = dlopen(sTemp, RTLD_LAZY); //load so
  34. if(hlib == NULL)
  35. {
  36. printf("dlopen - %sn", dlerror());
  37. return GetErrorInfo(ERR_NO_DEVICE, "DevOpen");
  38. }
  39. HSPSCall = (pHSPSCall)dlsym(hlib, "HSPSCall");
  40. }
  41. Sleep(200);
  42. if (m_hThreadID == 0)
  43. {
  44. m_bThreadExit = false;
  45. StartTimer();
  46. }
  47. int iRet = 0;
  48. if (HSPSCall("H 0 0", 0, iRet) < 0)
  49. return GetErrorInfo(ERR_NO_DEVICE, "DevOpen connect fail");
  50. if (iRet == ERR_DEVICE_CHG)//重插后摄像头编码变化,目前只能重新启动进程
  51. {
  52. LOG4VTM(INFO, "DevOpen camera need reconnected");
  53. system("killall CmbService.cw");
  54. Sleep(500);
  55. if (HSPSCall("H 0 2", 0, iRet) < 0)
  56. return GetErrorInfo(ERR_NO_DEVICE, "DevOpen camera reopen fail");
  57. }
  58. if (iRet == 0)
  59. m_bIsOpen = true;
  60. return GetErrorInfo(iRet, "DevOpen");
  61. }
  62. int getFileVer(char* sFile, short& ch1, short& ch2)
  63. {
  64. ch1 = 0;
  65. ch2 = 0;
  66. char* pFind = strstr(sFile, ".so");
  67. char* pTemp = pFind;
  68. while (pTemp)
  69. {
  70. pFind = pTemp;
  71. pTemp = strstr(pFind + 3, ".so");
  72. }
  73. if (pFind == NULL) return 0;
  74. pTemp = pFind - 1;
  75. while(isdigit(*pTemp) && pTemp > sFile) pTemp--;
  76. if (*pTemp == '.')
  77. ch2 = atoi(pTemp+1);
  78. pTemp--;
  79. while(isdigit(*pTemp) && pTemp > sFile) pTemp--;
  80. if (*pTemp == '.')
  81. ch1 = atoi(pTemp+1);
  82. return 1;
  83. }
  84. ErrorCodeEnum HSPSClassImpl::GetDevCategory(DevCategoryInfo &devCategory)
  85. {
  86. LOG4VTM_FUNCTION();
  87. if (!m_bIsOpen)
  88. return GetErrorInfo(ERR_NOT_OPENED, "GetDevCategory");
  89. memset(&devCategory, 0, sizeof(devCategory));
  90. strcpy(devCategory.szModel , "FWID=00000000");
  91. strcpy(devCategory.szVendor , "cw");
  92. strcpy(devCategory.szType ,"PVER=LHT#MID=5M01");
  93. char sPath[256], sFile[128] = {0};
  94. GetCurLibsPath(sPath, sFile);
  95. short v1,v2;
  96. getFileVer(sFile, v1, v2);
  97. devCategory.version.wMajor = v1;
  98. devCategory.version.wMinor = v2;
  99. devCategory.version.wRevision = 0xffff;
  100. devCategory.version.wBuild = FILE_VERSION;
  101. int iRet = 0;
  102. if (HSPSCall("H 3 0", 0, iRet) == 0 && iRet >= 0)
  103. devCategory.eState = DEVICE_STATUS_NORMAL;
  104. else
  105. return GetErrorInfo(ERR_NOT_OPENED, "GetDevCategory");
  106. // devCategory.eState = DEVICE_STATUS_NOT_READY;
  107. return Error_Succeed;
  108. }
  109. ErrorCodeEnum HSPSClassImpl::Reset()
  110. {
  111. LOG4VTM_FUNCTION();
  112. if (!m_bIsOpen)
  113. return GetErrorInfo(ERR_NOT_OPENED, "Reset");
  114. int iRet = 0;
  115. return GetErrorInfo(iRet, "Reset");
  116. }
  117. ErrorCodeEnum HSPSClassImpl::DevClose()
  118. {
  119. LOG4VTM_FUNCTION();
  120. int iRet = 0;
  121. HSPSCall("H 0 1", 0, iRet);
  122. Sleep(50);
  123. return Error_Succeed;
  124. }
  125. ErrorCodeEnum HSPSClassImpl::GetLastErr(DevErrorInfo &devErrInfo)
  126. {
  127. memcpy(&devErrInfo, &m_DevErrInfo, sizeof(DevErrorInfo));
  128. return Error_Succeed;
  129. }
  130. ErrorCodeEnum HSPSClassImpl::SetParam(ParamType type, ParamTypeValue value)
  131. {
  132. LOG4VTM_FUNCTION();
  133. if (!m_bIsOpen)
  134. return GetErrorInfo(ERR_NOT_OPENED, "SetParam");
  135. char sCmd[64];
  136. sprintf(sCmd, "SetParam type=%d val=%d", type, value);
  137. LOG4VTM(INFO, sCmd);
  138. switch(type){
  139. case HSPS_MODEL_COLOR:
  140. sprintf(sCmd, "H 2 2 %d", (value == HSPS_COLOR_GREY));
  141. break;
  142. case HSPS_MODEL_ROTATE:
  143. sprintf(sCmd, "H 2 3 %d", value - HSPS_ROTATE_NOANGLE);
  144. break;
  145. case HSPS_MODEL_SCANSIZE:
  146. sprintf(sCmd, "H 2 4 %d", value - HSPS_SCAN_FULL);
  147. break;
  148. case HSPS_MODEL_VIEW:
  149. sprintf(sCmd, "H 2 1 %d", (value == HSPS_VIEW_SHOW));
  150. }
  151. int iRet = 0;
  152. if (HSPSCall(sCmd, 0, iRet) < 0)
  153. return GetErrorInfo(ERR_NOT_OPENED, "SetParam");
  154. return Error_Succeed;
  155. }
  156. // 更新20161117: nValue值为 1 时打开预览,确保当前打开预览过程执行结束且窗口处于显示状态才返回Error_Succeed,
  157. // nValue值为 0 时关闭预览并隐藏窗口
  158. ErrorCodeEnum HSPSClassImpl::SetPreview(short nValue)
  159. {
  160. LOG4VTM_FUNCTION();
  161. Sleep(100);
  162. if (!m_bIsOpen)
  163. return GetErrorInfo(ERR_NOT_OPENED, "SetPreview not open");
  164. int iRet = 0;
  165. if (nValue == 1)
  166. {
  167. //预览,打开摄像头
  168. if (HSPSCall("H 2 0 1", 0, iRet) < 0)
  169. return GetErrorInfo(ERR_NOT_OPENED, "SetPreview connect fail");
  170. if (iRet == ERR_DEVICE_CHG)//重插后摄像头编码变化,目前只能重新启动进程
  171. {
  172. LOG4VTM(INFO, "SetPreview camera need reconnected");
  173. system("killall CmbService.cw");
  174. Sleep(400);
  175. if (HSPSCall("H 0 2", 0, iRet) < 0)
  176. return GetErrorInfo(ERR_NO_DEVICE, "SetPreview camera reopen fail");
  177. if (iRet != 0)
  178. return GetErrorInfo(ERR_NO_DEVICE, "SetPreview camera reopen %d", iRet);
  179. if (HSPSCall("H 2 0 2", 0, iRet) < 0) //预览,恢复保存的参数
  180. return GetErrorInfo(ERR_NOT_OPENED, "SetPreview camera review fail");
  181. }
  182. if (iRet != 0)
  183. return GetErrorInfo(ERR_NOT_OPENED, "SetPreview opencam %d", iRet);
  184. //显示界面
  185. HSPSCall("H 2 1 1", 0, iRet);
  186. // Sleep(2000);
  187. }
  188. else
  189. {
  190. int iOK = HSPSCall("H 2 0 0", 0, iRet);
  191. HSPSCall("H 2 1 0", 0, iRet);
  192. if (iOK < 0)
  193. return GetErrorInfo(ERR_NOT_OPENED, "SetPreview openwin");
  194. }
  195. return GetErrorInfo(iRet, "SetPreview");
  196. }
  197. // specifies that where the image will be located and what it would be named.
  198. // 拍摄照片,传入的文件名已带绝对路径,无需再进行拼接处理
  199. //
  200. ErrorCodeEnum HSPSClassImpl::ScanImage(const char* pszFileName)
  201. {
  202. LOG4VTM_FUNCTION();
  203. if (!m_bIsOpen)
  204. return GetErrorInfo(ERR_NOT_OPENED, "ScanImage");
  205. int iRet = 0;
  206. if (HSPSCall("H 3 2", 0, iRet) < 0 || iRet != 1)
  207. return GetErrorInfo(ERR_NOT_OPENED, "ScanImage");
  208. char sSend[300];
  209. strcpy(sSend, "H 4 ");
  210. strcat(sSend, pszFileName);
  211. HSPSCall(sSend, 0, iRet);
  212. return GetErrorInfo(iRet, "ScanImage");
  213. }
  214. // Scan Image from device and return the image data in byte format.
  215. // -pBtImg[out] The buffer used to store the scanned image data.
  216. // 存储图片字节流的缓冲区,大小为 nBtLen 字节
  217. // -nBtLen[in,out] Indicate the max byte-type size of pBtImg could be stored
  218. // and Store the real byte-type size of pBtImg had used when returned.
  219. // when detect value of nBtLen is 0 or smaller that necessary size, please
  220. // set nBtlen with real byte-type size and return Error_TooSmallBuffer.
  221. // 如果nBtLen指定的字节数过小,那么对nBtLen赋值实际所需的大小并返回 Error_TooSmallBuffer,此操作仅允许一次
  222. // -pszFileName[in] Store the path and name where the image file should be located
  223. // while "" indicates that the image file shouldn't be stored at locate.
  224. // 文件名长度为零表示不在本地生成图片文件
  225. ErrorCodeEnum HSPSClassImpl::ScanImageEx(BYTE* pBtImg, int& nBtLen, const char* pszFileName)
  226. {
  227. LOG4VTM_FUNCTION();
  228. if (!m_bIsOpen)
  229. return GetErrorInfo(ERR_NOT_OPENED, "ScanImage");
  230. int iRet = 0;
  231. if (HSPSCall("H 3 2", 0, iRet) < 0 || iRet != 1)
  232. return GetErrorInfo(ERR_NOT_OPENED, "ScanImage");
  233. char sSend[300];
  234. strcpy(sSend, "H 4 ");
  235. bool bFile = false;
  236. if (strlen(pszFileName))
  237. {
  238. strcpy(sSend + 4, pszFileName);
  239. bFile = true;
  240. }
  241. else
  242. sprintf(sSend + 4, "%s/hsps-temp.jpg", m_sLibPath);
  243. HSPSCall(sSend, 0, iRet);
  244. ErrorCodeEnum eRet = Error_Succeed;
  245. if (iRet != 0)
  246. return GetErrorInfo(iRet, "ScanImageEx");
  247. FILE* fp = fopen(sSend + 4, "rb");
  248. if (fp == NULL)
  249. return GetErrorInfo(Error_Param, "ScanImageEx");
  250. fseek(fp, 0, SEEK_END);
  251. int iLen = ftell(fp);
  252. if (pBtImg && iLen < nBtLen)
  253. {
  254. fseek(fp, 0, SEEK_SET);
  255. fread(pBtImg, 1, iLen, fp);
  256. nBtLen = iLen;
  257. }
  258. else
  259. {
  260. eRet = Error_TooSmallBuffer;
  261. nBtLen = iLen*1.2;//照片会动态变化,大概率出现下次拍照更大
  262. }
  263. fclose(fp);
  264. if (!bFile) remove(sSend + 4);
  265. return eRet;
  266. }
  267. // 传入预览窗口显示的坐标,左上角的横坐标nX,左上角的纵坐标nY,以及预览窗口的宽,宽与高的比例为 16:9
  268. ErrorCodeEnum HSPSClassImpl::SetViewPos(int nX, int nY, int nWidth)
  269. {
  270. LOG4VTM_FUNCTION();
  271. int iRet = 0;
  272. char sSend[32];
  273. sprintf(sSend, "H 1 %d %d %d %d", nX, nY, nWidth, nWidth*9/16);
  274. LOG4VTM(INFO, sSend);
  275. if (HSPSCall(sSend, 0, iRet) < 0)
  276. return GetErrorInfo(ERR_NOT_OPENED, "SetViewPos");
  277. return Error_Succeed;
  278. }
  279. ErrorCodeEnum HSPSClassImpl::GetDevStatus(HspsDevStatus& status)
  280. {
  281. LOG4VTM_FUNCTION();
  282. int iRet = 0;
  283. if (HSPSCall("H 3 4", 0, iRet) < 0)
  284. return GetErrorInfo(ERR_NOT_OPENED, "ScanImage");
  285. status.isConnected = (iRet & 4) > 0;
  286. status.inPreview = (iRet & 2) > 0;
  287. status.inShow = (iRet & 1) == 0;
  288. return Error_Succeed;
  289. }
  290. /////////////////////////////////////////////////////////////////////////////
  291. // DEC_SUCCESS DEC_HARDWARE DEC_TIMEOUT DEC_INVALID_PARAMETER DEC_INVALID_MASTER_KEY
  292. const static CmbErrorDef HSPSErrInfo[] = {
  293. {0, "命令执行成功", Error_Succeed, DEC_SUCCESS},
  294. {ERR_NO_DEVICE, "未发现设备", Error_Hardware, DEC_DEV_NOT_FOUND},
  295. {ERR_NOT_OPENED, "设备尚未打开", Error_Param, DEC_DEV_NOT_OPENED},
  296. {ERR_OPEN_FAIL, "设备打开失败", Error_Hardware, DEC_HARDWARE},
  297. {ERR_VIEW_FAIL, "启动预览失败", Error_Hardware, DEC_HARDWARE},
  298. };
  299. ErrorCodeEnum HSPSClassImpl::GetErrorInfo(int iCode, char* sErr, ...)
  300. {
  301. size_t iLenOne = sizeof(CmbErrorDef);
  302. size_t iLenAll = sizeof(HSPSErrInfo);
  303. int iCount = iLenAll / iLenOne;
  304. char sErrInfo[256]="";
  305. DWORD dSta = 0;
  306. int iErr = -1;
  307. for (int ia = 0; ia < iCount; ia++)
  308. {
  309. if (HSPSErrInfo[ia].iCode == iCode)
  310. {
  311. dSta = HSPSErrInfo[ia].iInf;
  312. strcpy(sErrInfo, HSPSErrInfo[ia].sInf);
  313. iErr = HSPSErrInfo[ia].iRet;
  314. break;
  315. }
  316. }
  317. char sErrAll[300];
  318. va_list arglist;
  319. va_start(arglist, sErr);
  320. _vsnprintf(sErrAll, 128, sErr, arglist);
  321. va_end(arglist);
  322. if (sErrInfo[0])
  323. {
  324. strcat(sErrAll, " ");
  325. strcat(sErrAll, sErrInfo);
  326. }
  327. sErrAll[200] = 0;
  328. iLenOne = strlen(sErrAll);
  329. sprintf(m_DevErrInfo.szErrMsg, "{\"ErrCode\":\"%04x\",\"Description\":\"%s\"}", iErr, sErrAll);
  330. // strcpy(m_DevErrInfo.szErrMsg, sErrAll);
  331. m_DevErrInfo.dwErrMsgLen = ((dSta << 16) & 0xffff0000) + iLenOne;
  332. if (iErr != Error_Succeed)
  333. LOG4VTM(WARN, m_DevErrInfo.szErrMsg);
  334. else
  335. LOG4VTM(INFO, m_DevErrInfo.szErrMsg);
  336. return (ErrorCodeEnum)iErr;
  337. }
  338. void HSPSClassImpl::ThreadRun()
  339. {
  340. HspsState* pBuf = (HspsState*) m_ShereMem.GetShareMem();
  341. while (1)
  342. {
  343. Sleep(50);
  344. if (m_bThreadExit) break;
  345. Sleep(50);
  346. if (m_bThreadExit) break;
  347. pBuf->iTime = GetSystemTime();
  348. }
  349. }
  350. void HSPSClassImpl::StartTimer()
  351. {
  352. pthread_attr_t attr;
  353. pthread_attr_init(&attr);
  354. pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
  355. pthread_create(&m_hThreadID, &attr, Proc, (void*) this);
  356. pthread_attr_destroy(&attr);
  357. }
  358. void* HSPSClassImpl::Proc(void* inPara)
  359. {
  360. HSPSClassImpl* pCtrl = (HSPSClassImpl*)inPara;
  361. pCtrl->ThreadRun();
  362. pCtrl->CloseThread(pCtrl->m_hThreadID);
  363. return 0;
  364. }
  365. void HSPSClassImpl::CloseThread(pthread_t& h)
  366. {
  367. pthread_exit(0);
  368. m_hThreadID = 0;
  369. }