From d2fea56d2d87ea38df99089a918a52a42ef817d9 Mon Sep 17 00:00:00 2001 From: chrisgalanis Date: Mon, 21 Jul 2025 21:00:18 +0200 Subject: [PATCH 1/3] fix: save persistent --- hil/src/commands/mod.rs | 2 ++ hil/src/flash.rs | 7 ++++++ hil/src/main.rs | 2 ++ scripts/upload-certs.sh | 51 +++++++++++++++++++++++++++++++++++++---- 4 files changed, 57 insertions(+), 5 deletions(-) diff --git a/hil/src/commands/mod.rs b/hil/src/commands/mod.rs index 09692f3c8..a65bab9d4 100644 --- a/hil/src/commands/mod.rs +++ b/hil/src/commands/mod.rs @@ -2,6 +2,7 @@ mod button_ctrl; mod cmd; +mod fetch_persistent; mod flash; mod login; mod mcu; @@ -9,6 +10,7 @@ mod reboot; pub use self::button_ctrl::ButtonCtrl; pub use self::cmd::Cmd; +pub use self::fetch_persistent::FetchPersistent; pub use self::flash::Flash; pub use self::login::Login; pub use self::mcu::Mcu; diff --git a/hil/src/flash.rs b/hil/src/flash.rs index 2d41b929d..457bc22bf 100644 --- a/hil/src/flash.rs +++ b/hil/src/flash.rs @@ -73,8 +73,15 @@ fn flash_cmd(variant: FlashVariant, extracted_dir: &Path) -> Result<()> { ); let cmd_file_name = variant.file_name(); + + // Remove the fetch persistent commands from flash script before executing + let flash_script_path = bootloader_dir.join(cmd_file_name); let result = run_cmd! { cd $bootloader_dir; + info "Removing fetch persistent commands from flash script"; + sed -i "/# This file should be templated to add a '--cmd' option/d" $flash_script_path; + sed -i "/--cmd.*read PERSISTENT.*reboot recovery/d" $flash_script_path; + sed -i "/wld-pre-flash-check.sh/d" $flash_script_path; info running $cmd_file_name; bash $cmd_file_name; info finished flashing!; diff --git a/hil/src/main.rs b/hil/src/main.rs index 6d7c60541..664f22a13 100644 --- a/hil/src/main.rs +++ b/hil/src/main.rs @@ -26,6 +26,7 @@ struct Cli { enum Commands { ButtonCtrl(crate::commands::ButtonCtrl), Cmd(crate::commands::Cmd), + FetchPersistent(crate::commands::FetchPersistent), Flash(crate::commands::Flash), Login(crate::commands::Login), Mcu(crate::commands::Mcu), @@ -62,6 +63,7 @@ async fn main() -> Result<()> { match args.commands { Commands::ButtonCtrl(c) => c.run().await, Commands::Cmd(c) => c.run().await, + Commands::FetchPersistent(c) => c.run().await, Commands::Flash(c) => c.run().await, Commands::Login(c) => c.run().await, Commands::Mcu(c) => c.run().await, diff --git a/scripts/upload-certs.sh b/scripts/upload-certs.sh index 54889c1b4..e8d19e23e 100755 --- a/scripts/upload-certs.sh +++ b/scripts/upload-certs.sh @@ -3,7 +3,7 @@ set -o errexit # abort on nonzero exit status set -o errtrace # pass ERR trap down to functions, substitutions, etc set -o nounset # abort on unbound variable -set -o pipefail # don’t hide errors within pipes +set -o pipefail # don't hide errors within pipes # Function to display usage information usage() { @@ -14,6 +14,7 @@ usage() { -t, --token Bearer token for authentication. -b, --backend (stage|prod) Targets the stage or prod backend. -s, --short Short upload (skip attestation cert). + -n, --dry-run Print key values without making curl requests. Environment variables (overriden by options): FM_CLI_ENV: Must be either 'stage' or 'prod'. @@ -36,6 +37,7 @@ main() { local backend="${FM_CLI_ENV:-""}" local positional_args=() local short=0 + local dry_run=0 local arg while [[ "$#" -gt 0 ]]; do arg="${1}"; shift @@ -48,6 +50,8 @@ main() { backend="${1}"; shift ;; -s|--short) short=1 ;; + -n|--dry-run) + dry_run=1 ;; -*) echo "Unknown option: ${arg}" usage; exit 1 ;; @@ -63,19 +67,19 @@ main() { exit 1 fi - if [[ -z "${bearer}" ]]; then + if [[ -z "${bearer}" ]] && [[ ${dry_run} -eq 0 ]]; then echo "Bearer token not found. Please export FM_CLI_ORB_MANAGER_INTERNAL_TOKEN, or pass it as an argument: -t " exit 1 fi - if [[ -z "${backend}" ]]; then + if [[ -z "${backend}" ]] && [[ ${dry_run} -eq 0 ]]; then echo "Environment not found. Please export FM_CLI_ENV, or pass it as an argument: -b (stage|prod)" exit 1 fi - if [[ "${backend}" != "prod" && "${backend}" != "stage" ]]; then + if [[ "${backend}" != "prod" && "${backend}" != "stage" ]] && [[ ${dry_run} -eq 0 ]]; then echo "Invalid environment: ${backend}. Must be either 'prod' or 'stage'." exit 1 fi @@ -97,6 +101,44 @@ main() { exit 1 fi + if [[ ${dry_run} -eq 1 ]]; then + echo "=== DRY RUN MODE - Key Values ===" + echo "Orb ID: ${orb_id}" + echo "Keypath: ${keypath}" + + # Print signup key values + echo "=== Signup Key ===" + local signup_pubkey + signup_pubkey=$(sed 's/$/\\n/' "${keypath}/sss_70000002_0002_0040.bin" | tr -d \\n) + echo "Key: ${signup_pubkey}" + echo "Signature: $(base64 -w 0 "${keypath}/70000002.signature.raw")" + echo "Extra Data: $(base64 -w 0 "${keypath}/70000002.extra.raw")" + + # Print attestation key values + echo "=== Attestation Key ===" + local attestation_pubkey + attestation_pubkey=$(sed 's/$/\\n/' "${keypath}/sss_70000001_0002_0040.bin" | tr -d \\n) + echo "Key: ${attestation_pubkey}" + echo "Signature: $(base64 -w 0 "${keypath}/70000001.signature.raw")" + echo "Extra Data: $(base64 -w 0 "${keypath}/70000001.extra.raw")" + + # Print chip ID values + echo "=== Chip ID ===" + echo "Key: $(base64 -w 0 "${keypath}/7fff0206.chip_id.raw")" + echo "Signature: $(base64 -w 0 "${keypath}/7fff0206.signature.raw")" + echo "Extra Data: $(base64 -w 0 "${keypath}/7fff0206.extra.raw")" + + # Print certificate if not short mode + if [[ ${short} -eq 0 ]]; then + echo "=== Certificate ===" + local certificate + certificate=$(sed 's/$/\\n/' "${keypath}/f0000013.cert" | tr -d \\n) + echo "Certificate: ${certificate}" + fi + + exit 0 + fi + echo "Getting Cloudflared access token..." local cf_token cf_token="$(get_cloudflared_token "${domain}")" @@ -163,4 +205,3 @@ main() { if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi - From 60e01cdc3bd116291c98e27d4550de94530e8f0b Mon Sep 17 00:00:00 2001 From: chrisgalanis Date: Sat, 3 Jan 2026 20:36:58 +0100 Subject: [PATCH 2/3] feat: vocal preflight check --- ui/src/engine/diamond.rs | 49 +++++++++++++++++++++++++++++++ ui/src/engine/mod.rs | 28 ++++++++++++++++++ ui/src/engine/pearl/self_serve.rs | 42 ++++++++++++++++++++++++++ ui/src/sound/mod.rs | 14 +++++++++ 4 files changed, 133 insertions(+) diff --git a/ui/src/engine/diamond.rs b/ui/src/engine/diamond.rs index 356b22285..26c975ff7 100644 --- a/ui/src/engine/diamond.rs +++ b/ui/src/engine/diamond.rs @@ -1079,6 +1079,55 @@ impl EventHandler for Runner { )?; } + Event::VoiceOcclusionGlasses => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionGlasses), + Duration::ZERO, + )?; + } + + Event::VoiceOcclusionMask => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionMask), + Duration::ZERO, + )?; + } + + Event::VoiceOcclusionHair => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionHair), + Duration::ZERO, + )?; + } + + Event::VoiceOcclusionSunglasses => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionSunglasses), + Duration::ZERO, + )?; + } + + Event::VoiceOcclusionSegmentation => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionSegmentation), + Duration::ZERO, + )?; + } + + Event::VoiceOcclusionOther => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionOther), + Duration::ZERO, + )?; + } + + Event::VoiceOcclusionEye => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionEye), + Duration::ZERO, + )?; + } + Event::GoodInternet => { self.operator_idle.good_internet(); } diff --git a/ui/src/engine/mod.rs b/ui/src/engine/mod.rs index 0f24eb2a2..18c5ead48 100644 --- a/ui/src/engine/mod.rs +++ b/ui/src/engine/mod.rs @@ -402,6 +402,34 @@ event_enum! { #[event_enum(method = voice_open_eyes)] VoiceOpenEyes, + /// Voice: glasses occlusion detected + #[event_enum(method = voice_occlusion_glasses)] + VoiceOcclusionGlasses, + + /// Voice: mask occlusion detected + #[event_enum(method = voice_occlusion_mask)] + VoiceOcclusionMask, + + /// Voice: hair occlusion detected + #[event_enum(method = voice_occlusion_hair)] + VoiceOcclusionHair, + + /// Voice: sunglasses occlusion detected + #[event_enum(method = voice_occlusion_sunglasses)] + VoiceOcclusionSunglasses, + + /// Voice: segmentation occlusion detected + #[event_enum(method = voice_occlusion_segmentation)] + VoiceOcclusionSegmentation, + + /// Voice: other face occlusion detected + #[event_enum(method = voice_occlusion_other)] + VoiceOcclusionOther, + + /// Voice: eye occlusion detected + #[event_enum(method = voice_occlusion_eye)] + VoiceOcclusionEye, + /// Set volume [0..100] #[event_enum(method = sound_volume)] SoundVolume { diff --git a/ui/src/engine/pearl/self_serve.rs b/ui/src/engine/pearl/self_serve.rs index 9479782d2..4e939ae34 100644 --- a/ui/src/engine/pearl/self_serve.rs +++ b/ui/src/engine/pearl/self_serve.rs @@ -741,6 +741,48 @@ impl Runner { Duration::ZERO, )?; } + Event::VoiceOcclusionGlasses => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionGlasses), + Duration::ZERO, + )?; + } + Event::VoiceOcclusionMask => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionMask), + Duration::ZERO, + )?; + } + Event::VoiceOcclusionHair => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionHair), + Duration::ZERO, + )?; + } + Event::VoiceOcclusionSunglasses => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionSunglasses), + Duration::ZERO, + )?; + } + Event::VoiceOcclusionSegmentation => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionSegmentation), + Duration::ZERO, + )?; + } + Event::VoiceOcclusionOther => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionOther), + Duration::ZERO, + )?; + } + Event::VoiceOcclusionEye => { + self.sound.queue( + sound::Type::Voice(sound::Voice::OcclusionEye), + Duration::ZERO, + )?; + } _ => {} } Ok(()) diff --git a/ui/src/sound/mod.rs b/ui/src/sound/mod.rs index fba755e9a..0e4898713 100644 --- a/ui/src/sound/mod.rs +++ b/ui/src/sound/mod.rs @@ -248,6 +248,20 @@ sound_enum! { PleaseDontShutDown, #[sound_enum(file = "voice_iris_open")] OpenEyes, + #[sound_enum(file = "voice_occlusion_glasses")] + OcclusionGlasses, + #[sound_enum(file = "voice_occlusion_mask")] + OcclusionMask, + #[sound_enum(file = "voice_occlusion_hair")] + OcclusionHair, + #[sound_enum(file = "voice_occlusion_sunglasses")] + OcclusionSunglasses, + #[sound_enum(file = "voice_occlusion_segmentation")] + OcclusionSegmentation, + #[sound_enum(file = "voice_occlusion_other")] + OcclusionOther, + #[sound_enum(file = "voice_occlusion_eye")] + OcclusionEye, } } From b7ddabf471c295fc9eeb17d329a3feadc8039857 Mon Sep 17 00:00:00 2001 From: chrisgalanis Date: Sat, 3 Jan 2026 20:42:56 +0100 Subject: [PATCH 3/3] fix: remove upload-certs.sh , staged by mistake --- scripts/upload-certs.sh | 207 ---------------------------------------- 1 file changed, 207 deletions(-) delete mode 100755 scripts/upload-certs.sh diff --git a/scripts/upload-certs.sh b/scripts/upload-certs.sh deleted file mode 100755 index e8d19e23e..000000000 --- a/scripts/upload-certs.sh +++ /dev/null @@ -1,207 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit # abort on nonzero exit status -set -o errtrace # pass ERR trap down to functions, substitutions, etc -set -o nounset # abort on unbound variable -set -o pipefail # don't hide errors within pipes - -# Function to display usage information -usage() { - echo "Usage: $0 [OPTIONS] - - Options: - -h, --help Display this help message - -t, --token Bearer token for authentication. - -b, --backend (stage|prod) Targets the stage or prod backend. - -s, --short Short upload (skip attestation cert). - -n, --dry-run Print key values without making curl requests. - - Environment variables (overriden by options): - FM_CLI_ENV: Must be either 'stage' or 'prod'. - FM_CLI_ORB_AUTH_INTERNAL_TOKEN: Bearer token for authentication. - - Example: - $0 -t -b stage 349df8b0 /path/to/provisioning_material" -} - -# Function to get Cloudflared access token -get_cloudflared_token() { - local -r domain="${1}" - - cloudflared access login --quiet "${domain}" - cloudflared access token -app="${domain}" -} - -main() { - local bearer="${FM_CLI_ORB_AUTH_INTERNAL_TOKEN:-""}" - local backend="${FM_CLI_ENV:-""}" - local positional_args=() - local short=0 - local dry_run=0 - local arg - while [[ "$#" -gt 0 ]]; do - arg="${1}"; shift - case "${arg}" in - -h|--help) - usage; exit 0 ;; - -t|--bearer-token) - bearer="${1}"; shift ;; - -b|--backend) - backend="${1}"; shift ;; - -s|--short) - short=1 ;; - -n|--dry-run) - dry_run=1 ;; - -*) - echo "Unknown option: ${arg}" - usage; exit 1 ;; - *) - positional_args+=("${arg}") ;; - esac - done - set -- "${positional_args[@]}" - - if [[ $# -ne 2 ]]; then - echo "must pass " - usage - exit 1 - fi - - if [[ -z "${bearer}" ]] && [[ ${dry_run} -eq 0 ]]; then - echo "Bearer token not found. Please export FM_CLI_ORB_MANAGER_INTERNAL_TOKEN, - or pass it as an argument: -t " - exit 1 - fi - - if [[ -z "${backend}" ]] && [[ ${dry_run} -eq 0 ]]; then - echo "Environment not found. Please export FM_CLI_ENV, - or pass it as an argument: -b (stage|prod)" - exit 1 - fi - - if [[ "${backend}" != "prod" && "${backend}" != "stage" ]] && [[ ${dry_run} -eq 0 ]]; then - echo "Invalid environment: ${backend}. Must be either 'prod' or 'stage'." - exit 1 - fi - - local -r orb_id="${1}" - local -r keypath="${2}" - - # Determine the domain based on the environment - local domain - if [[ "${backend}" == "prod" ]]; then - domain="auth.internal.orb.worldcoin.dev" - else - domain="auth.internal.stage.orb.worldcoin.dev" - fi - - # Ensure the keypath exists - if [[ ! -d "$keypath" ]]; then - echo "Error: Keypath directory '$keypath' does not exist." - exit 1 - fi - - if [[ ${dry_run} -eq 1 ]]; then - echo "=== DRY RUN MODE - Key Values ===" - echo "Orb ID: ${orb_id}" - echo "Keypath: ${keypath}" - - # Print signup key values - echo "=== Signup Key ===" - local signup_pubkey - signup_pubkey=$(sed 's/$/\\n/' "${keypath}/sss_70000002_0002_0040.bin" | tr -d \\n) - echo "Key: ${signup_pubkey}" - echo "Signature: $(base64 -w 0 "${keypath}/70000002.signature.raw")" - echo "Extra Data: $(base64 -w 0 "${keypath}/70000002.extra.raw")" - - # Print attestation key values - echo "=== Attestation Key ===" - local attestation_pubkey - attestation_pubkey=$(sed 's/$/\\n/' "${keypath}/sss_70000001_0002_0040.bin" | tr -d \\n) - echo "Key: ${attestation_pubkey}" - echo "Signature: $(base64 -w 0 "${keypath}/70000001.signature.raw")" - echo "Extra Data: $(base64 -w 0 "${keypath}/70000001.extra.raw")" - - # Print chip ID values - echo "=== Chip ID ===" - echo "Key: $(base64 -w 0 "${keypath}/7fff0206.chip_id.raw")" - echo "Signature: $(base64 -w 0 "${keypath}/7fff0206.signature.raw")" - echo "Extra Data: $(base64 -w 0 "${keypath}/7fff0206.extra.raw")" - - # Print certificate if not short mode - if [[ ${short} -eq 0 ]]; then - echo "=== Certificate ===" - local certificate - certificate=$(sed 's/$/\\n/' "${keypath}/f0000013.cert" | tr -d \\n) - echo "Certificate: ${certificate}" - fi - - exit 0 - fi - - echo "Getting Cloudflared access token..." - local cf_token - cf_token="$(get_cloudflared_token "${domain}")" - - # Post attestation certificate - if [[ ${short} -eq 0 ]]; then - local certificate - certificate=$(sed 's/$/\\n/' "${keypath}/f0000013.cert" | tr -d \\n) - curl --fail --location \ - -H "Authorization: Bearer ${bearer}" \ - -H "cf-access-token: ${cf_token}" \ - -X POST "https://${domain}/api/v1/certificate" \ - -d '{ "orbId": "'"${orb_id}"'", "certificate": "'"${certificate}"'" }' - fi - - # Post signup key - local signup_pubkey - signup_pubkey=$(sed 's/$/\\n/' "${keypath}/sss_70000002_0002_0040.bin" | tr -d \\n) - curl --fail --location \ - -H "Authorization: Bearer ${bearer}" \ - -H "cf-access-token: ${cf_token}" \ - -X POST "https://${domain}/api/v1/key" \ - -d '{ - "orbId": "'"${orb_id}"'", - "type": "signup", - "key": "'"${signup_pubkey}"'", - "signature": "'$(base64 -w 0 "${keypath}/70000002.signature.raw")'", - "extraData": "'$(base64 -w 0 "${keypath}/70000002.extra.raw")'", - "active": true - }' - - # Post attestation key - local attestation_pubkey - attestation_pubkey=$(sed 's/$/\\n/' "${keypath}/sss_70000001_0002_0040.bin" | tr -d \\n) - curl --fail --location \ - -H "Authorization: Bearer ${bearer}" \ - -H "cf-access-token: ${cf_token}" \ - -X POST "https://${domain}/api/v1/key" \ - -d '{ - "orbId": "'"${orb_id}"'", - "type": "attestation", - "key": "'"${attestation_pubkey}"'", - "signature": "'$(base64 -w 0 "${keypath}/70000001.signature.raw")'", - "extraData": "'$(base64 -w 0 "${keypath}/70000001.extra.raw")'", - "active": true - }' - - # Post chip ID - curl --fail --location \ - -H "Authorization: Bearer ${bearer}" \ - -H "cf-access-token: ${cf_token}" \ - -X POST "https://${domain}/api/v1/key" \ - -d '{ - "orbId": "'"${orb_id}"'", - "type": "chipid", - "key": "'"$(base64 -w 0 "${keypath}/7fff0206.chip_id.raw")"'", - "signature": "'$(base64 -w 0 "${keypath}/7fff0206.signature.raw")'", - "extraData": "'$(base64 -w 0 "${keypath}/7fff0206.extra.raw")'", - "active": true - }' -} - -# Ensure that main only runs when called as a script -if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then - main "$@" -fi