Skip to content

Commit 2c08ada

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

File tree

2 files changed

+150
-167
lines changed

2 files changed

+150
-167
lines changed

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

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

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

Lines changed: 150 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,153 @@ 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+
use prost::Message;
25+
26+
/// Creates an Error response. Corresponds to commander.c:_report_error().
27+
fn make_error(err: bitbox02::commander::Error) -> Response {
28+
use Error::*;
29+
let err = match err {
30+
COMMANDER_OK => panic!("can't call this function with COMMANDER_OK"),
31+
COMMANDER_ERR_INVALID_INPUT => pb::Error {
32+
code: 101,
33+
message: "invalid input".into(),
34+
},
35+
COMMANDER_ERR_MEMORY => pb::Error {
36+
code: 102,
37+
message: "memory".into(),
38+
},
39+
COMMANDER_ERR_GENERIC => pb::Error {
40+
code: 103,
41+
message: "generic error".into(),
42+
},
43+
COMMANDER_ERR_USER_ABORT => pb::Error {
44+
code: 104,
45+
message: "aborted by the user".into(),
46+
},
47+
COMMANDER_ERR_INVALID_STATE => pb::Error {
48+
code: 105,
49+
message: "can't call this endpoint: wrong state".into(),
50+
},
51+
COMMANDER_ERR_DISABLED => pb::Error {
52+
code: 106,
53+
message: "function disabled".into(),
54+
},
55+
COMMANDER_ERR_DUPLICATE => pb::Error {
56+
code: 107,
57+
message: "duplicate entry".into(),
58+
},
59+
};
60+
Response::Error(err)
61+
}
62+
63+
/// Encodes a protobuf Response message.
64+
fn encode(response: Response) -> Vec<u8> {
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+
let request = match pb::Request::decode(&input[..]) {
149+
Ok(pb::Request {
150+
request: Some(request),
151+
}) => request,
152+
_ => return encode(make_error(Error::COMMANDER_ERR_INVALID_INPUT)),
153+
};
154+
if !bitbox02::commander::states_can_call(request_tag(&request) as u16) {
155+
return encode(make_error(Error::COMMANDER_ERR_INVALID_STATE));
156+
}
157+
158+
// Since we will process the call now, so can clear the 'force next' info.
159+
// We do this before processing as the api call can potentially define the next api call
160+
// to be forced.
161+
bitbox02::commander::states_clear_force_next();
162+
163+
match process_api(&request).await {
164+
Some(response) => encode(response),
165+
// Api call not handled in Rust -> handle it in C.
166+
_ => bitbox02::commander::commander(input),
167+
}
168+
}

0 commit comments

Comments
 (0)