VM暫存
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

343 line
11KB

  1. <?php
  2. /*
  3. file: acer_servicemodel.php
  4. */
  5. class Acer_service_model extends CI_Model
  6. {
  7. var $vars = array();
  8. var $now_str;
  9. function __construct()
  10. {
  11. parent::__construct();
  12. $this->load->database();
  13. $this->now_str = date('Y-m-d H:i:s');
  14. // ACER 連線設定 (測試環境)
  15. //define('ACER_SERVICE_IP', '220.130.199.142');
  16. //define('ACER_SERVICE_PORT', 60833);
  17. // ACER 連線設定 (測試環境 - 現場呼叫)
  18. //define('ACER_SERVICE_IP', '220.130.199.142');
  19. //define('ACER_SERVICE_PORT', 8033);
  20. // ACER 連線設定 (正式環境 - 現場呼叫)
  21. define('ACER_SERVICE_IP', '192.168.10.221');
  22. define('ACER_SERVICE_PORT', 8033);
  23. // 結果代碼
  24. define('ALTOB_RESULT_CODE_SUCCESS', 'OK'); // 成功
  25. define('ALTOB_RESULT_CODE_FAIL', 'GG'); // 失敗
  26. // 錯誤碼
  27. define('ALTOB_ERROR_CODE_NONE', '0000'); // 預設值 (成功帶這個)
  28. define('ALTOB_ERROR_CODE_UNKNOWN_INPUT', '1001'); // 未知的 輸入
  29. define('ALTOB_ERROR_CODE_UNKNOWN_CMD', '1002'); // 未知的 CMD
  30. define('ALTOB_ERROR_CODE_NOT_FOUND', '1003'); // 查無記錄
  31. define('ALTOB_ERROR_CODE_ERROR', '1004'); // 交易失敗
  32. define('ALTOB_ERROR_CODE_UNDEFINED', '9999'); // 未定義的錯誤
  33. define('ALTOB_ERROR_CODE_ACER_RESULT_FAIL', '2001'); // ACER 回傳處理錯誤
  34. }
  35. // acer socket
  36. function acer_socket($in)
  37. {
  38. trigger_error(__FUNCTION__ . "..socket input|{$in}");
  39. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  40. if ($socket === false) {
  41. trigger_error(__FUNCTION__ . "..socket_create() failed: reason: " . socket_strerror(socket_last_error()));
  42. }
  43. $result = socket_connect($socket, ACER_SERVICE_IP, ACER_SERVICE_PORT);
  44. if ($result === false) {
  45. trigger_error(__FUNCTION__ . "..socket_connect() failed.\nReason: ({$result}) " . socket_strerror(socket_last_error($socket)));
  46. return false; // 中斷
  47. }
  48. if(!socket_write($socket, $in, strlen($in)))
  49. {
  50. trigger_error(__FUNCTION__ . '..Write failed..');
  51. }
  52. $out = socket_read($socket, 64);
  53. socket_shutdown($socket);
  54. socket_close($socket);
  55. trigger_error(__FUNCTION__ . "..socket output|{$out}");
  56. return $out;
  57. }
  58. public function init($vars)
  59. {
  60. $this->vars = $vars;
  61. }
  62. // 票卡入場訊號,供 ALTOB 登記
  63. //(傳入:卡號、入場編號、是否月租卡; 回傳:結果代碼、入場編號、錯誤碼)
  64. public function cmd_001($card_no, $cario_no, $card_type)
  65. {
  66. // 票號查詢最近一筆入場資料
  67. $rows_cario = $this->db
  68. ->select('cario_no, lpr, in_time, pay_time, out_before_time')
  69. ->from('cario')
  70. ->where(array(
  71. 'in_out' => 'CI', 'err' => 0, 'finished' => 0,
  72. 'cario_no' => $cario_no,
  73. 'in_time > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 1 DAY)' => null))
  74. ->limit(1)
  75. ->get()
  76. ->row_array();
  77. trigger_error(__FUNCTION__ . '..cario..' . print_r($rows_cario, true));
  78. $cario_no = 0; // 進出碼
  79. $error_code = ALTOB_ERROR_CODE_NONE; // 錯誤碼
  80. if (!empty($rows_cario['cario_no']))
  81. {
  82. $cario_no = $rows_cario['cario_no'];
  83. // 更新入場資訊
  84. $this->db->where(array('cario_no' => $cario_no))->update('cario', array('remarks' => "{$card_no}"));
  85. if (!$this->db->affected_rows())
  86. {
  87. trigger_error(__FUNCTION__ . '..fail..' . $this->db->last_query());
  88. $error_code = ALTOB_ERROR_CODE_ERROR;
  89. }
  90. }
  91. else
  92. {
  93. // 查無入場記錄
  94. $error_code = ALTOB_ERROR_CODE_NOT_FOUND;
  95. }
  96. $data = array();
  97. $data['result_code'] = ALTOB_RESULT_CODE_SUCCESS;
  98. $data['result']['cario_no'] = $cario_no;
  99. $data['result']['error_code'] = $error_code;
  100. return $data;
  101. }
  102. // 票卡離場訊號,供 ALTOB 登記
  103. //(傳入:卡號、繳費時間、是否月租卡; 回傳:結果代碼、入場編號、錯誤碼)
  104. public function cmd_002($card_no, $pay_time, $card_type)
  105. {
  106. // 卡號查詢最近一筆入場資料
  107. $rows_cario = $this->db
  108. ->select('cario_no, lpr, in_time, pay_time, out_before_time')
  109. ->from('cario')
  110. ->where(array(
  111. 'in_out' => 'CI', 'err' => 0, 'finished' => 0,
  112. 'remarks' => $card_no,
  113. 'in_time > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 5 DAY)' => null))
  114. ->order_by('cario_no', 'desc')
  115. ->limit(1)
  116. ->get()
  117. ->row_array();
  118. trigger_error(__FUNCTION__ . '..cario..' . print_r($rows_cario, true));
  119. $cario_no = 0; // 進出碼
  120. $error_code = ALTOB_ERROR_CODE_NONE; // 錯誤碼
  121. if (!empty($rows_cario['cario_no']))
  122. {
  123. $cario_no = $rows_cario['cario_no'];
  124. // 暫不處理
  125. }
  126. else
  127. {
  128. // 查無入場記錄
  129. $error_code = ALTOB_ERROR_CODE_NOT_FOUND;
  130. }
  131. $data = array();
  132. $data['result_code'] = ALTOB_RESULT_CODE_SUCCESS;
  133. $data['result']['cario_no'] = $cario_no;
  134. $data['result']['error_code'] = $error_code;
  135. return $data;
  136. }
  137. // 票號離場訊號,回傳若成功觸發 ACER 開門
  138. // (傳入:6 碼數字; 回傳:結果代碼、入場編號、錯誤碼、離場代碼)
  139. public function cmd_003($ticket_no)
  140. {
  141. // 票號查詢最近一筆入場資料 (只能查 5天 內)
  142. $rows_cario = $this->db
  143. ->select('cario_no, payed, in_time, pay_time, out_before_time')
  144. ->from('cario')
  145. ->where(array(
  146. 'ticket_no' => $ticket_no, 'err' => 0,
  147. 'in_time > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 5 DAY)' => null)
  148. )
  149. ->order_by('cario_no', 'desc')
  150. ->limit(1)
  151. ->get()
  152. ->row_array();
  153. trigger_error(__FUNCTION__ . '..cario..' . print_r($rows_cario, true));
  154. $cario_no = 0; // 進出碼
  155. $error_code = ALTOB_ERROR_CODE_NONE; // 錯誤碼
  156. $msg_code = 0; // 離場碼
  157. if (!empty($rows_cario['cario_no']))
  158. {
  159. $cario_no = $rows_cario['cario_no'];
  160. if(strtotime($rows_cario['out_before_time']) >= time())
  161. {
  162. if ($rows_cario['payed'])
  163. {
  164. // CO.B.1 臨停車已付款
  165. $msg_code = 6;
  166. }
  167. else
  168. {
  169. // CO.B.2 臨停車未付款
  170. $msg_code = 8;
  171. }
  172. }
  173. else
  174. {
  175. // CO.C.1 其它付款方式
  176. $msg_code = 9;
  177. }
  178. }
  179. else
  180. {
  181. // CO.Z.Z 無入場資料
  182. $cario_no = 0;
  183. $msg_code = 13;
  184. }
  185. $data = array();
  186. $data['result_code'] = ALTOB_RESULT_CODE_SUCCESS;
  187. $data['result']['cario_no'] = $cario_no;
  188. $data['result']['error_code'] = $error_code;
  189. $data['result']['msg_code'] = $msg_code;
  190. return $data;
  191. }
  192. // 呼叫 acer (cmd: 101)
  193. // (傳入:入場編號、進場時間、 6 碼數字、車牌號碼、出入口編號; 回傳:結果代碼、入場編號、錯誤碼)
  194. public function cmd_101($cario_no, $in_time, $ticket_no, $lpr, $ivs_no)
  195. {
  196. $seq = '00001';
  197. $cmd = '101';
  198. $cario_no_pad = str_pad($cario_no, 10, '0', STR_PAD_LEFT); // 入場編號: 10 碼 (左邊補 0)
  199. $lpr_pad = str_pad($lpr, 10, '*', STR_PAD_LEFT); // 車牌號碼: 10 碼 (左邊補 *)
  200. $ivs_no_pad = str_pad($ivs_no, 2, '0', STR_PAD_LEFT); // 車道編號: 2 碼 (左邊補 0)
  201. // 建立封包
  202. $packformat = "a10Ca19Ca6Ca10Ca2";
  203. $data = pack($packformat,
  204. // Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
  205. $cario_no_pad, 0x1f, $in_time, 0x1f, $ticket_no, 0x1f, $lpr_pad, 0x1f, $ivs_no_pad
  206. );
  207. $data_len = strlen($data);
  208. $socket_len = $data_len + 16;
  209. $in = pack("Ca2Ca5Ca3C{$packformat}CCC",
  210. 0x02, // STX:封包起始碼(0x02)
  211. $socket_len, 0x1c, // 封包長度:從STX到ETX的位元數
  212. $seq, 0x1c, // 封包流水號:5碼ASCII數字(不足5碼時左補”0”補滿5碼)
  213. $cmd, 0x1c, // CmdID:命令ID
  214. // Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
  215. $cario_no_pad, 0x1f, $in_time, 0x1f, $ticket_no, 0x1f, $lpr_pad, 0x1f, $ivs_no_pad,
  216. 0x1c,
  217. 0x80, // CRC:封包檢查碼
  218. 0x03 // ETX:封包結束碼(0x03)
  219. );
  220. // 連線
  221. $out = $this->acer_socket($in);
  222. if(!empty($out))
  223. {
  224. list($front, $seq, $cmd, $data) = explode(chr(28), $out);
  225. list($result_code, $cario_no, $error_code) = explode(chr(31), $data);
  226. trigger_error(__FUNCTION__ . "..socket return explode|{$front}, {$seq}, {$cmd}, {$result_code}, {$cario_no}, {$error_code}");
  227. if(!empty($result_code) && ALTOB_RESULT_CODE_SUCCESS == $result_code)
  228. {
  229. $data = array();
  230. $data['result_code'] = ALTOB_RESULT_CODE_SUCCESS;
  231. $data['result']['cario_no'] = $cario_no;
  232. return $data;
  233. }
  234. }
  235. $data = array();
  236. $data['result_code'] = ALTOB_RESULT_CODE_FAIL;
  237. $data['result']['error_code'] = ALTOB_ERROR_CODE_ACER_RESULT_FAIL;
  238. return $data;
  239. }
  240. // 呼叫 acer (cmd: 102)
  241. // (傳入:入場編號、出入口編號、離場代碼; 回傳:結果代碼、入場編號、錯誤碼)
  242. public function cmd_102($cario_no, $ivs_no, $msg_code)
  243. {
  244. $seq = '00001';
  245. $cmd = '102';
  246. $cario_no_pad = str_pad($cario_no, 10, '0', STR_PAD_LEFT); // 入場編號: 10 碼 (左邊補 0)
  247. $ivs_no_pad = str_pad($ivs_no, 2, '0', STR_PAD_LEFT); // 車道編號: 2 碼 (左邊補 0)
  248. $msg_code_pad = str_pad($msg_code, 5, '0', STR_PAD_LEFT); // 離場代碼: 5 碼 (左邊補 0)
  249. // 建立封包
  250. $packformat = "a10Ca2Ca5";
  251. $data = pack($packformat,
  252. // Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
  253. $cario_no_pad, 0x1f, $ivs_no_pad, 0x1f, $msg_code_pad
  254. );
  255. $data_len = strlen($data);
  256. $socket_len = $data_len + 16;
  257. $in = pack("Ca2Ca5Ca3C{$packformat}CCC",
  258. 0x02, // STX:封包起始碼(0x02)
  259. $socket_len, 0x1c, // 封包長度:從STX到ETX的位元數
  260. $seq, 0x1c, // 封包流水號:5碼ASCII數字(不足5碼時左補”0”補滿5碼)
  261. $cmd, 0x1c, // CmdID:命令ID
  262. // Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
  263. $cario_no_pad, 0x1f, $ivs_no_pad, 0x1f, $msg_code_pad,
  264. 0x1c,
  265. 0x80, // CRC:封包檢查碼
  266. 0x03 // ETX:封包結束碼(0x03)
  267. );
  268. // 連線
  269. $out = $this->acer_socket($in);
  270. if(!empty($out))
  271. {
  272. list($front, $seq, $cmd, $data) = explode(chr(28), $out);
  273. list($result_code, $cario_no, $error_code) = explode(chr(31), $data);
  274. trigger_error(__FUNCTION__ . "..socket return explode|{$front}, {$seq}, {$cmd}, {$result_code}, {$cario_no}, {$error_code}");
  275. if(!empty($result_code) && ALTOB_RESULT_CODE_SUCCESS == $result_code)
  276. {
  277. $data = array();
  278. $data['result_code'] = ALTOB_RESULT_CODE_SUCCESS;
  279. $data['result']['cario_no'] = $cario_no;
  280. return $data;
  281. }
  282. }
  283. $data = array();
  284. $data['result_code'] = ALTOB_RESULT_CODE_FAIL;
  285. $data['result']['error_code'] = ALTOB_ERROR_CODE_ACER_RESULT_FAIL;
  286. return $data;
  287. }
  288. }