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

Support for Nike+ GPS Watch ? #72

Open
prynhart opened this issue Apr 3, 2016 · 38 comments
Open

Support for Nike+ GPS Watch ? #72

prynhart opened this issue Apr 3, 2016 · 38 comments

Comments

@prynhart
Copy link

prynhart commented Apr 3, 2016

Hi,

I've got a Nike+ SportWatch GPS "Powered by TomTom" (http://www.tomtom.com/lib/doc/Nike-SportWatch-QuickStartGuide-EN.pdf), and would love to be able to grab the raw GPS datafiles from it (prior to them being munged by the Nike+ Fat client and uploaded to Nike+).

I was hoping that it would really be a "TomTom" watch - but it seems that this isn't the case, as with the watch connected to a Ubuntu 10.04 LTS box, I'm getting:

# ttwatch -a
Unable to open watch

Is there any chance that support could be added ? I'm hoping it's "close enough" to being a TomTom watch :-) I'm not much of a programmer, but am happy to help re USB sniffing etc.

This is how the device presents in my Mac (the output of system_profiler)

SportWatch:

  Product ID:   0x5455
  Vendor ID:    0x11ac
  Version:  2.00
  Serial Number:    105F94461E000B00
  Speed:    Up to 12 Mb/sec
  Manufacturer: Nike
  Location ID:  0xfa140000 / 8
  Current Available (mA):   500
  Current Required (mA):    500
  Capacity: 66 KB (66,048 bytes)
  Removable Media:  Yes
  Detachable Drive: Yes
  BSD Name: disk1
  Partition Map Type:   MBR (Master Boot Record)
  S.M.A.R.T. status:    Not Supported
  Volumes:
SportWatch:
  Capacity: 65 KB (65,024 bytes)
  Available:    62 KB (62,464 bytes)
  Writable: No
  File System:  MS-DOS FAT12
  BSD Name: disk1s1
  Mount Point:  /Volumes/SportWatch
  Content:  DOS_FAT_12
  Volume UUID:  F50B099E-1E3A-30BE-9AD7-474EBC44661B

Here's someones report (when they were playing around with this type of watch) for a University project:
https://www.os3.nl/_media/2013-2014/courses/ccf/smartwatches-hristo-leendert.pdf

With Thanks in Advance

Patrick Rynhart

@ryanbinns
Copy link
Owner

Interesting. If you're feeling brave, you could edit libttwatch/libttwatch.h and change TOMTOM_VENDOR_ID and TOMTOM_MULTISPORT_PRODUCT_ID to the values of your Nike watch then recompile and try to use it. If you start with simple commands (like getting version information) then it shouldn't cause problems if it doesn't work exactly the same. From the document you linked to, it looks like it should work just fine, so you might be really lucky!

@martinruenz
Copy link

I tried this today and it seems not to work.
I executed ./ttwatch --version, but when send_packet(watch, MSG_UNKNOWN_0D, 0, 0, 20, 0) is called from ttwatch_send_startup_message_group, then libusb_interrupt_transfer(...) returns -1 (LIBUSB_ERROR_IO). I guess this means that the device is not supported? :-/

@prynhart
Copy link
Author

prynhart commented Jul 1, 2016

Yeah that's the same point that I got to also - in libttwatch.cpp, this line returns LIBUSB_ERROR_IO:

result = libusb_interrupt_transfer(watch->device, write_usb_endpoint, packet, packet_size, &count, 10000);

called for packet 09 02 00 0D (dumped using print_packet(packet, packet_size)).

My guess is that the watch is the "same", but the addresses for write and read usb_endpoint are different than the official TomTom watches. Not sure how to determine these addresses - guess you would need to USB sniff the official Nike+ fat client....

@ryanbinns
Copy link
Owner

USB endpoints are fairly easy to find. Run lsusb -v -d11ac and look at the output. Look for an Interface Descriptor with bInterfaceClass equal to 3 Human Interface Device. There should be two Endpoint Descriptors under that. The addresses are listed as bEndpointAddress for each one. Simply copy these values to the code. You can also check the required packet size for the OUT endpoint - the wMaxPacketSize parameter.

Or if you want to list the output of lsusb -v -d11ac I can tell you which numbers to use.

@aw
Copy link

aw commented May 11, 2017

@ryanbinns I've tried a few things as suggested in the comments above, but failed to get it recognized with ttwatch.

Output from lsusb:

$ lsusb -v -d 11ac:5455

