Pārlūkot izejas kodu

蓝牙配网插件

htc 1 dienu atpakaļ
vecāks
revīzija
0cd5aaceab

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 802 - 0
utils/blufi/crypto/aes.js


+ 42 - 0
utils/blufi/crypto/crypto-dh.js

@@ -0,0 +1,42 @@
+var generatePrime = require('./lib/generatePrime')
+
+var DH = require('./lib/dh')
+var Buffer = require('./lib/safe-buffer').Buffer
+
+function getDiffieHellman(mod) {
+  var prime = new Buffer(primes[mod].prime, 'hex')
+  var gen = new Buffer(primes[mod].gen, 'hex')
+
+  return new DH(prime, gen)
+}
+
+var ENCODINGS = {
+  'binary': true, 'hex': true, 'base64': true
+}
+
+function createDiffieHellman(prime, enc, generator, genc) {
+  if (Buffer.isBuffer(enc) || ENCODINGS[enc] === undefined) {
+    return createDiffieHellman(prime, 'binary', enc, generator)
+  }
+
+  enc = enc || 'binary'
+  genc = genc || 'binary'
+  generator = generator || new Buffer([2])
+
+  if (!Buffer.isBuffer(generator)) {
+    generator = new Buffer(generator, genc)
+  }
+
+  if (typeof prime === 'number') {
+    return new DH(generatePrime(prime, generator), generator, true)
+  }
+
+  if (!Buffer.isBuffer(prime)) {
+    prime = new Buffer(prime, enc)
+  }
+
+  return new DH(prime, generator, true)
+}
+
+exports.DiffieHellmanGroup = exports.createDiffieHellmanGroup = exports.getDiffieHellman = getDiffieHellman
+exports.createDiffieHellman = exports.DiffieHellman = createDiffieHellman

+ 151 - 0
utils/blufi/crypto/lib/base64-js.js

@@ -0,0 +1,151 @@
+'use strict'
+
+exports.byteLength = byteLength
+exports.toByteArray = toByteArray
+exports.fromByteArray = fromByteArray
+
+var lookup = []
+var revLookup = []
+var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
+
+var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
+for (var i = 0, len = code.length; i < len; ++i) {
+  lookup[i] = code[i]
+  revLookup[code.charCodeAt(i)] = i
+}
+
+// Support decoding URL-safe base64 strings, as Node.js does.
+// See: https://en.wikipedia.org/wiki/Base64#URL_applications
+revLookup['-'.charCodeAt(0)] = 62
+revLookup['_'.charCodeAt(0)] = 63
+
+function getLens (b64) {
+  var len = b64.length
+
+  if (len % 4 > 0) {
+    throw new Error('Invalid string. Length must be a multiple of 4')
+  }
+
+  // Trim off extra bytes after placeholder bytes are found
+  // See: https://github.com/beatgammit/base64-js/issues/42
+  var validLen = b64.indexOf('=')
+  if (validLen === -1) validLen = len
+
+  var placeHoldersLen = validLen === len
+    ? 0
+    : 4 - (validLen % 4)
+
+  return [validLen, placeHoldersLen]
+}
+
+// base64 is 4/3 + up to two characters of the original data
+function byteLength (b64) {
+  var lens = getLens(b64)
+  var validLen = lens[0]
+  var placeHoldersLen = lens[1]
+  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
+}
+
+function _byteLength (b64, validLen, placeHoldersLen) {
+  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
+}
+
+function toByteArray (b64) {
+  var tmp
+  var lens = getLens(b64)
+  var validLen = lens[0]
+  var placeHoldersLen = lens[1]
+
+  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
+
+  var curByte = 0
+
+  // if there are placeholders, only get up to the last complete 4 chars
+  var len = placeHoldersLen > 0
+    ? validLen - 4
+    : validLen
+
+  for (var i = 0; i < len; i += 4) {
+    tmp =
+      (revLookup[b64.charCodeAt(i)] << 18) |
+      (revLookup[b64.charCodeAt(i + 1)] << 12) |
+      (revLookup[b64.charCodeAt(i + 2)] << 6) |
+      revLookup[b64.charCodeAt(i + 3)]
+    arr[curByte++] = (tmp >> 16) & 0xFF
+    arr[curByte++] = (tmp >> 8) & 0xFF
+    arr[curByte++] = tmp & 0xFF
+  }
+
+  if (placeHoldersLen === 2) {
+    tmp =
+      (revLookup[b64.charCodeAt(i)] << 2) |
+      (revLookup[b64.charCodeAt(i + 1)] >> 4)
+    arr[curByte++] = tmp & 0xFF
+  }
+
+  if (placeHoldersLen === 1) {
+    tmp =
+      (revLookup[b64.charCodeAt(i)] << 10) |
+      (revLookup[b64.charCodeAt(i + 1)] << 4) |
+      (revLookup[b64.charCodeAt(i + 2)] >> 2)
+    arr[curByte++] = (tmp >> 8) & 0xFF
+    arr[curByte++] = tmp & 0xFF
+  }
+
+  return arr
+}
+
+function tripletToBase64 (num) {
+  return lookup[num >> 18 & 0x3F] +
+    lookup[num >> 12 & 0x3F] +
+    lookup[num >> 6 & 0x3F] +
+    lookup[num & 0x3F]
+}
+
+function encodeChunk (uint8, start, end) {
+  var tmp
+  var output = []
+  for (var i = start; i < end; i += 3) {
+    tmp =
+      ((uint8[i] << 16) & 0xFF0000) +
+      ((uint8[i + 1] << 8) & 0xFF00) +
+      (uint8[i + 2] & 0xFF)
+    output.push(tripletToBase64(tmp))
+  }
+  return output.join('')
+}
+
+function fromByteArray (uint8) {
+  var tmp
+  var len = uint8.length
+  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
+  var parts = []
+  var maxChunkLength = 16383 // must be multiple of 3
+
+  // go through the array every three bytes, we'll deal with trailing stuff later
+  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
+    parts.push(encodeChunk(
+      uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
+    ))
+  }
+
+  // pad the end with zeros, but make sure to not forget the extra bytes
+  if (extraBytes === 1) {
+    tmp = uint8[len - 1]
+    parts.push(
+      lookup[tmp >> 2] +
+      lookup[(tmp << 4) & 0x3F] +
+      '=='
+    )
+  } else if (extraBytes === 2) {
+    tmp = (uint8[len - 2] << 8) + uint8[len - 1]
+    parts.push(
+      lookup[tmp >> 10] +
+      lookup[(tmp >> 4) & 0x3F] +
+      lookup[(tmp << 2) & 0x3F] +
+      '='
+    )
+  }
+
+  return parts.join('')
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 3427 - 0
utils/blufi/crypto/lib/bn.js


+ 52 - 0
utils/blufi/crypto/lib/brorand.js

