Skip to content
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

user management woes #2

Open
urandom2 opened this issue Apr 24, 2017 · 5 comments
Open

user management woes #2

urandom2 opened this issue Apr 24, 2017 · 5 comments

Comments

@urandom2
Copy link
Contributor

urandom2 commented Apr 24, 2017

The user blob is being accurately returned to the scale as part of ScaleUploadView(), I have confirmed that all my users are in the scale_users set and the response 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.

@micolous
Copy link
Owner

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:

8d8838d#diff-7327496955357b9792bab8720dc507d6

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.

@urandom2
Copy link
Contributor Author

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?

@urandom2
Copy link
Contributor Author

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)

@micolous
Copy link
Owner

micolous commented Jun 4, 2017

Ah, so was the version in that pull request functional or not? Did you solve it by using that trailer value?

@urandom2
Copy link
Contributor Author

urandom2 commented Jun 4, 2017

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.

micolous added a commit that referenced this issue Jun 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants