Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
isage committed Oct 7, 2022
0 parents commit f5a4521
Show file tree
Hide file tree
Showing 5 changed files with 290 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
build

34 changes: 34 additions & 0 deletions CMakeLists.txt
@@ -0,0 +1,34 @@
cmake_minimum_required(VERSION 3.12)

if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
if(DEFINED ENV{VITASDK})
set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file")
else()
message(FATAL_ERROR "Please define VITASDK to point to your SDK path!")
endif()
endif()

set(SHORT_NAME lsusb)
project(${SHORT_NAME})
include("${VITASDK}/share/vita.cmake" REQUIRED)

set(VITA_APP_NAME "lsusb")
set(VITA_TITLEID "LUSB00000")

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11")

add_executable(${SHORT_NAME}
main.c
)

target_link_libraries(${SHORT_NAME}
SceUsbd_stub
)

vita_create_self(${SHORT_NAME}.self ${SHORT_NAME} UNSAFE)

vita_create_vpk(${SHORT_NAME}.vpk ${VITA_TITLEID} ${SHORT_NAME}.self
VERSION ${VITA_VERSION}
NAME ${VITA_APP_NAME}
)

4 changes: 4 additions & 0 deletions README.md
@@ -0,0 +1,4 @@
# vita-lsusb

lsusb-alike app for PSVita.
Dumps currently connected usb devices info into stdout and `ux0:/data/lsusb.txt`
167 changes: 167 additions & 0 deletions main.c
@@ -0,0 +1,167 @@
#include <psp2/kernel/clib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "usbd.h"

#define dump(...) do { \
sceClibPrintf(__VA_ARGS__); \
fprintf(fp, __VA_ARGS__); \
} while (0);


