1

I'm trying to pair a rooted Android device with a PlayStation 4 (or 5) so that I can play around with the Bluetooth HID Profile. The problem is that the PlayStation firmware doesn't like to pair with unauthorised devices. I've seen that someone was able to work around this on a Raspberry Pi Zero by using ConfigFS and FunctionFS to simulate a PlayStation controller and initiate the pairing process over USB. So, I've set about trying to port their code to work on my Android device, but differences in the 2 devices are holding me back. My Android device's kernel version is 3.10, whereas the Pi Zero uses a newer 4.x or 5.x kernel.

I spotted some differences immediately, for example the Android device already has ConfigFS mounted at /config, and other FunctionFS files mounted at /dev/usb-ffs. After changing the code to skip mounting and point to the correct locations, I'm hitting some other issues. The first problem lies in this chunk of code:

  if (echo_to(CONFIGFS_MP "/" GADGET_PATH "/bDeviceClass", "0x00") < 0)
    goto fail_2;
  if (echo_to(CONFIGFS_MP "/" GADGET_PATH "/bDeviceSubClass", "0x00") < 0)
    goto fail_2;
  if (echo_to(CONFIGFS_MP "/" GADGET_PATH "/bDeviceProtocol", "0x00") < 0)
    goto fail_2;
  if (echo_to(CONFIGFS_MP "/" GADGET_PATH "/bMaxPacketSize0", "0x40") < 0)
    goto fail_2;
  if (echo_to(CONFIGFS_MP "/" GADGET_PATH "/idVendor", "0x054c") < 0)
    goto fail_2;
  if (echo_to(CONFIGFS_MP "/" GADGET_PATH "/idProduct", "0x09cc") < 0)
    goto fail_2;
  if (echo_to(CONFIGFS_MP "/" GADGET_PATH "/bcdDevice", "0x100") < 0)
    goto fail_2;

  if (mkdir(CONFIGFS_MP "/" GADGET_PATH "/configs/c.1", 0700) < 0)
    goto fail_2;


  if (echo_to(CONFIGFS_MP "/" GADGET_PATH "/configs/c.1/bmAttributes", "0xc0") < 0)
    goto fail_3;
  if (echo_to(CONFIGFS_MP "/" GADGET_PATH "/configs/c.1/MaxPower", "500") < 0)
    goto fail_3;

  if (mkdir(CONFIGFS_MP "/" GADGET_PATH "/functions/ffs.dualshock", 0700) < 0)
    goto fail_3;

  if (mkdir(CONFIGFS_MP "/" GADGET_PATH "/strings/0x409", 0700) < 0)
    goto fail_4;

  if (echo_to(CONFIGFS_MP "/" GADGET_PATH "/strings/0x409/manufacturer", "Sony Interactive Entertainment") < 0)
    goto fail_5;
  if (echo_to(CONFIGFS_MP "/" GADGET_PATH "/strings/0x409/product", "Wireless Controller") < 0)
    goto fail_5;

  if (symlink(CONFIGFS_MP "/" GADGET_PATH "/functions/ffs.dualshock", CONFIGFS_MP "/" GADGET_PATH "/configs/c.1/ffs.dualshock") < 0)

Particularly this part:

  if (mkdir(CONFIGFS_MP "/" GADGET_PATH "/functions/ffs.dualshock", 0700) < 0)
    goto fail_3;

This errors with the error message Function not implemented, and I am unable to figure out why. I'm not familiar with ConfigFS or FunctionFS and searching Google for this error message along with whatever keywords I can think of is proving unfruitful. If I comment out this part (and the part that symlinks it later) then the rest of this chunk of the code works, but then I hit errors in the do_functions() function further down:

int do_functions(const char* udc, options_t *opt)
{
  int ret = -1;

  fprintf(stdout, "Writing functions for %s...\n", udc);
  int fd = open(FUNCTIONFS_MP "/ep0", O_RDWR);
  if (fd < 0) {
    perror("open");
    goto failed0;
  }

  if (write(fd, &descriptor, sizeof(descriptor)) < 0) {
    perror("write descriptor");  // <-- Logs out "write descriptor: Invalid Argument"
    goto failed1;
  }

  if (write(fd, &strings, sizeof(strings)) < 0) {
    perror("write strings");
    goto failed1;
  }

I'm unsure if my commenting out the other code is causing this to fail or if it would fail anyway if I got the other code working. Can someone please help me understand this code, ConfigFS and FunctionFS better?

Andy E
  • 338,112
  • 86
  • 474
  • 445

1 Answers1

1

There is a related resource at Gentoo's wiki providing instructions on how to configure DualShock controllers. The article suggests using kernel versions above 3.15, so this might be a potential source behind your issue.

After searching the android kernel's git, there exists a driver targeting Sony devices that may prove handy as it provides support for Bluetooth connection, while also being more specific about the hid field modifications of DS4 that were mentioned by Gentoo's wiki page. The commit seems to be from around 2015, at the time the kernel's version that shipped with most devices was something like 3.18.x, so it still might not work with your kernel's version.

If the problem indeed seems to be a lack of support for your kernel's version then you should consider upgrading to a supported version, as @0andriy suggested you should either port the latest kernel to your device. But if this seems to be an unnecessary overhead to your project then you could search if your device is supported by other custom android distributions, for example, Lineage OS provides a list of currently supported devices here. Judging by your kernel version your device might have shipped with Android KitKat.

kalgoritmi
  • 738
  • 2
  • 7
  • 1
    It looks like I have some reading to do when I get a minute. Thanks for your detailed answer, bounty awarded! – Andy E Apr 23 '21 at 10:44