Bus 002 Device 005: ID 11ac:5455 Nike 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x11ac Nike
  idProduct          0x5455 
  bcdDevice            2.00
  iManufacturer           1 Nike
  iProduct                2 SportWatch
  iSerial                 3 REDACTED ;)
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           64
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          4 SportWatch
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    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              6 SportWatch HID
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.01
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      36
          Report Descriptor: (length is 36)
            Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
                            (null)
            Item(Local ): Usage, data= [ 0x01 ] 1
                            (null)
            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application
            Item(Global): Report ID, data= [ 0x01 ] 1
            Item(Global): Report Count, data= [ 0x3f ] 63
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Logical Maximum, data= [ 0x01 ] 1
            Item(Global): Logical Minimum, data= [ 0x01 ] 1
            Item(Local ): Usage, data= [ 0x01 ] 1
                            (null)
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Report ID, data= [ 0x09 ] 9
            Item(Global): Report Count, data= [ 0x3f ] 63
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Logical Maximum, data= [ 0x01 ] 1
            Item(Global): Logical Minimum, data= [ 0x01 ] 1
            Item(Local ): Usage, data= [ 0x01 ] 1
                            (null)
            Item(Main  ): Output, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      6 SCSI
      bInterfaceProtocol     80 Bulk-Only
      iInterface              5 SportWatch Drive
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
Device Status:     0x0000
  (Bus Powered)

@ryanbinns
Copy link
Owner

It looks like it uses different endpoint addresses. I'm not sure if it will work, but you could try. Try replacing lines 225-238 of libttwatch.cpp with this:

write_usb_endpoint = 0x01;
read_usb_endpoint = 0x81;

Compile and try again. Don't do anything that writes to the watch though. Use -v to read version number to start with. If that works, you can be a little more adventurous, but still be careful at first.

@aw
Copy link

aw commented May 15, 2017

Sadly, I tried that and it still couldn't detect it.

@prynhart
Copy link
Author

prynhart commented May 15, 2017 via email

@ryanbinns
Copy link
Owner

I don't think I'd be able to do anything useful. I think to make any more progress, you'd need to capture the USB packets transmitted between the watch and the Windows software when the watch is plugged in and the software does its stuff.

@prynhart
Copy link
Author

prynhart commented Aug 5, 2017

Hi Ryan,

Apologies - I've been putting this off, because it sounded too difficult (and because I didn't have a bare-metal Windows box). However, I've just had a go now, and it's much easier than I thought.

I have captured using the latest build of USBPcap (1.2.0.2) using the current version of the Nike Connect+ Software (Version 6.6.34.141).

I thought we would start with the simplest possible case:

  • All drivers installed along with the Fat Client
  • The watch plugged in and empty (i.e. no runs)
  • Start the PCAP packet trace
  • Open the Fat Client, wait for it to communicate with the device, then close the Fat Client
  • Stop the packet trace

I've done this, and the PCAP capture file is attached. I've opened it okay in Wireshark and can see communication with the device.

Very happy to upload runs etc as needed (or to switch features on and off using the Fat Client under a packet trace).

Thanks again - and apologies for not following up sooner.

Patrick
NikeWatchWithoutRuns.zip

@prynhart prynhart closed this as completed Aug 5, 2017
@prynhart
Copy link
Author

prynhart commented Aug 5, 2017

Oops - I did not mean to close this ticket :)

@prynhart prynhart reopened this Aug 5, 2017
@cgibson33
Copy link

Hi. Nike just announced they will be retiring the only applications that pull data off their watch by April 30, so I'm guessing this thread will receive more interest.

@prynhart
Copy link
Author

Yeah I know - amazing they can give less than 2 weeks notice on this - the link to the FAQ is https://en-gb-help.nike.com/app/answer/article/why-cant-i-sync/a_id/73653/country/nz

screen shot 2018-04-19 at 2 02 48 pm

@cgibson33
Copy link

So, reading through the thread, it appears that you were able to capture some data, but that ryanbinns or someone else still needs some run data before being able to create a version of the software(s) that works with the Nike+ sportwatch? Correct me if I misunderstand.

@prynhart
Copy link
Author

