Monday, 24 October 2016

Reversing PlayStation VR device (I)

First i need to give thanks to:
 The title of this blog article explains very well  about which is the main purpose of this blog entry.

PlayStation VR (before known by Morpheus) is the new device from Sony for Virtual Reality marketplace. As you know there are a few actors right now in this marketplace:
  • Oculus.
  • HTC.
  • Sony.
  • Google.
  • Samsung.
  • Others vendors.

 PlayStation VR need different parts:
  • VR headset.
  • Processor Unit.
  • PlayStation 4
  • PlayStation 4 Camera
  • PlayStation Move and PlayStation dualshock
  • TV with hdmi
Connection schema from Sony:
I have spoken already about PlayStation Move and PlayStation Camera  here in this blog and about its new design in my twitter account:

So now we are going to speak about usb connection between Processor Unit and PlayStation 4 because we want to use PlayStation VR in other platform different than PlayStation 4.

Processor Unit is a black box, if you want to know more about it you will need two things:
  1. Information about hardware. Sony published morpheus_bridge source for 1.50 and 2.0 and it will give you good information about how usb device is build and detailed information about all their 9 interfaces.
  2. An usb dump made with a usb protocol hardware analyzer.
1 was already published and 2 was shared by tokkyo_tw so...


What happen when you connect usb connector from Processor Unit to a Mac/PC?

Easy you can see a new usb device with these usb descriptors

You can check in morpheus_bridge source code that all information is already there.

Usb dump was done with:
  • Software: USB Protocol Suite 7.35
  • Hardware: USBTrace 2500H
USB Protocol Suite can be downloaded from here you must register your user to dowload it.

We are going to work with files from dump:
  • connect-to-ps4 (psvr off).usb
  • connect-to-ps4 (psvr on in game (rez))-then-vrmode-on.usb
  • connect-to-ps4 (psvr on in game (rez)).usb
  • switch-to-vr-mode (in rez).usb
We will choose  connect-to-ps4 (psvr off).usb file first opening it with USB Protocol Suite.

With PlayStation Camera we got dump from beagle hardware analyzer from totalphase and their tool is multiplatform and easy to use for me.

USB Protocol Suite is for windows only and it is  a little hard to use but task can be done with it.

After opening file, choose in menu View Apply Decoding Scripts and check that you have following interfaces and their usb class applied:

and in the endpoint option the same: 

A problem that i find with this tool is that sometimes it can't put the right type of endponint , class and packet size , so check it with usb descriptors first.(Some weird sometimes identify some endpoint with bulk type when they are interrupt type check with usb descriptor that info is correct)

Choose in menu View Transfer Level and Hide all except Transfers options and  in menu Report Detail, View Data and Decode Field View options.

After that we can go transfer by transfer to make our analysis.

I am not going to tech you how usb protocol works for that you have plenty of information, if you don't know about it stop here.

First transfers are about get device and config ,interaface and endpoint descriptors, basically a dump for all descriptors

For your reference these standard request transfer give you all information about device:
  • Transfer 4 device descriptor
  • Transfer 11 configuration descriptor
  • Transfer 12 all descriptor
  • Transfer 13 status
All these transfer can give you all usb descriptor for this device and you can compare with information in morpheus_bridge  source and lsusb output. It is the same.  Check Decoded Field View Tab to see values from these standard requests transfers.

