選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

TDRObuSDK.js 29KB

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