Skip to content

Commit ac87a45

Browse files
committed
rust/hww: fix module-inception
api::api is bad (clippy), so we move it to mod.rs.
1 parent 1e359f0 commit ac87a45

File tree

2 files changed

+151
-168
lines changed

2 files changed

+151
-168
lines changed

src/rust/bitbox02-rust/src/hww/api/api.rs

Lines changed: 0 additions & 166 deletions
This file was deleted.

src/rust/bitbox02-rust/src/hww/api/mod.rs

Lines changed: 151 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,154 @@ mod pb {
1616
include!("./shiftcrypto.bitbox02.rs");
1717
}
1818

19-
mod api;
20-
pub use api::process;
19+
use alloc::vec::Vec;
20+
21+
use bitbox02::commander::Error;
22+
use pb::request::Request;
23+
use pb::response::Response;
24+
25+
/// Creates an Error response. Corresponds to commander.c:_report_error().
26+
fn make_error(err: bitbox02::commander::Error) -> Response {
27+
use Error::*;
28+
let err = match err {
29+
COMMANDER_OK => panic!("can't call this function with COMMANDER_OK"),
30+
COMMANDER_ERR_INVALID_INPUT => pb::Error {
31+
code: 101,
32+
message: "invalid input".into(),
33+
},
34+
COMMANDER_ERR_MEMORY => pb::Error {
35+
code: 102,
36+
message: "memory".into(),
37+
},
38+
COMMANDER_ERR_GENERIC => pb::Error {
39+
code: 103,
40+
message: "generic error".into(),
41+
},
42+
COMMANDER_ERR_USER_ABORT => pb::Error {
43+
code: 104,
44+
message: "aborted by the user".into(),
45+
},
46+
COMMANDER_ERR_INVALID_STATE => pb::Error {
47+
code: 105,
48+
message: "can't call this endpoint: wrong state".into(),
49+
},
50+
COMMANDER_ERR_DISABLED => pb::Error {
51+
code: 106,
52+
message: "function disabled".into(),
53+
},
54+
COMMANDER_ERR_DUPLICATE => pb::Error {
55+
code: 107,
56+
message: "duplicate entry".into(),
57+
},
58+
};
59+
Response::Error(err)
60+
}
61+
62+
/// Encodes a protobuf Response message.
63+
fn encode(response: Response) -> Vec<u8> {
64+
use prost::Message;
65+
let response = pb::Response {
66+
response: Some(response),
67+
};
68+
let mut out = Vec::<u8>::new();
69+
response.encode(&mut out).unwrap();
70+
out
71+
}
72+
73+
/// Returns the field tag number of the request as defined in the .proto file. This is needed for
74+
/// compatibility with commander_states.c, and needed as long as API calls processed in C use
75+
/// `commmander_states_force_next()`.
76+
fn request_tag(request: &Request) -> u32 {
77+
use Request::*;
78+
match request {
79+
RandomNumber(_) => bitbox02::Request_random_number_tag,
80+
DeviceName(_) => bitbox02::Request_device_name_tag,
81+
DeviceLanguage(_) => bitbox02::Request_device_language_tag,
82+
DeviceInfo(_) => bitbox02::Request_device_info_tag,
83+
SetPassword(_) => bitbox02::Request_set_password_tag,
84+
CreateBackup(_) => bitbox02::Request_create_backup_tag,
85+
ShowMnemonic(_) => bitbox02::Request_show_mnemonic_tag,
86+
BtcPub(_) => bitbox02::Request_btc_pub_tag,
87+
BtcSignInit(_) => bitbox02::Request_btc_sign_init_tag,
88+
BtcSignInput(_) => bitbox02::Request_btc_sign_input_tag,
89+
BtcSignOutput(_) => bitbox02::Request_btc_sign_output_tag,
90+
InsertRemoveSdcard(_) => bitbox02::Request_insert_remove_sdcard_tag,
91+
CheckSdcard(_) => bitbox02::Request_check_sdcard_tag,
92+
SetMnemonicPassphraseEnabled(_) => bitbox02::Request_set_mnemonic_passphrase_enabled_tag,
93+
ListBackups(_) => bitbox02::Request_list_backups_tag,
94+
RestoreBackup(_) => bitbox02::Request_restore_backup_tag,
95+
PerformAttestation(_) => bitbox02::Request_perform_attestation_tag,
96+
Reboot(_) => bitbox02::Request_reboot_tag,
97+
CheckBackup(_) => bitbox02::Request_check_backup_tag,
98+
Eth(_) => bitbox02::Request_eth_tag,
99+
Reset(_) => bitbox02::Request_reset_tag,
100+
RestoreFromMnemonic(_) => bitbox02::Request_restore_from_mnemonic_tag,
101+
Bitboxbase(_) => bitbox02::Request_bitboxbase_tag,
102+
Fingerprint(_) => bitbox02::Request_fingerprint_tag,
103+
Btc(_) => bitbox02::Request_btc_tag,
104+
ElectrumEncryptionKey(_) => bitbox02::Request_electrum_encryption_key_tag,
105+
}
106+
}
107+
108+
async fn api_set_device_name(
109+
pb::SetDeviceNameRequest { name }: &pb::SetDeviceNameRequest,
110+
) -> Response {
111+
use crate::workflow::confirm;
112+
let params = confirm::Params {
113+
title: "Name",
114+
body: &name,
115+
scrollable: true,
116+
..Default::default()
117+
};
118+
119+
if !confirm::confirm(&params).await {
120+
return make_error(Error::COMMANDER_ERR_USER_ABORT);
121+
}
122+
123+
if bitbox02::memory::set_device_name(&name).is_err() {
124+
return make_error(Error::COMMANDER_ERR_MEMORY);
125+
}
126+
127+
Response::Success(pb::Success {})
128+
}
129+
130+
/// Handle a protobuf api call.
131+
///
132+
/// Returns `None` if the call was not handled by Rust, in which case
133+
/// it should be handled by the C commander.
134+
async fn process_api(request: &Request) -> Option<Response> {
135+
match request {
136+
Request::DeviceName(ref request) => Some(api_set_device_name(request).await),
137+
_ => None,
138+
}
139+
}
140+
141+
/// Handle a protobuf api call. API calls not handled by Rust are
142+
/// handled by the C commander, which allows us to use Rust for new
143+
/// api calls and port the old calls step by step.
144+
///
145+
/// `input` is a hww.proto Request message, protobuf encoded.
146+
/// Returns a protobuf encoded hww.proto Response message.
147+
pub async fn process(input: Vec<u8>) -> Vec<u8> {
148+
use prost::Message;
149+
let request = match pb::Request::decode(&input[..]) {
150+
Ok(pb::Request {
151+
request: Some(request),
152+
}) => request,
153+
_ => return encode(make_error(Error::COMMANDER_ERR_INVALID_INPUT)),
154+
};
155+
if !bitbox02::commander::states_can_call(request_tag(&request) as u16) {
156+
return encode(make_error(Error::COMMANDER_ERR_INVALID_STATE));
157+
}
158+
159+
// Since we will process the call now, so can clear the 'force next' info.
160+
// We do this before processing as the api call can potentially define the next api call
161+
// to be forced.
162+
bitbox02::commander::states_clear_force_next();
163+
164+
match process_api(&request).await {
165+
Some(response) => encode(response),
166+
// Api call not handled in Rust -> handle it in C.
167+
_ => bitbox02::commander::commander(input),
168+
}
169+
}

0 commit comments

Comments
 (0)