|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227 |
- /*!
- * WATCHDATA OBU Ble Javascript Library
- * @author Mi.Li on 2018/11/14
- * @version - v1.0.0
- */
- var dataArrayTopacg = [];
- var mExpLength = 0;
- var mExpPackets = 0;
- var delayTimer; //停止循环获取tag
- var sendTimeout = 0;
- var isFound = false
- var isConnected = 1 //1 是未连接 0是链接 -1连接失败
- var isResponse = false
- var isConnecting = false
- var expPktNum = 0;
- var expPktLen = 0;
- var recBuffer = [];
- var currentDevice = {}; //ble设备
- var currentService = {}; //写入服务
- var currentCharacteristic = {}; //特征值
- var currentDeviceService = {}; //服务
- var writeCharacteristic = {}; //写入特征值
- var indicateCharacteristic = {}; //indicate特征值
- var readCharacteristic = {}; //读取特征值
- var onSendSuccessCallBack = undefined; //发送成功回调
- var onSendFailCallBack = undefined; //发送失败回调
- var lastErrorCode = 0; //default ok
- var sendTO; //send timeout
- var retDeivces ={
- name:"",
- deviceId:"",
- RSSI:0,
- localName:"",
- services:null,
- characteristics:null,
- }
- var defaultRes = {
- errMsg: "ok",
- errCode: 0
- };
-
- const ERROR_CONNECT_FAIL = 80000;
- const ERROR_SERACH_TIMEOUT = 80001;
- const ERROR_CONNECT_TIMEOUT = 80002;
- const ERROR_SEND_TIMEOUT = 80003;
- const ERROR_DATA_ERROR = 80004;
-
- const LENGTH_PER_PACKET = 95; //TODO:?92
- const LENGTH_HEADER = 5; //skip st
- const common_vendor = require("../../../common/vendor.js");
- var uni = common_vendor.index
-
- module.exports = {
- startConnectDevice: startConnectDevice,
- disconnectBleDevice: disconnectBleDevice,
- transCmd: transCmd,
- packPkt: packPkt,
- unpackPkt: unpackPkt,
- bytes2HexStr: bytes2HexStr,
- hexStr2Bytes: hexStr2Bytes,
- sync_transCmd: sync_transCmd,
- isConnectionStateChange: isConnectionStateChange,
- isConnectingStateChange: isConnectingStateChange,
- setConnectingState: setConnectingState,
- arrayBuffer2HexString: arrayBuffer2HexString,
- createBLEConnection: createBLEConnection
- }
-
- /**
- * @method startConnectDevice
- * @param {params}
- * @desc 开始连接WATCHDATA低功耗蓝⽛设备
- */
- function startConnectDevice(params,callback_0) {
- console.log('start connect>>>');
- console.log("connecting === " + isConnecting);
- isConnecting = true;
- console.log("connecting1111 === " + isConnecting);
- openBluetoothAdapter(params, callback_0);
- }
-
- /**
- * @desc 断开连接WATCHDATA低功耗蓝⽛设备
- */
- function disconnectBleDevice(params) {
- if (isConnectionStateChange()==0) {
- closeBLEConnection(params);
- } else {
- //console.log("当前无连接");
- params({
- code: 0,
- data : [],
- msg: "断开连接成功"
- })
- }
- }
-
- /**
- * @method isConnectionStateChange
- * @param
- * @desc 查询蓝牙是否正处于链接状态
- */
- function isConnectionStateChange() {
- return isConnected;
- }
-
- /**
- * 获取当前是否处于连接中
- */
- function isConnectingStateChange() {
- return isConnecting;
- }
-
- function setConnectingState(state) {
- isConnecting = state;
- }
-
-
- /**
- * @desc 初始化蓝牙适配器
- */
- function openBluetoothAdapter(params,callback_0) {
- //reset bt adapter
-
- clearInterval(delayTimer);
-
- uni.closeBluetoothAdapter({
- success: function(res) {
- console.log("复位蓝牙适配器成功")
- console.log(res)
- params.success({
- code:1000,
- msg: "复位蓝牙适配器成功",
- })
- },
- fail: function(res) {
- console.log("复位蓝牙适配器失败")
- console.log(res)
- params.fail({
- errMsg: "复位蓝牙适配器失败",
- errCode: res.errCode
- })
- return
- }
- })
-
- uni.openBluetoothAdapter({
- success: function(res) {
- console.log("初始化蓝牙适配器成功")
- console.log(res)
- uni.getBluetoothAdapterState({
- success(res) {
- console.log('getBluetoothAdapterState success' + res)
- },
- fail(res) {
- console.log('getBluetoothAdapterState fail' + res)
- }
- })
- startBluetoothDevicesDiscovery(params,callback_0)
- },
- fail: function(res) {
- console.log("初始化蓝牙适配器失败" + res.errMsg)
- params.fail({
- errMsg: "初始化蓝牙适配器失败",
- errCode: res.errCode
- })
- return
- },
- complete: function(res) {
- console.log(res);
- }
- })
- }
- /**
- * @desc 开始搜寻附近的蓝牙外围设备。注意,该操作比较耗费系统资源,在搜索并连接到设备后调用 stop 方法停止搜索。
- */
- function startBluetoothDevicesDiscovery(params,callback_0) {
- console.log(params);
- setTimeout(function() {
- if (isFound) {
- return;
- } else {
- defaultRes.errCode = ERROR_SERACH_TIMEOUT;
- defaultRes.errMsg = "搜索设备超时";
- console.log("搜索设备超时");
- stopBluetoothDevicesDiscovery();
- clearInterval(delayTimer)
- params.fail({
- errCode :2000,
- errMsg:"搜索设备超时"
- });
- return
- }
- }, params.discoveryTimeout);
-
- uni.startBluetoothDevicesDiscovery({
- services: ['0000fee7-0000-1000-8000-00805f9b34fb'],
- success: function(res) {
- console.log("开启搜索成功")
- console.log(res)
- getBluetoothDevices(params,callback_0)
- },
- fail: function(res) {
- console.log("开启搜索失败")
- params.fail({
- errMsg: "开启搜索失败",
- errCode: res.errCode
- })
- return
- }
- })
-
- //每隔delayTime获取一次
- delayTimer = setInterval(function() {
- if (!isFound)
- getBluetoothDevices(params,callback_0)
- }, params.delayTime)
-
- }
-
- /**
- * @desc 获取所有已发现的蓝牙设备,包括已经和本机处于连接状态的设备
- */
- function getBluetoothDevices(params,callback_0) {
- uni.getBluetoothDevices({
- success: function(res) {
- console.log("getBluetoothDevices 扫描成功");
- console.log(res.devices);
- for (var i = 0; i < res.devices.length; i++) {
- var obuNameFinal = removeBytes(params.adviceId, ":")
- if (isContains(res.devices[i].name, obuNameFinal)) {
- console.log("搜索到要链接的设备....")
- console.log(res)
- stopBluetoothDevicesDiscovery();
- isFound = true
- clearInterval(delayTimer)
- currentDevice = res.devices[i]
- console.log(currentDevice)
- }
- }
- },
- fail: function(res) {
- clearInterval(delayTimer)
- console.log("没有搜索到OBU设备")
- console.log(res)
- params.fail({
- errMsg: "没有搜索到OBU设备",
- errCode: res.errCode
- })
- stopBluetoothDevicesDiscovery();
- return
- }
- })
- }
-
- /**
- *@desc 停止搜寻附近的蓝牙外围设备。请在确保找到需要连接的设备后调用该方法停止搜索。
- */
- function stopBluetoothDevicesDiscovery() {
- uni.stopBluetoothDevicesDiscovery({
- success: function(res) {
- console.log("停止搜索设备")
- console.log(res)
- }
- })
- }
-
-
- /**
- *@desc 连接低功耗蓝牙设备
- */
- function createBLEConnection(params,callback_0) {
- setTimeout(function() {
- console.log("链接定时器", isConnected)
- if (isConnected == 0 || isConnected == -1) return;
- defaultRes.errCode = ERROR_CONNECT_TIMEOUT;
- defaultRes.errMsg = "连接设备超时";
- console.log("连接设备超时");
- params.fail({
- code :1,
- meg : "连接设备超时"
- })
- return
- }, params.connectTimeout)
- uni.createBLEConnection({
- // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
- deviceId: params.adviceId,
- success: function(res) {
- //console.log(`成功: ${currentDevice.deviceId}`)
- isConnected = 0
- sendTimeout = params.sendTimeout;
-
-
- getBLEDeviceServices(params,callback_0);
- },
- fail: function(res) {
- isConnected = -1
- return null
- }
- })
- }
- /**
- *@desc 断开与低功耗蓝牙设备的连接
- */
- function closeBLEConnection(params) {
- uni.closeBLEConnection({
- deviceId: currentDevice.deviceId + "",
- success: function(res) {
- isConnected = 1
- isFound = false
- params({
- code: 0,
- data : [],
- msg: "断开连接成功"
- })
- },
- fail: function(res) {
- params({
- code : 1,
- data: [],
- msg: "断开连接失败",
- })
- }
- })
- }
-
-
-
-
-
- /**
- *@desc 获取蓝牙设备所有 service(服务)
- */
-
- function getBLEDeviceServices(params,callback_0) {
-
- uni.onBLEConnectionStateChange(function(res) {
-
- if (res.connected) {
- isConnected = 0
- } else {
- if (isConnected == 0) {
- callback_0({
- code: 1,
- data: [],
- msg: "设备意外,断开连接",
- })
- isConnected = -1
- return
- }
- }
- if (res.connected)
- {
- callback_0({
- code: 0,
- data: [],
- msg: "链接成功",
- })
- }else
- {
- callback_0({
- code: 1,
- data: [],
- msg: "断开连接",
- })
- }
-
- });
-
- uni.getBLEDeviceServices({
- // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
- deviceId: params.adviceId + "",
- success: function(res) {
- for (var i = 0; i < res.services.length; i++) {
- if (res.services[i].uuid.toUpperCase() === params.srv_uuid.toUpperCase()) {
- currentService = res.services[i]
-
- break;
- }
- }
-
- currentDeviceService = res.services;
- //获取Characteristics
- getBLEDeviceCharacteristics(params);
-
- },
- fail: function(res) {
- params.fail({
- code: 1,
- data: [],
- msg: "获取服务失败",
- })
- }
- })
- }
-
- /**
- *@desc 获取蓝牙设备唤醒characteristic(特征值)
- */
- function getBLEDeviceCharacteristics(params) {
- uni.getBLEDeviceCharacteristics({
- // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
- deviceId: params.adviceId + "",
- // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
- serviceId: params.srv_uuid + "",
- success: function(res) {
- for (var i = 0; i < res.characteristics.length; i++) {
- if (res.characteristics[i].uuid.toUpperCase() === params.chr_read_uuid.toUpperCase()) {
- readCharacteristic = res.characteristics[i];
- }
- if (res.characteristics[i].uuid.toUpperCase() === params.chr_write_uuid.toUpperCase()) {
- writeCharacteristic = res.characteristics[i];
- }
- if (res.characteristics[i].uuid.toUpperCase() === params.chr_indicate_uuid.toUpperCase()) {
- indicateCharacteristic = res.characteristics[i];
- }
- }
- currentCharacteristic = res.characteristics;
- // initNotifyListener(params);
- subscribeIndicateCharacteristic(params);
- },
- fail: function(res) {
- params.fail({
- errMsg: "唤醒特征值获取失败",
- errCode: res.errCode
- })
- }
- })
- }
-
- /**
- *
- * @desc 连接成功后,初始化回调监听
- */
- function initNotifyListener(params) {
- uni.readBLECharacteristicValue({
- deviceId: params.adviceId + "",
- serviceId: params.srv_uuid + "",
- characteristicId: readCharacteristic.uuid + "",
- success: function (res) {
-
- subscribeIndicateCharacteristic(params)
- },
- fail: function (res) {
-
- params.fail({
- errMsg: "开启监听失败",
- errCode: res.errCode
- })
- }
- })
- }
-
- function subscribeIndicateCharacteristic (params) {
- uni.notifyBLECharacteristicValueChange({
- deviceId: params.adviceId + "",
- serviceId: params.srv_uuid + "",
- characteristicId: indicateCharacteristic.uuid + "",
- state: true,
- success: function (res) {
-
- onBLECharacteristicValueChange();
- setTimeout(function () {
- //连接成功
- lastErrorCode = res.errCode;
- retDeivces.name = currentDevice.name;
- retDeivces.deviceId = currentDevice.deviceId;
- retDeivces.RSSI = currentDevice.RSSI;
- retDeivces.localName = currentDevice.localName;
- retDeivces.services = currentDeviceService;
- retDeivces.characteristics = currentCharacteristic;
- currentDevice.deviceId = params.adviceId
- params.success({
- code: 0,
- msg: "连接成功",
- })
- }, params.accTimeout);
- },
- fail: function (res) {
-
- params.fail({
- msg: "开启监听失败",
- code: res.errCode
- })
- }
- });
- }
-
-
- /**
- *@desc 启用低功耗蓝牙设备特征值变化时的 notify
- */
- function onBLECharacteristicValueChange() {
- uni.onBLECharacteristicValueChange(function (res) {
-
- //check pkt
- //每次发送可能多次触发此通知,检查返回包的完整性,否则触发接收等待超时
- let rValue = new Uint8Array(res.value);
- let pktArray = Array.prototype.slice.call(new Uint8Array(res.value));
- if ((expPktLen <= 0) && (pktArray.length < 4)) {
- //丢弃无效包
- console.log('incomplete data:expPktLen=${expPktLen},pktArray.length=${pktArray.lengths}');
- return false;
- }
- if (expPktLen <= 0) {
- expPktLen = pktArray[3] /*+ LENGTH_HEADER 3*/;
- expPktNum = pktArray[2] & 0x7F;
- }
- recBuffer = recBuffer.concat(pktArray.slice(0));
-
- expPktLen -= pktArray.length;
- if (expPktLen <= 0 && expPktNum <= 0) {
- //所有帧都收到了
-
- //接收的所有数据
- let allCmd = arrayBuffer2HexString(new Uint8Array(recBuffer).buffer);
-
- //得到有用的数据长度
- let dLen = allCmd.substring(22, 24);
- let rCommand = allCmd.substring(24, (24 + parseInt(dLen, 16)) * 2);
-
- let bufferArrs = hexStr2Bytes(rCommand);
- isResponse = true;
- clearTimeout(sendTO);
- //unpack
- // let retbuf = unpackPkt(recBuffer);
- let retbuf
- if (bufferArrs[2]==128){
- retbuf = unpackPkt(bufferArrs);
- }else{
- retbuf = bye2to(bufferArrs)
- }
-
- if (allCmd != null) {
- if (bufferArrs[0] == 40 && bufferArrs[1] == 2 && bufferArrs[2] == 58 && bufferArrs[3] == 6) {
- console.log("连接指令不返回")
- return
- }
- if (onSendSuccessCallBack != undefined) {
- onSendSuccessCallBack(retbuf);
- }
- } else {
- defaultRes.errCode = ERROR_DATA_ERROR;
- defaultRes.errMsg = "接收失败";
- onSendFailCallBack(defaultRes);
- }
- recBuffer = []
- return;
- }
- })
- }
-
-
- /**
- *@desc sync_delay 阻塞
- */
- function sync_delay(ms) {
- return new Promise((resolve, reject) => {
- setTimeout(resolve, ms);
- });
- }
-
-
- function sync_transCmd(cmd){
- return new Promise((resolve, reject) => {
- transCmd({ data: cmd, success:resolve,fail:reject});
- });
- }
-
-
- /**
- *@desc 收发ble通道数据
- */
- function transCmd(data,success,fail) {
- // uni.onBLEConnectionStateChange(function (res) {
- // // if (isConnected == 0) {
- // // if (!res.connected) {
- // // isResponse = true;
- // // fail({
- // // code: 1,
- // // data:[],
- // // msg: "设备连接已断开,发送指令失败"
- // // })
- // // }
- // // }
- // isConnected = -1
- // return null;
- // });
- if (isConnectionStateChange()!=0) {
- console.log("连接断开,发送失败")
- defaultRes.errCode = ERROR_CONNECT_FAIL;
- defaultRes.errMsg = "连接断开,发送失败";
- fail(defaultRes);
- } else {
- //pack
- let cmd = packPkt(data).toUpperCase();
- sendCmd(cmd, success, fail);
- }
- }
-
-
-
- /**
- * @desc 发送指令,不关心指令具体长度,从第一个字节开始
- */
- function sendCmd(cmd, successCb, failCb) {
- //清空接收buf
- isResponse = false;
- expPktLen = 0;
- expPktNum = 0;
- recBuffer = [];
- //设置发送超时
- sendTO = setTimeout(function(){
- if (isConnected != 0) return
- if (isResponse ) {
- return;
- } else {
- console.log("还是进来了isConnected", isConnected)
- defaultRes.errCode = ERROR_SEND_TIMEOUT;
- defaultRes.errMsg = "接收超时";
- console.log("接收超时");
- failCb({
- code: 1,
- data: [],
- msg: "接收超时",
- })
- onSendSuccessCallBack = undefined;
- onSendFailCallBack = undefined;
- isResponse = true;
- failCb(defaultRes);
- return
- }
- }, sendTimeout);
-
- //接收ble返回数据
- onSendSuccessCallBack = successCb;
- onSendFailCallBack = failCb;
- //递归发送
- sendCmds(cmd, 0, failCb);
- }
-
- /**
- *
- * @desc 逐条发送指令,小程序不会对写入数据包大小做限制,但系统与蓝牙设备会限制蓝牙4.0单次传输的数据大小,超过最大字节数后会发生写入错误,建议每次写入不超过20字节。
- */
- function sendCmds(command, index, onFailCallback) {
- var itemCmd;
- var isLast = false; // 判断是否是最后一条
- if (command.length > index + 40) {
- itemCmd = command.substr(index, 40);
- } else {
- isLast = true;
- itemCmd = command.substr(index);
- }
- writeCommandToBle(itemCmd, function(errMsg) {
- if (errMsg == 'ok' && !isLast) { // 发送成功并且不是最后一条时,执行下一条
- sendCmds(command, index + 40);
- }
- },
- onFailCallback)
- }
- /**
- *
- * @desc 向蓝牙中写入数据(ble蓝牙)
- */
- function writeCommandToBle(commonds, onSendCallback, onFailCallback) {
- var commond = commonds;
-
- let buffer = hexString2ArrayBuffer(commond);
- console.log("发送的数据",buffer)
- uni.writeBLECharacteristicValue({
- deviceId: currentDevice.deviceId + "",
- serviceId: currentService.uuid + '',
- characteristicId: writeCharacteristic.uuid + '',
- // 这里的value是ArrayBuffer类型
- value: buffer,
- success: function(res) {
- onSendCallback('ok');
- },
- fail: function(res) {
- onFailCallback({
- msg: "发送指令失败",
- code: res.errCode
- })
- }
- })
- }
-
- /**
- * @desc 打包16进制字符帧
- * @return Hex string packet
- */
- function packPkt(hexStr) {
- let dataArrayBuf = hexString2ArrayBuffer(hexStr);
- let dataArray = Array.prototype.slice.call(new Uint8Array(dataArrayBuf));
- let pkt = [];
- let buf = [];
- let pktSN = 0;
- let pktNum = Math.ceil(dataArray.length / LENGTH_PER_PACKET);
- let dataLen = 0;
- let offset = 0;
-
- //console.log('CMD:' + hexStr);
- if (dataArray.length <= 0) {
- console.log('Hex string pack fail:', hexStr);
- return null;
- }
- for (var i = 0; i < pktNum; i++) {
- buf = [];
- //ST:0x33
- buf.push(0x33);
- //SN
- pktSN++;
- buf.push(pktSN);
- //CTL
- if (pktNum > 1) {
- if (i == 0) {
- buf.push(0x80 | (pktNum - 1));
- } else {
- buf.push(pktNum - 1 - i);
- }
- } else {
- buf.push(0);
- }
-
- //LEN
- if (i == (pktNum - 1)) {
- dataLen = dataArray.length - offset;
- } else {
- dataLen = LENGTH_PER_PACKET;
- }
- buf.push(dataLen);
- //DATA
- buf = buf.concat(dataArray.slice(offset, offset + dataLen));
- offset += dataLen;
- //BCC: xor From SN to Data
- let xor = calXor(buf, 1, buf.length - 1);
- buf.push(xor);
- pkt = pkt.concat(buf);
- }
-
-
- let pktArrayBuffer = new Uint8Array(pkt).buffer;
- //console.log('packed cmd:' + arrayBuffer2HexString(pktArrayBuffer));
- //头
- let header = "FE01";
- //命令代码
- let cmdCode = "753100000A0012";
- //发送的数据
- let dataCmd = arrayBuffer2HexString(pktArrayBuffer);
- //发送数据的长度
- let cLen = wxNumberToHexString(dataCmd.length / 2, 1, true);
- //尾
- let footer = "1800";
- //总数据
- let ddd = header + cmdCode + cLen + footer + dataCmd;
- //总长度
- let cmdLen = wxNumberToHexString(ddd.length / 2, 2, true);
- let rCmd1 = header + cmdLen + cmdCode + cLen + arrayBuffer2HexString(pktArrayBuffer) + footer;
- let cmdLen1 = wxNumberToHexString(rCmd1.length / 2, 2, true);
- let rCmd = header + cmdLen1 + cmdCode + cLen + arrayBuffer2HexString(pktArrayBuffer) + footer;
- // return arrayBuffer2HexString(pktArrayBuffer);
- console.log("打包数据",rCmd)
- return rCmd;
- }
-
- // number转换成指定字节数的hexString
- // num:要转换的数(number) bitNum:转换后的字节数(number) isBig:是不是大端模式(boolean)
- function wxNumberToHexString(num, bitNum, isBig) {
- // 转大端hex并补足
- let hex = num.toString(16);
- for (let i = hex.length; i < bitNum * 2; i++) {
- hex = '0' + hex;
- }
- // 多位截取
- if (hex.length > bitNum * 2) {
- hex = hex.substring(hex.length - bitNum * 2);
- }
- // 转小端
- if (isBig == false) {
- let temp = '';
- for (let i = hex.length - 2; i >= 0; i -= 2) {
- temp = temp + hex.substring(i, i + 2);
- }
- hex = temp;
- }
- return hex;
- }
-
- /**
- * @desc 解包16进制字符帧
- * @return Hex string data
- */
- function unpackPkt(pktArray) {
- let buf = [];
- let pktNum = Math.ceil(pktArray.length / (LENGTH_PER_PACKET + LENGTH_HEADER));
- let dataLen = 0;
- let offset = 0;
- for (var i = 0; i < pktNum; i++) {
- //head
- offset += 3; //skip ST,SN,CTL
- dataLen = pktArray[offset];
- offset++;
-
- //data
- if (offset + dataLen >= pktArray.length) {
- //Incomplete data
- console.log('unpack length fail');
- return null
- }
- buf = buf.concat(pktArray.slice(offset, offset + dataLen));
-
- //xor
- var xor = calXor(pktArray, offset - 3, dataLen + 3);
- offset += dataLen;
- if (xor != pktArray[offset]) {
- console.log('unpack fail xor:', xor);
- return null;
- }
- offset++;
- }
- return buf;
- }
-
-
- /**
- * @desc 异或运算
- */
- function calXor(dataArray, offset, len) {
- var ret = 0;
- for (var i = 0; i < len; i++) {
- ret ^= dataArray[offset + i];
- }
- return ret;
- }
- /**
- * ArrayBuffer转16进制字符串
- */
- function arrayBuffer2HexString(buf) {
- var out = "";
- var u8a = new Uint8Array(buf);
- var single;
- for (var i = 0; i < u8a.length; i++) {
- single = u8a[i].toString(16)
- while (single.length < 2) single = "0".concat(single);
- out += single;
- }
- return out;
- }
-
-
- /**
- * 1、字符串转换为十六进制
- * 主要使用 charCodeAt()方法,此方法返回一个字符的 Unicode 值,该字符位于指定索引位置。
- */
- function stringToHex(str) {
- var val = "";
- for (var i = 0; i < str.length; i++) {
- val += str.charCodeAt(i).toString(16);
- }
- return val;
- }
-
- function filterChinese(str) {
- var tmp = str.split(''),
- arr = [];
- for (var i = 0, c = tmp.length; i < c; i++) {
- var s = tmp[i].charCodeAt();
- if (s > 0 && s < 127) {
- arr.push(tmp[i]);
- }
- }
- return arr;
- };
-
- function strToHex(hex, isFilterChinese) {
- hex = isFilterChinese ? filterChinese(hex).join('') : convertChinese(hex).join('');
-
- //清除所有空格
- hex = hex.replace(/\s/g, "");
- //若字符个数为奇数,补一个空格
- hex += hex.length % 2 != 0 ? " " : "";
-
- var c = hex.length / 2,
- arr = [];
- for (var i = 0; i < c; i++) {
- arr.push(parseInt(hex.substr(i * 2, 2), 16));
- }
- return arr;
- };
-
-
- /**
- * 16进制字符串转ArrayBuffer
- */
- function hexString2ArrayBuffer(hexStr) {
- var count = hexStr.length / 2;
- let buffer = new ArrayBuffer(count);
- let dataView = new DataView(buffer);
- for (var i = 0; i < count; i++) {
- var curCharCode = parseInt(hexStr.substr(i * 2, 2), 16);
- dataView.setUint8(i, curCharCode);
- }
- return buffer;
- }
-
-
- /**
- * 字符串转为ArrayBuffer对象,参数为字符串
- */
- function string2ArrayBuffer(str) {
- var buf = new ArrayBuffer(str.length * 2); // 每个字符占用2个字节
- var bufView = new Uint8Array(buf);
- for (var i = 0, strLen = str.length; i < strLen; i++) {
- bufView[i] = str.charCodeAt(i);
- }
- return buf;
- }
-
- function isArray(arr) {
- return Object.prototype.toString.call(arr) === '[object Array]';
- };
-
- function strToByte(str) {
- var tmp = str.split(''),
- arr = [];
- for (var i = 0, c = tmp.length; i < c; i++) {
- var j = encodeURI(tmp[i]);
- if (j.length == 1) {
- arr.push(j.charCodeAt());
- } else {
- var b = j.split('%');
- for (var m = 1; m < b.length; m++) {
- arr.push(parseInt('0x' + b[m]));
- }
- }
- }
- return arr;
- };
-
- function convertChinese(str) {
- var tmp = str.split(''),
- arr = [];
- for (var i = 0, c = tmp.length; i < c; i++) {
- var s = tmp[i].charCodeAt();
- if (s <= 0 || s >= 127) {
- arr.push(s.toString(16));
- } else {
- arr.push(tmp[i]);
- }
- }
- return arr;
- };
-
- // function filterChinese(str) {
- // var tmp = str.split(''),
- // arr = [];
- // for (var i = 0, c = tmp.length; i < c; i++) {
- // var s = tmp[i].charCodeAt();
- // if (s > 0 && s < 127) {
- // arr.push(tmp[i]);
- // }
- // }
- // return arr;
- // };
-
- // function strToHex(hex, isFilterChinese) {
- // hex = isFilterChinese ? filterChinese(hex).join('') : convertChinese(hex).join('');
-
- // //清除所有空格
- // hex = hex.replace(/\s/g, "");
- // //若字符个数为奇数,补一个空格
- // hex += hex.length % 2 != 0 ? " " : "";
-
- // var c = hex.length / 2,
- // arr = [];
- // for (var i = 0; i < c; i++) {
- // arr.push(parseInt(hex.substr(i * 2, 2), 16));
- // }
- // return arr;
- // };
-
- function padLeft(s, w, pc) {
- if (pc == undefined) {
- pc = '0';
- }
- for (var i = 0, c = w - s.length; i < c; i++) {
- s = pc + s;
- }
- return s;
- };
-
- function toString(arr, isReverse) {
- if (typeof isReverse == 'undefined') {
- isReverse = true;
- }
- var hi = arr[0],
- lo = arr[1];
- return padLeft((isReverse ? hi + lo * 0x100 : hi * 0x100 + lo).toString(16).toUpperCase(), 4, '0');
- };
-
-
- /**
- * 16进制字符串异或处理
- *
- * @param str1
- * @param str2
- * @return
- */
- function stringXor(str1, str2) {
- if (!str1 && !str2) {
- return "";
- }
- if (!str1 && str2) {
- return str2;
- }
- if (str1 && !str2) {
- return str1;
- }
- var longStr;
- var shortStr;
- if (str1.length >= str2.length) {
- longStr = str1;
- shortStr = str2;
- } else {
- longStr = str2;
- shortStr = str1;
- }
- var count = parseInt(shortStr.length / 2);
- var leftCount = longStr.length - shortStr.length;
- var resultStr = "";
- if (leftCount > 0) {
- resultStr += longStr.substr(0, leftCount);
- }
- for (var i = 0; i < count; i++) {
- var shortCharCode = parseInt(shortStr.substr(i * 2, 2), 16);
- var longCharCode = parseInt(longStr.substr(leftCount + i * 2, 2), 16);
- var resultCode = shortCharCode ^ longCharCode;
- var single = resultCode.toString(16);
- while (single.length < 2) single = "0".concat(single);
- resultStr += single;
- }
- return resultStr.toUpperCase();
- }
-
-
- /**
- * 指令两个16进制字符串异或处理
- *
- * @param command
- * @param secretKey
- * @return
- */
- function getSecretEncoding(command, secretKey) {
- if (!command || !secretKey) {
- return "";
- }
- var secretLength = secretKey.length;
- var length = parseInt(command.length / secretLength);
- console.log(`command(${command.length})/secretLength(${secretLength}) = ${length}`);
- var resultCmd = "";
- console.log(`secretKey(${secretKey.length}):${secretKey}`);
- for (var i = 0; i < length; i++) {
- var part = command.substr(i * secretLength, secretLength);
- resultCmd += stringXor(part, secretKey);
- console.log(`part${i}:${stringXor(part, secretKey)}`);
- }
- var lastLen = command.length % secretLength;
- if (lastLen > 0) {
- console.log(`lastCMD:${command.substr(command.length - lastLen, lastLen)}`);
- console.log(`lastSecretKey:${secretKey.substr(0, lastLen)}`);
- var lastPart = command.substr(command.length - lastLen, lastLen);
- var lastCmd = stringXor(lastPart, secretKey.substr(0, lastLen));
- resultCmd += lastCmd;
- console.log(`lastPart:${lastCmd}`);
- }
- return resultCmd;
- }
- /**
- * 2、十六进制转换为字符串
- *主要使用 fromCharCode()方法,此方法将 Unicode 码转换为与之对应的字符。
- */
- function hexToString(str) {
- var val = "";
- var arr = str.split(",");
- for (var i = 0; i < arr.length; i++) {
- val += arr[i].fromCharCode(i);
-
- }
- return val;
- }
-
- /**
- * 获取随机长度16进制字符串
- */
- function getRamNumber(length) {
- var result = '';
- for (var i = 0; i < length; i++) {
- result += Math.floor(Math.random() * 16).toString(16); //获取0-15并通过toString转16进制
- }
- //默认字母小写,手动转大写
- return result.toUpperCase(); //另toLowerCase()转小写
- }
-
-
- /**
- * 得到BCD码时间字符串
- *
- * @param datetime
- * @return
- */
- function getBCDTime(datetime, needWeek) {
- if (typeof datetime == 'undefined') {
- datetime = new Date();
- }
- if (typeof needWeek == 'undefined') {
- needWeek = true;
- }
- var year = datetime.getFullYear() - 2000; //获取年份,从2000年开始计算
- if (year < 0) year = 0; // 不允许小于2000年的年份出现
- var month = datetime.getMonth() + 1; //获取月份 0-11 所以需要加1
- var day = datetime.getDate(); //获取日
- var hour = datetime.getHours(); //小时
- var minute = datetime.getMinutes(); //分
- var second = datetime.getSeconds(); //秒
- if (needWeek) {
- var dayOfWeek = datetime.getDay(); //一周的第几天 0-6
- return formatNumber(year) + formatNumber(month) + formatNumber(day) + formatNumber(dayOfWeek) +
- formatNumber(hour) + formatNumber(minute) + formatNumber(second); // 得到BCD码的时间字符串
- } else {
- return formatNumber(year) + formatNumber(month) + formatNumber(day) +
- formatNumber(hour) + formatNumber(minute) + formatNumber(second); // 得到BCD码的时间字符串
- }
- }
-
- function formatNumber(n) {
- n = n.toString()
- return (n[1] ? n : '0' + n) + "";
- }
-
-
-
- /**
- * 判断一个字符串是否包含子串
- */
- function isContains(str, substr) {
-
- var strUp = str.toUpperCase();
- var substrUp = substr.toUpperCase()
-
- return new RegExp(substrUp).test(strUp);
- }
-
- /**
- * 去除字符串中特定的字符
- */
-
-
- function removeBytes(str, substr) {
- console.log("split",str)
- var items = str.split(substr)
- // 会得到一个数组,数组中包括利用o分割后的多个字符串(不包括o)
- var newStr = items.join("");
- return newStr
- // }
- }
-
-
- //十六进制字符串转字节数组
- function hexStr2Bytes(str) {
- var pos = 0;
- var len = str.length;
- if (len % 2 != 0) {
- return null;
- }
- len /= 2;
- var hexA = new Array();
- for (var i = 0; i < len; i++) {
- var s = str.substr(pos, 2);
- var v = parseInt(s, 16);
- hexA.push(v);
- pos += 2;
- }
- return hexA;
- }
-
- //字节数组转十六进制字符串
- function bytes2HexStr(arr) {
- var str = "";
- for (var i = 0; i < arr.length; i++) {
- var tmp = arr[i].toString(16);
- if (tmp.length == 1) {
- tmp = "0" + tmp;
- }
- str += tmp;
- }
- return str;
- }
-
- function bye2to(byte){
- if (byte[2]!=129){
- //console.log("第二包", arrayBuffer2HexString(byte))
- byte.splice(0,4)
- dataArrayTopacg = dataArrayTopacg.concat(byte.slice(0));
- dataArrayTopacg.splice(3, 1, dataArrayTopacg.length-7);
- //console.log("第二包", arrayBuffer2HexString(byte), dataArrayTopacg)
- let retbuf = unpackPktTo(dataArrayTopacg)
- return retbuf
- }else{
- dataArrayTopacg = []
- byte.splice(byte.length - 3, byte.length)
- dataArrayTopacg = dataArrayTopacg.concat(byte.slice(0));
- }
-
-
- /**
- * @desc 解包16进制字符帧
- * @return Hex string data
- */
- function unpackPktTo(pktArray) {
- pktArray.splice(0, 4)
- pktArray.splice(pktArray.length - 3, pktArray.length)
- return pktArray
-
- }
- }
-
|