User Tools

Site Tools


elec:notes:wt_pulse

# 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_)`

  • `_ACCOUNT_PASSWORD_` is the plain-text password of the account

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_&currentfw=_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.

  • It's generated with `md5(_PULSE_MACADDR_:_PULSE_SECRET_:_ONCEVAL_)`
  • `_PULSE_SECRET_` is a 16-chars hexstring: `NNxxxNNNNxNxNNNN`

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_&currentfw=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

/home/share/www/redox.ws/wiki/data/pages/elec/notes/wt_pulse.txt · Last modified: 2023/11/24 21:55 by 127.0.0.1