终端一体化运控平台
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.
 
 
 

242 regels
8.1 KiB

  1. using BPASmartClient.Helper;
  2. using BPASmartClient.Message;
  3. using System.Text.RegularExpressions;
  4. namespace BPASmartClient.Nfc
  5. {
  6. public class NFCHelper
  7. {
  8. private volatile static NFCHelper _Instance;
  9. public static NFCHelper GetInstance => _Instance ?? (_Instance = new NFCHelper());
  10. private NFCHelper() { }
  11. public ReadResult GetReadResult { get; set; } = new ReadResult();
  12. public Action Update { get; set; }
  13. //转换卡号专用
  14. private byte[] convertSNR(string str, int keyN)
  15. {
  16. string regex = "[^a-fA-F0-9]";
  17. string tmpJudge = Regex.Replace(str, regex, "");
  18. //长度不对,直接退回错误
  19. if (tmpJudge.Length != 12) return null;
  20. string[] tmpResult = Regex.Split(str, regex);
  21. byte[] result = new byte[keyN];
  22. int i = 0;
  23. foreach (string tmp in tmpResult)
  24. {
  25. result[i] = Convert.ToByte(tmp, 16);
  26. i++;
  27. }
  28. return result;
  29. }
  30. //数据输入判断函数2个
  31. private string formatStr(string str, int num_blk)
  32. {
  33. string tmp = Regex.Replace(str, "[^a-fA-F0-9]", "");
  34. //长度不对直接报错
  35. //num_blk==-1指示不用检查位数
  36. if (num_blk == -1) return tmp;
  37. //num_blk==其它负数,为-1/num_blk
  38. if (num_blk < -1)
  39. {
  40. if (tmp.Length != -16 / num_blk * 2) return null;
  41. else return tmp;
  42. }
  43. if (tmp.Length != 16 * num_blk * 2) return null;
  44. else return tmp;
  45. }
  46. private void convertStr(byte[] after, string before, int length)
  47. {
  48. for (int i = 0; i < length; i++)
  49. {
  50. after[i] = Convert.ToByte(before.Substring(2 * i, 2), 16);
  51. }
  52. }
  53. //显示命令执行结果
  54. private string showStatue(int Code)
  55. {
  56. string msg = "";
  57. switch (Code)
  58. {
  59. case 0x00:
  60. msg = "命令执行成功";
  61. break;
  62. case 0x01:
  63. msg = "命令操作失败";
  64. break;
  65. case 0x02:
  66. msg = "地址校验错误";
  67. break;
  68. case 0x03:
  69. msg = "找不到已选择的端口";
  70. break;
  71. case 0x04:
  72. msg = "读写器返回超时";
  73. break;
  74. case 0x05:
  75. msg = "数据包流水号不正确";
  76. break;
  77. case 0x07:
  78. msg = "接收异常";
  79. break;
  80. case 0x0A:
  81. msg = "参数值超出范围";
  82. break;
  83. case 0x80:
  84. msg = "参数设置成功";
  85. break;
  86. case 0x81:
  87. msg = "参数设置失败";
  88. break;
  89. case 0x82:
  90. msg = "通讯超时";
  91. break;
  92. case 0x83:
  93. msg = "卡不存在";
  94. break;
  95. case 0x84:
  96. msg = "接收卡数据出错";
  97. break;
  98. case 0x85:
  99. msg = "未知的错误";
  100. break;
  101. case 0x87:
  102. msg = "输入参数或者输入命令格式错误";
  103. break;
  104. case 0x89:
  105. msg = "输入的指令代码不存在";
  106. break;
  107. case 0x8A:
  108. msg = "在对于卡块初始化命令中出现错误";
  109. break;
  110. case 0x8B:
  111. msg = "在防冲突过程中得到错误的序列号";
  112. break;
  113. case 0x8C:
  114. msg = "密码认证没通过";
  115. break;
  116. case 0x8F:
  117. msg = "读取器接收到未知命令";
  118. break;
  119. case 0x90:
  120. msg = "卡不支持这个命令";
  121. break;
  122. case 0x91:
  123. msg = "命令格式有错误";
  124. break;
  125. case 0x92:
  126. msg = "在命令的FLAG参数中,不支持OPTION 模式";
  127. break;
  128. case 0x93:
  129. msg = "要操作的BLOCK不存在";
  130. break;
  131. case 0x94:
  132. msg = "要操作的对象已经别锁定,不能进行修改";
  133. break;
  134. case 0x95:
  135. msg = "锁定操作不成功";
  136. break;
  137. case 0x96:
  138. msg = "写操作不成功";
  139. break;
  140. default:
  141. msg = "未知错误2";
  142. break;
  143. }
  144. return msg;
  145. }
  146. /// <summary>
  147. /// 结果显示
  148. /// </summary>
  149. /// <param name="text"></param>
  150. /// <param name="data"></param>
  151. /// <param name="s"></param>
  152. /// <param name="e"></param>
  153. private string showData(byte[] data, int s, int e)
  154. {
  155. string res = string.Empty;
  156. //非负转换
  157. for (int i = 0; i < e; i++)
  158. {
  159. if (data[s + i] < 0)
  160. data[s + i] = Convert.ToByte(Convert.ToInt32(data[s + i]) + 256);
  161. }
  162. for (int i = 0; i < e; i++)
  163. {
  164. res += data[s + i].ToString("X2") + " ";
  165. }
  166. return res;
  167. }
  168. public void Init()
  169. {
  170. ThreadManage.GetInstance().StartLong(new Action(() =>
  171. {
  172. Read();
  173. if (GetReadResult.ErrorInfo.Length > 0) MessageLog.GetInstance.ShowDebugLog(GetReadResult.ErrorInfo);
  174. Thread.Sleep(1000);
  175. }), "NFC数据读取");
  176. }
  177. public void Read(ReadKeyEnum readKeyEnum = ReadKeyEnum.KeyA, ReadTypeEnum readTypeEnum = ReadTypeEnum.Idle, byte ReadStart = 16, byte ReadNum = 1)
  178. {
  179. //数据是一个64位的长整形,读取块的数量就是指第几个字
  180. if (ReadStart < 0 || ReadStart > 63) return;
  181. if (ReadNum <= 0 || ReadNum > 4) return;
  182. byte mode1 = (readKeyEnum == ReadKeyEnum.KeyB) ? (byte)0x01 : (byte)0x00;
  183. byte mode2 = (readTypeEnum == ReadTypeEnum.All) ? (byte)0x01 : (byte)0x00;
  184. byte mode = (byte)((mode1 << 1) | mode2);
  185. byte blk_add = ReadStart;
  186. byte num_blk = ReadNum;
  187. //秘钥:
  188. //第一组:FF FF FF FF FF FF
  189. //第二组:B0 B1 B2 B3 B4 B5
  190. //第三组:A0 A1 A2 A3 A4 A5
  191. byte[] snr = new byte[6];
  192. snr = convertSNR("FF FF FF FF FF FF", 6);
  193. if (snr == null)
  194. {
  195. GetReadResult.ErrorInfo = "序列号无效!";
  196. return;
  197. }
  198. byte[] buffer = new byte[16 * num_blk];
  199. try
  200. {
  201. int nRet = Reader.MF_Read(mode, blk_add, num_blk, snr, buffer);
  202. GetReadResult.StatueCode = showStatue(nRet);
  203. if (nRet != 0)
  204. {
  205. GetReadResult.StatueCode = showStatue(buffer[0]);
  206. GetReadResult.CardNum = string.Empty;
  207. GetReadResult.Data = string.Empty;
  208. }
  209. else
  210. {
  211. GetReadResult.CardNum = showData(snr, 0, 4);
  212. GetReadResult.Data = showData(buffer, 0, 16 * num_blk);
  213. }
  214. }
  215. catch (Exception ex)
  216. {
  217. GetReadResult.CardNum = string.Empty;
  218. GetReadResult.Data = string.Empty;
  219. MessageLog.GetInstance.ShowDebugLog(ex.ToString());
  220. }
  221. finally
  222. {
  223. Update?.Invoke();
  224. }
  225. }
  226. }
  227. }