FortiusANT icon indicating copy to clipboard operation
FortiusANT copied to clipboard

Virtual USB-driver to run without hardware ANT+ dongle

Open michelrdagenais opened this issue 3 years ago • 34 comments

Have you considered using the Linux dummy_hcd module? This is the equivalent of a loopback device. You could feed data from FortiusANT into a "software" ANT+ usb device. Zwift/Rouvy would be happy seeing an ANT+ device, and there would be no need for 2 ANT+ dongles.

michelrdagenais avatar Dec 18 '20 23:12 michelrdagenais

Hi @michelrdagenais Welcome to the FortiusANT community


I'm always curious to know where FortiusANT is used (Canada) and what configuration is used. Please tell me what bundle did you buy, and what brake and what head unit do you use?


The suggestion you do is very interesting! I do not have linux (windows only) but I would be interested to hear your suggestions.

WouterJD avatar Dec 21 '20 09:12 WouterJD

I bought the "Tacx Fortius" with steering around 2008. The head unit is solid blue, motor control T1946.50, brake motor T1941. I traced the USB communication between the Tacx software and the unit to understand the protocol. I documented my findings and wrote a Linux driver with the help of Petr Blaha. My name appears in the credits of https://github.com/totalreverse/ttyT1941. However, TotalReverse went much further analyzing the Fortius. I am now looking at their documentation to improve the GoldenCheetah Fortius driver and add calibration.