Unfortunately the strap on my Nike+ GPS Sportwatch broke very recently and it won't connect up to any of my computers (a common fault with these watches). However, what you're saying above is correct - i.e. a patch needs to be created for the Nike version of this TomTom watch. Capturing the USB packets was straight forward on Windows (I followed the instructions at https://wiki.wireshark.org/CaptureSetup/USB) - so in theory anyone with a Windows box, the watch, and the Nike+ Connect Software (while it is still running) should be able to capture the protocol exchange between the client and the watch.

@cgibson33
Copy link

Ok. I guess I better get on that then. I assume I need to run a variety of use cases. First I will try to capture watch connection with 1 run to transfer/upload.

@cgibson33
Copy link

I managed to capture a single run transfer. I have never used wireshark before, so I suspect that the file may also contain traffic from other USB ports. Any directions on how to remove information from the other ports?

@cgibson33
Copy link

The capture used the 64 bit version of wireshark with USBPcap included with the wireshark installation. Easy enough to use once I got it installed correctly. I suppose I should read the wireshark wiki on how to analyse the resultant file.

@cgibson33
Copy link

one run filtered for bus1 and device ID6.zip

Ok - I think I did that correctly - I did the capture and then created a new file filtered only for bus1 and device ID that correlated to the watch. I noticed that the address seemed to change from 1.6.0 to 1.6.1 but that appears to be the correct data/traffic.

@prynhart
Copy link
Author

prynhart commented Apr 21, 2018 via email

@cgibson33
Copy link

Will do. Do you think it would be ok if I left the watch plugged in the whole time, but just recorded each action separately using different file names?
Also, I think there is a watch reset function that I should record because that might be the only way to clear the watch memory when it is getting full.

@internecivusraptus
Copy link

internecivusraptus commented Apr 22, 2018

I think I should share my research notes.
All the relevant information can be filtered by entering usb.capdata into wireshark's display filter — it's a leftover capture data that we're interested in.
This leftover data is 64 bytes long. First byte is a direction (09 into watch, 01 from watch), second byte is a packet size, third one is just a counter. For the query that goes into watch, fourth byte is a command, next bytes are arguments. For the respond that we receive from watch fourth byte and next bytes are the reply data, last byte is some sort of check byte, it has to be the same as a counter byte.

The system nike client uses to download tracks is pretty dumb — it sends the '09 05 xx 10 00 00 00 ..' packet, the watch responds with a complete eeprom dump and the client is analyzing it afterwards.
Typical response is '01 3d xx 01 xx xx xx (significant_data_bytes) xx' when we still have data to receive and '01 (size_of_packet) xx 00 xx xx xx (significant_data_bytes) 00 .. 00 xx' when it is the last packet.

It seems that I have a corrupted watch, so I couldn't analyze what I am getting from the watch.

P.S. I was still able to change some settings like sounds, weight, metric or imperial units, etc.

@prynhart
Copy link
Author

prynhart commented Apr 22, 2018 via email

@prynhart
Copy link
Author

prynhart commented Apr 22, 2018 via email

@cgibson33
Copy link

Ok - last minute I recorded a bunch of settings interactions including a factory reset
Documents.zip

@cgibson33
Copy link

When I did the settings changes, you could see packages transferring as soon as I typed any number or changed any setting on the fly, so I didn't bother removing the watch at any point

@cgibson33
Copy link

And Nike has checked out of the building - I assume that will get people's attention.
capture

@cgibson33
Copy link

Ok - so now what? Do I need to do some further analysis on the captures? Is this watch too different than the other watches serviced by this code?

@iglezouton
Copy link

Hi guys, other solution would be to run a local proxy interpecting calls to Nike+ from the local app running and then store the data locally. But this is in case this project can't support the watch because as @prynhart suggested would be very different to the 'other'
TomTom watches

@prynhart
Copy link
Author

prynhart commented May 6, 2018

Hi guys - unfortunately nothing to add, I don't know how different this watch is. Hopefully someone else watching this thread can advise. Thanks, Patrick

@tomasdev
Copy link

tomasdev commented May 8, 2018

@iglezouton your suggested proxy solution doesn't work, because there are pre-flight validations on services that don't work anymore, even before the upload service is called.

@tomasdev
Copy link

tomasdev commented May 8, 2018

@cgibson33 could you post your guide to watch the packets? I've tried USB Probe (mac only) and Wireshark with no luck.

@cgibson33
Copy link

The main problems I had with wireshark were just getting installed with USBPCap included - that can be accomplished just by selecting that option during install - assuming you have the version of wirecap with USBPCap and WinPCAP (gui) included.
Once installed, its easy: Just start capturing and then add display filters at the top using the expression button or autocomplete - at a minimum you will have to filter for Bus and device ID (use AND expression). The PC seems to randomly assign ID numbers but I usually found the watch traffic on Bus 1 and ID 6, 7, or 8. Wireshark will still be recording ALL USB traffic. Once done, stop recording and save the file - you can re-filter it later at any time and then just save the filtered packets if you want.
tempsnip

@cgibson33
Copy link

Note that it is now impossible to record any actual communications for GPS updates or Run uploads since Nike has shut down the server - the only thing you can record is settings changes.

@slavutichd
Copy link

С мая 2018 года компания Nike прекратила поддержку Nike sportwatch gps описанный в вашей статье. Не удалось ли создать install программу ... с конвертацией в gpx?

@MauroMarini
Copy link

Hi everybody,
is it possible, after uninstalling the Nike app, to use an "USB tool" to try to engage the watch and let it transfer the data? What tool should be used to try?

@ViktorNest
Copy link

@rvernica
Copy link

The code posted here seems to be able to download binary data from the watch and parse it into XML.

There is also this project, but I'm not sure what are its capabilities.

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