Compare commits

..

2 Commits

Author SHA1 Message Date
JackTheRooster 546bca4af1 added link to lookup usb device ids 2025-02-17 22:53:23 -06:00
JackTheRooster 23771e7bb6 added preconfigured options for USB Emulation 2025-02-17 22:29:04 -06:00
2 changed files with 114 additions and 10 deletions

View File

@ -7,6 +7,7 @@ import Modal from "@components/Modal";
import { InputFieldWithLabel } from "./InputField";
import { useJsonRpc } from "@/hooks/useJsonRpc";
import { useUsbConfigModalStore } from "@/hooks/stores";
import ExtLink from "@components/ExtLink";
export interface UsbConfigState {
vendor_id: string;
@ -135,18 +136,26 @@ function UpdateUsbConfigModal({
Set custom USB parameters to control how the USB device is emulated.
The device will rebind once the parameters are updated.
</p>
<div className="flex justify-start mt-4 text-xs text-slate-500 dark:text-slate-400">
<ExtLink
href={`https://the-sz.com/products/usbid/index.php?v=${usbConfigState.vendor_id}&p=${usbConfigState.product_id}`}
className="hover:underline"
>
Look up USB Device IDs
</ExtLink>
</div>
</div>
<InputFieldWithLabel
required
label="Vendor ID"
placeholder="Enter Vendor ID"
pattern="^0[xX][\da-fA-F]{4}$"
defaultValue={usbConfigState?.vendor_id}
onChange={e => handleUsbVendorIdChange(e.target.value)}
required
label="Vendor ID"
placeholder="Enter Vendor ID"
pattern="^0[xX][\da-fA-F]{4}$"
defaultValue={usbConfigState?.vendor_id}
onChange={e => handleUsbVendorIdChange(e.target.value)}
/>
<InputFieldWithLabel
required
label="Product ID"
required
label="Product ID"
placeholder="Enter Product ID"
pattern="^0[xX][\da-fA-F]{4}$"
defaultValue={usbConfigState?.product_id}

View File

@ -74,6 +74,63 @@ const edids = [
},
];
const defaultUsbConfig =
JSON.stringify({
vendor_id: "0x1d6b",
product_id: "0x0104",
serial_number: "",
manufacturer: "JetKVM",
product: "JetKVM USB Emulation Device",
})
const usbConfigs = [
{
value: defaultUsbConfig,
label: "JetKVM Default",
},
{
value: JSON.stringify({
vendor_id: "0x046d",
product_id: "0xc52b",
serial_number: [generateNumber(1,9), generateHex(7,7), 0, 1].join("&"),
manufacturer: "Logitech (x64)",
product: "Logitech USB Input Device",
}),
label: "Logitech Universal Adapter",
},
{
value: JSON.stringify({
vendor_id: "0x045e",
product_id: "0x005f",
serial_number: [generateNumber(1,9), generateHex(7,7), 0, 1].join("&"),
manufacturer: "Microsoft",
product: "Wireless MultiMedia Keyboard",
}),
label: "Microsoft Wireless MultiMedia Keyboard",
},
{
value: JSON.stringify({
vendor_id: "0x413c",
product_id: "0x2011",
serial_number: [generateNumber(1,9), generateHex(7,7), 0, 1].join("&"),
manufacturer: "Dell Inc.",
product: "Multimedia Pro Keyboard",
}),
label: "Dell Multimedia Pro Keyboard",
}
];
function generateNumber(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function generateHex(min: number, max: number) {
const len = generateNumber(min, max);
const n = (Math.random() * 0xfffff * 1000000).toString(16);
return n.slice(0, len);
}
export default function SettingsSidebar() {
const setSidebarView = useUiStore(state => state.setSidebarView);
const settings = useSettingsStore();
@ -84,6 +141,7 @@ export default function SettingsSidebar() {
const [jiggler, setJiggler] = useState(false);
const [edid, setEdid] = useState<string | null>(null);
const [customEdidValue, setCustomEdidValue] = useState<string | null>(null);
const [usbConfigJson, setUsbConfigJson] = useState("");
const [isAdopted, setAdopted] = useState(false);
const [deviceId, setDeviceId] = useState<string | null>(null);
@ -183,6 +241,21 @@ export default function SettingsSidebar() {
});
};
const handleUsbConfigChange = (jsonString: string) => {
const usbConfig = JSON.parse(jsonString);
send("setUsbConfig", { usbConfig }, resp => {
if ("error" in resp) {
notifications.error(
`Failed to set usb config: ${resp.error.data || "Unknown error"}`,
);
return;
}
setUsbConfigJson(jsonString);
notifications.success(`USB Config set to ${usbConfig.product}`);
console.info(`usbConfigJson set to: ${usbConfigJson}`)
});
};
const handleJigglerChange = (enabled: boolean) => {
send("setJigglerState", { enabled }, resp => {
if ("error" in resp) {
@ -860,8 +933,30 @@ export default function SettingsSidebar() {
</SettingsItem>
{settings.developerMode && (
<SettingsItem
title="USB Configuration"
description="Set the USB Descriptors for the JetKVM"
title="Set USB Device Emulation"
description="Select a Preconfigured USB Device"
>
<SelectMenuBasic
size="SM"
label=""
fullWidth
value={usbConfigJson}
onChange={e => {
if (e.target.value === "custom") {
setUsbConfigJson("custom")
// If set to custom, show the USB Config button
} else {
handleUsbConfigChange(e.target.value as string);
}
}}
options={[...usbConfigs, { value: "custom", label: "Custom" }]}
/>
</SettingsItem>
)}
{usbConfigJson == "custom" && (
<SettingsItem
title="USB Config"
description="Set Custom USB Descriptors"
>
<Button
size="SM"