Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions src/drivers/lamzu/hid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,10 +413,27 @@ test("each Inca connection gets the rate list that connection actually offers",
assert.equal(LAMZU_INCA_PRODUCTS.get(0x0010)?.wireless, true);
});

test("the Inca's DFU bootloader identities are not offered as mice", () => {
// 0x000a is the mouse's flashing identity and 0x0002 the dongle's; neither
// speaks the config protocol, so a picker entry for them would be dead.
for (const bootloader of [0x000a, 0x0002]) {
test("the Paro Aurora carries the same split as the Inca, from the same vendor table", () => {
// Issue #167: Lamzu's own env-models.json gives the Paro Aurora PIDWired
// 0x0007, _1KDongle 0x000d and _8KDongle 0x000e, with the same
// IsNewProtocol/IsCompx flags and DPIMax as the Inca. None exercised on
// hardware yet, so the catalog is the only claim.
assert.equal(lamzuProduct(LAMZU_INCA_VENDOR_ID, 0x0007)?.model, "Paro Aurora");
assert.equal(lamzuProduct(LAMZU_INCA_VENDOR_ID, 0x000d)?.model, "Paro Aurora");
assert.equal(lamzuProduct(LAMZU_INCA_VENDOR_ID, 0x000e)?.model, "Paro Aurora");
assert.deepEqual(LAMZU_INCA_PRODUCTS.get(0x0007)?.pollingRates, [125, 250, 500, 1000]);
assert.deepEqual(LAMZU_INCA_PRODUCTS.get(0x000d)?.pollingRates, [125, 250, 500, 1000]);
assert.deepEqual(LAMZU_INCA_PRODUCTS.get(0x000e)?.pollingRates, [500, 1000, 2000, 4000, 8000]);
assert.equal(LAMZU_INCA_PRODUCTS.get(0x0007)?.wireless, false);
assert.equal(LAMZU_INCA_PRODUCTS.get(0x000d)?.wireless, true);
assert.equal(LAMZU_INCA_PRODUCTS.get(0x000e)?.wireless, true);
});

test("the Inca's and Paro Aurora's DFU bootloader identities are not offered as mice", () => {
// 0x000a is the Inca mouse's flashing identity and 0x0002 the shared dongle's;
// the Paro adds 0x0008 (mouse) and 0x0004 (1K dongle). None speaks the config
// protocol, so a picker entry for one would be dead.
for (const bootloader of [0x000a, 0x0002, 0x0008, 0x0004]) {
assert.equal(LAMZU_INCA_PRODUCTS.has(bootloader), false);
assert.equal(LamzuHidClient.isSupported(fakeInca(bootloader)), false);
}
Expand Down
15 changes: 14 additions & 1 deletion src/lamzu/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,28 @@ export const LAMZU_VENDOR_IDS: readonly number[] = [LAMZU_VENDOR_ID, LAMZU_INCA_
* has NOT been exercised on hardware; the protocol is the receiver protocol
* either way, so the risk is a wrong rate list rather than a dead device.
*
* The Paro Aurora (released mid-2025, PAW3950) is also entered here from that
* table, under the same vendor id and protocol flags as the Inca
* (`IsNewProtocol`: 1, `IsCompx`: 0, `DPIMax` 30000 — the driver default, so
* no `maxDpi` override). Its three ids are `PIDWired` 0x0007 (125-1000),
* `_1KDongle` 0x000d (125-1000) and `_8KDongle` 0x000e (500-8000). None of
* them has been exercised on hardware yet — issue #167 — so a wrong rate list
* is the failure mode, not a dead device.
*
* Deliberately absent: 0x000a and 0x0002, which Aurora lists as
* `DeviceBLPID` and `Receiver4K8KBLPID` — the DFU bootloader identities the
* mouse and dongle take while flashing firmware. They never speak this
* protocol and must not be offered in the picker.
* protocol and must not be offered in the picker. The Paro's own bootloader
* ids, 0x0008 (`DeviceBLPID`) and 0x0004 (`_1KDongleIDVD`), are excluded for
* the same reason; its 8K dongle shares 0x0002 with the Inca.
*/
export const LAMZU_INCA_PRODUCTS: ReadonlyMap<number, LamzuProduct> = new Map([
[0x0009, { model: "Inca 8K", wireless: false, pollingRates: RATES_1K }],
[0x000f, { model: "Inca 8K", wireless: true, pollingRates: RATES_1K }],
[0x0010, { model: "Inca 8K", wireless: true, pollingRates: RATES_8K }],
[0x0007, { model: "Paro Aurora", wireless: false, pollingRates: RATES_1K }],
[0x000d, { model: "Paro Aurora", wireless: true, pollingRates: RATES_1K }],
[0x000e, { model: "Paro Aurora", wireless: true, pollingRates: RATES_8K }],
]);

/**
Expand Down
Loading