feat: USBIP & Standard USB Descriptor Definitions
1. Add Standard USB Descriptor Definitions 2. USBIP stage1 completed
This commit is contained in:
parent
a15f873744
commit
a6a5e6ec0c
|
@ -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
|
|
@ -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));
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#ifndef __USB_HANDLE_H__
|
||||
#define __USB_HANDLE_H__
|
||||
#include "usbip_defs.h"
|
||||
int handleUSBControlRequest(usbip_stage2_header *header);
|
||||
#endif
|
|
@ -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
|
||||
};
|
|
@ -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
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue