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.

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. }