I would also like to use FortiusAnt to run the Fortius with Zwift, without having to use two ANT+ dongles. Yes, it is possible to run Zwift on Linux, I run Zwift on Linux with my newer Wahoo Kickr Core using wine (https://zwiftinsider.com/zwift-on-linux/). To avoid using two ANT+ dongle, you need to emulate the ANT+ dongle seen by Zwift. This is possible on Linux with the dummy_hcd module. I do not use Windows but a quick search seems to indicate that it is also possible to emulate USB devices there with UDE (USB Device Emulation https://docs.microsoft.com/en-gb/windows-hardware/drivers/usbcon/developing-windows-drivers-for-emulated-usb-host-controllers-and-devices) which replaces DSF (Device Simulation Framework https://docs.microsoft.com/en-us/previous-versions/windows/hardware/dsf/ff538337(v=vs.85)?redirectedfrom=MSDN).

Thanks for the good work on FortiusAnt!

michelrdagenais avatar Dec 21 '20 13:12 michelrdagenais

Thanks for the good work on FortiusAnt!

@michelrdagenais thank you for your prior work on the Fortius!

I am currently about half way through a first pass to implement Fortius calibration in GC. Hoping to complete this today.

Related stuff: https://github.com/WouterJD/FortiusANT/issues/171 https://github.com/GoldenCheetah/GoldenCheetah/pull/3725 https://groups.google.com/g/golden-cheetah-users/c/8EDSFJiRLGU https://github.com/mattipee/GoldenCheetah/tree/tacx_fortius

mattipee avatar Dec 21 '20 15:12 mattipee

@michelrdagenais There is no reason this could not be done. I have explored several approaches before. The ANT dongle is quite sophisticated and there would be a lot of commands you need to support if you want to do this properly (https://www.thisisant.com/assets/resources/ANT%20Protocol/D00000652_ANT_Message_Protocol_and_Usage_Rev_5.1.pdf). If you only use Zwift you may get away with a subset (but it might break after the next Zwift update). You would probably still need one physical ANT dongle for other sensors (like HRM and power meter) as well AND you would need to merge that input into your virtual dongle.

This is probably the closest anyone got (an experimental firmware for T1942 head unit simulating an ANT USB dongle): https://github.com/totalreverse/ezTraCon

On Linux you should be able to create a "gadget" and attach that to your dummy_hcd in user-space (with functionfs/configfs?). On Windows I think you will be writing a kernel-mode driver, with all the complexity and signing/qualification implications that come with it. I have no idea what you would do on MacOS.

Other approaches might be:

  • Implement a USB/IP server with a simulated ANT dongle (clients are available for different platform, but I think the protocol is not well-documented)
  • Replace/hook ANT_DLL.dll or libusb (used by Zwift and other software) instead

In any case, there is a good chance a proper cross-platform implementation will end up being more complicated than FortiusANT itself. So I basically abandoned the idea. But I would be curious to see what you come up with and if I can help, I will.

switchabl avatar Dec 21 '20 16:12 switchabl

will end up being more complicated than FortiusANT itself.

Good reason not to go this path. Especially since one dongle remains required (e.g. HRM) and (I assume) Zwift will use one dongle, not two.

WouterJD avatar Dec 21 '20 20:12 WouterJD

I suggest to close; anybody creative ideas not to close and go for this instead?

WouterJD avatar Dec 22 '20 19:12 WouterJD

When I find time, I will prototype something. It may take the form of a software ANT bridge between FortiusANT and the Training software, creating two dummy ANT devices and forwarding/adapting the serial port messages between the two. If you want to close the issue, this is fine.

michelrdagenais avatar Dec 22 '20 19:12 michelrdagenais

@WouterJD Don't get me wrong, it would be great to have this. Having to buy a (second) ANT dongle is maybe the biggest obstacles for new users. I just couldn't come up with a realiable way to do it that is not a lot of work.

If @michelrdagenais or someone else wants to attempt this (dummy_hcd/functionfs is probably one of the most straightforward ways, unfortunately it is also Linux-only) the good news is this: you don't even have to touch the FortiusANT code. You can just emulate two ANT dongles, one for FortiusANT and one for Zwift and virtually route between them.

For many real-world use-cases you would have to implement support for a physical ANT dongle as well, though. Take my personal setup: you would have to route

  • the FE-C messages between FortiusANT and Zwift
  • the Tacx Genius messages between the physical ANT dongle to FortiusANT
  • the HRM and power meter meter messages from the physical ANT dongle to Zwift

EDIT: @michelrdagenais Yes, that is the approach I had in mind as well. I am curious to see what you come up with. Let me know if you have any ANT related question I can help with.

switchabl avatar Dec 22 '20 19:12 switchabl

Great!

A thought from my side: In stead of two dongles; FortiusANT should behave as a dongle itself (register itself as a USBdevice) so that Zwift can pair directly.

WouterJD avatar Dec 22 '20 20:12 WouterJD

@WouterJD Yes, would be nice, but it does mean a lot of changes and a lot of complexity in FortiusANT. At least for a prototype, to see it works and what approach is best, emulating two dongles and not changing FortiusANT at all seems like the more sensible way. If it turns out to work well, you can start thinking about built-in USB emulation. That step should be easy by comparison.

switchabl avatar Dec 22 '20 20:12 switchabl

I understand it's considered a challenge.

I suggest we first define the outline: Option 1. No dongle at all

  • Zwift connects to FortiusANT through software
  • FortiusANT publishes FE-C only
  • Zwift will not be able to receive HRM
  • USBtrainer only (no Vortex Genius Bushido)
  • No HRM, SCS, PWR profile

Option 2. One dongle

  • I suggest to make a clear picture what devices are supported and how the data from these devices is interchanged.

Succes!

WouterJD avatar Dec 22 '20 21:12 WouterJD

My visual thoughts on the subject. Used assumption: Zwift will connect with one dongle and expect all it's devices on that dongle.

image image image

WouterJD avatar Dec 24 '20 09:12 WouterJD

The Tacx Fortius came with an option for heartbeat. I suppose that many people use a different, non Tacx, device that requires ANT+.

  • The fisrt step can be to see how to bridge messages between the dummy_hcd serial port sending unit (from FortiusANT) and the dummy_hcd serial port receiving unit (to Zwift).
  • Then accepting HRM messages from a real ANT+ device and merging them to be sent on the dummy_hcd serial port receiving unit may be relatively easy.
  • Finally, we could do without intercepting the messages at the simulated USB device and directly emulate the needed functions in libusb, since this is what FortiusANT, Zwift and GoldenCheetah use.

michelrdagenais avatar Dec 25 '20 02:12 michelrdagenais

Succes! And all this to save one ANTdongle?

WouterJD avatar Dec 25 '20 08:12 WouterJD

See #204 CYCPLUS issues and ANT dongles hard to come by Who creates virtual-ANTdongles?

WouterJD avatar Jan 14 '21 21:01 WouterJD

In line with this discussion, new proposed ethernet protocol wahoo introduced with "KICKR 2020 Direct Connect Cable", mith be a solution in future. Seems ZWIFT have alreday add compatibility on that, and wahoo is willing to open/share usage to other use that protocol

E-NINA avatar Feb 02 '21 22:02 E-NINA

That looks very interesting indeed. Implementing this is a lot more realistic than virtual USB. It may take a while before this is actually supported everywhere:

FulGaz: In beta builds, but not fully working yet in my testing
RGT: Fully functional in public production version
The Sufferfest: Supposed to be working in production, but not for me or others
TrainerRoad: In certain beta builds, but not fully working yet in my testing. Targeting early February for release.
Zwift: According to Zwift’s product & PR team, actual official target is “later this year”

(https://www.dcrainmaker.com/2021/01/wahoo-starts-shipping-kickr-2020-direct-connect-cable-hands-on-details.html)

Anyone want to email them at [email protected] and see if they are open to sharing the specification?

switchabl avatar Feb 03 '21 16:02 switchabl

OK. SO I understand after proprietary Tacx-USB-interface and Tacx-ANT-interface which we opened to standard ANT+ and BLE, now we get a next proprietary Wahoo-USB-interface?

WouterJD avatar Feb 08 '21 13:02 WouterJD

Kinda. They have apparently indicated that they are willing to share the specs but it is not clear how far they will go with that (maybe they will eventually offer it on their website along with their SDK?). And it looks like all major CTP have plans to support it.

But from a technical perspective it is very intriguing: it works over the network, not USB. So if we get the protocol details (or can reverse engineer them), we can implement a simple TCP server to make our trainers available to all devices on the our home network (including tablets and phones) with no dongles and no virtual USB.

I don't see this replacing ANT+/BLE either. This is a niche thing for e-sports or gyms (where wireless doesn't work so well because you have a lot of devices) and for people who have some bad interference issues.

switchabl avatar Feb 08 '21 14:02 switchabl

Apart from niche: FortiusAnt enables OLD Tacx trainers to communicate. I gues these trainers are not in this scope :-)

WouterJD avatar Feb 17 '21 14:02 WouterJD

@WouterJD Oh I see, no that is not the point. We do not want to talk to a Kickr. We want to simulate a Kickr with Direct Connect (instead of an ANT+ FE-C trainer). Because then people wouldn't need the ANT dongles anymore. And Direct Connect uses the network instead of USB so this would be much much easier than a virtual USB dongle.

switchabl avatar Feb 17 '21 14:02 switchabl

SO I understand after proprietary Tacx-USB-interface and Tacx-ANT-interface which we opened to standard ANT+ and BLE, now we get a next proprietary Wahoo-USB-interface?

I understand the pain, but when I read https://bikerumor.com/2021/01/26/dont-get-dropped-signals-w-wahoo-kickr-direct-connect-wired-ethernet-adapter/ the first thing that came to my mind was that FortiusANT should support it. As the article also points out, Wahoo Direct Connect is already support by many training system or will be supported soon.

In general, I think that other manufacturers will follow with Direct Connect. That is the next logical step. I also believe that the next generation will have directly integrated Wi-Fi. The manufacturers will agree on the lowest common denominator for the network protocol. Wahoo was the first, only Tacx/Garmin could possibly dictate something other with its power.

IMHO the advantages are obvious: no ant dongles, less cable clutter and better connection. Resulting in more users as the barrier to entry becomes lower. For me, the RassberryPi is generally connected to the WLAN. The Zwift PC anyway, so why not transfer the trainer data over it. Zwift offers in the companion app to receive via the ANT / BLE data and send directly to Zwift, without the in between Zwift PC. This would also be a possibility, however, that would then exclusively only work for Zwift. Not so good indeed.

The implementation should be simple: A Wahoo KICKR + Wahoo Direct Connect and a computer with Wireshark or tcpdump in between. I suspect the network protocol should be easy to analyze. The adaptation with Python I also imagine not difficult.

Now comes the hard part, where do we get a network dump from the Direct Connect Adapter? I am thinking of the following options:

  • Write to Wahoo that we want to integrate it exclusively into our trainer program. It costs nothing to ask.
  • Someone knows someone who has such a part. Or write to a Youtuber / Influencer? This person should then be able to set up a network with Wireshark.
  • Buy an KICKR and Direct Connect Adapter ... At least for me, this is not possible or too expensive. Maybe just buy the adapter and see what this already chats about the network without the KICKR. In Germany we have 14 day return policy. Then it is only to be careful when unpacking.

Do you have any ideas about this?

martin-vi avatar Mar 03 '21 09:03 martin-vi

@martin-vi Yeah, asking Wahoo for some more info is probably step 1. Worst case is they say no.

There were some hints that it is some kind of BLE tunneled over TCP but I don't know if that is technically accurate or just an explanation the marketing department came up with. Working from a static Wireshark dump without the ability to actually inject your own data may be hard. And I don't know if the adapter by itself is going to do you much good. You would need to find a way to power it up without the KICKR and then chances are it won't do much at all.

The software situation doesn't seem to have improved either. RGT and Sufferfest seem to be the only apps that actually work right now. I am still very interested in this but I will probably wait for better software support before making a serious effort. That may make reverse-engineering a bit easier too.

switchabl avatar Mar 03 '21 12:03 switchabl

I will be very happy to add this on my QZ app. Does anyone have this device? We can easily reverse engineered it. Let me know

cagnulein avatar Oct 29 '21 17:10 cagnulein

@cagnulein Your QZ app looks quite impressive, it is always nice to see more proprietary/legacy training devices being opened up.

I don't have a Direct Connect (it doesn't work without at KICKR anyway) but I have made some progress on the protocol anyway. It would still be nice to have a Wireshark capture from an actual device though. In short, it really is a BLE/GATT-like interface over TCP. You can enumerate services and characteristics and then do read/write/notify on them. Discovery is done using mDNS.

