code: 测试配网程序

This commit is contained in:
DuRuofu
2025-02-22 12:30:31 +08:00
parent b1ff060c68
commit 3201632dff
83 changed files with 10843 additions and 0 deletions
@@ -0,0 +1,2 @@
node_modules/
miniprogram_npm/
@@ -0,0 +1,5 @@
# ESP Config WeChat
A WeChat application for provisioning ESP smart devices.
## Implemented modules
[BluFi](https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/blufi)
@@ -0,0 +1,22 @@
//app.js
App({
data: {
service_uuid: "0000FFFF-0000-1000-8000-00805F9B34FB",
characteristic_write_uuid: "0000FF01-0000-1000-8000-00805F9B34FB",
characteristic_read_uuid: "0000FF02-0000-1000-8000-00805F9B34FB",
name: "BLUFI",
mtu: 19,
constMtu: 128,
md5Key: "",
platform: '',
sequenceControl: -1,
sequenceNumber: -1
},
onLaunch: function () {
},
globalData: {
userInfo: null
}
})
@@ -0,0 +1,15 @@
{
"pages": [
"pages/index/index",
"pages/blueDevices/blueDevices",
"pages/blueWifi/blueWifi",
"pages/blueConnect/blueConnect"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#4d9efb",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle": "white"
},
"sitemapLocation": "sitemap.json"
}
@@ -0,0 +1,119 @@
/**app.wxss**/
.container {
height: 100%;
display: flex;
padding: 0 10px;
flex-direction: column;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
}
.item {
display: flex;
height: 130rpx;
width: 100%;
align-items: center;
border-bottom: 1px solid #eee;
}
.item-img {
flex: 0 0 100rpx;
height: 100rpx;
display: flex;
justify-content: center;
align-items: center;
border-radius: 100%;
}
.bluetooth-img {
height: 80rpx;
width: 80rpx;
}
.item-name {
flex: 1;
padding-left: 10px;
display: flex;
flex-direction: column;
font-size: 32rpx;
}
.text-rssi {
font-size: 28rpx;
color: #999;
}
.btn {
width: 100%;
height: 90rpx;
line-height: 90rpx;
background: #4d9efb;
border: none;
margin-bottom: 30rpx;
font-size: 14px;
color: #fff;
}
.font14 {
font-size: 14px;
}
.font16 {
font-size: 16px;
}
.textcenter {
text-align: center;
}
.width100 {
width: 100%;
}
.margintop20 {
margin-top: 20px;
}
.margintop10 {
margin-top: 10px;
}
.modal-mask{
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0,0,0,.7);
overflow: hidden;
color: #ffffff;
z-index:900;
}
.modal-dialog{
background-color: #f9f9f9;
/*background: rgba(0,0,0,.7);*/
opacity: 0.95;
position: fixed;
z-index: 999;
top: 20%;
left: 10%;
overflow: hidden;
width: 80%;
color: #000;
border-radius: 26rpx;
}
.modal-dialog input{
margin: 15px 0;
padding: 0 20px;
font-size: 32rpx;
}
.modal-btn-wrapper{
display: flex;
flex-direction: row;
height: 100rpx;
line-height:90rpx;
border-top: 2rpx solid rgba(7,17,27,0.1);
}
.cancel-btn, .confirm-btn{
flex: 1;
height: 100rpx;
line-height: 100rpx;
text-align: center;
font-size: 32rpx;
}
.cancel-btn{
border-right: 2rpx solid rgba(7,17,27,0.1);
}
.modal-title{
text-align: center;
padding-top: 10px;
}
File diff suppressed because it is too large Load Diff
@@ -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
@@ -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('')
}
File diff suppressed because it is too large Load Diff
@@ -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) {
}
}
File diff suppressed because it is too large Load Diff
@@ -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);
}
}
@@ -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;
}
}
}
@@ -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
}
@@ -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;
};
@@ -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
}
@@ -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)
}
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

