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

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  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.4.2020092701"
  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. callback_2(makeRes(-1, [],
  149. '蓝牙已断开'))
  150. }
  151. }
  152. })
  153. my.offBLECharacteristicValueChange();
  154. my.notifyBLECharacteristicValueChange({
  155. deviceId: deviceId,
  156. serviceId: (m_IsIOS ? mServiceId_i :
  157. mServiceId),
  158. characteristicId: (m_IsIOS ?
  159. mNotifyUUID_i : mNotifyUUID),
  160. state: true,
  161. success: function(res) {
  162. my.onBLECharacteristicValueChange(
  163. function(res) {
  164. console.log(
  165. '收到数据:' +
  166. res.value)
  167. let pRead =
  168. str2Bytes(res
  169. .value)
  170. if (pRead.length >
  171. 0 && pRead !=
  172. null) {
  173. if (pRead[0] ==
  174. WECHAT_PRO_HEAD_MAGIC_NUMBER &&
  175. pRead[1] ==
  176. WECHAT_PRO_HEAD_PACK_VERSION
  177. ) {
  178. mPacketLen =
  179. (pRead[
  180. 2
  181. ] <<
  182. 8) |
  183. pRead[
  184. 3];
  185. }
  186. mRecvDataCache
  187. .push.apply(
  188. mRecvDataCache,
  189. pRead)
  190. if (mRecvDataCache
  191. .length ==
  192. mPacketLen
  193. ) {
  194. let pData =
  195. mRecvDataCache
  196. let nCmdID =
  197. (pData[
  198. 4
  199. ] <<
  200. 8) |
  201. pData[5]
  202. switch (
  203. nCmdID
  204. ) {
  205. case WECHAT_CMD_ECI_REQ_AUTH: {
  206. console
  207. .log(
  208. 'WECHAT_CMD_ECI_REQ_AUTH'
  209. )
  210. let data =
  211. makeHandShakeStep1WithETC()
  212. mRecvDataCache
  213. = []
  214. write
  215. (
  216. data
  217. )
  218. }
  219. break;
  220. case WECHAT_CMD_ECI_REQ_INIT: {
  221. console
  222. .log(
  223. 'WECHAT_CMD_ECI_REQ_INIT'
  224. )
  225. let data =
  226. makeHandShakeStep2WithETC()
  227. write
  228. (
  229. data
  230. )
  231. setTimeout
  232. (function() {
  233. let dataInit =
  234. makeInitWithETC()
  235. mRecvDataCache
  236. = []
  237. write
  238. (
  239. dataInit
  240. )
  241. mIsInitCmdSend
  242. =
  243. true
  244. },
  245. 20
  246. )
  247. }
  248. break;
  249. case WECHAT_CMD_ECI_REQ_SEND_DATA: {
  250. console
  251. .log(
  252. 'WECHAT_CMD_ECI_REQ_SEND_DATA'
  253. )
  254. if (
  255. mIsInitCmdSend
  256. ) {
  257. m_isConn
  258. =
  259. true
  260. callback_1
  261. (makeRes(
  262. 0,
  263. [],
  264. '连接成功'
  265. ))
  266. mIsInitCmdSend
  267. =
  268. false
  269. }
  270. mEtcRawData
  271. = []
  272. mEtcRawDataLen
  273. =
  274. 0
  275. let op =
  276. unpaketProto(
  277. mRecvDataCache
  278. )
  279. if (!
  280. op
  281. ) {
  282. if (mEtcRawData[
  283. 0
  284. ] ==
  285. 0xB2
  286. ) {
  287. maxLenPerPacket
  288. =
  289. mEtcRawData[
  290. 3
  291. ];
  292. } else {
  293. mUnpacketDataCache
  294. .push
  295. .apply(
  296. mUnpacketDataCache,
  297. mEtcRawData
  298. )
  299. console
  300. .log(
  301. '******返回未解析的指令数据包为:' +
  302. ab2hexArr(
  303. mUnpacketDataCache
  304. )
  305. )
  306. if (mCurrentPacketNum ==
  307. 0
  308. ) {
  309. mReturnedRawCmdData
  310. = []
  311. let errorcode =
  312. unpackXXCmdPacket(
  313. mUnpacketDataCache
  314. )
  315. console
  316. .log(
  317. '******解析后的指令数据为' +
  318. mReturnedRawCmdData
  319. )
  320. if (
  321. receiveDataCallBack
  322. ) {
  323. receiveDataCallBack
  324. (makeRes(
  325. errorcode,
  326. mReturnedRawCmdData,
  327. errorcode ==
  328. 0 ?
  329. '收到数据成功' :
  330. '数据透传失败'
  331. ))
  332. receiveDataCallBack
  333. =
  334. null
  335. }
  336. mUnpacketDataCache
  337. = []
  338. }
  339. }
  340. } else {
  341. mUnpacketDataCache
  342. .push
  343. .apply(
  344. mUnpacketDataCache,
  345. mEtcRawData
  346. )
  347. }
  348. mRecvDataCache
  349. = []
  350. }
  351. break;
  352. default:
  353. break;
  354. }
  355. }
  356. }
  357. })
  358. },
  359. fail: function(e) {
  360. callback_1(makeRes(-1, [],
  361. '连接失败'))
  362. }
  363. })
  364. },
  365. fail: function(res) {
  366. callback_1(makeRes(-1, [], '连接失败'))
  367. }
  368. })
  369. }
  370. },
  371. fail: function(res) {
  372. callback_1(makeRes(-1, [], '连接失败'))
  373. }
  374. })
  375. },
  376. fail: function(res) {
  377. // if (mConnCount > 0) {
  378. // console.log(mConnCount)
  379. // mConnCount--
  380. // connectDevice(device, callback_1, callback_2)
  381. // } else {
  382. // console.log(mConnCount)
  383. // mConnCount = 2
  384. // m_isConn = false;
  385. // callback_1(-1, [], '连接失败')
  386. // }
  387. callback_1(makeRes(-1, [], '连接失败'))
  388. }
  389. })
  390. }
  391. //断开与OBU设备的蓝牙连接
  392. function disconnectDevice(callBack) {
  393. if (!m_isConn) {
  394. callBack(makeRes(-1, [], '未连接'))
  395. return;
  396. }
  397. let data = makeDisconnectWithETC();
  398. mIsInitCmdSend = false;
  399. mRecvDataCache = []
  400. write(data)
  401. my.disconnectBLEDevice({
  402. deviceId: mDeviceId,
  403. success: function(res) {
  404. m_isConn = false;
  405. callBack(makeRes(0, [], '断开成功'))
  406. },
  407. fail: function(e) {
  408. console.log('error:' + e.errMsg)
  409. callBack(makeRes(-1, [], '断开失败'))
  410. }
  411. })
  412. }
  413. /**
  414. 数据透传
  415. @param cmd 指令[]
  416. @param cmdtype 明文:IC:10、ESAM:20
  417. @param callBack 回调函数
  418. status 成功为 true,失败为 false
  419. data NSData 回应数据(明文)+ 签名
  420. errorMsg 报错信息
  421. */
  422. function transCmd(cmd, cmdtype, callBack) {
  423. if (callBack) {
  424. receiveDataCallBack = callBack;
  425. }
  426. if (!m_isConn) {
  427. receiveDataCallBack(makeRes(-2, [], '连接失败'))
  428. return;
  429. }
  430. let cmdType = 0;
  431. if (cmdtype == '10') {
  432. cmdType = 0xA3;
  433. } else if (cmdtype == '20') {
  434. cmdType = 0xA8;
  435. }
  436. let totalMutableData = []
  437. for (var i = 0; i < cmd.length; i++) {
  438. let obj = str2Bytes(cmd[i]);
  439. console.log('##### cmd_:' + ab2hexArr(obj))
  440. let oneData = makeMutiPackageData(obj, i + 1)
  441. console.log('##### oneData:' + ab2hexArr(oneData))
  442. totalMutableData.push.apply(totalMutableData, oneData);
  443. }
  444. console.log('totalMutableData:' + ab2hexArr(totalMutableData))
  445. let totalChar = totalMutableData;
  446. let pbChar = [];
  447. pbChar[0] = 0xA1;
  448. pbChar[1] = totalMutableData.length;
  449. pbChar.push.apply(pbChar, totalChar);
  450. let reallyData = pbChar;
  451. console.log('reallyData:' + ab2hexArr(reallyData))
  452. mTransData = []
  453. if (!makeXXCmdPacket(cmdType, reallyData)) {
  454. subReqDataAndMakeEtcProtoPacket(mTransData)
  455. }
  456. }
  457. function makeMutiPackageData(xxCmdData, dataIndex) {
  458. let index = 0;
  459. let cmdDataLen = xxCmdData.length;
  460. let cmdPacketDataLen = cmdDataLen + 12;
  461. let pbData = []
  462. pbData[index++] = 0xA4; //1
  463. pbData[index++] = 0x00; //Len2 1字节长度,真实数值后续代码算 2
  464. //stable data
  465. pbData[index++] = 0x38; //3
  466. pbData[index++] = 0x01; //4
  467. pbData[index++] = dataIndex; //5
  468. pbData[index++] = 0x39; //6
  469. pbData[index++] = cmdDataLen; //Len3
  470. pbData.push.apply(pbData, xxCmdData)
  471. index += cmdDataLen;
  472. //stable data
  473. pbData[index++] = 0x3C;
  474. pbData[index++] = 0x01;
  475. pbData[index++] = 0x00;
  476. // pbData[index++] = 0x00;
  477. // pbData[index] = 0x00;
  478. pbData[1] = cmdDataLen + 3 + 2 + 3;
  479. return pbData;
  480. }
  481. function subReqDataAndMakeEtcProtoPacket(etcProtoData) {
  482. let hr = 0;
  483. let totalDataLen = etcProtoData.length;
  484. let blockSize = maxLenPerPacket;
  485. let offset = 0
  486. if (blockSize == undefined) {
  487. blockSize = 100
  488. }
  489. let YuShu = totalDataLen % blockSize;
  490. let PackNumOffset = 0;
  491. let PackNum = (YuShu == 0) ? (totalDataLen / blockSize) : (parseInt(totalDataLen / blockSize) + 1);
  492. let LastPackSize = (YuShu == 0) ? ETC_PRO_SINGLE_PACK_SIZE : YuShu;
  493. let pSendBuf = etcProtoData;
  494. let sendBuff = [];
  495. mSingleEtcProtoData = [];
  496. let _pack = {}
  497. _pack.perPackSize = blockSize
  498. _pack.finalPackSize = LastPackSize
  499. _pack.packNum = PackNum
  500. if (totalDataLen > blockSize) {
  501. for (; offset < (totalDataLen - blockSize); offset += blockSize) {
  502. _pack.packNumOffset = PackNumOffset;
  503. sendBuff.push.apply(sendBuff, pSendBuf.slice(offset, offset + blockSize))
  504. hr = makeSingleEtcProtocolPaket(sendBuff, _pack)
  505. if (hr != 0) {
  506. return hr;
  507. }
  508. PackNumOffset++;
  509. hr = tranmitBleBlock()
  510. if (hr != 0) {
  511. return hr;
  512. }
  513. sendBuff = []
  514. }
  515. }
  516. _pack.packNumOffset = PackNumOffset;
  517. sendBuff.push.apply(sendBuff, pSendBuf.slice(offset, totalDataLen))
  518. let data = sendBuff.slice(0, totalDataLen - offset)
  519. hr = makeSingleEtcProtocolPaket(data, _pack)
  520. if (hr != 0) {
  521. return hr;
  522. }
  523. console.log('tranmitBleBlock(' + mSingleEtcProtoData.length + '):' + ab2hexArr(mSingleEtcProtoData))
  524. return tranmitBleBlock()
  525. }
  526. function makeSingleEtcProtocolPaket(ectCmdRawData, sPack) {
  527. let SendCTL = sPack.packNum - sPack.packNumOffset - 1;
  528. let IsLastPack = ((sPack.packNumOffset + 1) == sPack.packNum) ? 1 : 0;
  529. let DataLen = 0;
  530. let SendLen = 0;
  531. let etcCmdRawDataLen = ectCmdRawData.length;
  532. let etcCmdRawBufLen = etcCmdRawDataLen + 5;
  533. let etcCmdRawBuf = [];
  534. SendCTL = (sPack.packNumOffset == 0) ? (BLE_CTL_START_BIT | SendCTL) : SendCTL;
  535. DataLen = IsLastPack ? sPack.finalPackSize : sPack.perPackSize; //ETC_PRO_SINGLE_PACK_SIZE;
  536. /* 33协议组包*/
  537. etcCmdRawBuf[SendLen++] = BLE_ETC_PRO_HEAD_ST; //ST
  538. etcCmdRawBuf[SendLen++] = 0x00; //sPack.packNumOffset+1;//0x00;
  539. etcCmdRawBuf[SendLen++] = SendCTL; //CTL
  540. etcCmdRawBuf[SendLen++] = etcCmdRawDataLen; //LEN
  541. etcCmdRawBuf.push.apply(etcCmdRawBuf, ectCmdRawData);
  542. SendLen += ectCmdRawData.length;
  543. etcCmdRawBuf[SendLen++] = XorVerify(etcCmdRawBuf.slice(1), (ectCmdRawData.length + 3)); //BCC校验,从SN到DATA
  544. console.log('*****makeSingleEtcPacket : ' + ab2hexArr(etcCmdRawBuf))
  545. return makeSingleProtoPacket(etcCmdRawBuf)
  546. }
  547. function XorVerify(buf, len) {
  548. let TempVerify = 0x00;
  549. let i = 0;
  550. for (i = 0; i < len; i++) {
  551. TempVerify ^= buf[i];
  552. }
  553. return TempVerify
  554. }
  555. function AppSetVarints(inValue) {
  556. if (inValue < 128) {
  557. mLenBuf[0] = inValue;
  558. mBytesNumOfDataLen = 1;
  559. } else {
  560. mLenBuf[0] = (inValue & 0x7F) | 0x80;
  561. mLenBuf[1] = (inValue >> 7) & 0x7F;
  562. mBytesNumOfDataLen = 2;
  563. }
  564. }
  565. function makeSingleProtoPacket(etcEnclosurBuf) {
  566. let index = 0;
  567. let ManufactoryDefineKeyValue = 0; //厂商自定义数据长度,根据不同值设置不同数据
  568. let sDataLen = etcEnclosurBuf.length;
  569. if (sDataLen == 0 || sDataLen > (MAX_WECHAT_SEND_LEN - 12)) {
  570. console.log('[ERROR] Wechat send len error, return!')
  571. return 1;
  572. }
  573. mLenBuf = []
  574. mBytesNumOfDataLen = 0;
  575. AppSetVarints(sDataLen)
  576. let protoBufLen = sDataLen + 11 + mBytesNumOfDataLen + ManufactoryDefineKeyValue;
  577. let protoBuf = [];
  578. protoBuf[index++] = WECHAT_PRO_HEAD_MAGIC_NUMBER;
  579. protoBuf[index++] = WECHAT_PRO_HEAD_PACK_VERSION;
  580. protoBuf[index++] = (protoBufLen >> 8) & 0xff;
  581. protoBuf[index++] = (protoBufLen) & 0xff;
  582. protoBuf[index++] = (WECHAT_CMD_ECI_PUSH_RECV_DATA >> 8) & 0xff;
  583. protoBuf[index++] = (WECHAT_CMD_ECI_PUSH_RECV_DATA) & 0xff;
  584. protoBuf[index++] = 0x00;
  585. protoBuf[index++] = 0x00;
  586. /* 变长包体,key1-value1 - key2-value2 - key3-value3... ,value=len+data 具体可参考protobuf协议*/
  587. protoBuf[index++] = 0x0A; //可认为固定值
  588. protoBuf[index++] = 0x00;
  589. protoBuf[index++] = 0x12; //data域key值;
  590. protoBuf[index++] = mLenBuf[0]; //data域lenth
  591. if (mBytesNumOfDataLen == 2) {
  592. protoBuf[index++] = mLenBuf[1];
  593. }
  594. protoBuf.push.apply(protoBuf, etcEnclosurBuf)
  595. index += sDataLen;
  596. if (ManufactoryDefineKeyValue == 2) //暂时未用到
  597. {
  598. protoBuf[index++] = 0x18;
  599. protoBuf[index++] = 0x00;
  600. }
  601. if (ManufactoryDefineKeyValue == 3) //暂时未用到
  602. {
  603. protoBuf[index++] = 0x18;
  604. protoBuf[index++] = 0x91;
  605. protoBuf[index++] = 0x4e;
  606. }
  607. mSingleEtcProtoData = []
  608. mSingleEtcProtoData.push.apply(mSingleEtcProtoData, protoBuf.slice(0, index))
  609. console.log('*****makeSingleProtoPacket : ' + ab2hexArr(mSingleEtcProtoData))
  610. return 0;
  611. }
  612. function tranmitBleBlock() {
  613. let totalDataLen = mSingleEtcProtoData.length;
  614. let blockSize = MAX_BLE_SIZE;
  615. let offset = 0;
  616. if (blockSize <= 0) {
  617. return 1;
  618. }
  619. let pSendBuf = mSingleEtcProtoData;
  620. let sendBuff = [];
  621. if (totalDataLen > blockSize) {
  622. for (; offset < totalDataLen - blockSize; offset += blockSize) {
  623. sendBuff.push.apply(sendBuff, pSendBuf.slice(offset, blockSize + offset))
  624. let data = sendBuff.slice(0, blockSize)
  625. console.log('tranmitBleBlock part:(' + blockSize + '),data:' + ab2hexArr(data))
  626. writeData(data)
  627. sendBuff = []
  628. sleep(100)
  629. }
  630. }
  631. sendBuff.push.apply(sendBuff, pSendBuf.slice(offset, totalDataLen))
  632. let data = sendBuff.slice(0, totalDataLen - offset)
  633. console.log('tranmitBleBlock part:(' + (totalDataLen - offset) + '),data:' + ab2hexArr(data))
  634. writeData(data)
  635. return 0;
  636. }
  637. function sleep(delay) {
  638. var start = (new Date()).getTime();
  639. while ((new Date()).getTime() - start < delay) {
  640. continue;
  641. }
  642. }
  643. function write(arrayBuffer) {
  644. console.log('发送:' + ab2hex(arrayBuffer))
  645. my.writeBLECharacteristicValue({
  646. deviceId: mDeviceId,
  647. serviceId: (m_IsIOS ? mServiceId_i : mServiceId),
  648. characteristicId: (m_IsIOS ? mWriteUUID_i : mWriteUUID),
  649. value: ab2hex(arrayBuffer),
  650. success: function(res) {
  651. console.log('发送成功')
  652. },
  653. fail: function(e) {
  654. console.log('发送失败')
  655. }
  656. })
  657. }
  658. function writeData(data) {
  659. // let arrayBuffer = new Uint8Array(data).buffer;
  660. console.log('发送Data:' + data)
  661. my.writeBLECharacteristicValue({
  662. deviceId: mDeviceId,
  663. serviceId: (m_IsIOS ? mServiceId_i : mServiceId),
  664. characteristicId: (m_IsIOS ? mWriteUUID_i : mWriteUUID),
  665. value: ab2hex(data),
  666. success: function(res) {
  667. console.log('发送成功')
  668. },
  669. fail: function(e) {
  670. console.log('发送失败')
  671. }
  672. })
  673. }
  674. function ab2hex(buffer) {
  675. let hexArr = Array.prototype.map.call(
  676. new Uint8Array(buffer),
  677. function(bit) {
  678. return ('00' + bit.toString(16)).slice(-2)
  679. }
  680. )
  681. return hexArr.join('');
  682. }
  683. function ab2DecArr(buffer) {
  684. return new Uint8Array(buffer);
  685. }
  686. function ab2hexArr(arr) {
  687. let hexArr = Array.prototype.map.call(
  688. arr,
  689. function(bit) {
  690. return ('00' + bit.toString(16)).slice(-2)
  691. }
  692. )
  693. return hexArr;
  694. }
  695. function makeHandShakeStep1WithETC() {
  696. let cBuff = []
  697. let index = 0
  698. cBuff[index++] = 0xFE;
  699. cBuff[index++] = 0x01;
  700. cBuff[index++] = 0x00;
  701. cBuff[index++] = 0x0E;
  702. cBuff[index++] = 0x4E;
  703. cBuff[index++] = 0x21;
  704. cBuff[index++] = 0x00;
  705. cBuff[index++] = 0x01;
  706. cBuff[index++] = 0x0A;
  707. cBuff[index++] = 0x02;
  708. cBuff[index++] = 0x08;
  709. cBuff[index++] = 0x00;
  710. cBuff[index++] = 0x12;
  711. cBuff[index] = 0x00;
  712. return new Uint8Array(cBuff).buffer;
  713. }
  714. function makeHandShakeStep2WithETC() {
  715. let cBuff = []
  716. let index = 0
  717. cBuff[index++] = 0xFE;
  718. cBuff[index++] = 0x01;
  719. cBuff[index++] = 0x00;
  720. cBuff[index++] = 0x13;
  721. cBuff[index++] = 0x4E;
  722. cBuff[index++] = 0x23;
  723. cBuff[index++] = 0x00;
  724. cBuff[index++] = 0x02;
  725. cBuff[index++] = 0x0A;
  726. cBuff[index++] = 0x02;
  727. cBuff[index++] = 0x08;
  728. cBuff[index++] = 0x00;
  729. cBuff[index++] = 0x10;
  730. cBuff[index++] = 0xB4;
  731. cBuff[index++] = 0x24;
  732. cBuff[index++] = 0x18;
  733. cBuff[index++] = 0xF8;
  734. cBuff[index++] = 0xAC;
  735. cBuff[index] = 0x01;
  736. return new Uint8Array(cBuff).buffer;
  737. }
  738. function makeInitWithETC() {
  739. let cBuff = []
  740. let index = 0
  741. cBuff[index++] = 0xFE;
  742. cBuff[index++] = 0x01;
  743. cBuff[index++] = 0x00;
  744. cBuff[index++] = 0x14;
  745. cBuff[index++] = 0x75;
  746. cBuff[index++] = 0x31;
  747. cBuff[index++] = 0x00;
  748. cBuff[index++] = 0x02;
  749. cBuff[index++] = 0x0A;
  750. cBuff[index++] = 0x00;
  751. cBuff[index++] = 0x12;
  752. cBuff[index++] = 0x06;
  753. cBuff[index++] = 0x33;
  754. cBuff[index++] = 0x0A;
  755. cBuff[index++] = 0x80;
  756. cBuff[index++] = 0x01;
  757. cBuff[index++] = 0xA2;
  758. cBuff[index++] = 0x29;
  759. cBuff[index++] = 0x18;
  760. cBuff[index] = 0x00;
  761. return new Uint8Array(cBuff).buffer;
  762. }
  763. function makeDisconnectWithETC() {
  764. let cBuff = []
  765. let index = 0
  766. cBuff[index++] = 0xFE;
  767. cBuff[index++] = 0x01;
  768. cBuff[index++] = 0x00;
  769. cBuff[index++] = 0x14;
  770. cBuff[index++] = 0x75;
  771. cBuff[index++] = 0x31;
  772. cBuff[index++] = 0x00;
  773. cBuff[index++] = 0x02;
  774. cBuff[index++] = 0x0A;
  775. cBuff[index++] = 0x00;
  776. cBuff[index++] = 0x12;
  777. cBuff[index++] = 0x06;
  778. cBuff[index++] = 0x33;
  779. cBuff[index++] = 0x0A;
  780. cBuff[index++] = 0x80;
  781. cBuff[index++] = 0x01;
  782. cBuff[index++] = 0xAE;
  783. cBuff[index] = 0x25;
  784. return new Uint8Array(cBuff).buffer;
  785. }
  786. function unpaketProto(recvDataCache) {
  787. let data = recvDataCache.slice(12)
  788. let dataLen = recvDataCache[13]
  789. let st = data[0];
  790. let ctl = data[2];
  791. let dataLet = data[3];
  792. let ndata = data.slice(4);
  793. let StartPackFlag = ((ctl & 0x80) > 0) ? true : false
  794. let CurrentPackNum = ctl & 0x7F;
  795. mCurrentPacketNum = CurrentPackNum;
  796. let operatorStatus = 0;
  797. if (st != 0x33) {
  798. return -1;
  799. console.log('[ERROR] The received data head ST is not right!')
  800. }
  801. if (StartPackFlag) {
  802. operatorStatus = 1;
  803. }
  804. mEtcRawData = ndata.slice(0, dataLen - 1)
  805. mEtcRawDataLen = dataLen
  806. return operatorStatus & CurrentPackNum;
  807. }
  808. function unpaketProto_1(recvDataCache) {
  809. let data = recvDataCache.slice(12)
  810. let dataLen = recvDataCache[13]
  811. let st = data[0];
  812. let ctl = data[2];
  813. let dataLet = data[3];
  814. let ndata = data.slice(4);
  815. let StartPackFlag = ((ctl & 0x80) > 0) ? true : false
  816. let CurrentPackNum = ctl & 0x7F;
  817. let operatorStatus = 0;
  818. if (st != 0x33) {
  819. return -1;
  820. console.log('[ERROR] The received data head ST is not right!')
  821. }
  822. if (StartPackFlag) {
  823. operatorStatus = 1;
  824. }
  825. mAbCmdBuf = ndata.slice(0, dataLen - 1)
  826. mnCmdBufLen = dataLen
  827. return operatorStatus & CurrentPackNum;
  828. }
  829. function unpackXXCmdPacket(recvDataCache) {
  830. mAbCmdBuf = recvDataCache;
  831. // mnCmdBufLen = 0
  832. // unpaketProto_1(recvDataCache)
  833. // let cmdStatus = mAbCmdBuf[1];
  834. // if (cmdStatus != 0) {
  835. // return 4;
  836. // }
  837. let abCmdTLVLen = (mAbCmdBuf[4] << 8) + mAbCmdBuf[3];
  838. if (abCmdTLVLen <= 0) {
  839. receiveDataCallBack(makeRes(-1, [], '未插卡'))
  840. return
  841. }
  842. let abCmdTLVBuf = mAbCmdBuf.slice(5, abCmdTLVLen + 5)
  843. if (abCmdTLVBuf[0] == 0xA3 && abCmdTLVBuf[2] == 0xA2) {
  844. let abCmdTLVBuf1 = abCmdTLVBuf.slice(2, abCmdTLVLen)
  845. let len = abCmdTLVLen - 2;
  846. while (len > 0) {
  847. let rData = abCmdTLVBuf1.slice(3, abCmdTLVBuf1[1] - 1 + 3)
  848. mReturnedRawCmdData.push(bytes2Str(rData))
  849. abCmdTLVBuf1 = abCmdTLVBuf1.slice(3 + abCmdTLVBuf1[1] - 1, abCmdTLVBuf1.length)
  850. len = abCmdTLVBuf1.length;
  851. }
  852. } else {
  853. return 5;
  854. }
  855. return 0;
  856. }
  857. function makeXXCmdPacket(cmdType, reqData) {
  858. let index = 0;
  859. let cmdDataLen = reqData.length
  860. let cmdPacketDataLen = cmdDataLen + 10;
  861. let pbData = [];
  862. if (KYunNanObuMultiplePackages == 0) {
  863. pbData[index++] = ((cmdType == 0xA3) ? cmdType : 0xA8); // PICC 通道 0
  864. pbData[index++] = 0x00; // 明文数据 01 加密数据 1
  865. pbData[index++] = 0x00; //总长度 2
  866. pbData[index++] = 0x00; //总长度,后续代码会算 3
  867. pbData[index++] = 0xA1; //4
  868. pbData[index++] = 0x00; //Len1 1字节长度,真实数值后续代码算 5
  869. pbData[index++] = 0xA4; //6
  870. pbData[index++] = 0x00; //Len2 1字节长度,真实数值后续代码算 7
  871. //stable data
  872. pbData[index++] = 0x38; //8
  873. pbData[index++] = 0x01; //9
  874. pbData[index++] = 0x01; //10
  875. pbData[index++] = 0x39; //11
  876. pbData[index++] = cmdDataLen; //Len3
  877. pbData.push.apply(pbData, reqData)
  878. index += cmdDataLen;
  879. //stable data
  880. pbData[index++] = 0x3C;
  881. pbData[index++] = 0x03;
  882. pbData[index++] = 0x90;
  883. pbData[index++] = 0x00;
  884. pbData[index] = 0x00;
  885. pbData[7] = cmdDataLen + 1 + 9; //Len2长度 = 指令数据长度+两组固定数据长度+cmdDatalen自身长度标识1字节
  886. pbData[5] = pbData[7] + 2; //2包含固定数据0xA4与 pbData[7]本身长度标识1字节
  887. pbData[2] = ((pbData[5] + 2) & 0xff);
  888. pbData[3] = ((pbData[5]) >> 8) & 0xff; //总长度 小端模式
  889. } else {
  890. pbData[index++] = ((cmdType == 0xA3) ? cmdType : 0xA8);
  891. pbData[index++] = 0x00; //0 明文 1密文
  892. pbData[index++] = (cmdDataLen & 0xff); //总长度
  893. pbData[index++] = (cmdDataLen >> 8) & 0xff; //总长度,后续代码会算
  894. pbData.push.apply(pbData, reqData)
  895. }
  896. mTransData.push.apply(mTransData, pbData.slice(0, pbData[5] + 6))
  897. return 0;
  898. }
  899. function str2Bytes(str) {
  900. var pos = 0;
  901. var len = str.length;
  902. if (len % 2 != 0) {
  903. return null;
  904. }
  905. len /= 2;
  906. var hexA = new Array();
  907. for (var i = 0; i < len; i++) {
  908. var s = str.substr(pos, 2);
  909. var v = parseInt(s, 16);
  910. hexA.push(v);
  911. pos += 2;
  912. }
  913. return hexA;
  914. }
  915. function bytes2Str(arr) {
  916. var str = "";
  917. for (var i = 0; i < arr.length; i++) {
  918. var tmp = arr[i].toString(16);
  919. if (tmp.length == 1) {
  920. tmp = "0" + tmp;
  921. }
  922. str += tmp;
  923. }
  924. return str;
  925. }
  926. function makeRes(code, data, msg) {
  927. return {
  928. code: code,
  929. data: data,
  930. msg: msg
  931. }
  932. }
  933. module.exports = {
  934. getVersion: getVersion,
  935. connectDevice: connectDevice,
  936. transCmd: transCmd,
  937. disconnectDevice: disconnectDevice
  938. }