mini_program_gizwits_sdk 3.2.30 → 3.2.32-FeiSiMan
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3 -3
- package/dist/src/aepApi/aepApiRequest.d.ts +7 -0
- package/dist/src/handler/ble.d.ts +5 -10
- package/dist/src/protocol/Reset.d.ts +8 -0
- package/dist/src/protocol/SetReset.d.ts +7 -0
- package/dist/src/sdk.d.ts +204 -0
- package/dist/src/wifiConfig/ConfigBase.d.ts +2 -1
- package/dist/src/wifiConfig/ble.d.ts +16 -3
- package/dist/src/wifiConfig/nfc/disposeData.d.ts +2 -0
- package/dist/src/wifiConfig/nfc/formatData.d.ts +3 -0
- package/dist/src/wifiConfig/nfc/formatSSID.d.ts +6 -0
- package/dist/src/wifiConfig/nfc/index.d.ts +22 -0
- package/dist/src/wifiConfig/nfc/isIncludedCH.d.ts +1 -0
- package/dist/src/wifiConfig/nfc/nfcAConnect.d.ts +6 -0
- package/dist/src/wifiConfig/nfc/nfcATransceive.d.ts +5 -0
- package/dist/src/wifiConfig/nfc/ssIDToASC.d.ts +1 -0
- package/dist/src/wifiConfig/nfc/stringToGbk.d.ts +1 -0
- package/dist/src/wifiConfig/nfc/transceive.wx.d.ts +2 -0
- package/dist/src/wifiConfig/nfc/types.d.ts +15 -0
- package/package.json +1 -1
- package/src/aepApi/aepApiRequest.ts +62 -0
- package/src/handler/ble.ts +32 -17
- package/src/protocol/Reset.ts +16 -0
- package/src/protocol/SetReset.ts +13 -0
- package/src/protocol/dataPoint.ts +18 -18
- package/src/sdk.ts +129 -36
- package/src/services/devices.ts +92 -4
- package/src/utils.ts +15 -5
- package/src/wifiConfig/ConfigBase.ts +3 -1
- package/src/wifiConfig/ble.ts +86 -26
- package/src/wifiConfig/nfc/disposeData.ts +63 -0
- package/src/wifiConfig/nfc/formatData.ts +46 -0
- package/src/wifiConfig/nfc/formatSSID.ts +59 -0
- package/src/wifiConfig/nfc/index.ts +136 -0
- package/src/wifiConfig/nfc/isIncludedCH.ts +8 -0
- package/src/wifiConfig/nfc/nfcAConnect.ts +30 -0
- package/src/wifiConfig/nfc/nfcATransceive.ts +29 -0
- package/src/wifiConfig/nfc/ssIDToASC.ts +12 -0
- package/src/wifiConfig/nfc/stringToGbk.ts +51 -0
- package/src/wifiConfig/nfc/transceive.wx.ts +124 -0
- package/src/wifiConfig/nfc/types.ts +18 -0
package/src/wifiConfig/ble.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import errorCode from "../errorCode";
|
|
2
|
-
import {
|
|
2
|
+
import { IConfigResult, IResult } from "../sdk";
|
|
3
3
|
import { ab2hex, advertisData2PkAndMac, isWXDevicesResult } from '../utils';
|
|
4
4
|
|
|
5
5
|
import GizLog from "../GizLog";
|
|
@@ -11,6 +11,14 @@ import {
|
|
|
11
11
|
notifyBLECharacteristicValueChange, retryConnect, startBluetoothDevicesDiscovery, unpackWriteBLECharacteristicValue
|
|
12
12
|
} from '../wechatApi';
|
|
13
13
|
import ConfigBase from "./ConfigBase";
|
|
14
|
+
import aepApiRequest from "../aepApi/aepApiRequest";
|
|
15
|
+
|
|
16
|
+
interface IVerifyOnlineResult {
|
|
17
|
+
data: {
|
|
18
|
+
status: number; // 2表示离线 3表示在线
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
14
22
|
|
|
15
23
|
interface IArgs {
|
|
16
24
|
bleDeviceId: string;
|
|
@@ -204,8 +212,8 @@ interface ISetDeviceOnboardingDeployProps {
|
|
|
204
212
|
class BLEConfig extends ConfigBase {
|
|
205
213
|
bleHandle: BleHandle;
|
|
206
214
|
|
|
207
|
-
constructor(ssid: string, password: string, specialProductKeys: string[], specialProductKeySecrets: string[],bleHandle: BleHandle) {
|
|
208
|
-
super(ssid,password,specialProductKeys,specialProductKeySecrets)
|
|
215
|
+
constructor(ssid: string, bssid: string, password: string, specialProductKeys: string[], specialProductKeySecrets: string[],bleHandle: BleHandle) {
|
|
216
|
+
super(ssid, bssid, password,specialProductKeys,specialProductKeySecrets)
|
|
209
217
|
this.bleHandle = bleHandle;
|
|
210
218
|
}
|
|
211
219
|
destroy = () => {
|
|
@@ -260,6 +268,52 @@ class BLEConfig extends ConfigBase {
|
|
|
260
268
|
return { success: true };
|
|
261
269
|
};
|
|
262
270
|
|
|
271
|
+
getDeviceLastestOnlineTime = async ({ productKey, mac }:
|
|
272
|
+
{ productKey: string, mac: string }) => {
|
|
273
|
+
GizLog.debug('GIZ_SDK: getDeviceLastestOnlineTime', mac);
|
|
274
|
+
const res = await aepApiRequest<IVerifyOnlineResult>(`/applet/device/getDeviceInfo/${(mac ?? '')}`, { method: 'get' });
|
|
275
|
+
GizLog.debug('GIZ_SDK: 请求结果', res);
|
|
276
|
+
return res;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// 配网后确认设备是否上线
|
|
280
|
+
verifyDeviceOnline = ({ productKey, mac }: { productKey: string, mac: string }) => {
|
|
281
|
+
return new Promise<IResult<IVerifyOnlineResult>>((res, rej) => {
|
|
282
|
+
GizLog.debug('GIZ_SDK: 开始确认设备上线')
|
|
283
|
+
const query = async () => {
|
|
284
|
+
|
|
285
|
+
if (!this.hasTimeoutHandler()) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
try {
|
|
290
|
+
await sleep(2000);
|
|
291
|
+
const data = await this.getDeviceLastestOnlineTime({ productKey, mac })
|
|
292
|
+
GizLog.debug('GIZ_SDK: 确认到设备是否在线', data.data.data.status);
|
|
293
|
+
if (data.success && data.data && data.data.data && data.data.data.status == 3) {
|
|
294
|
+
// 确认设备最后一次上线时间有更新
|
|
295
|
+
GizLog.debug('GIZ_SDK: 确认到设备是在线的', data);
|
|
296
|
+
res({
|
|
297
|
+
success: true,
|
|
298
|
+
data: data.data,
|
|
299
|
+
});
|
|
300
|
+
} else {
|
|
301
|
+
// 重新请求
|
|
302
|
+
GizLog.debug('GIZ_SDK: 未确认到设备是在线');
|
|
303
|
+
await sleep(1500);
|
|
304
|
+
!this.disableSearchDevice && query();
|
|
305
|
+
}
|
|
306
|
+
} catch (error) {
|
|
307
|
+
// 重新请求
|
|
308
|
+
await sleep(3000);
|
|
309
|
+
!this.disableSearchDevice && query();
|
|
310
|
+
// GizLog.debug('GIZ_SDK: random codes error', error);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
query();
|
|
314
|
+
});
|
|
315
|
+
};
|
|
316
|
+
|
|
263
317
|
|
|
264
318
|
enableAndGetBluetoothDevices = async (
|
|
265
319
|
softAPSSIDPrefix?: string
|
|
@@ -301,19 +355,20 @@ class BLEConfig extends ConfigBase {
|
|
|
301
355
|
softAPSSIDPrefix,
|
|
302
356
|
});
|
|
303
357
|
|
|
304
|
-
const newData: IDevice[] =
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
358
|
+
const newData: IDevice[] = [result.data as IDevice];
|
|
359
|
+
// const newData: IDevice[] = (result.data || []).map(item => {
|
|
360
|
+
// return {
|
|
361
|
+
// mac: item.mac,
|
|
362
|
+
// productKey: item.product_key,
|
|
363
|
+
// did: item.did,
|
|
364
|
+
// name: '',
|
|
365
|
+
// isBind: false,
|
|
366
|
+
// connectType: 'NONE',
|
|
367
|
+
// isBleOnline: false,
|
|
368
|
+
// isLanOnline: false,
|
|
369
|
+
// isOnline: false,
|
|
370
|
+
// }
|
|
371
|
+
// })
|
|
317
372
|
if (isBind) {
|
|
318
373
|
res(await this.bindDevices(newData));
|
|
319
374
|
} else {
|
|
@@ -341,7 +396,7 @@ class BLEConfig extends ConfigBase {
|
|
|
341
396
|
password,
|
|
342
397
|
softAPSSIDPrefix,
|
|
343
398
|
}: configBLEDeviceParams) => {
|
|
344
|
-
|
|
399
|
+
return new Promise<IResult<IConfigResult>>(async (res, rej) => {
|
|
345
400
|
GizLog.debug('GIZ_SDK: start config ble device');
|
|
346
401
|
const enableAndGetRes = await this.enableAndGetBluetoothDevices(
|
|
347
402
|
softAPSSIDPrefix
|
|
@@ -374,18 +429,19 @@ class BLEConfig extends ConfigBase {
|
|
|
374
429
|
bleDevices,
|
|
375
430
|
devices.filter((d) => this.isValidBleDevice(d, softAPSSIDPrefix))
|
|
376
431
|
)
|
|
377
|
-
: wx.offBluetoothDeviceFound();
|
|
432
|
+
: wx.offBluetoothDeviceFound(()=>{});
|
|
378
433
|
};
|
|
379
434
|
|
|
380
435
|
wx.onBluetoothDeviceFound(handleFoundDevices);
|
|
381
436
|
|
|
382
437
|
const uint8Array = WifiConfig.pack(ssid,password);
|
|
438
|
+
const bleDevice = bleDevices.shift();
|
|
439
|
+
const { productKey, mac } = advertisData2PkAndMac(bleDevice.advertisData, this.specialProductKeys)
|
|
383
440
|
const startConfigDevice = async () => {
|
|
384
441
|
GizLog.debug('GIZ_SDK: startConfigDevice');
|
|
385
442
|
if (!this.hasTimeoutHandler()) {
|
|
386
443
|
return;
|
|
387
444
|
}
|
|
388
|
-
const bleDevice = bleDevices.shift();
|
|
389
445
|
if (bleDevice) {
|
|
390
446
|
GizLog.debug('GIZ_SDK: startConfigDevice, target device: ', bleDevice);
|
|
391
447
|
}
|
|
@@ -408,21 +464,25 @@ class BLEConfig extends ConfigBase {
|
|
|
408
464
|
|
|
409
465
|
// 如果有一个设备发送成功,则不再发现新设备
|
|
410
466
|
GizLog.debug("GIZ_SDK: offBluetoothDeviceFound ready search device")
|
|
411
|
-
wx.offBluetoothDeviceFound();
|
|
467
|
+
wx.offBluetoothDeviceFound(() => {});
|
|
412
468
|
};
|
|
469
|
+
await startConfigDevice();
|
|
413
470
|
|
|
414
|
-
//
|
|
471
|
+
// 开始确认设备是否上线
|
|
415
472
|
try {
|
|
416
473
|
// const devicesReturn = await this.searchDevice({ ssid, password });
|
|
417
|
-
this.searchDevice({ ssid, password }).then(devicesReturn => {
|
|
418
|
-
|
|
419
|
-
})
|
|
474
|
+
// this.searchDevice({ ssid, password }).then(devicesReturn => {
|
|
475
|
+
// res(devicesReturn);
|
|
476
|
+
// })
|
|
477
|
+
await sleep(5000);
|
|
478
|
+
// const devicesReturn = await this.searchDevice({ ssid, password });
|
|
479
|
+
this.verifyDeviceOnline({ productKey, mac }).then(devicesReturn => {
|
|
480
|
+
res({ ...devicesReturn, data: { ...devicesReturn.data.data, mac, productKey } });
|
|
481
|
+
});
|
|
420
482
|
} catch (error) {
|
|
421
483
|
rej(error);
|
|
422
484
|
GizLog.error("GIZ_SDK: searchDevice error", new Error(JSON.stringify(error)))
|
|
423
485
|
}
|
|
424
|
-
|
|
425
|
-
await startConfigDevice();
|
|
426
486
|
});
|
|
427
487
|
};
|
|
428
488
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { IDATA } from './types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 配网标志位
|
|
5
|
+
*/
|
|
6
|
+
const formatSign = (): Uint8Array => {
|
|
7
|
+
const buffer = new ArrayBuffer(1);
|
|
8
|
+
const uint8Array = new Uint8Array(buffer);
|
|
9
|
+
uint8Array[0] = 1;
|
|
10
|
+
return uint8Array;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* 标志位,APP端设置,含有中⽂字符SSID置为1,不含中⽂字符SSID置为0,默认为0
|
|
14
|
+
* @param isSSIDincludeCH
|
|
15
|
+
*/
|
|
16
|
+
const formatRouterType = (isSSIDincludeCH: boolean): Uint8Array => {
|
|
17
|
+
const buffer = new ArrayBuffer(1);
|
|
18
|
+
const uint8Array = new Uint8Array(buffer);
|
|
19
|
+
uint8Array[0] = 0;
|
|
20
|
+
if (isSSIDincludeCH) {
|
|
21
|
+
uint8Array[0] = 1;
|
|
22
|
+
}
|
|
23
|
+
return uint8Array;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* 模块初始化标志位,默认未初始化,值为 0x55 0xaa代表已初始化,其他代表未初始化。
|
|
27
|
+
*/
|
|
28
|
+
const formatInitValue = (): Uint8Array => {
|
|
29
|
+
const buffer = new ArrayBuffer(2);
|
|
30
|
+
const uint8Array = new Uint8Array(buffer);
|
|
31
|
+
uint8Array[0] = parseInt('0x55', 16);
|
|
32
|
+
uint8Array[1] = parseInt('0xaa', 16);
|
|
33
|
+
return uint8Array;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* 处理整合传入的数据
|
|
37
|
+
* @param SSID SSIDTLV
|
|
38
|
+
* @param isSSIDincludeCH SSID是否含有中文
|
|
39
|
+
* @param pwd pwdTLV
|
|
40
|
+
* @param passIP passIPTLV
|
|
41
|
+
* @param BSSID BSSIDTLV
|
|
42
|
+
* @returns 最终要写入固件的数据
|
|
43
|
+
*/
|
|
44
|
+
export const disposeData = (
|
|
45
|
+
SSID: Uint8Array,
|
|
46
|
+
isSSIDincludeCH: boolean,
|
|
47
|
+
pwd: Uint8Array,
|
|
48
|
+
passIP: Uint8Array,
|
|
49
|
+
BSSID: Uint8Array
|
|
50
|
+
): IDATA => {
|
|
51
|
+
const sign = formatSign();
|
|
52
|
+
const routerType = formatRouterType(isSSIDincludeCH);
|
|
53
|
+
const initValue = formatInitValue();
|
|
54
|
+
|
|
55
|
+
const uint8Array_sign = Uint8Array.from([...sign, ...routerType, ...initValue]);
|
|
56
|
+
const uint8Array_others = Uint8Array.from([...SSID, ...pwd, ...passIP, ...BSSID]);
|
|
57
|
+
console.log(uint8Array_sign.buffer, 'uint8Array_sign.buffer', uint8Array_sign);
|
|
58
|
+
console.log(uint8Array_others.buffer, 'uint8Array_others.buffer', uint8Array_others);
|
|
59
|
+
return {
|
|
60
|
+
ArrayBuffer_sign: uint8Array_sign.buffer,
|
|
61
|
+
ArrayBuffer_others: uint8Array_others.buffer,
|
|
62
|
+
};
|
|
63
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
type IType = 'BSSID' | 'pwd' | 'address';
|
|
2
|
+
/**
|
|
3
|
+
* BSSID去除冒号,转TLV编码(总长8字节)& pwd | passIP转TLV编码
|
|
4
|
+
* @param data BSSID | pwd | passIP
|
|
5
|
+
* @param type 'BSSID' & 'pwd' & 'passIP'
|
|
6
|
+
* @returns BSSID(TLV) & pwd(TLV) & passIP(TLV): Uint8Array;
|
|
7
|
+
*/
|
|
8
|
+
export const formatData = (data: string, type: IType): Uint8Array => {
|
|
9
|
+
const isNull = data.length === 0;
|
|
10
|
+
const Data = type === 'BSSID' ? data.split(':') : data.split('');
|
|
11
|
+
let length: number = 0;
|
|
12
|
+
let T: any = null;
|
|
13
|
+
let L: number = 0;
|
|
14
|
+
switch (type) {
|
|
15
|
+
case 'BSSID':
|
|
16
|
+
length = isNull ? 3 : Data.length + 2;
|
|
17
|
+
T = 'b';
|
|
18
|
+
L = isNull ? 0 : Data.length;
|
|
19
|
+
break;
|
|
20
|
+
case 'pwd':
|
|
21
|
+
length = data.length + 2;
|
|
22
|
+
T = 'p';
|
|
23
|
+
L = data.length;
|
|
24
|
+
break;
|
|
25
|
+
case 'address':
|
|
26
|
+
length = isNull ? 3 : Data.length + 2;
|
|
27
|
+
T = 'i';
|
|
28
|
+
L = isNull ? 0 : Data.length;
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
const buffer = new ArrayBuffer(length);
|
|
32
|
+
const uint8Array = new Uint8Array(buffer);
|
|
33
|
+
uint8Array[0] = T.charCodeAt(0); // Tag
|
|
34
|
+
uint8Array[1] = L; // Length
|
|
35
|
+
|
|
36
|
+
if (isNull) {
|
|
37
|
+
uint8Array[2] = 0;
|
|
38
|
+
} else {
|
|
39
|
+
Data.forEach((byte, index) => {
|
|
40
|
+
const v = type === 'BSSID' ? parseInt(byte, 16) : byte.charCodeAt(0);
|
|
41
|
+
uint8Array[index + 2] = v; // 前两个字节为Tag\Length预留
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
console.log(buffer, uint8Array, 'formatData', type);
|
|
45
|
+
return uint8Array;
|
|
46
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { formatCodesFromStr, arrayToString } from '../../protocol/tool';
|
|
2
|
+
import { unionBy } from '../../utils';
|
|
3
|
+
import isIncludedCH from './isIncludedCH';
|
|
4
|
+
import { ssIDToASC } from './ssIDToASC';
|
|
5
|
+
import stringToGbk from './stringToGbk';
|
|
6
|
+
|
|
7
|
+
interface IExport {
|
|
8
|
+
SSIDTLV: any;
|
|
9
|
+
isSSIDIncludedCH: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* SSID转TLV编码 / 判断SSID是否含有中文
|
|
13
|
+
* @param SSID
|
|
14
|
+
* @returns SSIDTLV: TLV(Uint8Array), isSSIDIncludedCH: boolean
|
|
15
|
+
*/
|
|
16
|
+
export const formatSSID = (SSID: string): IExport => {
|
|
17
|
+
const _export: IExport = {
|
|
18
|
+
SSIDTLV: null,
|
|
19
|
+
isSSIDIncludedCH: isIncludedCH(SSID),
|
|
20
|
+
};
|
|
21
|
+
// const enCode = isIncludedCH(SSID) ? stringToGbk(SSID) : ssIDToASC(SSID);
|
|
22
|
+
// const length = enCode.byteLength;
|
|
23
|
+
|
|
24
|
+
const [enCode, length] = formatCodesFromStr(SSID);
|
|
25
|
+
const codeLength = parseInt(arrayToString(length), 16);
|
|
26
|
+
if (codeLength <= 127) {
|
|
27
|
+
const buffer = new ArrayBuffer(codeLength + 2);
|
|
28
|
+
const uint8Array = new Uint8Array(buffer);
|
|
29
|
+
uint8Array[0] = 's'.charCodeAt(0); // T
|
|
30
|
+
uint8Array[1] = codeLength; // L
|
|
31
|
+
enCode.forEach((byte, index) => {
|
|
32
|
+
uint8Array[index + 2] = byte;
|
|
33
|
+
});
|
|
34
|
+
_export['SSIDTLV'] = uint8Array;
|
|
35
|
+
} else {
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
const extra_L = parseInt(length / 255) + 1;
|
|
38
|
+
const buffer = new ArrayBuffer(codeLength + 2 + extra_L);
|
|
39
|
+
const uint8Array = new Uint8Array(buffer);
|
|
40
|
+
uint8Array[0] = 's'.charCodeAt(0); // T
|
|
41
|
+
uint8Array[1] = 128 + extra_L; // L@No1.Byte
|
|
42
|
+
if (extra_L === 1) {
|
|
43
|
+
uint8Array[2] = codeLength; // L@No2.Byte
|
|
44
|
+
} else {
|
|
45
|
+
uint8Array[extra_L] = 255;
|
|
46
|
+
uint8Array[extra_L + 1] = codeLength - 255 * (extra_L - 1);
|
|
47
|
+
for (let d = extra_L; d >= 1; d--) {
|
|
48
|
+
if (uint8Array[extra_L - d] === 0) {
|
|
49
|
+
uint8Array[extra_L - d] = 255;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
enCode.forEach((byte, index) => {
|
|
54
|
+
uint8Array[index + 2 + extra_L] = byte;
|
|
55
|
+
});
|
|
56
|
+
_export['SSIDTLV'] = uint8Array;
|
|
57
|
+
}
|
|
58
|
+
return _export;
|
|
59
|
+
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { disposeData } from './disposeData';
|
|
2
|
+
import { formatData } from './formatData';
|
|
3
|
+
import { formatSSID } from './formatSSID';
|
|
4
|
+
import { transceive } from './transceive.wx';
|
|
5
|
+
import errorCode from "../../errorCode";
|
|
6
|
+
import GizLog from "../../GizLog";
|
|
7
|
+
import WifiConfig from "../../protocol/WifiConfig";
|
|
8
|
+
import { IRandomCodesResult, IResult, IntervalHandle } from "../../sdk";
|
|
9
|
+
import ConfigBase from "../ConfigBase";
|
|
10
|
+
|
|
11
|
+
// type IParams = {
|
|
12
|
+
// SSID: string;
|
|
13
|
+
// BSSID: string;
|
|
14
|
+
// pwd: string;
|
|
15
|
+
// passIP: string;
|
|
16
|
+
// };
|
|
17
|
+
/**
|
|
18
|
+
* 配网
|
|
19
|
+
*/
|
|
20
|
+
// export const distribution = ({ SSID, BSSID, pwd, passIP }: IParams) => {
|
|
21
|
+
// const { SSIDTLV, isSSIDIncludedCH } = formatSSID(SSID);
|
|
22
|
+
// const BSSIDTLV = formatData(BSSID, 'BSSID');
|
|
23
|
+
// const pwdTLV = formatData(pwd, 'pwd');
|
|
24
|
+
// const passIPTLV = formatData(passIP, 'passIP');
|
|
25
|
+
// const DATA = disposeData(SSIDTLV, isSSIDIncludedCH, pwdTLV, passIPTLV, BSSIDTLV);
|
|
26
|
+
// console.log(DATA, 'DATA');
|
|
27
|
+
|
|
28
|
+
// // 发送数据
|
|
29
|
+
// transceive(DATA);
|
|
30
|
+
// };
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
interface configDeviceParams {
|
|
35
|
+
ssid: string;
|
|
36
|
+
password: string;
|
|
37
|
+
bssid: string;
|
|
38
|
+
address: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface ISetDeviceOnboardingDeployProps {
|
|
42
|
+
timeout: number;
|
|
43
|
+
isBind: boolean;
|
|
44
|
+
BSSID: string;
|
|
45
|
+
softAPSSIDPrefix: string;
|
|
46
|
+
}
|
|
47
|
+
class NFCConfig extends ConfigBase {
|
|
48
|
+
// 服务器地址
|
|
49
|
+
address: string = '';
|
|
50
|
+
constructor(ssid: string, bssid: string, password: string,
|
|
51
|
+
specialProductKeys: string[], specialProductKeySecrets: string[], address: string) {
|
|
52
|
+
super(ssid, bssid, password, specialProductKeys, specialProductKeySecrets)
|
|
53
|
+
this.address = address;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
destroy = () => {
|
|
57
|
+
this.cleanTimeout();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 负责发指令
|
|
62
|
+
*/
|
|
63
|
+
configDevice = async ({ ssid, password, bssid, address }: configDeviceParams) => {
|
|
64
|
+
// TODO 发包
|
|
65
|
+
const { SSIDTLV, isSSIDIncludedCH } = formatSSID(ssid);
|
|
66
|
+
const BSSIDTLV = formatData(bssid, 'BSSID');
|
|
67
|
+
const pwdTLV = formatData(password, 'pwd');
|
|
68
|
+
const passIPTLV = formatData(address, 'address');
|
|
69
|
+
const DATA = disposeData(SSIDTLV, isSSIDIncludedCH, pwdTLV, passIPTLV, BSSIDTLV);
|
|
70
|
+
console.log(DATA, 'DATA');
|
|
71
|
+
|
|
72
|
+
// 发送数据
|
|
73
|
+
transceive(DATA);
|
|
74
|
+
// 大循环搜索
|
|
75
|
+
const devicesReturn = await this.searchDevice({ ssid, password });
|
|
76
|
+
return devicesReturn
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* 配网接口
|
|
80
|
+
* setDeviceOnboardingDeploy方法不可重复调用
|
|
81
|
+
*/
|
|
82
|
+
setDeviceOnboardingDeploy = ({
|
|
83
|
+
timeout,
|
|
84
|
+
isBind = true,
|
|
85
|
+
}: ISetDeviceOnboardingDeployProps) => {
|
|
86
|
+
const ssid = this.ssid;
|
|
87
|
+
const password = this.password;
|
|
88
|
+
return new Promise<IResult<IDevice[]>>(async (res, rej) => {
|
|
89
|
+
console.log('ssid0', ssid, password, this.bssid, this.address)
|
|
90
|
+
this.destroy();
|
|
91
|
+
this.initDeviceOnboardingDeploy(res, rej);
|
|
92
|
+
this.startTimeoutTimer(timeout);
|
|
93
|
+
console.log('ssid', ssid, password, this.bssid, this.address)
|
|
94
|
+
try {
|
|
95
|
+
const result = await this.configDevice({
|
|
96
|
+
ssid,
|
|
97
|
+
password,
|
|
98
|
+
bssid: this.bssid,
|
|
99
|
+
address: this.address
|
|
100
|
+
});
|
|
101
|
+
const newData: IDevice[] = (result.data || []).map(item => {
|
|
102
|
+
return {
|
|
103
|
+
mac: item.mac,
|
|
104
|
+
productKey: item.product_key,
|
|
105
|
+
did: item.did,
|
|
106
|
+
name: '',
|
|
107
|
+
isBind: false,
|
|
108
|
+
connectType: 'NONE',
|
|
109
|
+
isBleOnline: false,
|
|
110
|
+
isLanOnline: false,
|
|
111
|
+
isOnline: false,
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
if (isBind) {
|
|
115
|
+
try {
|
|
116
|
+
res(await this.bindDevices(newData));
|
|
117
|
+
} catch (error) {
|
|
118
|
+
rej(error);
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
// 不需要绑定 直接返回成功
|
|
122
|
+
res({
|
|
123
|
+
success: true,
|
|
124
|
+
data: newData,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
rej(error);
|
|
129
|
+
} finally {
|
|
130
|
+
this.destroy();
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export default NFCConfig;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type T = {
|
|
2
|
+
success: boolean;
|
|
3
|
+
nfcA: any;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 连接NFCA实例
|
|
8
|
+
* @param NFCAdapter NFCAdapter实例
|
|
9
|
+
* @returns Promise<{success: boolean, nfcA: any}>
|
|
10
|
+
*/
|
|
11
|
+
export const nfcAConnect = (NFCAdapter: any): Promise<T> => {
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
// nfcA实例
|
|
14
|
+
const nfcA = NFCAdapter.getNfcA();
|
|
15
|
+
nfcA.connect({
|
|
16
|
+
success() {
|
|
17
|
+
resolve({
|
|
18
|
+
success: true,
|
|
19
|
+
nfcA,
|
|
20
|
+
});
|
|
21
|
+
},
|
|
22
|
+
fail() {
|
|
23
|
+
resolve({
|
|
24
|
+
success: false,
|
|
25
|
+
nfcA,
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
type T = {
|
|
2
|
+
transceiveSuccess: boolean;
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* NfcA.transceive
|
|
7
|
+
* @param nfcA: NFCA实例
|
|
8
|
+
* @param buffer: ArrayBuffer实例
|
|
9
|
+
* @returns Promise<T>
|
|
10
|
+
*/
|
|
11
|
+
export const nfcATransceive = (nfcA: any, buffer: ArrayBuffer): Promise<T> => {
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
nfcA.transceive({
|
|
14
|
+
data: buffer,
|
|
15
|
+
success: (res) => {
|
|
16
|
+
console.log('success', res);
|
|
17
|
+
resolve({
|
|
18
|
+
transceiveSuccess: true,
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
fail: (err) => {
|
|
22
|
+
console.log('fail', err);
|
|
23
|
+
resolve({
|
|
24
|
+
transceiveSuccess: false,
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 传入不含中文的SSID,返回SSID(TLV)中的Value
|
|
3
|
+
* @param SSID string;
|
|
4
|
+
* @returns Uint8Array SSID(Value部分)
|
|
5
|
+
*/
|
|
6
|
+
export const ssIDToASC = (SSID: string): Uint8Array => {
|
|
7
|
+
const uint8Array = new Uint8Array(SSID.length);
|
|
8
|
+
SSID.split('').forEach((byte, index) => {
|
|
9
|
+
uint8Array[index] = byte.charCodeAt(0);
|
|
10
|
+
});
|
|
11
|
+
return uint8Array;
|
|
12
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const encoding = require('./text-encoding-master/lib/encoding')
|
|
2
|
+
const ranges = [
|
|
3
|
+
[0xA1, 0xA9, 0xA1, 0xFE],
|
|
4
|
+
[0xB0, 0xF7, 0xA1, 0xFE],
|
|
5
|
+
[0x81, 0xA0, 0x40, 0xFE],
|
|
6
|
+
[0xAA, 0xFE, 0x40, 0xA0],
|
|
7
|
+
[0xA8, 0xA9, 0x40, 0xA0],
|
|
8
|
+
[0xAA, 0xAF, 0xA1, 0xFE],
|
|
9
|
+
[0xF8, 0xFE, 0xA1, 0xFE],
|
|
10
|
+
[0xA1, 0xA7, 0x40, 0xA0],
|
|
11
|
+
];
|
|
12
|
+
const codes = new Uint16Array(23940);
|
|
13
|
+
let i = 0;
|
|
14
|
+
|
|
15
|
+
for (const [b1Begin, b1End, b2Begin, b2End] of ranges) {
|
|
16
|
+
for (let b2 = b2Begin; b2 <= b2End; b2++) {
|
|
17
|
+
if (b2 !== 0x7F) {
|
|
18
|
+
for (let b1 = b1Begin; b1 <= b1End; b1++) {
|
|
19
|
+
codes[i++] = b2 << 8 | b1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const str = new encoding.TextDecoder('gbk').decode(codes);
|
|
25
|
+
const table = new Uint16Array(65536);
|
|
26
|
+
for (let i = 0; i < str.length; i++) {
|
|
27
|
+
table[str.charCodeAt(i)] = codes[i];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* string转GBK编码
|
|
32
|
+
* @param str
|
|
33
|
+
* @returns 参数的GBK编码
|
|
34
|
+
*/
|
|
35
|
+
export default function stringToGbk(str: string): Uint8Array {
|
|
36
|
+
const buf = new Uint8Array(str.length * 2);
|
|
37
|
+
let n = 0;
|
|
38
|
+
|
|
39
|
+
for (let i = 0; i < str.length; i++) {
|
|
40
|
+
const code = str.charCodeAt(i);
|
|
41
|
+
if (code < 0x80) {
|
|
42
|
+
buf[n++] = code;
|
|
43
|
+
} else {
|
|
44
|
+
const gbk = table[code];
|
|
45
|
+
buf[n++] = gbk & 0xFF;
|
|
46
|
+
buf[n++] = gbk >> 8;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return buf.subarray(0, n);
|
|
50
|
+
}
|
|
51
|
+
|