0
0
Fork 0

feat: USBIP & Standard USB Descriptor Definitions

1. Add Standard USB Descriptor Definitions
2. USBIP stage1 completed
This commit is contained in:
windowsair 2020-01-23 21:55:51 +08:00
parent a15f873744
commit a6a5e6ec0c
11 changed files with 713 additions and 32 deletions

View File

@ -1,3 +1,4 @@
# TODO
1. adapt to special hardware
2. USB
2. USB
3. Significant Bit is difficult to judge, may need to dive into the details of usbip

View File

@ -0,0 +1,221 @@
/**
* @file USB_handle.c
* @brief Handle all Standard Device Requests
* @version 0.1
* @date 2020-01-23
*
* @copyright Copyright (c) 2020
*
*/
#include <stdint.h>
#include "USB_handle.h"
// handle functions
static void handleGetDescriptor(usbip_stage2_header *header);
static void handle_get_device_descriptor(usbip_stage2_header *header);
////TODO: fill this
int handleUSBControlRequest(usbip_stage2_header *header)
{
// Table 9-3. Standard Device Requests
switch (header->u.cmd_submit.request.bmRequestType)
{
case 0x00:
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_CLEAR_FEATURE:
/* code */
break;
case USB_REQ_SET_FEATURE:
/* code */
break;
case USB_REQ_SET_ADDRESS:
/* code */
break;
case USB_REQ_SET_DESCRIPTOR:
/* code */
break;
case USB_REQ_SET_CONFIGURATION:
/* code */
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
case 0x01:
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_CLEAR_FEATURE:
/* code */
break;
case USB_REQ_SET_FEATURE:
/* code */
break;
case USB_REQ_SET_INTERFACE:
/* code */
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
case 0x02:
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_CLEAR_FEATURE:
/* code */
break;
case USB_REQ_SET_FEATURE:
/* code */
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
case 0x80:
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_GET_CONFIGURATION:
handleGetDescriptor(header);
break;
case USB_REQ_GET_DESCRIPTOR:
/* code */
break;
case USB_REQ_GET_STATUS:
/* code */
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
case 0x81:
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_GET_INTERFACE:
/* code */
break;
case USB_REQ_SET_SYNCH_FRAME:
/* code */
break;
case USB_REQ_GET_STATUS:
/* code */
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
case 0x82:
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_GET_STATUS:
/* code */
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
/////////
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
}
////TODO: fill this
static void handleGetDescriptor(usbip_stage2_header *header)
{
// 9.4.3 Get Descriptor
switch (header->u.cmd_submit.request.wValue.u8hi)
{
case USB_DT_DEVICE:
handleGetDeviceDescriptor(header);
break;
case USB_DT_CONFIGURATION:
handleGetConfigurationDescriptor(header);
break;
case USB_DT_STRING:
handleGetStringDescriptor(header);
break;
case USB_DT_INTERFACE:
handleGetInterfaceDescriptor(header);
break;
case USB_DT_ENDPOINT:
handleGetEndpointDescriptor(header);
break;
case USB_DT_DEVICE_QUALIFIER:
handleGetDeviceQualifierDescriptor(header);
break;
case USB_DT_OTHER_SPEED_CONFIGURATION:
os_printf("GET 0x07 [UNIMPLEMENTED] USB_DT_OTHER_SPEED_CONFIGURATION");
break;
case USB_DT_INTERFACE_POWER:
os_printf("GET 0x08 [UNIMPLEMENTED] USB_DT_INTERFACE_POWER");
break;
case USB_DT_REPORT:
handle_get_hid_report_descriptor(header);
break;
default:
os_printf("USB unknown Get Descriptor requested:%d", header->u.cmd_submit.request.wValue.u8lo);
break;
}
}
static void handle_get_device_descriptor(usbip_stage2_header *header)
{
os_printf("* GET 0x01 DEVICE DESCRIPTOR\r\n");
usb_device_descriptor desc;
desc.bLength = USB_DT_DEVICE_SIZE;
desc.bDescriptorType = USB_DT_DEVICE;
desc.bcdUSB = 0x0110;
// defined at interface level
desc.bDeviceClass = 0x0;
desc.bDeviceSubClass = 0x0;
desc.bDeviceProtocol = 0x0;
desc.bMaxPacketSize0 = USB_HID_MAX_PACKET_SIZE;
desc.idVendor = USB_DEVICE_VENDOR_ID;
desc.idProduct = USB_DEVICE_PRODUCT_ID;
desc.bcdDevice = USB_DEVICE_VERSION;
desc.iManufacturer = STR_IMANUFACTURER;
desc.iProduct = STR_IPRODUCT;
desc.iSerialNumber = STR_ISERIAL;
desc.bNumConfigurations = 1;
send_stage2_submit_data(header, 0, &desc, sizeof(usb_device_descriptor));
}

View File

@ -0,0 +1,5 @@
#ifndef __USB_HANDLE_H__
#define __USB_HANDLE_H__
#include "usbip_defs.h"
int handleUSBControlRequest(usbip_stage2_header *header);
#endif

View File

@ -0,0 +1,220 @@
////TODO: refactoring into structure
/**
* @file USBd_config.c
* @brief Standard USB Descriptor Definitions
fix bugs 2020-1-23
* @version 0.2
* @date 2020-1-23
*
*
*/
#include <stdint.h>
#include <stdbool.h>
#include "USBd_config.h"
#include "usb_defs.h"
#include "USBd_config_CustomClass_0.h"
#define USBShort(ui16Value) ((ui16Value) & 0xff), ((ui16Value) >> 8) //((ui16Value) & 0xFF),(((ui16Value) >> 8) & 0xFF)
/**
* @brief step 1. Build Standard Device Descriptor
*
*/
// Standard Device Descriptor
const uint8_t kUSBd0DeviceDescriptor[0x12] =
{
0x12, // bLength
USB_DT_DEVICE, // bDescriptorType (constant)
USBShort(0x0200), // bcdUSB (2.00)
// We need to use a device other than the USB-IF standard, set to 0x00
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
USBD0_MAX_PACKET0, // Maximum packet size for default pipe.
USBShort(USBD0_DEV_DESC_IDVENDOR), // Vendor ID (VID).
USBShort(USBD0_DEV_DESC_IDPRODUCT), // Product ID (PID).
USBShort(USBD0_DEV_DESC_BCDDEVICE), // Device Version BCD.
0x01, // Index of Manufacturer string identifier.
0x02, // Index of Product string identifier.
0x03 * USBD0_STR_DESC_SER_EN, // Index of Product serial number.
0x01 // Number of configurations.
};
/**
* @brief step 2. Buid Standard Configuration Descriptor
*
*/
// Standard Interface Descriptor
const uint8_t kUSBd0InterfaceDescriptor[]=
{
0x09, // bLength
USB_DT_INTERFACE, // bDescriptorType
USBD_CUSTOM_CLASS0_IF0_NUM, // bInterfaceNumber
USBD_CUSTOM_CLASS0_IF0_ALT, // bAlternateSetting
0x03, // bNumEndpoints(we will use three endpoints)
//
USBD_CUSTOM_CLASS0_IF0_CLASS, // bInterfaceClass
USBD_CUSTOM_CLASS0_IF0_SUBCLASS, // bInterfaceSubClass
USBD_CUSTOM_CLASS0_IF0_PROTOCOL, // bInterfaceProtocol
0x00, // iInterface
// Index of string descriptor describing this interface
////TODO: fix this 0x04 ?
// Standard Endpoint Descriptor
0x07, // bLength
USB_DTYPE_ENDPOINT, // bDescriptorType
USBD_CUSTOM_CLASS0_IF0_EP0_BENDPOINTADDRESS, // bEndpointAddress -> set 0x01 for endpoint 0
USB_EP_ATTR_BULK, // bmAttributes -> Endpoint is a bulk endpoint.
USBShort(USBD_CUSTOM_CLASS0_IF0_EP0_HS_WMAXPACKETSIZE),
// wMaxPacketSize -> The maximum packet size: 512 bytes
// We assume that it always runs in High Speed.
USBD_CUSTOM_CLASS0_IF0_EP0_HS_BINTERVAL, // bInterval
// Endpoint 1: Bulk Out used for commands received from host PC.
// Endpoint 2: Bulk In used for responses send to host PC.
// Endpoint 3: Bulk In (optional) used for streaming SWO trace
// ATTENTION:
// physical endpoint 1 indeed included two "endpoints": Bulk OUT and Bulk IN
// physical endpoint 1 -> Endpoint 1 & Endpoint 2
// physical endpoint 2 -> Endpoint 3
// See also :
// http://www.keil.com/pack/doc/CMSIS/DAP/html/group__DAP__ConfigUSB__gr.html
/* Pysical endpoint 1 */
// "Endpoint 1: Bulk Out used for commands received from host PC." PC -> Device
0x07, // bLength
USB_DTYPE_ENDPOINT, // bDescriptorType
0x01, // bEndpointAddress
USB_ENDPOINT_ATTR_BULK, // bmAttributes
USBShort(USBD_CUSTOM_CLASS0_IF0_EP1_HS_WMAXPACKETSIZE), // wMaxPacketSize
USBD_CUSTOM_CLASS0_IF0_EP1_HS_BINTERVAL, // bInterval
/* Pysical endpoint 1 */
// "Endpoint 2: Bulk In used for responses send to host PC." Device -> PC
0x07, // bLength
USB_DTYPE_ENDPOINT, // bDescriptorType
0x81, // bEndpointAddress
USB_ENDPOINT_ATTR_BULK, // bmAttributes
USBShort(USBD_CUSTOM_CLASS0_IF0_EP2_HS_WMAXPACKETSIZE), // wMaxPacketSize
USBD_CUSTOM_CLASS0_IF0_EP2_HS_BINTERVAL, // bInterval
/* Pysical endpoint 2 */
// "Endpoint 3: Bulk In (optional) used for streaming SWO trace" Device -> PC
0x07, // bLength
USB_DTYPE_ENDPOINT, // bDescriptorType
0x82, // bEndpointAddress
USB_ENDPOINT_ATTR_BULK, // bmAttributes
USBShort(USBD_CUSTOM_CLASS0_IF0_EP3_HS_WMAXPACKETSIZE), // wMaxPacketSize
USBD_CUSTOM_CLASS0_IF0_EP3_HS_BINTERVAL, // bInterval
};
// Standard Configuration Descriptor
const uint8_t kUSBd0ConfigDescriptor[] =
{
// Configuration descriptor header.
0x09, // bLength -> 0x09?? may be ok... 1-23
0x03, // bDescriptorType
// constant, set to 0x03
USBShort((sizeof(kUSBd0InterfaceDescriptor)) + (sizeof(kUSBd0ConfigDescriptor))),
// wTotalLength
0x01, // bNumInterfaces
// There is only one interface in the CMSIS-DAP project
0x01, // bConfigurationValue: 0x01 is used to select this configuration */
0x00, // iConfiguration: no string to describe this configuration */
USBD0_CFG_DESC_BMATTRIBUTES, // bmAttributes
USBD0_CFG_DESC_BMAXPOWER, // bMaxPower
};
/**
* @brief step 3. Build String Descriptor
*
*/
const uint8_t kLangDescriptor[] =
{
4,
USB_DT_STRING,
USBShort(USB_LANGID_ENGLISH_US)
};
/**
* @brief We will use these string descriptor:
* 1. Manufacturer string -> "KEIL - Tools By ARM"
* 2. Product string -> "LPC-Link-II"
* 3. Serial number string -> "0001A0000000"
* 4. Interface string -> "LPC-Link-II CMSIS-DAP"
*
*
*/
const uint8_t kManufacturerString[0x28] =
{
0x28, // bLength
0x03, // bDescriptorType
// "KEIL - Tools By ARM"
'K', 0, 'E', 0, 'I', 0, 'L', 0, ' ', 0, '-', 0, ' ', 0, 'T', 0, 'o', 0, 'o', 0,
'l', 0, 's', 0, ' ', 0, 'B', 0, 'y', 0, ' ', 0, 'A', 0, 'R', 0, 'M', 0
};
const uint8_t kProductString[0x18] =
{
0x18, // bLength
0x03, // bDescriptorType
// "LPC-Link-II"
'L', 0, 'P', 0, 'C', 0, '-', 0, 'L', 0, 'i', 0, 'n', 0, 'k', 0, '-', 0, 'I', 0,
'I', 0
};
const uint8_t kSerialNumberString[0x1A] =
{
0x1A, // bLength
0x03, // bDescriptorType
// "0001A0000000"
'0', 0, '0', 0, '0', 0, '1', 0, 'A', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0,
'0', 0, '0', 0
};
const uint8_t kInterfaceString[0x2C] =
{
0x2C, // bLength
0x03, // bDescriptorType
// "LPC-Link-II CMSIS-DAP"
'L', 0, 'P', 0, 'C', 0, '-', 0, 'L', 0, 'i', 0, 'n', 0, 'k', 0, '-', 0, 'I', 0,
'I', 0, ' ', 0, 'C', 0, 'M', 0, 'S', 0, 'I', 0, 'S', 0, '-', 0, 'D', 0, 'A', 0,
'P', 0
};
const uint8_t * const kUSBd0StringDescriptorsSet[] =
{
kLangDescriptor,
kManufacturerString,
kProductString,
kSerialNumberString,
kInterfaceString
};

View File

@ -0,0 +1,41 @@
#ifndef __USBD_CONFIG_H__
#define __USBD_CONFIG_H__
// Vendor ID assigned by USB-IF (idVendor).
#define USBD0_DEV_DESC_IDVENDOR 0xC251
// Product ID assigned by manufacturer (idProduct).
#define USBD0_DEV_DESC_IDPRODUCT 0xF00A
// Device Release Number in binary-coded decimal (bcdDevice).
#define USBD0_DEV_DESC_BCDDEVICE 0x0100
// Maximum packet size for Endpoint 0 (bMaxPacketSize0).
#define USBD0_MAX_PACKET0 64
// If disabled Serial Number String will not be assigned to USB Device.
#define USBD0_STR_DESC_SER_EN 1
// bmAttributes
#define USBD0_CFG_DESC_BMATTRIBUTES 0x80
// bMaxPower
#define USBD0_CFG_DESC_BMAXPOWER 250
// Interface Number
#define USBD_CUSTOM_CLASS0_IF0_NUM 0
// Alternate Setting
#define USBD_CUSTOM_CLASS0_IF0_ALT 0
// Class Code
#define USBD_CUSTOM_CLASS0_IF0_CLASS 0xFF // 0xFF: Vendor Specific
// Subclass Code
#define USBD_CUSTOM_CLASS0_IF0_SUBCLASS 0x00
// Protocol Code
#define USBD_CUSTOM_CLASS0_IF0_PROTOCOL 0x00
#endif

View File

@ -23,10 +23,6 @@
#define USB_MISC_PROTOCOL_INTERFACE_ASSOCIATION_DESCRIPTOR 0x01
union word_t {
struct {
uint8_t u8lo;
@ -39,7 +35,7 @@ struct usb_standard_request
{
uint8_t bmRequestType;
uint8_t bRequest;
word_t wValue;
word_t wValue; // 16bit
word_t wIndex;
word_t wLength;
} __attribute__((packed));

View File

@ -165,7 +165,7 @@ struct usbip_stage2_header_cmd_submit {
*/
struct usbip_stage2_header_ret_submit {
int32_t status;
int32_t data_length;
int32_t data_length;//actual_length
int32_t start_frame;
int32_t number_of_packets;
int32_t error_count;

View File

@ -122,7 +122,7 @@ static void wait_for_ip()
os_printf("Waiting for AP connection...\r\n");
xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY);
os_printf("Connected to AP");
os_printf("Connected to AP\r\n");
}

View File

@ -30,7 +30,7 @@
#include "usbip_server.h"
uint8_t state = ACCEPTING;
int sock = -1;
int kSock = -1;
void tcp_server_task(void *pvParameters)
{
char rx_buffer[2048];
@ -89,8 +89,8 @@ void tcp_server_task(void *pvParameters)
struct sockaddr_in sourceAddr;
#endif
uint32_t addrLen = sizeof(sourceAddr);
sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
if (sock < 0)
kSock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
if (kSock < 0)
{
os_printf("Unable to accept connection: errno %d\r\n", errno);
break;
@ -99,7 +99,7 @@ void tcp_server_task(void *pvParameters)
while (1)
{
int len = recv(sock, rx_buffer, 2047, 0);
int len = recv(kSock, rx_buffer, 2047, 0);
// Error occured during receiving
if (len < 0)
{
@ -156,11 +156,11 @@ void tcp_server_task(void *pvParameters)
}
}
state = ACCEPTING;
if (sock != -1)
if (kSock != -1)
{
os_printf("Shutting down socket and restarting...\r\n");
shutdown(sock, 0);
close(sock);
shutdown(kSock, 0);
close(kSock);
shutdown(listen_sock, 0);
close(listen_sock);

View File

@ -8,18 +8,25 @@
#include "usbip_defs.h"
#include "usb_defs.h"
// attach helper function
static int read_stage1_command(uint8_t *buffer, uint32_t length);
static int handle_device_list(uint8_t *buffer, uint32_t length);
static int handle_device_attach(uint8_t *buffer, uint32_t length);
static void send_stage1_header(uint16_t command, uint32_t status);
static void send_device_list();
static void send_device_info();
static void send_interface_info();
// emulate helper function
static void pack(void *data, int size);
static void unpack(void *data, int size);
static int handle_submit(usbip_stage2_header *header);
static int handle_control_request(usbip_stage2_header *header);
static void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t data_length);
int attach(uint8_t *buffer, uint32_t length)
{
uint32_t command = read_stage1_command(buffer, length);
int command = read_stage1_command(buffer, length);
if (command < 0)
{
return -1;
@ -31,12 +38,12 @@ int attach(uint8_t *buffer, uint32_t length)
handle_device_list(buffer, length);
break;
case USBIP_STAGE1_CMD_DEVICE_ATTACH: // OP_REQ_IMPORT
handle_device_attach(buffer, length);
case USBIP_STAGE1_CMD_DEVICE_ATTACH: // OP_REQ_IMPORT
handle_device_attach(buffer, length); ////TODO: fill this
break;
default:
os_printf("s1 unknown command: %d\r\n", command);
os_printf("attach Unknown command: %d\r\n", command);
break;
}
}
@ -48,7 +55,7 @@ static int read_stage1_command(uint8_t *buffer, uint32_t length)
return -1;
}
usbip_stage1_header *req = (usbip_stage1_header *)buffer;
return ntohs(req->command) & 0xFF; // 0x80xx low bit
return (ntohs(req->command) & 0xFF); // 0x80xx low bit
}
static int handle_device_list(uint8_t *buffer, uint32_t length)
@ -60,18 +67,33 @@ static int handle_device_list(uint8_t *buffer, uint32_t length)
static int handle_device_attach(uint8_t *buffer, uint32_t length)
{
int
os_printf("Handling dev attach request...\r\n");
//char bus[USBIP_BUSID_SIZE];
if (length < sizeof(USBIP_BUSID_SIZE))
{
return -1;
}
//client.readBytes((uint8_t *)bus, USBIP_BUSID_SIZE);
send_stage1_header(USBIP_STAGE1_CMD_DEVICE_ATTACH, 0);
send_device_info();
state = EMULATING;
}
static void send_stage1_header(uint16_t command, uint32_t status)
{
os_printf("Sending header...\r\n");
usbip_stage1_header header;
header.version = htons(273); // 273???
header.version = htons(273); ////TODO: 273???
// may be : https://github.com/Oxalin/usbip_windows/issues/4
header.command = htons(command);
header.status = htonl(status);
send(socket, (uint8_t *)&header, sizeof(usbip_stage1_header), 0);
send(kSock, (uint8_t *)&header, sizeof(usbip_stage1_header), 0);
}
static void send_device_list()
@ -97,7 +119,7 @@ static void send_device_list()
}
}
void send_device_info()
static void send_device_info()
{
//// TODO:fill this
os_printf("Sending device info...");
@ -111,12 +133,11 @@ void send_device_info()
device.speed = htonl(2); // what is this???
//// TODO: 0200H for USB2.0
//// TODO: fill Vendor Product Device-version
device.idVendor = htons(USB_DEVICE_VENDOR_ID);
device.idProduct = htons(USB_DEVICE_PRODUCT_ID);
device.bcdDevice = htons(USB_DEVICE_VERSION);
device.idVendor = htons(USBD0_DEV_DESC_IDVENDOR);
device.idProduct = htons(USBD0_DEV_DESC_IDPRODUCT);
device.bcdDevice = htons(USBD0_DEV_DESC_BCDDEVICE);
device.bDeviceClass = 0x00; // <defined at interface level>
device.bDeviceClass = 0x00; // We need to use a device other than the USB-IF standard, set to 0x00
device.bDeviceSubClass = 0x00;
device.bDeviceProtocol = 0x00;
@ -124,9 +145,185 @@ void send_device_info()
device.bNumConfigurations = 1;
device.bNumInterfaces = 1;
write(&device, sizeof(usbip_stage1_usb_device));
send(kSock, (uint8_t *)&device, sizeof(usbip_stage1_usb_device), 0);
}
static void send_interface_info()
{
os_printf("Sending interface info...\r\n");
usbip_stage1_usb_interface interface;
interface.bInterfaceClass = USBD_CUSTOM_CLASS0_IF0_CLASS;
interface.bInterfaceSubClass = USBD_CUSTOM_CLASS0_IF0_SUBCLASS;
interface.bInterfaceProtocol = USBD_CUSTOM_CLASS0_IF0_PROTOCOL;
interface.padding = 0; // shall be set to zero
send(kSock, (uint8_t *)&interface, sizeof(usbip_stage1_usb_interface), 0);
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
int emulate(uint8_t *buffer, uint32_t length)
{
// usbip_stage2_header header;
int command = read_stage2_command((usbip_stage2_header *)buffer); ////TODO: fill this
if (command < 0)
{
return -1;
}
switch (command)
{
case USBIP_STAGE2_REQ_SUBMIT:
handle_submit((usbip_stage2_header *)buffer);
break;
case USBIP_STAGE2_REQ_UNLINK:
handle_unlink((usbip_stage2_header *)buffer);
break;
default:
os_printf("emulate unknown command:%d\r\n", command);
return -1;
}
return 0;
}
int read_stage2_command(usbip_stage2_header *header, uint32_t length)
{
if (length < sizeof(usbip_stage2_header))
{
return -1;
}
//client.readBytes((uint8_t *)&header, sizeof(usbip_stage2_header));
unpack((uint32_t *)&header, sizeof(usbip_stage2_header));
return header->base.command;
}
/**
* @brief Pack the following packets(Offset 0x00 - 0x28):
* - cmd_submit
* - ret_submit
* - cmd_unlink
* - ret_unlink
*
* @param data Point to packets header
* @param size Packets header size
*/
static void pack(void *data, int size)
{
// Ignore the setup field
int size = (size / sizeof(uint32_t)) - 2;
uint32_t *ptr = (uint32_t *)data;
for (int i = 0; i < size; i++)
{
ptr[i] = htonl(ptr[i]);
}
}
/**
* @brief Unack the following packets(Offset 0x00 - 0x28):
* - cmd_submit
* - ret_submit
* - cmd_unlink
* - ret_unlink
*
* @param data Point to packets header
* @param size packets header size
*/
static void unpack(void *data, int size)
{
// Ignore the setup field
int size = (size / sizeof(uint32_t)) - 2;
uint32_t *ptr = (uint32_t *)data;
for (int i = 0; i < size; i++)
{
ptr[i] = ntohl(ptr[i]);
}
}
////TODO: fill this
/**
* @brief
*
*/
static int handle_submit(usbip_stage2_header *header)
{
switch (header->base.ep)
{
// control endpoint(endpoint 0)
case 0x00:
handle_control_request(header);
break;
// data
case 0x01:
if (header->base.direction == 0)
{
// Serial.println("EP 01 DATA FROM HOST");
handle_data_request(header);
}
else
{
// Serial.println("EP 01 DATA TO HOST");
handle_data_response(header);
}
break;
// request to save data to device
case 0x81:
if (header->base.direction == 0)
{
os_printf("*** WARN! EP 81 DATA TX");
}
else
{
os_printf("*** WARN! EP 81 DATA RX");
}
return -1;
default:
os_printf("*** WARN ! UNKNOWN ENDPOINT: ");
os_printf((int)header.base.ep);
return -1;
}
return 0;
}
static void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t data_length)
{
req_header->base.command = USBIP_STAGE2_RSP_SUBMIT;
req_header->base.direction = !req_header->base.direction;
memset(&req_header->u.ret_submit, 0, sizeof(usbip_stage2_header_ret_submit));
req_header->u.ret_submit.status = status;
req_header->u.ret_submit.data_length = data_length;
pack(&req_header, sizeof(usbip_stage2_header));
send(kSock, req_header, sizeof(usbip_stage2_header), 0);
}
void send_stage2_submit_data(usbip_stage2_header *req_header, int32_t status, void *data, int32_t data_length)
{
send_stage2_submit(req_header, status, data_length);
if (data_length)
{
send(kSock, data, data_length, 0);
}
}

View File

@ -8,7 +8,7 @@ enum state_t
EMULATING
};
extern uint32_t state;
extern int socket;
extern int kSock;
int attach(uint8_t *buffer, uint32_t length);
int emulate(uint8_t *buffer, uint32_t length);