@wodzik/cubecore 0.1.0
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/LICENSE +373 -0
- package/README.md +118 -0
- package/analyze/client.d.ts +18 -0
- package/analyze/client.js +42 -0
- package/analyze/index.d.ts +114 -0
- package/analyze/index.js +151 -0
- package/analyze/rotations.d.ts +3 -0
- package/analyze/rotations.js +15 -0
- package/analyze/roux.d.ts +67 -0
- package/analyze/roux.js +95 -0
- package/analyze/worker.d.ts +6 -0
- package/analyze/worker.js +31 -0
- package/analyze/zz.d.ts +47 -0
- package/analyze/zz.js +102 -0
- package/bld/index.d.ts +14 -0
- package/bld/index.js +14 -0
- package/bld/memo.d.ts +66 -0
- package/bld/memo.js +139 -0
- package/bld/scheme.d.ts +30 -0
- package/bld/scheme.js +35 -0
- package/bld/skin.d.ts +26 -0
- package/bld/skin.js +46 -0
- package/bld/tracker.d.ts +68 -0
- package/bld/tracker.js +145 -0
- package/bluetooth/clock.d.ts +22 -0
- package/bluetooth/clock.js +37 -0
- package/bluetooth/cubeSkins.d.ts +31 -0
- package/bluetooth/cubeSkins.js +32 -0
- package/bluetooth/gyro.d.ts +31 -0
- package/bluetooth/gyro.js +46 -0
- package/bluetooth/index.d.ts +5 -0
- package/bluetooth/index.js +5 -0
- package/bluetooth/session.d.ts +140 -0
- package/bluetooth/session.js +201 -0
- package/bluetooth/simulated.d.ts +52 -0
- package/bluetooth/simulated.js +80 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-cube-definitions.d.ts +38 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-cube-definitions.js +51 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-cube-encrypter.d.ts +35 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-cube-encrypter.js +70 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-cube-protocol.d.ts +273 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-cube-protocol.js +846 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-gen1.d.ts +38 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-gen1.js +340 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-gen234-packet-validate.d.ts +11 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-gen234-packet-validate.js +118 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-mac-salt.d.ts +2 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-mac-salt.js +15 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-smart-cube.d.ts +18 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-smart-cube.js +152 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-smart-timer.d.ts +74 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-smart-timer.js +161 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-write-queue.d.ts +7 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gan-write-queue.js +11 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gatt-characteristic-write.d.ts +2 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/gatt-characteristic-write.js +36 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/index.d.ts +4 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/index.js +4 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/address-hints.d.ts +12 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/address-hints.js +122 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/build-picker-options.d.ts +11 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/build-picker-options.js +55 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/default-optional-services.d.ts +21 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/default-optional-services.js +47 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/device-name-scan-filters.d.ts +6 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/device-name-scan-filters.js +24 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/gatt-snapshot.d.ts +6 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/gatt-snapshot.js +57 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/mac-candidates.d.ts +11 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/mac-candidates.js +67 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/mac-probe-moyu32.d.ts +8 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/mac-probe-moyu32.js +98 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/mac-probe-qiyi.d.ts +8 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/mac-probe-qiyi.js +128 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/moyu32-session-crypto.d.ts +5 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/moyu32-session-crypto.js +60 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/normalize-uuid.d.ts +2 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/normalize-uuid.js +8 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/packet-sanity.d.ts +7 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/packet-sanity.js +142 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/profile-rank.d.ts +6 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/profile-rank.js +21 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/types.d.ts +32 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/types.js +1 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/ble-utils.d.ts +6 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/ble-utils.js +68 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/connect.d.ts +3 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/connect.js +178 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/cubie-cube.d.ts +16 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/cubie-cube.js +141 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/index.d.ts +11 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/index.js +10 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocol.d.ts +26 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocol.js +8 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/gan.d.ts +3 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/gan.js +265 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/giiker.d.ts +3 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/giiker.js +345 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/gocube.d.ts +15 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/gocube.js +382 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/moyu-mhc.d.ts +3 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/moyu-mhc.js +352 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/moyu-v1.d.ts +57 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/moyu-v1.js +243 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/moyu32.d.ts +3 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/moyu32.js +454 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/qiyi.d.ts +3 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/protocols/qiyi.js +424 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/types.d.ts +78 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/types.js +1 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/utils.d.ts +45 -0
- package/bluetooth/vendor/smartcube-web-bluetooth/utils.js +150 -0
- package/cfop/caseData.d.ts +16 -0
- package/cfop/caseData.js +88 -0
- package/cfop/cases.d.ts +42 -0
- package/cfop/cases.js +116 -0
- package/cfop/f2l.d.ts +28 -0
- package/cfop/f2l.js +88 -0
- package/cfop/f2lData.d.ts +15 -0
- package/cfop/f2lData.js +49 -0
- package/cfop/index.d.ts +41 -0
- package/cfop/index.js +110 -0
- package/cfop/slots.d.ts +2 -0
- package/cfop/slots.js +1 -0
- package/core/arrows.d.ts +24 -0
- package/core/arrows.js +22 -0
- package/core/bytes.d.ts +27 -0
- package/core/bytes.js +145 -0
- package/core/centers.d.ts +32 -0
- package/core/centers.js +83 -0
- package/core/checks.d.ts +53 -0
- package/core/checks.js +85 -0
- package/core/cubies.d.ts +45 -0
- package/core/cubies.js +169 -0
- package/core/frames.d.ts +61 -0
- package/core/frames.js +126 -0
- package/core/geometry.d.ts +58 -0
- package/core/geometry.js +132 -0
- package/core/index.d.ts +19 -0
- package/core/index.js +19 -0
- package/core/masks.d.ts +32 -0
- package/core/masks.js +39 -0
- package/core/method.d.ts +35 -0
- package/core/method.js +30 -0
- package/core/moves.d.ts +48 -0
- package/core/moves.js +88 -0
- package/core/notation.d.ts +48 -0
- package/core/notation.js +226 -0
- package/core/physical.d.ts +53 -0
- package/core/physical.js +99 -0
- package/core/practice.d.ts +62 -0
- package/core/practice.js +87 -0
- package/core/sequence.d.ts +90 -0
- package/core/sequence.js +157 -0
- package/core/stages.d.ts +90 -0
- package/core/stages.js +21 -0
- package/core/state.d.ts +55 -0
- package/core/state.js +140 -0
- package/core/stateCodec.d.ts +12 -0
- package/core/stateCodec.js +51 -0
- package/core/stream.d.ts +45 -0
- package/core/stream.js +75 -0
- package/core/tracker.d.ts +62 -0
- package/core/tracker.js +121 -0
- package/element/alg.d.ts +45 -0
- package/element/alg.js +150 -0
- package/element/base.d.ts +2 -0
- package/element/base.js +3 -0
- package/element/bld.d.ts +82 -0
- package/element/bld.js +222 -0
- package/element/index.d.ts +8 -0
- package/element/index.js +21 -0
- package/element/model.d.ts +36 -0
- package/element/model.js +64 -0
- package/element/player.d.ts +196 -0
- package/element/player.js +680 -0
- package/element/practice.d.ts +75 -0
- package/element/practice.js +150 -0
- package/element/scramble.d.ts +50 -0
- package/element/scramble.js +107 -0
- package/element/sequence.d.ts +126 -0
- package/element/sequence.js +254 -0
- package/element/styles.d.ts +32 -0
- package/element/styles.js +196 -0
- package/image/cache.d.ts +21 -0
- package/image/cache.js +66 -0
- package/image/index.d.ts +2 -0
- package/image/index.js +2 -0
- package/image/png-node.d.ts +6 -0
- package/image/png-node.js +10 -0
- package/image/svg.d.ts +36 -0
- package/image/svg.js +215 -0
- package/lbl/index.d.ts +10 -0
- package/lbl/index.js +31 -0
- package/methods/index.d.ts +20 -0
- package/methods/index.js +33 -0
- package/package.json +133 -0
- package/petrus/index.d.ts +11 -0
- package/petrus/index.js +27 -0
- package/react/index.d.ts +176 -0
- package/react/index.js +228 -0
- package/render/arrows.d.ts +68 -0
- package/render/arrows.js +190 -0
- package/render/build/attachments.d.ts +35 -0
- package/render/build/attachments.js +94 -0
- package/render/build/models.d.ts +9 -0
- package/render/build/models.js +27 -0
- package/render/build/tiles.d.ts +48 -0
- package/render/build/tiles.js +194 -0
- package/render/gltf.d.ts +10 -0
- package/render/gltf.js +106 -0
- package/render/index.d.ts +12 -0
- package/render/index.js +12 -0
- package/render/layers.d.ts +21 -0
- package/render/layers.js +24 -0
- package/render/pictures.d.ts +46 -0
- package/render/pictures.js +80 -0
- package/render/pieceModels.d.ts +38 -0
- package/render/pieceModels.js +43 -0
- package/render/renderer.d.ts +165 -0
- package/render/renderer.js +647 -0
- package/render/tile.d.ts +114 -0
- package/render/tile.js +390 -0
- package/render/viewports.d.ts +25 -0
- package/render/viewports.js +26 -0
- package/roux/cmll.d.ts +35 -0
- package/roux/cmll.js +121 -0
- package/roux/cmllData.d.ts +12 -0
- package/roux/cmllData.js +49 -0
- package/roux/index.d.ts +52 -0
- package/roux/index.js +175 -0
- package/skin/attachments.d.ts +82 -0
- package/skin/attachments.js +110 -0
- package/skin/index.d.ts +3 -0
- package/skin/index.js +3 -0
- package/skin/shapes.d.ts +112 -0
- package/skin/shapes.js +147 -0
- package/skin/skin.d.ts +911 -0
- package/skin/skin.js +412 -0
- package/solve/client.d.ts +58 -0
- package/solve/client.js +56 -0
- package/solve/handle.d.ts +6 -0
- package/solve/handle.js +38 -0
- package/solve/index.d.ts +8 -0
- package/solve/index.js +7 -0
- package/solve/lse.d.ts +42 -0
- package/solve/lse.js +151 -0
- package/solve/pieces.d.ts +18 -0
- package/solve/pieces.js +24 -0
- package/solve/protocol.d.ts +70 -0
- package/solve/protocol.js +16 -0
- package/solve/scramble.d.ts +76 -0
- package/solve/scramble.js +187 -0
- package/solve/stage.d.ts +108 -0
- package/solve/stage.js +532 -0
- package/solve/twophase.d.ts +36 -0
- package/solve/twophase.js +229 -0
- package/solve/worker.d.ts +6 -0
- package/solve/worker.js +15 -0
- package/timeline/codec.d.ts +23 -0
- package/timeline/codec.js +84 -0
- package/timeline/index.d.ts +7 -0
- package/timeline/index.js +7 -0
- package/timeline/recording.d.ts +19 -0
- package/timeline/recording.js +20 -0
- package/timeline/replay.d.ts +68 -0
- package/timeline/replay.js +145 -0
- package/timeline/segments.d.ts +31 -0
- package/timeline/segments.js +39 -0
- package/timeline/share.d.ts +30 -0
- package/timeline/share.js +62 -0
- package/timeline/stats.d.ts +34 -0
- package/timeline/stats.js +56 -0
- package/timeline/timings.d.ts +30 -0
- package/timeline/timings.js +54 -0
- package/zz/index.d.ts +29 -0
- package/zz/index.js +68 -0
- package/zz/seeds.d.ts +9 -0
- package/zz/seeds.js +29 -0
package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/default-optional-services.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consolidated GATT service UUIDs for pairing so the OS grants access across vendors.
|
|
3
|
+
*/
|
|
4
|
+
export declare const DEVICE_INFORMATION_SERVICE: string;
|
|
5
|
+
export declare const GENERIC_ACCESS_SERVICE: string;
|
|
6
|
+
/** QiYi primary (16-bit FFF0). */
|
|
7
|
+
export declare const QIYI_LIKE_FFF0: string;
|
|
8
|
+
/** MoYu plain (MHC). */
|
|
9
|
+
export declare const MOYU_PLAIN_SERVICE: string;
|
|
10
|
+
/** MoYu32 / WCU. */
|
|
11
|
+
export declare const MOYU32_SERVICE = "0783b03e-7735-b5a0-1760-a305d2795cb0";
|
|
12
|
+
/** Giiker. */
|
|
13
|
+
export declare const GIIKER_DATA_SERVICE: string;
|
|
14
|
+
export declare const GIIKER_CTRL_SERVICE: string;
|
|
15
|
+
/** GoCube UART. */
|
|
16
|
+
export declare const GOCUBE_UART_SERVICE = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
|
|
17
|
+
/**
|
|
18
|
+
* Union of services commonly needed when connecting smart cubes via Web Bluetooth.
|
|
19
|
+
*/
|
|
20
|
+
export declare const DEFAULT_SMARTCUBE_OPTIONAL_SERVICES: readonly string[];
|
|
21
|
+
export declare function mergeOptionalServiceUuids(protocolServices: Iterable<string>): string[];
|
package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/default-optional-services.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consolidated GATT service UUIDs for pairing so the OS grants access across vendors.
|
|
3
|
+
*/
|
|
4
|
+
import * as gan from '../../gan-cube-definitions.js';
|
|
5
|
+
const S = '-0000-1000-8000-00805f9b34fb';
|
|
6
|
+
export const DEVICE_INFORMATION_SERVICE = '0000180a' + S;
|
|
7
|
+
export const GENERIC_ACCESS_SERVICE = '00001800' + S;
|
|
8
|
+
/** QiYi primary (16-bit FFF0). */
|
|
9
|
+
export const QIYI_LIKE_FFF0 = '0000fff0' + S;
|
|
10
|
+
/** MoYu plain (MHC). */
|
|
11
|
+
export const MOYU_PLAIN_SERVICE = '00001000' + S;
|
|
12
|
+
/** MoYu32 / WCU. */
|
|
13
|
+
export const MOYU32_SERVICE = '0783b03e-7735-b5a0-1760-a305d2795cb0';
|
|
14
|
+
/** Giiker. */
|
|
15
|
+
export const GIIKER_DATA_SERVICE = '0000aadb' + S;
|
|
16
|
+
export const GIIKER_CTRL_SERVICE = '0000aaaa' + S;
|
|
17
|
+
/** GoCube UART. */
|
|
18
|
+
export const GOCUBE_UART_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e';
|
|
19
|
+
/**
|
|
20
|
+
* Union of services commonly needed when connecting smart cubes via Web Bluetooth.
|
|
21
|
+
*/
|
|
22
|
+
export const DEFAULT_SMARTCUBE_OPTIONAL_SERVICES = [
|
|
23
|
+
GENERIC_ACCESS_SERVICE,
|
|
24
|
+
DEVICE_INFORMATION_SERVICE,
|
|
25
|
+
gan.GAN_GEN2_SERVICE,
|
|
26
|
+
gan.GAN_GEN2_COMMAND_CHARACTERISTIC,
|
|
27
|
+
gan.GAN_GEN2_STATE_CHARACTERISTIC,
|
|
28
|
+
gan.GAN_GEN3_SERVICE,
|
|
29
|
+
gan.GAN_GEN3_COMMAND_CHARACTERISTIC,
|
|
30
|
+
gan.GAN_GEN3_STATE_CHARACTERISTIC,
|
|
31
|
+
gan.GAN_GEN4_SERVICE,
|
|
32
|
+
gan.GAN_GEN4_COMMAND_CHARACTERISTIC,
|
|
33
|
+
gan.GAN_GEN4_STATE_CHARACTERISTIC,
|
|
34
|
+
QIYI_LIKE_FFF0,
|
|
35
|
+
MOYU_PLAIN_SERVICE,
|
|
36
|
+
MOYU32_SERVICE,
|
|
37
|
+
GIIKER_DATA_SERVICE,
|
|
38
|
+
GIIKER_CTRL_SERVICE,
|
|
39
|
+
GOCUBE_UART_SERVICE,
|
|
40
|
+
];
|
|
41
|
+
export function mergeOptionalServiceUuids(protocolServices) {
|
|
42
|
+
const u = new Set(DEFAULT_SMARTCUBE_OPTIONAL_SERVICES);
|
|
43
|
+
for (const s of protocolServices) {
|
|
44
|
+
u.add(s);
|
|
45
|
+
}
|
|
46
|
+
return Array.from(u);
|
|
47
|
+
}
|
package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/device-name-scan-filters.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference types="web-bluetooth" />
|
|
2
|
+
/**
|
|
3
|
+
* Extra Web Bluetooth scan filters when reconnecting with a known advertised name.
|
|
4
|
+
*/
|
|
5
|
+
/** Wildcard-style names some stacks use for GAN advertising aliases. */
|
|
6
|
+
export declare function extraScanFiltersForKnownDeviceName(deviceName: string | undefined): BluetoothLEScanFilter[];
|
package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/device-name-scan-filters.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extra Web Bluetooth scan filters when reconnecting with a known advertised name.
|
|
3
|
+
*/
|
|
4
|
+
/** Wildcard-style names some stacks use for GAN advertising aliases. */
|
|
5
|
+
export function extraScanFiltersForKnownDeviceName(deviceName) {
|
|
6
|
+
if (!deviceName) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
const n = deviceName.trim();
|
|
10
|
+
if (!n) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
const out = [{ name: n }];
|
|
14
|
+
if (n.startsWith('GANic')) {
|
|
15
|
+
out.push({ name: 'GANicXXX' });
|
|
16
|
+
}
|
|
17
|
+
if (n.startsWith('GANi3')) {
|
|
18
|
+
out.push({ name: 'GANi3XXX' });
|
|
19
|
+
}
|
|
20
|
+
if (n.startsWith('AiCube')) {
|
|
21
|
+
out.push({ name: 'AiCubeXXX' });
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference types="web-bluetooth" />
|
|
2
|
+
/**
|
|
3
|
+
* Connect GATT (if needed) and return normalized primary service UUIDs.
|
|
4
|
+
* Uses a connect timeout and limited retries on transient failures.
|
|
5
|
+
*/
|
|
6
|
+
export declare function collectPrimaryServiceUuids(device: BluetoothDevice): Promise<ReadonlySet<string>>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { normalizeUuid } from './normalize-uuid.js';
|
|
2
|
+
const GATT_CONNECT_TIMEOUT_MS = 25_000;
|
|
3
|
+
const GATT_RETRY_MAX = 2;
|
|
4
|
+
const GATT_RETRY_BASE_DELAY_MS = 150;
|
|
5
|
+
function disconnectGattSafe(gatt) {
|
|
6
|
+
return Promise.resolve(gatt.disconnect()).catch(() => { });
|
|
7
|
+
}
|
|
8
|
+
async function delay(ms) {
|
|
9
|
+
await new Promise((r) => setTimeout(r, ms));
|
|
10
|
+
}
|
|
11
|
+
async function connectGattWithTimeout(gatt, timeoutMs) {
|
|
12
|
+
const sym = Symbol('gattTimeout');
|
|
13
|
+
try {
|
|
14
|
+
await Promise.race([
|
|
15
|
+
gatt.connect(),
|
|
16
|
+
new Promise((_, rej) => setTimeout(() => rej(sym), timeoutMs)),
|
|
17
|
+
]);
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
if (e === sym) {
|
|
21
|
+
await disconnectGattSafe(gatt);
|
|
22
|
+
throw new Error('GATT connection timeout');
|
|
23
|
+
}
|
|
24
|
+
await disconnectGattSafe(gatt).catch(() => { });
|
|
25
|
+
throw e;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Connect GATT (if needed) and return normalized primary service UUIDs.
|
|
30
|
+
* Uses a connect timeout and limited retries on transient failures.
|
|
31
|
+
*/
|
|
32
|
+
export async function collectPrimaryServiceUuids(device) {
|
|
33
|
+
const gatt = device.gatt;
|
|
34
|
+
if (!gatt) {
|
|
35
|
+
throw new Error('GATT unavailable on this device');
|
|
36
|
+
}
|
|
37
|
+
let lastErr;
|
|
38
|
+
for (let attempt = 0; attempt <= GATT_RETRY_MAX; attempt++) {
|
|
39
|
+
try {
|
|
40
|
+
await connectGattWithTimeout(gatt, GATT_CONNECT_TIMEOUT_MS);
|
|
41
|
+
const services = await gatt.getPrimaryServices();
|
|
42
|
+
const set = new Set();
|
|
43
|
+
for (const s of services) {
|
|
44
|
+
set.add(normalizeUuid(s.uuid));
|
|
45
|
+
}
|
|
46
|
+
return set;
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
lastErr = e;
|
|
50
|
+
await disconnectGattSafe(gatt);
|
|
51
|
+
if (attempt < GATT_RETRY_MAX) {
|
|
52
|
+
await delay(GATT_RETRY_BASE_DELAY_MS * (attempt + 1));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
|
|
57
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derive BLE address candidates from advertised device names (pattern-based only).
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* QiYi / XMD-style names: build candidate MACs for cryptographic probing.
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildQiYiMacCandidatesFromName(deviceName: string | null | undefined): string[];
|
|
8
|
+
/**
|
|
9
|
+
* MoYu32 / WCU name patterns: multiple third-byte variants per hardware line.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildMoyu32MacCandidatesFromName(deviceName: string | null | undefined): string[];
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derive BLE address candidates from advertised device names (pattern-based only).
|
|
3
|
+
*/
|
|
4
|
+
function pushUnique(out, seen, mac) {
|
|
5
|
+
if (seen.has(mac)) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
seen.add(mac);
|
|
9
|
+
out.push(mac);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* QiYi / XMD-style names: build candidate MACs for cryptographic probing.
|
|
13
|
+
*/
|
|
14
|
+
export function buildQiYiMacCandidatesFromName(deviceName) {
|
|
15
|
+
const out = [];
|
|
16
|
+
const seen = new Set();
|
|
17
|
+
if (!deviceName) {
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
const t = deviceName.trim();
|
|
21
|
+
const qyA = /^QY-QYSC-A-([0-9A-Fa-f]{4})$/.exec(t);
|
|
22
|
+
if (qyA) {
|
|
23
|
+
const x = qyA[1].toUpperCase();
|
|
24
|
+
pushUnique(out, seen, `CC:A2:00:00:${x.slice(0, 2)}:${x.slice(2, 4)}`);
|
|
25
|
+
}
|
|
26
|
+
const qyS = /^QY-QYSC-S-([0-9A-Fa-f]{4})$/.exec(t);
|
|
27
|
+
if (qyS) {
|
|
28
|
+
const x = qyS[1].toUpperCase();
|
|
29
|
+
const a = `${x.slice(0, 2)}:${x.slice(2, 4)}`;
|
|
30
|
+
pushUnique(out, seen, `CC:A3:00:00:${a}`);
|
|
31
|
+
pushUnique(out, seen, `CC:A3:00:01:${a}`);
|
|
32
|
+
}
|
|
33
|
+
const xmd = /^XMD-TornadoV4-i-([0-9A-Fa-f]{4})$/.exec(t);
|
|
34
|
+
if (xmd) {
|
|
35
|
+
const x = xmd[1].toUpperCase();
|
|
36
|
+
pushUnique(out, seen, `CC:A6:00:00:${x.slice(0, 2)}:${x.slice(2, 4)}`);
|
|
37
|
+
}
|
|
38
|
+
return out.slice(0, 100);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* MoYu32 / WCU name patterns: multiple third-byte variants per hardware line.
|
|
42
|
+
*/
|
|
43
|
+
export function buildMoyu32MacCandidatesFromName(deviceName) {
|
|
44
|
+
const out = [];
|
|
45
|
+
const seen = new Set();
|
|
46
|
+
if (!deviceName) {
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
const t = deviceName.trim();
|
|
50
|
+
const my32 = /^WCU_MY32_([0-9A-Fa-f]{4})$/.exec(t);
|
|
51
|
+
if (my32) {
|
|
52
|
+
const x = my32[1].toUpperCase();
|
|
53
|
+
const a = `${x.slice(0, 2)}:${x.slice(2, 4)}`;
|
|
54
|
+
for (const mid of ['00', '01', '02']) {
|
|
55
|
+
pushUnique(out, seen, `CF:30:16:${mid}:${a}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const my33 = /^WCU_MY33_([0-9A-Fa-f]{4})$/.exec(t);
|
|
59
|
+
if (my33) {
|
|
60
|
+
const x = my33[1].toUpperCase();
|
|
61
|
+
const a = `${x.slice(0, 2)}:${x.slice(2, 4)}`;
|
|
62
|
+
for (const mid of ['02', '01', '00']) {
|
|
63
|
+
pushUnique(out, seen, `CF:30:16:${mid}:${a}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return out.slice(0, 100);
|
|
67
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="web-bluetooth" />
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if notifications decrypt to plausible MoYu32 payloads for this MAC.
|
|
4
|
+
*/
|
|
5
|
+
export declare function probeMoyu32Mac(device: BluetoothDevice, mac: string, options?: {
|
|
6
|
+
timeoutMs?: number;
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
}): Promise<boolean>;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { findCharacteristic } from '../ble-utils.js';
|
|
2
|
+
import { writeGattCharacteristicValue } from '../../gatt-characteristic-write.js';
|
|
3
|
+
import { createMoyu32SessionCrypto } from './moyu32-session-crypto.js';
|
|
4
|
+
import { isValidMoYu32DecryptedPacket } from './packet-sanity.js';
|
|
5
|
+
const MOYU32_SVC = '0783b03e-7735-b5a0-1760-a305d2795cb0';
|
|
6
|
+
const MOYU32_CHR_READ = '0783b03e-7735-b5a0-1760-a305d2795cb1';
|
|
7
|
+
const MOYU32_CHR_WRITE = '0783b03e-7735-b5a0-1760-a305d2795cb2';
|
|
8
|
+
/**
|
|
9
|
+
* Returns true if notifications decrypt to plausible MoYu32 payloads for this MAC.
|
|
10
|
+
*/
|
|
11
|
+
export async function probeMoyu32Mac(device, mac, options) {
|
|
12
|
+
const timeoutMs = options?.timeoutMs ?? 2000;
|
|
13
|
+
const gatt = device.gatt;
|
|
14
|
+
if (!gatt) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
if (!gatt.connected) {
|
|
18
|
+
await gatt.connect();
|
|
19
|
+
}
|
|
20
|
+
const service = await gatt.getPrimaryService(MOYU32_SVC);
|
|
21
|
+
const chrcts = await service.getCharacteristics();
|
|
22
|
+
const readChrct = findCharacteristic(chrcts, MOYU32_CHR_READ);
|
|
23
|
+
const writeChrct = findCharacteristic(chrcts, MOYU32_CHR_WRITE);
|
|
24
|
+
if (!readChrct || !writeChrct) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const crypto = createMoyu32SessionCrypto(mac);
|
|
28
|
+
let samples = 0;
|
|
29
|
+
let good = 0;
|
|
30
|
+
let stopped = false;
|
|
31
|
+
const onNotify = (ev) => {
|
|
32
|
+
if (stopped) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const t = ev.target.value;
|
|
36
|
+
if (!t) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const raw = [];
|
|
41
|
+
for (let i = 0; i < t.byteLength; i++) {
|
|
42
|
+
raw.push(t.getUint8(i));
|
|
43
|
+
}
|
|
44
|
+
const dec = crypto.decrypt(raw);
|
|
45
|
+
samples++;
|
|
46
|
+
if (isValidMoYu32DecryptedPacket(dec)) {
|
|
47
|
+
good++;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
samples++;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
readChrct.addEventListener('characteristicvaluechanged', onNotify);
|
|
55
|
+
await readChrct.startNotifications();
|
|
56
|
+
const sendCmd = async (cmd) => {
|
|
57
|
+
const t = Array(20).fill(0);
|
|
58
|
+
t[0] = cmd;
|
|
59
|
+
const enc = crypto.encrypt(t);
|
|
60
|
+
await writeGattCharacteristicValue(writeChrct, new Uint8Array(enc).buffer);
|
|
61
|
+
};
|
|
62
|
+
const sendInitBurst = async () => {
|
|
63
|
+
await sendCmd(161);
|
|
64
|
+
await sendCmd(163);
|
|
65
|
+
await sendCmd(164);
|
|
66
|
+
};
|
|
67
|
+
try {
|
|
68
|
+
await sendInitBurst();
|
|
69
|
+
// Some MoYu32 variants do not begin steady-state status updates until
|
|
70
|
+
// they receive the same startup request burst a second time.
|
|
71
|
+
await sendInitBurst();
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
stopped = true;
|
|
75
|
+
readChrct.removeEventListener('characteristicvaluechanged', onNotify);
|
|
76
|
+
await readChrct.stopNotifications().catch(() => { });
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
const deadline = Date.now() + timeoutMs;
|
|
80
|
+
while (Date.now() < deadline && !stopped) {
|
|
81
|
+
if (options?.signal?.aborted) {
|
|
82
|
+
stopped = true;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
if (good >= 3) {
|
|
86
|
+
stopped = true;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
if (samples > 8 && good === 0) {
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
await new Promise((r) => setTimeout(r, 120));
|
|
93
|
+
}
|
|
94
|
+
stopped = true;
|
|
95
|
+
readChrct.removeEventListener('characteristicvaluechanged', onNotify);
|
|
96
|
+
await readChrct.stopNotifications().catch(() => { });
|
|
97
|
+
return good >= 3;
|
|
98
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="web-bluetooth" />
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if notifications decrypt to plausible QiYi payloads for this MAC.
|
|
4
|
+
*/
|
|
5
|
+
export declare function probeQiYiMac(device: BluetoothDevice, mac: string, options?: {
|
|
6
|
+
timeoutMs?: number;
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
}): Promise<boolean>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { ModeOfOperation } from 'aes-js';
|
|
2
|
+
import { findCharacteristic } from '../ble-utils.js';
|
|
3
|
+
import { writeGattCharacteristicValue } from '../../gatt-characteristic-write.js';
|
|
4
|
+
import { isValidQiYiDecryptedPacket } from './packet-sanity.js';
|
|
5
|
+
const UUID_SUFFIX = '-0000-1000-8000-00805f9b34fb';
|
|
6
|
+
const QIYI_SVC = '0000fff0' + UUID_SUFFIX;
|
|
7
|
+
const QIYI_CHR = '0000fff6' + UUID_SUFFIX;
|
|
8
|
+
const QIYI_KEY = [87, 177, 249, 171, 205, 90, 232, 167, 156, 185, 140, 231, 87, 140, 81, 8];
|
|
9
|
+
function crc16modbus(data) {
|
|
10
|
+
let crc = 0xffff;
|
|
11
|
+
for (let i = 0; i < data.length; i++) {
|
|
12
|
+
crc ^= data[i];
|
|
13
|
+
for (let j = 0; j < 8; j++) {
|
|
14
|
+
crc = (crc & 1) > 0 ? (crc >> 1) ^ 0xa001 : crc >> 1;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return crc;
|
|
18
|
+
}
|
|
19
|
+
/** Same wire as QiYiConnection.sendHello → sendMessage (wake cube for MAC validation). */
|
|
20
|
+
function buildEncryptedQiYiHello(mac) {
|
|
21
|
+
const macBytes = mac.split(/[:-\s]+/).map((x) => parseInt(x, 16));
|
|
22
|
+
const content = [0x00, 0x6b, 0x01, 0x00, 0x00, 0x22, 0x06, 0x00, 0x02, 0x08, 0x00];
|
|
23
|
+
for (let i = 5; i >= 0; i--) {
|
|
24
|
+
content.push(macBytes[i] ?? 0);
|
|
25
|
+
}
|
|
26
|
+
const msg = [0xfe];
|
|
27
|
+
msg.push(4 + content.length);
|
|
28
|
+
for (let k = 0; k < content.length; k++) {
|
|
29
|
+
msg.push(content[k]);
|
|
30
|
+
}
|
|
31
|
+
const crc = crc16modbus(msg);
|
|
32
|
+
msg.push(crc & 0xff, crc >> 8);
|
|
33
|
+
const npad = (16 - (msg.length % 16)) % 16;
|
|
34
|
+
for (let p = 0; p < npad; p++) {
|
|
35
|
+
msg.push(0);
|
|
36
|
+
}
|
|
37
|
+
return encryptBlocks(new Uint8Array(msg));
|
|
38
|
+
}
|
|
39
|
+
function encryptBlocks(plain) {
|
|
40
|
+
const cipher = new ModeOfOperation.ecb(new Uint8Array(QIYI_KEY));
|
|
41
|
+
const out = new Uint8Array(plain.length);
|
|
42
|
+
for (let i = 0; i < plain.length; i += 16) {
|
|
43
|
+
const block = cipher.encrypt(plain.subarray(i, i + 16));
|
|
44
|
+
out.set(block, i);
|
|
45
|
+
}
|
|
46
|
+
return out.buffer;
|
|
47
|
+
}
|
|
48
|
+
function decryptBlocks(enc) {
|
|
49
|
+
const view = enc instanceof ArrayBuffer ? new Uint8Array(enc) : new Uint8Array(enc.buffer, enc.byteOffset, enc.byteLength);
|
|
50
|
+
const cipher = new ModeOfOperation.ecb(new Uint8Array(QIYI_KEY));
|
|
51
|
+
const out = new Uint8Array(view.length);
|
|
52
|
+
for (let i = 0; i < view.length; i += 16) {
|
|
53
|
+
const block = cipher.decrypt(view.subarray(i, i + 16));
|
|
54
|
+
out.set(block, i);
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Returns true if notifications decrypt to plausible QiYi payloads for this MAC.
|
|
60
|
+
*/
|
|
61
|
+
export async function probeQiYiMac(device, mac, options) {
|
|
62
|
+
const timeoutMs = options?.timeoutMs ?? 3000;
|
|
63
|
+
const gatt = device.gatt;
|
|
64
|
+
if (!gatt) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
if (!gatt.connected) {
|
|
68
|
+
await gatt.connect();
|
|
69
|
+
}
|
|
70
|
+
const service = await gatt.getPrimaryService(QIYI_SVC);
|
|
71
|
+
const chrcts = await service.getCharacteristics();
|
|
72
|
+
const chrct = findCharacteristic(chrcts, QIYI_CHR);
|
|
73
|
+
if (!chrct) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
let stopped = false;
|
|
77
|
+
let ok = false;
|
|
78
|
+
const onNotify = (ev) => {
|
|
79
|
+
if (stopped) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const v = ev.target.value;
|
|
83
|
+
if (!v) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const raw = new Uint8Array(v.buffer, v.byteOffset, v.byteLength);
|
|
88
|
+
const dec = decryptBlocks(raw);
|
|
89
|
+
if (isValidQiYiDecryptedPacket(dec)) {
|
|
90
|
+
ok = true;
|
|
91
|
+
stopped = true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
/* ignore */
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
chrct.addEventListener('characteristicvaluechanged', onNotify);
|
|
99
|
+
await chrct.startNotifications();
|
|
100
|
+
const wake = () => {
|
|
101
|
+
if (stopped) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
void writeGattCharacteristicValue(chrct, buildEncryptedQiYiHello(mac)).catch(() => { });
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
/* ignore */
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const iv = setInterval(wake, 100);
|
|
112
|
+
wake();
|
|
113
|
+
await new Promise((resolve) => {
|
|
114
|
+
const maxTimer = setTimeout(() => resolve(), timeoutMs);
|
|
115
|
+
const poll = setInterval(() => {
|
|
116
|
+
if (ok || options?.signal?.aborted) {
|
|
117
|
+
clearInterval(poll);
|
|
118
|
+
clearTimeout(maxTimer);
|
|
119
|
+
resolve();
|
|
120
|
+
}
|
|
121
|
+
}, 40);
|
|
122
|
+
});
|
|
123
|
+
clearInterval(iv);
|
|
124
|
+
stopped = true;
|
|
125
|
+
chrct.removeEventListener('characteristicvaluechanged', onNotify);
|
|
126
|
+
await chrct.stopNotifications().catch(() => { });
|
|
127
|
+
return ok;
|
|
128
|
+
}
|
package/bluetooth/vendor/smartcube-web-bluetooth/smartcube/attachment/moyu32-session-crypto.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ModeOfOperation } from 'aes-js';
|
|
2
|
+
const BASE_KEY = [21, 119, 58, 92, 103, 14, 45, 31, 23, 103, 42, 19, 155, 103, 82, 87];
|
|
3
|
+
const BASE_IV = [17, 35, 38, 37, 134, 42, 44, 59, 85, 6, 127, 49, 126, 103, 33, 87];
|
|
4
|
+
function macSegments(mac) {
|
|
5
|
+
const parts = mac.split(/[:-\s]+/).map((x) => parseInt(x, 16));
|
|
6
|
+
if (parts.length < 6 || parts.some((n) => Number.isNaN(n))) {
|
|
7
|
+
throw new Error('Invalid MAC');
|
|
8
|
+
}
|
|
9
|
+
return parts.slice(0, 6);
|
|
10
|
+
}
|
|
11
|
+
/** MoYu32 AES session crypto keyed by device address (same derivation as protocol driver). */
|
|
12
|
+
export function createMoyu32SessionCrypto(mac) {
|
|
13
|
+
const t = macSegments(mac);
|
|
14
|
+
const key = BASE_KEY.slice();
|
|
15
|
+
const iv = BASE_IV.slice();
|
|
16
|
+
for (let i = 0; i < 6; i++) {
|
|
17
|
+
key[i] = (key[i] + t[5 - i]) % 255;
|
|
18
|
+
iv[i] = (iv[i] + t[5 - i]) % 255;
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
decrypt(raw) {
|
|
22
|
+
const cipher = new ModeOfOperation.ecb(new Uint8Array(key));
|
|
23
|
+
const ret = raw.slice();
|
|
24
|
+
if (ret.length > 16) {
|
|
25
|
+
const offset = ret.length - 16;
|
|
26
|
+
const block = cipher.decrypt(new Uint8Array(ret.slice(offset)));
|
|
27
|
+
for (let i = 0; i < 16; i++) {
|
|
28
|
+
ret[i + offset] = block[i] ^ iv[i];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const block = cipher.decrypt(new Uint8Array(ret.slice(0, 16)));
|
|
32
|
+
for (let i = 0; i < 16; i++) {
|
|
33
|
+
ret[i] = block[i] ^ iv[i];
|
|
34
|
+
}
|
|
35
|
+
return ret;
|
|
36
|
+
},
|
|
37
|
+
encrypt(data) {
|
|
38
|
+
const ret = data.slice();
|
|
39
|
+
const cipher = new ModeOfOperation.ecb(new Uint8Array(key));
|
|
40
|
+
for (let i = 0; i < 16; i++) {
|
|
41
|
+
ret[i] ^= iv[i];
|
|
42
|
+
}
|
|
43
|
+
const block = cipher.encrypt(new Uint8Array(ret.slice(0, 16)));
|
|
44
|
+
for (let i = 0; i < 16; i++) {
|
|
45
|
+
ret[i] = block[i];
|
|
46
|
+
}
|
|
47
|
+
if (ret.length > 16) {
|
|
48
|
+
const offset = ret.length - 16;
|
|
49
|
+
for (let i = 0; i < 16; i++) {
|
|
50
|
+
ret[i + offset] ^= iv[i];
|
|
51
|
+
}
|
|
52
|
+
const block2 = cipher.encrypt(new Uint8Array(ret.slice(offset, offset + 16)));
|
|
53
|
+
for (let i = 0; i < 16; i++) {
|
|
54
|
+
ret[i + offset] = block2[i];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return ret;
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-decrypt sanity checks for MAC candidate probing.
|
|
3
|
+
*/
|
|
4
|
+
/** Validates decrypted MoYu32 notification bitstream. */
|
|
5
|
+
export declare function isValidMoYu32DecryptedPacket(bytes: number[]): boolean;
|
|
6
|
+
/** Validates decrypted QiYi notification payload. */
|
|
7
|
+
export declare function isValidQiYiDecryptedPacket(e: Uint8Array): boolean;
|