@@ -0,0 +1,52 @@
+var r;
+
+module.exports = function rand(len) {
+  if (!r)
+    r = new Rand(null);
+
+  return r.generate(len);
+};
+
+function Rand(rand) {
+  this.rand = rand;
+}
+module.exports.Rand = Rand;
+
+Rand.prototype.generate = function generate(len) {
+  return this._rand(len);
+};
+
+// Emulate crypto API using randy
+Rand.prototype._rand = function _rand(n) {
+  console.log(this);
+  if (this.rand.getBytes)
+    return this.rand.getBytes(n);
+
+  var res = new Uint8Array(n);
+  for (var i = 0; i < res.length; i++)
+    res[i] = this.rand.getByte();
+  return res;
+};
+
+if (typeof self === 'object') {
+  Rand.prototype._rand = function _rand(n) {
+    var list = [];
+    for (var i = 0; i < n; i++) {
+      list.push(Math.ceil(Math.random() * 255))
+    }
+    var arr = new Uint8Array(list);
+    return arr;
+  };
+} else {
+  // Node.js or Web worker with no crypto support
+  try {
+    var crypto = require('crypto');
+    if (typeof crypto.randomBytes !== 'function')
+      throw new Error('Not supported');
+
+    Rand.prototype._rand = function _rand(n) {
+      return crypto.randomBytes(n);
+    };
+  } catch (e) {
+  }
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1776 - 0
utils/blufi/crypto/lib/buffer.js


+ 165 - 0
utils/blufi/crypto/lib/dh.js

@@ -0,0 +1,165 @@
+var BN = require('./bn');
+var MillerRabin = require('./miller-rabin');
+var millerRabin = new MillerRabin();
+var TWENTYFOUR = new BN(24);
+var ELEVEN = new BN(11);
+var TEN = new BN(10);
+var THREE = new BN(3);
+var SEVEN = new BN(7);
+var Buffer = require('./safe-buffer').Buffer
+var primes = require('./generatePrime');
+var randomBytes = require('./randombytes');
+module.exports = DH;
+
+function setPublicKey(pub, enc) {
+  enc = enc || 'utf8';
+  if (!Buffer.isBuffer(pub)) {
+    pub = new Buffer(pub, enc);
+  }
+  this._pub = new BN(pub);
+  return this;
+}
+
+function setPrivateKey(priv, enc) {
+  enc = enc || 'utf8';
+  if (!Buffer.isBuffer(priv)) {
+    priv = new Buffer(priv, enc);
+  }
+  this._priv = new BN(priv);
+  return this;
+}
+
+var primeCache = {};
+function checkPrime(prime, generator) {
+  var gen = generator.toString('hex');
+  var hex = [gen, prime.toString(16)].join('_');
+  if (hex in primeCache) {
+    return primeCache[hex];
+  }
+  var error = 0;
+
+  if (prime.isEven() ||
+    !primes.simpleSieve ||
+    !primes.fermatTest(prime) ||
+    !millerRabin.test(prime)) {
+    //not a prime so +1
+    error += 1;
+
+    if (gen === '02' || gen === '05') {
+      // we'd be able to check the generator
+      // it would fail so +8
+      error += 8;
+    } else {
+      //we wouldn't be able to test the generator
+      // so +4
+      error += 4;
+    }
+    primeCache[hex] = error;
+    return error;
+  }
+  if (!millerRabin.test(prime.shrn(1))) {
+    //not a safe prime
+    error += 2;
+  }
+  var rem;
+  switch (gen) {
+    case '02':
+      if (prime.mod(TWENTYFOUR).cmp(ELEVEN)) {
+        // unsuidable generator
+        error += 8;
+      }
+      break;
+    case '05':
+      rem = prime.mod(TEN);
+      if (rem.cmp(THREE) && rem.cmp(SEVEN)) {
+        // prime mod 10 needs to equal 3 or 7
+        error += 8;
+      }
+      break;
+    default:
+      error += 4;
+  }
+  primeCache[hex] = error;
+  return error;
+}
+
+function DH(prime, generator, malleable) {
+  this.setGenerator(generator);
+  this.__prime = new BN(prime);
+  this._prime = BN.mont(this.__prime);
+  this._primeLen = 128;
+  this._pub = undefined;
+  this._priv = undefined;
+  this._primeCode = undefined;
+  if (malleable) {
+    this.setPublicKey = setPublicKey;
+    this.setPrivateKey = setPrivateKey;
+  } else {
+    this._primeCode = 8;
+  }
+}
+Object.defineProperty(DH.prototype, 'verifyError', {
+  enumerable: true,
+  get: function () {
+    if (typeof this._primeCode !== 'number') {
+      this._primeCode = checkPrime(this.__prime, this.__gen);
+    }
+    return this._primeCode;
+  }
+});
+DH.prototype.generateKeys = function () {
+  if (!this._priv) {
+    this._priv = new BN(randomBytes(this._primeLen));
+  }
+  this._pub = this._gen.toRed(this._prime).redPow(this._priv).fromRed();
+  return this.getPublicKey();
+};
+
+DH.prototype.computeSecret = function (other) {
+  other = new BN(other);
+  other = other.toRed(this._prime);
+  var secret = other.redPow(this._priv).fromRed();
+  var out = new Buffer(secret.toArray());
+  var prime = this.getPrime();
+  if (out.length < prime.length) {
+    var front = new Buffer(prime.length - out.length);
+    front.fill(0);
+    out = Buffer.concat([front, out]);
+  }
+  return out;
+};
+
+DH.prototype.getPublicKey = function getPublicKey(enc) {
+  return formatReturnValue(this._pub, enc);
+};
+
+DH.prototype.getPrivateKey = function getPrivateKey(enc) {
+  return formatReturnValue(this._priv, enc);
+};
+
+DH.prototype.getPrime = function (enc) {
+  return formatReturnValue(this.__prime, enc);
+};
+
+DH.prototype.getGenerator = function (enc) {
+  return formatReturnValue(this._gen, enc);
+};
+
+DH.prototype.setGenerator = function (gen, enc) {
+  enc = enc || 'utf8';
+  if (!Buffer.isBuffer(gen)) {
+    gen = new Buffer(gen, enc);
+  }
+  this.__gen = gen;
+  this._gen = new BN(gen);
+  return this;
+};
+
+function formatReturnValue(bn, enc) {
+  var buf = new Buffer(bn.toArray());
+  if (!enc) {
+    return buf;
+  } else {
+    return buf.toString(enc);
+  }
+}

+ 105 - 0
utils/blufi/crypto/lib/generatePrime.js

@@ -0,0 +1,105 @@
+var randomBytes = require('randombytes');
+module.exports = findPrime;
+findPrime.simpleSieve = simpleSieve;
+findPrime.fermatTest = fermatTest;
+var BN = require('bn.js');
+var TWENTYFOUR = new BN(24);
+var MillerRabin = require('miller-rabin');
+var millerRabin = new MillerRabin();
+var ONE = new BN(1);
+var TWO = new BN(2);
+var FIVE = new BN(5);
+var SIXTEEN = new BN(16);
+var EIGHT = new BN(8);
+var TEN = new BN(10);
+var THREE = new BN(3);
+var SEVEN = new BN(7);
+var ELEVEN = new BN(11);
+var FOUR = new BN(4);
+var TWELVE = new BN(12);
+var primes = null;
+
+function _getPrimes() {
+  if (primes !== null)
+    return primes;
+
+  var limit = 0x100000;
+  var res = [];
+  res[0] = 2;
+  for (var i = 1, k = 3; k < limit; k += 2) {
+    var sqrt = Math.ceil(Math.sqrt(k));
+    for (var j = 0; j < i && res[j] <= sqrt; j++)
+      if (k % res[j] === 0)
+        break;
+
+    if (i !== j && res[j] <= sqrt)
+      continue;
+
+    res[i++] = k;
+  }
+  primes = res;
+  return res;
+}
+
+function simpleSieve(p) {
+  var primes = _getPrimes();
+
+  for (var i = 0; i < primes.length; i++)
+    if (p.modn(primes[i]) === 0) {
+      if (p.cmpn(primes[i]) === 0) {
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+  return true;
+}
+
+function fermatTest(p) {
+  var red = BN.mont(p);
+  return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0;
+}
+
+function findPrime(bits, gen) {
+  if (bits < 16) {
+    // this is what openssl does
+    if (gen === 2 || gen === 5) {
+      return new BN([0x8c, 0x7b]);
+    } else {
+      return new BN([0x8c, 0x27]);
+    }
+  }
+  gen = new BN(gen);
+
+  var num, n2;
+
+  while (true) {
+    num = new BN(randomBytes(Math.ceil(bits / 8)));
+    while (num.bitLength() > bits) {
+      num.ishrn(1);
+    }
+    if (num.isEven()) {
+      num.iadd(ONE);
+    }
+    if (!num.testn(1)) {
+      num.iadd(TWO);
+    }
+    if (!gen.cmp(TWO)) {
+      while (num.mod(TWENTYFOUR).cmp(ELEVEN)) {
+        num.iadd(FOUR);
+      }
+    } else if (!gen.cmp(FIVE)) {
+      while (num.mod(TEN).cmp(THREE)) {
+        num.iadd(FOUR);
+      }
+    }
+    n2 = num.shrn(1);
+    if (simpleSieve(n2) && simpleSieve(num) &&
+      fermatTest(n2) && fermatTest(num) &&
+      millerRabin.test(n2) && millerRabin.test(num)) {
+      return num;
+    }
+  }
+
+}

+ 84 - 0
utils/blufi/crypto/lib/ieee754.js

@@ -0,0 +1,84 @@
+exports.read = function (buffer, offset, isLE, mLen, nBytes) {
+  var e, m
+  var eLen = (nBytes * 8) - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var nBits = -7
+  var i = isLE ? (nBytes - 1) : 0
+  var d = isLE ? -1 : 1
+  var s = buffer[offset + i]
+
+  i += d
+
+  e = s & ((1 << (-nBits)) - 1)
+  s >>= (-nBits)
+  nBits += eLen
+  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
+
+  m = e & ((1 << (-nBits)) - 1)
+  e >>= (-nBits)
+  nBits += mLen
+  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
+
+  if (e === 0) {
+    e = 1 - eBias
+  } else if (e === eMax) {
+    return m ? NaN : ((s ? -1 : 1) * Infinity)
+  } else {
+    m = m + Math.pow(2, mLen)
+    e = e - eBias
+  }
+  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
+}
+
+exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
+  var e, m, c
+  var eLen = (nBytes * 8) - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
+  var i = isLE ? 0 : (nBytes - 1)
+  var d = isLE ? 1 : -1
+  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
+
+  value = Math.abs(value)
+
+  if (isNaN(value) || value === Infinity) {
+    m = isNaN(value) ? 1 : 0
+    e = eMax
+  } else {
+    e = Math.floor(Math.log(value) / Math.LN2)
+    if (value * (c = Math.pow(2, -e)) < 1) {
+      e--
+      c *= 2
+    }
+    if (e + eBias >= 1) {
+      value += rt / c
+    } else {
+      value += rt * Math.pow(2, 1 - eBias)
+    }
+    if (value * c >= 2) {
+      e++
+      c /= 2
+    }
+
+    if (e + eBias >= eMax) {
+      m = 0
+      e = eMax
+    } else if (e + eBias >= 1) {
+      m = ((value * c) - 1) * Math.pow(2, mLen)
+      e = e + eBias
+    } else {
+      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
+      e = 0
+    }
+  }
+
+  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
+
+  e = (e << mLen) | m
+  eLen += mLen
+  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
+
+  buffer[offset + i - d] |= s * 128
+}

+ 115 - 0
utils/blufi/crypto/lib/miller-rabin.js

@@ -0,0 +1,115 @@
+var bn = require('bn.js');
+var brorand = require('brorand');
+
+function MillerRabin(rand) {
+  this.rand = rand || new brorand.Rand();
+}
+module.exports = MillerRabin;
+
+MillerRabin.create = function create(rand) {
+  return new MillerRabin(rand);
+};
+
+MillerRabin.prototype._randbelow = function _randbelow(n) {
+  var len = n.bitLength();
+  var min_bytes = Math.ceil(len / 8);
+
+  // Generage random bytes until a number less than n is found.
+  // This ensures that 0..n-1 have an equal probability of being selected.
+  do
+    var a = new bn(this.rand.generate(min_bytes));
+  while (a.cmp(n) >= 0);
+
+  return a;
+};
+
+MillerRabin.prototype._randrange = function _randrange(start, stop) {
+  // Generate a random number greater than or equal to start and less than stop.
+  var size = stop.sub(start);
+  return start.add(this._randbelow(size));
+};
+
+MillerRabin.prototype.test = function test(n, k, cb) {
+  var len = n.bitLength();
+  var red = bn.mont(n);
+  var rone = new bn(1).toRed(red);
+
+  if (!k)
+    k = Math.max(1, (len / 48) | 0);
+
+  // Find d and s, (n - 1) = (2 ^ s) * d;
+  var n1 = n.subn(1);
+  for (var s = 0; !n1.testn(s); s++) {}
+  var d = n.shrn(s);
+
+  var rn1 = n1.toRed(red);
+
+  var prime = true;
+  for (; k > 0; k--) {
+    var a = this._randrange(new bn(2), n1);
+    if (cb)
+      cb(a);
+
+    var x = a.toRed(red).redPow(d);
+    if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
+      continue;
+
+    for (var i = 1; i < s; i++) {
+      x = x.redSqr();
+
+      if (x.cmp(rone) === 0)
+        return false;
+      if (x.cmp(rn1) === 0)
+        break;
+    }
+
+    if (i === s)
+      return false;
+  }
+
+  return prime;
+};
+
+MillerRabin.prototype.getDivisor = function getDivisor(n, k) {
+  var len = n.bitLength();
+  var red = bn.mont(n);
+  var rone = new bn(1).toRed(red);
+
+  if (!k)
+    k = Math.max(1, (len / 48) | 0);
+
+  // Find d and s, (n - 1) = (2 ^ s) * d;
+  var n1 = n.subn(1);
+  for (var s = 0; !n1.testn(s); s++) {}
+  var d = n.shrn(s);
+
+  var rn1 = n1.toRed(red);
+
+  for (; k > 0; k--) {
+    var a = this._randrange(new bn(2), n1);
+
+    var g = n.gcd(a);
+    if (g.cmpn(1) !== 0)
+      return g;
+
+    var x = a.toRed(red).redPow(d);
+    if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
+      continue;
+
+    for (var i = 1; i < s; i++) {
+      x = x.redSqr();
+
+      if (x.cmp(rone) === 0)
+        return x.fromRed().subn(1).gcd(n);
+      if (x.cmp(rn1) === 0)
+        break;
+    }
+
+    if (i === s) {
+      x = x.redSqr();
+      return x.fromRed().subn(1).gcd(n);
+    }
+  }
+
+  return false;
+};

+ 31 - 0
utils/blufi/crypto/lib/randombytes.js

@@ -0,0 +1,31 @@
+'use strict'
+
+function oldBrowser() {
+  throw new Error('Secure random number generation is not supported by this browser.\nUse Chrome, Firefox or Internet Explorer 11')
+}
+
+var Buffer = require('safe-buffer').Buffer
+
+module.exports = randomBytes
+
+function randomBytes(size, cb) {
+  // phantomjs needs to throw
+  if (size > 65536) throw new Error('requested too many random bytes')
+  // in case browserify  isn't using the Uint8Array version
+  var arr = [];
+  for (var i = 0; i < size; i++) {
+    arr.push(Math.ceil(Math.random() * 255))
+  }
+  var rawBytes = new Uint8Array(arr)
+
+  // XXX: phantomjs doesn't like a buffer being passed here
+  var bytes = Buffer.from(rawBytes.buffer)
+
+  if (typeof cb === 'function') {
+    return process.nextTick(function () {
+      cb(null, bytes)
+    })
+  }
+
+  return bytes
+}

+ 62 - 0
utils/blufi/crypto/lib/safe-buffer.js

@@ -0,0 +1,62 @@
+/* eslint-disable node/no-deprecated-api */
+var buffer = require('buffer')
+var Buffer = buffer.Buffer
+
+// alternative to using Object.keys for old browsers
+function copyProps (src, dst) {
+  for (var key in src) {
+    dst[key] = src[key]
+  }
+}
+if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
+  module.exports = buffer
+} else {
+  // Copy properties from require('buffer')
+  copyProps(buffer, exports)
+  exports.Buffer = SafeBuffer
+}
+
+function SafeBuffer (arg, encodingOrOffset, length) {
+  return Buffer(arg, encodingOrOffset, length)
+}
+
+// Copy static methods from Buffer
+copyProps(Buffer, SafeBuffer)
+
+SafeBuffer.from = function (arg, encodingOrOffset, length) {
+  if (typeof arg === 'number') {
+    throw new TypeError('Argument must not be a number')
+  }
+  return Buffer(arg, encodingOrOffset, length)
+}
+
+SafeBuffer.alloc = function (size, fill, encoding) {
+  if (typeof size !== 'number') {
+    throw new TypeError('Argument must be a number')
+  }
+  var buf = Buffer(size)
+  if (fill !== undefined) {
+    if (typeof encoding === 'string') {
+      buf.fill(fill, encoding)
+    } else {
+      buf.fill(fill)
+    }
+  } else {
+    buf.fill(0)
+  }
+  return buf
+}
+
+SafeBuffer.allocUnsafe = function (size) {
+  if (typeof size !== 'number') {
+    throw new TypeError('Argument must be a number')
+  }
+  return Buffer(size)
+}
+
+SafeBuffer.allocUnsafeSlow = function (size) {
+  if (typeof size !== 'number') {
+    throw new TypeError('Argument must be a number')
+  }
+  return buffer.SlowBuffer(size)
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 10 - 0
utils/blufi/crypto/md5.min.js


+ 149 - 0
utils/blufi/other/onfire.js

@@ -0,0 +1,149 @@
+/**
+  Copyright (c) 2016 hustcc http://www.atool.org/
+  License: MIT 
+  https://github.com/hustcc/onfire.js
+**/
+/* jshint expr: true */ 
+!function (root, factory) {
+  if (typeof module === 'object' && module.exports)
+    module.exports = factory();
+  else
+    root.onfire = factory();
+}(typeof window !== 'undefined' ? window : this, function () {
+  var __onfireEvents = {},
+   __cnt = 0, // evnet counter
+   string_str = 'string',
+   function_str = 'function',
+   hasOwnKey = Function.call.bind(Object.hasOwnProperty),
+   slice = Function.call.bind(Array.prototype.slice);
+
+  function _bind(eventName, callback, is_one, context) {
+    if (typeof eventName !== string_str || typeof callback !== function_str) {
+      throw new Error('args: '+string_str+', '+function_str+'');
+    }
+    if (! hasOwnKey(__onfireEvents, eventName)) {
+      __onfireEvents[eventName] = {};
+    }
+    __onfireEvents[eventName][++__cnt] = [callback, is_one, context];
+
+    return [eventName, __cnt];
+  }
+  function _each(obj, callback) {
+    for (var key in obj) {
+      if (hasOwnKey(obj, key)) callback(key, obj[key]);
+    }
+  }
+  /**
+   *  onfire.on( event, func, context ) -> Object
+   *  - event (String): The event name to subscribe / bind to
+   *  - func (Function): The function to call when a new event is published / triggered
+   *  Bind / subscribe the event name, and the callback function when event is triggered, will return an event Object
+  **/
+  function on(eventName, callback, context) {
+    return _bind(eventName, callback, 0, context);
+  }
+  /**
+   *  onfire.one( event, func, context ) -> Object
+   *  - event (String): The event name to subscribe / bind to
+   *  - func (Function): The function to call when a new event is published / triggered
+   *  Bind / subscribe the event name, and the callback function when event is triggered only once(can be triggered for one time), will return an event Object
+  **/
+  function one(eventName, callback, context) {
+    return _bind(eventName, callback, 1, context);
+  }
+  function _fire_func(eventName, args) {
+    if (hasOwnKey(__onfireEvents, eventName)) {
+      _each(__onfireEvents[eventName], function(key, item) {
+        item[0].apply(item[2], args); // do the function
+        if (item[1]) delete __onfireEvents[eventName][key]; // when is one, delete it after triggle
+      });
+    }
+  }
+  /**
+   *  onfire.fire( event[, data1 [,data2] ... ] )
+   *  - event (String): The event name to publish
+   *  - data...: The data to pass to subscribers / callbacks
+   *  Async Publishes / fires the the event, passing the data to it's subscribers / callbacks
+  **/
+  function fire(eventName) {
+    // fire events
+    var args = slice(arguments, 1);
+    setTimeout(function () {
+      _fire_func(eventName, args);
+    });
+  }
+  /**
+   *  onfire.fireSync( event[, data1 [,data2] ... ] )
+   *  - event (String): The event name to publish
+   *  - data...: The data to pass to subscribers / callbacks
+   *  Sync Publishes / fires the the event, passing the data to it's subscribers / callbacks
+  **/
+  function fireSync(eventName) {
+    _fire_func(eventName, slice(arguments, 1));
+  }
+  /**
+   * onfire.un( event ) -> Boolean
+   *  - event (String / Object): The message to publish
+   * When passed a event Object, removes a specific subscription.
+   * When passed event name String, removes all subscriptions for that event name(hierarchy)
+  *
+   * Unsubscribe / unbind an event or event object.
+   *
+   * Examples
+   *
+   *  // Example 1 - unsubscribing with a event object
+   *  var event_object = onfire.on('my_event', myFunc);
+   *  onfire.un(event_object);
+   *
+   *  // Example 2 - unsubscribing with a event name string
+   *  onfire.un('my_event');
+  **/
+  function un(event) {
+    var eventName, key, r = false, type = typeof event;
+    if (type === string_str) {
+      // cancel the event name if exist
+      if (hasOwnKey(__onfireEvents, event)) {
+        delete __onfireEvents[event];
+        return true;
+      }
+      return false;
+    }
+    else if (type === 'object') {
+      eventName = event[0];
+      key = event[1];
+      if (hasOwnKey(__onfireEvents, eventName) && hasOwnKey(__onfireEvents[eventName], key)) {
+        delete __onfireEvents[eventName][key];
+        return true;
+      }
+      // can not find this event, return false
+      return false;
+    }
+    else if (type === function_str) {
+      _each(__onfireEvents, function(key_1, item_1) {
+        _each(item_1, function(key_2, item_2) {
+          if (item_2[0] === event) {
+            delete __onfireEvents[key_1][key_2];
+            r = true;
+          }
+        });
+      });
+      return r;
+    }
+    return true;
+  }
+  /**
+   *  onfire.clear()
+   *  Clears all subscriptions
+  **/
+  function clear() {
+    __onfireEvents = {};
+  }
+  return {
+    on: on,
+    one: one,
+    un: un,
+    fire: fire,
+    fireSync: fireSync,
+    clear: clear
+  };
+});

+ 446 - 0
utils/blufi/util.js

@@ -0,0 +1,446 @@
+const SERVICE_TYPE = "_notice_service._tcp.";
+const FACE_DERECT = "face_detect";
+const FACE_RECOGNIZE = "face_recognize";
+const FACE_ENROll = "face_enroll";
+const STOP_STREAM = "stop_stream";
+const GET_ID = "get_id";
+const FACE_DELETE = "face_delete";
+const DELETE_ALL = "delete_all";
+const ON_STATUS = 1;
+const OFF_STATUS = 0;
+const HTTP_STR = "http://null:80/control";
+const HTTP_STATUS = "http://null:80/status";
+const HTTP_STREAM = "http://null:81/stream";
+const FRAME_CTRL_POSITION_ENCRYPTED = 0;
+const FRAME_CTRL_POSITION_CHECKSUM = 1;
+const FRAME_CTRL_POSITION_DATA_DIRECTION = 2;
+const FRAME_CTRL_POSITION_REQUIRE_ACK = 3;
+const FRAME_CTRL_POSITION_FRAG = 4;
+const DIRECTION_OUTPUT = 0;
+const DIRECTION_INPUT = 1;
+const AES_BASE_IV = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+const NEG_SET_SEC_TOTAL_LEN = 0x00;
+const NEG_SET_SEC_ALL_DATA = 0x01;
+const PACKAGE_VALUE = 0x01;
+const SUBTYPE_NEG = 0x00;
+const SUBTYPE_WIFI_MODEl = 0x02;
+const SUBTYPE_END = 0x03;
+const PACKAGE_CONTROL_VALUE = 0x00;
+const SUBTYPE_WIFI_NEG = 0x09;
+const SUBTYPE_SET_SSID = 0x2;
+const SUBTYPE_SET_PWD = 0x3;
+const SUBTYPE_WIFI_LIST_NEG = 17;
+const SUBTYPE_NEGOTIATION_NEG = 0;
+const SUBTYPE_CUSTOM_DATA = 0x13;
+var DH_P = "cf5cf5c38419a724957ff5dd323b9c45c3cdd261eb740f69aa94b8bb1a5c96409153bd76b24222d03274e4725a5406092e9e82e9135c643cae98132b0d95f7d65347c68afc1e677da90e51bbab5f5cf429c291b4ba39c6b2dc5e8c7231e46aa7728e87664532cdf547be20c9a3fa8342be6e34371a27c06f7dc0edddd2f86373";
+var DH_G = "02";
+
+const descSucListEN = ["Bluetooth connecting...", "Bluetooth connection successful", "Device information is successfully obtained", "Attribute information is successfully obtained", "Send configuration information...", "Configuration information sent successfully", "Connection successfully"];
+const descFailListEN = ["Bluetooth connection failed", "Device information acquisition failed", "Attribute information acquisition failed", "Configuration information sent failed", "Distribution network failed"];
+
+const descSucList = ["蓝牙连接...", "蓝牙连接成功", "设备信息已成功获取", "属性信息已成功获取", "发送配置信息...", "成功发送配置信息", "成功连接"];
+const descFailList = ["蓝牙连接失败", "设备信息获取失败", "属性信息获取失败", "配置信息发送失败", "网络配置失败","蓝牙异常断开"];
+const successList = {
+  "0": "NULL",
+  "1": "STA",
+  "2": "SoftAP",
+  "3": "SoftAP & STA"
+};
+const failList = {
+  "0": "sequence error",
+  "1": "checksum error",
+  "2": "decrypt error",
+  "3": "encrypt error",
+  "4": "init security error",
+  "5": "dh malloc error",
+  "6": "dh param error",
+  "7": "read param error",
+  "8": "make public error"
+};
+var CRC_TB = [
+  0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+  0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+  0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+  0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+  0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+  0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+  0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+  0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+  0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+  0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+  0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+  0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+  0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+  0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+  0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+  0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+];
+
+//转16进制
+const ab2hex = buffer => {
+  var hexArr = Array.prototype.map.call(
+    new Uint8Array(buffer),
+    function(bit) {
+      return ('00' + bit.toString(16)).slice(-2)
+    }
+  )
+  return hexArr;
+}
+//16进制转字符串
+const hexCharCodeToStr = hexCharCodeStr => {
+  var trimedStr = hexCharCodeStr.trim();
+  var rawStr =
+    trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
+  var len = rawStr.length;
+  if (len % 2 !== 0) {
+    alert("Illegal Format ASCII Code!");
+    return "";
+  }
+  var curCharCode;
+  var resultStr = [];
+  for (var i = 0; i < len; i = i + 2) {
+    curCharCode = parseInt(rawStr.substr(i, 2), 16); // ASCII Code Value
+    resultStr.push(String.fromCharCode(curCharCode));
+  }
+  return resultStr.join("");
+}
+//过滤名称
+const filterDevice = (devices, filterName) => {
+  var self = this,
+    list = [];
+  for (var i = 0; i < devices.length; i++) {
+    var device = devices[i];
+    var re = new RegExp("^(" + filterName + ")");
+    if (re.test(device["name"])) {
+      list.push(device);
+    }
+  }
+  return list;
+}
+//获去type
+const getType = (pkgType, subType) => {
+  return (subType << 2) | pkgType;
+}
+//unit8Arry转数组
+const uint8ArrayToArray = uint8Array => {
+  var array = [];
+
+  for (var i = 0; i < uint8Array.byteLength; i++) {
+    array[i] = uint8Array[i];
+  }
+
+  return array;
+}
+//16进制转二进制数组
+const hexToBinArray = str => {
+  var dec = parseInt(str, 16),
+    bin = dec.toString(2),
+    len = bin.length;
+  if (len < 8) {
+    var diff = 8 - len,
+      zeros = "";
+    for (var i = 0; i < diff; i++) {
+      zeros += "0";
+    }
+    bin = zeros + bin;
+  }
+  return bin.split("");
+}
+//16进制转数组
+const hexByArray = str => {
+  var arr = [];
+  if (str.length % 2 != 0) {
+    str = "0" + str;
+  }
+  for (var i = 0; i < str.length; i += 2) {
+    arr.push(str.substring(i, i + 2))
+  }
+  return arr;
+}
+//16进制转整形数组
+const hexByInt = str => {
+  var arr = [];
+  if (str.length % 2 != 0) {
+    str = "0" + str;
+  }
+  for (var i = 0; i < str.length; i += 2) {
+    arr.push(parseInt(str.substring(i, i + 2), 16))
+  }
+  return arr;
+}
+//排序
+const sortBy = (attr, rev) => {
+  //第二个参数没有传递 默认升序排列
+  if (rev == undefined) {
+    rev = 1;
+  } else {
+    rev = (rev) ? 1 : -1;
+  }
+  return function(a, b) {
+    a = a[attr];
+    b = b[attr];
+    if (a < b) {
+      return rev * -1;
+    } else if (a > b) {
+      return rev * 1;
+    }
+    return 0;
+  }
+}
+//判断非空
+const _isEmpty = str => {
+  if (str === "" || str === null || str === undefined || str === "null" || str === "undefined") {
+    return true;
+  } else {
+    return false;
+  }
+}
+//设置配网失败背景色
+const setFailBg = () => {
+  wx.setNavigationBarColor({
+    frontColor: "#ffffff",
+    backgroundColor: '#737d89',
+  })
+}
+//设置配网成功背景色
+const setSucBg = () => {
+  wx.setNavigationBarColor({
+    frontColor: "#ffffff",
+    backgroundColor: '#4d9efb',
+  })
+}
+//组装数据格式
+const writeData = (type, subType, frameCtl, seq, len, data) => {
+  var value = [],type = getType(type, subType);
+  value.push(type);
+  value.push(frameCtl);
+  value.push(seq);
+  value.push(len);
+  if (!_isEmpty(data)) {
+    value = value.concat(data);
+  }
+  return value;
+}
+//是否分包
+const isSubcontractor = (data, checksum, sequence, encrypt) => {
+  var len = 0,
+    lenData = [],
+    laveData = [],
+    flag = false;
+  var total = data.length;
+  if (total > 16) {
+    if (checksum) {
+      lenData = data.slice(0, 12);
+      laveData = data.slice(12);
+    } else {
+      lenData = data.slice(0, 14);
+      laveData = data.slice(14);
+    }
+    var len1 = (total >> 8) & 0xff;
+    var len2 = total & 0xff;
+    lenData.splice(0, 0, len1);
+    lenData.splice(0, 0, len2);
+    len = lenData.length;
+    flag = true;
+  } else {
+    lenData = data;
+    len = lenData.length;
+  }
+  if (checksum) {
+    lenData = assemblyChecksum(lenData, len, sequence);
+  }
+  return {
+    "len": len,
+    "lenData": lenData,
+    "laveData": laveData,
+    "flag": flag
+  }
+}
+const assemblyChecksum = (list, len, sequence, encrypt) => {
+  var checkData = [];
+  checkData.push(sequence);
+  checkData.push(len);
+  checkData = checkData.concat(list);
+  var crc = caluCRC(0, checkData);
+  var checksumByte1 = crc & 0xff;
+  var checksumByte2 = (crc >> 8) & 0xff;
+  list.push(checksumByte1);
+  list.push(checksumByte2);
+  return list;
+}
+//加密发送的数据
+const encrypt = (aesjs, md5Key, sequence, data, checksum) => {
+  var iv = generateAESIV(sequence),
+    sumArr = [],
+    list = [];
+  if (checksum) {
+    var len = data.length - 2;
+    list = data.slice(0, len);
+    sumArr = data.slice(len);
+  } else {
+    list = data;
+  }
+  var encryptData = uint8ArrayToArray(blueAesEncrypt(aesjs, md5Key, iv, new Uint8Array(list)));
+  return encryptData.concat(sumArr);
+}
+
+//DH加密
+const blueDH = (p, g, crypto) => {
+  var client = crypto.createDiffieHellman(p, "hex", g, "hex");
+  var clientKey = client.generateKeys();
+  //var clientSecret = client.computeSecret(server.getPublicKey());
+  return client;
+}
+//md5加密
+const blueMd5 = (md5, key) => {
+  var arr = md5.array(key);
+  return arr;
+}
+// aes加密
+const blueAesEncrypt = (aesjs, mdKey, iv, bytes) => {
+  var aesOfb = new aesjs.ModeOfOperation.ofb(mdKey, iv);
+  var encryptedBytes = aesOfb.encrypt(bytes);
+  return encryptedBytes;
+}
+//aes解密
+const blueAesDecrypt = (aesjs, mdKey, iv, bytes) => {
+  var aesOfb = new aesjs.ModeOfOperation.ofb(mdKey, iv);
+  var decryptedBytes = aesOfb.decrypt(bytes);
+  return decryptedBytes;
+}
+//获取Frame Control
+const getFrameCTRLValue = (encrypted, checksum, direction, requireAck, frag) => {
+  var frame = 0;
+  if (encrypted) {
+    frame = frame | (1 << FRAME_CTRL_POSITION_ENCRYPTED);
+  }
+  if (checksum) {
+    frame = frame | (1 << FRAME_CTRL_POSITION_CHECKSUM);
+  }
+  if (direction == DIRECTION_INPUT) {
+    frame = frame | (1 << FRAME_CTRL_POSITION_DATA_DIRECTION);
+  }
+  if (requireAck) {
+    frame = frame | (1 << FRAME_CTRL_POSITION_REQUIRE_ACK);
+  }
+  if (frag) {
+    frame = frame | (1 << FRAME_CTRL_POSITION_FRAG);
+  }
+  return frame;
+}
+//获取aes iv
+const generateAESIV = sequence => {
+  var result = [];
+  for (var i = 0; i < 16; i++) {
+    if (i == 0) {
+      result[0] = sequence;
+    } else {
+      result[i] = AES_BASE_IV[i];
+    }
+  }
+  return result;
+}
+//计算CRC值
+const caluCRC = (crc, pByte) => {
+  crc = (~crc) & 0xffff;
+  for (var i in pByte) {
+    crc = CRC_TB[((crc & 0xffff) >> 8) ^ (pByte[i] & 0xff)] ^ ((crc & 0xffff) << 8);
+  }
+  return (~crc) & 0xffff;
+}
+const send = (method, url, data, suc, error) => {
+  console.log(url);
+  wx.request({
+    url: url,
+    data: data,
+    header: {
+      'Content-Type': 'application/json'
+    },
+    method: method,
+    success: function(res) {
+      if (!_isEmpty(suc)) {
+        suc(res.data);
+      }
+    },
+    fail: function(res) {
+      if (!_isEmpty(error)) {
+        error();
+      }
+    }
+  })
+}
+const showLoading = msg => {
+  wx.hideLoading();
+  wx.showLoading({
+    title: msg,
+    mask: true
+  });
+}
+const showToast = msg => {
+  wx.showToast({
+    title: msg,
+    icon: 'none',
+    duration: 2000
+  })
+}
+module.exports = {
+  _isEmpty: _isEmpty,
+  send: send,
+  SERVICE_TYPE: SERVICE_TYPE,
+  FACE_DERECT: FACE_DERECT,
+  FACE_RECOGNIZE: FACE_RECOGNIZE,
+  FACE_ENROll: FACE_ENROll,
+  STOP_STREAM: STOP_STREAM,
+  GET_ID: GET_ID,
+  ON_STATUS: ON_STATUS,
+  OFF_STATUS: OFF_STATUS,
+  HTTP_STR: HTTP_STR,
+  HTTP_STATUS: HTTP_STATUS,
+  HTTP_STREAM: HTTP_STREAM,
+  FACE_DELETE: FACE_DELETE,
+  DELETE_ALL: DELETE_ALL,
+  ab2hex: ab2hex,
+  hexCharCodeToStr: hexCharCodeToStr,
+  filterDevice: filterDevice,
+  getType: getType,
+  hexToBinArray: hexToBinArray,
+  hexByArray: hexByArray,
+  hexByInt: hexByInt,
+  sortBy: sortBy,
+  setFailBg: setFailBg,
+  setSucBg: setSucBg,
+  writeData: writeData,
+  isSubcontractor: isSubcontractor,
+  getFrameCTRLValue: getFrameCTRLValue,
+  blueDH: blueDH,
+  blueMd5: blueMd5,
+  blueAesEncrypt: blueAesEncrypt,
+  blueAesDecrypt: blueAesDecrypt,
+  uint8ArrayToArray: uint8ArrayToArray,
+  generateAESIV: generateAESIV,
+  caluCRC: caluCRC,
+  encrypt: encrypt,
+  DH_P: DH_P,
+  DH_G: DH_G,
+  DIRECTION_OUTPUT: DIRECTION_OUTPUT,
+  DIRECTION_INPUT: DIRECTION_INPUT,
+  NEG_SET_SEC_TOTAL_LEN: NEG_SET_SEC_TOTAL_LEN,
+  NEG_SET_SEC_ALL_DATA: NEG_SET_SEC_ALL_DATA,
+  PACKAGE_VALUE: PACKAGE_VALUE,
+  SUBTYPE_NEG: SUBTYPE_NEG,
+  PACKAGE_CONTROL_VALUE: PACKAGE_CONTROL_VALUE,
+  SUBTYPE_WIFI_NEG: SUBTYPE_WIFI_NEG,
+  SUBTYPE_WIFI_LIST_NEG: SUBTYPE_WIFI_LIST_NEG,
+  SUBTYPE_NEGOTIATION_NEG: SUBTYPE_NEGOTIATION_NEG,
+  SUBTYPE_WIFI_MODEl: SUBTYPE_WIFI_MODEl,
+  SUBTYPE_SET_SSID: SUBTYPE_SET_SSID,
+  SUBTYPE_SET_PWD: SUBTYPE_SET_PWD,
+  SUBTYPE_END: SUBTYPE_END,
+  SUBTYPE_CUSTOM_DATA: SUBTYPE_CUSTOM_DATA,
+  descSucList: descSucList,
+  descFailList: descFailList,
+  successList: successList,
+  failList: failList,
+  showToast: showToast,
+  showLoading: showLoading
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 6 - 0
utils/blufi/weui.scss


+ 847 - 0
utils/blufi/xBlufi-wx-impl.js

@@ -0,0 +1,847 @@
+let tempTimer = 0;
+let client = null;
+let util = null
+let mDeviceEvent = null
+let crypto = null
+let md5 = null
+let aesjs = null
+const timeOut = 20; //超时时间
+var timeId = "";
+let sequenceControl = 0;
+let sequenceNumber = -1;
+
+let _self = {
+  data: {
+    deviceId: null,
+    isConnected: false,
+    failure: false,
+    value: 0,
+    desc: "请耐心等待...",
+    isChecksum: true,
+    isEncrypt: true,
+    flagEnd: false,
+    defaultData: 1,
+    ssidType: 2,
+    passwordType: 3,
+    meshIdType: 3,
+    deviceId: "",
+    ssid: "",
+    uuid: "",
+    serviceId: "",
+    password: "",
+    meshId: "",
+    processList: [],
+    result: [],
+    service_uuid: "0000FFFF-0000-1000-8000-00805F9B34FB",
+    characteristic_write_uuid: "0000FF01-0000-1000-8000-00805F9B34FB",
+    characteristic_read_uuid: "0000FF02-0000-1000-8000-00805F9B34FB",
+    customData: null,
+    md5Key: 0,
+  }
+}
+
+function buf2hex(buffer) {
+  return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
+}
+
+function buf2string(buffer) {
+  var arr = Array.prototype.map.call(new Uint8Array(buffer), x => x);
+  var str = '';
+  for (var i = 0; i < arr.length; i++) {
+    str += String.fromCharCode(arr[i]);
+  }
+  return str;
+}
+
+function getSsids(str) {
+  var list = [],
+    strs = str.split(":");
+  for (var i = 0; i < strs.length; i++) {
+    list.push(parseInt(strs[i], 16));
+  }
+  return list;
+}
+
+function getCharCodeat(str) {
+  var list = [];
+  for (var i = 0; i < str.length; i++) {
+    list.push(str.charCodeAt(i));
+  }
+  return list;
+}
+function getCharCodeatSSID(str) {
+  return unescape(encodeURIComponent(str)).split("").map(val => val.charCodeAt());
+}
+
+
+//判断返回的数据是否加密
+function isEncrypt(fragNum, list, md5Key) {
+  var checksum = [],
+    checkData = [];
+  if (fragNum[7] == "1") { //返回数据加密
+    if (fragNum[6] == "1") {
+      var len = list.length - 2;
+      list = list.slice(0, len);
+    }
+    var iv = this.generateAESIV(parseInt(list[2], 16));
+    if (fragNum[3] == "0") { //未分包
+      list = list.slice(4);
+      _self.data.flagEnd = true
+    } else { //分包
+      list = list.slice(6);
+    }
+  } else { //返回数据未加密
+    if (fragNum[6] == "1") {
+      var len = list.length - 2;
+      list = list.slice(0, len);
+    }
+    if (fragNum[3] == "0") { //未分包
+      list = list.slice(4);
+      _self.data.flagEnd = true
+    } else { //分包
+      list = list.slice(6);
+    }
+  }
+  return list;
+}
+
+function getSecret(deviceId, serviceId, characteristicId, client, kBytes, pBytes, gBytes, data) {
+
+  var obj = [],
+    frameControl = 0;
+  sequenceControl = parseInt(sequenceControl) + 1;
+  if (!util._isEmpty(data)) {
+    obj = util.isSubcontractor(data, true, sequenceControl);
+    frameControl = util.getFrameCTRLValue(false, true, util.DIRECTION_OUTPUT, false, obj.flag);
+  } else {
+    data = [];
+    data.push(util.NEG_SET_SEC_ALL_DATA);
+    var pLength = pBytes.length;
+    var pLen1 = (pLength >> 8) & 0xff;
+    var pLen2 = pLength & 0xff;
+    data.push(pLen1);
+    data.push(pLen2);
+    data = data.concat(pBytes);
+    var gLength = gBytes.length;
+    var gLen1 = (gLength >> 8) & 0xff;
+    var gLen2 = gLength & 0xff;
+    data.push(gLen1);
+    data.push(gLen2);
+    data = data.concat(gBytes);
+    var kLength = kBytes.length;
+    var kLen1 = (kLength >> 8) & 0xff;
+    var kLen2 = kLength & 0xff;
+    data.push(kLen1);
+    data.push(kLen2);
+    data = data.concat(kBytes);
+    obj = util.isSubcontractor(data, true, sequenceControl);
+    frameControl = util.getFrameCTRLValue(false, true, util.DIRECTION_OUTPUT, false, obj.flag);
+  }
+  var value = util.writeData(util.PACKAGE_VALUE, util.SUBTYPE_NEG, frameControl, sequenceControl, obj.len, obj.lenData);
+  var typedArray = new Uint8Array(value);
+  console.log(typedArray)
+  wx.writeBLECharacteristicValue({
+    deviceId: deviceId,
+    serviceId: serviceId,
+    characteristicId: characteristicId,
+    value: typedArray.buffer,
+    success: function (res) {
+      if (obj.flag) {
+        getSecret(deviceId, serviceId, characteristicId, client, kBytes, pBytes, gBytes, obj.laveData);
+      }
+    },
+    fail: function (res) {
+      console.log(res)
+      console.log(deviceId)
+      console.log(serviceId)
+      console.log(characteristicId)
+      console.log(typedArray.length)
+    }
+  })
+}
+
+function writeDeviceRouterInfoStart(deviceId, serviceId, characteristicId, data) {
+  var obj = {},
+    frameControl = 0;
+  sequenceControl = parseInt(sequenceControl) + 1;
+  if (!util._isEmpty(data)) {
+    obj = util.isSubcontractor(data, _self.data.isChecksum, sequenceControl, _self.data.isEncrypt);
+    frameControl = util.getFrameCTRLValue(_self.data.isEncrypt, _self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
+  } else {
+    obj = util.isSubcontractor([_self.data.defaultData], _self.data.isChecksum, sequenceControl, true);
+    frameControl = util.getFrameCTRLValue(_self.data.isEncrypt, _self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
+  }
+  var defaultData = util.encrypt(aesjs, _self.data.md5Key, sequenceControl, obj.lenData, true);
+  var value = util.writeData(util.PACKAGE_CONTROL_VALUE, util.SUBTYPE_WIFI_MODEl, frameControl, sequenceControl, obj.len, defaultData);
+  var typedArray = new Uint8Array(value)
+  wx.writeBLECharacteristicValue({
+    deviceId: deviceId,
+    serviceId: serviceId,
+    characteristicId: characteristicId,
+    value: typedArray.buffer,
+    success: function (res) {
+      if (obj.flag) {
+        writeDeviceRouterInfoStart(deviceId, serviceId, characteristicId, obj.laveData);
+      } else {
+        writeRouterSsid(deviceId, serviceId, characteristicId, null);
+      }
+    },
+    fail: function (res) {
+    }
+  })
+}
+
+function writeCutomsData(deviceId, serviceId, characteristicId, data) {
+  var obj = {},
+    frameControl = 0;
+  sequenceControl = parseInt(sequenceControl) + 1;
+  if (!util._isEmpty(data)) {
+    obj = util.isSubcontractor(data, _self.data.isChecksum, sequenceControl, _self.data.isEncrypt);
+    frameControl = util.getFrameCTRLValue(_self.data.isEncrypt, _self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
+  } else {
+    var ssidData = getCharCodeat(_self.data.customData);
+    obj = util.isSubcontractor(ssidData, _self.data.isChecksum, sequenceControl, _self.data.isEncrypt);
+    frameControl = util.getFrameCTRLValue(_self.data.isEncrypt, _self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
+  }
+  var defaultData = util.encrypt(aesjs, _self.data.md5Key, sequenceControl, obj.lenData, true);
+  var value = util.writeData(util.PACKAGE_VALUE, util.SUBTYPE_CUSTOM_DATA, frameControl, sequenceControl, obj.len, defaultData);
+  var typedArray = new Uint8Array(value)
+  wx.writeBLECharacteristicValue({
+    deviceId: deviceId,
+    serviceId: serviceId,
+    characteristicId: characteristicId,
+    value: typedArray.buffer,
+    success: function (res) {
+      if (obj.flag) {
+        writeCutomsData(deviceId, serviceId, characteristicId, obj.laveData);
+      }
+    },
+    fail: function (res) {
+      //console.log(257);
+    }
+  })
+}
+
+
+function writeGetNearRouterSsid(deviceId, serviceId, characteristicId, data) {
+  sequenceControl = parseInt(sequenceControl) + 1;
+  var frameControl = util.getFrameCTRLValue(_self.data.isEncrypt, false, util.DIRECTION_OUTPUT, false, false);
+  var value = util.writeData(_self.data.PACKAGE_CONTROL_VALUE, util.SUBTYPE_WIFI_NEG, frameControl, sequenceControl, 0, null);
+  var typedArray = new Uint8Array(value)
+  wx.writeBLECharacteristicValue({
+    deviceId: deviceId,
+    serviceId: serviceId,
+    characteristicId: characteristicId,
+    value: typedArray.buffer,
+    success: function (res) {
+
+    },
+    fail: function (res) {
+
+    }
+  })
+}
+
+
+
+function writeRouterSsid(deviceId, serviceId, characteristicId, data) {
+  var obj = {},
+    frameControl = 0;
+  sequenceControl = parseInt(sequenceControl) + 1;
+  if (!util._isEmpty(data)) {
+    obj = util.isSubcontractor(data, _self.data.isChecksum, sequenceControl, _self.data.isEncrypt);
+    frameControl = util.getFrameCTRLValue(_self.data.isEncrypt, _self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
+  } else {
+    // var ssidData = getCharCodeat(_self.data.ssid);
+    var ssidData = getCharCodeatSSID(_self.data.ssid);
+    obj = util.isSubcontractor(ssidData, _self.data.isChecksum, sequenceControl, _self.data.isEncrypt);
+    frameControl = util.getFrameCTRLValue(_self.data.isEncrypt, _self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
+  }
+  var defaultData = util.encrypt(aesjs, _self.data.md5Key, sequenceControl, obj.lenData, true);
+  var value = util.writeData(util.PACKAGE_VALUE, util.SUBTYPE_SET_SSID, frameControl, sequenceControl, obj.len, defaultData);
+  var typedArray = new Uint8Array(value)
+  wx.writeBLECharacteristicValue({
+    deviceId: deviceId,
+    serviceId: serviceId,
+    characteristicId: characteristicId,
+    value: typedArray.buffer,
+    success: function (res) {
+      if (obj.flag) {
+        writeRouterSsid(deviceId, serviceId, characteristicId, obj.laveData);
+      } else {
+        writeDevicePwd(deviceId, serviceId, characteristicId, null);
+      }
+    },
+    fail: function (res) {
+      //console.log(257);
+    }
+  })
+}
+
+function writeDevicePwd(deviceId, serviceId, characteristicId, data) {
+  var obj = {},
+    frameControl = 0;
+  sequenceControl = parseInt(sequenceControl) + 1;
+  if (!util._isEmpty(data)) {
+    obj = util.isSubcontractor(data, _self.data.isChecksum, sequenceControl, _self.data.isEncrypt);
+    frameControl = util.getFrameCTRLValue(_self.data.isEncrypt, _self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
+  } else {
+    var pwdData = getCharCodeat(_self.data.password);
+    obj = util.isSubcontractor(pwdData, _self.data.isChecksum, sequenceControl, _self.data.isEncrypt);
+    frameControl = util.getFrameCTRLValue(_self.data.isEncrypt, _self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
+  }
+  var defaultData = util.encrypt(aesjs, _self.data.md5Key, sequenceControl, obj.lenData, true);
+  var value = util.writeData(util.PACKAGE_VALUE, util.SUBTYPE_SET_PWD, frameControl, sequenceControl, obj.len, defaultData);
+  var typedArray = new Uint8Array(value)
+
+  wx.writeBLECharacteristicValue({
+    deviceId: deviceId,
+    serviceId: serviceId,
+    characteristicId: characteristicId,
+    value: typedArray.buffer,
+    success: function (res) {
+      if (obj.flag) {
+        writeDevicePwd(deviceId, serviceId, characteristicId, obj.laveData);
+      } else {
+        writeDeviceEnd(deviceId, serviceId, characteristicId, null);
+      }
+    },
+    fail: function (res) { }
+  })
+}
+
+function writeDeviceEnd(deviceId, serviceId, characteristicId) {
+  sequenceControl = parseInt(sequenceControl) + 1;
+  var frameControl = util.getFrameCTRLValue(_self.data.isEncrypt, false, util.DIRECTION_OUTPUT, false, false);
+  var value = util.writeData(_self.data.PACKAGE_CONTROL_VALUE, util.SUBTYPE_END, frameControl, sequenceControl, 0, null);
+  var typedArray = new Uint8Array(value)
+  wx.writeBLECharacteristicValue({
+    deviceId: deviceId,
+    serviceId: serviceId,
+    characteristicId: characteristicId,
+    value: typedArray.buffer,
+    success: function (res) {
+
+    },
+    fail: function (res) {
+
+    }
+  })
+}
+
+function init() {
+
+  let mOnFire = require("./other/onfire.js");
+  mDeviceEvent = require('./xBlufi.js');
+
+  util = require('@/utils/blufi/util.js');
+  crypto = require('@/utils/blufi/crypto/crypto-dh.js');
+  md5 = require('@/utils/blufi/crypto/md5.min.js');
+  aesjs = require('@/utils/blufi/crypto/aes.js');
+
+  wx.onBLEConnectionStateChange(function (res) {
+    let obj = {
+      'type': mDeviceEvent.XBLUFI_TYPE.TYPE_STATUS_CONNECTED,
+      'result': res.connected,
+      'data': res
+    }
+    mDeviceEvent.notifyDeviceMsgEvent(obj);
+  })
+
+  mDeviceEvent.listenStartDiscoverBle(true, function (options) {
+
+    if (options.isStart) {
+      //第一步检查蓝牙适配器是否可用
+      wx.onBluetoothAdapterStateChange(function (res) {
+        if (!res.available) {
+
+        }
+      });
+      //第二步关闭适配器,重新来搜索
+      wx.closeBluetoothAdapter({
+        complete: function (res) {
+          wx.openBluetoothAdapter({
+            success: function (res) {
+              wx.getBluetoothAdapterState({
+                success: function (res) {
+                  wx.stopBluetoothDevicesDiscovery({
+                    success: function (res) {
+                      let devicesList = [];
+                      let countsTimes = 0;
+                      wx.onBluetoothDeviceFound(function (devices) {
+                        //剔除重复设备,兼容不同设备API的不同返回值
+                        var isnotexist = true;
+                        if (devices.deviceId) {
+                          if (devices.advertisData) {
+                            devices.advertisData = buf2hex(devices.advertisData)
+                          } else {
+                            devices.advertisData = ''
+                          }
+                          for (var i = 0; i < devicesList.length; i++) {
+                            if (devices.deviceId === devicesList[i].deviceId) {
+                              isnotexist = false
+                            }
+                          }
+                          if (isnotexist) {
+                            devicesList.push(devices)
+                          }
+                        } else if (devices.devices) {
+                          if (devices.devices[0].advertisData) {
+                            devices.devices[0].advertisData = buf2hex(devices.devices[0].advertisData)
+                          } else {
+                            devices.devices[0].advertisData = ''
+                          }
+                          for (var i = 0; i < devicesList.length; i++) {
+                            if (devices.devices[0].deviceId == devicesList[i].deviceId) {
+                              isnotexist = false
+                            }
+                          }
+                          if (isnotexist) {
+                            devicesList.push(devices.devices[0])
+                          }
+                        } else if (devices[0]) {
+                          if (devices[0].advertisData) {
+                            devices[0].advertisData = buf2hex(devices[0].advertisData)
+                          } else {
+                            devices[0].advertisData = ''
+                          }
+                          for (var i = 0; i < devices_list.length; i++) {
+                            if (devices[0].deviceId == devicesList[i].deviceId) {
+                              isnotexist = false
+                            }
+                          }
+                          if (isnotexist) {
+                            devicesList.push(devices[0])
+                          }
+                        }
+
+                        let obj = {
+                          'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS,
+                          'result': true,
+                          'data': devicesList
+                        }
+                        mDeviceEvent.notifyDeviceMsgEvent(obj);
+                      })
+                      wx.startBluetoothDevicesDiscovery({
+                        allowDuplicatesKey: true,
+                        success: function (res) {
+                          let obj = {
+                            'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START,
+                            'result': true,
+                            'data': res
+                          }
+                          mDeviceEvent.notifyDeviceMsgEvent(obj);
+                          //开始扫码,清空列表
+                          devicesList.length = 0;
+
+                        },
+                        fail: function (res) {
+                          let obj = {
+                            'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START,
+                            'result': false,
+                            'data': res
+                          }
+                          mDeviceEvent.notifyDeviceMsgEvent(obj);
+                        }
+                      });
+                    },
+                    fail: function (res) {
+                      let obj = {
+                        'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START,
+                        'result': false,
+                        'data': res
+                      }
+                      mDeviceEvent.notifyDeviceMsgEvent(obj);
+                    }
+                  });
+                },
+                fail: function (res) {
+                  let obj = {
+                    'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START,
+                    'result': false,
+                    'data': res
+                  }
+                  mDeviceEvent.notifyDeviceMsgEvent(obj);
+                }
+              });
+            },
+            fail: function (res) {
+              let obj = {
+                'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START,
+                'result': false,
+                'data': res
+              }
+              mDeviceEvent.notifyDeviceMsgEvent(obj);
+            }
+          });
+        }
+      });
+    } else {
+      wx.stopBluetoothDevicesDiscovery({
+        success: function (res) {
+          clearInterval(tempTimer);
+          let obj = {
+            'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_STOP,
+            'result': true,
+            'data': res
+          }
+          mDeviceEvent.notifyDeviceMsgEvent(obj);
+        },
+        fail: function (res) {
+          let obj = {
+            'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_STOP,
+            'result': false,
+            'data': res
+          }
+          mDeviceEvent.notifyDeviceMsgEvent(obj);
+        }
+      })
+    }
+  })
+
+
+  mDeviceEvent.listenConnectBle(true, function (options) {
+    //console.log("我要连接?", (options.isStart))
+
+    if (options.isStart)
+      wx.createBLEConnection({
+        deviceId: options.deviceId,
+        success: function (res) {
+          wx.setBLEMTU({
+            deviceId: options.deviceId,
+            mtu: 128
+          })
+          _self.data.deviceId = options.deviceId
+          mDeviceEvent.notifyDeviceMsgEvent({
+            'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CONNECTED,
+            'result': true,
+            'data': {
+              deviceId: options.deviceId,
+              name: options.name
+            },
+          });
+        },
+        fail: function (res) {
+          _self.data.deviceId = null
+          mDeviceEvent.notifyDeviceMsgEvent({
+            'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CONNECTED,
+            'result': false,
+            'data': res,
+          });
+        }
+      });
+    else wx.closeBLEConnection({
+      deviceId: options.deviceId,
+      success: function (res) {
+        console.log('断开成功')
+        _self.data.deviceId = null
+        mDeviceEvent.notifyDeviceMsgEvent({
+          'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CLOSE_CONNECTED,
+          'result': true,
+          'data': {
+            deviceId: options.deviceId,
+            name: options.name
+          }
+        });
+      },
+      fail: function (res) {
+        _self.data.deviceId = null
+        mDeviceEvent.notifyDeviceMsgEvent({
+          'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CLOSE_CONNECTED,
+          'result': false,
+          'data': res,
+        });
+      }
+    })
+  })
+
+  mDeviceEvent.listenInitBleEsp32(true, function (options) {
+    sequenceControl = 0;
+    sequenceNumber = -1;
+    _self = null
+    _self = {
+      data: {
+        deviceId: null,
+        isConnected: false,
+        failure: false,
+        value: 0,
+        desc: "请耐心等待...",
+        isChecksum: true,
+        isEncrypt: true,
+        flagEnd: false,
+        defaultData: 1,
+        ssidType: 2,
+        passwordType: 3,
+        meshIdType: 3,
+        deviceId: "",
+        ssid: "",
+        uuid: "",
+        serviceId: "",
+        password: "",
+        meshId: "",
+        processList: [],
+        result: [],
+        service_uuid: "0000FFFF-0000-1000-8000-00805F9B34FB",
+        characteristic_write_uuid: "0000FF01-0000-1000-8000-00805F9B34FB",
+        characteristic_read_uuid: "0000FF02-0000-1000-8000-00805F9B34FB",
+        customData: null,
+        md5Key: 0,
+      }
+    }
+    let deviceId = options.deviceId
+    _self.data.deviceId = options.deviceId
+    wx.getBLEDeviceServices({
+      // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
+      deviceId: deviceId,
+      success: function (res) {
+        var services = res.services;
+        if (services.length > 0) {
+          for (var i = 0; i < services.length; i++) {
+            if (services[i].uuid === _self.data.service_uuid) {
+              var serviceId = services[i].uuid;
+              wx.getBLEDeviceCharacteristics({
+                // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
+                deviceId: deviceId,
+                serviceId: serviceId,
+                success: function (res) {
+                  var list = res.characteristics;
+                  if (list.length > 0) {
+                    for (var i = 0; i < list.length; i++) {
+                      var uuid = list[i].uuid;
+                      if (uuid == _self.data.characteristic_write_uuid) {
+                        _self.data.serviceId = serviceId;
+                        _self.data.uuid = uuid;
+                        wx.notifyBLECharacteristicValueChange({
+                          state: true, // 启用 notify 功能
+                          deviceId: deviceId,
+                          serviceId: serviceId,
+                          characteristicId: list[1].uuid,
+                          success: function (res) {
+                            let characteristicId = _self.data.characteristic_write_uuid
+                            //通知设备交互方式(是否加密) start
+                            client = util.blueDH(util.DH_P, util.DH_G, crypto);
+                            var kBytes = util.uint8ArrayToArray(client.getPublicKey());
+                            var pBytes = util.hexByInt(util.DH_P);
+                            var gBytes = util.hexByInt(util.DH_G);
+                            var pgkLength = pBytes.length + gBytes.length + kBytes.length + 6;
+                            var pgkLen1 = (pgkLength >> 8) & 0xff;
+                            var pgkLen2 = pgkLength & 0xff;
+                            var data = [];
+                            data.push(util.NEG_SET_SEC_TOTAL_LEN);
+                            data.push(pgkLen1);
+                            data.push(pgkLen2);
+                            var frameControl = util.getFrameCTRLValue(false, false, util.DIRECTION_OUTPUT, false, false);
+                            var value = util.writeData(util.PACKAGE_VALUE, util.SUBTYPE_NEG, frameControl, sequenceControl, data.length, data);
+                            var typedArray = new Uint8Array(value);
+                            wx.writeBLECharacteristicValue({
+                              deviceId: deviceId,
+                              serviceId: serviceId,
+                              characteristicId: characteristicId,
+                              value: typedArray.buffer,
+                              success: function (res) {
+                                getSecret(deviceId, serviceId, characteristicId, client, kBytes, pBytes, gBytes, null);
+                              },
+                              fail: function (res) {
+                                let obj = {
+                                  'type': mDeviceEvent.XBLUFI_TYPE.TYPE_INIT_ESP32_RESULT,
+                                  'result': false,
+                                  'data': res
+                                }
+                                mDeviceEvent.notifyDeviceMsgEvent(obj);
+                              }
+                            })
+                            //通知设备交互方式(是否加密) end
+                            wx.onBLECharacteristicValueChange(function (res) {
+                              let list2 = (util.ab2hex(res.value));
+                              // start
+                              let result = _self.data.result;
+                              if (list2.length < 4) {
+                                cosnole.log(407);
+                                return false;
+                              }
+                              var val = parseInt(list2[0], 16),
+                                type = val & 3,
+                                subType = val >> 2;
+                              var dataLength = parseInt(list2[3], 16);
+                              if (dataLength == 0) {
+                                return false;
+                              }
+                              var fragNum = util.hexToBinArray(list2[1]);
+                              list2 = isEncrypt(fragNum, list2, _self.data.md5Key);
+                              result = result.concat(list2);
+                              _self.data.result = result
+                              if (_self.data.flagEnd) {
+                                _self.data.flagEnd = false
+                                if (type == 1) {
+                                  let what = [];
+                                  console.log("recieve data subType: ", subType)
+                                  switch (subType) {
+                                    case 15:
+                                      if (result.length == 3) {
+                                        mDeviceEvent.notifyDeviceMsgEvent({
+                                          'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CONNECT_ROUTER_RESULT,
+                                          'result': false,
+                                          'data': {
+                                            'progress': 0,
+                                            'ssid': what.join('')
+                                          }
+                                        });
+                                      } else {
+                                        for (var i = 0; i <= result.length; i++) {
+                                          var num = parseInt(result[i], 16) + "";
+                                          if (i > 12) what.push(String.fromCharCode(parseInt(result[i], 16)));
+                                        }
+                                        mDeviceEvent.notifyDeviceMsgEvent({
+                                          'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CONNECT_ROUTER_RESULT,
+                                          'result': true,
+                                          'data': {
+                                            'progress': 100,
+                                            'ssid': what.join('')
+                                          }
+                                        });
+                                      }
+
+                                      break;
+                                    case 19: //自定义数据
+                                      let customData = [];
+                                      for (var i = 0; i <= result.length; i++) {
+                                        customData.push(String.fromCharCode(parseInt(result[i], 16)));
+                                      }
+                                      let obj = {
+                                        'type': mDeviceEvent.XBLUFI_TYPE.TYPE_RECIEVE_CUSTON_DATA,
+                                        'result': true,
+                                        'data': customData.join('')
+                                      }
+                                      mDeviceEvent.notifyDeviceMsgEvent(obj);
+
+                                      break;
+                                    case util.SUBTYPE_NEGOTIATION_NEG:
+                                      var arr = util.hexByInt(result.join(""));
+                                      var clientSecret = client.computeSecret(new Uint8Array(arr));
+                                      var md5Key = md5.array(clientSecret);
+                                      _self.data.md5Key = md5Key;
+                                      mDeviceEvent.notifyDeviceMsgEvent({
+                                        'type': mDeviceEvent.XBLUFI_TYPE.TYPE_INIT_ESP32_RESULT,
+                                        'result': true,
+                                        'data': {
+                                          deviceId,
+                                          serviceId,
+                                          characteristicId
+                                        }
+                                      });
+                                      break;
+
+                                    case 17:
+                                      getList(result, result.length, 0);
+                                      break;
+
+                                    default:
+                                      console.log(468);
+                                      //_self.setFailProcess(true, util.descFailList[4])
+                                      console.log("入网失败 468 :", util.failList[4]);
+                                      break;
+                                  }
+                                  _self.data.result = []
+                                } else {
+                                  //console.log(472);
+                                  console.log("入网失败 472:", util.failList[4]);
+                                }
+                              }
+                              // end
+
+                            })
+
+                          },
+                          fail: function (res) {
+                            let obj = {
+                              'type': mDeviceEvent.XBLUFI_TYPE.TYPE_INIT_ESP32_RESULT,
+                              'result': false,
+                              'data': res
+                            }
+                            mDeviceEvent.notifyDeviceMsgEvent(obj);
+                          }
+                        })
+                      }
+                    }
+                  }
+                },
+                fail: function (res) {
+                  let obj = {
+                    'type': mDeviceEvent.XBLUFI_TYPE.TYPE_INIT_ESP32_RESULT,
+                    'result': false,
+                    'data': res
+                  }
+                  mDeviceEvent.notifyDeviceMsgEvent(obj);
+                  console.log("fail getBLEDeviceCharacteristics:" + JSON.stringify(res))
+                }
+              })
+              break;
+            }
+          }
+        }
+      },
+      fail: function (res) {
+        let obj = {
+          'type': mDeviceEvent.XBLUFI_TYPE.TYPE_INIT_ESP32_RESULT,
+          'result': false,
+          'data': res
+        }
+        mDeviceEvent.notifyDeviceMsgEvent(obj);
+        console.log("fail getBLEDeviceServices:" + JSON.stringify(res))
+      }
+    })
+  })
+
+  mDeviceEvent.listenSendRouterSsidAndPassword(true, function (options) {
+    _self.data.password = options.password
+    _self.data.ssid = options.ssid
+    writeDeviceRouterInfoStart(_self.data.deviceId, _self.data.service_uuid, _self.data.characteristic_write_uuid, null);
+  })
+
+
+  mDeviceEvent.listenSendCustomData(true, function (options) {
+    _self.data.customData = options.customData
+    writeCutomsData(_self.data.deviceId, _self.data.service_uuid, _self.data.characteristic_write_uuid, null);
+  })
+
+  mDeviceEvent.listenSendGetNearRouterSsid(true, function (options) {
+    writeGetNearRouterSsid(_self.data.deviceId, _self.data.service_uuid, _self.data.characteristic_write_uuid, null);
+  })
+
+}
+
+function getList(arr, totalLength, curLength) {
+  // console.log(totalLength)
+  // console.log(arr)
+  var _self = this;
+  if (arr.length > 0) {
+    var len = parseInt(arr[0], 16);
+    curLength += (1 + len);
+    if (len > 0 && curLength < totalLength) {
+      var rssi = 0, name = "";
+      let list = []
+      for (var i = 1; i <= len; i++) {
+        if (i == 1) {
+          rssi = parseInt(arr[i], 16);
+        } else {
+          list.push(parseInt(arr[i], 16))
+        }
+      }
+      name = decodeURIComponent(escape(String.fromCharCode(...list)))
+      let obj = {
+        'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CONNECT_NEAR_ROUTER_LISTS,
+        'result': true,
+        'data': { "rssi": rssi, "SSID": name }
+      }
+      mDeviceEvent.notifyDeviceMsgEvent(obj);
+      arr = arr.splice(len + 1);
+      getList(arr, totalLength, curLength);
+    }
+  }
+}
+
+
+/****************************** 对外  ***************************************/
+module.exports = {
+  init: init,
+};

+ 226 - 0
utils/blufi/xBlufi.js

@@ -0,0 +1,226 @@
+var mOnFire = require("./other/onfire.js");
+var $wxBlufiImpl = require('./xBlufi-wx-impl.js');
+
+// 0表示阿里支付宝小程序 1表示微信小程序
+let XMQTT_SYSTEM = {
+  Alis: 0,
+  WeChat: 1,
+};
+
+
+let XBLUFI_TYPE = {
+  TYPE_STATUS_CONNECTED: '-2', /// 设备连接状态回调
+  TYPE_CLOSE_CONNECTED: '-1', ///主动关闭连接
+  TYPE_CONNECTED: '0',  //主动连接
+  TYPE_GET_DEVICE_LISTS: '1', //发现设备列表回调
+  TYPE_INIT_ESP32_RESULT: '2',
+  TYPE_RECIEVE_CUSTON_DATA: '3', //接收到自定义数据
+  TYPE_CONNECT_ROUTER_RESULT: '4',
+  TYPE_CONNECT_NEAR_ROUTER_LISTS: '5',
+
+
+  TYPE_GET_DEVICE_LISTS_START: ' 41', //发现设备列表回调开始
+  TYPE_GET_DEVICE_LISTS_STOP: '42', //停止发现设备列表回调
+
+};
+
+let OnFireEvent = {
+
+  EVENT_START_DISCONORY: '0', //蓝牙状态事件 发现设备
+  EVENT_CONNECT_DISCONNECT: '1', //通知连接或断开蓝牙
+  EVENT_NOFITY_INIT_ESP32: '3', //通知获取蓝牙设备的服务uuid列表等初始化工作
+
+
+
+  ENENT_ALL: '6',
+
+  EVENT_NOFITY_SEND_ROUTER_SSID_PASSWORD: '50', //通知发送路由器的ssid和password
+  EVENT_NOFITY_SEND_CUSTON_DATA: '51', //通知发送自定义数据
+  EVENT_NOFITY_SEND_GET_ROUTER_SSID:"52",//获取周围的SSID
+
+}
+
+/**
+ * 初始化
+ * @param type 参考 XMQTT_SYSTEM
+ */
+function initXBlufi(type) {
+  switch (type) {
+    case XMQTT_SYSTEM.Alis:
+      break;
+    case XMQTT_SYSTEM.WeChat:
+      $wxBlufiImpl.init();
+      break;
+  }
+}
+
+
+function notifyDeviceMsgEvent(options) {
+  mOnFire.fire(OnFireEvent.ENENT_ALL, options);
+}
+
+
+function listenDeviceMsgEvent(isSetListener, funtion) {
+  if (isSetListener) {
+    mOnFire.on(OnFireEvent.ENENT_ALL, funtion)
+  } else {
+    mOnFire.un(funtion)
+  }
+}
+
+/**
+ * 开始或停止发现附近的蓝牙设备
+ * @param options 连接参数 {"isStart":true , "filter":"名字过滤"} :是否开始发现设备
+ */
+function notifyStartDiscoverBle(options) {
+  mOnFire.fire(OnFireEvent.EVENT_START_DISCONORY, options);
+}
+
+/**
+ * 开始或停止发现附近的蓝牙设备
+ * @param options 连接参数 {"isStart":true} 是否开始发现设备
+ */
+function listenStartDiscoverBle(isSetListener, funtion) {
+  if (isSetListener) {
+    mOnFire.on(OnFireEvent.EVENT_START_DISCONORY, funtion)
+  } else {
+    mOnFire.un(funtion)
+  }
+}
+/**
+ * 连接或断开 蓝牙连接
+ *
+ * @param options 连接参数 {"connect":true,"deviceID":"设备id,蓝牙发现列表获取"}
+ */
+function notifyConnectBle(options) {
+  console.log('notifyConnectBle 蓝牙准备连接的deviceId --------------')
+  mOnFire.fire(OnFireEvent.EVENT_CONNECT_DISCONNECT, options);
+}
+/**
+ * 开始或停止连接的蓝牙设备
+ * @param options 连接参数 {"isStart":true} 是否开始发现设备
+ */
+function listenConnectBle(isSetListener, funtion) {
+  
+  if (isSetListener) {
+    mOnFire.on(OnFireEvent.EVENT_CONNECT_DISCONNECT, funtion)
+  } else {
+    mOnFire.un(funtion)
+  }
+}
+
+/**
+ * 通知初始化获取设备的服务列表等信息
+ * @param options 连接参数 {"deviceId":"设备的设备id"} 
+ */
+function notifyInitBleEsp32(options) {
+  mOnFire.fire(OnFireEvent.EVENT_NOFITY_INIT_ESP32, options);
+}
+/**
+ * 通知初始化获取设备的服务列表等信息
+ * @param options 连接参数 {"isStart":true} 是否开始发现设备
+ */
+function listenInitBleEsp32(isSetListener, funtion) {
+  if (isSetListener) {
+    mOnFire.on(OnFireEvent.EVENT_NOFITY_INIT_ESP32, funtion)
+  } else {
+    mOnFire.un(funtion)
+  }
+}
+
+/**
+ * 获取模组周围的SSID
+ * @param options NULL
+ */
+function notifySendGetNearRouterSsid() {
+  mOnFire.fire(OnFireEvent.EVENT_NOFITY_SEND_GET_ROUTER_SSID, null);
+}
+/**
+ * 获取模组周围的SSID
+ * @param options 连接参数 {"isStart":true} 是否开始发现设备
+ */
+function listenSendGetNearRouterSsid(isSetListener, funtion) {
+  if (isSetListener) {
+    mOnFire.on(OnFireEvent.EVENT_NOFITY_SEND_GET_ROUTER_SSID, funtion)
+  } else {
+    mOnFire.un(funtion)
+  }
+}
+
+
+/**
+ * 发送要连接的路由器的ssid和密码
+ * @param options 连接参数 {"deviceId":"设备的设备id","serverId":"服务id","characterId":"通道","ssid":"路由器名字","password":"密码"}
+ */
+function notifySendRouterSsidAndPassword(options) {
+  mOnFire.fire(OnFireEvent.EVENT_NOFITY_SEND_ROUTER_SSID_PASSWORD, options);
+}
+/**
+ * 发送要连接的路由器的ssid和密码
+ * @param options 连接参数 {"isStart":true} 是否开始发现设备
+ */
+function listenSendRouterSsidAndPassword(isSetListener, funtion) {
+  if (isSetListener) {
+    mOnFire.on(OnFireEvent.EVENT_NOFITY_SEND_ROUTER_SSID_PASSWORD, funtion)
+  } else {
+    mOnFire.un(funtion)
+  }
+}
+
+
+/**
+ * 发送自定义数据
+ * @param options 连接参数 {"deviceId":"设备的设备id","serverId":"服务id","characterId":"通道","customData":"自定义数据""}
+ */
+function notifySendCustomData(options) {
+  mOnFire.fire(OnFireEvent.EVENT_NOFITY_SEND_CUSTON_DATA, options);
+}
+
+/**
+ * 发送自定义数据
+ * @param options 连接参数 {"deviceId":"设备的设备id","serverId":"服务id","characterId":"通道","customData":"自定义数据""}
+ */
+function listenSendCustomData(isSetListener, funtion) {
+  if (isSetListener) {
+    mOnFire.on(OnFireEvent.EVENT_NOFITY_SEND_CUSTON_DATA, funtion)
+  } else {
+    mOnFire.un(funtion)
+  }
+}
+
+
+
+/****************************** 对外  ***************************************/
+
+module.exports = {
+
+  XMQTT_SYSTEM,
+  XBLUFI_TYPE,
+  OnFireEvent,
+
+  notifyDeviceMsgEvent,
+  listenDeviceMsgEvent,
+
+  notifyStartDiscoverBle,
+  listenStartDiscoverBle,
+
+  notifyConnectBle,
+  listenConnectBle,
+
+  notifyInitBleEsp32,
+  listenInitBleEsp32,
+
+  notifySendRouterSsidAndPassword,
+  listenSendRouterSsidAndPassword,
+
+  notifySendCustomData,
+  listenSendCustomData,
+
+
+  notifySendGetNearRouterSsid,
+  listenSendGetNearRouterSsid,
+
+
+  initXBlufi,
+
+};