Transfer 14 set usb configuration to 1
Transfer 15 get size for string at index 3: 30 bytes (14 characters)
Transfer 16 get string at index 3 : PS VR 3D Audio  (name associated to interface 0)
Transfer 17 put alternate setting to 1 in inteface 0
Transfer 18 get size for string at index 4: 24 bytes
Transfer 19 get string at index 4: PS VR Audio (name associated to interface 1)
Transfer 20 21 22  23  25 and 26 are audio claass requests to get min max res from both channels associate to control volume features on interface 1
Transfer 24 is a isoc transfer empty no audio send yet to endpoint 1 OUT
Transfer 27 28 29 set volume to channel 1, channel 2 and again channel 1
Transfer 30 set alternate 1 to interface 3
Transfer 31 set alternate 1 to interface 2
Transfer 32 get size for string at index 7 : 26 bytes (12 caracteres)
Transfer 33 get string at index 7:  PS VR Sensor  (associated to interface 4)
Transfer 34 get report descriptor  from interface 4
/*0x06, 0x01, 0xff, // Usage Page (Vendor-defined 0xFF01)
    0x09, 0x01, // Usage (Vendor-defined 0x0001)
    0xa1, 0x01, // Collection (Application)
    0x09, 0x10, // Usage (Vendor-defined 0x0010)
    0x15, 0x00,       //    Logical minimum (0)
    0x26, 0xff, 0x00, //    Logical maximum (255)
    0x75, 0x08,       //    Report Size (8)
    0x95, 0x40,       //    Report Count (64)
    0x81, 0x02,       //    Input
    0xc0 // End Collection
Transfer 35 get size for string at index 8 : 28 bytes (13 caracteres)
Transfer 36 get string at index 8:  PS VR Control    (associated to interface 5)
Transfer 37 get report descriptor from interface 5
    0x06, 0x00, 0xff, // Usage Page (Vendor-defined 0xFF00)
    0x15, 0x00, // Logical Minimum(0)
    0x26, 0xff, 0x00, // Logical Maximun(255)
    0x09, 0x08, //Usage (Vendor-defined 0x0008)
    0xa1, 0x01, // Collection (Application)
    0x09, 0x80, // Usage (Vendor-defined 0x0080)
    0x85, 0x40, // Report ID (0X40)
    0x75, 0x08, // Report Size(0x8)
    0x95, 0x04, // Report Count(0x4)
    0xb1, 0x02, // Feature
Transfer 38 put alternating setting to 3 to interface 6
Transfer 39 get size for string at index 10 : 26 bytes (12 caracteres)
Transfer 40 get string at index 10: PS VR BulkIn  (associated to interface 7)
Transfer 41 get size for string at index 11: 30 bytes (14 caracteres)
Transfer 42 get string at index 11: PS VR Control2  (associated to interface 8)
Transger 43 get report descriptor from interface 8
    0x06, 0xf0, 0xff, // Usage Page (Vendor-defined 0xFFF0)
    0x15, 0x00, // Logical Minimum(0)
    0x26, 0xff, 0x00, // Logical Maximum(255)
    0x75, 0x08, // Report Size(0x8)
    0x95, 0x3f, // Report Count(0x3F)

    0x09, 0x01, // Usage(Vendor-defined 0x0001)
    0xa1, 0x01, // Collection(Application)
    0x85, 0xd0, // Report ID(0xD0)
    0x09, 0xd0, // Usage(Vendor-defined 0x00d0)
    0xb1, 0x02, // Feature

    0x85, 0xd1, // Report ID(0xD1)
    0x09, 0xd1, // Usage(Vendor-defined 0x00d1)
    0xb1, 0x02, // Feature

    0x85, 0xd2, // Report ID(0xD2)
    0x09, 0xd2, // Usage(Vendor-defined 0x00d2)
    0xb1, 0x02, // Feature

    0x85, 0xd3, // Report ID(0xD3)
    0x09, 0xd3, // Usage(Vendor-defined 0x00d3)
    0xb1, 0x02, // Feature
    0xc0, // End Collection 

    0x09, 0x02, // Usage(Vendor-defined 0x0002)
    0xa1, 0x01, // Collection(Application)
    0x85, 0xe0, // Report ID(0xE0)
    0x09, 0xe0, // Usage(Vendor-defined 0x00e0)
    0xb1, 0x02, // Feature

    0x85, 0xe1, // Report ID(0xE1)
    0x09, 0xe1, // Usage(Vendor-defined 0x00e1)
    0xb1, 0x02, // Feature

    0x85, 0xe2, // Report ID(0xE2)
    0x09, 0xe2, // Usage(Vendor-defined 0x00e2)
    0xb1, 0x02, // Feature

    0x85, 0xe3, // Report ID(0xE3)
    0x09, 0xe3, // Usage(Vendor-defined 0x00e3)
    0xb1, 0x02, // Feature

    0x85, 0xe4, // Report ID(0xE4)
    0x09, 0xe4, // Usage(Vendor-defined 0x00e4)
    0xb1, 0x02, // Feature

    0x85, 0xe5, // Report ID(0xE5)
    0x09, 0xe5, // Usage(Vendor-defined 0x00e5)
    0xb1, 0x02, // Feature

    0x85, 0xe6, // Report ID(0xE6)
    0x09, 0xe6, // Usage(Vendor-defined 0x00e6)
    0xb1, 0x02, // Feature

    0x85, 0xe7, // Report ID(0xE7)
    0x09, 0xe7, // Usage(Vendor-defined 0x00e7)
    0xb1, 0x02, // Feature

    0x85, 0xe8, // Report ID(0xE8)
    0x09, 0xe8, // Usage(Vendor-defined 0x00e8)
    0xb1, 0x02, // Feature

    0x85, 0xe9, // Report ID(0xE9)
    0x09, 0xe9, // Usage(Vendor-defined 0x00e9)
    0xb1, 0x02, // Feature

    0x85, 0xef, // Report ID(0xEF)
    0x09, 0xef, // Usage(Vendor-defined 0x00ef)
    0x95, 0x04, // Report Count(0x4)
    0xb1, 0x02, // Feature
    0xc0, // End Collection 

    0x09, 0x40, // Usage(Vendor-defined 0x0040)
    0xa1, 0x01, // Collection(Application)
    0x85, 0xf0, // Report ID(0xF0)
    0x09, 0x47, // Usage(Vendor-defined 0x0047)
    0x15, 0x00, // Logical Minimum(0)
    0x26, 0xff, 0x00, // Logical Maximum(255)
    0x75, 0x08, // Report Size(0x8)
    0x95, 0x3f, // Report Count(0x3F)
    0xb1, 0x02, // Feature

    0x85, 0xf1, // Report ID(0xF1)
    0x09, 0x48, // Usage(Vendor-defined 0x0048)
    0x95, 0x3f, // Report Count(0x3F)
    0xb1, 0x02, // Feature

    0x85, 0xf2, // Report ID(0xF2)
    0x09, 0x49, // Usage(Vendor-defined 0x0049)
    0x95, 0x0f, // Report Count(0x0F)
    0xb1, 0x02, // Feature

    0x85, 0xf3, // Report ID(0xF3)
    0x0a, 0x01, 0x47, // Usage(Vendor-defined 0x4701)
    0x95, 0x07, // Report Count(0x07)
    0xb1, 0x02, // Feature
    0xc0 // End Collection 
Ttrasfer 44 set idle to interface 8

Translation to c/c++ code with libusb api call is direct with all information from dump. All repoorts are described in morpheus_bridge source code so it's confirm all  is fine.


No comments: