123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
-
- /**
- * number转换成指定字节数的hexString
- * num:转换的number值
- * bitNum:转换后的字节数
- * isBig:true-大端,fasle-小端
- */
- var num2hex = function (num, bitNum, isBig) {
- //转大端hex并补足
- let hex = num.toString(16);
- for (let i = hex.length; i < bitNum * 2; i++) {
- hex = "0" + hex;
- }
- //多位截取
- if (hex.length > bitNum * 2) {
- hex = hex.substring(hex.length - bitNum * 2);
- }
- //转小端
- if (isBig == false) {
- let temp = "";
- for (let i = hex.length - 2; i >= 0; i -= 2) {
- temp = temp + hex.substring(i, i + 2);
- }
- hex = temp;
- }
- return hex;
- }
-
- /**
- * 将hexString转成bufferArray
- */
- var hex2buf = function (hexString) {
- let bufferArray = new Uint8Array(hexString.match(/[\da-f]{2}/gi).map(function (h) {
- return parseInt(h, 16)
- }))
- return bufferArray.buffer
- }
-
- /**
- * 将bufferArray转成hexString
- */
- var buf2hex = function (bufferArray) {
- let hex = Array.prototype.map.call(new Uint8Array(bufferArray), x => ('00' + x.toString(16)).slice(-2)).join('')
- return hex
- }
-
- /**
- * TLV指令构造
- * tpdus:指令集合
- * needResponse:对于tpdu指令是否需要返回数据,true有返回,fasle没有返回,如:["00a40000023f00","00a40000021001"],[true,false],这前一条有返回3f00的信息和状态码,后一条则只返回状态码,没有信息
- */
- var makeTLV = function (tpdus, needResponses) {
- let tlv = ""
- for (let i = 0; i < tpdus.length; i++) {
- let temp = "" + tpdus[i]
- let status = i + 1
- if (typeof needResponses == "object" && needResponses[i] === false) {
- status = 0x80 + status
- }
- //指令失败继续往下执行
- status += 0x40;
- let cmdLen = parseInt(temp.length / 2);
- let cmdLenHex = cmdLen.toString(16);
- if (cmdLenHex.length % 2 != 0) {
- cmdLenHex = "0" + cmdLenHex;
- }
- if (cmdLen > 0x80) {
- cmdLenHex = (0x80 + parseInt(cmdLenHex.length / 2)).toString(16) + cmdLenHex;
- }
- tlv = tlv + num2hex(status, 1, true) + cmdLenHex + temp;
- }
- let tlvLen = tlv.length / 2;
- let tlvLenHex = tlvLen.toString(16);
- if (tlvLenHex.length % 2 != 0) {
- tlvLenHex = "0" + tlvLenHex;
- }
- if (tlvLen > 0x80) {
- tlvLenHex = (0x80 + parseInt(tlvLenHex.length / 2)).toString(16) + tlvLenHex;
- }
- return "80" + tlvLenHex + tlv;
- }
-
-
- /**
- * 分解TLV指令结构,返回tpdu指令数组
- */
- var reTLV = function (tlv) {
- let tpdus = new Array();
- let lenc = parseInt(tlv.substring(2, 4), 16);
- let index = 4;
- if (lenc > 0x80) {
- index = index + (lenc - 0x80) * 2;
- }
- let count = 1;
- while (index < tlv.length) {
- let time = parseInt(tlv.substring(index, index + 2), 16);
- index += 2;
- let len = parseInt(tlv.substring(index, index + 2), 16);
- index += 2;
- if (len > 0x80) {
- let bit = (len - 0x80) * 2;
- len = parseInt(tlv.substring(index, index + bit), 16);
- index += bit;
- }
- let tpdu = tlv.substring(index, index + len * 2);
- tpdus.push(tpdu);
- index += len * 2;
- }
- if (tpdus.length == 0) {
- tpdus.push("FFFF");
- }
- return tpdus;
- }
-
- const frame_Len = 184
- const send_Len = 40
- const ST = "50"
-
- var makeFrame = function (data) {
- let frameCount = parseInt(data.length / frame_Len)
- let frameBalance = data.length % frame_Len
- let frames = new Array()
- for (let i = 0; i < frameCount; i++) {
- frames.push(data.slice(i * frame_Len, (i + 1) * frame_Len))
- }
- if (frameBalance > 0) {
- frames.push(data.slice(- frameBalance))
- }
- //加厂商结构
- let manufacturerFrames = new Array();
- for (let i = 0; i < frames.length; i++) {
- let temp = frames[i]
- let CTL = ""
- if (i == 0) {
- CTL = num2hex(0x8000 + frames.length, 2, true)
- }
- else {
- CTL = num2hex(i + 1, 2, true)
- }
- let LEN = num2hex(parseInt(temp.length / 2), 1, true)
- let frame = ST + CTL + LEN + temp
- let bcc = 0
- for (let j = 0; j < parseInt(frame.length / 2); j++) {
- let bit = parseInt(frame.slice(j * 2, (j + 1) * 2), 16)
- bcc = bcc ^ bit
- }
- frame += num2hex(bcc, 1, true)
- manufacturerFrames.push(frame)
- }
- //分割发生小包
- let bufferArray = new Array()
- for (let i = 0; i < manufacturerFrames.length; i++) {
- let temp = manufacturerFrames[i]
- let bufferCount = parseInt(temp.length / send_Len)
- let bufferBalance = temp.length % send_Len
- for (let j = 0; j < bufferCount; j++) {
- let item = temp.slice(j * send_Len, (j + 1) * send_Len)
- bufferArray.push(hex2buf(item))
- }
- if (bufferBalance > 0) {
- let item = temp.slice(- bufferBalance)
- bufferArray.push(hex2buf(item))
- }
- }
- return bufferArray
- }
-
- /**
- * 设备初始化通道
- */
- var make80SendData = function () {
- let data = "80"
- return makeFrame(data)
- }
-
- /**
- * 对设备操作通道
- * "c0" : 获取设备的设备表面号
- * "c1" : 获取设备的版本号
- * "c2" : 获取设备的电池电量
- * "c3" : 强制设备断电
- * "c4" : 对设备复位
- * "c5" : 获取设备的蓝牙MAC
- * "cc" : 获取设备信息:ASCII码,最长100字节
- */
- var make81SendData = function (command) {
- let data = "81"
- let len = num2hex(parseInt(command.length / 2), 2, false)
- data += len
- data += command
- return makeFrame(data)
- }
-
- /**
- * 对IC/ESAM/SE等进行COS操作通道
- * dataType : bit0=数据类型(0-明文数据,1-密文数据);bit1~bit3=(设置为0);bit4~bit7=目标索引(1-用户卡,2-ESAM安全模块,3-SE,其他保留)
- * cos : TLV格式(长度不超过384)
- */
- var make82SendData = function (dataType, cos) {
- let data = "82"
- let len = num2hex(parseInt(cos.length / 2), 2, false)
- data += dataType
- data += len
- data += cos
- return makeFrame(data)
- }
-
- /**
- * 获取IC卡密文通讯时的记录通道
- * conmand : "co" + 记录索引
- */
- var make83SendData = function (command) {
- let data = "83"
- let len = num2hex(parseInt(command.length / 2), 2, false)
- data += len
- data += command
- return makeFrame(data)
- }
-
- /**
- * 设备认证(包括更新终端证书)操作通道
- * "c0" : 设备认证步骤1
- * "c1" + 工作密钥密文 + ... + Rnd2 + S2 : 设备认证步骤2
- * "c2" : 更新终端证书步骤1 -- 初始化
- * "c3" : 更新终端证书步骤2 -- 获取终端公钥
- * "c4" + 终端证书 : 更新终端证书步骤3 -- 更新证书
- */
- var make84SendData = function (command) {
- let data = "84"
- let len = num2hex(parseInt(command.length / 2), 2, false)
- data += len
- data += command
- return makeFrame(data)
- }
-
- /**
- * 数据透彻操作通道
- * dataType : bit0=数据类型(0-明文数据,1-密文数据);bit1~bit3=(设置为0);bit4~bit7=目标索引(1-用户卡,2-ESAM安全模块,3-SE,其他保留)
- * command : 透彻指令数据
- */
- var make85SendData = function (dataType, command) {
- let data = "85"
- let len = num2hex(parseInt(command.length / 2), 2, false)
- data += dataType
- data += len
- data += command
- return makeFrame(data)
- }
-
- /**
- * 厂商自定义功能
- * "c1" + code : 设备显示字符,code("01"=激活中,"02"=激活成功,"03"=激活失败,"04"=发行中,"05"=发行成功,"06"=发行失败)
- */
- var make8FSendData = function (command) {
- let data = "8F"
- let len = num2hex(parseInt(command.length / 2), 2, false)
- data += len
- data += command
- return makeFrame(data)
- }
-
-
- var ArtcDataUtil = {
- num2hex: num2hex,
- hex2buf: hex2buf,
- buf2hex: buf2hex,
- makeTLV: makeTLV,
- reTLV: reTLV,
- make80SendData: make80SendData,
- make81SendData: make81SendData,
- make82SendData: make82SendData,
- make83SendData: make83SendData,
- make84SendData: make84SendData,
- make85SendData: make85SendData,
- make8FSendData: make8FSendData,
- }
-
- module.exports = ArtcDataUtil
|