-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
api/firmware/device: info use device status fields #98
base: master
Are you sure you want to change the base?
Conversation
68e1951
to
0008efa
Compare
0008efa
to
51ae730
Compare
(added version check and fixed some formatting) |
51ae730
to
aca0124
Compare
api/firmware/device.go
Outdated
@@ -145,24 +145,24 @@ func NewDevice( | |||
|
|||
// info uses the opInfo api endpoint to learn about the version, platform/edition, and unlock | |||
// status (true if unlocked). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update docstring please
api/firmware/device.go
Outdated
@@ -145,24 +145,24 @@ func NewDevice( | |||
|
|||
// info uses the opInfo api endpoint to learn about the version, platform/edition, and unlock | |||
// status (true if unlocked). | |||
func (device *Device) info() (*semver.SemVer, common.Product, bool, error) { | |||
func (device *Device) info() (*semver.SemVer, common.Product, bool, *bool, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at this point i think it makes sense to convert the result into a struct with named and documented fields
api/firmware/device.go
Outdated
@@ -261,7 +287,7 @@ func (device *Device) Init() error { | |||
|
|||
// Before 2.0.0, unlock was invoked automatically by the device before USB communication | |||
// started. | |||
if device.version.AtLeast(semver.NewSemVer(2, 0, 0)) { | |||
if device.version.AtLeast(semver.NewSemVer(2, 0, 0)) && (device.status != StatusInitialized) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is wrong I think - Initialized means backup created, not unlocked. The docstring in status.go might be wrong. Regardless it's an unrelated change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes the docstring on StatusInitialized
is wrong, I got confused because I thought it actually meant something else in this repo (also because the animation stops playing when status changes from StatusConnected
to StatusInitialized
) but we actually need a new status StatusUnlocked
and use that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this can then be changed to 'initialized' || 'seeded'
:
https://github.com/BitBoxSwiss/bitbox-wallet-app/blob/0fa7a7144984fa5a4f7731d222b69505902b220a/frontends/web/src/routes/device/bitbox02/wizard.tsx#L103
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need StatusUnlocked 'seeded' is the step after setting password, before creating a backup, but upon re-plug the user starts from the beginning (by design). No need to change to 'seeded' in the above link.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I was not sure I thought there might be a situation where the user unplugs the device after setting a password but before finishing the backup which would cause the device to end up 'seeded' when reconnecting it.
I don't think we need StatusUnlocked.
makes sense, I'll remove StatusUnlocked
and set the status to StatusInitialized
if deviceInfo.unlocked || deviceInfo.initialized
api/firmware/device.go
Outdated
if err != nil { | ||
return errp.New( | ||
"OP_INFO unavailable; need to provide version and product via the USB HID descriptor") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is incorrect - old firmwares don't support OP_INFO and we can't just error here. Before, the OP_INFO call to infer the version/product would be done only if it was not already provided.
What you now want to do is probably to call info() if supported by the firmware (need to look up fw version), and use the results of it when possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes. We do need to call info()
if we don't know if its supported device.version == nil
too tough, so I'll just put this into a version == nil || version atLeast(4.3.0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned above here:
#98 (comment)
I think changing the if-clause around this to:
if device.version == nil || device.version.AtLeast(semver.NewSemVer(9, 2, 0)) { ...}
is the way to go.
side note: But I also think that it was not incorrect though, we basically do the same already:
bitbox02-api-go/api/firmware/device.go
Line 247 in a2115fe
return err |
Just propagated from the inferVersionAndProduct
function instead of directly.
aca0124
to
15a4a16
Compare
@benma thanks. addressed these, PTAL:
Now
|
I also added one commit that renames |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to think more about StatusUnlocked and how it relates to the problem in the bbapp. Could be good already, but I need to revisit it later.
api/firmware/device.go
Outdated
@@ -114,15 +114,28 @@ type DeviceInfo struct { | |||
SecurechipModel string `json:"securechipModel"` | |||
} | |||
|
|||
// DeviceInfoREQ_INFO is the data returned from the REQ_INFO api call. | |||
type DeviceInfoREQ_INFO struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can unexport the struct, and i'd simply name info struct
or sth, REQ_INFO
is not really following any naming pattern in Go :P
api/firmware/device.go
Outdated
|
||
if err := device.inferVersionAndProduct(); err != nil { | ||
return err | ||
if device.version == nil || device.version.AtLeast(semver.NewSemVer(4, 3, 0)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the version is below 4.3, you can't call it either really as it does not exist, so the 2nd condition alone is enough.
If the fw is older and version is nil, you could return an error, as at least one of them has to be true.
I don't think you need to call inferVersionAndProduct
at all really. It helped to avoid the OP_INFO call if the version was already known, but you call it now always, so its not really doing anything. Maybe you could compare the version/product to the one already set if available as a sanity check, but you can just also override it directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand.
- we want to call
info()
always except if the version is known before 4.3. doesn't this mean we call it either if version isnil
or if its notnil
but higher than 4.3 ? - why is it an error if fw is older than 4.3 and nil ?
device.version.AtLeast()
will befalse
(older) ifdevice.version
isnil
I don't think you need to call inferVersionAndProduct at all really.
I agree, let me know what you think is best, sanity check, override or just removing the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Thinking about this again, I think removing the
inferVersionAndProduct
makes most sense. - Actually without the first condition there would be a nil pointer dereference error if the version is actually
nil
, this crashes:
- if device.version == nil || device.version.AtLeast(semver.NewSemVer(4, 3, 0)) {
+ device.version = nil
+ if device.version.AtLeast(semver.NewSemVer(4, 3, 0)) {
I think changing it to if (device.version == nil || device.version.AtLeast(semver.NewSemVer(9, 2, 0)))
makes sense:
We always want to check info()
because we're interested in the initialized
field:
- if we know the version and we know it supports the
initialized
field we want to callinfo()
- if the version is
nil
we want to callinfo()
like we did before ininferVersionAndProduct
- if we know the version but we know we won't learn the
initialized
field from callinginfo()
there is no need to call it anyways, just likeinferVersionAndProduct
avoided calling it if the version was already known.
(unimportant) I think I initially used AtLeast(4,3,0)
because I thought it makes sense since info()
will only work for at least this version, but I did not see that if we know the version and we don't want to call info()
unless we know we can get the initialized status from it, even if calling it is supported.
api/firmware/device.go
Outdated
@@ -261,7 +293,7 @@ func (device *Device) Init() error { | |||
|
|||
// Before 2.0.0, unlock was invoked automatically by the device before USB communication | |||
// started. | |||
if device.version.AtLeast(semver.NewSemVer(2, 0, 0)) { | |||
if device.version.AtLeast(semver.NewSemVer(2, 0, 0)) && (device.status != StatusUnlocked) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again, unrelated change and not needed. why did you add it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed it now, mb I think I just thought since we can check for that now it makes sense to do so.
15a4a16
to
02bafe6
Compare
02bafe6
to
ccf77e3
Compare
3c00608
to
77762fe
Compare
Return struct containing REQ_INFO response data from device.info(). Amongst the already existing fields that were previously returned by info() as a tuple, also add the initialized status to the struct that is returned after firmware version 9.20.0. In case the device does not respond with the initialized status byte yet it will be nil. Otherwise true/false depending on the initialized status (seeded and backup created) of the device. Also use the information from device.info to set the device.status earlier to avoid showing the password video if the device is not initialized. Also rename OP_INFO to REQ_INFO because the name changed after this commit: BitBoxSwiss/bitbox02-firmware@a785012 The name should be the same as in the firmware repositroy so that the code base is easier to understand. Also rename StatusInitialized to StatusUnlocked to avoid confusion.
77762fe
to
f484ac8
Compare
@benma I think this is ready now, I tested it thoroughly with BB02M FW 9.20.0 and BB02B FW 9.19.0. App needs the following changes: To test I put
This was very confusing because Initialized means something different in the Firmware then it did in the app/go-api. In the app/go-api, we used TLDR; Is that we want to set the status to If the device is unlocked we obviously set it to side note: there is still a But this one is used for another call on the device and actually means initialized and not unlocked if I understand it correctly. |
Return initialized status from info() and use unlocked and initialized to set the device status appropriately.
After firmware PR 1229