Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
d2fea56
fix: save persistent
chrisgalanis Jul 21, 2025
195d75e
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Jul 25, 2025
d02e2b5
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Jul 30, 2025
9040984
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Aug 7, 2025
9ba8e91
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Aug 8, 2025
8866016
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Aug 15, 2025
b7f0532
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Aug 19, 2025
a950a82
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Sep 1, 2025
f85882a
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Sep 1, 2025
912df00
Merge github.com:worldcoin/orb-software
chrisgalanis Sep 3, 2025
68cb5cd
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Oct 17, 2025
1543d27
Merge github.com:worldcoin/orb-software
chrisgalanis Oct 19, 2025
b75b812
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Nov 7, 2025
8dda1fb
Merge github.com:worldcoin/orb-software
chrisgalanis Nov 9, 2025
3725ede
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Nov 12, 2025
7b12495
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Nov 12, 2025
2466287
Merge github.com:worldcoin/orb-software
chrisgalanis Dec 6, 2025
7940035
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Dec 9, 2025
f92ac94
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Dec 11, 2025
9a55d7c
fix: replace mcu-reboot with button reboot
chrisgalanis Dec 9, 2025
7973a70
fix: remove upload.sh
chrisgalanis Dec 9, 2025
a8d615b
fix: fmt
chrisgalanis Dec 9, 2025
9fe311c
fix: clippy & build
chrisgalanis Dec 11, 2025
8a42a30
fix(ota-hil): Fix target version in update_version_json
chrisgalanis Dec 19, 2025
368513b
Merge github.com:worldcoin/orb-software into chris/ota-hil
chrisgalanis Dec 19, 2025
b50d887
fix(ota-hil): Fix target version Clippy
chrisgalanis Dec 19, 2025
e27f1cc
fix(ota-hil): Fix Format
chrisgalanis Dec 19, 2025
19fb770
feat(ota-hil): Set Non Recovery Mode after Reboot from the MCU
chrisgalanis Dec 23, 2025
7e24ebf
fix(ota-hil): Remove unused command
chrisgalanis Dec 23, 2025
7a7c7c5
fix(ota-hil): Set BTN Pin to High to not trigger button reboot
chrisgalanis Dec 23, 2025
82f5f84
Merge github.com:worldcoin/orb-software into chris/ota-hil
chrisgalanis Dec 23, 2025
c17337e
fix(set_recovery_pin): Simplify Code Logic
chrisgalanis Dec 23, 2025
3687bf4
fix(ota-hil): Restore MCU Reboot Command
chrisgalanis Dec 23, 2025
33497fc
fix: format
chrisgalanis Dec 24, 2025
0522779
Merge branch 'main' into chris/ota-hil
chrisgalanis Dec 24, 2025
484fa1b
feat: Wipe Overlays for Both Diamond and Pearl
chrisgalanis Dec 30, 2025
d150f51
Merge branch 'main' into chris/ota-hil
chrisgalanis Dec 30, 2025
0ef98f2
feat: Added Logs when Update-agent Fails
chrisgalanis Dec 31, 2025
8781765
fix: Restart Update agent after NTP sync
chrisgalanis Dec 31, 2025
8b471ea
Merge branch 'main' into chris/ota-hil
chrisgalanis Dec 31, 2025
1b07e90
fix: format
chrisgalanis Dec 31, 2025
e83bfa5
Merge github.com:worldcoin/orb-software into chris/ota-hil
chrisgalanis Jan 3, 2026
1f65059
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Jan 3, 2026
449a924
Merge branch 'chris/ota-hil' of github.com:worldcoin/orb-software int…
chrisgalanis Jan 3, 2026
0c15f91
feat: Caputer Serial Logs during Boot
chrisgalanis Jan 3, 2026
ceae6e6
fix: format
chrisgalanis Jan 3, 2026
4f8b4b2
fix: remove unessary pub vis
chrisgalanis Jan 3, 2026
5cc74ab
fix: set recovery mode before capture logs
chrisgalanis Jan 5, 2026
83a80fd
fix: Permission issue of not capturing serial logs
chrisgalanis Jan 6, 2026
c8df636
fix: reboot command not setting every time orb to recovery mode
chrisgalanis Jan 6, 2026
32b2f1f
fix: added NTP sync before reboot, for attestation token -> key retri…
chrisgalanis Jan 6, 2026
16746e9
fix: set recovery mode HIGH for longer time
chrisgalanis Jan 6, 2026
0299eda
fix: format
chrisgalanis Jan 6, 2026
d972cb2
fix: clippy
chrisgalanis Jan 6, 2026
b96d50f
fix: use either: chronyc or timedatectl (temp change for testing befo…
chrisgalanis Jan 7, 2026
6c1ae63
fix: add delay between recovery mode triggerring and log capturing
chrisgalanis Jan 7, 2026
8be233d
fix: on ota-reboot wait until ssh get disconnected to press recovery pin
chrisgalanis Jan 7, 2026
d7b211a
Merge github.com:worldcoin/orb-software into chris/ota-hil
chrisgalanis Jan 8, 2026
fe8d64b
Merge branch 'main' of github.com:worldcoin/orb-software
chrisgalanis Jan 8, 2026
a16deaa
Merge branch 'main' into chris/ota-hil
chrisgalanis Jan 8, 2026
2651eef
Merge branch 'main' into chris/ota-hil
chrisgalanis Jan 8, 2026
c377b95
fix: NTP check hanging
chrisgalanis Jan 9, 2026
8e02331
feat: wait for SSH disconnection before holding the recovery pin
chrisgalanis Jan 9, 2026
55f290b
fix: removing waiting NTP before reboot
chrisgalanis Jan 9, 2026
cb86863
Merge github.com:worldcoin/orb-software into chris/ota-hil
chrisgalanis Jan 9, 2026
62f59a0
Merge branch 'chris/ota-hil' of github.com:worldcoin/orb-software int…
chrisgalanis Jan 9, 2026
3a9c42e
fix: capturing serial async & removing timeout
chrisgalanis Jan 11, 2026
3cb60a9
Merge branch 'main' into chris/ota-hil
chrisgalanis Jan 11, 2026
22e027c
fix: clean code
chrisgalanis Jan 12, 2026
7a1b966
fix: format
chrisgalanis Jan 12, 2026
fe82002
Merge github.com:worldcoin/orb-software into chris/ota-hil
chrisgalanis Jan 12, 2026
1df5421
Merge branch 'chris/ota-hil' of github.com:worldcoin/orb-software int…
chrisgalanis Jan 12, 2026
6f2a845
fix: replace delay value with constant
chrisgalanis Jan 12, 2026
73b249a
Merge branch 'chris/ota-hil' of github.com:worldcoin/orb-software int…
chrisgalanis Jan 13, 2026
022ae7b
fix: try chrony first & fallback to timedatectl
chrisgalanis Jan 13, 2026
d2ff64c
Merge branch 'chris/ota-hil' of github.com:worldcoin/orb-software int…
chrisgalanis Jan 13, 2026
269826c
fix: time sync bug, unhandled error
chrisgalanis Jan 13, 2026
3568b0b
fix: default hold for 5 secs
chrisgalanis Jan 13, 2026
857ec45
feat: Include More Serial Logs Capture When Orbs is not Reachable
chrisgalanis Jan 13, 2026
7662565
fix: format
chrisgalanis Jan 13, 2026
b113e94
Merge branch 'main' into chris/ota-hil
chrisgalanis Jan 13, 2026
bec8b5d
feat: Introduce Ethernet Through Usb for Ota orb
chrisgalanis Jan 14, 2026
b2b4038
Merge branch 'chris/ota-hil' of github.com:worldcoin/orb-software int…
chrisgalanis Jan 14, 2026
2c89aa4
feat: Ethernet through USB
chrisgalanis Jan 14, 2026
65dacd1
fix: restore from main / nix conf
chrisgalanis Jan 14, 2026
0e6ac47
Merge branch 'main' into chris/ota-hil
chrisgalanis Jan 14, 2026
3b35464
fix: make test only for linux
chrisgalanis Jan 14, 2026
aef3ffe
Merge branch 'chris/ota-hil' of github.com:worldcoin/orb-software int…
chrisgalanis Jan 14, 2026
2a7ff45
Merge branch 'main' into chris/ota-hil
chrisgalanis Jan 15, 2026
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
18 changes: 13 additions & 5 deletions hil/src/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ pub async fn is_recovery_mode_detected() -> Result<bool> {
/// If `device` is `None`, will get the first available device.
#[tracing::instrument]
pub async fn reboot(recovery: bool, device: Option<&FtdiId>) -> Result<()> {
const DEFAULT_HOLDING_DELAY: u64 = 5;
const INBETWEEN_DELAY: u64 = 4;

fn make_ftdi(device: Option<FtdiId>) -> Result<FtdiGpio> {
let builder = FtdiGpio::builder();
let builder = match &device {
Expand All @@ -37,7 +40,12 @@ pub async fn reboot(recovery: bool, device: Option<&FtdiId>) -> Result<()> {

info!("Turning off");
let device_clone = device.cloned();
let ftdi = tokio::task::spawn_blocking(|| -> Result<_, color_eyre::Report> {
let recovery_state = if recovery {
OutputState::Low
} else {
OutputState::High
};
let ftdi = tokio::task::spawn_blocking(move || -> Result<_, color_eyre::Report> {
for d in FtdiGpio::list_devices().wrap_err("failed to list ftdi devices")? {
debug!(
"ftdi device: desc:{}, serial:{}, vid:{}, pid:{}",
Expand All @@ -46,18 +54,18 @@ pub async fn reboot(recovery: bool, device: Option<&FtdiId>) -> Result<()> {
}
let mut ftdi = make_ftdi(device_clone)?;
ftdi.set_pin(BUTTON_PIN, OutputState::Low)?;
ftdi.set_pin(RECOVERY_PIN, OutputState::High)?;
ftdi.set_pin(RECOVERY_PIN, recovery_state)?;
Ok(ftdi)
})
.await
.wrap_err("task panicked")??;
tokio::time::sleep(Duration::from_secs(10)).await;
tokio::time::sleep(Duration::from_secs(DEFAULT_HOLDING_DELAY)).await;

info!("Resetting FTDI");
tokio::task::spawn_blocking(move || ftdi.destroy())
.await
.wrap_err("task panicked")??;
tokio::time::sleep(Duration::from_secs(4)).await;
tokio::time::sleep(Duration::from_secs(INBETWEEN_DELAY)).await;

info!("Turning on");
let device_clone = device.cloned();
Expand All @@ -74,7 +82,7 @@ pub async fn reboot(recovery: bool, device: Option<&FtdiId>) -> Result<()> {
})
.await
.wrap_err("task panicked")??;
tokio::time::sleep(Duration::from_secs(4)).await;
tokio::time::sleep(Duration::from_secs(DEFAULT_HOLDING_DELAY)).await;

tokio::task::spawn_blocking(move || ftdi.destroy())
.await
Expand Down
98 changes: 82 additions & 16 deletions hil/src/commands/ota/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ pub struct Ota {
#[arg(long)]
target_version: String,

/// Hostname of the Orb device
/// Hostname of the Orb device (optional - will auto-discover via USB ethernet if not provided)
#[arg(long)]
hostname: String,
hostname: Option<String>,

/// Username
#[arg(long, default_value = "worldcoin")]
Expand Down Expand Up @@ -69,6 +69,23 @@ pub struct Ota {
/// Serial port ID for boot log capture (alternative to --serial-path)
#[arg(long, group = "serial")]
serial_id: Option<String>,

/// Skip NTP time synchronization check before the first reboot (after wipe_overlays).
/// Time sync will still be checked after reboot and before starting the update.
#[arg(long, default_value = "false")]
skip_time_sync_before_reboot: bool,

/// IP range start for USB ethernet auto-discovery
#[arg(long, default_value = "2")]
discovery_ip_start: u8,

/// IP range end for USB ethernet auto-discovery
#[arg(long, default_value = "10")]
discovery_ip_end: u8,

/// Timeout for discovering Orb via USB ethernet (seconds)
#[arg(long, default_value = "30")]
discovery_timeout_secs: u64,
}

#[derive(Debug, Clone, clap::ValueEnum)]
Expand All @@ -94,6 +111,13 @@ impl Ota {
let _start_time = Instant::now();
info!("Starting OTA update to version: {}", self.target_version);

if let Some(log_dir) = self.log_file.parent() {
tokio::fs::create_dir_all(log_dir).await.wrap_err_with(|| {
format!("Failed to create log directory: {}", log_dir.display())
})?;
info!("Log directory created/verified: {}", log_dir.display());
}

let session = self.connect_ssh().await.inspect_err(|e| {
println!("OTA_RESULT=FAILED");
println!("OTA_ERROR=SSH_CONNECTION_FAILED: {e}");
Expand All @@ -105,7 +129,19 @@ impl Ota {
system::wipe_overlays(&session).await.inspect_err(|e| {
error!("Failed to wipe overlays: {}", e);
})?;
info!("Overlays wiped successfully, rebooting device");
info!("Overlays wiped successfully");

if !self.skip_time_sync_before_reboot {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why we need this I wonder ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, basically the problem was with the worldcoin-key-retrival service. With pearl, teh harware clock is not working so if it NTP server is not synced then worldcoin-attest is failing and also key-retrieval. This should be fixed with new key-retrieval fix, that is why i ketp it as a flag, so we can test older commits, that don't have key-retrival fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am also not getting it sorry.

With pearl, teh harware clock is not working so if it NTP server is not synced then worldcoin-attest is failing and also key-retrieval.

That is not true. The clock will synchronize and https requests is going to succeed. And the delay is not big for that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By default this is not correct. Because reboot is manually triggered faster than the NTP server syncrhonizes the clock....

info!("Waiting for NTP time synchronization before reboot");
system::wait_for_time_sync(&session)
.await
.inspect_err(|e| {
error!("Failed to sync time before reboot: {}", e);
})?;
info!("NTP time synchronized, rebooting device");
} else {
info!("Skipping NTP time synchronization before reboot (--skip-time-sync-before-reboot flag set)");
}

system::reboot_orb(&session).await?;
info!("Reboot command sent to Orb device");
Expand Down Expand Up @@ -315,24 +351,44 @@ impl Ota {
}

async fn connect_ssh(&self) -> Result<SshWrapper> {
info!(
"Connecting to Orb device at {}:{}",
self.hostname, self.port
);

let auth = match (&self.password, &self.key_path) {
(Some(password), None) => AuthMethod::Password(password.clone()),
(None, Some(key_path)) => AuthMethod::Key {
private_key_path: key_path.clone(),
},
_ => unreachable!("Clap ensures exactly one auth method is specified"),
let hostname = match &self.hostname {
Some(h) => {
info!("Using provided hostname: {}", h);
h.clone()
}
None => {
info!("No hostname provided, starting USB ethernet auto-discovery");
let discovery = orb_hil::NetworkDiscovery {
username: self.username.clone(),
auth: self.get_auth_method(),
port: self.port,
ip_range_start: self.discovery_ip_start,
ip_range_end: self.discovery_ip_end,
connection_timeout: std::time::Duration::from_secs(
self.discovery_timeout_secs,
),
};

let discovered = discovery
.discover_orb()
.await
.wrap_err("Failed to discover Orb via USB ethernet")?;

info!(
"Discovered Orb at {} on interface {}",
discovered.hostname, discovered.interface
);
discovered.hostname
}
};

info!("Connecting to Orb device at {}:{}", hostname, self.port);

let connect_args = SshConnectArgs {
hostname: self.hostname.clone(),
hostname,
port: self.port,
username: self.username.clone(),
auth,
auth: self.get_auth_method(),
};

let session = SshWrapper::connect(connect_args)
Expand All @@ -342,4 +398,14 @@ impl Ota {
info!("Successfully connected to Orb device");
Ok(session)
}

fn get_auth_method(&self) -> AuthMethod {
match (&self.password, &self.key_path) {
(Some(password), None) => AuthMethod::Password(password.clone()),
(None, Some(key_path)) => AuthMethod::Key {
private_key_path: key_path.clone(),
},
_ => unreachable!("Clap ensures exactly one auth method is specified"),
}
}
}
Loading
Loading