# Withings Pulse
## Overview
It's an activity tracker. I'm curious about this stuff theses days, so I thought I'd dive in and see… And of course, look closer
## USB
The USB port of the device is only here for charging. But plugging it would throw:
[27701.907508] usb 4-1: new full-speed USB device number 18 using uhci_hcd [27702.023964] usb 4-1: device descriptor read/64, error -71 ... [27703.414113] usb 4-1: device not accepting address 20, error -71 ... [27703.934408] hub 4-0:1.0: unable to enumerate USB device on port 1
So I thought there would be some way to put the Pulse in some kind of real USB Mode: To get there, hold the Pulse button before you plug it in. With some trials, it enumerates as an USB HID device
[27723.342193] hid-generic 0003:1FB2:0004.0008: hiddev0,hidraw4: USB HID v1.10 Device [ Withings Pulse ] on usb-0000:00:1d.1-1/input0
### lsusb output
Bus 004 Device 017: ID 1fb2:0004 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x1fb2 idProduct 0x0004 bcdDevice 0.02 iManufacturer 1 (error) iProduct 2 (error) iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 41 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 No Subclass bInterfaceProtocol 0 None iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.10 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 57 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x003a 1x 58 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x003a 1x 58 bytes bInterval 1 Device Status: 0xbd03 Self Powered Remote Wakeup Enabled
## Sync ### Overview
The Android App syncs with the Pulse, and then to the account. It uses some kind of JSON API, with POST requests.
The base URL for the synchronization server is `http://scalews.withings.net/`.
There's also a call to `http://maintws.withings.net/` for the /cgi-bin/maint call.
### /cgi-bin/once : Once Query
action=get&appliver=_ANDRO_APPV_&apppfm=android&appname=wiscaleNG
* `_ANDRO_APPV_` is the Android App version. Current is: `161`
Reply:
{"status":0,"body":{"once":"_ONCEVAL_"}}
* `_ONCEVAL_` is a server-generated value that's used to instanciate session (both User and Device)
### /cgi-bin/session : Session handling It looks like there are different actions handled by this URL. #### User login Query:
action=new&auth=_ACCOUNT_MAILADDR_&hash=_ACCOUNT_HASH_ca&duration=60&appliver=_ANDRO_APPV_&apppfm=android&appname=wiscaleNG
* `_ACCOUNT_MAILADDR_` is the Mail address of the account, in plain text * `_ACCOUNT_HASH_` looks like a MD5 hash, but isn't the account password. It's generated with `md5(_ACCOUNT_MAILADDR_:md5(_ACCOUNT_PASSWORD_):_ONCEVAL_)`
Reply:
{"status":0,"body":{"sessionid":"_SESSION_ID_","account":[{"id":_ACCOUNT_ID_,"debug":0}]}}
* `_SESSION_ID_` is a server-generated ID: `xxxx-xxxxxxxx-xxxxxxxx` * `_ACCOUNT_ID_` must be the real account ID (not sure though…)
#### Pulse login Query:
action=new&auth=_PULSE_MACADDR_&hash=_PULSE_HASH_¤tfw=_PULSE_FWV_&mfgid=_MFGID_&batterylvl=_PULSE_BATLVL_&appliver=_ANDRO_APPV_&apppfm=android&appname=wiscaleNG
* `_PULSE_MACADDR_` is the Bluetooth MAC Address of the Pulse device: `xx:xx:xx:xx:xx:xx` * `_PULSE_HASH_` looks like a MD5 hash.
I don't know it's generated, but it can be extracted from the Android log (with logcat, search for `– withings *` ) * `_PULSE_FWV_` is the Firmware version. Current is `971`. * `_MFGID_` is a numeric ID: `XX32XX`. * `_PULSE_BATLVL_` is the battery percentage: `0` to `100`
Reply:
{"status":0,"body":{"sessionid":"_PULSE_SESSID","sp":{"users":[]},"ind":{"lg":"fr_FR","imt":1,"stp":"1","f":0,"g":98071},"syp":{"utc":_DATEA_},"ctp":{"goff":3600,"dst":_DATEB_,"ngoff":7200}}}
* `_PULSE_SESSID_` is a server-generated ID: `xxxx-xxxxxxxx-xxxxxxxx` * `_DATEA_` is a Unix timestamp. Ex: `1391328539` * `_DATEB_` is a Unix timestamp. Ex: `1396141200`
#### Session destroy Query:
action=delete&sessionid=_SESSION_ID_`&appliver=`_ANDRO_APPV_`&apppfm=android&appname=wiscaleNG
* `_SESSION_ID_` is the server-generated ID of the session to be destroyed: `xxxx-xxxxxxxx-xxxxxxxx`
Reply:
{"status":0}
### Not detailed yet
/cgi-bin/account
/cgi-bin/association
/cgi-bin/device
/cgi-bin/measure
/cgi-bin/bodymedia
/cgi-bin/zeo
/cgi-bin/push
/cgi-bin/runkeeper
/cgi-bin/v2/link
/cgi-bin/v2/measure
/cgi-bin/v2/activity
/cgi-bin/v2/firmware \\ firmware?action=getupdate&sessionid=_SESSION_ID_¤tfw=1&appliver=_ANDRO_APPV_&apppfm=android&appname=wiscaleNG {"status":0,"body":{"url":"http:\/\/fw.withings.net\/wam01_971.bin"}}
/cgi-bin/user
/cgi-bin/maint
## Random notes
The Pulse has an OLED screen, a USB port, an onboard button and, of course, bluetooth
* Freescale Kinetis MK20DX256 - FCC photo is bad quality…K23ZJ2SD74 * USB Mode, CDC Shell * Serial Debug * Hack firmware * AC20B co-processor maybe * SPI flash * I2C bus * DbLib * 1234 * DHD_RTOS * ADXL 202/345 * CC2564 *
http://www.droid-developers.org/wiki/Disassembling
## Links
* Hacking the Withings Smart Baby Monitor * Summercon 2013 - Hacking the Withings WS30 * Summercon 2013 - Hacking the WS30 - Youtube * Hacking the WS30 - Local server
### Angel
* Indiego Angel * Angel