Tuesday, August 6, 2013

Facedancer

At this point my motivation was a bit lower, since I had a mostly working solution.
But there was an option I had run across in my searches, the Facedancer.

This performs a function very similar to the 2 Teensy setup used with Salamax, but all in one package and with more flexibility in some ways (can support host mode) and less in others (limited number of USB endpoints). Basically it presents itself to your computer as a USB serial port, and then you can read and write data that will go out the other end and seem like a hardware device to whatever it is connected to.

I didn't feel like doing surface mount soldering, so I passed on it initially, but eventually they found a partner to make and distribute fully assembled boards.  So I went ahead and ordered one.

The original PC based code for it is in Python, not my 1st language, so I decided to port it to .Net (and the port is available on the repository under the /contrib/facedancer section).

What I was essentially trying to do, once I got the basics working, was set up a passthrough device, that would pass all the traffic the facedancer received to a physical device also connected to the computer. Using the LibUSBDotNet library I was able to pass on whatever packets the facedancer got to the real device, and read back their responses.

I found two great references that I used during this process to learn about the USB protocol:
USB in a NutShell
USB Made Simple

Eventually I was able to get to a point where I could emulate a keyboard, and finally the 360 controller. I could then also inject additional HID report packets to simulate button presses.

However there were two limitations to this approach:
The facedancer is not suited (although it may be possible to improve this) to low latency or high speed communication. There is an interval of about 100ms between each packet it sends out, which means you are looking at latency of up to 100ms, which is not so great for a controller.
The USB chip it is based on  (the Max3421E) has a limited number of endpoints, besides the control endpoint (0) it has 1 endpoint which can only receive data from the host (1) and 2 which can only send data from the host (2,3). The full usb spec allows up to 16 total endpoints (including 0), which can both send and receive. So if the device you are passing traffic through for has more endpoints than this, you won't be able to capture them all. In the case of the controllers this isn't too much of an issue, as there is only 1 endpoint in each direction that matters for button presses, although there are others that are used for audio, etc. if there is a headset connected. It did require that I map the facedancer endpoints to the correct device endpoints in my translation code.

One additional note, although I didn't get to this point, the facedancer is quite long (about 2 7/8").
If you want to fit it in a 5" long project box, a standard mini usb cable will probably need about 2" of clearance or more if you don't want to bend it too sharply and potentially damage it, that would need about a 7" box. If you are able to pass it straight out through a hole in the box, you will still probably need about 1 1/4", which puts it at about 5 1/2". If you want a plug on your project box rather than running the cables out, I was able to find a mini USB to a standard size type A with a right angle connector here but then you end up needing Male/Male USB cables, which are not something you are likely to have lying around. Unfortunately I wasn't able to find a panel mount jack that combined a female type B connector (which is more "correct") and a right angled mini USB jack.
You can get right angle mini usb cables, that need about 5/8" clearance on each end for a total of 4 1/8".

Monday, March 25, 2013

PS2 Controller Emulation

I finally ran into some success at this point :).
On the teensy project page, I found the blog of someone who was using a PS2 controller along with a capture card to teach his computer to Autonomously play Guitar Hero using a Teensy2. He emulated the SPI protocol (used by the PS2 controller).

I ordered:
PS2 extension cables $4.34
PS2 -> 360 controller adapters $8.50
project enclosures (3"x2"x1") $3.50
teensy2 (i already had this but I'm including it here anyway) $19

Total: ~$35 before shipping

You will also need a mini USB cable. I used a regular one and just made a hole in the side of the project box for it.

I was able to successfuly control my xbxo with one minor change.
The program that makes the Teensy2 emulate a PS2 controller allows three different modes. Digital only (3 byte record), Digital buttons & analog joysticks (7 byte record), and all analog (19 byte record).

Apparently the adapter I used falsely indicates it accepts analog button presses, but then indicates the 12 bytes of analog button data as additional 7 byte reports. So i had to change the Teensy2 program to only send the 7 byte report, even if it was reported as supporting the analog buttons.

With that change it was working great.
There were three limitation of the PS2->360 adapter however:
It is a little bit finicky in terms of resetting. It will not properly sync up with the 360 if the PS2 controller/teensy is already connected to it. So that needs to be removed before it is connected to the 360, and then reconnected after the 360 controller has been recognized.
It can only be used with a vanilla wired 360 controller. It will not work guitars, steering wheels, etc at least as far as I tested. I am not sure how it would behave with an off brand controller (Gamestop, etc) as I didn't have any at that time.
You can only use 1 at a time. Something seems to be hard-coded in there. If you attach a 2nd adapter, it will take over the controller # of the 1st one, and the 1st one will no longer function.


Wednesday, March 20, 2013

Salamax & Teensy

At this point I ran across Salamax, a guy who had used a protocol analyzer to look at the Xbox security handshake, and then used a TI-83 calculator connected to the Xbox as a middleman to relay that handshake to a Xbox controller connected to his PC and send the correct responses back, and then to relay the HID report packets back once authentication was complete. He also had an alternate solution using a pair of Teensy2s.

Once again I was bitten by my naivete. I order a pair of Teensy3s, since they are significantly more powerful. 32bit 48Mhz processor vs a 8bit 16Mhz, 128k of flash vs ~32k. 16k of ram vs 2.5k, and 3 UARTs (capable of much faster speed) vs 1.
Unfortunately the hardware architecture is very different, and while it wouldn't be a big problem just for the code used by Salamax directly, it also included LUFA a USB framework for the AVR processor family (used by the Teensy2). I didn't really want to spend the time to rewrite that for the Teensy3, so I set my Teensy3s aside (but will come back to them later), and ordered a pair of Teensy2s.

I tried getting them working with Salamax, but they were apparently the red headed step child (compared to the TI-83). The code in the Salamax App on the PC wasn't all there for the Teensy option, and the USB descriptors the code running on the Teensy presented didn't match up with the app seemed to be expecting, so I put it aside for a few days.

Monday, March 18, 2013

HID emulation and Netduino


My next stop was naively believing it would be as simple as emulating a HID joystick and hooking it up to the Xbox.

To accomplish that I got a NetDuino plus 2. Since my day job involves .Net programming I figured this would be the simplest route to follow, since it allows you to program it using the .Net micro framework, and includes the USB port as well as up to 4 UARTs  and an ethernet controller.

Unfortunately the Xbox employs a security handshake that prevents you from using just any controller on it (which I would have realized if I had tried to hook up a random joystick to it).

It will however let you hook up a USB keyboard which you can use to enter text during text entry which is a lot more convenient than using the on screen keyboard with the controller.

Friday, March 1, 2013

Our story so far

This blog is to cover my attempts to control my Xbox360 using my computer.

First, I'll be catching up on what I've attempted so far, so the post dates will have no bearing on when things actually happened.

I started out with a desire to see if I could control my xbox using my computer.

There were a couple of out-of-box products that I ran across the XIM3 (Discontinued) and XIM EDGE. Unfortunately, both seem to suffer from some limitations, one is price (although by now with all the gadgets I've gotten, that is ironic in retrospect). The other is that they are meant to be controlled via mouse and keyboard, so while that could certainly work, I'd have another level of emulation, since I would need to then emulate the USB mouse & keyboard to attach to the XIM.