Merge pull request #19 from Lab-8916100448256/fido

Fallback to fido::read_device_details when rescue::read_device_details fails
This commit is contained in:
Suyog Tandel
2026-01-20 22:27:09 +05:30
committed by GitHub
8 changed files with 89 additions and 18 deletions
+17 -1
View File
@@ -16,6 +16,9 @@ const CTAPHID_KEEPALIVE: u8 = 0xBB;
pub struct HidTransport {
device: hidapi::HidDevice,
cid: u32,
pub vid: u16,
pub pid: u16,
pub product_name: String,
}
impl HidTransport {
@@ -41,6 +44,13 @@ impl HidTransport {
info.product_id()
);
let vid = info.vendor_id();
let pid = info.product_id();
let product_name = info
.product_string()
.unwrap_or("Unknown FIDO Device")
.to_string();
let device = info.open_device(&api).map_err(|e| {
log::error!("Failed to open HID device: {}", e);
e
@@ -53,7 +63,13 @@ impl HidTransport {
})?;
log::info!("HID Transport established successfully. CID: 0x{:08X}", cid);
Ok(Self { device, cid })
Ok(Self {
device,
cid,
vid,
pid,
product_name,
})
}
fn init_channel(device: &hidapi::HidDevice) -> Result<u32> {
+15 -4
View File
@@ -37,7 +37,11 @@ pub(crate) fn get_fido_info() -> Result<FidoDeviceInfo, String> {
max_msg_size: info.max_msg_size,
pin_protocols: info.pin_uv_auth_protocols,
min_pin_length: info.min_pin_length,
firmware_version: format!("0x{:X}", info.firmware_version),
firmware_version: format!(
"{}.{}",
(info.firmware_version >> 8) & 0xFF,
info.firmware_version & 0xFF
),
})
}
@@ -188,7 +192,7 @@ pub fn read_device_details() -> Result<FullDeviceStatus, PFError> {
m.get(&Value::Integer(0x0E))
.and_then(|v| {
if let Value::Integer(i) = v {
Some(format!("0x{:X}", i))
Some(format!("{}.{}", (i >> 8) & 0xFF, i & 0xFF))
} else {
None
}
@@ -292,7 +296,13 @@ pub fn read_device_details() -> Result<FullDeviceStatus, PFError> {
Vec::new()
});
let mut config = AppConfig::default();
let mut config = AppConfig {
vid: format!("{:04X}", transport.vid),
pid: format!("{:04X}", transport.pid),
product_name: transport.product_name.clone(),
..Default::default()
};
if let Ok(Value::Map(m)) = from_slice(&phy_res) {
log::debug!("Parsed Physical Config map successfully");
// These keys might need adjustment based on exact firmware response structure
@@ -311,7 +321,7 @@ pub fn read_device_details() -> Result<FullDeviceStatus, PFError> {
Ok(FullDeviceStatus {
info: DeviceInfo {
serial: aaguid_str, // Using AAGUID as serial since unique serial isn't available
serial: "?".to_string(), // Serial number is not available through fido. Previous code was using AAGUID as serial but it is too long to display in place of serial it is already displayed somewhere else.
flash_used: used / 1024,
flash_total: total / 1024,
firmware_version: fw_version,
@@ -319,5 +329,6 @@ pub fn read_device_details() -> Result<FullDeviceStatus, PFError> {
config,
secure_boot: false,
secure_lock: false,
method: "FIDO".to_string(),
})
}
+7 -2
View File
@@ -3,8 +3,13 @@ use crate::{error::PFError, fido, rescue, types::*};
#[tauri::command]
pub fn read_device_details() -> Result<FullDeviceStatus, PFError> {
rescue::read_device_details()
// fido::read_device_details()
match rescue::read_device_details() {
Ok(status) => Ok(status),
Err(e) => {
log::warn!("Rescue method failed: {}. Falling back to FIDO...", e);
fido::read_device_details()
}
}
}
#[tauri::command]
+1
View File
@@ -235,6 +235,7 @@ pub fn read_device_details() -> Result<FullDeviceStatus, PFError> {
config,
secure_boot: sb_enabled,
secure_lock: sb_locked,
method: "Rescue".to_string(),
})
}
+1
View File
@@ -55,6 +55,7 @@ pub struct FullDeviceStatus {
pub config: AppConfig,
pub secure_boot: bool,
pub secure_lock: bool,
pub method: String,
}
// Fido stuff:
+3
View File
@@ -16,6 +16,7 @@ class DeviceManager {
connected = $state(false);
fidoInfo: FidoInfo | null = $state(null);
error: string | null = $state(null);
method: string = $state("");
credentials: StoredCredential[] = $state([]);
unlocked = $state(false);
@@ -60,6 +61,8 @@ class DeviceManager {
confirmed: false,
};
this.method = status.method;
const fido = await invoke<FidoInfo>("get_fido_info");
this.fidoInfo = fido;
+1
View File
@@ -38,6 +38,7 @@ export interface FullDeviceStatus {
config: DeviceConfig;
secureBoot: boolean;
secureLock: boolean;
method: string;
}
export interface SecurityState {
+44 -11
View File
@@ -7,14 +7,24 @@
import { device } from "$lib/device/manager.svelte";
import { Cpu, Lock, LockOpen, Microchip, ShieldCheck, TriangleAlert, Shield } from "@lucide/svelte";
import {
Cpu,
Lock,
LockOpen,
Microchip,
ShieldCheck,
TriangleAlert,
Shield,
} from "@lucide/svelte";
import NoDeviceStatus from "$lib/components/device/NoDeviceStatus.svelte";
</script>
<div class="space-y-6">
<div>
<h1 class="text-3xl font-bold tracking-tight">Device Overview</h1>
<p class="text-muted-foreground">Quick view of your device status and specifications.</p>
<p class="text-muted-foreground">
Quick view of your device status and specifications.
</p>
</div>
{#if !device.connected}
@@ -36,16 +46,24 @@
</div>
<div class="space-y-1">
<p class="text-muted-foreground">Firmware Version</p>
<p class="font-mono font-medium">v{device.info.firmwareVersion}</p>
<p class="font-mono font-medium">
v{device.info.firmwareVersion}
</p>
</div>
<div class="space-y-1">
<p class="text-muted-foreground">VID:PID</p>
<p class="font-mono font-medium">{device.config.vid}:{device.config.pid}</p>
<p class="font-mono font-medium">
{device.config.vid}:{device.config.pid}
</p>
</div>
<div class="space-y-1">
<p class="text-muted-foreground">Product Name</p>
<p class="font-medium truncate">{device.config.productName}</p>
</div>
<div class="space-y-1">
<p class="text-muted-foreground">Connection Method</p>
<Badge variant="outline" class="font-mono">{device.method}</Badge>
</div>
</div>
<Separator />
@@ -57,7 +75,10 @@
{device.info.flashUsed} / {device.info.flashTotal} KB
</span>
</div>
<Progress value={(device.info.flashUsed / device.info.flashTotal) * 100} class="h-2" />
<Progress
value={(device.info.flashUsed / device.info.flashTotal) * 100}
class="h-2"
/>
</div>
</Card.Content>
</Card.Root>
@@ -74,7 +95,9 @@
<div class="grid grid-cols-2 gap-4 text-sm">
<div class="space-y-1">
<p class="text-muted-foreground">FIDO Version</p>
<p class="font-medium">{device.fidoInfo.versions[0] || "N/A"}</p>
<p class="font-medium">
{device.fidoInfo.versions[0] || "N/A"}
</p>
</div>
<div class="space-y-1">
<p class="text-muted-foreground">PIN Set</p>
@@ -98,10 +121,14 @@
<div class="space-y-1">
<p class="text-muted-foreground text-sm">AAGUID</p>
<p class="font-mono text-xs break-all">{device.fidoInfo.aaguid}</p>
<p class="font-mono text-xs break-all">
{device.fidoInfo.aaguid}
</p>
</div>
{:else}
<p class="text-muted-foreground text-sm">FIDO information not available</p>
<p class="text-muted-foreground text-sm">
FIDO information not available
</p>
{/if}
</Card.Content>
</Card.Root>
@@ -128,7 +155,9 @@
</div>
<div class="flex justify-between">
<span class="text-muted-foreground">LED Dimmable</span>
<Badge variant={device.config.ledDimmable ? "default" : "secondary"}>
<Badge
variant={device.config.ledDimmable ? "default" : "secondary"}
>
{device.config.ledDimmable ? "Yes" : "No"}
</Badge>
</div>
@@ -157,7 +186,9 @@
{:else}
<LockOpen class="h-3 w-3 text-amber-500" />
{/if}
<Badge variant={device.security.secureBoot ? "default" : "secondary"}>
<Badge
variant={device.security.secureBoot ? "default" : "secondary"}
>
{device.security.secureBoot ? "Secure Boot" : "Development"}
</Badge>
</div>
@@ -170,7 +201,9 @@
</div>
<div class="flex justify-between items-center">
<span class="text-muted-foreground">Secure Lock</span>
<Badge variant={device.security.confirmed ? "destructive" : "outline"}>
<Badge
variant={device.security.confirmed ? "destructive" : "outline"}
>
{device.security.confirmed ? "Acknowledged" : "Pending"}
</Badge>
</div>