Module_Payment.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. /*
  2. * Module_Payment.c
  3. *
  4. * Created on: 2021/03/24
  5. * Author: Henry Yeh
  6. */
  7. #include "Module_Payment.h"
  8. unsigned char version[] = {'D', '0', '.', '0', '1'};
  9. unsigned char CMD_C8[30] = {0xc8,0x01, // Activate the reader
  10. 0x9f,0x02,0x06,0x00,0x00,0x00,0x01,0x00,0x00, // Amount, Authorized, sample: 100.00 dollar
  11. 0x5f,0x2a,0x02,0x08,0x40, // Transaction Currency Code follow ISO-4217, sample: 0840(USD)
  12. 0x9c,0x01,0x00, // Transaction Type, sample: 00
  13. 0x9a,0x03,0x21,0x03,0x24, // Transaction Date, sample: 2021/03/24
  14. 0x9f,0x21,0x03,0x13,0x36,0x10 }; // Transaction Time, sample: 13:36:10
  15. unsigned char CMD_CARD_DETECT[11] = {0x09, 0, 0x07, 'M','F','1','4','1','2','1', 0x32}; // Enable payment, MIFARE, 15693 card; Detect Payment Card First; Enable ApplePay VAS
  16. unsigned char CMD_USI2[7] = {0x09, 0, 0x03, 'P', 'C', '0', 0x29}; // Configure protocol to USI2
  17. unsigned char CMD_SET_BAUD[7] = {0x09, 0, 0x03, 'B', 'R', '7', 0x2d}; // Configure module baud rate to 115200
  18. unsigned char CMD_RESTORE_DEFAULT[7] = {0x09, 0, 0x03, 'D', 'F', 0, 0x08 }; // Restore module configuration to default setting
  19. int system_command(int uart, unsigned char* cmd, int cmd_len, unsigned char* rx);
  20. int USI2_Parse(unsigned char* rx, unsigned char* rx_data);
  21. struct C9_RESULT
  22. {
  23. unsigned char result_data[512];
  24. unsigned char status;
  25. unsigned char pos_entry;
  26. unsigned char u_id[20];
  27. unsigned char tkData[4][128];
  28. } C9_Result;
  29. //==========================================
  30. // Common routine
  31. //==========================================
  32. int StoreLogMsg(const char *fmt, ...)
  33. {
  34. char Buf[65536+256];
  35. char buffer[65536];
  36. //char Buf[4096+256];
  37. //char buffer[4096];
  38. time_t CurrentTime;
  39. struct tm *tm;
  40. struct timeval tv;
  41. va_list args;
  42. va_start(args, fmt);
  43. int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
  44. va_end(args);
  45. memset(Buf,0,sizeof(Buf));
  46. CurrentTime = time(NULL);
  47. tm=localtime(&CurrentTime);
  48. gettimeofday(&tv, NULL); // get microseconds, 10^-6
  49. sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]PaymentLog",
  50. tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec,
  51. buffer,
  52. tm->tm_year+1900,tm->tm_mon+1);
  53. system((const char*)Buf);
  54. #ifdef ConsloePrintLog
  55. printf("[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer);
  56. #endif
  57. return rc;
  58. }
  59. /**
  60. * Execute shell command
  61. * @param cmd: shell command string
  62. * @return shell command execution result
  63. */
  64. int runShellCmd(const char*cmd)
  65. {
  66. int result = FAIL;
  67. char buf[256];
  68. FILE *fp;
  69. fp = popen(cmd, "r");
  70. if(fp != NULL)
  71. {
  72. while(fgets(buf, sizeof(buf), fp) != NULL)
  73. {
  74. DEBUG_INFO("%s\n", buf);
  75. }
  76. result = PASS;
  77. }
  78. pclose(fp);
  79. return result;
  80. }
  81. /**
  82. * Calculate time differential
  83. * @param ST: start time
  84. * @param ET: end time
  85. * @return time differential in million seconds
  86. */
  87. int DiffTimeb(struct timeb ST, struct timeb ET)
  88. {
  89. //return milli-second
  90. unsigned int StartTime,StopTime;
  91. StartTime=(unsigned int)ST.time;
  92. StopTime=(unsigned int)ET.time;
  93. return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
  94. }
  95. /**
  96. * Show communication raw data to debug info
  97. * @param data: raw data
  98. * @param len: data length
  99. * @param isRX: is receive data
  100. */
  101. void show_raw(uint8_t *data, uint16_t len, uint8_t isRX)
  102. {
  103. uint8_t output[8192];
  104. memset(output, 0x00, ARRAY_SIZE(output));
  105. sprintf((char*)output, "%s", (isRX?"RX: ":"TX: "));
  106. for(uint16_t idx = 0;idx<len;idx++)
  107. {
  108. sprintf((char*)output, "%s%02x ", output, data[idx]);
  109. }
  110. DEBUG_INFO("%s\n", output);
  111. }
  112. /**
  113. * Show data to debug info
  114. * @param dat: data content
  115. * @param len: data length
  116. */
  117. void show_data(unsigned char *dat, unsigned int len)
  118. {
  119. uint8_t output[8192];
  120. memset(output, 0x00, ARRAY_SIZE(output));
  121. sprintf((char*)output, "Data: ");
  122. for(uint16_t idx = 0;idx<len;idx++)
  123. {
  124. if(dat[idx] > 31 && dat[idx] < 128 )
  125. sprintf((char*)output, "%s%c", output, dat[idx]);
  126. else
  127. sprintf((char*)output, "%s<%x>", output, dat[idx]);
  128. }
  129. DEBUG_INFO("%s\n", output);
  130. }
  131. /**
  132. * Get sentinel quantity in data array
  133. * @param data: message array address
  134. * @param dataLen: array seek size
  135. * @return how many sentinel flag found
  136. */
  137. int getSentinelQuantity(unsigned char *data, unsigned int dataLen)
  138. {
  139. int result = 0;
  140. for(uint16_t idx=0;idx<dataLen;idx++)
  141. {
  142. if(data[idx] == '?')
  143. result++;
  144. }
  145. return result;
  146. }
  147. /**
  148. * Get sentinel position in array
  149. * @param data: message array address
  150. * @param dataLen: array seek size
  151. * @param idxSentinel: which sentinel idx want to find, since 0 start
  152. * @return sentinel position in array
  153. */
  154. int getSentinelPosition(unsigned char *data, unsigned int dataLen, unsigned char idxSentinel)
  155. {
  156. int result = -1;
  157. int foundCnt = -1;
  158. for(uint16_t idx=0;idx<dataLen;idx++)
  159. {
  160. if(data[idx] == '?')
  161. foundCnt++;
  162. if(foundCnt == idxSentinel)
  163. {
  164. result = idx;
  165. break;
  166. }
  167. }
  168. return result;
  169. }
  170. //==========================================
  171. // Init share memory
  172. //==========================================
  173. /**
  174. * Share memory initialization
  175. * @return function result
  176. */
  177. int InitShareMemory()
  178. {
  179. int result = PASS;
  180. int MeterSMId;
  181. //init ShmSysConfigAndInfo
  182. if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
  183. {
  184. DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
  185. result = FAIL;
  186. }
  187. else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  188. {
  189. DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
  190. result = FAIL;
  191. }
  192. else
  193. {}
  194. //init ShmStatusCodeData
  195. if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
  196. {
  197. DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
  198. result = FAIL;
  199. }
  200. else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  201. {
  202. DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
  203. result = FAIL;
  204. }
  205. else
  206. {}
  207. return result;
  208. }
  209. //==========================================
  210. // Init com port
  211. //==========================================
  212. /**
  213. * TTY port initialization
  214. * @return port initial result
  215. */
  216. int InitComPort()
  217. {
  218. int fd;
  219. struct termios tios;
  220. fd = open("/dev/ttyS3", O_RDWR);
  221. if(fd<=0)
  222. {
  223. return FAIL;
  224. }
  225. ioctl (fd, TCGETS, &tios);
  226. tios.c_cflag = B9600| CS8 | CLOCAL | CREAD;
  227. tios.c_lflag = 0;
  228. tios.c_iflag = 0;
  229. tios.c_oflag = 0;
  230. tios.c_cc[VMIN]=0;
  231. tios.c_cc[VTIME]=(unsigned char)5; // timeout 0.5 seconds
  232. tios.c_lflag=0;
  233. tcflush(fd, TCIFLUSH);
  234. ioctl (fd, TCSETS, &tios);
  235. return fd;
  236. }
  237. /**
  238. * Send command to UIC680fg module.
  239. * @param uart: port handle
  240. * @param cmd: command buffer
  241. * @param cmd_len: command length
  242. * @param rx: receive buffer
  243. * @return receive data length
  244. */
  245. int system_command(int uart, unsigned char* cmd, int cmd_len, unsigned char* rx)
  246. {
  247. int rx_len = 0;
  248. tcflush(uart,TCIOFLUSH);
  249. show_raw(cmd, cmd_len, NO);
  250. if(write(uart, cmd, cmd_len) > 0)
  251. {
  252. /*
  253. * TODO: Improve sleep time.
  254. */
  255. usleep(1000000);
  256. rx_len = read(uart, rx, 512);
  257. show_raw(rx, rx_len, YES);
  258. }
  259. else
  260. {
  261. DEBUG_ERROR("system command write fail.\n");
  262. }
  263. return rx_len;
  264. }
  265. /**
  266. * Parsing raw data to USI data
  267. * @param rx: raw data
  268. * @param rx_data: parsing result data
  269. * @return parsing result data length
  270. */
  271. int USI2_Parse(unsigned char* rx, unsigned char* rx_data)
  272. {
  273. int result = -1;
  274. unsigned int data_len =0;
  275. unsigned int chksum = 0;
  276. if(rx[0] == SOH) // SOH = 0x01
  277. {
  278. data_len = (unsigned int)rx[2] <<8;
  279. data_len |= rx[3];
  280. for(int idx=0;idx<(data_len+4);idx++)
  281. {
  282. chksum ^= rx[idx];
  283. }
  284. if((chksum&0xff) == rx[(data_len+4)])
  285. {
  286. memcpy(rx_data, &rx[4], data_len);
  287. result = data_len;
  288. }
  289. }
  290. else
  291. {
  292. DEBUG_WARN("USI2 message header is not <01>.\n");
  293. }
  294. return result;
  295. }
  296. //==========================================
  297. // Main loop
  298. //==========================================
  299. int main(void)
  300. {
  301. int UartFd;
  302. uint16_t failCount = 0;
  303. unsigned char rx_Array[512]={0}, rx_Data[512]={0};
  304. char C8_Polling = true;
  305. char Wait_C9 = false;
  306. int rx_len = 0;
  307. int data_len = 0;
  308. DEBUG_INFO("Task version: %s\n", version);
  309. //===============================================
  310. // Initialization
  311. //===============================================
  312. if(InitShareMemory() == FAIL)
  313. {
  314. DEBUG_ERROR("InitShareMemory NG\n");
  315. if(ShmStatusCodeData!=NULL)
  316. {
  317. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
  318. }
  319. sleep(5);
  320. return FAIL;
  321. }
  322. UartFd=InitComPort();
  323. if(UartFd<0)
  324. {
  325. DEBUG_ERROR("InitComPort NG\n");
  326. if(ShmStatusCodeData!=NULL)
  327. {
  328. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed=1;
  329. }
  330. sleep(5);
  331. return FAIL;
  332. }
  333. else
  334. {
  335. DEBUG_INFO("ttyS3 port open success.\n");
  336. }
  337. //===============================================
  338. // Payment module configuration set to default.
  339. //===============================================
  340. do
  341. {
  342. rx_len = system_command(UartFd, CMD_RESTORE_DEFAULT, ARRAY_SIZE(CMD_RESTORE_DEFAULT), rx_Array);
  343. if((rx_Array[0] == ACK) && (rx_len ==1))
  344. {
  345. DEBUG_INFO("Set to the default success.\n");
  346. failCount = 0;
  347. }
  348. else
  349. {
  350. DEBUG_WARN("Set to the default fail (<%02x>).\n", rx_Array[0]);
  351. failCount++;
  352. }
  353. if(failCount > RETRY_LIMIT)
  354. {
  355. DEBUG_ERROR("Set to the default fail over retry limit.\n");
  356. return FAIL;
  357. }
  358. }while((rx_Array[0] != ACK) || (rx_len !=1));
  359. //===============================================
  360. // set payment card detect type.
  361. //===============================================
  362. do
  363. {
  364. rx_len = system_command(UartFd, CMD_CARD_DETECT, ARRAY_SIZE(CMD_CARD_DETECT), rx_Array);
  365. if((rx_Array[0] == ACK) && (rx_len ==1))
  366. {
  367. DEBUG_INFO("Set payment card type success.\n");
  368. failCount = 0;
  369. }
  370. else
  371. {
  372. DEBUG_WARN("Set payment card type fail (<%02x>).\n", rx_Array[0]);
  373. failCount++;
  374. }
  375. if(failCount > RETRY_LIMIT)
  376. {
  377. DEBUG_ERROR("Set payment card type fail over retry limit.\n");
  378. return FAIL;
  379. }
  380. }while((rx_Array[0] != ACK) || (rx_len !=1));
  381. //===============================================
  382. // set to protocol_2
  383. //===============================================
  384. do
  385. {
  386. rx_len =system_command(UartFd, CMD_USI2, ARRAY_SIZE(CMD_USI2), rx_Array);
  387. if((rx_Array[0] == ACK) && (rx_len ==1))
  388. {
  389. DEBUG_INFO("Set protocol to USI2 success.\n");
  390. failCount = 0;
  391. }
  392. else
  393. {
  394. DEBUG_WARN("Set protocol to USI2 fail (<%02x>).\n", rx_Array[0]);
  395. failCount++;
  396. }
  397. if(failCount > RETRY_LIMIT)
  398. {
  399. DEBUG_ERROR("Set protocol to USI2 fail over retry limit.\n");
  400. return FAIL;
  401. }
  402. }while((rx_Array[0] != ACK) || (rx_len !=1));
  403. //===============================================
  404. // Main loop
  405. //===============================================
  406. for(;;)
  407. {
  408. if(C8_Polling == true)
  409. {
  410. Wait_C9 = false;
  411. /*
  412. * TODO:
  413. * 1. C8 parameter configure
  414. */
  415. rx_len =system_command(UartFd, CMD_C8, sizeof(CMD_C8), rx_Array);
  416. if((rx_Array[0] == ACK) && (rx_len ==1))
  417. {
  418. DEBUG_INFO("Polling C8 command get response.\n");
  419. Wait_C9 = true;
  420. failCount = 0;
  421. }
  422. if(Wait_C9 == true)
  423. {
  424. //=============================================
  425. // wait card to attach the reader and wait C9
  426. //=============================================
  427. tcflush(UartFd,TCIOFLUSH);
  428. memset(rx_Array, 0x00, ARRAY_SIZE(rx_Array));
  429. rx_len = 0;
  430. do
  431. {
  432. sleep(1);
  433. rx_len = read(UartFd, rx_Array, ARRAY_SIZE(rx_Array)); // read response if data count match 512 or timeout.
  434. failCount++;
  435. } while ((rx_len == 0) && (failCount < RETRY_LIMIT));
  436. //=============================================
  437. // Parse rx_Array to rx_Data
  438. //=============================================
  439. if((rx_len > 3) && (failCount < RETRY_LIMIT))
  440. {
  441. // print this raw data before parse it.
  442. show_data(rx_Array, rx_len);
  443. rx_len = USI2_Parse( rx_Array, rx_Data);
  444. if(rx_len > 0)
  445. {
  446. // debug the input data message
  447. show_data(rx_Data, rx_len);
  448. // Copy RAW data to structure
  449. memcpy(&C9_Result.result_data, rx_Data, rx_len);
  450. C9_Result.status = C9_Result.result_data[1];
  451. C9_Result.pos_entry = C9_Result.result_data[2];
  452. switch(C9_Result.pos_entry)
  453. {
  454. case VISA_qVSDC:
  455. case VISA_MSD:
  456. case MASTER_MChip:
  457. case Master_MagStripe:
  458. case AMEX_EMV:
  459. case AMEX_MSD:
  460. memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
  461. memcpy(C9_Result.u_id, &C9_Result.result_data[4], 16);
  462. DEBUG_INFO("Credit card SN:\n");
  463. show_data(C9_Result.u_id, 16);
  464. DEBUG_INFO("Payment card\n");
  465. for(uint8_t idx=0;idx<getSentinelQuantity(C9_Result.result_data, rx_len);idx++)
  466. {
  467. memset(C9_Result.tkData[idx], 0x00, ARRAY_SIZE(C9_Result.tkData[idx]));
  468. memcpy(C9_Result.tkData[idx],
  469. &C9_Result.result_data[((idx==0)?3:getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2)],
  470. (idx==0?getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-3+1:getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2+1));
  471. DEBUG_INFO("TK[%d]: \n", idx);
  472. show_data(C9_Result.tkData[idx], getSentinelPosition(C9_Result.tkData[idx], ARRAY_SIZE(C9_Result.tkData[idx]), 0)+2);
  473. }
  474. break;
  475. case Mifare:
  476. data_len = C9_Result.result_data[6];
  477. memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
  478. memcpy(C9_Result.u_id, &C9_Result.result_data[7], data_len);
  479. switch(C9_Result.result_data[3])
  480. {
  481. case MIFARE_ULTRALIGHT:
  482. DEBUG_INFO("MIFARE Ultralight, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6]);
  483. break;
  484. case MIFARE_CLASSIC_1K:
  485. DEBUG_INFO("MIFARE Classic 1K, UID: %02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3]);
  486. break;
  487. case MIFARE_CLASSIC_4K:
  488. DEBUG_INFO("MIFARE Classic 4K, UID: %02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3]);
  489. break;
  490. case MIFARE_DESFIRE:
  491. DEBUG_INFO("MIFARE DESFire, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6]);
  492. break;
  493. case MIFARE_PLUS_2K:
  494. DEBUG_INFO("MIFARE Plus 2k, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6]);
  495. break;
  496. case MIFARE_MINI:
  497. DEBUG_INFO("MIFARE Mini, UID: %02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3]);
  498. break;
  499. case MIFARE_RESERVE:
  500. DEBUG_INFO("MIFARE Reserve, UID: \n");
  501. break;
  502. case MIFARE_JEWEL:
  503. DEBUG_INFO("MIFARE Jewel, UID: \n");
  504. break;
  505. case MIFARE_JCOP31:
  506. DEBUG_INFO("MIFARE JCOP31, UID: \n");
  507. break;
  508. }
  509. break;
  510. case ISO_15693:
  511. data_len =(C9_Result.result_data[5]<<8) | C9_Result.result_data[6];
  512. memset(C9_Result.u_id, 0x00, ARRAY_SIZE(C9_Result.u_id));
  513. memcpy(C9_Result.u_id, &C9_Result.result_data[4+data_len-8], 8);
  514. DEBUG_INFO("ISO_15693, UID: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", C9_Result.u_id[0], C9_Result.u_id[1], C9_Result.u_id[2], C9_Result.u_id[3], C9_Result.u_id[4], C9_Result.u_id[5], C9_Result.u_id[6], C9_Result.u_id[7]);
  515. break;
  516. case Apple_Pay:
  517. DEBUG_INFO("Apple_Pay VAS only.\n");
  518. for(uint8_t idx=0;idx<getSentinelQuantity(C9_Result.result_data, rx_len);idx++)
  519. {
  520. memcpy(C9_Result.tkData[idx],
  521. &C9_Result.result_data[((idx==0)?3:getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2)],
  522. (idx==0?getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-3+1:getSentinelPosition(C9_Result.result_data, rx_len, idx)+1-getSentinelPosition(C9_Result.result_data, rx_len, idx-1)+2+1));
  523. DEBUG_INFO("TK[%d]: \n", idx);
  524. show_data(C9_Result.tkData[idx], getSentinelPosition(C9_Result.tkData[idx], ARRAY_SIZE(C9_Result.tkData[idx]), 0)+2);
  525. }
  526. break;
  527. case No_Data:
  528. DEBUG_INFO("--> No any data.\n");
  529. break;
  530. default:
  531. DEBUG_INFO("--> Unknown pos entry.\n");
  532. break;
  533. }
  534. failCount = 0;
  535. }
  536. else
  537. {
  538. DEBUG_INFO("C9 Parsing result fail.\n");
  539. }
  540. }
  541. else
  542. {
  543. DEBUG_WARN("C9 Response timeout: %d \n", failCount);
  544. }
  545. }
  546. }
  547. usleep(500000);
  548. }
  549. return FAIL;
  550. }