@@ -0,0 +1,28 @@
{
"name": "ESP-Config-WeChat",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "ESP-Config-WeChat",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"crypto-js": "^4.0.0"
}
},
"node_modules/crypto-js": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
}
},
"dependencies": {
"crypto-js": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
}
}
}
@@ -0,0 +1,23 @@
{
"name": "ESP-Config-WeChat",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/EspressifApps/ESP-Config-WeChat.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/EspressifApps/ESP-Config-WeChat/issues"
},
"homepage": "https://github.com/EspressifApps/ESP-Config-WeChat#readme",
"dependencies": {
"crypto-js": "^4.0.0"
}
}
@@ -0,0 +1,29 @@
<!--pages/blueConnect/blueConnect.wxml-->
<view class="container">
<block wx:if="{{!failure}}">
<view class="schedule">
<view class="schedule-result schedule-success">
<image class='schedule-img' mode='aspectFit' src='../../images/round.gif'></image>
<view class="desc-wrapper">
<view class="text-value"><text>{{value}}</text><text class="text-samll">%</text></view>
<view class="text-desc">{{desc}}</view>
</view>
</view>
</view>
</block>
<block wx:else>
<view class="schedule fail">
<view class="schedule-result schedule-fail">
<image class='schedule-img' mode='aspectFit' src='../../images/failure.png'></image>
<view class="desc-wrapper">
<view class="text-sigh"><text>!</text></view>
<view class="text-desc">{{desc}}</view>
</view>
</view>
</view>
</block>
<view class="process-wrapper">
<text class="text-process" wx:for="{{processList}}" wx:key="*this">{{item}}</text>
<text>{{vConsoleV}}</text>
</view>
</view>
@@ -0,0 +1,68 @@
/* pages/blueConnect/blueConnect.wxss */
.container {
padding: 0;
}
.schedule {
background: #4d9efb;
height: 46vh;
width: 100%;
padding: 50rpx;
}
.schedule-result {
position: relative;
display: flex;
justify-content: center;
align-items: center;
border-radius: 100%;
background: transparent;
height: 55vw;
width: 55vw;
margin: 0 auto;
color: #fff;
}
.schedule-img {
height: 55vw;
width: 55vw;
}
.fail{
background: #737d89;
}
.desc-wrapper {
position: absolute;
}
.text-value {
text-align: center;
font-size: 20px;
}
.text-desc {
font-size: 14px;
}
.text-samll {
font-size: 16px;
}
.text-sigh {
height: 80rpx;
width: 80rpx;
background: #fff;
border-radius: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
font-weight: bold;
color: #737d89;
margin: 0 auto 10px;
}
.process-wrapper {
display: flex;
flex-direction: column;
width: 100%;
text-align: left;
margin-top: 20px;
padding-left: 30px;
font-size: 14px;
color: #999;
}
.text-process {
margin: 3px 0;
}
@@ -0,0 +1,105 @@
//获取应用实例
const app = getApp();
const util = require('../../utils/util.js');
Page({
data: {
deviceList: [],
deviceId: "",
},
bindViewConnect: function (event) {
var self = this,
deviceId = event.currentTarget.dataset.value;
self.setData({
deviceId: deviceId
});
wx.navigateTo({
url: '/pages/blueWifi/blueWifi?deviceId=' + deviceId,
})
},
getBluDevice: function () {
var self = this;
wx.getBluetoothDevices({
success: function (res) {
var list = util.filterDevice(res.devices, "name");
if (list.length > 0) {
wx.hideLoading();
}
self.setData({
deviceList: list
})
}
})
wx.onBluetoothDeviceFound(function (res) {
console.log(res.devices[0].name);
var list = util.filterDevice(res.devices, "name");
if (list.length > 0) {
wx.hideLoading();
}
self.setData({
deviceList: self.data.deviceList.concat(list)
})
})
},
onLoad: function () {
var self = this;
wx.setNavigationBarTitle({
title: 'BluFi扫描'
});
wx.showLoading({
title: '设备扫描中...',
})
self.getBluDevice();
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
var self = this,
deviceId = self.data.deviceId;
if (!util._isEmpty(deviceId)) {
wx.closeBLEConnection({
deviceId: deviceId,
})
}
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
})
@@ -0,0 +1,13 @@
<!--index.wxml-->
<view class="container">
<view data-value="{{item.deviceId}}" bindtap="bindViewConnect" wx:for="{{deviceList}}" class="item" wx:key="*this">
<view class="item-img">
<image class='bluetooth-img' mode='aspectFit' src='../../images/bluetooth.png'></image>
</view>
<view class="item-name">
<text class="text-name">{{item.name}}</text>
<text class="text-rssi">Rssi: {{item.RSSI}}</text>
<text class="text-rssi">deviceId: {{item.deviceId}}</text>
</view>
</view>
</view>
@@ -0,0 +1,11 @@
/* pages/blueDevices/blueDevices.wxss */
.prompt-title {
height: 50rpx;
border-top: 1px solid #999;
border-bottom: 1px solid #999;
width: 100%;
}
.item {
height: auto;
padding: 8rpx 0;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,4 @@
{
"backgroundTextStyle": "dark",
"enablePullDownRefresh": true
}
@@ -0,0 +1,19 @@
<view class="container">
<view data-bssid="" data-ssid="{{item.SSID}}" bindtap="bindViewWifi" wx:for="{{wifiList}}" class="item" wx:key="*this">
<view class="item-name">
<text class="text-name">{{item.SSID}}</text>
</view>
<view class="item-icon">
<image class='wifi-img' mode='aspectFit' src='../../images/wifi.png'></image>
</view>
</view>
<view class='modal-mask' hidden="{{hiddenModal}}"></view>
<view class='modal-dialog' hidden="{{hiddenModal}}">
<view class='modal-title'>{{ssid}}</view>
<input type='text' password='true' bindinput='bindViewInput' placeholder="请输入密码"/>
<view class='modal-btn-wrapper'>
<view class='cancel-btn' style='color:rgba(7,17,27,0.6)' bindtap='bindViewCancel'>取消</view>
<view class='confirm-btn' style='color:#4d9efb' bindtap='bindViewConfirm'>开始配网</view>
</view>
</view>
</view>
@@ -0,0 +1,12 @@
/* pages/blueWifi/blueWifi.wxss */
.item-icon {
flex: 0 0 80rpx;
height: 100%;
display: flex;
justify-items: center;
align-items: center;
}
.wifi-img {
width: 60rpx;
height: 60rpx;
}
@@ -0,0 +1,57 @@
//index.js
//获取应用实例
const app = getApp();
const util = require('../../utils/util.js');
Page({
data: {
},
//事件处理函数
bindViewBlue: function() {
wx.closeBluetoothAdapter({
success: function () {
}
});
wx.openBluetoothAdapter({
success: function (res) {
wx.startBluetoothDevicesDiscovery({
success: function (res) {
wx.navigateTo({
url: '/pages/blueDevices/blueDevices',
})
}
})
},
fail: function (res) {
wx.showToast({
title: '请打开蓝牙',
icon: 'none',
duration: 2000
})
}
})
},
bindViewWifi: function () {
wx.navigateTo({
url: '/pages/wifiDevices/wifiDevices',
})
},
onLoad: function () {
wx.setNavigationBarTitle({
title: '配网方式'
})
wx.getSystemInfo({
success (res) {
try {
app.data.platform = res.platform.toLocaleLowerCase()
} catch(e) {
console.log(e)
}
}
})
},
getUserInfo: function(e) {
}
})
@@ -0,0 +1,19 @@
<!--index.wxml-->
<view class="container">
<view class='header-wrapper'>
<image class="header-image" src="../../images/network.png"></image>
</view>
<view class='content-wrapper'>
<view class="title">配网方式</view>
<view class="btn-info">
<view bindtap="bindViewBlue" class="select-way">
<image class="btn-image" src="../../images/bluetooth-way.png"></image>
<text class="name">BluFi 配网</text>
</view>
<!-- <view bindtap="bindViewWifi" class="select-way">
<image class="btn-image" src="../../images/wifi-way.png"></image>
<text class="name">WiFi配网</text>
</view> -->
</view>
</view>
</view>
@@ -0,0 +1,60 @@
.container {
display: block;
padding: 0;
height: 100vh;
background: #eee;
}
.header-wrapper {
display: flex;
justify-content: center;
align-items: center;
height: 45vh;
width: 100%;
background: #4d9efb;
border-bottom-right-radius: 40px;
border-bottom-left-radius: 40px;
}
.header-image {
width: 29vh;
height: 29vh;
position: relative;
top: -5vh;
}
.content-wrapper {
position: absolute;
top: 38vh;
left: 15px;
height: 50vh;
width: calc(100% - 30px);
padding: 20px;
box-sizing: border-box;
background: #fff;
border-radius: 10px;
box-shadow: 0px 0px 3px #fff;
color: #818181;
}
.title {
margin: 10px 0;
text-align: center;
font-size: 16px;
}
.btn-info {
display: flex;
margin-top: 10vh;
}
.btn-image {
width: 50px;
height: 50px;
}
.select-way {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.name {
margin: 10px 0;
font-size: 14px;
}
@@ -0,0 +1,72 @@
// pages/wifiConfig/wifiConfig.js
Page({
/**
* 页面的初始数据
*/
data: {
},
next: function () {
wx.navigateTo({
url: "/pages/wifiList/wifiList"
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.setNavigationBarTitle({
title: 'WiFi配网'
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
@@ -0,0 +1,20 @@
<!--pages/wifi3/wifi3.wxml-->
<view class='container'>
<view class='textcenter'>
<view><text class='font14'>第二步</text></view>
<view class="margintop10"><text class='font16'>将手机连接设备,请前往手机设置,进入无线局域网</text></view>
</view>
<!-- wifi -->
<view>
<image class="wifi-img" src="../../images/wifi.jpg"></image>
</view>
<view class="width100 margintop20">
<button class="btn" bindtap='setWifi'>去设置 </button>
</view>
<view class="width100" bindtap='next'>
<button class="btn" > 下一步 </button>
</view>
</view>
@@ -0,0 +1,9 @@
/* pages/wifiConfig/wifiConfig.wxss */
.container{
padding-top: 50rpx;
}
.wifi-img {
width:300px;
height:234px;
margin-top:20px;
}
@@ -0,0 +1,166 @@
// pages/wifiConnect/wifiConnect.js
Page({
/**
* 页面的初始数据
*/
data: {
failStatus: false,
sucStatus: false,
progress: 0,
},
getStatus: function() {
var self = this;
wx.request({
url: 'https://www.alavening.com/wifi/connstatus.cgi',
data: {
},
header: {
'content-type': 'application/json' // 默认值
},
success: function (res) {
console.log(res.data);
var data = res.data;
console.log(data.status);
if (data.status == "success") {
self.setData({
progress: 100,
failStatus: false,
sucStatus: true,
})
self.setResult("success");
} else if (data.status == "fail") {
self.setData({
failStatus: true,
sucStatus: false,
})
self.setResult("fail");
} else {
if (self.data.progress <= 90) {
self.setData({
progress: (self.data.progress + 5),
failStatus: false,
sucStatus: false,
})
}
self.getStatus();
}
},
fail: function (res) {
self.setData({
failStatus: true,
sucStatus: false,
})
}
})
},
setResult: function(result) {
var self = this;
wx.request({
url: 'https://www.alavening.com/wifi/configsuccess.cgi',
method: "post",
data: {
configstatus: result
},
header: {
'content-type': 'application/x-www-form-urlencoded'
},
success: function (res) {
},
fail: function () {
}
})
},
setConnect: function(ssid, password) {
var self = this;
wx.request({
url: 'https://alavening.com/wifi/connect.cgi',
method: "post",
data: {
essid: ssid,
password: password
},
header: {
'content-type': 'application/x-www-form-urlencoded'
},
success: function (res) {
},
fail: function () {
}
})
self.getStatus();
},
successwifi: function() {
wx.reLaunch({
url: '/pages/index/index'
})
},
failwifi: function() {
wx.navigateBack({
delta: 2
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var self = this;
wx.setNavigationBarTitle({
title: 'WiFi配网'
});
self.setConnect(options.ssid, options.password);
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
@@ -0,0 +1,13 @@
<!--pages/wifi4/wifi4.wxml-->
<view class='container'>
<view class='textcenter'>
<view><text class='font16'>配网中...</text></view>
</view>
<view class="progress-wrapper">
<progress percent="{{progress}}" stroke-width="12" activeColor="#4d9efb"/>
</view>
<view class='width100 margintop20'>
<button hidden='{{failStatus || !sucStatus}}' class="btn" bindtap='successwifi'>配网成功 </button>
<button hidden='{{!failStatus || sucStatus}}' class="btn" bindtap='failwifi'>配网失败 </button>
</view>
</view>
@@ -0,0 +1,13 @@
/* pages/wifiConnect/wifiConnect.wxss */
.container {
padding-top: 50rpx;
}
.progress-wrapper {
width: 100%;
height: 40px;
display: flex;
align-items: center;
}
progress {
flex: 1;
}
@@ -0,0 +1,67 @@
// pages/wifiDevices/wifiDevices.js
Page({
/**
* 页面的初始数据
*/
data: {
},
next: function () {
wx.navigateTo({
url: "/pages/wifiConfig/wifiConfig"
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.setNavigationBarTitle({
title: 'WiFi配网'
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
})
@@ -0,0 +1,23 @@
<!--pages/wifi/wifi.wxml-->
<view class='container'>
<view class='textcenter'>
<view><text class='font14'>第一步</text></view>
<view class="margintop10"><text class='font16'>双击设备按键</text></view>
</view>
<!-- 图片 -->
<view>
<image></image>
</view>
<view class='textcenter font14'>
<checkbox-group>
<label class="checkbox">
<checkbox color="#4d9efb" value=""/>我已双击设备按钮
</label>
</checkbox-group>
</view>
<view class='width100 margintop20' bindtap='next'>
<button class="btn" >下一步</button>
</view>
<!-- <button class='font14 back' >返回上一步</button> -->
</view>
@@ -0,0 +1,20 @@
/* pages/wifi/wifi.wxss */
.container {
padding-top: 50rpx;
}
.checkbox{
color: #333
}
.back{
width: 40%;
margin: 0 auto
}
.colored{
color: red;
}
.hide{
display: none;
}
.show{
display: block;
}
@@ -0,0 +1,142 @@
// pages/wifiList/wifiList.js
Page({
/**
* 页面的初始数据
*/
data: {
password: '',
hiddenmodal: true,//可以通过hidden是否掩藏弹出框的属性,来指定那个弹出框
wifiList: [],
ssid: '',
},
//点击按钮弹出指定的hiddenmodalput弹出框
bindViewWifi: function (e) {
var list = this.data.wifiList;
var index = e.currentTarget.dataset.index;
//console.log(list[index])
this.setData({
ssid: list[index].essid,
hiddenmodal: !this.data.hiddenmodal,
})
},
bindViewInput: function (e) {
this.setData({ password: e.detail.value })
},
getWifiList: function() {
var self = this;
wx.request({
url: 'https://www.alavening.com/wifi/wifiscan.cgi',
data: {
},
header: {
'content-type': 'application/json' // 默认值
},
success: function (res) {
console.log(res);
var data = res.data.result;
console.log(data);
if (data.inProgress == "0") {
wx.hideLoading();
self.setData({
wifiList: data.APs
})
} else {
self.getWifiList();
}
},
fail: function(res) {
console.log(res);
wx.hideLoading();
}
})
},
//取消按钮
cancel: function () {
this.setData({
hiddenmodal: true
});
},
//确认
confirm: function () {
var self = this;
// this.setData({
// hiddenmodal: true
// })
if (!self.data.password.length < 8) {
// 这里修改成跳转的页面
wx.redirectTo({
url: '/pages/wifiConnect/wifiConnect?password=' + self.data.password + "&ssid=" + self.data.ssid
})
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var self = this;
wx.setNavigationBarTitle({
title: 'WiFi配网'
});
setTimeout(function() {
wx.showLoading({
title: 'WiFi加载中...',
});
self.getWifiList();
console.log("WiFi加载中...");
}, 500);
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
@@ -0,0 +1,35 @@
<!--pages/wifi2/wifi2.wxml-->
<view class='container'>
<view class='textcenter'>
<view><text class='font14'>第三步</text></view>
<view class="margintop10"><text class='font16'>请选择您的WiFi</text></view>
</view>
<!-- wifi -->
<view class="width100 margintop20">
<view data-index="{{index}}" bindtap="bindViewWifi" wx:for="{{wifiList}}" class="item" wx:key="*this">
<view class="item-name">
<text class="text-name">{{item.essid}}</text>
</view>
<view class="item-icon">
<image class='wifi-img' mode='aspectFit' src='../../images/wifi.png'></image>
</view>
</view>
</view>
<view class='modal-mask' hidden="{{hiddenmodal}}"></view>
<!-- 弹窗 -->
<view class='modal-dialog' hidden="{{hiddenmodal}}" data-index="{{index}}">
<view class='modal-title'>{{ssid}}</view>
<input type='text' password='true' bindinput='bindViewInput' placeholder="请输入密码"/>
<view class='modal-btn-wrapper'>
<view class='cancel-btn' style='color:rgba(7,17,27,0.6)' bindtap='cancel'>取消</view>
<view class='confirm-btn' style='color:#4d9efb' bindtap='confirm'>确定</view>
</view>
</view>
</view>
@@ -0,0 +1,35 @@
.container{
position: relative;
padding-top: 50rpx;
}
.weui-cell__bd{
padding: 0 20px;
}
.wifi-list{
margin-top: 30px;
}
.main-content{
flex: 1;
height: 100%;
overflow-y: hidden;
}
.item-wifi{
border-bottom:2rpx solid #eee;
height:100rpx;
line-height:100rpx;
margin-top:0;
padding: 0 20px;
}
.item-icon {
flex: 0 0 80rpx;
height: 100%;
display: flex;
justify-items: center;
align-items: center;
}
.wifi-img {
width: 60rpx;
height: 60rpx;
}
@@ -0,0 +1,54 @@
{
"description": "项目配置文件",
"packOptions": {
"ignore": [],
"include": []
},
"setting": {
"urlCheck": true,
"es6": true,
"enhance": false,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": true,
"coverView": true,
"nodeModules": true,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": false,
"useMultiFrameRuntime": false,
"useApiHook": false,
"useApiHostProcess": false,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"useIsolateContext": false,
"userConfirmedBundleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true,
"disableUseStrict": false,
"minifyWXML": true,
"showES6CompileOption": false,
"useCompilerPlugins": false
},
"compileType": "miniprogram",
"libVersion": "2.3.0",
"appid": "wx3ff81ef68814b084",
"projectname": "ESPConfig",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
}
}
@@ -0,0 +1,7 @@
{
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "ESPConfig",
"setting": {
"compileHotReLoad": true
}
}
@@ -0,0 +1,7 @@
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{
"action": "allow",
"page": "*"
}]
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,6 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(blufi_demo)
@@ -0,0 +1,84 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
# ESP-IDF Blufi Example
This demo shows how to use the *Blufi* to configurate the Wi-Fi connection to AP.
The BluFi for ESP32 is a Wi-Fi network configuration function via Bluetooth channel. It provides a secure protocol to pass Wi-Fi configuration and credentials to the ESP32.
## How to Use Example
Before project configuration and build, be sure to set the correct chip target using:
```bash
idf.py set-target <chip_name>
```
To test this demo, you need to prepare a mobile phone with blufi application installed. You can download the blufi application from [Android version](https://github.com/EspressifApp/EspBlufi) and [iOS version](https://itunes.apple.com/cn/app/espblufi/id1450614082?mt=8).
Blufi is completely open source, here is the download link:
* [Blufi source code](https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/blufi)
* [BluFi protocol](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/ble/blufi.html)
* [iOS source code](https://github.com/EspressifApp/EspBlufiForiOS)
* [Android source code](https://github.com/EspressifApp/EspBlufi)
* [Bluetooth Network User Guide CN](https://www.espressif.com/sites/default/files/documentation/esp32_bluetooth_networking_user_guide_cn.pdf)
### Hardware Required
* A development board with ESP32/ESP32-C3/ESP32-S3/ESP32-C2 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.)
* A USB cable for Power supply and programming
See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it.
### Build and Flash
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects.
## Example Output
```
I (0) cpu_start: Starting scheduler on APP CPU.
I (708) wifi:wifi driver task: 3ffbb118, prio:23, stack:6656, core=0
I (708) system_api: Base MAC address is not set
I (708) system_api: read default base MAC address from EFUSE
I (718) wifi:wifi firmware version: 44799ff
I (718) wifi:wifi certification version: v7.0
I (718) wifi:config NVS flash: enabled
I (718) wifi:config nano formatting: disabled
I (728) wifi:Init data frame dynamic rx buffer num: 32
I (728) wifi:Init management frame dynamic rx buffer num: 32
I (738) wifi:Init management short buffer num: 32
I (738) wifi:Init dynamic tx buffer num: 32
I (748) wifi:Init static rx buffer size: 1600
I (748) wifi:Init static rx buffer num: 10
I (748) wifi:Init dynamic rx buffer num: 32
I (758) wifi_init: rx ba win: 6
I (758) wifi_init: tcpip mbox: 32
I (768) wifi_init: udp mbox: 6
I (768) wifi_init: tcp mbox: 6
I (768) wifi_init: tcp tx win: 5744
I (778) wifi_init: tcp rx win: 5744
I (778) wifi_init: tcp mss: 1440
I (788) wifi_init: WiFi IRAM OP enabled
I (788) wifi_init: WiFi RX IRAM OP enabled
I (798) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07
I (908) wifi:mode : sta (fc:f5:c4:3c:62:90)
I (908) wifi:enable tsf
I (908) BTDM_INIT: BT controller compile version [1342a48]
I (1198) BLUFI_EXAMPLE: BD ADDR: fc:f5:c4:3c:62:92
I (1198) BLUFI_EXAMPLE: BLUFI VERSION 0102
I (1198) BLUFI_EXAMPLE: BLUFI init finish
```
## Troubleshooting
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
@@ -0,0 +1,4 @@
idf_component_register(SRCS "blufi_example_main.c"
"blufi_security.c"
"blufi_init.c"
INCLUDE_DIRS ".")
@@ -0,0 +1,10 @@
menu "Example Configuration"
config EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY
int "WiFi connection maximum retry"
range 0 255
default 2
help
WiFi connection maximum retry, from 0 to 255.
endmenu
@@ -0,0 +1,26 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#pragma once
#define BLUFI_EXAMPLE_TAG "BLUFI_EXAMPLE"
#define BLUFI_INFO(fmt, ...) ESP_LOGI(BLUFI_EXAMPLE_TAG, fmt, ##__VA_ARGS__)
#define BLUFI_ERROR(fmt, ...) ESP_LOGE(BLUFI_EXAMPLE_TAG, fmt, ##__VA_ARGS__)
void blufi_dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free);
int blufi_aes_encrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
int blufi_aes_decrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
uint16_t blufi_crc_checksum(uint8_t iv8, uint8_t *data, int len);
int blufi_security_init(void);
void blufi_security_deinit(void);
int esp_blufi_gap_register_callback(void);
esp_err_t esp_blufi_host_init(void);
esp_err_t esp_blufi_host_and_cb_init(esp_blufi_callbacks_t *callbacks);
esp_err_t esp_blufi_host_deinit(void);
esp_err_t esp_blufi_controller_init(void);
esp_err_t esp_blufi_controller_deinit(void);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
# Override some defaults so BT stack is enabled
# in this example
#
# Partition Table
# (It's possible to fit Blufi in 1MB app partition size with some other optimizations, but
# default config is close to 1MB.)
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y
#
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BT_GATTC_ENABLE=n
CONFIG_BT_BLE_SMP_ENABLE=n
CONFIG_BT_BLE_BLUFI_ENABLE=y
CONFIG_MBEDTLS_HARDWARE_MPI=n
CONFIG_MBEDTLS_DHM_C=y
@@ -0,0 +1,7 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
CONFIG_IDF_TARGET="esp32"
CONFIG_BT_ENABLED=y
# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
@@ -0,0 +1,18 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_BLUFI_ENABLE=y
# CONFIG_BT_GATTC_ENABLE is not set
# CONFIG_BT_BLE_SMP_ENABLE is not set
# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
CONFIG_MBEDTLS_DHM_C=y
# The config items for NIMBLE HOST
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_ROLE_CENTRAL=n
CONFIG_BT_NIMBLE_ROLE_OBSERVER=n
CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=n
CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=n
@@ -0,0 +1,7 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
CONFIG_IDF_TARGET="esp32c3"
CONFIG_BT_ENABLED=y
# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
@@ -0,0 +1,18 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_BLUFI_ENABLE=y
# CONFIG_BT_GATTC_ENABLE is not set
# CONFIG_BT_BLE_SMP_ENABLE is not set
# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
CONFIG_MBEDTLS_DHM_C=y
# The config items for NIMBLE HOST
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_ROLE_CENTRAL=n
CONFIG_BT_NIMBLE_ROLE_OBSERVER=n
CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=n
CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=n
@@ -0,0 +1,7 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
CONFIG_IDF_TARGET="esp32s3"
CONFIG_BT_ENABLED=y
# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
@@ -0,0 +1,6 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(smart_config)
@@ -0,0 +1,66 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# smartconfig Example
This example shows how ESP32 connects to a target AP with ESPTOUCH.
## How to use example
### Hardware Required
Download ESPTOUCH APP from app store:
[Android source code](https://github.com/EspressifApp/EsptouchForAndroid)
[iOS source code](https://github.com/EspressifApp/EsptouchForIOS) is available.
### Configure the project
```
idf.py menuconfig
```
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example output
* Make sure your phone connect to the target AP (2.4GHz).
* Open ESPTOUCH app and input password. There will be success message after few sec.
Here is an example of smartconfig console output.
```
I (372) wifi: mode : sta (24:0a:c4:00:44:86)
I (422) smartconfig: SC version: V2.6.6
I (3802) wifi: ic_enable_sniffer
I (3802) sc: SC_STATUS_FIND_CHANNEL
I (234592) smartconfig: TYPE: ESPTOUCH
I (234592) smartconfig: T|PHONE MAC:68:3e:34:88:59:bf
I (234592) smartconfig: T|AP MAC:a4:56:02:47:30:07
I (234592) sc: SC_STATUS_GETTING_SSID_PSWD
I (239922) smartconfig: T|pswd: 123456789
I (239922) smartconfig: T|ssid: IOT_DEMO_TEST
I (239922) smartconfig: T|bssid: a4:56:02:47:30:07
I (239922) wifi: ic_disable_sniffer
I (239922) sc: SC_STATUS_LINK
I (239932) sc: SSID:IOT_DEMO_TEST
I (239932) sc: PASSWORD:123456789
I (240062) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (241042) wifi: state: init -> auth (b0)
I (241042) wifi: state: auth -> assoc (0)
I (241052) wifi: state: assoc -> run (10)
I (241102) wifi: connected with IOT_DEMO_TEST, channel 1
I (244892) event: ip: 192.168.0.152, mask: 255.255.255.0, gw: 192.168.0.1
I (244892) sc: WiFi Connected to ap
I (247952) sc: SC_STATUS_LINK_OVER
I (247952) sc: Phone ip: 192.168.0.31
I (247952) sc: smartconfig over
```
@@ -0,0 +1,2 @@
idf_component_register(SRCS "smartconfig_main.c"
INCLUDE_DIRS ".")
@@ -0,0 +1,7 @@
menu "Example Configuration"
config SET_MAC_ADDRESS_OF_TARGET_AP
bool "whether set MAC address of target AP or not"
default y
endmenu
@@ -0,0 +1,135 @@
/* Esptouch example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_eap_client.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "esp_smartconfig.h"
#include "esp_mac.h"
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t s_wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
static const int CONNECTED_BIT = BIT0;
static const int ESPTOUCH_DONE_BIT = BIT1;
static const char *TAG = "smartconfig_example";
static void smartconfig_example_task(void * parm);
static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
xTaskCreate(smartconfig_example_task, "smartconfig_example_task", 4096, NULL, 3, NULL);
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
esp_wifi_connect();
xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT);
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE) {
ESP_LOGI(TAG, "Scan done");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL) {
ESP_LOGI(TAG, "Found channel");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD) {
ESP_LOGI(TAG, "Got SSID and password");
smartconfig_event_got_ssid_pswd_t *evt = (smartconfig_event_got_ssid_pswd_t *)event_data;
wifi_config_t wifi_config;
uint8_t ssid[33] = { 0 };
uint8_t password[65] = { 0 };
uint8_t rvd_data[33] = { 0 };
bzero(&wifi_config, sizeof(wifi_config_t));
memcpy(wifi_config.sta.ssid, evt->ssid, sizeof(wifi_config.sta.ssid));
memcpy(wifi_config.sta.password, evt->password, sizeof(wifi_config.sta.password));
#ifdef CONFIG_SET_MAC_ADDRESS_OF_TARGET_AP
wifi_config.sta.bssid_set = evt->bssid_set;
if (wifi_config.sta.bssid_set == true) {
ESP_LOGI(TAG, "Set MAC address of target AP: "MACSTR" ", MAC2STR(evt->bssid));
memcpy(wifi_config.sta.bssid, evt->bssid, sizeof(wifi_config.sta.bssid));
}
#endif
memcpy(ssid, evt->ssid, sizeof(evt->ssid));
memcpy(password, evt->password, sizeof(evt->password));
ESP_LOGI(TAG, "SSID:%s", ssid);
ESP_LOGI(TAG, "PASSWORD:%s", password);
if (evt->type == SC_TYPE_ESPTOUCH_V2) {
ESP_ERROR_CHECK( esp_smartconfig_get_rvd_data(rvd_data, sizeof(rvd_data)) );
ESP_LOGI(TAG, "RVD_DATA:");
for (int i=0; i<33; i++) {
printf("%02x ", rvd_data[i]);
}
printf("\n");
}
ESP_ERROR_CHECK( esp_wifi_disconnect() );
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
esp_wifi_connect();
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE) {
xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);
}
}
static void initialise_wifi(void)
{
ESP_ERROR_CHECK(esp_netif_init());
s_wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL) );
ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) );
ESP_ERROR_CHECK( esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_start() );
}
static void smartconfig_example_task(void * parm)
{
EventBits_t uxBits;
ESP_ERROR_CHECK(esp_smartconfig_set_type(SC_TYPE_ESPTOUCH_AIRKISS));
smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_smartconfig_start(&cfg) );
while (1) {
uxBits = xEventGroupWaitBits(s_wifi_event_group, CONNECTED_BIT | ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
if(uxBits & CONNECTED_BIT) {
ESP_LOGI(TAG, "WiFi Connected to ap");
}
if(uxBits & ESPTOUCH_DONE_BIT) {
ESP_LOGI(TAG, "smartconfig over");
esp_smartconfig_stop();
vTaskDelete(NULL);
}
}
}
void app_main(void)
{
ESP_ERROR_CHECK( nvs_flash_init() );
initialise_wifi();
}