Tuesday, January 22, 2013

Fitbit USB Dongle Sniffing

Sync packets are all well and good, and decoding them continues to be a priority, but I decided to give it another go with the USB filter driver today.

Using busdog, I'm now seeing chatter text in a USB trace!  (Does that mean the link is not encrypted?)

11 In  (USB URB Function: 9) 0.007991 32 48 45 59 20 48 45 59 21 20 20 48 49 47 48 46 49 56 45 20 20 00 00 00 00 00 00 00 00 00 00 00 14 HEY HEY!  HIGHFIVE  ............

I expected that the filter driver would just pick up bluetooth transport (HCI?) bytes, but I also see strings in the log that make me wonder if the dongle uses something like a serial protocol to communicate with the host PC.  That would be weird, though, or at least not like most other bluetooth dongles.

13  In  (USB URB Function: 9)   0.000002    32  20 01 43 61 6e 63 65 6c 44 69 73 63 6f 76 65 72 79 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  .CancelDiscovery...............
. . .
13  In  (USB URB Function: 9)   0.000003    32  20 01 47 41 50 5f 4c 49 4e 4b 5f 45 53 54 41 42 4c 49 53 48 45 44 5f 45 56 45 4e 54 00 00 00 00  .GAP_LINK_ESTABLISHED_EVENT....

Anyway... we'll see.  I don't have protocol docs for Bluetooth LE, but perhaps by subtracting the bytes in the sync log from this output and doing some more reading, I'll be able to deduce something more about the actual device communication.

Saturday, January 19, 2013

Fitbit Sync Decode - Part 3

Slowly but steadily piecing together parts of the puzzle from the sync logs / fiddler traces.

Discovered that there is a so-called "mega-dump" and "micro-dump".  The mega-dump is used for general syncs, but the micro-dump was used when I tried a firmware update.

I've setup a github repo for my parsing code at https://github.com/hiptopjones/fitbit.  I'll let that code stand as documentation for now.

Wednesday, January 9, 2013

Fitbit Sync Decode - Part 2

If we think about what information would need to be passed back and forth, that might help when looking at the sync data, and provide ideas about what knobs to turn.  A good source for inspiration here is the user manual.

This summary data would probably go in both directions:
  • Calories
  • Steps (walking + running)
  • Elevation (floors, distance)
  • Distance (native units)
  • Active score (# plant leaves, score)
These would be passed from device to server:
  • Timer information (start/stop)
  • Steps data series (per minute)
  • Elevation data series (per minute)
  • Battery level (charging status?)
  • Firmware version
  • Beginner mode flag (?)
These would be passed from server to device:
  • Enable/Disable flag for all of the displayed metrics
  • Chatter text
  • Current date/time
  • Stride length (walking, running)
  • Body stats / BMR (for calorie estimations)
  • Timezone
  • Units (distance)
  • Time format (ie. 12/24 hour clock)
  • Left-hand/Right-hand mode
  • Silent alarm settings (including repetitions on specific days)
  • Sleep tracking mode (normal vs. sensitive)
Some additional inputs:
  • There are 10 leaves on a fully-grown plant
  • The device can store 14 days of minute by minute data, and summary data for 30 days
  • The device can have 8 separate alarms



Tuesday, January 8, 2013

Fitbit Sync Decode - Part 1

There are two sync blobs available to us for inspection.  One blob is from the POST to the server, and the other is the server's response.

An example request:


POST http://client.fitbit.com/tracker/client/message?p_lcl=en_US HTTP/1.1
Content-Type: text/xml
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)
Host: client.fitbit.com
Content-Length: 3328
Pragma: no-cache
Cookie: JSESSIONID=...

<?xml version="1.0"?>
<galileo-client version="2.0">
<client-info>
<client-id>...guid...</client-id>
<client-version>1.0.0.2292</client-version>
<client-mode>force-sync</client-mode>
<dongle-version major="1" minor="1" />
</client-info>
<tracker tracker-id="FFFFFFFFFFFF">
<data>...base64-encoded data...</data>
</tracker>
</galileo-client>

An example response:


HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Type: text/xml;charset=UTF-8
Content-Language: en-US
Vary: Accept-Encoding
Date: Sun, 06 Jan 2013 20:25:11 GMT
Content-Length: 17077

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><galileo-server version="2.0"><server-version>URL: https://wush.net/svn/fitbit/weightsite/branches/Release_20130104
Last Changed Rev: 44872
</server-version><ui-request action="done"><client-display height="450" width="650" minDisplayTimeMs="20000" containsForm="true"> ...html...</client-display></ui-request><commands><connect-to-tracker connection="disconnect" tracker-id="FFFFFFFFFFFF"/></commands><tracker type="megadumpresponse" tracker-id="FFFFFFFFFFFF"><data>...base64-encoded data...</data></tracker></galileo-server>

Comments:
  • This is a trace from a forced sync, where I clicked the Sync Now button in the FitbitConnect UI, so it also contains an HTML page for display.
  • The blobs are base64-encoded since they are part of an XML body.
  • The blob data is also written (not base64 encoded) to the sync log on my desktop
Next up... start digging into these blobs.



Fitbit Text

Just for fun, keeping a list of the chatter text the Fitbit throws at me:
  • HI THERE
  • HOWDY
  • I LIKE U
  • GO
  • STEPGEEK
  • HELLO
  • CLIMB IT
  • WOOT!
  • ITS ON!
  • FASTER
  • IM READY
  • WALK ME
  • SMOOCHES
  • STEPITUP
  • HOLD ME
  • HEY HEY!
  • BON JOUR
  • MOVE IT
  • CHEERS
  • UCANDOIT
  • LETS GO
  • HUG ME
  • READY?
  • GOOOOAL
  • VAMOS
  • YOU ROCK
  • BURN IT
  • HIGHFIVE
  • LOVE YA
  • WHATS UP

Sunday, January 6, 2013

FileScanner

Started working on a file scanner today.  This project is a result of my cluttered hard drives.  I have music and photos and videos all over the place, with duplication, etc.  I need to consolidate them, index them, and make sure they are all stored safely on one set of RAID-1 drives.

This is also an attempt to get out of the C# trap.  Since I use C# a lot at work, it's become my go-to language.  This sucks in a non-MSFT world, like the Mac I use at home, so I'm writing the scanner in Java.  I used to have mad Java chops, but have mostly lost them over the past 4 years.  Hopefully this will bring some of that back.

Ideally, I'd like to write this in Objective C or C++, just to really push myself, but I don't want to spend a ton of time on this particular project.  Java is a lot like C#, so I'm hopeful this will be wrapped up fairly quickly.

Friday, January 4, 2013

Fitbit Sync Experiment

Managed to screw up my Win7 VM by installing the USB filter driver.  Had to go back to a system restore point.

On another note, I tried a little experiment today.  I didn't let my Fitbit sync all day so I could see if there would be a difference in the size of the data payload when I eventually did sync it.  There was.

My Fitbit sent 2380 bytes to the service.  My wife's Fitbit was home with her all day, syncing regularly, and her Fitbit only sent 784 bytes.

Need to decode the sync packets.