# Pair a LIGHTSPEED mouse to the G903 receiver (046D:C539) via HID++ register 0xB2. Add-Type -Path (Join-Path $PSScriptRoot 'Hidpp.cs') $rx = New-Object HidppReceiver (, [HidppReceiver]::Find('vid_046d&pid_c539')) function Reg([byte[]]$req) { while ($rx.Next(0)) {} $rx.Send($req) $deadline = (Get-Date).AddSeconds(2) while ((Get-Date) -lt $deadline) { $r = $rx.Next(200) if ($r -and $r[1] -eq 0xFF -and ($r[2] -eq $req[2] -or $r[2] -eq 0x8F)) { return ,$r } } return $null } function SlotInfo { $p = Reg ([byte[]](0x10,0xFF,0x83,0xB5,0x20,0,0)) $n = Reg ([byte[]](0x10,0xFF,0x83,0xB5,0x40,0,0)) if ($p -and $p[2] -eq 0x83) { $name = if ($n -and $n[2] -eq 0x83) { [Text.Encoding]::ASCII.GetString($n, 6, $n[5]) } else { '?' } "Slot 1: wpid 0x{0:X2}{1:X2} name '{2}'" -f $p[7], $p[8], $name } else { "Slot 1: empty ({0})" -f [HidppReceiver]::Hex($p) } } try { Write-Host "" Write-Host "Before: $(SlotInfo)" Write-Host "" Write-Host "STEP 1: Unplug the USB cable from the G903 and switch the mouse OFF (switch on the underside)." -ForegroundColor Yellow Read-Host " Press Enter when it's off" for ($attempt = 1; $attempt -le 2; $attempt++) { $r = Reg ([byte[]](0x10,0xFF,0x80,0xB2,0x01,0x00,0x00)) # open pairing lock, default timeout if (-not $r) { throw "No reply to open-lock request" } if ($r[2] -eq 0x8F -and $r[5] -eq 0x05) { # 0x05 = too many devices: this receiver holds one device, so drop the old (broken) mouse first Write-Host "Receiver is full - unpairing the old (broken) mouse from slot 1..." -ForegroundColor Yellow $u = Reg ([byte[]](0x10,0xFF,0x80,0xB2,0x03,0x01,0x00)) Write-Host (" unpair reply " + [HidppReceiver]::Hex($u)) if (-not $u -or $u[2] -eq 0x8F) { throw "Receiver refused to unpair slot 1" } Start-Sleep -Milliseconds 500 Write-Host " now: $(SlotInfo)" $r = Reg ([byte[]](0x10,0xFF,0x80,0xB2,0x01,0x00,0x00)) if (-not $r) { throw "No reply to open-lock request" } } if ($r[2] -eq 0x8F) { throw ("Receiver rejected open-lock: " + [HidppReceiver]::Hex($r)) } Write-Host "" Write-Host "STEP 2: Pairing window is OPEN. Switch the G903 ON now (cable stays unplugged)." -ForegroundColor Green $connected = $false; $lockError = $null $deadline = (Get-Date).AddSeconds(45) while ((Get-Date) -lt $deadline) { $m = $rx.Next(500) if (-not $m) { continue } Write-Host (" rx " + [HidppReceiver]::Hex($m)) -ForegroundColor DarkGray if ($m[0] -eq 0x10 -and $m[2] -eq 0x41) { $linked = -not ($m[4] -band 0x40) Write-Host (" device on slot {0}: wpid 0x{1:X2}{2:X2}, link {3}" -f $m[1], $m[6], $m[5], $(if ($linked) {'UP'} else {'down'})) if ($linked) { $connected = $true } } if ($m[0] -eq 0x10 -and $m[2] -eq 0x4A -and -not ($m[3] -band 1)) { $lockError = $m[4]; break } } if ($lockError -eq 3 -and $attempt -eq 1) { Write-Host "Receiver is full - unpairing the old (broken) mouse from slot 1 and retrying..." -ForegroundColor Yellow $u = Reg ([byte[]](0x10,0xFF,0x80,0xB2,0x03,0x01,0x00)) Write-Host (" unpair reply " + [HidppReceiver]::Hex($u)) Write-Host "Switch the mouse OFF again." -ForegroundColor Yellow Read-Host "Press Enter when it's off" continue } break } Write-Host "" switch ($lockError) { 0 { Write-Host "Pairing lock closed normally." } 1 { Write-Host "Pairing window timed out (mouse not seen)." -ForegroundColor Red } $null { Write-Host "Pairing window still open after 45 s; closing it." -ForegroundColor Red $null = Reg ([byte[]](0x10,0xFF,0x80,0xB2,0x02,0x00,0x00)) } default { Write-Host ("Pairing lock closed with error code {0}." -f $lockError) -ForegroundColor Red } } Write-Host "After: $(SlotInfo)" if ($connected) { Write-Host "SUCCESS - move the mouse; it should work through the dongle now." -ForegroundColor Green } else { Write-Host "No link-up notification seen. Try moving the mouse anyway; if it doesn't work, rerun this script." -ForegroundColor Yellow } } finally { $rx.Dispose() }