int main(int argc, char *argv[]) {
SceUID uid;
SceUsbdDeviceInfo info[8];

sceUsbdInit(&uid);

sceUsbdGetDeviceList(uid, 8, (SceUsbdDeviceInfo *)&info);

FILE* fp = fopen("ux0:/data/lsusb.txt","wb");

static const char * const typeattr[] = {
"Control",
"Isochronous",
"Bulk",
"Interrupt"
};
static const char * const syncattr[] = {
"None",
"Asynchronous",
"Adaptive",
"Synchronous"
};
static const char * const usage[] = {
"Data",
"Feedback",
"Implicit feedback Data",
"(reserved)"
};

int i = 0;
while (i < 8 && info[i].device_num != 0xffffffff) {
unsigned int device_id = (info[i].port << 16) + info[i].device_num;
int size = sceUsbdGetDescriptorSize(uid, device_id);

uint8_t* descr = malloc(size);

sceUsbdGetDescriptor(uid, device_id, descr, size);
int speed;
sceUsbdGetDeviceSpeed(uid, device_id, &speed);

dump("Bus %x Device %x (%s):\n", info[i].port, info[i].device_num, (speed == 0) ? "Low-speed" : ((speed == 1) ? "High-speed" : "Full-speed") );

uint8_t *ptr = descr;
while (ptr - descr < size)
{
switch(ptr[1]) {
case USB_DESCRIPTOR_DEVICE:
{
USB_DEVICE_DESCRIPTOR *d = (USB_DEVICE_DESCRIPTOR*)ptr;
ptr += ptr[0];
dump("Device Descriptor:\n");
dump(" bLength: 0x%02x\n", d->bLength);
dump(" bDescriptorType: 0x%02x\n", d->bDescriptorType);
dump(" bcdUSB: %2x.%02x\n", d->bcdUSB >> 8, d->bcdUSB & 0xff);
dump(" bDeviceClass: 0x%02x\n", d->bDeviceClass);
dump(" bDeviceSubClass: 0x%02x\n", d->bDeviceSubClass);
dump(" bDeviceProtocol: 0x%02x\n", d->bDeviceProtocol);
dump(" bMaxPacketSize0: 0x%02x\n", d->bMaxPacketSize0);
dump(" idVendor: 0x%04x\n", d->idVendor);
dump(" idProduct: 0x%04x\n", d->idProduct);
dump(" bcdDevice: %2x.%02x\n", d->bcdDevice >> 8, d->bcdDevice & 0xff);
dump(" iManufacturer: 0x%02x\n", d->iManufacturer);
dump(" iProduct: 0x%02x\n", d->iProduct);
dump(" iSerialNumber: 0x%02x\n", d->iSerialNumber);
dump(" bNumConfigurations: 0x%02x\n", d->bNumConfigurations);

break;
}
case USB_DESCRIPTOR_CONFIGURATION:
{
USB_CONFIGURATION_DESCRIPTOR *d = (USB_CONFIGURATION_DESCRIPTOR*)ptr;
ptr += ptr[0];
dump(" Configuration Descriptor:\n");
dump(" bLength: 0x%02x\n", d->bLength);
dump(" bDescriptorType: 0x%02x\n", d->bDescriptorType);
dump(" wTotalLength: 0x%04x\n", d->wTotalLength);
dump(" bNumInterfaces: 0x%02x\n", d->bNumInterfaces);
dump(" bConfigurationValue: 0x%02x\n", d->bConfigurationValue);
dump(" iConfiguration: 0x%02x\n", d->iConfiguration);
dump(" bmAttributes: 0x%02x\n", d->bmAttributes);
if (!(d->bmAttributes & 0x80))
{
dump(" (Missing must-be-set bit!)\n");
}
if (d->bmAttributes & 0x40)
{
dump(" Self Powered\n");
}
else
{
dump(" (Bus Powered)\n");
}
if (d->bmAttributes & 0x20)
{
dump(" Remote Wakeup\n");
}
if (d->bmAttributes & 0x10)
{
dump(" Battery Powered\n");
}
dump(" bMaxPower: 0x%04x (%5umA)\n", d->bMaxPower, d->bMaxPower * 2);
break;
}
case USB_DESCRIPTOR_INTERFACE:
{
USB_INTERFACE_DESCRIPTOR *d = (USB_INTERFACE_DESCRIPTOR*)ptr;
ptr += ptr[0];
dump(" Interface Descriptor:\n");
dump(" bLength: 0x%02x\n", d->bLength);
dump(" bDescriptorType: 0x%02x\n", d->bDescriptorType);
dump(" bInterfaceNumber: 0x%04x\n", d->bInterfaceNumber);
dump(" bAlternateSetting: 0x%02x\n", d->bAlternateSetting);
dump(" bNumEndpoints: 0x%02x\n", d->bNumEndpoints);
dump(" bInterfaceClass: 0x%02x\n", d->bInterfaceClass);
dump(" bInterfaceSubClass: 0x%02x\n", d->bInterfaceSubClass);
dump(" bInterfaceProtocol: 0x%02x\n", d->bInterfaceProtocol);
dump(" iInterface: 0x%02x\n", d->iInterface);
break;
}
case USB_DESCRIPTOR_ENDPOINT:
{
USB_ENDPOINT_DESCRIPTOR *d = (USB_ENDPOINT_DESCRIPTOR*)ptr;
ptr += ptr[0];
dump(" Endpoint Descriptor:\n");
dump(" bLength: 0x%02x\n", d->bLength);
dump(" bDescriptorType: 0x%02x\n", d->bDescriptorType);
dump(" bEndpointAddress: 0x%02x EP %u %s\n", d->bEndpointAddress, d->bEndpointAddress & 0x0f, (d->bEndpointAddress & 0x80) ? "IN" : "OUT");

dump(" bmAttributes: 0x%02x\n", d->bmAttributes);
dump(" Transfer Type: %s\n", typeattr[d->bmAttributes & 3]);
dump(" Synch Type: %s\n", syncattr[(d->bmAttributes >> 2) & 3]);
dump(" Usage Type: %s\n", usage[(d->bmAttributes >> 4) & 3]);

dump(" wMaxPacketSize: 0x%02x\n", d->wMaxPacketSize);
dump(" bInterval: 0x%02x\n", d->bInterval);
break;
}
default:
dump("unhandled dtype: %x\n", ptr[1]);
ptr += ptr[0];
break;
};
}
dump("\n\n", ptr[1]);

free(descr);
i++;
}

fclose(fp);

sceUsbdEnd(uid);

return 0;
}
83 changes: 83 additions & 0 deletions usbd.h
@@ -0,0 +1,83 @@
#ifndef _USBD_H_
#define _USBD_H_

