Open prynhart opened 8 years ago
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!
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? :-/
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....
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 Descriptor
s 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.
@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)
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.
Sadly, I tried that and it still couldn't detect it.
Hi Ryan (cc Alex)
Sorry for not replying - I did try a few things at the time, but got stuck. If I set up SSH access to the dev box I was using with the watch plugged in, do you think you might be able to have a look ? I'm not running much at the moment :-)
Thanks,
Patrick
On 15/05/17 7:34 PM, Alex Williams wrote:
Sadly, I tried that and it still couldn't detect it.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ryanbinns/ttwatch/issues/72#issuecomment-301398776, or mute the thread https://github.com/notifications/unsubscribe-auth/APCDi-Qztzg0Q1D9S1mA9WyM6tlBZ-s9ks5r6AAjgaJpZM4H-stG.
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.
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:
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
Oops - I did not mean to close this ticket :)
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.
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
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.
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.
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.
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?
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.
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.
Nice work. Not sure what the next step would be though - need someone who can look at the comms in the packet capture and compare this with what’s happening in the source. Would be good to get something underway before the shutdown, but at least these captures are around while the Nike client is still working.
Other things that could be captured while the client still works (probably with the runs empty) would be the settings - e.g. comms when the colours are inverted, weight of runner, enable/disable beep. I.e. All the control / admin features if the watch. Maybe do a trace for one at a time (so as little is changing as possible).
Get Outlook for iOShttps://aka.ms/o0ukef
From: cgibson33 notifications@github.com Sent: Saturday, April 21, 2018 12:56:40 PM To: ryanbinns/ttwatch Cc: Rynhart, Patrick; State change Subject: Re: [ryanbinns/ttwatch] Support for Nike+ GPS Watch ? (#72)
one run filtered for bus1 and device ID6.ziphttps://github.com/ryanbinns/ttwatch/files/1934020/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.
— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHubhttps://github.com/ryanbinns/ttwatch/issues/72#issuecomment-383255579, or mute the threadhttps://github.com/notifications/unsubscribe-auth/APCDi_94PH8f6qzWL5uO2FMprVvryecBks5tqoPIgaJpZM4H-stG.
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.
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.
Hi Ryan,
Recording the reset function sounds like an excellent idea :-) With regard to recording each action, not sure. I guess it depends whether the Connect client sends / updates the watch immediately when a change is made. (It probably does.). If you can see traffic (in wireshark afterwards) when you change/adjust a feature then this would be a good indicator as to whether you've got the exchange recorded.
The surefire / OCD way to do it would be to disconnect the watch each time, and record each transaction individually. (i.e. Record, Connect Watch, Start client, Change one feature, Exit client, disconnect watch.). This would obviously be more noisy though.
In short - not sure which is the best approach :-)
Thanks,
Patrick
On 22/04/18 3:04 AM, cgibson33 wrote:
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.
— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/ryanbinns/ttwatch/issues/72#issuecomment-383303636, or mute the thread https://github.com/notifications/unsubscribe-auth/APCDi6NYpuupqCos4DSoUyr-IAx60NxXks5tq0qYgaJpZM4H-stG.
Very interesting. I wonder if this 'offline' processing is being done because the watch itself doesn't support an API that can pull individual events off it ? If so, the watch would be very different to the 'other' TomTom watches that this Github project supports.
On 22/04/18 9:57 PM, Igor Gritsenko wrote:
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.
— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/ryanbinns/ttwatch/issues/72#issuecomment-383369183, or mute the thread https://github.com/notifications/unsubscribe-auth/APCDi2WSNdb5cNx5VRDsXUqp1QVhPGWeks5trFP0gaJpZM4H-stG.
Ok - last minute I recorded a bunch of settings interactions including a factory reset Documents.zip
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
And Nike has checked out of the building - I assume that will get people's attention.
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?
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
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
@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.
@cgibson33 could you post your guide to watch the packets? I've tried USB Probe (mac only) and Wireshark with no luck.
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.
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.
С мая 2018 года компания Nike прекратила поддержку Nike sportwatch gps описанный в вашей статье. Не удалось ли создать install программу ... с конвертацией в gpx?
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?
Maybe someone can figure it out?
https://www.os3.nl/_media/2013-2014/courses/ccf/smartwatches-hristo-leendert.pdf
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)
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