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.

TDRObuSDK.js 27KB

2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872
  1. const mServiceId = '0000FEE7-0000-1000-8000-00805F9B34FB';
  2. const mWriteUUID = '0000FEC7-0000-1000-8000-00805F9B34FB';
  3. const mReadUUID = '0000FEC7-0000-1000-8000-00805F9B34FB';
  4. const mNotifyUUID = '0000FEC8-0000-1000-8000-00805F9B34FB';
  5. const mActiviceReadUUID = '0000FEC9-0000-1000-8000-00805F9B34FB';
  6. const WECHAT_PRO_HEAD_MAGIC_NUMBER = 0xFE;
  7. const WECHAT_PRO_HEAD_PACK_VERSION = 0x01;
  8. const WECHAT_CMD_ECI_REQ_AUTH = 0x2711; //握手数据(设备--->手机)
  9. const WECHAT_CMD_ECI_REQ_SEND_DATA = 0x2712;
  10. const WECHAT_CMD_ECI_REQ_INIT = 0x2713; //初始化 (设备--->手机)
  11. const WECHAT_CMD_ECI_RESP_AUTH = 0x4E21; //握手数据 (手机--->设备)
  12. const WECHAT_CMD_ECI_RESP_INIT = 0x4E23; //初始化 (手机--->设备)
  13. const WECHAT_CMD_ECI_PUSH_RECV_DATA = 0x7531; //发送指令数据(手机--->设备)
  14. const ETC_PRO_SINGLE_PACK_SIZE = 105; /* ETC–≠“È∑÷∞¸≥§∂» */
  15. const BLE_CTL_START_BIT = 0x80; //分包后,此包是否为起始包
  16. const BLE_ETC_PRO_HEAD_ST = 0x33; /* ETC(33协议头标识) */
  17. const MAX_WECHAT_SEND_LEN = 255;
  18. const MAX_BLE_SIZE = 20;
  19. const KYunNanObuMultiplePackages = 1;
  20. let mDeviceId = 0;
  21. let service = {}; //服务
  22. let writeCharVal = {}; //写入特征值
  23. let readCharVal = {}; //读取特征值
  24. let notifyCharVal = {}; //通知特征值
  25. let activiceReadCharVal = {}; //读取特征值
  26. let mPacketLen = 0;
  27. let mRecvDataCache = [];
  28. let mUnpacketDataCache = [];
  29. let mIsInitCmdSend = false;
  30. let mEtcRawData = [];
  31. let mEtcRawDataLen = 0;
  32. let maxLenPerPacket = 0;
  33. let mReturnedRawCmdData = 0;
  34. let mAbCmdBuf = [];
  35. let mnCmdBufLen = 0;
  36. let mTransData = [];
  37. let mSingleEtcProtoData = [];
  38. let mLenBuf = [];
  39. let mBytesNumOfDataLen = 0;
  40. let receiveDataCallBack = null;
  41. let m_isConn = false;
  42. let mCurrentPacketNum = 0;
  43. let mConnCount = 2;
  44. let beginTime = 0;
  45. const common_vendor = require("../../../common/vendor.js");
  46. var uni = common_vendor.index
  47. /**
  48. 通过蓝牙,连接OBU设备
  49. @param deviceId 需要连接的蓝牙外围设备ID
  50. @param callback_1 回调函数 连接结果
  51. code=0表示连接成功,code = 非0 连接失败
  52. @param callback_2 回调函数 时时监听连接状态
  53. code=0表示监听连接成功,code = 1表示监听到断开连接
  54. */
  55. function connectDevice(device, callback_1, callback_2) {
  56. beginTime = +new Date();
  57. let deviceId = device.deviceId
  58. // if (m_isConn && mDeviceId == deviceId) {
  59. // callback_1(makeRes(0, [] , '已连接'))
  60. // return;
  61. // }
  62. // if (mDeviceId == 0) {
  63. conn(device, callback_1, callback_2)
  64. // } else {
  65. // uni.closeBLEConnection({
  66. // deviceId: mDeviceId,
  67. // complete: function (e) {
  68. // conn(device, callback_1, callback_2)
  69. // }
  70. // })
  71. // }
  72. }
  73. function conn(device, callback_1, callback_2) {
  74. let deviceId = device.deviceId
  75. uni.createBLEConnection({
  76. deviceId: deviceId,
  77. timeout: 5000,
  78. success: function (res) {
  79. mDeviceId = deviceId;
  80. uni.getBLEDeviceServices({
  81. deviceId: deviceId,
  82. success: function (res) {
  83. console.log('getBLEDeviceServices:' + JSON.stringify(res))
  84. var isExistsService = false
  85. for (var i = 0; i < res.services.length; i++) {
  86. if (res.services[i].uuid == mServiceId) {
  87. service: res.services[i]
  88. isExistsService = true;
  89. break;
  90. }
  91. }
  92. if (isExistsService) {
  93. uni.getBLEDeviceCharacteristics({
  94. deviceId: deviceId,
  95. serviceId: mServiceId,
  96. success: function (res) {
  97. for (var i = 0; i < res.characteristics.length; i++) {
  98. if (res.characteristics[i].uuid == mWriteUUID) {
  99. writeCharVal: res.characteristics[i]
  100. }
  101. if (res.characteristics[i].uuid == mReadUUID) {
  102. readCharVal: res.characteristics[i]
  103. }
  104. if (res.characteristics[i].uuid == mNotifyUUID) {
  105. notifyCharVal: res.characteristics[i]
  106. }
  107. if (res.characteristics[i].uuid == mActiviceReadUUID) {
  108. activiceReadCharVal: res.characteristics[i]
  109. }
  110. }
  111. uni.onBLEConnectionStateChange(function (res) {
  112. // 该方法回调中可以用于处理连接意外断开等异常情况
  113. console.log('改变onBLEConnectionStateChange');
  114. if (res.connected) {
  115. console.log('connected true')
  116. m_isConn = true;
  117. console.log(callback_2)
  118. callback_2(makeRes(0, [], '蓝牙已连接'))
  119. } else {
  120. console.log('connected false')
  121. var endTime = +new Date();
  122. if ((endTime - beginTime) >= 3000) {
  123. mIsInitCmdSend = false;
  124. m_isConn = false;
  125. console.log(callback_2)
  126. callback_2(makeRes(-1, [], '蓝牙已断开'))
  127. }
  128. }
  129. })
  130. uni.notifyBLECharacteristicValueChange({
  131. deviceId: deviceId,
  132. serviceId: mServiceId,
  133. characteristicId: mNotifyUUID,
  134. state: true,
  135. success: function (res) {
  136. uni.onBLECharacteristicValueChange(function (res) {
  137. console.log('收到数据:' + ab2hex(res.value))
  138. let pRead = ab2DecArr(res.value)
  139. if (pRead.length > 0 && pRead != null) {
  140. if (pRead[0] == WECHAT_PRO_HEAD_MAGIC_NUMBER &&
  141. pRead[1] == WECHAT_PRO_HEAD_PACK_VERSION) {
  142. mPacketLen = (pRead[2] << 8) | pRead[3];
  143. }
  144. mRecvDataCache.push.apply(mRecvDataCache, pRead)
  145. if (mRecvDataCache.length == mPacketLen) {
  146. let pData = mRecvDataCache
  147. let nCmdID = (pData[4] << 8) | pData[5]
  148. switch (nCmdID) {
  149. case WECHAT_CMD_ECI_REQ_AUTH:
  150. {
  151. console.log('WECHAT_CMD_ECI_REQ_AUTH')
  152. let data = makeHandShakeStep1WithETC()
  153. mRecvDataCache = []
  154. write(data)
  155. }
  156. break;
  157. case WECHAT_CMD_ECI_REQ_INIT:
  158. {
  159. console.log('WECHAT_CMD_ECI_REQ_INIT')
  160. let data = makeHandShakeStep2WithETC()
  161. write(data)
  162. setTimeout(function () {
  163. let dataInit = makeInitWithETC()
  164. mRecvDataCache = []
  165. write(dataInit)
  166. mIsInitCmdSend = true
  167. }, 20)
  168. }
  169. break;
  170. case WECHAT_CMD_ECI_REQ_SEND_DATA:
  171. {
  172. console.log('WECHAT_CMD_ECI_REQ_SEND_DATA')
  173. if (mIsInitCmdSend) {
  174. m_isConn = true
  175. callback_1(makeRes(0, [] , '连接成功'))
  176. mIsInitCmdSend = false
  177. }
  178. mEtcRawData = []
  179. mEtcRawDataLen = 0
  180. let op = unpaketProto(mRecvDataCache)
  181. if (!op) {
  182. if (mEtcRawData[0] == 0xB2) {
  183. maxLenPerPacket = mEtcRawData[3];
  184. } else {
  185. mUnpacketDataCache.push.apply(mUnpacketDataCache, mEtcRawData)
  186. console.log('******返回未解析的指令数据包为(' + mUnpacketDataCache.length + '):' + ab2hexArr(mUnpacketDataCache))
  187. if (mCurrentPacketNum == 0) {
  188. mReturnedRawCmdData = []
  189. let errorcode = unpackXXCmdPacket(mUnpacketDataCache)
  190. console.log('******解析后的指令数据为(' + mReturnedRawCmdData.length + '):' + mReturnedRawCmdData)
  191. if (receiveDataCallBack) {
  192. receiveDataCallBack(makeRes(errorcode, mReturnedRawCmdData, errorcode == 0 ? '收到数据成功' : '数据透传失败,请重试'))
  193. }
  194. mUnpacketDataCache = []
  195. }
  196. }
  197. } else {
  198. mUnpacketDataCache.push.apply(mUnpacketDataCache, mEtcRawData)
  199. }
  200. mRecvDataCache = []
  201. }
  202. break;
  203. default:
  204. break;
  205. }
  206. }
  207. }
  208. })
  209. },
  210. fail: function (e) {
  211. console.log('notifyBLECharacteristicValueChange fail')
  212. callback_1(makeRes(-1, [] , '连接失败'))
  213. }
  214. })
  215. },
  216. fail: function (res) {
  217. console.log('getBLEDeviceCharacteristics fail')
  218. callback_1(makeRes(-1, [] , '连接失败'))
  219. }
  220. })
  221. }
  222. },
  223. fail: function (res) {
  224. console.log('getBLEDeviceServices fail')
  225. callback_1(makeRes(-1, [] , '连接失败'))
  226. }
  227. })
  228. },
  229. fail: function (res) {
  230. // console.log('createBLEConnection fail')
  231. // if (mConnCount > 0) {
  232. // console.log(mConnCount)
  233. // mConnCount--
  234. // connectDevice(device, callback_1, callback_2)
  235. // } else {
  236. // console.log(mConnCount)
  237. // mConnCount = 2
  238. // m_isConn = false;
  239. // callback_1(-1, [] , '连接失败')
  240. // }
  241. callback_1(makeRes(-1, [] , '连接失败'))
  242. }
  243. })
  244. }
  245. //断开与OBU设备的蓝牙连接
  246. function disConnectDevice(callBack) {
  247. if(!m_isConn) {
  248. callBack(makeRes(-1, [], '未连接'))
  249. return;
  250. }
  251. let data = makeDisconnectWithETC();
  252. mIsInitCmdSend = false;
  253. mRecvDataCache = []
  254. write(data)
  255. uni.closeBLEConnection({
  256. deviceId: mDeviceId,
  257. success: function(res) {
  258. m_isConn = false;
  259. callBack(makeRes(0, [] , '断开成功'))
  260. },
  261. fail: function (e) {
  262. console.log('error:'+e.errMsg)
  263. callBack(makeRes(-1, [] , '断开失败'))
  264. }
  265. })
  266. }
  267. /**
  268. 数据透传
  269. @param cmd 指令[]
  270. @param cmdtype 明文:IC:10、ESAM:20
  271. @param callBack 回调函数
  272. status 成功为 true,失败为 false
  273. data NSData 回应数据(明文)+ 签名
  274. errorMsg 报错信息
  275. */
  276. function transCmd(cmd, cmdtype, callBack) {
  277. if (callBack) {
  278. receiveDataCallBack = callBack;
  279. }
  280. if (!m_isConn) {
  281. receiveDataCallBack(makeRes(-1, [] , '连接失败'))
  282. return;
  283. }
  284. let cmdType = 0;
  285. if (cmdtype == '10') {
  286. cmdType = 0xA3;
  287. } else if (cmdtype == '20') {
  288. cmdType = 0xA8;
  289. }
  290. let totalMutableData = []
  291. for(var i = 0; i < cmd.length; i++) {
  292. let obj = str2Bytes(cmd[i]);
  293. console.log('##### cmd_:' + ab2hexArr(obj))
  294. let oneData = makeMutiPackageData(obj, i+1)
  295. console.log('##### oneData:' + ab2hexArr(oneData))
  296. totalMutableData.push.apply(totalMutableData, oneData);
  297. }
  298. console.log('totalMutableData:' + ab2hexArr(totalMutableData))
  299. let totalChar = totalMutableData;
  300. let pbChar = [];
  301. pbChar[0] = 0xA1;
  302. pbChar[1] = totalMutableData.length;
  303. pbChar.push.apply(pbChar, totalChar);
  304. let reallyData = pbChar;
  305. console.log('reallyData:' + ab2hexArr(reallyData))
  306. mTransData = []
  307. if (!makeXXCmdPacket(cmdType, reallyData)) {
  308. subReqDataAndMakeEtcProtoPacket(mTransData)
  309. }
  310. }
  311. function makeMutiPackageData(xxCmdData, dataIndex) {
  312. let index = 0;
  313. let cmdDataLen = xxCmdData.length;
  314. let cmdPacketDataLen = cmdDataLen + 12;
  315. let pbData = []
  316. pbData[index++] = 0xA4; //1
  317. pbData[index++] = 0x00; //Len2 1字节长度,真实数值后续代码算 2
  318. //stable data
  319. pbData[index++] = 0x38; //3
  320. pbData[index++] = 0x01; //4
  321. pbData[index++] = dataIndex; //5
  322. pbData[index++] = 0x39; //6
  323. pbData[index++] = cmdDataLen; //Len3
  324. pbData.push.apply(pbData, xxCmdData)
  325. index += cmdDataLen;
  326. //stable data
  327. pbData[index++] = 0x3C;
  328. pbData[index++] = 0x01;
  329. pbData[index++] = 0x00;
  330. // pbData[index++] = 0x00;
  331. // pbData[index] = 0x00;
  332. pbData[1] = cmdDataLen + 3 + 2 + 3;
  333. return pbData;
  334. }
  335. function subReqDataAndMakeEtcProtoPacket(etcProtoData) {
  336. let hr = 0;
  337. let totalDataLen = etcProtoData.length;
  338. console.log('**** maxLenPerPacket:' + maxLenPerPacket)
  339. let blockSize = maxLenPerPacket;
  340. let offset = 0
  341. if (blockSize == undefined) {
  342. blockSize = 100
  343. }
  344. let YuShu = totalDataLen % blockSize;
  345. let PackNumOffset = 0;
  346. let PackNum = (YuShu == 0) ? (totalDataLen / blockSize) : (parseInt(totalDataLen / blockSize) + 1);
  347. let LastPackSize = (YuShu == 0) ? ETC_PRO_SINGLE_PACK_SIZE : YuShu;
  348. let pSendBuf = etcProtoData;
  349. let sendBuff = [];
  350. mSingleEtcProtoData = [];
  351. let _pack = {}
  352. _pack.perPackSize = blockSize
  353. _pack.finalPackSize = LastPackSize
  354. _pack.packNum = PackNum
  355. if (totalDataLen > blockSize) {
  356. for (; offset < (totalDataLen - blockSize); offset += blockSize) {
  357. _pack.packNumOffset = PackNumOffset;
  358. sendBuff.push.apply(sendBuff, pSendBuf.slice(offset, offset + blockSize))
  359. hr = makeSingleEtcProtocolPaket(sendBuff, _pack)
  360. if (hr != 0) {
  361. return hr;
  362. }
  363. PackNumOffset++;
  364. hr = tranmitBleBlock()
  365. if (hr != 0) {
  366. return hr;
  367. }
  368. sendBuff = []
  369. }
  370. }
  371. _pack.packNumOffset = PackNumOffset;
  372. sendBuff.push.apply(sendBuff, pSendBuf.slice(offset, totalDataLen))
  373. let data = sendBuff.slice(0, totalDataLen - offset)
  374. hr = makeSingleEtcProtocolPaket(data, _pack)
  375. if (hr != 0) {
  376. return hr;
  377. }
  378. console.log('tranmitBleBlock(' + mSingleEtcProtoData.length + '):' + ab2hexArr(mSingleEtcProtoData))
  379. return tranmitBleBlock()
  380. }
  381. function makeSingleEtcProtocolPaket(ectCmdRawData, sPack) {
  382. let SendCTL = sPack.packNum - sPack.packNumOffset - 1;
  383. let IsLastPack = ((sPack.packNumOffset + 1) == sPack.packNum) ? 1 : 0;
  384. let DataLen = 0;
  385. let SendLen = 0;
  386. let etcCmdRawDataLen = ectCmdRawData.length;
  387. let etcCmdRawBufLen = etcCmdRawDataLen + 5;
  388. let etcCmdRawBuf = [];
  389. SendCTL = (sPack.packNumOffset == 0) ? (BLE_CTL_START_BIT | SendCTL) : SendCTL;
  390. DataLen = IsLastPack ? sPack.finalPackSize : sPack.perPackSize; //ETC_PRO_SINGLE_PACK_SIZE;
  391. /* 33协议组包*/
  392. etcCmdRawBuf[SendLen++] = BLE_ETC_PRO_HEAD_ST; //ST
  393. etcCmdRawBuf[SendLen++] = 0x00; //sPack.packNumOffset+1;//0x00;
  394. etcCmdRawBuf[SendLen++] = SendCTL; //CTL
  395. etcCmdRawBuf[SendLen++] = etcCmdRawDataLen; //LEN
  396. etcCmdRawBuf.push.apply(etcCmdRawBuf, ectCmdRawData);
  397. SendLen += ectCmdRawData.length;
  398. etcCmdRawBuf[SendLen++] = XorVerify(etcCmdRawBuf.slice(1), (ectCmdRawData.length + 3)); //BCC校验,从SN到DATA
  399. console.log('*****makeSingleEtcPacket : ' + ab2hexArr(etcCmdRawBuf))
  400. return makeSingleProtoPacket(etcCmdRawBuf)
  401. }
  402. function XorVerify(buf, len) {
  403. let TempVerify = 0x00;
  404. let i = 0;
  405. for (i = 0; i < len; i++) {
  406. TempVerify ^= buf[i];
  407. }
  408. return TempVerify
  409. }
  410. function AppSetVarints(inValue) {
  411. if (inValue < 128) {
  412. mLenBuf[0] = inValue;
  413. mBytesNumOfDataLen = 1;
  414. } else {
  415. mLenBuf[0] = (inValue & 0x7F) | 0x80;
  416. mLenBuf[1] = (inValue >> 7) & 0x7F;
  417. mBytesNumOfDataLen = 2;
  418. }
  419. }
  420. function makeSingleProtoPacket(etcEnclosurBuf) {
  421. let index = 0;
  422. let ManufactoryDefineKeyValue = 0; //厂商自定义数据长度,根据不同值设置不同数据
  423. let sDataLen = etcEnclosurBuf.length;
  424. if (sDataLen == 0 || sDataLen > (MAX_WECHAT_SEND_LEN - 12)) {
  425. console.log('[ERROR] Wechat send len error, return!')
  426. return 1;
  427. }
  428. mLenBuf = []
  429. mBytesNumOfDataLen = 0;
  430. AppSetVarints(sDataLen)
  431. let protoBufLen = sDataLen + 11 + mBytesNumOfDataLen + ManufactoryDefineKeyValue;
  432. let protoBuf = [];
  433. protoBuf[index++] = WECHAT_PRO_HEAD_MAGIC_NUMBER;
  434. protoBuf[index++] = WECHAT_PRO_HEAD_PACK_VERSION;
  435. protoBuf[index++] = (protoBufLen >> 8) & 0xff;
  436. protoBuf[index++] = (protoBufLen) & 0xff;
  437. protoBuf[index++] = (WECHAT_CMD_ECI_PUSH_RECV_DATA >> 8) & 0xff;
  438. protoBuf[index++] = (WECHAT_CMD_ECI_PUSH_RECV_DATA) & 0xff;
  439. protoBuf[index++] = 0x00;
  440. protoBuf[index++] = 0x00;
  441. /* 变长包体,key1-value1 - key2-value2 - key3-value3... ,value=len+data 具体可参考protobuf协议*/
  442. protoBuf[index++] = 0x0A; //可认为固定值
  443. protoBuf[index++] = 0x00;
  444. protoBuf[index++] = 0x12; //data域key值;
  445. protoBuf[index++] = mLenBuf[0]; //data域lenth
  446. if (mBytesNumOfDataLen == 2) {
  447. protoBuf[index++] = mLenBuf[1];
  448. }
  449. protoBuf.push.apply(protoBuf, etcEnclosurBuf)
  450. index += sDataLen;
  451. if (ManufactoryDefineKeyValue == 2) //暂时未用到
  452. {
  453. protoBuf[index++] = 0x18;
  454. protoBuf[index++] = 0x00;
  455. }
  456. if (ManufactoryDefineKeyValue == 3) //暂时未用到
  457. {
  458. protoBuf[index++] = 0x18;
  459. protoBuf[index++] = 0x91;
  460. protoBuf[index++] = 0x4e;
  461. }
  462. mSingleEtcProtoData = []
  463. mSingleEtcProtoData.push.apply(mSingleEtcProtoData, protoBuf.slice(0, index))
  464. console.log('*****makeSingleProtoPacket : ' + ab2hexArr(mSingleEtcProtoData))
  465. return 0;
  466. }
  467. function tranmitBleBlock() {
  468. let totalDataLen = mSingleEtcProtoData.length;
  469. let blockSize = MAX_BLE_SIZE;
  470. let offset = 0;
  471. if (blockSize <= 0) {
  472. return 1;
  473. }
  474. let pSendBuf = mSingleEtcProtoData;
  475. let sendBuff = [];
  476. if (totalDataLen > blockSize) {
  477. for (; offset < totalDataLen - blockSize; offset += blockSize) {
  478. sendBuff.push.apply(sendBuff, pSendBuf.slice(offset, blockSize + offset))
  479. let data = sendBuff.slice(0, blockSize)
  480. console.log('tranmitBleBlock part:(' + blockSize + '),data:' + ab2hexArr(data))
  481. writeData(data)
  482. sendBuff = []
  483. }
  484. }
  485. sendBuff.push.apply(sendBuff, pSendBuf.slice(offset, totalDataLen))
  486. let data = sendBuff.slice(0, totalDataLen - offset)
  487. console.log('tranmitBleBlock part:(' + (totalDataLen - offset) + '),data:' + ab2hexArr(data))
  488. writeData(data)
  489. return 0;
  490. }
  491. function write(arrayBuffer) {
  492. uni.writeBLECharacteristicValue({
  493. deviceId: mDeviceId,
  494. serviceId: mServiceId,
  495. characteristicId: mWriteUUID,
  496. value: arrayBuffer,
  497. success: function(res) {
  498. console.log('发送成功')
  499. },
  500. fail: function (e) {
  501. }
  502. })
  503. }
  504. function writeData(data) {
  505. let arrayBuffer = new Uint8Array(data).buffer;
  506. uni.writeBLECharacteristicValue({
  507. deviceId: mDeviceId,
  508. serviceId: mServiceId,
  509. characteristicId: mWriteUUID,
  510. value: arrayBuffer,
  511. success: function(res) {
  512. console.log('发送成功')
  513. },
  514. })
  515. }
  516. function ab2hex(buffer) {
  517. let hexArr = Array.prototype.map.call(
  518. new Uint8Array(buffer),
  519. function(bit) {
  520. return ('00' + bit.toString(16)).slice(-2)
  521. }
  522. )
  523. return hexArr.join('');
  524. }
  525. function ab2DecArr(buffer) {
  526. return new Uint8Array(buffer);
  527. }
  528. function ab2hexArr(arr) {
  529. let hexArr = Array.prototype.map.call(
  530. arr,
  531. function(bit) {
  532. return ('00' + bit.toString(16)).slice(-2)
  533. }
  534. )
  535. return hexArr;
  536. }
  537. function makeHandShakeStep1WithETC() {
  538. let cBuff = []
  539. let index = 0
  540. cBuff[index++] = 0xFE;
  541. cBuff[index++] = 0x01;
  542. cBuff[index++] = 0x00;
  543. cBuff[index++] = 0x0E;
  544. cBuff[index++] = 0x4E;
  545. cBuff[index++] = 0x21;
  546. cBuff[index++] = 0x00;
  547. cBuff[index++] = 0x01;
  548. cBuff[index++] = 0x0A;
  549. cBuff[index++] = 0x02;
  550. cBuff[index++] = 0x08;
  551. cBuff[index++] = 0x00;
  552. cBuff[index++] = 0x12;
  553. cBuff[index] = 0x00;
  554. return new Uint8Array(cBuff).buffer;
  555. }
  556. function makeHandShakeStep2WithETC() {
  557. let cBuff = []
  558. let index = 0
  559. cBuff[index++] = 0xFE;
  560. cBuff[index++] = 0x01;
  561. cBuff[index++] = 0x00;
  562. cBuff[index++] = 0x13;
  563. cBuff[index++] = 0x4E;
  564. cBuff[index++] = 0x23;
  565. cBuff[index++] = 0x00;
  566. cBuff[index++] = 0x02;
  567. cBuff[index++] = 0x0A;
  568. cBuff[index++] = 0x02;
  569. cBuff[index++] = 0x08;
  570. cBuff[index++] = 0x00;
  571. cBuff[index++] = 0x10;
  572. cBuff[index++] = 0xB4;
  573. cBuff[index++] = 0x24;
  574. cBuff[index++] = 0x18;
  575. cBuff[index++] = 0xF8;
  576. cBuff[index++] = 0xAC;
  577. cBuff[index] = 0x01;
  578. return new Uint8Array(cBuff).buffer;
  579. }
  580. function makeInitWithETC() {
  581. let cBuff = []
  582. let index = 0
  583. cBuff[index++] = 0xFE;
  584. cBuff[index++] = 0x01;
  585. cBuff[index++] = 0x00;
  586. cBuff[index++] = 0x14;
  587. cBuff[index++] = 0x75;
  588. cBuff[index++] = 0x31;
  589. cBuff[index++] = 0x00;
  590. cBuff[index++] = 0x02;
  591. cBuff[index++] = 0x0A;
  592. cBuff[index++] = 0x00;
  593. cBuff[index++] = 0x12;
  594. cBuff[index++] = 0x06;
  595. cBuff[index++] = 0x33;
  596. cBuff[index++] = 0x0A;
  597. cBuff[index++] = 0x80;
  598. cBuff[index++] = 0x01;
  599. cBuff[index++] = 0xA2;
  600. cBuff[index++] = 0x29;
  601. cBuff[index++] = 0x18;
  602. cBuff[index] = 0x00;
  603. return new Uint8Array(cBuff).buffer;
  604. }
  605. function makeDisconnectWithETC() {
  606. let cBuff = []
  607. let index = 0
  608. cBuff[index++] = 0xFE;
  609. cBuff[index++] = 0x01;
  610. cBuff[index++] = 0x00;
  611. cBuff[index++] = 0x14;
  612. cBuff[index++] = 0x75;
  613. cBuff[index++] = 0x31;
  614. cBuff[index++] = 0x00;
  615. cBuff[index++] = 0x02;
  616. cBuff[index++] = 0x0A;
  617. cBuff[index++] = 0x00;
  618. cBuff[index++] = 0x12;
  619. cBuff[index++] = 0x06;
  620. cBuff[index++] = 0x33;
  621. cBuff[index++] = 0x0A;
  622. cBuff[index++] = 0x80;
  623. cBuff[index++] = 0x01;
  624. cBuff[index++] = 0xAE;
  625. cBuff[index] = 0x25;
  626. return new Uint8Array(cBuff).buffer;
  627. }
  628. function unpaketProto(recvDataCache) {
  629. let data = recvDataCache.slice(12)
  630. let dataLen = recvDataCache[13]
  631. let st = data[0];
  632. let ctl = data[2];
  633. let dataLet = data[3];
  634. let ndata = data.slice(4);
  635. let StartPackFlag = ((ctl & 0x80) > 0) ? true : false
  636. let CurrentPackNum = ctl & 0x7F;
  637. mCurrentPacketNum = CurrentPackNum;
  638. let operatorStatus = 0;
  639. if (st != 0x33) {
  640. return -1;
  641. console.log('[ERROR] The received data head ST is not right!')
  642. }
  643. if (StartPackFlag) {
  644. operatorStatus = 1;
  645. }
  646. mEtcRawData = ndata.slice(0, dataLen - 1)
  647. mEtcRawDataLen = dataLen
  648. return operatorStatus & CurrentPackNum;
  649. }
  650. function unpaketProto_1(recvDataCache) {
  651. console.log('***** recvDataCache:' + ab2hexArr(recvDataCache))
  652. let data = recvDataCache.slice(12)
  653. let dataLen = recvDataCache[13]
  654. let st = data[0];
  655. let ctl = data[2];
  656. let dataLet = data[3];
  657. let ndata = data.slice(4);
  658. let StartPackFlag = ((ctl & 0x80) > 0) ? true : false
  659. let CurrentPackNum = ctl & 0x7F;
  660. let operatorStatus = 0;
  661. if (st != 0x33) {
  662. return -1;
  663. console.log('[ERROR] The received data head ST is not right!')
  664. }
  665. if (StartPackFlag) {
  666. operatorStatus = 1;
  667. }
  668. mAbCmdBuf = ndata.slice(0, dataLen - 1)
  669. mnCmdBufLen = dataLen
  670. return operatorStatus & CurrentPackNum;
  671. }
  672. function unpackXXCmdPacket(recvDataCache) {
  673. mAbCmdBuf = recvDataCache;
  674. mnCmdBufLen = 0
  675. // unpaketProto_1(recvDataCache)
  676. // let cmdStatus = mAbCmdBuf[1];
  677. // if (cmdStatus != 0) {
  678. // return 4;
  679. // }
  680. let abCmdTLVLen = (mAbCmdBuf[4] << 8) + mAbCmdBuf[3];
  681. if (abCmdTLVLen <= 0) {
  682. receiveDataCallBack(makeRes(-1, [], '未插卡'))
  683. return
  684. }
  685. console.log('mAbCmdBuf[4]' + mAbCmdBuf[4] + ',mAbCmdBuf[3]:' + mAbCmdBuf[3])
  686. console.log('mAbCmdBuf:' + ab2hexArr(mAbCmdBuf))
  687. let abCmdTLVBuf = mAbCmdBuf.slice(5, abCmdTLVLen + 5)
  688. console.log('abCmdTLVLen' + abCmdTLVLen)
  689. console.log('abCmdTLVBuf:' + ab2hexArr(abCmdTLVBuf))
  690. if (abCmdTLVBuf[0] == 0xA3 && abCmdTLVBuf[2] == 0xA2) {
  691. let abCmdTLVBuf1 = abCmdTLVBuf.slice(2, abCmdTLVLen)
  692. let len = abCmdTLVLen - 2;
  693. while (len > 0) {
  694. let rData = abCmdTLVBuf1.slice(3, abCmdTLVBuf1[1] - 1 + 3)
  695. console.log('rData:' + ab2hexArr(rData))
  696. mReturnedRawCmdData.push(bytes2Str(rData))
  697. abCmdTLVBuf1 = abCmdTLVBuf1.slice(3 + abCmdTLVBuf1[1] - 1, abCmdTLVBuf1.length)
  698. console.log('abCmdTLVBuf1:' + ab2hexArr(abCmdTLVBuf1))
  699. len = abCmdTLVBuf1.length;
  700. console.log('len:' + len)
  701. }
  702. } else {
  703. return 5;
  704. }
  705. return 0;
  706. }
  707. function makeXXCmdPacket(cmdType, reqData) {
  708. let index = 0;
  709. let cmdDataLen = reqData.length
  710. let cmdPacketDataLen = cmdDataLen + 10;
  711. let pbData = [];
  712. if (KYunNanObuMultiplePackages == 0) {
  713. pbData[index++] = ((cmdType == 0xA3) ? cmdType : 0xA8); // PICC 通道 0
  714. pbData[index++] = 0x00; // 明文数据 01 加密数据 1
  715. pbData[index++] = 0x00; //总长度 2
  716. pbData[index++] = 0x00; //总长度,后续代码会算 3
  717. pbData[index++] = 0xA1; //4
  718. pbData[index++] = 0x00; //Len1 1字节长度,真实数值后续代码算 5
  719. pbData[index++] = 0xA4; //6
  720. pbData[index++] = 0x00; //Len2 1字节长度,真实数值后续代码算 7
  721. //stable data
  722. pbData[index++] = 0x38; //8
  723. pbData[index++] = 0x01; //9
  724. pbData[index++] = 0x01; //10
  725. pbData[index++] = 0x39; //11
  726. pbData[index++] = cmdDataLen; //Len3
  727. pbData.push.apply(pbData, reqData)
  728. index += cmdDataLen;
  729. //stable data
  730. pbData[index++] = 0x3C;
  731. pbData[index++] = 0x03;
  732. pbData[index++] = 0x90;
  733. pbData[index++] = 0x00;
  734. pbData[index] = 0x00;
  735. pbData[7] = cmdDataLen + 1 + 9; //Len2长度 = 指令数据长度+两组固定数据长度+cmdDatalen自身长度标识1字节
  736. pbData[5] = pbData[7] + 2; //2包含固定数据0xA4与 pbData[7]本身长度标识1字节
  737. pbData[2] = ((pbData[5] + 2) & 0xff);
  738. pbData[3] = ((pbData[5]) >> 8) & 0xff; //总长度 小端模式
  739. } else {
  740. pbData[index++] = ((cmdType == 0xA3) ? cmdType : 0xA8);
  741. pbData[index++] = 0x00; //0 明文 1密文
  742. pbData[index++] = (cmdDataLen & 0xff); //总长度
  743. pbData[index++] = (cmdDataLen >> 8) & 0xff; //总长度,后续代码会算
  744. pbData.push.apply(pbData, reqData)
  745. }
  746. mTransData.push.apply(mTransData, pbData.slice(0, pbData[5] + 6))
  747. return 0;
  748. }
  749. function str2Bytes(str) {
  750. var pos = 0;
  751. var len = str.length;
  752. if (len % 2 != 0) {
  753. return null;
  754. }
  755. len /= 2;
  756. var hexA = new Array();
  757. for (var i = 0; i < len; i++) {
  758. var s = str.substr(pos, 2);
  759. var v = parseInt(s, 16);
  760. hexA.push(v);
  761. pos += 2;
  762. }
  763. return hexA;
  764. }
  765. function bytes2Str(arr) {
  766. var str = "";
  767. for (var i = 0; i < arr.length; i++) {
  768. var tmp = arr[i].toString(16);
  769. if (tmp.length == 1) {
  770. tmp = "0" + tmp;
  771. }
  772. str += tmp;
  773. }
  774. return str;
  775. }
  776. function makeRes(code, data ,msg) {
  777. return {code: code, data: data, msg: msg}
  778. }
  779. module.exports = {
  780. connectDevice: connectDevice,
  781. transCmd: transCmd,
  782. disConnectDevice: disConnectDevice
  783. }