summaryrefslogtreecommitdiffhomepage
path: root/index.html
blob: b04539b54cc3147ee507aef3c8d775b22cc1aeee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<html>
    <head>
        <title>Setup AIRMX device</title>
    </head>
    <body>
        <h1>Setup your AIRMX device</h1>
        <div>
            <button id="connect" type="button">
                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'

            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)

                // 1. Enable notifications
                await notifyChar.startNotifications()
                notifyChar.addEventListener('characteristicvaluechanged', handleDeviceResponse)

                await delay(500)

                // 2. Send the first bind command
                await sendBindCommand(writeChar)
            }

            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(' ')}`)
            }

            async function sendBindCommand(writeChar) {
                const handshakePacket = new Uint8Array([
                    // --- 4-byte Header ---
                    0x01, // Sequence Number: 1
                    0x11, // Packet Info: (Packet 1 of 1)
                    0x00, // Command ID: 11 (Big Endian Short, MSB)
                    0x0B, // Command ID: 11 (Big Endian Short, LSB)

                    // --- 15-byte Payload ---
                    0x08, // Hardcoded first byte of payload
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Token (as 0L)
                    0x05, // Length of version string "1.0.0"
                    0x31, 0x2e, 0x30, 0x2e, 0x30  // ASCII for "1.0.0"
                ])

                await sendRawData(writeChar, handshakePacket)
            }

            async function sendRawData(characteristic, data) {
                const chunkSize = 20
                for (let i = 0; i < data.length; i += chunkSize) {
                    const chunk = data.slice(i, i + chunkSize)
                    console.log(`Sending chunk: ${Array.from(chunk).map(b => b.toString(16).padStart(2, '0')).join(' ')}`)
                    await characteristic.writeValueWithResponse(chunk)
                }
            }

            const connect = document.getElementById('connect')
            connect.addEventListener('click', connectToDevice)
        </script>
    </body>
</html>