summaryrefslogtreecommitdiffhomepage
path: root/index.html
diff options
context:
space:
mode:
authorLi Zhineng <[email protected]>2025-06-12 22:19:44 +0800
committerLi Zhineng <[email protected]>2025-06-12 22:19:44 +0800
commit29c8378dca07b3731b150362a36f71a7e5c35337 (patch)
treed2543238a0471135d84006424473c104056927b1 /index.html
parent6e429bfaa2baf196fbbc312bb292351cadf4b08f (diff)
downloadsetup-29c8378dca07b3731b150362a36f71a7e5c35337.tar.gz
setup-29c8378dca07b3731b150362a36f71a7e5c35337.zip
main.mjs
Diffstat (limited to 'index.html')
-rw-r--r--index.html176
1 files changed, 1 insertions, 175 deletions
diff --git a/index.html b/index.html
index 1e7ffe6..e9b2647 100644
--- a/index.html
+++ b/index.html
@@ -1,6 +1,7 @@
<html>
<head>
<title>Setup AIRMX device</title>
+ <script defer src="main.mjs"></script>
</head>
<body>
<h1>Setup your AIRMX device</h1>
@@ -9,180 +10,5 @@
Connect
</button>
</div>
- <script>
- const DEVICE_NAME = 'AIRMX Pro'
- const MAIN_SERVICE_UUID = '22210000-554a-4546-5542-46534450464d'
- const WRITE_CHAR_UUID = '22210001-554a-4546-5542-46534450464d'
- const NOTIFY_CHAR_UUID = '22210002-554a-4546-5542-46534450464d'
-
- class Dispatcher {
- #characteristic
- #sequenceNumber = 1
- #chunkSize = 16
-
- constructor(characteristic) {
- this.#characteristic = characteristic
- }
-
- async dispatch(command) {
- const data = this.#chunk(command.payload, command)
-
- for (let chunk of data) {
- console.log(`Sending chunk: ${Array.from(chunk).map(b => b.toString(16).padStart(2, '0')).join(' ')}`)
- await this.#characteristic.writeValueWithResponse(chunk)
- await delay(500)
- }
- }
-
- #chunk(data, command) {
- const packets = this.#chunked(data, this.#chunkSize)
- const total = packets.length
-
- if (total === 0) {
- return [
- this.#packetHeader(
- this.#sequenceNumber++, 1, 1, // 1 of 1 packet
- command.commandId
- )
- ]
- }
-
- return packets.map((chunk, index) => {
- return new Uint8Array([
- ...this.#packetHeader(
- this.#sequenceNumber++, index + 1, total,
- command.commandId
- ),
- ...chunk
- ])
- })
- }
-
- /**
- * Splits an array into chunks of `size`.
- *
- * @param {Uint8Array} data - The array of 8-bit unsigned integers.
- * @param {number} size - The size of each chunk.
- */
- #chunked(data, size) {
- const packets = []
-
- for (let i = 0; i < data.length; i += size) {
- packets.push(data.slice(i, i + size))
- }
-
- return packets
- }
-
- #packetHeader(sequenceNumber, currentPacket, totalPacket, commandId) {
- return new Uint8Array([
- sequenceNumber,
- currentPacket << 4 | totalPacket,
- 0x00, // Unencrypted flag
- commandId
- ])
- }
- }
-
- class Command {
- get commandId() {
- throw new Error('The command ID does not exist.')
- }
-
- get payload() {
- throw new Error('The payload does not exist.')
- }
- }
-
- class HandshakeCommand extends Command {
- get commandId() {
- return 0x0b
- }
-
- get payload() {
- return new Uint8Array([
- 0x08, // The storage size of the token
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Token: 0
- 0x05, // The length of the version
- 0x31, 0x2e, 0x30, 0x2e, 0x30 // Version: 1.0.0
- ])
- }
- }
-
- class ConfigureWifiCommand extends Command {
- #ssid
- #password
-
- constructor(ssid, password) {
- super()
- this.#ssid = ssid
- this.#password = password
- }
-
- get commandId() {
- return 0x15
- }
-
- get payload() {
- const encoder = new TextEncoder()
- const ssid = encoder.encode(this.#ssid)
- const password = encoder.encode(this.#password)
-
- return new Uint8Array([
- ssid.length, ...ssid,
- password.length, ...password
- ])
- }
- }
-
- class RequestIdentityCommand extends Command {
- get commandId() {
- return 0x16
- }
-
- get payload() {
- return new Uint8Array([
- //
- ])
- }
- }
-
- async function delay(ms) {
- return new Promise(resolve => setTimeout(resolve, ms))
- }
-
- async function connectToDevice() {
- const device = await navigator.bluetooth.requestDevice({
- filters: [{ name: DEVICE_NAME }],
- optionalServices: [MAIN_SERVICE_UUID]
- })
-
- const server = await device.gatt.connect()
- const service = await server.getPrimaryService(MAIN_SERVICE_UUID)
-
- const writeChar = await service.getCharacteristic(WRITE_CHAR_UUID)
- const notifyChar = await service.getCharacteristic(NOTIFY_CHAR_UUID)
-
- await notifyChar.startNotifications()
- notifyChar.addEventListener('characteristicvaluechanged', handleDeviceResponse)
-
- const dispatcher = new Dispatcher(writeChar)
- await dispatcher.dispatch(new HandshakeCommand())
- await dispatcher.dispatch(new ConfigureWifiCommand('<ssid>', '<password>'))
- await dispatcher.dispatch(new RequestIdentityCommand())
- }
-
- function handleDeviceResponse(event) {
- const value = event.target.value
- const receivedBytes = []
- for (let i = 0; i < value.byteLength; i++) {
- receivedBytes.push(value.getUint8(i).toString(16).padStart(2, '0'))
- }
- console.log(`Received data from device: ${receivedBytes.join(' ')}`)
- }
-
- const connect = document.getElementById('connect')
- connect.addEventListener('click', connectToDevice)
- </script>
</body>
</html>