终端一体化运控平台
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

241 líneas
8.1 KiB

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