Open urandom2 opened 7 years ago
Yeah, I got the user blob wrong, which is causing problems when there is >1 user.
When I picked this up again recently I got offered a firmware upgrade, so I started writing notes:
But when I last looked at this code (2014), there wasn't such a firmware update available.
However I haven't actually put that into the testserver or Django implementation of the protocol yet. As a result, the scales won't work properly with this if you have >1 user.
hmm, I consulted your notes and came up with the following diff:
@@ -161,8 +160,7 @@ class ScaleUploadView(View):
if min_var < 0:
min_var = 0
max_var = last_weight + 4000
-
- response += struct.pack('<L16x20sLLLBLLLLLLLLL',
+ response += struct.pack('<L16x20sLLLBLLLLLLL',
profile.user.id,
profile.short_name_formatted(),
min_var,
@@ -177,14 +175,15 @@ class ScaleUploadView(View):
0, # another weight
0, # timestamp
- 0, # always 0
- 3, # always 3
0 # always 0
)
- response = response + struct.pack('<HBB',
+ response = response + struct.pack('<LLLHBB',
+ 0x03, # update status: no
+ 3, # unknown
+ 0, # unknown
crc16xmodem(response), # checksum
- 0x66, # always 0x66
+ 0x66, # always 0x66 sometimes also 0xac
0x00, # always 0x00
)
however, this triggers a NO SYNC
error; it is worth noting that I am attempting to push two users. I have also tried this:
@@ -161,8 +160,7 @@ class ScaleUploadView(View):
if min_var < 0:
min_var = 0
max_var = last_weight + 4000
-
- response += struct.pack('<L16x20sLLLBLLLLLLLLL',
+ response += struct.pack('<L16x20sLLLBLLLLLLL',
profile.user.id,
profile.short_name_formatted(),
min_var,
@@ -177,14 +175,14 @@ class ScaleUploadView(View):
0, # another weight
0, # timestamp
- 0, # always 0
- 3, # always 3
0 # always 0
)
- response = response + struct.pack('<HBB',
+ response = response + struct.pack('<LLHBB',
+ 0x03, # update status: no
+ 0, # unknown
crc16xmodem(response), # checksum
- 0x66, # always 0x66
+ 0x66, # always 0x66 sometimes also 0xac
0x00, # always 0x00
)
but this too had no success; my thought process was that since the current code does succeed for 1 user that the 3
and 0
, uint32
values should be bottom factored out of the loop; am I misunderstanding your notes, or is it time to break out the proxies and capture some packets going to the fitbit servers?
p.s. my suggested implementation breaks the crc16 checksum, and potentially has the wrong magic number at the end (0x66 is given by fitbit for 1 user, 0xb3 is given for 2)
Ah, so was the version in that pull request functional or not? Did you solve it by using that trailer
value?
oh, sorry I forgot to document my later findings; it looks like that trailer value is some sort of length parameter that is correlated with the number of scale users
this formula gives the accurate value:
0x19 + (len(scale_users) * 0x4d)
so, you should be in buisness if the last response = response +
stanza looks like this:
response = response + struct.pack('<HH',
crc16xmodem(response), # checksum
0x19 + (len(scale_users) * 0x4d),
)
I can provide intercepted packets if you like.
The user blob is being accurately returned to the scale as part of
ScaleUploadView()
, I have confirmed that all my users are in thescale_users
set and theresponse
blob, but the scale never recognizes them.This may be an issue with my management of the database, but I am looking for good ways to debug this, since the aria is such a black box.