typedef struct SceUsbdDeviceInfo {
unsigned int port;
unsigned int device_num;
unsigned int unk3; // handled? 0, 1, 2
} SceUsbdDeviceInfo;

typedef struct {
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // DEVICE descriptor type (USB_DESCRIPTOR_DEVICE).
uint16_t bcdUSB; // USB Spec Release Number (BCD).
uint8_t bDeviceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t bDeviceSubClass; // Subclass code (assigned by the USB-IF).
uint8_t bDeviceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t bMaxPacketSize0; // Maximum packet size for endpoint 0.
uint16_t idVendor; // Vendor ID (assigned by the USB-IF).
uint16_t idProduct; // Product ID (assigned by the manufacturer).
uint16_t bcdDevice; // Device release number (BCD).
uint8_t iManufacturer; // Index of String Descriptor describing the manufacturer.
uint8_t iProduct; // Index of String Descriptor describing the product.
uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number.
uint8_t bNumConfigurations; // Number of possible configurations.
} __attribute__((packed)) USB_DEVICE_DESCRIPTOR;

/* Configuration descriptor structure */
typedef struct {
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION).
uint16_t wTotalLength; // Total length of all descriptors for this configuration.
uint8_t bNumInterfaces; // Number of interfaces in this configuration.
uint8_t bConfigurationValue; // Value of this configuration (1 based).
uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
uint8_t bmAttributes; // Configuration characteristics.
uint8_t bMaxPower; // Maximum power consumed by this configuration.
} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR;

/* Interface descriptor structure */
typedef struct {
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE).
uint8_t bInterfaceNumber; // Number of this interface (0 based).
uint8_t bAlternateSetting; // Value of this alternate interface setting.
uint8_t bNumEndpoints; // Number of endpoints in this interface.
uint8_t bInterfaceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t iInterface; // Index of String Descriptor describing the interface.
} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR;

/* Endpoint descriptor structure */
typedef struct {
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT).
uint8_t bEndpointAddress; // Endpoint address. Bit 7 indicates direction (0=OUT, 1=IN).
uint8_t bmAttributes; // Endpoint transfer type.
uint16_t wMaxPacketSize; // Maximum packet size.
uint8_t bInterval; // Polling interval in frames.
} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR;

#define USB_DESCRIPTOR_DEVICE 0x01 // bDescriptorType for a Device Descriptor.
#define USB_DESCRIPTOR_CONFIGURATION 0x02 // bDescriptorType for a Configuration Descriptor.
#define USB_DESCRIPTOR_STRING 0x03 // bDescriptorType for a String Descriptor.
#define USB_DESCRIPTOR_INTERFACE 0x04 // bDescriptorType for an Interface Descriptor.
#define USB_DESCRIPTOR_ENDPOINT 0x05 // bDescriptorType for an Endpoint Descriptor.

#define USB_DESCRIPTOR_DEVICE_QUALIFIER 0x06 // bDescriptorType for a Device Qualifier.
#define USB_DESCRIPTOR_OTHER_SPEED 0x07 // bDescriptorType for a Other Speed Configuration.
#define USB_DESCRIPTOR_INTERFACE_POWER 0x08 // bDescriptorType for Interface Power.
#define USB_DESCRIPTOR_OTG 0x09 // bDescriptorType for an OTG Descriptor.

int sceUsbdInit(SceUID *uid);
int sceUsbdEnd(SceUID uid);

int sceUsbdGetDeviceList(SceUID uid, unsigned int num, SceUsbdDeviceInfo *info); // 8 devices max
// returns all descriptors (device, config, interface, etc.)
int sceUsbdGetDescriptor(SceUID uid, unsigned int device_id, unsigned char *descriptor, unsigned int size);
int sceUsbdGetDescriptorSize(SceUID uid, unsigned int device_id);
// 0, 1, 2 = Low, Full, High
int sceUsbdGetDeviceSpeed(SceUID uid, unsigned int device_id, unsigned int *speed);

#endif /* _USBD_H_ */

0 comments on commit f5a4521

Please sign in to comment.