AND, unfortunately Zwift doesn't support it yet either. They claim to be working on it but until that happens it is not actually that useful for us. Not sure about the other apps. Still, I think this is our best chance to run FortiusANT without any USB dongles in the future, so I will keep working on it.

switchabl avatar Oct 30 '21 20:10 switchabl

Hi @switchabl ! Thanks for your answer! Did you have already some code about it? Where did you take the information about the protocol? I tried to google it but i can't find almost anything. Thanks!

cagnulein avatar Oct 31 '21 04:10 cagnulein

@cagnulein I have only just started writing some code, so not yet (at least I have finally figured out how to do the mDNS advertisements). I have written up a preliminary specification that I am working from, but the usual disclaimer applies (WIP, untested, probably incomplete and inaccurate).

If you want to discuss details, feel free to drop me an email (switchabl at mailbox dot org).

switchabl avatar Nov 01 '21 19:11 switchabl

@switchabl have a look at this https://github.com/cagnulein/qdomyos-zwift/issues/476#issuecomment-979240427

cagnulein avatar Nov 25 '21 14:11 cagnulein

@cagnulein Thanks, I will, that sounds great. I also have a mostly-working, still-unpublished DIRCON server implementation written in Rust. Unfortunately I didn't have the time to finish it yet it because I was busy with other things (mostly steering related). Sorry that I haven't been more active.

switchabl avatar Nov 25 '21 22:11 switchabl

@switchabl thanks for all the effort! Don't apologize for not doing more. I'm curious what development will be released first...

WouterJD avatar Nov 25 '21 22:11 WouterJD