diff --git a/captures/vxe-r1-pro/receiver-atk-hub-profiles.txt b/captures/vxe-r1-pro/receiver-atk-hub-profiles.txt new file mode 100644 index 00000000..4a3aca91 --- /dev/null +++ b/captures/vxe-r1-pro/receiver-atk-hub-profiles.txt @@ -0,0 +1,538 @@ +# ATK HUB (v3-hub.atk.store) switching configuration banks on a VXE R1 Pro, +# firmware 1.20, through the 0x3554:0xf58a 1K dongle. Same format and redactions +# as receiver-atk-hub.txt. The last two marks apply a host-stored "computer +# config", which selects bank 4 and rewrites its rows. + +=== changing to config 2 (there seems to be 4 configs on board). (20505 ms) + 22117 out 3554:f58a id=8 0f 00 00 00 01 01 00 00 00 00 00 00 00 00 00 3c + 22219 in 3554:f58a id=8 0f 00 00 00 01 01 00 00 00 00 00 00 00 00 00 3c + 22225 in 3554:f58a id=8 0a 00 00 00 0a 04 00 00 00 00 00 00 00 00 00 35 + 23219 out 3554:f58a id=8 08 00 00 60 08 00 00 00 00 00 00 00 00 00 00 dd + 23223 out 3554:f58a id=8 08 00 00 68 08 00 00 00 00 00 00 00 00 00 00 d5 + 23223 in 3554:f58a id=8 08 00 00 60 08 01 01 00 53 01 02 00 52 00 00 33 + 23227 out 3554:f58a id=8 08 00 00 70 08 00 00 00 00 00 00 00 00 00 00 cd + 23227 in 3554:f58a id=8 08 00 00 68 08 01 04 00 50 01 08 00 4c 00 00 2b + 23231 in 3554:f58a id=8 08 00 00 70 08 01 10 00 44 02 01 00 52 00 00 23 + 23241 out 3554:f58a id=8 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3f + 23251 in 3554:f58a id=8 0e 00 00 00 01 01 00 00 00 00 00 00 00 00 00 3d + 23261 out 3554:f58a id=8 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3b + 23265 in 3554:f58a id=8 12 00 00 00 02 01 20 00 00 00 00 00 00 00 00 18 + 23276 out 3554:f58a id=8 08 00 00 4c 08 00 00 00 00 00 00 00 00 00 00 f1 + 23279 in 3554:f58a id=8 08 00 00 4c 08 02 53 80 d5 03 52 00 55 00 00 9d + 23291 out 3554:f58a id=8 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 49 + 23295 in 3554:f58a id=8 04 00 00 00 02 14 00 0d f6 00 00 00 00 00 00 30 + 23307 out 3554:f58a id=8 08 00 01 00 0a 00 00 00 00 00 00 00 00 00 00 3a + 23311 out 3554:f58a id=8 08 00 01 0a 0a 00 00 00 00 00 00 00 00 00 00 30 + 23311 in 3554:f58a id=8 08 00 01 00 0a ff ff ff ff ff ff ff ff ff ff 44 + 23314 out 3554:f58a id=8 08 00 01 20 0a 00 00 00 00 00 00 00 00 00 00 1a + 23314 in 3554:f58a id=8 08 00 01 0a 0a ff ff ff ff ff ff ff ff ff ff 3a + 23317 out 3554:f58a id=8 08 00 01 2a 0a 00 00 00 00 00 00 00 00 00 00 10 + 23317 in 3554:f58a id=8 08 00 01 20 0a ff ff ff ff ff ff ff ff ff ff 24 + 23320 out 3554:f58a id=8 08 00 01 40 0a 00 00 00 00 00 00 00 00 00 00 fa + 23320 in 3554:f58a id=8 08 00 01 2a 0a ff ff ff ff ff ff ff ff ff ff 1a + 23323 out 3554:f58a id=8 08 00 01 4a 0a 00 00 00 00 00 00 00 00 00 00 f0 + 23323 in 3554:f58a id=8 08 00 01 40 0a ff ff ff ff ff ff ff ff ff ff 04 + 23326 out 3554:f58a id=8 08 00 01 60 0a 00 00 00 00 00 00 00 00 00 00 da + 23326 in 3554:f58a id=8 08 00 01 4a 0a ff ff ff ff ff ff ff ff ff ff fa + 23329 out 3554:f58a id=8 08 00 01 6a 0a 00 00 00 00 00 00 00 00 00 00 d0 + 23329 in 3554:f58a id=8 08 00 01 60 0a ff ff ff ff ff ff ff ff ff ff e4 + 23332 out 3554:f58a id=8 08 00 01 80 0a 00 00 00 00 00 00 00 00 00 00 ba + 23332 in 3554:f58a id=8 08 00 01 6a 0a ff ff ff ff ff ff ff ff ff ff da + 23335 out 3554:f58a id=8 08 00 01 8a 0a 00 00 00 00 00 00 00 00 00 00 b0 + 23335 in 3554:f58a id=8 08 00 01 80 0a ff ff ff ff ff ff ff ff ff ff c4 + 23338 out 3554:f58a id=8 08 00 01 a0 0a 00 00 00 00 00 00 00 00 00 00 9a + 23338 in 3554:f58a id=8 08 00 01 8a 0a ff ff ff ff ff ff ff ff ff ff ba + 23341 out 3554:f58a id=8 08 00 01 aa 0a 00 00 00 00 00 00 00 00 00 00 90 + 23341 in 3554:f58a id=8 08 00 01 a0 0a ff ff ff ff ff ff ff ff ff ff a4 + 23345 in 3554:f58a id=8 08 00 01 aa 0a ff ff ff ff ff ff ff ff ff ff 9a + 23355 out 3554:f58a id=8 08 00 00 a9 0a 00 00 00 00 00 00 00 00 00 00 92 + 23359 out 3554:f58a id=8 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3d + 23359 in 3554:f58a id=8 08 00 00 a9 0a 08 4d 01 54 06 4f 00 55 00 55 e9 + 23362 out 3554:f58a id=8 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 36 + 23362 in 3554:f58a id=8 10 00 00 00 03 02 08 4b 00 00 00 00 00 00 00 e5 + 23365 out 3554:f58a id=8 08 00 00 0a 02 00 00 00 00 00 00 00 00 00 00 39 + 23365 in 3554:f58a id=8 17 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2c + 23368 out 3554:f58a id=8 1d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 + 23368 in 3554:f58a id=8 08 00 00 0a 02 01 54 00 00 00 00 00 00 00 00 e4 + 23369 out 3554:f58a id=8 08 00 00 b5 06 00 00 00 00 00 00 00 00 00 00 8a + 23369 in 3554:f58a id=8 1d 01 00 00 00 00 00 00 00 00 00 00 00 00 00 2f + 23372 out 3554:f58a id=8 08 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 3b + 23372 in 3554:f58a id=8 08 00 00 b5 06 00 55 06 4f 00 55 00 00 00 00 8b + 23375 out 3554:f58a id=8 08 00 00 bd 04 00 00 00 00 00 00 00 00 00 00 84 + 23375 in 3554:f58a id=8 08 00 00 00 0a 01 54 04 51 01 54 00 55 00 55 92 + 23378 out 3554:f58a id=8 08 00 00 0c 08 00 00 00 00 00 00 00 00 00 00 31 + 23378 in 3554:f58a id=8 08 00 00 bd 04 ff ff ff ff 00 00 00 00 00 00 88 + 23381 out 3554:f58a id=8 08 00 00 14 08 00 00 00 00 00 00 00 00 00 00 29 + 23381 in 3554:f58a id=8 08 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 87 + 23385 out 3554:f58a id=8 08 00 00 1c 08 00 00 00 00 00 00 00 00 00 00 21 + 23385 in 3554:f58a id=8 08 00 00 14 08 1f 1f 00 17 3f 3f 00 d7 00 00 7f + 23387 out 3554:f58a id=8 08 00 00 24 08 00 00 00 00 00 00 00 00 00 00 19 + 23387 in 3554:f58a id=8 08 00 00 1c 08 3f 3f 00 d7 3f 3f 00 d7 00 00 77 + 23390 out 3554:f58a id=8 08 00 00 2c 08 00 00 00 00 00 00 00 00 00 00 11 + 23390 in 3554:f58a id=8 08 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 6f + 23393 out 3554:f58a id=8 08 00 00 34 08 00 00 00 00 00 00 00 00 00 00 09 + 23393 in 3554:f58a id=8 08 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 67 + 23396 out 3554:f58a id=8 08 00 00 3c 08 00 00 00 00 00 00 00 00 00 00 01 + 23396 in 3554:f58a id=8 08 00 00 34 08 00 00 ff 56 ff 00 ff 57 00 00 5f + 23399 out 3554:f58a id=8 08 00 00 44 08 00 00 00 00 00 00 00 00 00 00 f9 + 23399 in 3554:f58a id=8 08 00 00 3c 08 ff 00 ff 57 ff 00 ff 57 00 00 57 + 23402 out 3554:f58a id=8 08 00 00 e3 02 00 00 00 00 00 00 00 00 00 00 60 + 23402 in 3554:f58a id=8 08 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 4f + 23405 out 3554:f58a id=8 08 00 1b 4c 04 00 00 00 00 00 00 00 00 00 00 da + 23405 in 3554:f58a id=8 08 00 00 e3 02 ff ff 00 00 00 00 00 00 00 00 62 + 23408 in 3554:f58a id=8 08 00 1b 4c 04 ff ff ff ff 00 00 00 00 00 00 de + +=== changing to config 3 (35032 ms) + 36406 out 3554:f58a id=8 0f 00 00 00 01 02 00 00 00 00 00 00 00 00 00 3b + 36502 in 3554:f58a id=8 0f 00 00 00 01 02 00 00 00 00 00 00 00 00 00 3b + 36509 in 3554:f58a id=8 0a 00 00 00 0a 04 00 00 00 00 00 00 00 00 00 35 + 37507 out 3554:f58a id=8 08 00 00 60 08 00 00 00 00 00 00 00 00 00 00 dd + 37511 out 3554:f58a id=8 08 00 00 68 08 00 00 00 00 00 00 00 00 00 00 d5 + 37511 in 3554:f58a id=8 08 00 00 60 08 01 01 00 53 01 02 00 52 00 00 33 + 37514 out 3554:f58a id=8 08 00 00 70 08 00 00 00 00 00 00 00 00 00 00 cd + 37514 in 3554:f58a id=8 08 00 00 68 08 01 04 00 50 01 08 00 4c 00 00 2b + 37517 in 3554:f58a id=8 08 00 00 70 08 01 10 00 44 02 01 00 52 00 00 23 + 37529 out 3554:f58a id=8 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3f + 37533 in 3554:f58a id=8 0e 00 00 00 01 02 00 00 00 00 00 00 00 00 00 3c + 37544 out 3554:f58a id=8 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3b + 37548 in 3554:f58a id=8 12 00 00 00 02 01 20 00 00 00 00 00 00 00 00 18 + 37559 out 3554:f58a id=8 08 00 00 4c 08 00 00 00 00 00 00 00 00 00 00 f1 + 37563 in 3554:f58a id=8 08 00 00 4c 08 02 53 80 d5 03 52 00 55 00 00 9d + 37575 out 3554:f58a id=8 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 49 + 37579 in 3554:f58a id=8 04 00 00 00 02 14 00 0d f6 00 00 00 00 00 00 30 + 37589 out 3554:f58a id=8 08 00 01 00 0a 00 00 00 00 00 00 00 00 00 00 3a + 37594 out 3554:f58a id=8 08 00 01 0a 0a 00 00 00 00 00 00 00 00 00 00 30 + 37594 in 3554:f58a id=8 08 00 01 00 0a ff ff ff ff ff ff ff ff ff ff 44 + 37597 out 3554:f58a id=8 08 00 01 20 0a 00 00 00 00 00 00 00 00 00 00 1a + 37597 in 3554:f58a id=8 08 00 01 0a 0a ff ff ff ff ff ff ff ff ff ff 3a + 37601 out 3554:f58a id=8 08 00 01 2a 0a 00 00 00 00 00 00 00 00 00 00 10 + 37601 in 3554:f58a id=8 08 00 01 20 0a ff ff ff ff ff ff ff ff ff ff 24 + 37605 out 3554:f58a id=8 08 00 01 40 0a 00 00 00 00 00 00 00 00 00 00 fa + 37605 in 3554:f58a id=8 08 00 01 2a 0a ff ff ff ff ff ff ff ff ff ff 1a + 37608 out 3554:f58a id=8 08 00 01 4a 0a 00 00 00 00 00 00 00 00 00 00 f0 + 37608 in 3554:f58a id=8 08 00 01 40 0a ff ff ff ff ff ff ff ff ff ff 04 + 37612 out 3554:f58a id=8 08 00 01 60 0a 00 00 00 00 00 00 00 00 00 00 da + 37612 in 3554:f58a id=8 08 00 01 4a 0a ff ff ff ff ff ff ff ff ff ff fa + 37615 out 3554:f58a id=8 08 00 01 6a 0a 00 00 00 00 00 00 00 00 00 00 d0 + 37615 in 3554:f58a id=8 08 00 01 60 0a ff ff ff ff ff ff ff ff ff ff e4 + 37618 out 3554:f58a id=8 08 00 01 80 0a 00 00 00 00 00 00 00 00 00 00 ba + 37618 in 3554:f58a id=8 08 00 01 6a 0a ff ff ff ff ff ff ff ff ff ff da + 37621 out 3554:f58a id=8 08 00 01 8a 0a 00 00 00 00 00 00 00 00 00 00 b0 + 37621 in 3554:f58a id=8 08 00 01 80 0a ff ff ff ff ff ff ff ff ff ff c4 + 37624 out 3554:f58a id=8 08 00 01 a0 0a 00 00 00 00 00 00 00 00 00 00 9a + 37624 in 3554:f58a id=8 08 00 01 8a 0a ff ff ff ff ff ff ff ff ff ff ba + 37627 out 3554:f58a id=8 08 00 01 aa 0a 00 00 00 00 00 00 00 00 00 00 90 + 37627 in 3554:f58a id=8 08 00 01 a0 0a ff ff ff ff ff ff ff ff ff ff a4 + 37631 in 3554:f58a id=8 08 00 01 aa 0a ff ff ff ff ff ff ff ff ff ff 9a + 37642 out 3554:f58a id=8 08 00 00 a9 0a 00 00 00 00 00 00 00 00 00 00 92 + 37646 out 3554:f58a id=8 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3d + 37646 in 3554:f58a id=8 08 00 00 a9 0a 08 4d 01 54 06 4f 00 55 00 55 e9 + 37649 out 3554:f58a id=8 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 36 + 37649 in 3554:f58a id=8 10 00 00 00 03 02 08 4b 00 00 00 00 00 00 00 e5 + 37652 out 3554:f58a id=8 08 00 00 0a 02 00 00 00 00 00 00 00 00 00 00 39 + 37652 in 3554:f58a id=8 17 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2c + 37655 out 3554:f58a id=8 1d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 + 37655 in 3554:f58a id=8 08 00 00 0a 02 01 54 00 00 00 00 00 00 00 00 e4 + 37656 out 3554:f58a id=8 08 00 00 b5 06 00 00 00 00 00 00 00 00 00 00 8a + 37656 in 3554:f58a id=8 1d 01 00 00 00 00 00 00 00 00 00 00 00 00 00 2f + 37660 out 3554:f58a id=8 08 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 3b + 37660 in 3554:f58a id=8 08 00 00 b5 06 00 55 06 4f 00 55 00 00 00 00 8b + 37663 out 3554:f58a id=8 08 00 00 bd 04 00 00 00 00 00 00 00 00 00 00 84 + 37663 in 3554:f58a id=8 08 00 00 00 0a 01 54 04 51 01 54 00 55 00 55 92 + 37666 out 3554:f58a id=8 08 00 00 0c 08 00 00 00 00 00 00 00 00 00 00 31 + 37666 in 3554:f58a id=8 08 00 00 bd 04 ff ff ff ff 00 00 00 00 00 00 88 + 37669 out 3554:f58a id=8 08 00 00 14 08 00 00 00 00 00 00 00 00 00 00 29 + 37669 in 3554:f58a id=8 08 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 87 + 37672 out 3554:f58a id=8 08 00 00 1c 08 00 00 00 00 00 00 00 00 00 00 21 + 37672 in 3554:f58a id=8 08 00 00 14 08 1f 1f 00 17 3f 3f 00 d7 00 00 7f + 37675 out 3554:f58a id=8 08 00 00 24 08 00 00 00 00 00 00 00 00 00 00 19 + 37675 in 3554:f58a id=8 08 00 00 1c 08 3f 3f 00 d7 3f 3f 00 d7 00 00 77 + 37678 out 3554:f58a id=8 08 00 00 2c 08 00 00 00 00 00 00 00 00 00 00 11 + 37678 in 3554:f58a id=8 08 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 6f + 37681 out 3554:f58a id=8 08 00 00 34 08 00 00 00 00 00 00 00 00 00 00 09 + 37681 in 3554:f58a id=8 08 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 67 + 37684 out 3554:f58a id=8 08 00 00 3c 08 00 00 00 00 00 00 00 00 00 00 01 + 37684 in 3554:f58a id=8 08 00 00 34 08 00 00 ff 56 ff 00 ff 57 00 00 5f + 37688 out 3554:f58a id=8 08 00 00 44 08 00 00 00 00 00 00 00 00 00 00 f9 + 37688 in 3554:f58a id=8 08 00 00 3c 08 ff 00 ff 57 ff 00 ff 57 00 00 57 + 37691 out 3554:f58a id=8 08 00 00 e3 02 00 00 00 00 00 00 00 00 00 00 60 + 37691 in 3554:f58a id=8 08 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 4f + 37694 out 3554:f58a id=8 08 00 1b 4c 04 00 00 00 00 00 00 00 00 00 00 da + 37694 in 3554:f58a id=8 08 00 00 e3 02 ff ff 00 00 00 00 00 00 00 00 62 + 37697 in 3554:f58a id=8 08 00 1b 4c 04 ff ff ff ff 00 00 00 00 00 00 de + +=== to 4 (40947 ms) + 42230 out 3554:f58a id=8 0f 00 00 00 01 03 00 00 00 00 00 00 00 00 00 3a + 42327 in 3554:f58a id=8 0f 00 00 00 01 03 00 00 00 00 00 00 00 00 00 3a + 42334 in 3554:f58a id=8 0a 00 00 00 0a 04 00 00 00 00 00 00 00 00 00 35 + 43332 out 3554:f58a id=8 08 00 00 60 08 00 00 00 00 00 00 00 00 00 00 dd + 43336 out 3554:f58a id=8 08 00 00 68 08 00 00 00 00 00 00 00 00 00 00 d5 + 43336 in 3554:f58a id=8 08 00 00 60 08 01 01 00 53 01 02 00 52 00 00 33 + 43340 out 3554:f58a id=8 08 00 00 70 08 00 00 00 00 00 00 00 00 00 00 cd + 43340 in 3554:f58a id=8 08 00 00 68 08 01 04 00 50 01 08 00 4c 00 00 2b + 43344 in 3554:f58a id=8 08 00 00 70 08 01 10 00 44 02 01 00 52 00 00 23 + 43355 out 3554:f58a id=8 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3f + 43359 in 3554:f58a id=8 0e 00 00 00 01 03 00 00 00 00 00 00 00 00 00 3b + 43370 out 3554:f58a id=8 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3b + 43375 in 3554:f58a id=8 12 00 00 00 02 01 20 00 00 00 00 00 00 00 00 18 + 43386 out 3554:f58a id=8 08 00 00 4c 08 00 00 00 00 00 00 00 00 00 00 f1 + 43391 in 3554:f58a id=8 08 00 00 4c 08 02 53 80 d5 03 52 00 55 00 00 9d + 43403 out 3554:f58a id=8 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 49 + 43407 in 3554:f58a id=8 04 00 00 00 02 14 00 0d f2 00 00 00 00 00 00 34 + 43419 out 3554:f58a id=8 08 00 01 00 0a 00 00 00 00 00 00 00 00 00 00 3a + 43423 out 3554:f58a id=8 08 00 01 0a 0a 00 00 00 00 00 00 00 00 00 00 30 + 43424 in 3554:f58a id=8 08 00 01 00 0a ff ff ff ff ff ff ff ff ff ff 44 + 43429 out 3554:f58a id=8 08 00 01 20 0a 00 00 00 00 00 00 00 00 00 00 1a + 43429 in 3554:f58a id=8 08 00 01 0a 0a ff ff ff ff ff ff ff ff ff ff 3a + 43433 out 3554:f58a id=8 08 00 01 2a 0a 00 00 00 00 00 00 00 00 00 00 10 + 43433 in 3554:f58a id=8 08 00 01 20 0a ff ff ff ff ff ff ff ff ff ff 24 + 43436 out 3554:f58a id=8 08 00 01 40 0a 00 00 00 00 00 00 00 00 00 00 fa + 43436 in 3554:f58a id=8 08 00 01 2a 0a ff ff ff ff ff ff ff ff ff ff 1a + 43440 out 3554:f58a id=8 08 00 01 4a 0a 00 00 00 00 00 00 00 00 00 00 f0 + 43440 in 3554:f58a id=8 08 00 01 40 0a ff ff ff ff ff ff ff ff ff ff 04 + 43444 out 3554:f58a id=8 08 00 01 60 0a 00 00 00 00 00 00 00 00 00 00 da + 43444 in 3554:f58a id=8 08 00 01 4a 0a ff ff ff ff ff ff ff ff ff ff fa + 43448 out 3554:f58a id=8 08 00 01 6a 0a 00 00 00 00 00 00 00 00 00 00 d0 + 43448 in 3554:f58a id=8 08 00 01 60 0a ff ff ff ff ff ff ff ff ff ff e4 + 43452 out 3554:f58a id=8 08 00 01 80 0a 00 00 00 00 00 00 00 00 00 00 ba + 43452 in 3554:f58a id=8 08 00 01 6a 0a ff ff ff ff ff ff ff ff ff ff da + 43456 out 3554:f58a id=8 08 00 01 8a 0a 00 00 00 00 00 00 00 00 00 00 b0 + 43456 in 3554:f58a id=8 08 00 01 80 0a ff ff ff ff ff ff ff ff ff ff c4 + 43459 out 3554:f58a id=8 08 00 01 a0 0a 00 00 00 00 00 00 00 00 00 00 9a + 43459 in 3554:f58a id=8 08 00 01 8a 0a ff ff ff ff ff ff ff ff ff ff ba + 43463 out 3554:f58a id=8 08 00 01 aa 0a 00 00 00 00 00 00 00 00 00 00 90 + 43463 in 3554:f58a id=8 08 00 01 a0 0a ff ff ff ff ff ff ff ff ff ff a4 + 43467 in 3554:f58a id=8 08 00 01 aa 0a ff ff ff ff ff ff ff ff ff ff 9a + 43478 out 3554:f58a id=8 08 00 00 a9 0a 00 00 00 00 00 00 00 00 00 00 92 + 43482 out 3554:f58a id=8 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3d + 43482 in 3554:f58a id=8 08 00 00 a9 0a 08 4d 01 54 06 4f 00 55 00 55 e9 + 43487 out 3554:f58a id=8 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 36 + 43487 in 3554:f58a id=8 10 00 00 00 03 02 08 4b 00 00 00 00 00 00 00 e5 + 43491 out 3554:f58a id=8 08 00 00 0a 02 00 00 00 00 00 00 00 00 00 00 39 + 43491 in 3554:f58a id=8 17 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2c + 43495 out 3554:f58a id=8 1d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 + 43495 in 3554:f58a id=8 08 00 00 0a 02 01 54 00 00 00 00 00 00 00 00 e4 + 43496 out 3554:f58a id=8 08 00 00 b5 06 00 00 00 00 00 00 00 00 00 00 8a + 43496 in 3554:f58a id=8 1d 01 00 00 00 00 00 00 00 00 00 00 00 00 00 2f + 43500 out 3554:f58a id=8 08 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 3b + 43500 in 3554:f58a id=8 08 00 00 b5 06 00 55 06 4f 00 55 00 00 00 00 8b + 43504 out 3554:f58a id=8 08 00 00 bd 04 00 00 00 00 00 00 00 00 00 00 84 + 43504 in 3554:f58a id=8 08 00 00 00 0a 01 54 04 51 01 54 00 55 00 55 92 + 43508 out 3554:f58a id=8 08 00 00 0c 08 00 00 00 00 00 00 00 00 00 00 31 + 43509 in 3554:f58a id=8 08 00 00 bd 04 ff ff ff ff 00 00 00 00 00 00 88 + 43513 out 3554:f58a id=8 08 00 00 14 08 00 00 00 00 00 00 00 00 00 00 29 + 43513 in 3554:f58a id=8 08 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 87 + 43517 out 3554:f58a id=8 08 00 00 1c 08 00 00 00 00 00 00 00 00 00 00 21 + 43517 in 3554:f58a id=8 08 00 00 14 08 1f 1f 00 17 3f 3f 00 d7 00 00 7f + 43521 out 3554:f58a id=8 08 00 00 24 08 00 00 00 00 00 00 00 00 00 00 19 + 43521 in 3554:f58a id=8 08 00 00 1c 08 3f 3f 00 d7 3f 3f 00 d7 00 00 77 + 43525 out 3554:f58a id=8 08 00 00 2c 08 00 00 00 00 00 00 00 00 00 00 11 + 43525 in 3554:f58a id=8 08 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 6f + 43529 out 3554:f58a id=8 08 00 00 34 08 00 00 00 00 00 00 00 00 00 00 09 + 43529 in 3554:f58a id=8 08 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 67 + 43533 out 3554:f58a id=8 08 00 00 3c 08 00 00 00 00 00 00 00 00 00 00 01 + 43533 in 3554:f58a id=8 08 00 00 34 08 00 00 ff 56 ff 00 ff 57 00 00 5f + 43537 out 3554:f58a id=8 08 00 00 44 08 00 00 00 00 00 00 00 00 00 00 f9 + 43537 in 3554:f58a id=8 08 00 00 3c 08 ff 00 ff 57 ff 00 ff 57 00 00 57 + 43541 out 3554:f58a id=8 08 00 00 e3 02 00 00 00 00 00 00 00 00 00 00 60 + 43541 in 3554:f58a id=8 08 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 4f + 43545 out 3554:f58a id=8 08 00 1b 4c 04 00 00 00 00 00 00 00 00 00 00 da + 43545 in 3554:f58a id=8 08 00 00 e3 02 ff ff 00 00 00 00 00 00 00 00 62 + 43549 in 3554:f58a id=8 08 00 1b 4c 04 ff ff ff ff 00 00 00 00 00 00 de + +=== back to 1 (47410 ms) + 48594 out 3554:f58a id=8 0f 00 00 00 01 00 00 00 00 00 00 00 00 00 00 3d + 48695 in 3554:f58a id=8 0f 00 00 00 01 00 00 00 00 00 00 00 00 00 00 3d + 48698 in 3554:f58a id=8 0a 00 00 00 0a 04 00 00 00 00 00 00 00 00 00 35 + 49699 out 3554:f58a id=8 08 00 00 60 08 00 00 00 00 00 00 00 00 00 00 dd + 49703 out 3554:f58a id=8 08 00 00 68 08 00 00 00 00 00 00 00 00 00 00 d5 + 49703 in 3554:f58a id=8 08 00 00 60 08 01 01 00 53 01 02 00 52 00 00 33 + 49707 out 3554:f58a id=8 08 00 00 70 08 00 00 00 00 00 00 00 00 00 00 cd + 49707 in 3554:f58a id=8 08 00 00 68 08 01 04 00 50 01 08 00 4c 00 00 2b + 49712 in 3554:f58a id=8 08 00 00 70 08 01 10 00 44 02 01 00 52 00 00 23 + 49723 out 3554:f58a id=8 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3f + 49727 in 3554:f58a id=8 0e 00 00 00 01 00 00 00 00 00 00 00 00 00 00 3e + 49738 out 3554:f58a id=8 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3b + 49742 in 3554:f58a id=8 12 00 00 00 02 01 20 00 00 00 00 00 00 00 00 18 + 49753 out 3554:f58a id=8 08 00 00 4c 08 00 00 00 00 00 00 00 00 00 00 f1 + 49757 in 3554:f58a id=8 08 00 00 4c 08 02 53 ff 56 05 50 00 55 00 00 9d + 49768 out 3554:f58a id=8 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 49 + 49771 in 3554:f58a id=8 04 00 00 00 02 14 00 0d f2 00 00 00 00 00 00 34 + 49782 out 3554:f58a id=8 08 00 01 00 0a 00 00 00 00 00 00 00 00 00 00 3a + 49785 out 3554:f58a id=8 08 00 01 0a 0a 00 00 00 00 00 00 00 00 00 00 30 + 49785 in 3554:f58a id=8 08 00 01 00 0a ff ff ff ff ff ff ff ff ff ff 44 + 49789 out 3554:f58a id=8 08 00 01 20 0a 00 00 00 00 00 00 00 00 00 00 1a + 49789 in 3554:f58a id=8 08 00 01 0a 0a ff ff ff ff ff ff ff ff ff ff 3a + 49792 out 3554:f58a id=8 08 00 01 2a 0a 00 00 00 00 00 00 00 00 00 00 10 + 49792 in 3554:f58a id=8 08 00 01 20 0a ff ff ff ff ff ff ff ff ff ff 24 + 49797 out 3554:f58a id=8 08 00 01 40 0a 00 00 00 00 00 00 00 00 00 00 fa + 49797 in 3554:f58a id=8 08 00 01 2a 0a ff ff ff ff ff ff ff ff ff ff 1a + 49801 out 3554:f58a id=8 08 00 01 4a 0a 00 00 00 00 00 00 00 00 00 00 f0 + 49801 in 3554:f58a id=8 08 00 01 40 0a ff ff ff ff ff ff ff ff ff ff 04 + 49804 out 3554:f58a id=8 08 00 01 60 0a 00 00 00 00 00 00 00 00 00 00 da + 49804 in 3554:f58a id=8 08 00 01 4a 0a ff ff ff ff ff ff ff ff ff ff fa + 49807 out 3554:f58a id=8 08 00 01 6a 0a 00 00 00 00 00 00 00 00 00 00 d0 + 49807 in 3554:f58a id=8 08 00 01 60 0a 02 82 92 01 42 92 01 69 00 00 85 + 49811 out 3554:f58a id=8 08 00 01 80 0a 00 00 00 00 00 00 00 00 00 00 ba + 49811 in 3554:f58a id=8 08 00 01 6a 0a ff ff ff ff ff ff ff ff ff ff da + 49814 out 3554:f58a id=8 08 00 01 8a 0a 00 00 00 00 00 00 00 00 00 00 b0 + 49814 in 3554:f58a id=8 08 00 01 80 0a ff ff ff ff ff ff ff ff ff ff c4 + 49817 out 3554:f58a id=8 08 00 01 a0 0a 00 00 00 00 00 00 00 00 00 00 9a + 49817 in 3554:f58a id=8 08 00 01 8a 0a ff ff ff ff ff ff ff ff ff ff ba + 49820 out 3554:f58a id=8 08 00 01 aa 0a 00 00 00 00 00 00 00 00 00 00 90 + 49820 in 3554:f58a id=8 08 00 01 a0 0a ff ff ff ff ff ff ff ff ff ff a4 + 49824 in 3554:f58a id=8 08 00 01 aa 0a ff ff ff ff ff ff ff ff ff ff 9a + 49835 out 3554:f58a id=8 08 00 00 a9 0a 00 00 00 00 00 00 00 00 00 00 92 + 49839 out 3554:f58a id=8 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3d + 49839 in 3554:f58a id=8 08 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 e9 + 49842 out 3554:f58a id=8 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 36 + 49842 in 3554:f58a id=8 10 00 00 00 03 02 08 4b 00 00 00 00 00 00 00 e5 + 49846 out 3554:f58a id=8 08 00 00 0a 02 00 00 00 00 00 00 00 00 00 00 39 + 49846 in 3554:f58a id=8 17 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2c + 49850 out 3554:f58a id=8 1d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 + 49850 in 3554:f58a id=8 08 00 00 0a 02 01 54 00 00 00 00 00 00 00 00 e4 + 49851 out 3554:f58a id=8 08 00 00 b5 06 00 00 00 00 00 00 00 00 00 00 8a + 49851 in 3554:f58a id=8 1d 01 00 00 00 00 00 00 00 00 00 00 00 00 00 2f + 49854 out 3554:f58a id=8 08 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 3b + 49854 in 3554:f58a id=8 08 00 00 b5 06 01 54 06 4f 01 54 00 00 00 00 8b + 49858 out 3554:f58a id=8 08 00 00 bd 04 00 00 00 00 00 00 00 00 00 00 84 + 49858 in 3554:f58a id=8 08 00 00 00 0a 01 54 04 51 03 52 00 55 00 55 92 + 49862 out 3554:f58a id=8 08 00 00 0c 08 00 00 00 00 00 00 00 00 00 00 31 + 49862 in 3554:f58a id=8 08 00 00 bd 04 ff ff ff ff 00 00 00 00 00 00 88 + 49866 out 3554:f58a id=8 08 00 00 14 08 00 00 00 00 00 00 00 00 00 00 29 + 49866 in 3554:f58a id=8 08 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 87 + 49870 out 3554:f58a id=8 08 00 00 1c 08 00 00 00 00 00 00 00 00 00 00 21 + 49870 in 3554:f58a id=8 08 00 00 14 08 3f 3f 00 d7 17 17 00 27 00 00 7f + 49874 out 3554:f58a id=8 08 00 00 24 08 00 00 00 00 00 00 00 00 00 00 19 + 49874 in 3554:f58a id=8 08 00 00 1c 08 17 17 00 27 27 27 00 07 00 00 77 + 49878 out 3554:f58a id=8 08 00 00 2c 08 00 00 00 00 00 00 00 00 00 00 11 + 49878 in 3554:f58a id=8 08 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 6f + 49881 out 3554:f58a id=8 08 00 00 34 08 00 00 00 00 00 00 00 00 00 00 09 + 49881 in 3554:f58a id=8 08 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 67 + 49884 out 3554:f58a id=8 08 00 00 3c 08 00 00 00 00 00 00 00 00 00 00 01 + 49884 in 3554:f58a id=8 08 00 00 34 08 ff 00 ff 57 df b6 20 a0 00 00 5f + 49888 out 3554:f58a id=8 08 00 00 44 08 00 00 00 00 00 00 00 00 00 00 f9 + 49888 in 3554:f58a id=8 08 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 57 + 49892 out 3554:f58a id=8 08 00 00 e3 02 00 00 00 00 00 00 00 00 00 00 60 + 49892 in 3554:f58a id=8 08 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 4f + 49897 out 3554:f58a id=8 08 00 1b 4c 04 00 00 00 00 00 00 00 00 00 00 da + 49897 in 3554:f58a id=8 08 00 00 e3 02 ff ff 00 00 00 00 00 00 00 00 62 + 49901 in 3554:f58a id=8 08 00 1b 4c 04 ff ff ff ff 00 00 00 00 00 00 de + +=== creating new config , not sure if this is gonna owrk (68488 ms) + 82991 out 3554:f58a id=8 0f 00 00 00 01 03 00 00 00 00 00 00 00 00 00 3a + 83093 in 3554:f58a id=8 0f 00 00 00 01 03 00 00 00 00 00 00 00 00 00 3a + 83100 in 3554:f58a id=8 0a 00 00 00 0a 04 00 00 00 00 00 00 00 00 00 35 + 84403 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 84410 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 84465 out 3554:f58a id=8 07 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 88 + 84470 out 3554:f58a id=8 07 00 00 14 08 3f 3f 00 d7 17 17 00 27 00 00 80 + 84470 in 3554:f58a id=8 07 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 88 + 84474 out 3554:f58a id=8 07 00 00 1c 08 17 17 00 27 27 27 00 07 00 00 78 + 84474 in 3554:f58a id=8 07 00 00 14 08 3f 3f 00 d7 17 17 00 27 00 00 80 + 84478 out 3554:f58a id=8 07 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 70 + 84478 in 3554:f58a id=8 07 00 00 1c 08 17 17 00 27 27 27 00 07 00 00 78 + 84483 in 3554:f58a id=8 07 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 70 + 84534 out 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 84538 out 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 df b6 20 a0 00 00 60 + 84538 in 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 84542 out 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 84542 in 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 df b6 20 a0 00 00 60 + 84546 out 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + 84546 in 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 84550 in 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + 84602 out 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 03 52 00 00 00 55 e8 + 84607 in 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 03 52 00 00 00 55 e8 + 84658 out 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 03 52 00 00 00 55 e8 + 84663 in 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 03 52 00 00 00 55 e8 + 84717 out 3554:f58a id=8 07 00 00 b5 06 01 54 06 4f 01 54 00 00 00 00 8c + 84723 in 3554:f58a id=8 07 00 00 b5 06 01 54 06 4f 01 54 00 00 00 00 8c + 84774 out 3554:f58a id=8 07 00 00 0a 02 01 54 00 00 00 00 00 00 00 00 e5 + 84781 in 3554:f58a id=8 07 00 00 0a 02 01 54 00 00 00 00 00 00 00 00 e5 + 84831 out 3554:f58a id=8 16 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2d + 84927 in 3554:f58a id=8 16 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2d + 84979 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 84984 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 85037 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 85041 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 85094 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 85098 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 85151 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 85156 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 85208 out 3554:f58a id=8 07 00 00 4c 08 00 00 ff 56 05 50 00 55 00 00 f3 + 85213 in 3554:f58a id=8 07 00 00 4c 08 00 00 ff 56 05 50 00 55 00 00 f3 + 85265 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 85270 out 3554:f58a id=8 07 00 00 b5 06 01 54 06 4f 01 54 00 00 00 00 8c + 85270 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 85274 in 3554:f58a id=8 07 00 00 b5 06 01 54 06 4f 01 54 00 00 00 00 8c + 85328 out 3554:f58a id=8 07 00 00 bd 04 ff 56 ff 56 00 00 00 00 00 00 db + 85333 in 3554:f58a id=8 07 00 00 bd 04 ff 56 ff 56 00 00 00 00 00 00 db + 85385 out 3554:f58a id=8 07 00 00 60 04 01 01 00 53 00 00 00 00 00 00 8d + 85390 in 3554:f58a id=8 07 00 00 60 04 01 01 00 53 00 00 00 00 00 00 8d + 85442 out 3554:f58a id=8 07 00 00 64 04 01 02 00 52 00 00 00 00 00 00 89 + 85448 in 3554:f58a id=8 07 00 00 64 04 01 02 00 52 00 00 00 00 00 00 89 + 85500 out 3554:f58a id=8 07 00 00 68 04 01 04 00 50 00 00 00 00 00 00 85 + 85504 in 3554:f58a id=8 07 00 00 68 04 01 04 00 50 00 00 00 00 00 00 85 + 85557 out 3554:f58a id=8 07 00 00 6c 04 01 08 00 4c 00 00 00 00 00 00 81 + 85561 in 3554:f58a id=8 07 00 00 6c 04 01 08 00 4c 00 00 00 00 00 00 81 + 85614 out 3554:f58a id=8 07 00 01 60 0a 02 82 92 01 42 92 01 69 00 00 86 + 85619 in 3554:f58a id=8 07 00 01 60 0a 02 82 92 01 42 92 01 69 00 00 86 + 85671 out 3554:f58a id=8 07 00 00 70 04 01 10 00 44 00 00 00 00 00 00 7d + 85676 in 3554:f58a id=8 07 00 00 70 04 01 10 00 44 00 00 00 00 00 00 7d + 85728 out 3554:f58a id=8 07 00 00 74 04 02 01 00 52 00 00 00 00 00 00 79 + 85733 in 3554:f58a id=8 07 00 00 74 04 02 01 00 52 00 00 00 00 00 00 79 + 86785 out 3554:f58a id=8 08 00 00 60 08 00 00 00 00 00 00 00 00 00 00 dd + 86790 out 3554:f58a id=8 08 00 00 68 08 00 00 00 00 00 00 00 00 00 00 d5 + 86790 in 3554:f58a id=8 08 00 00 60 08 01 01 00 53 01 02 00 52 00 00 33 + 86794 out 3554:f58a id=8 08 00 00 70 08 00 00 00 00 00 00 00 00 00 00 cd + 86794 in 3554:f58a id=8 08 00 00 68 08 01 04 00 50 01 08 00 4c 00 00 2b + 86798 in 3554:f58a id=8 08 00 00 70 08 01 10 00 44 02 01 00 52 00 00 23 + 86808 out 3554:f58a id=8 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3f + 86813 in 3554:f58a id=8 0e 00 00 00 01 03 00 00 00 00 00 00 00 00 00 3b + 86824 out 3554:f58a id=8 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3b + 86829 in 3554:f58a id=8 12 00 00 00 02 01 20 00 00 00 00 00 00 00 00 18 + 86840 out 3554:f58a id=8 08 00 00 4c 08 00 00 00 00 00 00 00 00 00 00 f1 + 86844 in 3554:f58a id=8 08 00 00 4c 08 02 53 ff 56 05 50 00 55 00 00 9d + 86856 out 3554:f58a id=8 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 49 + 86861 in 3554:f58a id=8 04 00 00 00 02 14 00 0d f2 00 00 00 00 00 00 34 + 86872 out 3554:f58a id=8 08 00 01 00 0a 00 00 00 00 00 00 00 00 00 00 3a + 86876 out 3554:f58a id=8 08 00 01 0a 0a 00 00 00 00 00 00 00 00 00 00 30 + 86876 in 3554:f58a id=8 08 00 01 00 0a ff ff ff ff ff ff ff ff ff ff 44 + 86880 out 3554:f58a id=8 08 00 01 20 0a 00 00 00 00 00 00 00 00 00 00 1a + 86880 in 3554:f58a id=8 08 00 01 0a 0a ff ff ff ff ff ff ff ff ff ff 3a + 86884 out 3554:f58a id=8 08 00 01 2a 0a 00 00 00 00 00 00 00 00 00 00 10 + 86884 in 3554:f58a id=8 08 00 01 20 0a ff ff ff ff ff ff ff ff ff ff 24 + 86889 out 3554:f58a id=8 08 00 01 40 0a 00 00 00 00 00 00 00 00 00 00 fa + 86889 in 3554:f58a id=8 08 00 01 2a 0a ff ff ff ff ff ff ff ff ff ff 1a + 86893 out 3554:f58a id=8 08 00 01 4a 0a 00 00 00 00 00 00 00 00 00 00 f0 + 86893 in 3554:f58a id=8 08 00 01 40 0a ff ff ff ff ff ff ff ff ff ff 04 + 86897 out 3554:f58a id=8 08 00 01 60 0a 00 00 00 00 00 00 00 00 00 00 da + 86897 in 3554:f58a id=8 08 00 01 4a 0a ff ff ff ff ff ff ff ff ff ff fa + 86901 out 3554:f58a id=8 08 00 01 6a 0a 00 00 00 00 00 00 00 00 00 00 d0 + 86901 in 3554:f58a id=8 08 00 01 60 0a 02 82 92 01 42 92 01 69 00 00 85 + 86905 out 3554:f58a id=8 08 00 01 80 0a 00 00 00 00 00 00 00 00 00 00 ba + 86905 in 3554:f58a id=8 08 00 01 6a 0a ff ff ff ff ff ff ff ff ff ff da + 86909 out 3554:f58a id=8 08 00 01 8a 0a 00 00 00 00 00 00 00 00 00 00 b0 + 86909 in 3554:f58a id=8 08 00 01 80 0a ff ff ff ff ff ff ff ff ff ff c4 + 86913 out 3554:f58a id=8 08 00 01 a0 0a 00 00 00 00 00 00 00 00 00 00 9a + 86913 in 3554:f58a id=8 08 00 01 8a 0a ff ff ff ff ff ff ff ff ff ff ba + 86917 out 3554:f58a id=8 08 00 01 aa 0a 00 00 00 00 00 00 00 00 00 00 90 + 86917 in 3554:f58a id=8 08 00 01 a0 0a ff ff ff ff ff ff ff ff ff ff a4 + 86922 in 3554:f58a id=8 08 00 01 aa 0a ff ff ff ff ff ff ff ff ff ff 9a + 86933 out 3554:f58a id=8 08 00 00 a9 0a 00 00 00 00 00 00 00 00 00 00 92 + 86937 out 3554:f58a id=8 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3d + 86937 in 3554:f58a id=8 08 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 e9 + 86941 out 3554:f58a id=8 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 36 + 86941 in 3554:f58a id=8 10 00 00 00 03 02 08 4b 00 00 00 00 00 00 00 e5 + 86945 out 3554:f58a id=8 08 00 00 0a 02 00 00 00 00 00 00 00 00 00 00 39 + 86945 in 3554:f58a id=8 17 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2c + 86949 out 3554:f58a id=8 1d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 + 86949 in 3554:f58a id=8 08 00 00 0a 02 01 54 00 00 00 00 00 00 00 00 e4 + 86950 out 3554:f58a id=8 08 00 00 b5 06 00 00 00 00 00 00 00 00 00 00 8a + 86950 in 3554:f58a id=8 1d 01 00 00 00 00 00 00 00 00 00 00 00 00 00 2f + 86954 out 3554:f58a id=8 08 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 3b + 86954 in 3554:f58a id=8 08 00 00 b5 06 01 54 06 4f 01 54 00 00 00 00 8b + 86958 out 3554:f58a id=8 08 00 00 bd 04 00 00 00 00 00 00 00 00 00 00 84 + 86958 in 3554:f58a id=8 08 00 00 00 0a 01 54 04 51 03 52 00 55 00 55 92 + 86962 out 3554:f58a id=8 08 00 00 0c 08 00 00 00 00 00 00 00 00 00 00 31 + 86962 in 3554:f58a id=8 08 00 00 bd 04 ff 56 ff 56 00 00 00 00 00 00 da + 86966 out 3554:f58a id=8 08 00 00 14 08 00 00 00 00 00 00 00 00 00 00 29 + 86966 in 3554:f58a id=8 08 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 87 + 86970 out 3554:f58a id=8 08 00 00 1c 08 00 00 00 00 00 00 00 00 00 00 21 + 86970 in 3554:f58a id=8 08 00 00 14 08 3f 3f 00 d7 17 17 00 27 00 00 7f + 86974 out 3554:f58a id=8 08 00 00 24 08 00 00 00 00 00 00 00 00 00 00 19 + 86974 in 3554:f58a id=8 08 00 00 1c 08 17 17 00 27 27 27 00 07 00 00 77 + 86979 out 3554:f58a id=8 08 00 00 2c 08 00 00 00 00 00 00 00 00 00 00 11 + 86979 in 3554:f58a id=8 08 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 6f + 86983 out 3554:f58a id=8 08 00 00 34 08 00 00 00 00 00 00 00 00 00 00 09 + 86983 in 3554:f58a id=8 08 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 67 + 86987 out 3554:f58a id=8 08 00 00 3c 08 00 00 00 00 00 00 00 00 00 00 01 + 86987 in 3554:f58a id=8 08 00 00 34 08 ff 00 ff 57 df b6 20 a0 00 00 5f + 86991 out 3554:f58a id=8 08 00 00 44 08 00 00 00 00 00 00 00 00 00 00 f9 + 86992 in 3554:f58a id=8 08 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 57 + 86996 out 3554:f58a id=8 08 00 00 e3 02 00 00 00 00 00 00 00 00 00 00 60 + 86996 in 3554:f58a id=8 08 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 4f + 87000 out 3554:f58a id=8 08 00 1b 4c 04 00 00 00 00 00 00 00 00 00 00 da + 87000 in 3554:f58a id=8 08 00 00 e3 02 ff ff 00 00 00 00 00 00 00 00 62 + 87004 in 3554:f58a id=8 08 00 1b 4c 04 ff ff ff ff 00 00 00 00 00 00 de + +=== created and applied. tho seems like it's stored locally o nthe pc, not on the mouse cuz only 4 slots on the mouse maybe? (121418 ms) + +=== switching back to 1 (131058 ms) + 132371 out 3554:f58a id=8 0f 00 00 00 01 00 00 00 00 00 00 00 00 00 00 3d + 132469 in 3554:f58a id=8 0f 00 00 00 01 00 00 00 00 00 00 00 00 00 00 3d + 132478 in 3554:f58a id=8 0a 00 00 00 0a 04 00 00 00 00 00 00 00 00 00 35 + 133470 out 3554:f58a id=8 08 00 00 60 08 00 00 00 00 00 00 00 00 00 00 dd + 133476 out 3554:f58a id=8 08 00 00 68 08 00 00 00 00 00 00 00 00 00 00 d5 + 133476 in 3554:f58a id=8 08 00 00 60 08 01 01 00 53 01 02 00 52 00 00 33 + 133481 out 3554:f58a id=8 08 00 00 70 08 00 00 00 00 00 00 00 00 00 00 cd + 133481 in 3554:f58a id=8 08 00 00 68 08 01 04 00 50 01 08 00 4c 00 00 2b + 133485 in 3554:f58a id=8 08 00 00 70 08 01 10 00 44 02 01 00 52 00 00 23 + 133497 out 3554:f58a id=8 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3f + 133501 in 3554:f58a id=8 0e 00 00 00 01 00 00 00 00 00 00 00 00 00 00 3e + 133511 out 3554:f58a id=8 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3b + 133516 in 3554:f58a id=8 12 00 00 00 02 01 20 00 00 00 00 00 00 00 00 18 + 133526 out 3554:f58a id=8 08 00 00 4c 08 00 00 00 00 00 00 00 00 00 00 f1 + 133531 in 3554:f58a id=8 08 00 00 4c 08 02 53 ff 56 05 50 00 55 00 00 9d + 133543 out 3554:f58a id=8 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 49 + 133548 in 3554:f58a id=8 04 00 00 00 02 14 00 0d f2 00 00 00 00 00 00 34 + 133559 out 3554:f58a id=8 08 00 01 00 0a 00 00 00 00 00 00 00 00 00 00 3a + 133563 out 3554:f58a id=8 08 00 01 0a 0a 00 00 00 00 00 00 00 00 00 00 30 + 133563 in 3554:f58a id=8 08 00 01 00 0a ff ff ff ff ff ff ff ff ff ff 44 + 133567 out 3554:f58a id=8 08 00 01 20 0a 00 00 00 00 00 00 00 00 00 00 1a + 133567 in 3554:f58a id=8 08 00 01 0a 0a ff ff ff ff ff ff ff ff ff ff 3a + 133571 out 3554:f58a id=8 08 00 01 2a 0a 00 00 00 00 00 00 00 00 00 00 10 + 133571 in 3554:f58a id=8 08 00 01 20 0a ff ff ff ff ff ff ff ff ff ff 24 + 133574 out 3554:f58a id=8 08 00 01 40 0a 00 00 00 00 00 00 00 00 00 00 fa + 133574 in 3554:f58a id=8 08 00 01 2a 0a ff ff ff ff ff ff ff ff ff ff 1a + 133577 out 3554:f58a id=8 08 00 01 4a 0a 00 00 00 00 00 00 00 00 00 00 f0 + 133577 in 3554:f58a id=8 08 00 01 40 0a ff ff ff ff ff ff ff ff ff ff 04 + 133580 out 3554:f58a id=8 08 00 01 60 0a 00 00 00 00 00 00 00 00 00 00 da + 133580 in 3554:f58a id=8 08 00 01 4a 0a ff ff ff ff ff ff ff ff ff ff fa + 133584 out 3554:f58a id=8 08 00 01 6a 0a 00 00 00 00 00 00 00 00 00 00 d0 + 133584 in 3554:f58a id=8 08 00 01 60 0a 02 82 92 01 42 92 01 69 00 00 85 + 133587 out 3554:f58a id=8 08 00 01 80 0a 00 00 00 00 00 00 00 00 00 00 ba + 133587 in 3554:f58a id=8 08 00 01 6a 0a ff ff ff ff ff ff ff ff ff ff da + 133590 out 3554:f58a id=8 08 00 01 8a 0a 00 00 00 00 00 00 00 00 00 00 b0 + 133590 in 3554:f58a id=8 08 00 01 80 0a ff ff ff ff ff ff ff ff ff ff c4 + 133593 out 3554:f58a id=8 08 00 01 a0 0a 00 00 00 00 00 00 00 00 00 00 9a + 133593 in 3554:f58a id=8 08 00 01 8a 0a ff ff ff ff ff ff ff ff ff ff ba + 133596 out 3554:f58a id=8 08 00 01 aa 0a 00 00 00 00 00 00 00 00 00 00 90 + 133596 in 3554:f58a id=8 08 00 01 a0 0a ff ff ff ff ff ff ff ff ff ff a4 + 133599 in 3554:f58a id=8 08 00 01 aa 0a ff ff ff ff ff ff ff ff ff ff 9a + 133610 out 3554:f58a id=8 08 00 00 a9 0a 00 00 00 00 00 00 00 00 00 00 92 + 133614 out 3554:f58a id=8 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3d + 133614 in 3554:f58a id=8 08 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 e9 + 133618 out 3554:f58a id=8 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 36 + 133618 in 3554:f58a id=8 10 00 00 00 03 02 08 4b 00 00 00 00 00 00 00 e5 + 133622 out 3554:f58a id=8 08 00 00 0a 02 00 00 00 00 00 00 00 00 00 00 39 + 133622 in 3554:f58a id=8 17 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2c + 133625 out 3554:f58a id=8 1d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 + 133625 in 3554:f58a id=8 08 00 00 0a 02 01 54 00 00 00 00 00 00 00 00 e4 + 133626 out 3554:f58a id=8 08 00 00 b5 06 00 00 00 00 00 00 00 00 00 00 8a + 133626 in 3554:f58a id=8 1d 01 00 00 00 00 00 00 00 00 00 00 00 00 00 2f + 133630 out 3554:f58a id=8 08 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 3b + 133630 in 3554:f58a id=8 08 00 00 b5 06 01 54 06 4f 01 54 00 00 00 00 8b + 133634 out 3554:f58a id=8 08 00 00 bd 04 00 00 00 00 00 00 00 00 00 00 84 + 133634 in 3554:f58a id=8 08 00 00 00 0a 01 54 04 51 03 52 00 55 00 55 92 + 133637 out 3554:f58a id=8 08 00 00 0c 08 00 00 00 00 00 00 00 00 00 00 31 + 133637 in 3554:f58a id=8 08 00 00 bd 04 ff ff ff ff 00 00 00 00 00 00 88 + 133640 out 3554:f58a id=8 08 00 00 14 08 00 00 00 00 00 00 00 00 00 00 29 + 133640 in 3554:f58a id=8 08 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 87 + 133643 out 3554:f58a id=8 08 00 00 1c 08 00 00 00 00 00 00 00 00 00 00 21 + 133643 in 3554:f58a id=8 08 00 00 14 08 3f 3f 00 d7 17 17 00 27 00 00 7f + 133646 out 3554:f58a id=8 08 00 00 24 08 00 00 00 00 00 00 00 00 00 00 19 + 133646 in 3554:f58a id=8 08 00 00 1c 08 17 17 00 27 27 27 00 07 00 00 77 + 133651 out 3554:f58a id=8 08 00 00 2c 08 00 00 00 00 00 00 00 00 00 00 11 + 133651 in 3554:f58a id=8 08 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 6f + 133654 out 3554:f58a id=8 08 00 00 34 08 00 00 00 00 00 00 00 00 00 00 09 + 133654 in 3554:f58a id=8 08 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 67 + 133657 out 3554:f58a id=8 08 00 00 3c 08 00 00 00 00 00 00 00 00 00 00 01 + 133657 in 3554:f58a id=8 08 00 00 34 08 ff 00 ff 57 df b6 20 a0 00 00 5f + 133660 out 3554:f58a id=8 08 00 00 44 08 00 00 00 00 00 00 00 00 00 00 f9 + 133660 in 3554:f58a id=8 08 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 57 + 133663 out 3554:f58a id=8 08 00 00 e3 02 00 00 00 00 00 00 00 00 00 00 60 + 133663 in 3554:f58a id=8 08 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 4f + 133668 out 3554:f58a id=8 08 00 1b 4c 04 00 00 00 00 00 00 00 00 00 00 da + 133668 in 3554:f58a id=8 08 00 00 e3 02 ff ff 00 00 00 00 00 00 00 00 62 + 133671 in 3554:f58a id=8 08 00 1b 4c 04 ff ff ff ff 00 00 00 00 00 00 de diff --git a/captures/vxe-r1-pro/receiver-atk-hub.txt b/captures/vxe-r1-pro/receiver-atk-hub.txt new file mode 100644 index 00000000..61b15189 --- /dev/null +++ b/captures/vxe-r1-pro/receiver-atk-hub.txt @@ -0,0 +1,287 @@ +# ATK HUB (v3-hub.atk.store) driving a VXE R1 Pro, firmware 1.20, through the +# 0x3554:0xf58a "VXE NordicMouse 1K Dongle". Columns: ms, direction, USB id, +# report id, 16-byte frame. Marks (===) are the owner's notes on what was changed. +# The hub's session handshake (command 0x01) and the receiver RF identity +# (command 0x03 reply) are removed. + 23758 out 3554:f58a id=8 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3d + 23763 out 3554:f58a id=8 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3b + 23763 in 3554:f58a id=8 10 00 00 00 03 02 08 4b 00 00 00 00 00 00 00 e5 + 23767 out 3554:f58a id=8 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4a + 23768 in 3554:f58a id=8 12 00 00 00 02 01 20 00 00 00 00 00 00 00 00 18 + 23771 out 3554:f58a id=8 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 49 + 23775 out 3554:f58a id=8 1d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 + 23776 in 3554:f58a id=8 04 00 00 00 02 14 00 0d f6 00 00 00 00 00 00 30 + 23779 in 3554:f58a id=8 1d 01 00 00 00 00 00 00 00 00 00 00 00 00 00 2f + +=== clicking on the device on the device list, after clicking it will open the mouse's overview/dashboard where you can change stuff (58805 ms) + 60176 out 3554:f58a id=8 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3d + 60182 out 3554:f58a id=8 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3b + 60183 in 3554:f58a id=8 10 00 00 00 03 02 08 4b 00 00 00 00 00 00 00 e5 + 60187 out 3554:f58a id=8 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4a + 60187 in 3554:f58a id=8 12 00 00 00 02 01 20 00 00 00 00 00 00 00 00 18 + 60189 out 3554:f58a id=8 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 49 + 60193 out 3554:f58a id=8 1d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 + 60194 in 3554:f58a id=8 04 00 00 00 02 14 00 0d fa 00 00 00 00 00 00 2c + 60195 in 3554:f58a id=8 1d 01 00 00 00 00 00 00 00 00 00 00 00 00 00 2f + 60564 out 3554:f58a id=8 08 00 00 60 08 00 00 00 00 00 00 00 00 00 00 dd + 60572 out 3554:f58a id=8 08 00 00 68 08 00 00 00 00 00 00 00 00 00 00 d5 + 60572 in 3554:f58a id=8 08 00 00 60 08 01 01 00 53 01 02 00 52 00 00 33 + 60577 out 3554:f58a id=8 08 00 00 70 08 00 00 00 00 00 00 00 00 00 00 cd + 60577 in 3554:f58a id=8 08 00 00 68 08 01 04 00 50 01 08 00 4c 00 00 2b + 60582 in 3554:f58a id=8 08 00 00 70 08 01 10 00 44 02 01 00 52 00 00 23 + 60593 out 3554:f58a id=8 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3f + 60597 in 3554:f58a id=8 0e 00 00 00 01 00 00 00 00 00 00 00 00 00 00 3e + 60607 out 3554:f58a id=8 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3b + 60612 in 3554:f58a id=8 12 00 00 00 02 01 20 00 00 00 00 00 00 00 00 18 + 60624 out 3554:f58a id=8 08 00 00 4c 08 00 00 00 00 00 00 00 00 00 00 f1 + 60629 in 3554:f58a id=8 08 00 00 4c 08 02 53 80 d5 05 50 00 55 00 00 9d + 60642 out 3554:f58a id=8 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 49 + 60646 in 3554:f58a id=8 04 00 00 00 02 14 00 0d fa 00 00 00 00 00 00 2c + 60658 out 3554:f58a id=8 08 00 01 00 0a 00 00 00 00 00 00 00 00 00 00 3a + 60663 out 3554:f58a id=8 08 00 01 0a 0a 00 00 00 00 00 00 00 00 00 00 30 + 60663 in 3554:f58a id=8 08 00 01 00 0a ff ff ff ff ff ff ff ff ff ff 44 + 60668 out 3554:f58a id=8 08 00 01 20 0a 00 00 00 00 00 00 00 00 00 00 1a + 60668 in 3554:f58a id=8 08 00 01 0a 0a ff ff ff ff ff ff ff ff ff ff 3a + 60671 out 3554:f58a id=8 08 00 01 2a 0a 00 00 00 00 00 00 00 00 00 00 10 + 60671 in 3554:f58a id=8 08 00 01 20 0a ff ff ff ff ff ff ff ff ff ff 24 + 60675 out 3554:f58a id=8 08 00 01 40 0a 00 00 00 00 00 00 00 00 00 00 fa + 60675 in 3554:f58a id=8 08 00 01 2a 0a ff ff ff ff ff ff ff ff ff ff 1a + 60679 out 3554:f58a id=8 08 00 01 4a 0a 00 00 00 00 00 00 00 00 00 00 f0 + 60679 in 3554:f58a id=8 08 00 01 40 0a ff ff ff ff ff ff ff ff ff ff 04 + 60683 out 3554:f58a id=8 08 00 01 60 0a 00 00 00 00 00 00 00 00 00 00 da + 60683 in 3554:f58a id=8 08 00 01 4a 0a ff ff ff ff ff ff ff ff ff ff fa + 60687 out 3554:f58a id=8 08 00 01 6a 0a 00 00 00 00 00 00 00 00 00 00 d0 + 60687 in 3554:f58a id=8 08 00 01 60 0a 02 82 92 01 42 92 01 69 00 00 85 + 60691 out 3554:f58a id=8 08 00 01 80 0a 00 00 00 00 00 00 00 00 00 00 ba + 60691 in 3554:f58a id=8 08 00 01 6a 0a ff ff ff ff ff ff ff ff ff ff da + 60695 out 3554:f58a id=8 08 00 01 8a 0a 00 00 00 00 00 00 00 00 00 00 b0 + 60695 in 3554:f58a id=8 08 00 01 80 0a ff ff ff ff ff ff ff ff ff ff c4 + 60699 out 3554:f58a id=8 08 00 01 a0 0a 00 00 00 00 00 00 00 00 00 00 9a + 60699 in 3554:f58a id=8 08 00 01 8a 0a ff ff ff ff ff ff ff ff ff ff ba + 60703 out 3554:f58a id=8 08 00 01 aa 0a 00 00 00 00 00 00 00 00 00 00 90 + 60703 in 3554:f58a id=8 08 00 01 a0 0a ff ff ff ff ff ff ff ff ff ff a4 + 60708 in 3554:f58a id=8 08 00 01 aa 0a ff ff ff ff ff ff ff ff ff ff 9a + 60719 out 3554:f58a id=8 08 00 00 a9 0a 00 00 00 00 00 00 00 00 00 00 92 + 60726 out 3554:f58a id=8 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3d + 60726 in 3554:f58a id=8 08 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 e9 + 60731 out 3554:f58a id=8 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 36 + 60731 in 3554:f58a id=8 10 00 00 00 03 02 08 4b 00 00 00 00 00 00 00 e5 + 60735 out 3554:f58a id=8 08 00 00 0a 02 00 00 00 00 00 00 00 00 00 00 39 + 60735 in 3554:f58a id=8 17 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2c + 60739 out 3554:f58a id=8 1d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 + 60739 in 3554:f58a id=8 08 00 00 0a 02 01 54 00 00 00 00 00 00 00 00 e4 + 60740 out 3554:f58a id=8 08 00 00 b5 06 00 00 00 00 00 00 00 00 00 00 8a + 60740 in 3554:f58a id=8 1d 01 00 00 00 00 00 00 00 00 00 00 00 00 00 2f + 60744 out 3554:f58a id=8 08 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 3b + 60744 in 3554:f58a id=8 08 00 00 b5 06 00 55 06 4f 01 54 00 00 00 00 8b + 60748 out 3554:f58a id=8 08 00 00 bd 04 00 00 00 00 00 00 00 00 00 00 84 + 60748 in 3554:f58a id=8 08 00 00 00 0a 01 54 04 51 03 52 00 55 00 55 92 + 60753 out 3554:f58a id=8 08 00 00 0c 08 00 00 00 00 00 00 00 00 00 00 31 + 60754 in 3554:f58a id=8 08 00 00 bd 04 ff ff ff ff 00 00 00 00 00 00 88 + 60758 out 3554:f58a id=8 08 00 00 14 08 00 00 00 00 00 00 00 00 00 00 29 + 60758 in 3554:f58a id=8 08 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 87 + 60762 out 3554:f58a id=8 08 00 00 1c 08 00 00 00 00 00 00 00 00 00 00 21 + 60762 in 3554:f58a id=8 08 00 00 14 08 3f 3f 00 d7 17 17 00 27 00 00 7f + 60766 out 3554:f58a id=8 08 00 00 24 08 00 00 00 00 00 00 00 00 00 00 19 + 60766 in 3554:f58a id=8 08 00 00 1c 08 17 17 00 27 27 27 00 07 00 00 77 + 60770 out 3554:f58a id=8 08 00 00 2c 08 00 00 00 00 00 00 00 00 00 00 11 + 60770 in 3554:f58a id=8 08 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 6f + 60775 out 3554:f58a id=8 08 00 00 34 08 00 00 00 00 00 00 00 00 00 00 09 + 60775 in 3554:f58a id=8 08 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 67 + 60779 out 3554:f58a id=8 08 00 00 3c 08 00 00 00 00 00 00 00 00 00 00 01 + 60779 in 3554:f58a id=8 08 00 00 34 08 ff 00 ff 57 ff c3 5c 37 00 00 5f + 60783 out 3554:f58a id=8 08 00 00 44 08 00 00 00 00 00 00 00 00 00 00 f9 + 60783 in 3554:f58a id=8 08 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 57 + 60788 out 3554:f58a id=8 08 00 00 e3 02 00 00 00 00 00 00 00 00 00 00 60 + 60788 in 3554:f58a id=8 08 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 4f + 60794 out 3554:f58a id=8 08 00 1b 4c 04 00 00 00 00 00 00 00 00 00 00 da + 60794 in 3554:f58a id=8 08 00 00 e3 02 ff ff 00 00 00 00 00 00 00 00 62 + 60798 in 3554:f58a id=8 08 00 1b 4c 04 ff ff ff ff 00 00 00 00 00 00 de + +=== switching dpi to another one already on the mouse (dpi2, 800) (93905 ms) + 96951 out 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 01 54 00 00 00 55 e8 + 96958 in 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 01 54 00 00 00 55 e8 + +=== switching to dpi 1, 400 (105975 ms) + 107458 out 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 00 55 00 00 00 55 e8 + 107463 in 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 00 55 00 00 00 55 e8 + +=== switching to dpi3, 3200 (118816 ms) + 122181 out 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 02 53 00 00 00 55 e8 + 122186 in 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 02 53 00 00 00 55 e8 + +=== switching back to original, dpi4, 1200 (131228 ms) + 133336 out 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 03 52 00 00 00 55 e8 + 133341 in 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 03 52 00 00 00 55 e8 + +=== changing active dpi4 value to 1500 (150582 ms) + 153256 out 3554:f58a id=8 07 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 88 + 153261 out 3554:f58a id=8 07 00 00 14 08 3f 3f 00 d7 1d 1d 00 1b 00 00 80 + 153261 in 3554:f58a id=8 07 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 88 + 153265 out 3554:f58a id=8 07 00 00 1c 08 17 17 00 27 27 27 00 07 00 00 78 + 153265 in 3554:f58a id=8 07 00 00 14 08 3f 3f 00 d7 1d 1d 00 1b 00 00 80 + 153268 out 3554:f58a id=8 07 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 70 + 153268 in 3554:f58a id=8 07 00 00 1c 08 17 17 00 27 27 27 00 07 00 00 78 + 153271 in 3554:f58a id=8 07 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 70 + +=== back to 1200 (158796 ms) + 161745 out 3554:f58a id=8 07 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 88 + 161751 out 3554:f58a id=8 07 00 00 14 08 3f 3f 00 d7 17 17 00 27 00 00 80 + 161751 in 3554:f58a id=8 07 00 00 0c 08 07 07 00 47 0f 0f 00 37 00 00 88 + 161756 out 3554:f58a id=8 07 00 00 1c 08 17 17 00 27 27 27 00 07 00 00 78 + 161757 in 3554:f58a id=8 07 00 00 14 08 3f 3f 00 d7 17 17 00 27 00 00 80 + 161762 out 3554:f58a id=8 07 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 70 + 161762 in 3554:f58a id=8 07 00 00 1c 08 17 17 00 27 27 27 00 07 00 00 78 + 161767 in 3554:f58a id=8 07 00 00 24 08 3f 3f 00 d7 3f 3f 00 d7 00 00 70 + +=== changing polling rate to 500 (181352 ms) + 182267 out 3554:f58a id=8 07 00 00 00 0a 02 53 04 51 03 52 00 00 00 55 e8 + 182272 in 3554:f58a id=8 07 00 00 00 0a 02 53 04 51 03 52 00 00 00 55 e8 + +=== back to 1k (188268 ms) + 189111 out 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 03 52 00 00 00 55 e8 + 189120 in 3554:f58a id=8 07 00 00 00 0a 01 54 04 51 03 52 00 00 00 55 e8 + +=== changing LOD to 2mm (215151 ms) + 216487 out 3554:f58a id=8 07 00 00 0a 02 02 53 00 00 00 00 00 00 00 00 e5 + 216493 in 3554:f58a id=8 07 00 00 0a 02 02 53 00 00 00 00 00 00 00 00 e5 + +=== back to 1mm (220813 ms) + 221928 out 3554:f58a id=8 07 00 00 0a 02 01 54 00 00 00 00 00 00 00 00 e5 + 221934 in 3554:f58a id=8 07 00 00 0a 02 01 54 00 00 00 00 00 00 00 00 e5 + +=== dbeounce to 20ms (232856 ms) + 233852 out 3554:f58a id=8 07 00 00 a9 0a 14 41 00 55 06 4f 00 55 00 55 ea + 233856 in 3554:f58a id=8 07 00 00 a9 0a 14 41 00 55 06 4f 00 55 00 55 ea + +=== back to 4ms (237797 ms) + 239228 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 239232 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + +=== to 0ms (242390 ms) + 245404 out 3554:f58a id=8 07 00 00 a9 0a 00 55 00 55 06 4f 00 55 00 55 ea + 245407 in 3554:f58a id=8 07 00 00 a9 0a 00 55 00 55 06 4f 00 55 00 55 ea + +=== back to 4ms (248662 ms) + 249919 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 249923 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + +=== enablign movement sync (267388 ms) + 268547 out 3554:f58a id=8 07 00 00 a9 0a 04 51 01 54 06 4f 00 55 00 55 ea + 268552 in 3554:f58a id=8 07 00 00 a9 0a 04 51 01 54 06 4f 00 55 00 55 ea + +=== disabling (272721 ms) + 273821 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 273826 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + +=== changing sleep timer to 30min (283260 ms) + 284457 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 b4 a1 00 55 00 55 ea + 284462 out 3554:f58a id=8 07 00 00 b5 06 01 54 b4 a1 01 54 00 00 00 00 8c + 284462 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 b4 a1 00 55 00 55 ea + 284467 in 3554:f58a id=8 07 00 00 b5 06 01 54 b4 a1 01 54 00 00 00 00 8c + +=== back to 1min (287285 ms) + 288400 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 288404 out 3554:f58a id=8 07 00 00 b5 06 01 54 06 4f 01 54 00 00 00 00 8c + 288404 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 288408 in 3554:f58a id=8 07 00 00 b5 06 01 54 06 4f 01 54 00 00 00 00 8c + +=== enabling ripple contrl (299671 ms) + 300691 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 01 54 ea + 300696 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 01 54 ea + +=== disabling (303150 ms) + 304350 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 304355 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + +=== changing dpi4 color (321693 ms) + 325622 out 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 325626 out 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 5c ff 7c 7e 00 00 60 + 325626 in 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 325629 out 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 325629 in 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 5c ff 7c 7e 00 00 60 + 325635 out 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + 325635 in 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 325640 in 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + 326633 out 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 326638 out 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 2b a6 44 40 00 00 60 + 326638 in 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 326642 out 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 326642 in 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 2b a6 44 40 00 00 60 + 326646 out 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + 326646 in 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 326651 in 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + 328291 out 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 328295 out 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 00 00 00 55 00 00 60 + 328295 in 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 328298 out 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 328298 in 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 00 00 00 55 00 00 60 + 328303 out 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + 328303 in 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 328309 in 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + +=== changed it to black, changing back to orange (340225 ms) + 344711 out 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 344715 out 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 96 a7 16 02 00 00 60 + 344715 in 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 344719 out 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 344719 in 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 96 a7 16 02 00 00 60 + 344724 out 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + 344724 in 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 344730 in 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + 345571 out 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 345576 out 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 a7 88 16 10 00 00 60 + 345576 in 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 345581 out 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 345581 in 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 a7 88 16 10 00 00 60 + 345585 out 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + 345585 in 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 345589 in 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + 346517 out 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 346521 out 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 df b6 20 a0 00 00 60 + 346521 in 3554:f58a id=8 07 00 00 2c 08 ff 00 00 56 00 ff 00 56 00 00 68 + 346525 out 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 346525 in 3554:f58a id=8 07 00 00 34 08 ff 00 ff 57 df b6 20 a0 00 00 60 + 346528 out 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + 346528 in 3554:f58a id=8 07 00 00 3c 08 ff c3 5c 37 ff ff 00 57 00 00 58 + 346532 in 3554:f58a id=8 07 00 00 44 08 ff 00 ff 57 ff 00 ff 57 00 00 50 + +=== enabling straight line correction (377876 ms) + 379065 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 01 54 00 55 ea + 379070 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 01 54 00 55 ea + +=== disabling (381729 ms) + 382778 out 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + 382783 in 3554:f58a id=8 07 00 00 a9 0a 04 51 00 55 06 4f 00 55 00 55 ea + +=== enabling dpi light (always on) (393093 ms) + 393912 out 3554:f58a id=8 07 00 00 4c 08 01 54 80 d5 05 50 01 54 00 00 9e + 393916 in 3554:f58a id=8 07 00 00 4c 08 01 54 80 d5 05 50 01 54 00 00 9e + +=== changing it to breathing (402089 ms) + 403064 out 3554:f58a id=8 07 00 00 4c 08 02 53 80 d5 05 50 01 54 00 00 9e + 403069 in 3554:f58a id=8 07 00 00 4c 08 02 53 80 d5 05 50 01 54 00 00 9e + +=== changing breathing speed to slowest from fastest (options: slowest, medium fastest) (436244 ms) + 437525 out 3554:f58a id=8 07 00 00 4c 08 02 53 80 d5 01 54 01 54 00 00 9e + 437530 in 3554:f58a id=8 07 00 00 4c 08 02 53 80 d5 01 54 01 54 00 00 9e + +=== changing back to always on (444684 ms) + 445716 out 3554:f58a id=8 07 00 00 4c 08 01 54 80 d5 01 54 01 54 00 00 9e + 445720 in 3554:f58a id=8 07 00 00 4c 08 01 54 80 d5 01 54 01 54 00 00 9e + +=== changing brightness from medium to min (min, medium, max) (459891 ms) + 461295 out 3554:f58a id=8 07 00 00 4c 08 01 54 10 45 01 54 01 54 00 00 9e + 461300 in 3554:f58a id=8 07 00 00 4c 08 01 54 10 45 01 54 01 54 00 00 9e + +=== turning off dpi light effect (486691 ms) + 487735 out 3554:f58a id=8 07 00 00 4c 08 00 00 10 45 01 54 00 55 00 00 f3 + 487740 in 3554:f58a id=8 07 00 00 4c 08 00 00 10 45 01 54 00 55 00 00 f3 + +=== enabling ultra range mode (495739 ms) + 496913 out 3554:f58a id=8 16 00 00 00 0a 01 00 00 00 00 00 00 00 00 00 2c + 497010 in 3554:f58a id=8 16 00 00 00 0a 01 00 00 00 00 00 00 00 00 00 2c + +=== disabliing (501783 ms) + 502785 out 3554:f58a id=8 16 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2d + 502880 in 3554:f58a id=8 16 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 2d diff --git a/docs/vxe-r1-pro-testing.md b/docs/vxe-r1-pro-testing.md new file mode 100644 index 00000000..205dce2f --- /dev/null +++ b/docs/vxe-r1-pro-testing.md @@ -0,0 +1,95 @@ +# VXE R1 Pro hardware notes + +This document records what was verified on a real VXE R1 Pro for the ATK +driver. Only the 1K receiver was tested; the wired transport is untested and +stays read-only. + +## Identity and transport + +- Receiver: VID/PID `0x3554:0xf58a`, product string "VXE NordicMouse 1K + Dongle". This is the same USB id as the R1 Pro Max receiver. +- Mouse identity (`GetMouseCIDMID`, command `0x10`): CID `0x02`, MID `0x08`, + firmware 1.20. +- Sensor: PAW3395 (50-DPI step codec). +- Configuration collection: usage page `0xff02`, usage `0x02`. + +ATK HUB lists the wired R1 Pro as CID/MID `2,7` on `0x3554:0xf58c`; the +hardware reports `2,8` through the receiver. + +### CID/MID is scoped by USB vendor + +Under ATK's `0x373b` vendor id, CID/MID `2,8` is the VXE R1 NK, a PAW3395SE +mouse. The receiver is not in the vendor catalog, so the driver used to fall +back to the only catalog entry with that pair and decode the R1 Pro with the +PAW3395SE codec. That codec has no code `0x07`, so a 400-DPI stage +(`07 07 00 47`) aborted the status read with a checksum error even though the +row's checksum was valid. + +Ten of the twelve Compx (`0x3554`) CID/MID pairs in the catalog name a +different mouse under `0x373b`. A CID/MID-only catalog match is therefore +accepted only when the entry belongs to the connected USB vendor, and the R1 +Pro is registered as a Compx-only identity. + +## Verified receiver behavior + +`captures/vxe-r1-pro/receiver-atk-hub.txt` and +`captures/vxe-r1-pro/receiver-atk-hub-profiles.txt` are logs of ATK HUB +(`v3-hub.atk.store`) changing each setting below. The frames match the R1 Pro +Max receiver protocol, so the R1 Pro reuses those write/echo helpers. Each +setting was then written by the driver on the same mouse, confirmed by +readback, and restored. + +| Setting | Row | Notes | +| --- | --- | --- | +| Polling rate (125–1,000 Hz) | 10-byte system row at `0x0000` | | +| DPI stage count, active stage | 10-byte system row at `0x0000` | Stage count was written by the driver only; HUB's stage-count change was not captured. | +| DPI stage value | 8-byte two-stage group from `0x000c` | 1,500 DPI is `1d 1d 00 1b`. HUB rewrites all four groups; the driver writes the one that changed. | +| Lift-off distance | pair at `0x000a` | 1 = 1 mm, 2 = 2 mm. | +| Debounce, Motion Sync, sleep, straight-line correction, ripple control | 10-byte advanced row at `0x00a9` | Offsets 0, 2, 4, 6, 8. | +| DPI stage colours | 8-byte two-colour group from `0x002c` | | +| DPI lighting | 8-byte row at `0x004c` | See below. | +| Ultra Long Range | command `0x16`, readback `0x17` | | +| Configuration bank (profile) 1–4 | command `0x0f`, readback `0x0e` | Zero-based bank at data offset 0; the receiver echoes the request about 100 ms later. | + +### Profiles and buttons + +The mouse holds four configuration banks. Switching to bank 2 through the +driver changed the reported DPI stages from 400/800/3,200/1,200 to +400/800/1,600/3,200, and switching back restored them, so EEPROM reads follow +the active bank as they do on the other R1s. + +The six button records at `0x0060`–`0x0074` use the R1 layout and are read +only. The stock assignments read as left, right, middle, back, forward and DPI +cycle. + +ATK HUB's "computer config" entries are stored on the PC: applying one selects +bank 4 and rewrites its rows from the host. The driver does not model them. + +### DPI lighting + +The row is `effect | brightness | speed | enabled`, each a value/checksum pair. +Always On and Breathing match the R1 Pro Max. Off differs: + +- ATK HUB sends `00 00 | brightness unchanged | speed | 00 55`. +- The mouse stores `02 53` in the effect pair regardless, so Off is carried by + the enabled flag alone. A row reading `02 53 80 d5 05 50 00 55` is Off. + +The driver sends HUB's Off row, does not require the effect pair to read back, +and decodes enabled = 0 as Off for this identity. + +### Sleep timer + +When the sleep timer changes, ATK HUB also writes the 6-byte row at `0x00b5` +(`01 54 | timer | 01 54`). The driver writes only `0x00a9`, as it does for the +R1 Pro Max; the readback confirms the value, but that the mouse then sleeps on +the new schedule was not timed. + +## Not enabled + +- Button-assignment writes and macros: not captured, and not implemented by + the driver for any R1. +- Performance Mode (`0x00b5` bytes 4–5): ATK HUB showed no such switch for + this mouse, so the driver neither reports nor writes it. +- Separate X/Y DPI: not tested. +- Wired transport: not tested. It is not on the verified-wired list, so + persistent writes stay blocked there. diff --git a/src/drivers/atk/hid.test.ts b/src/drivers/atk/hid.test.ts index 12d4c9ca..e3589a8b 100644 --- a/src/drivers/atk/hid.test.ts +++ b/src/drivers/atk/hid.test.ts @@ -1300,11 +1300,17 @@ test("a mouse behind the generic 8K dongle-L is decoded with the sensor its CID/ }); test("a CID/MID shared by models with different sensors stays on the generic codec behind a receiver", () => { - assert.equal(atkCatalogSensorForCidMid("2,77"), "PAW3395SE"); - assert.equal(atkCatalogSensorForCidMid("1,2"), "PAW3950Ultra"); - assert.equal(atkCatalogSensorForCidMid("2,5"), null); - assert.equal(atkCatalogSensorForCidMid("250,250"), null); - assert.equal(atkCatalogSensorForCidMid(null), null); + assert.equal(atkCatalogSensorForCidMid("2,77", 0x373b), "PAW3395SE"); + assert.equal(atkCatalogSensorForCidMid("1,2", 0x373b), "PAW3950Ultra"); + assert.equal(atkCatalogSensorForCidMid("2,5", 0x373b), null); + assert.equal(atkCatalogSensorForCidMid("250,250", 0x373b), null); + assert.equal(atkCatalogSensorForCidMid(null, 0x373b), null); + // CID/MID 2,8 is the VXE R1 NK under ATK's vendor id only; a Compx (0x3554) + // device reporting it is a different mouse and must not borrow that entry. + assert.equal(atkCatalogSensorForCidMid("2,8", 0x373b), "PAW3395SE"); + assert.equal(atkCatalogSensorForCidMid("2,8", 0x3554), null); + assert.equal(atkCatalogDevice(0x3554, 0xf58a, "2,8"), undefined); + assert.equal(atkCatalogDevice(0x373b, 0x10c9, "2,8")?.model, "VXE R1 NK"); assert.equal(atkCatalogDevice(0x373b, 0x1278, "2,77")?.model, "ATK X1 SE NK"); assert.equal(atkCatalogDevice(0x373b, 0x1278, "2,5"), undefined); }); diff --git a/src/drivers/atk/hid.ts b/src/drivers/atk/hid.ts index e3e88157..7867e8e0 100644 --- a/src/drivers/atk/hid.ts +++ b/src/drivers/atk/hid.ts @@ -45,7 +45,7 @@ import { atkUnpackDpiStage, atkUnpackDpiStageForSensor, } from "@openmouse/protocol/atk"; -import { type AtkProduct, ATK_COMPX_PRODUCT_IDS, ATK_PRODUCTS, atkCatalogDevice, atkCatalogSensorForCidMid, atkCatalogSensorToSensor } from "./products.ts"; +import { type AtkProduct, ATK_COMPX_PRODUCT_IDS, ATK_COMPX_PRODUCTS, ATK_PRODUCTS, atkCatalogDevice, atkCatalogSensorForCidMid, atkCatalogSensorToSensor, atkProductFor } from "./products.ts"; import type { AtkDeviceDescriptor, AtkDeviceFeatures } from "./device-catalog.generated.ts"; import type { AtkSensor } from "@openmouse/protocol/atk"; @@ -156,6 +156,8 @@ export class AtkHidClient { readonly device: HIDDevice; private queue: Promise = Promise.resolve(); + /** Serializes whole read/patch/write transactions on shared EEPROM rows. */ + private rowQueue: Promise = Promise.resolve(); private lastStatus: MouseStatus | null = null; private product: AtkProduct | null = null; private identified = false; @@ -399,6 +401,9 @@ export class AtkHidClient { dpiLighting: r1Extras && this.features().noDpiRGB !== true ? { modes: [0, 1, 2], brightness: [0, 1, 2], + // ATK HUB offers no brightness while breathing on these two, and + // setDpiLighting leaves the stored pair alone in that mode. + brightnessModes: this.isR1ProMax() || this.isR1Pro() ? [1] : undefined, speed: [0, 1, 2], } : undefined, }, @@ -424,7 +429,8 @@ export class AtkHidClient { motionSync: advanced[2] === 1, sleepTimeout: advanced[4] * SLEEP_STEP_SECONDS || null, rippleControl: advanced[8] === 1, - performanceMode: r1Extras?.performanceMode ?? a9PerformanceMode, + // ATK HUB offers no performance-mode switch for the R1 Pro. + performanceMode: this.isR1Pro() ? undefined : r1Extras?.performanceMode ?? a9PerformanceMode, longRangeMode: r1Extras?.longRangeMode, atkSensorMode: f1Extras?.sensorMode ?? null, atkAntiMistouchMs: f1Extras?.antiMistouchMs ?? null, @@ -800,6 +806,7 @@ export class AtkHidClient { async setPerformanceMode(enabled: boolean): Promise { await this.identify(); + if (this.isR1Pro()) throw new Error("Performance mode is not available on this connection."); const change = (block: number[]): void => { block.splice(4, 2, ...wePackScalarPair(enabled ? 1 : 0)); @@ -961,14 +968,19 @@ export class AtkHidClient { // Off = 00 00 | 00 00 | speed | 00 55 // Always On = 01 54 | brightness | speed | 01 54 // Breathing = 02 53 | preserve brightness | speed | 01 54 + // The R1 Pro shares that encoding, except that ATK HUB leaves its + // brightness pair untouched when switching the light off, and the mouse + // keeps its previous effect pair instead of storing 00 00: there, Off is + // carried by the trailing enabled flag alone. const block = Array.from(await this.read(REGISTER.dpiLighting, R1_DPI_LIGHTING_LENGTH)); - const proMax = this.isR1ProMax(); + const r1Pro = this.isR1Pro(); + const proMax = this.isR1ProMax() || r1Pro; const expectedEffect = proMax && mode === 0 ? [0, 0] : wePackScalarPair(mode === 2 ? 2 : 1); - const expectedBrightness = proMax && mode === 2 + const expectedBrightness = (proMax && mode === 2) || (r1Pro && mode === 0) ? [block[2]!, block[3]!] : mode === 0 ? [0, 0] @@ -988,7 +1000,8 @@ export class AtkHidClient { const expectedSpeed = wePackScalarPair(R1_DPI_SPEED[speed]!); const expectedEnabled = wePackScalarPair(mode === 0 ? 0 : 1); const expected = [...expectedEffect, ...expectedBrightness, ...expectedSpeed, ...expectedEnabled]; - if (!expected.every((byte, index) => raw[index] === byte)) { + const firstChecked = r1Pro && mode === 0 ? expectedEffect.length : 0; + if (!expected.every((byte, index) => index < firstChecked || raw[index] === byte)) { throw new Error("The mouse did not retain its DPI lighting settings."); } @@ -1173,10 +1186,12 @@ export class AtkHidClient { /** The advanced block is written whole, so read it back, patch one pair, write. */ private async writeAdvanced(offset: number, value: number): Promise { - const group = Array.from(await this.read(REGISTER.advanced, ADVANCED_LENGTH)); - group.splice(offset, 2, ...wePackScalarPair(value)); - await this.write(REGISTER.advanced, group); - return (await this.read(REGISTER.advanced, ADVANCED_LENGTH))[offset]; + return await this.inRowTransaction(async () => { + const group = Array.from(await this.read(REGISTER.advanced, ADVANCED_LENGTH)); + group.splice(offset, 2, ...wePackScalarPair(value)); + await this.write(REGISTER.advanced, group); + return (await this.read(REGISTER.advanced, ADVANCED_LENGTH))[offset]; + }); } /** @@ -1324,6 +1339,11 @@ export class AtkHidClient { if (brightnessIndex < 0 || speedIndex < 0 || (enabled !== 0 && enabled !== 1)) return null; + // The R1 Pro stores Off as enabled=0 and leaves the last effect in place. + if (this.isR1Pro() && enabled === 0) { + return { dpiLedMode: 0, dpiLedBrightness: brightnessIndex, dpiLedSpeed: speedIndex }; + } + // R1 Pro Max may report the trailing flag as 0 after reconnect even when // the stored effect is Breathing. Treat the effect field as authoritative. // Keep effect=1 + enabled=0 as the legacy Off encoding used by other R1s. @@ -1422,7 +1442,14 @@ export class AtkHidClient { const stage = sensor ? atkUnpackDpiStageForSensor(sensor, data) : atkUnpackDpiStage(data); - if (!stage) throw new Error("The mouse reported a DPI stage that failed its checksum."); + if (!stage) { + // A row can sum correctly and still hold a value this sensor's codec + // rejects, which points at a misidentified model rather than bad data. + const checksumValid = data.reduce((total, byte) => total + byte, 0) % 0x100 === 0x55; + throw new Error(checksumValid + ? "The mouse reported a DPI stage this sensor cannot produce; the model may be misidentified." + : "The mouse reported a DPI stage that failed its checksum."); + } return stage; } @@ -1583,7 +1610,7 @@ export class AtkHidClient { } this.identified = true; this.cidMid = `${reply[DATA_OFFSET]},${reply[DATA_OFFSET + 1]}`; - this.product = ATK_PRODUCTS[this.cidMid] ?? null; + this.product = atkProductFor(this.device.vendorId, this.cidMid); } /** @@ -1615,7 +1642,7 @@ export class AtkHidClient { */ private sensorKey(): AtkSensor | null { if (this.product) return this.product.sensor; - return atkCatalogSensorToSensor(this.catalogEntry()?.sensor ?? null) ?? atkCatalogSensorForCidMid(this.cidMid); + return atkCatalogSensorToSensor(this.catalogEntry()?.sensor ?? null) ?? atkCatalogSensorForCidMid(this.cidMid, this.device.vendorId); } private usesSharedR1Transport(): boolean { @@ -1635,10 +1662,21 @@ export class AtkHidClient { return this.product === ATK_PRODUCTS["2,27"]; } + /** VXE R1 Pro (Compx CID 2, MID 8), captured behind the F58A 1K dongle. */ + private isR1Pro(): boolean { + return this.device.vendorId === VENDOR_ID.vgn && this.product === ATK_COMPX_PRODUCTS["2,8"]; + } + + /** + * The F58A dongle's captured write/echo protocol. The R1 Pro Max and the R1 + * Pro both pair with this dongle and ATK HUB sends them the same rows, so + * the R1 Pro reuses the Pro Max receiver helpers for the settings that were + * captured on it; see docs/vxe-r1-pro-testing.md for what was not. + */ private usesVerifiedR1ProMaxReceiverTransport(): boolean { return this.device.vendorId === VENDOR_ID.vgn && this.device.productId === VXE_R1_PRO_MAX_RECEIVER_PID - && this.isR1ProMax(); + && (this.isR1ProMax() || this.isR1Pro()); } /** @@ -1735,32 +1773,34 @@ export class AtkHidClient { } const address = REGISTER.advanced; - const block = Array.from(await this.read(address, ADVANCED_LENGTH)); - block.splice(offset, 2, ...wePackScalarPair(value)); - - const payload = weBuildCmdPayload( - WE_CMD_WRITE_EEPROM, - [ - 0, - (address >> 8) & 0xff, - address & 0xff, - block.length, - ...block, - ], - ); + return await this.inRowTransaction(async () => { + const block = Array.from(await this.read(address, ADVANCED_LENGTH)); + block.splice(offset, 2, ...wePackScalarPair(value)); + + const payload = weBuildCmdPayload( + WE_CMD_WRITE_EEPROM, + [ + 0, + (address >> 8) & 0xff, + address & 0xff, + block.length, + ...block, + ], + ); - await this.exchange( - payload, - (frame) => frame[0] === WE_CMD_WRITE_EEPROM - && frame[1] === 0 - && frame[2] === ((address >> 8) & 0xff) - && frame[3] === (address & 0xff) - && frame[4] === block.length - && this.hasValidChecksum(frame) - && block.every((byte, index) => frame[DATA_OFFSET + index] === byte), - ); + await this.exchange( + payload, + (frame) => frame[0] === WE_CMD_WRITE_EEPROM + && frame[1] === 0 + && frame[2] === ((address >> 8) & 0xff) + && frame[3] === (address & 0xff) + && frame[4] === block.length + && this.hasValidChecksum(frame) + && block.every((byte, index) => frame[DATA_OFFSET + index] === byte), + ); - return (await this.read(address, ADVANCED_LENGTH))[offset]!; + return (await this.read(address, ADVANCED_LENGTH))[offset]!; + }); } /** @@ -1923,6 +1963,18 @@ export class AtkHidClient { this.queue = started.catch(() => undefined); return await started; } + + /** + * Holds a whole read/patch/write of a shared row, so two setters patching + * different fields cannot both read the old row and overwrite each other. + * The task's own reads and writes still go through run(); this is a + * separate chain, so nesting cannot deadlock. + */ + private async inRowTransaction(task: () => Promise): Promise { + const started = this.rowQueue.then(task, task); + this.rowQueue = started.catch(() => undefined); + return await started; + } } function copyDataView(view: DataView): Uint8Array { diff --git a/src/drivers/atk/products.ts b/src/drivers/atk/products.ts index 9a6d6992..66fb2944 100644 --- a/src/drivers/atk/products.ts +++ b/src/drivers/atk/products.ts @@ -53,19 +53,25 @@ export function atkCatalogDevice( ): AtkDeviceDescriptor | undefined { const byUsbId = atkDeviceForHid(vendorId, productId, cidMid); if (byUsbId || !cidMid || atkDevicesForHid(vendorId, productId).length > 0) return byUsbId; + // CID/MID numbering restarts per USB vendor: Compx (0x3554) "2,8" is the + // VXE R1 Pro while ATK (0x373b) "2,8" is the VXE R1 NK, a different sensor. + // A CID/MID-only match is trusted only within the connected vendor. const byCidMid = atkDevicesForCidMid(cidMid); - return byCidMid.length === 1 ? byCidMid[0] : undefined; + return byCidMid.length === 1 && byCidMid[0]!.vendorId === vendorId ? byCidMid[0] : undefined; } /** * Sensor shared by every catalog model with this CID/MID. Receivers enumerate * under their own USB id, so the paired mouse is known only by CID/MID; the * pair is not unique, but when every model sharing it has the same sensor the - * DPI codec is still unambiguous. + * DPI codec is still unambiguous. A pair listed only under another USB vendor + * is ignored, because the same pair names unrelated mice there. */ -export function atkCatalogSensorForCidMid(cidMid: string | null): AtkSensor | null { +export function atkCatalogSensorForCidMid(cidMid: string | null, vendorId: number): AtkSensor | null { if (!cidMid) return null; - const sensors = new Set(atkDevicesForCidMid(cidMid).map((device) => atkCatalogSensorToSensor(device.sensor))); + const devices = atkDevicesForCidMid(cidMid); + if (!devices.some((device) => device.vendorId === vendorId)) return null; + const sensors = new Set(devices.map((device) => atkCatalogSensorToSensor(device.sensor))); const [only] = sensors; return sensors.size === 1 && only ? only : null; } @@ -84,5 +90,27 @@ export const ATK_PRODUCTS: Record = { "2,83": { brand: "ATK", model: "A9 Plus Nearlink", sensor: "PAW3395", maxPollingHz: 1000, verified: true }, }; +/** + * Identities that exist only under Compx's USB vendor id (0x3554), where the + * same CID/MID means a different mouse than it does under ATK's 0x373b. + * + * "2,8" is the VXE R1 Pro as reported through the 0x3554:0xf58a 1K dongle + * (firmware 1.20). ATK HUB lists the wired mouse as "2,7", one below. The + * verified R1 ("2,12", listed "2,11") and R1 SE+ ("2,32", listed "2,31") + * entries above sit one above their HUB listings in the same way. + */ +export const ATK_COMPX_PRODUCTS: Record = { + "2,8": { brand: "VXE", model: "R1 Pro", sensor: "PAW3395", family: "r1", verified: true }, +}; + +const COMPX_VENDOR_ID = 0x3554; + +/** Hand-built identity for a CID/MID reply, scoped by the USB vendor that answered. */ +export function atkProductFor(vendorId: number, cidMid: string): AtkProduct | null { + return (vendorId === COMPX_VENDOR_ID ? ATK_COMPX_PRODUCTS[cidMid] : undefined) + ?? ATK_PRODUCTS[cidMid] + ?? null; +} + /** Known VXE R1-family transports under COMPX's shared vendor id. */ export const ATK_COMPX_PRODUCT_IDS: readonly number[] = [0xf58a, 0xf58c, 0xf58e, 0xf58f]; diff --git a/src/drivers/atk/r1-pro-max-hid.test.ts b/src/drivers/atk/r1-pro-max-hid.test.ts index 4d74c729..392a5dc4 100644 --- a/src/drivers/atk/r1-pro-max-hid.test.ts +++ b/src/drivers/atk/r1-pro-max-hid.test.ts @@ -787,4 +787,186 @@ test("R1 Pro Max accepts firmware-normalized Breathing state after reconnect", ( dpiLedBrightness: 1, dpiLedSpeed: 0, }); -}); \ No newline at end of file +}); +test("R1 Pro over the Compx 1K dongle decodes PAW3395 stages instead of borrowing the ATK-vendor R1 NK codec", async () => { + // Replies captured from a VXE R1 Pro (firmware 1.20) behind 0x3554:0xf58a + // "VXE NordicMouse 1K Dongle". It reports CID/MID 2,8, which under ATK's + // 0x373b vendor id is the PAW3395SE-based VXE R1 NK; that codec has no code + // 0x07, so the 400-DPI stage used to abort the whole status read. + const fake = device(0xf58a, "VXE NordicMouse 1K Dongle"); + (fake as unknown as FakeR1ProMaxDevice).replies = [ + reply(0x10, 0, [0x02, 0x08, 0x4b]), + reply(0x04, 0, [0x14, 0x00]), + reply(0x08, 0x0000, [0x01, 0x54, 0x04, 0x51, 0x03, 0x52]), + reply(0x08, 0x000c, [0x07, 0x07, 0x00, 0x47]), + reply(0x08, 0x0010, [0x0f, 0x0f, 0x00, 0x37]), + reply(0x08, 0x0014, [0x3f, 0x3f, 0x00, 0xd7]), + reply(0x08, 0x0018, [0x17, 0x17, 0x00, 0x27]), + reply(0x12, 0, [0x01, 0x20]), + reply(0x08, 0x000a, [0x01, 0x54]), + reply(0x08, 0x00a9, [0x04, 0x51, 0x00, 0x55, 0x06, 0x4f, 0x00, 0x55, 0x00, 0x55]), + reply(0x08, 0x00bd, [0xff, 0xff, 0xff, 0xff]), + reply(0x08, 0x00b5, [0x00, 0x55, 0x06, 0x4f, 0x01, 0x54]), + reply(0x08, 0x004c, [0x02, 0x53, 0x80, 0xd5, 0x05, 0x50, 0x00, 0x55]), + reply(0x08, 0x002c, [0xff, 0x00, 0x00, 0x56, 0x00, 0xff, 0x00, 0x56]), + reply(0x08, 0x0034, [0xff, 0x00, 0xff, 0x57, 0xff, 0xc3, 0x5c, 0x37]), + reply(0x17, 0, [0x00]), + reply(0x0e, 0, [0x00]), + reply(0x08, 0x0060, [0x01, 0x01, 0x00, 0x53, 0x01, 0x02, 0x00, 0x52]), + reply(0x08, 0x0068, [0x01, 0x04, 0x00, 0x50, 0x01, 0x08, 0x00, 0x4c]), + reply(0x08, 0x0070, [0x01, 0x10, 0x00, 0x44, 0x02, 0x01, 0x00, 0x52]), + ]; + + const client = new AtkHidClient(fake); + const status = await client.readStatus(); + + assert.deepEqual(status.dpiStageColors, ["#ff0000", "#00ff00", "#ff00ff", "#ffc35c"]); + assert.equal(status.dpiLedMode, 0, "enabled flag 0 is Off even with a Breathing effect pair stored"); + assert.deepEqual(status.ui?.dpiLighting?.brightnessModes, [1], "no brightness control while breathing"); + assert.equal(status.longRangeMode, false); + assert.equal(status.performanceMode, undefined); + assert.equal(status.activeProfile, 1); + assert.equal(status.atkProfileCount, 4); + assert.deepEqual( + status.atkButtonMappings?.map((mapping) => mapping.action), + ["Left click", "Right click", "Middle click", "Back", "Forward", "DPI cycle"], + ); + assert.equal(status.name, "VXE R1 Pro"); + assert.deepEqual(status.dpiStages, [400, 800, 3200, 1200]); + assert.equal(status.activeDpiStage, 3); + assert.equal(status.dpi, 1200); + assert.equal(status.pollingRateHz, 1000); + assert.equal(status.connectionDetail, "2.4 GHz receiver"); + assert.equal(status.atkCatalogFeatures, undefined, "no ATK-vendor catalog flags leak onto a Compx device"); + assert.equal(client.maxDpi(), 30000); +}); + +test("a DPI row with a valid checksum but an impossible sensor code is not reported as a checksum failure", async () => { + // CID/MID 2,29 on 0xf58f is the catalog's PAW3395SE-based R1 SE; 0x07 is + // one of the codes that sensor never uses. + const fake = device(0xf58f, "VXE R1 SE"); + (fake as unknown as FakeR1ProMaxDevice).replies = [ + reply(0x10, 0, [0x02, 0x1d]), + reply(0x04, 0, [0x14, 0x00]), + reply(0x08, 0x0000, [0x01, 0x54, 0x01, 0x54, 0x00, 0x55]), + reply(0x08, 0x000c, [0x07, 0x07, 0x00, 0x47]), + ]; + + await assert.rejects( + new AtkHidClient(fake).readStatus(), + /cannot produce; the model may be misidentified/, + ); +}); + +// Frames below were captured from ATK HUB (v3-hub.atk.store) driving a VXE R1 +// Pro, firmware 1.20, through the 0x3554:0xf58a 1K dongle. +const R1_PRO_IDENTITY = reply(0x10, 0, [0x02, 0x08, 0x4b]); +const R1_PRO_SYSTEM = [0x01, 0x54, 0x04, 0x51, 0x03, 0x52, 0x00, 0x55, 0x00, 0x55]; + +function r1ProReceiver(): FakeR1ProMaxDevice { + return device(0xf58a, "VXE NordicMouse 1K Dongle") as unknown as FakeR1ProMaxDevice; +} + +test("R1 Pro receiver writes a DPI stage as the vendor's two-stage group and waits for the echo", async () => { + const fake = r1ProReceiver(); + const group = [0x3f, 0x3f, 0x00, 0xd7, 0x1d, 0x1d, 0x00, 0x1b]; + fake.replies = [ + R1_PRO_IDENTITY, + reply(0x08, 0x0000, R1_PRO_SYSTEM.slice(0, 6)), + reply(0x08, 0x0014, [0x3f, 0x3f, 0x00, 0xd7, 0x17, 0x17, 0x00, 0x27]), + reply(0x08, 0x0018, [0x1d, 0x1d, 0x00, 0x1b]), + ]; + fake.writeReplies = [reply(0x07, 0x0014, group)]; + + const client = new AtkHidClient(fake as unknown as HIDDevice); + assert.equal(await client.setDpiStageValue(3, 1500), 1500); + + const sent = writes(fake as unknown as HIDDevice); + assert.equal(sent.length, 1); + assert.deepEqual([...sent[0]!.subarray(0, 13)], [0x07, 0x00, 0x00, 0x14, 0x08, ...group]); + assert.equal(sent[0]![15], 0x80, "frame checksum matches the captured vendor write"); +}); + +test("R1 Pro receiver changes polling through the complete system row", async () => { + const fake = r1ProReceiver(); + const row = [0x02, 0x53, ...R1_PRO_SYSTEM.slice(2)]; + fake.replies = [ + R1_PRO_IDENTITY, + reply(0x08, 0x0000, R1_PRO_SYSTEM), + reply(0x08, 0x0000, row.slice(0, 6)), + ]; + fake.writeReplies = [reply(0x07, 0x0000, row)]; + + const client = new AtkHidClient(fake as unknown as HIDDevice); + assert.equal(await client.setPollingRate(500), 500); + assert.deepEqual([...writes(fake as unknown as HIDDevice)[0]!.subarray(0, 15)], [0x07, 0x00, 0x00, 0x00, 0x0a, ...row]); +}); + +test("R1 Pro receiver turns DPI lighting off through the enabled flag and keeps the stored brightness", async () => { + const fake = r1ProReceiver(); + const sentRow = [0x00, 0x00, 0x10, 0x45, 0x01, 0x54, 0x00, 0x55]; + fake.replies = [ + R1_PRO_IDENTITY, + reply(0x08, 0x004c, [0x01, 0x54, 0x10, 0x45, 0x01, 0x54, 0x01, 0x54]), + // The mouse keeps a Breathing effect pair rather than the 00 00 it was sent. + reply(0x08, 0x004c, [0x02, 0x53, 0x10, 0x45, 0x01, 0x54, 0x00, 0x55]), + ]; + fake.writeReplies = [reply(0x07, 0x004c, sentRow)]; + + const client = new AtkHidClient(fake as unknown as HIDDevice); + await client.setDpiLighting(0, 0, 0); + + const sent = writes(fake as unknown as HIDDevice); + assert.deepEqual([...sent[0]!.subarray(0, 13)], [0x07, 0x00, 0x00, 0x4c, 0x08, ...sentRow]); + assert.equal(sent[0]![15], 0xf3, "frame checksum matches the captured vendor write"); +}); + +test("R1 Pro receiver switches configuration banks with the captured select/echo/readback exchange", async () => { + const fake = r1ProReceiver(); + const select = reply(0x0f, 0, [0x01]); + fake.replies = [R1_PRO_IDENTITY, select, reply(0x0e, 0, [0x01])]; + + const client = new AtkHidClient(fake as unknown as HIDDevice); + assert.equal(await client.setR1ActiveProfile(2), 2); + + const sent = fake.sent.map(({ data }) => [...data]).find((frame) => frame[0] === 0x0f); + assert.deepEqual(sent, select); + assert.equal(select[15], 0x3c, "frame checksum matches the captured vendor write"); +}); + +test("R1 Pro receiver refuses Performance Mode, which ATK HUB does not offer for it", async () => { + const fake = r1ProReceiver(); + fake.replies = [R1_PRO_IDENTITY]; + + const client = new AtkHidClient(fake as unknown as HIDDevice); + await assert.rejects(client.setPerformanceMode(true), /Performance mode is not available/); + assert.equal(writes(fake as unknown as HIDDevice).length, 0); +}); + +test("R1 Pro Max receiver keeps concurrent advanced-row writes from overwriting each other", async () => { + const fake = device(0xf58a, "VXE R1 Pro Max Receiver"); + const hardware = fake as unknown as FakeR1ProMaxDevice; + // Stateful advanced row: reads return what the last write stored. + let row = [0x04, 0x51, 0x01, 0x54, 0x06, 0x4f, 0x01, 0x54, 0x01, 0x54]; + const send = hardware.sendReport.bind(hardware); + hardware.sendReport = async (reportId: number, data: ArrayBuffer) => { + const frame = new Uint8Array(data); + if (frame[0] === 0x10) hardware.replies = [reply(0x10, 0, [0x02, 0x1b])]; + if (frame[0] === 0x08 && frame[3] === 0xa9) hardware.replies = [reply(0x08, 0x00a9, row)]; + if (frame[0] === 0x07 && frame[3] === 0xa9) { + row = [...frame.subarray(5, 15)]; + hardware.writeReplies = [reply(0x07, 0x00a9, row)]; + } + await send(reportId, data); + }; + + const client = new AtkHidClient(fake); + const [motionSync, ripple] = await Promise.all([ + client.setMotionSync(false), + client.setRippleControl(false), + ]); + + assert.equal(motionSync, false); + assert.equal(ripple, false); + assert.deepEqual(row, [0x04, 0x51, 0x00, 0x55, 0x06, 0x4f, 0x01, 0x54, 0x00, 0x55]); +}); diff --git a/src/drivers/mouse-types.ts b/src/drivers/mouse-types.ts index 78bb6c0f..91643724 100644 --- a/src/drivers/mouse-types.ts +++ b/src/drivers/mouse-types.ts @@ -77,6 +77,11 @@ export interface MouseUiHints { dpiLighting?: { modes: readonly (0 | 1 | 2)[]; brightness: readonly number[]; + /** + * Modes in which brightness can be changed. Omitted when every lit mode + * accepts it; a mouse whose breathing effect has no brightness lists [1]. + */ + brightnessModes?: readonly (1 | 2)[]; speed: readonly number[]; /** Optional DPI-indicator-only sleep values in seconds. */ sleepTimeouts?: readonly number[];