0
0
Fork 0

feat: Add USBIP component (partially completed)

This commit is contained in:
windowsair 2020-01-22 22:06:29 +08:00
parent 2037ba6392
commit a15f873744
13 changed files with 932 additions and 149 deletions

View File

@ -0,0 +1,5 @@
# Setup
1. DAP_Setup()
2. Server begin
# Loop

320
components/USBIP/usb_defs.h Normal file
View File

@ -0,0 +1,320 @@
/**
* @file usb_defs.h
* @brief Modify
* @version 0.1
* @date 2020-01-22
*
* @copyright Copyright (c) 2020
*
*/
//
// Created by thevoidnn on 10/25/17.
//
#ifndef __USB_DEFS_H__
#define __USB_DEFS_H__
#include <stdint.h>
#define USB_CLASS_MISCELLANEOUS_DEVICE 0xef
#define USB_MISC_SUBCLASS_COMMON 0x02
#define USB_MISC_PROTOCOL_INTERFACE_ASSOCIATION_DESCRIPTOR 0x01
union word_t {
struct {
uint8_t u8lo;
uint8_t u8hi;
} __attribute__((packed));
uint16_t u16;
};
struct usb_standard_request
{
uint8_t bmRequestType;
uint8_t bRequest;
word_t wValue;
word_t wIndex;
word_t wLength;
} __attribute__((packed));
//#define USB_CLASS_HID 3
#define USB_DT_HID 0x21
#define USB_DT_REPORT 0x22
//struct usb_hid_descriptor {
// uint8_t bLength;
// uint8_t bDescriptorType;
// uint16_t bcdHID;
// uint8_t bCountryCode;
// uint8_t bNumDescriptors;
//} __attribute__((packed));
//#define USB_DT_HID_SIZE sizeof(struct usb_hid_descriptor)
//struct usb_hid_report_descriptor {
// uint8_t bDescriptorType;
// uint16_t wReportLength;
//} __attribute__((packed));
#define USB_DT_REPORT_SIZE sizeof(struct usb_hid_report_descriptor)
/* Class Definition */
#define USB_CLASS_VENDOR 0xFF
///////////////////////////////////////////////////////////////
/* Table 9-2. Format of Setup Data */
/* bmRequestType bit definitions */
/* bit 7 : Direction */
#define USB_REQ_TYPE_OUT 0x00 // Host-to-device
#define USB_REQ_TYPE_IN 0x80 // Device-to-host
/* bits 6..5 : Type */
#define USB_REQ_TYPE_STANDARD 0x00
#define USB_REQ_TYPE_CLASS 0x20
#define USB_REQ_TYPE_VENDOR 0x40
#define USB_REQ_TYPE_RESERVED 0x60
/* bits 4..0 : Recipient */
#define USB_REQ_TYPE_DEVICE 0x00
#define USB_REQ_TYPE_INTERFACE 0x01
#define USB_REQ_TYPE_ENDPOINT 0x02
#define USB_REQ_TYPE_OTHER 0x03
#define USB_REQ_TYPE_RESERVED 0x1F
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* USB Standard Request Codes - Table 9-4 */
#define USB_REQ_GET_STATUS 0
#define USB_REQ_CLEAR_FEATURE 1
/* Reserved for future use: 2 */
#define USB_REQ_SET_FEATURE 3
/* Reserved for future use: 3 */
#define USB_REQ_SET_ADDRESS 5
#define USB_REQ_GET_DESCRIPTOR 6
#define USB_REQ_SET_DESCRIPTOR 7
#define USB_REQ_GET_CONFIGURATION 8
#define USB_REQ_SET_CONFIGURATION 9
#define USB_REQ_GET_INTERFACE 10
#define USB_REQ_SET_INTERFACE 11
#define USB_REQ_SET_SYNCH_FRAME 12
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* USB Descriptor Types - Table 9-5 */
#define USB_DT_DEVICE 1
#define USB_DT_CONFIGURATION 2
#define USB_DT_STRING 3
#define USB_DT_INTERFACE 4
#define USB_DT_ENDPOINT 5
#define USB_DT_DEVICE_QUALIFIER 6
#define USB_DT_OTHER_SPEED_CONFIGURATION 7
#define USB_DT_INTERFACE_POWER 8
/* From ECNs */
#define USB_DT_OTG 9
#define USB_DT_DEBUG 10
#define USB_DT_INTERFACE_ASSOCIATION 11
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* USB Standard Feature Selectors - Table 9-6 */
#define USB_FEAT_ENDPOINT_HALT 0 // Recipient: Device
#define USB_FEAT_DEVICE_REMOTE_WAKEUP 1 // Recipient: Endpoint
#define USB_FEAT_TEST_MODE 2 // Recipient: Device
/* Information Returned by a GetStatus() Request to a Device - Figure 9-4 */
#define USB_DEV_STATUS_SELF_POWERED 0x01
#define USB_DEV_STATUS_REMOTE_WAKEUP 0x02
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* USB Standard Device Descriptor - Table 9-8 */
struct usb_device_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} __attribute__((packed));
#define USB_DT_DEVICE_SIZE sizeof(struct usb_device_descriptor)
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* USB Device_Qualifier Descriptor - Table 9-9
* Not used in this implementation.
*/
struct usb_device_qualifier_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint8_t bNumConfigurations;
uint8_t bReserved;
} __attribute__((packed));
///////////////////////////////////////////////////////////////
/* This is only defined as a top level named struct to improve c++
* compatibility. You should never need to instance this struct
* in user code! */
struct usb_interface {
uint8_t *cur_altsetting;
uint8_t num_altsetting;
const struct usb_iface_assoc_descriptor *iface_assoc;
const struct usb_interface_descriptor *altsetting;
};
///////////////////////////////////////////////////////////////
/* USB Standard Configuration Descriptor - Table 9-10 */
struct usb_config_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} __attribute__((packed));
#define USB_DT_CONFIGURATION_SIZE sizeof(struct usb_config_descriptor)
///////////////////////////////////////////////////////////////
/* USB Configuration Descriptor *bmAttributes* bit definitions */
#define USB_CONFIG_ATTR_DEFAULT 0x80 /** always required (USB2.0 table 9-10) */
#define USB_CONFIG_ATTR_SELF_POWERED 0x40
#define USB_CONFIG_ATTR_REMOTE_WAKEUP 0x20
/* Other Speed Configuration is the same as Configuration Descriptor.
* - Table 9-11
*/
///////////////////////////////////////////////////////////////
/* USB Standard Interface Descriptor - Table 9-12 */
struct usb_interface_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} __attribute__((packed));
#define USB_DT_INTERFACE_SIZE sizeof(struct usb_interface_descriptor)
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* USB Standard Endpoint Descriptor - Table 9-13 */
struct usb_endpoint_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} __attribute__((packed));
#define USB_DT_ENDPOINT_SIZE sizeof(struct usb_endpoint_descriptor)
///////////////////////////////////////////////////////////////
/* USB bEndpointAddress helper macros */
#define USB_ENDPOINT_ADDR_OUT(x) (x)
#define USB_ENDPOINT_ADDR_IN(x) (0x80 | (x))
///////////////////////////////////////////////////////////////
/* USB Endpoint Descriptor bmAttributes bit definitions - Table 9-13 */
/* bits 1..0 : Transfer type */
#define USB_ENDPOINT_ATTR_CONTROL 0x00
#define USB_ENDPOINT_ATTR_ISOCHRONOUS 0x01
#define USB_ENDPOINT_ATTR_BULK 0x02
#define USB_ENDPOINT_ATTR_INTERRUPT 0x03
#define USB_ENDPOINT_ATTR_TYPE 0x03
// If not an isochronous endpoint, bits 5..2 are reserved
// and must be set to zero.
/* bits 3..2 : Sync type (only if ISOCHRONOUS) */
#define USB_ENDPOINT_ATTR_NOSYNC 0x00
#define USB_ENDPOINT_ATTR_ASYNC 0x04
#define USB_ENDPOINT_ATTR_ADAPTIVE 0x08
#define USB_ENDPOINT_ATTR_SYNC 0x0C
#define USB_ENDPOINT_ATTR_SYNCTYPE 0x0C
/* bits 5..4 : Usage type (only if ISOCHRONOUS) */
#define USB_ENDPOINT_ATTR_DATA 0x00
#define USB_ENDPOINT_ATTR_FEEDBACK 0x10
#define USB_ENDPOINT_ATTR_IMPLICIT_FEEDBACK_DATA 0x20
#define USB_ENDPOINT_ATTR_USAGETYPE 0x30
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* Table 9-15 specifies String Descriptor Zero.
* Table 9-16 specified UNICODE String Descriptor.
*/
struct usb_string_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wData[];
} __attribute__((packed));
/* From ECN: Interface Association Descriptors, Table 9-Z */
struct usb_iface_assoc_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bFirstInterface;
uint8_t bInterfaceCount;
uint8_t bFunctionClass;
uint8_t bFunctionSubClass;
uint8_t bFunctionProtocol;
uint8_t iFunction;
} __attribute__((packed));
#define USB_DT_INTERFACE_ASSOCIATION_SIZE \
sizeof(struct usb_iface_assoc_descriptor)
enum usb_language_id {
USB_LANGID_ENGLISH_US = 0x409,
};
///////////////////////////////////////////////////////////////
#endif

View File

@ -0,0 +1,223 @@
/**
* @file usbip_defs.h
* @brief Simple modification
* @version 0.1
* @date 2020-01-22
*
* @copyright Copyright (c) 2020
*
*/
// Focus on the following structures in this file:
// usbip_stage2_header
// usbip_stage1_response_devlist
//
// Created by thevoidnn on 10/25/17.
//
#ifndef __USBIP_DEFS_H__
#define __USBIP_DEFS_H__
#include <stdint.h>
#include "usb_defs.h"
#define USBIP_SYSFS_PATH_SIZE 256
#define USBIP_BUSID_SIZE 32
enum usbip_stage1_command {
// Offset 2
USBIP_STAGE1_CMD_DEVICE_LIST = 0x05, // OP_REQ_DEVLIST
USBIP_STAGE1_CMD_DEVICE_ATTACH = 0x03, // OP_REQ_IMPORT
};
enum usbip_stager2_command { ////TODO: change to stage2
//Offset 0
USBIP_STAGE2_REQ_SUBMIT = 0x0001,
USBIP_STAGE2_REQ_UNLINK = 0x0002,
USBIP_STAGE2_RSP_SUBMIT = 0x0003,
USBIP_STAGE2_RSP_UNLINK = 0x0004,
};
enum usbip_stage2_direction {
USBIP_DIR_OUT = 0x00,
USBIP_DIR_IN = 0x01,
};
struct usbip_stage1_header {
uint16_t version;
uint16_t command;
uint32_t status;
} __attribute__ ((__packed__));
/////////////////////////////////////////////////////////////
// Device description
struct usbip_stage1_usb_device {
char path[USBIP_SYSFS_PATH_SIZE];
char busid[USBIP_BUSID_SIZE];
uint32_t busnum;
uint32_t devnum;
uint32_t speed;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bConfigurationValue;
uint8_t bNumConfigurations;
uint8_t bNumInterfaces;
} __attribute__((packed));
// Interface description
struct usbip_stage1_usb_interface {
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t padding;
} __attribute__((packed));
struct usbip_stage1_response_devlist_entry {
struct usbip_stage1_usb_device udev;
struct usbip_stage1_usb_interface uinf[];
} __attribute__((packed));
struct usbip_stage1_response_devlist {
uint32_t list_size;
usbip_stage1_response_devlist_entry devices[];
} __attribute__ ((__packed__));
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/**
* struct usbip_header_basic - data pertinent to every URB request
* RESPONSE & REQUEST
*
* @command: the usbip request type
* @seqnum: sequential number that identifies requests; incremented per
* connection
* @devid: specifies a remote USB device uniquely instead of busnum and devnum;
* in the stub driver, this value is ((busnum << 16) | devnum)
* @direction: direction of the transfer
* @ep: endpoint number
*/
struct usbip_stage2_header_basic {
uint32_t command;
uint32_t seqnum;
uint32_t devid;
uint32_t direction;
uint32_t ep;
} __attribute__((packed));
/**
* struct usbip_header_cmd_submit - USBIP_CMD_SUBMIT packet header
* >>>REQUEST
*
* @transfer_flags: URB flags
* @transfer_buffer_length: the data size for (in) or (out) transfer
* @start_frame: initial frame for isochronous or interrupt transfers
* @number_of_packets: number of isochronous packets
* @interval: maximum time for the request on the server-side host controller
* @setup: setup data for a control request
*/
struct usbip_stage2_header_cmd_submit {
uint32_t transfer_flags;
int32_t data_length;
/* it is difficult for usbip to sync frames (reserved only?) */
int32_t start_frame;
int32_t number_of_packets;
int32_t interval;
union {
uint8_t setup[8];
usb_standard_request request;
};
} __attribute__((packed));
/**
* struct usbip_header_ret_submit - USBIP_RET_SUBMIT packet header
* <<<RESPONSE
*
* @status: return status of a non-iso request
* @actual_length: number of bytes transferred
* @start_frame: initial frame for isochronous or interrupt transfers
* @number_of_packets: number of isochronous packets
* @error_count: number of errors for isochronous transfers
*/
struct usbip_stage2_header_ret_submit {
int32_t status;
int32_t data_length;
int32_t start_frame;
int32_t number_of_packets;
int32_t error_count;
} __attribute__((packed));
/**
* struct usbip_header_cmd_unlink - USBIP_CMD_UNLINK packet header
* >>>REQUEST
* @seqnum: the URB seqnum to unlink
*/
struct usbip_stage2_header_cmd_unlink {
uint32_t seqnum;
} __attribute__((packed));
/**
* struct usbip_header_ret_unlink - USBIP_RET_UNLINK packet header
* <<<RESPONSE
* @status: return status of the request
*/
struct usbip_stage2_header_ret_unlink {
int32_t status;
} __attribute__((packed));
/**
* struct usbip_header - common header for all usbip packets
* @base: the basic header
* @u: packet type dependent header
*/
struct usbip_stage2_header {
struct usbip_stage2_header_basic base;
union {
struct usbip_stage2_header_cmd_submit cmd_submit;
struct usbip_stage2_header_ret_submit ret_submit;
struct usbip_stage2_header_cmd_unlink cmd_unlink;
struct usbip_stage2_header_ret_unlink ret_unlink;
} u;
} __attribute__((packed));
#endif

View File

@ -1,4 +1,4 @@
set(COMPONENT_SRCS "tcp_server.c") set(COMPONENT_SRCS "main.c timer.c tcp_server.c usbip_server.c")
set(COMPONENT_ADD_INCLUDEDIRS ". $ENV{IDF_PATH}/components/esp8266/include/esp8266/") set(COMPONENT_ADD_INCLUDEDIRS ". $ENV{IDF_PATH}/components/esp8266/include/esp8266/ ../components/USBIP")
register_component() register_component()

View File

@ -1,4 +0,0 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View File

@ -23,20 +23,16 @@
#include "lwip/sys.h" #include "lwip/sys.h"
#include <lwip/netdb.h> #include <lwip/netdb.h>
#include "gpio.h" #include "tcp_server.h"
#include "hw_timer.h" #include "timer.h"
#include "timer_struct.h" #include "wifi_configuration.h"
/* The examples use simple WiFi configuration that you can set via /* The examples use simple WiFi configuration that you can set via
'make menuconfig'. 'make menuconfig'.
If you'd rather not, just change the below entries to strings with If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/ */
#define EXAMPLE_WIFI_SSID "DAP"
#define EXAMPLE_WIFI_PASS "12345678"
#define PORT 22350
/* FreeRTOS event group to signal when we are connected & ready to make a request */ /* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group; static EventGroupHandle_t wifi_event_group;
@ -46,7 +42,6 @@ const int IPV4_GOTIP_BIT = BIT0;
const int IPV6_GOTIP_BIT = BIT1; const int IPV6_GOTIP_BIT = BIT1;
#endif #endif
static const char *TAG = "example";
static esp_err_t event_handler(void *ctx, system_event_t *event) static esp_err_t event_handler(void *ctx, system_event_t *event)
{ {
@ -130,143 +125,9 @@ static void wait_for_ip()
os_printf("Connected to AP"); os_printf("Connected to AP");
} }
static void tcp_server_task(void *pvParameters)
{
char rx_buffer[2048];
char addr_str[128];
int addr_family;
int ip_protocol;
while (1)
{
#ifdef CONFIG_EXAMPLE_IPV4
struct sockaddr_in destAddr;
destAddr.sin_addr.s_addr = htonl(INADDR_ANY);
destAddr.sin_family = AF_INET;
destAddr.sin_port = htons(PORT);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);
#else // IPV6
struct sockaddr_in6 destAddr;
bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un));
destAddr.sin6_family = AF_INET6;
destAddr.sin6_port = htons(PORT);
addr_family = AF_INET6;
ip_protocol = IPPROTO_IPV6;
inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
#endif
int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);
if (listen_sock < 0)
{
os_printf("Unable to create socket: errno %d\r\n", errno);
break;
}
os_printf("Socket created");
int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
if (err != 0)
{
os_printf("Socket unable to bind: errno %d\r\n", errno);
break;
}
os_printf("Socket binded");
err = listen(listen_sock, 1);
if (err != 0)
{
os_printf("Error occured during listen: errno %d\r\n", errno);
break;
}
os_printf("Socket listening");
#ifdef CONFIG_EXAMPLE_IPV6
struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6
#else
struct sockaddr_in sourceAddr;
#endif
uint32_t addrLen = sizeof(sourceAddr);
int sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
if (sock < 0)
{
os_printf("Unable to accept connection: errno %d\r\n", errno);
break;
}
os_printf("Socket accepted");
while (1)
{
int len = recv(sock, rx_buffer, 2047, 0);
// Error occured during receiving
if (len < 0)
{
os_printf("recv failed: errno %d\r\n", errno);
break;
}
// Connection closed
else if (len == 0)
{
os_printf("Connection closed\r\n");
break;
}
// Data received
else
{
#ifdef CONFIG_EXAMPLE_IPV6
// Get the sender's ip address as string
if (sourceAddr.sin6_family == PF_INET)
{
inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
}
else if (sourceAddr.sin6_family == PF_INET6)
{
inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
}
#else
inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
#endif
rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
//os_printf("Received %d bytes from %s:\r\n", len, addr_str);
// os_printf("%s", rx_buffer);
int err = send(sock, rx_buffer, len, 0);
if (err < 0)
{
os_printf("Error occured during sending: errno %d\r\n", errno);
break;
}
}
}
if (sock != -1)
{
os_printf("Shutting down socket and restarting...\r\n");
shutdown(sock, 0);
close(sock);
shutdown(listen_sock, 0);
close(listen_sock);
vTaskDelay(5);
}
}
vTaskDelete(NULL);
}
void timer_create_task()
{
// FRC1 frequency 80MHz
vPortEnterCritical();
frc1.ctrl.div = TIMER_CLKDIV_16; // 80MHz / 16 = 5MHz
frc1.ctrl.intr_type = TIMER_EDGE_INT;
frc1.ctrl.reload = 0x01;
frc1.load.data = 0x1000000U - 1U;
frc1.ctrl.en = 0x01;
vPortExitCritical();
vTaskDelete(NULL);
}
void app_main() void app_main()
{ {
@ -274,6 +135,6 @@ void app_main()
initialise_wifi(); initialise_wifi();
wait_for_ip(); wait_for_ip();
xTaskCreate(timer_create_task, "timer_create", 2048, NULL, 10, NULL); xTaskCreate(timer_create_task, "timer_create", 1024, NULL, 10, NULL);
xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL); xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL);
} }

171
main/tcp_server.c Normal file
View File

@ -0,0 +1,171 @@
/**
* @file tcp_server.c
* @brief Handle main tcp tasks
* @version 0.1
* @date 2020-01-22
*
* @copyright Copyright (c) 2020
*
*/
#include "tcp_server.h"
#include <string.h>
#include <stdint.h>
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>
#include "wifi_configuration.h"
#include "usbip_server.h"
uint8_t state = ACCEPTING;
int sock = -1;
void tcp_server_task(void *pvParameters)
{
char rx_buffer[2048];
char addr_str[128];
int addr_family;
int ip_protocol;
while (1)
{
#ifdef CONFIG_EXAMPLE_IPV4
struct sockaddr_in destAddr;
destAddr.sin_addr.s_addr = htonl(INADDR_ANY);
destAddr.sin_family = AF_INET;
destAddr.sin_port = htons(PORT);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);
#else // IPV6
struct sockaddr_in6 destAddr;
bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un));
destAddr.sin6_family = AF_INET6;
destAddr.sin6_port = htons(PORT);
addr_family = AF_INET6;
ip_protocol = IPPROTO_IPV6;
inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
#endif
int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);
if (listen_sock < 0)
{
os_printf("Unable to create socket: errno %d\r\n", errno);
break;
}
os_printf("Socket created");
int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
if (err != 0)
{
os_printf("Socket unable to bind: errno %d\r\n", errno);
break;
}
os_printf("Socket binded");
err = listen(listen_sock, 1);
if (err != 0)
{
os_printf("Error occured during listen: errno %d\r\n", errno);
break;
}
os_printf("Socket listening");
#ifdef CONFIG_EXAMPLE_IPV6
struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6
#else
struct sockaddr_in sourceAddr;
#endif
uint32_t addrLen = sizeof(sourceAddr);
sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
if (sock < 0)
{
os_printf("Unable to accept connection: errno %d\r\n", errno);
break;
}
os_printf("Socket accepted");
while (1)
{
int len = recv(sock, rx_buffer, 2047, 0);
// Error occured during receiving
if (len < 0)
{
os_printf("recv failed: errno %d\r\n", errno);
break;
}
// Connection closed
else if (len == 0)
{
os_printf("Connection closed\r\n");
break;
}
// Data received
else
{
#ifdef CONFIG_EXAMPLE_IPV6
// Get the sender's ip address as string
if (sourceAddr.sin6_family == PF_INET)
{
inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
}
else if (sourceAddr.sin6_family == PF_INET6)
{
inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
}
#else
inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
#endif
rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
//os_printf("Received %d bytes from %s:\r\n", len, addr_str);
// os_printf("%s", rx_buffer);
switch (state)
{
case ACCEPTING:
state = ATTACHING;
break;
case ATTACHING:
attach(rx_buffer, len);
break;
case EMULATING:
emulate(rx_buffer, len);
break;
}
// int err = send(sock, rx_buffer, len, 0);
// if (err < 0)
// {
// os_printf("Error occured during sending: errno %d\r\n", errno);
// break;
// }
}
}
state = ACCEPTING;
if (sock != -1)
{
os_printf("Shutting down socket and restarting...\r\n");
shutdown(sock, 0);
close(sock);
shutdown(listen_sock, 0);
close(listen_sock);
vTaskDelay(5);
}
}
vTaskDelete(NULL);
}

6
main/tcp_server.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __TCP_SERVER_H__
#define __TCP_SERVER_H__
void tcp_server_task(void *pvParameters);
#endif

29
main/timer.c Normal file
View File

@ -0,0 +1,29 @@
/**
* @file timer.c
* @brief Hardware timer for DAP timestamp
* @version 0.1
* @date 2020-01-22
*
* @copyright Copyright (c) 2020
*
*/
#include <stdint.h>
#include <stdbool.h>
#include "timer.h"
#include "hw_timer.h"
#include "timer_struct.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
void timer_create_task()
{
// FRC1 frequency 80MHz
vPortEnterCritical();
frc1.ctrl.div = TIMER_CLKDIV_16; // 80MHz / 16 = 5MHz
frc1.ctrl.intr_type = TIMER_EDGE_INT;
frc1.ctrl.reload = 0x01;
frc1.load.data = 0x1000000U - 1U;
frc1.ctrl.en = 0x01;
vPortExitCritical();
vTaskDelete(NULL);
}

6
main/timer.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __TIMER_H__
#define __TIMER_H__
void timer_create_task();
#endif

132
main/usbip_server.c Normal file
View File

@ -0,0 +1,132 @@
#include <stdint.h>
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>
#include "usbip_server.h"
#include "usbip_defs.h"
#include "usb_defs.h"
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();
int attach(uint8_t *buffer, uint32_t length)
{
uint32_t command = read_stage1_command(buffer, length);
if (command < 0)
{
return -1;
}
switch (command)
{
case USBIP_STAGE1_CMD_DEVICE_LIST: // OP_REQ_DEVLIST
handle_device_list(buffer, length);
break;
case USBIP_STAGE1_CMD_DEVICE_ATTACH: // OP_REQ_IMPORT
handle_device_attach(buffer, length);
break;
default:
os_printf("s1 unknown command: %d\r\n", command);
break;
}
}
static int read_stage1_command(uint8_t *buffer, uint32_t length)
{
if (length < sizeof(usbip_stage1_header))
{
return -1;
}
usbip_stage1_header *req = (usbip_stage1_header *)buffer;
return ntohs(req->command) & 0xFF; // 0x80xx low bit
}
static int handle_device_list(uint8_t *buffer, uint32_t length)
{
os_printf("Handling dev list request...\r\n");
send_stage1_header(USBIP_STAGE1_CMD_DEVICE_LIST, 0);
send_device_list();
}
static int handle_device_attach(uint8_t *buffer, uint32_t length)
{
int
}
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.command = htons(command);
header.status = htonl(status);
send(socket, (uint8_t *)&header, sizeof(usbip_stage1_header), 0);
}
static void send_device_list()
{
os_printf("Sending device list...\r\n");
// send device list size:
os_printf("Sending device list size...\r\n");
usbip_stage1_response_devlist response_devlist;
// we have only 1 device, so:
response_devlist.list_size = htonl(1);
send(socket, (uint8_t *)&response_devlist, sizeof(usbip_stage1_response_devlist), 0);
// may be foreach:
{
// send device info:
send_device_info();
// send device interfaces: // (1)
send_interface_info();
}
}
void send_device_info()
{
//// TODO:fill this
os_printf("Sending device info...");
usbip_stage1_usb_device device;
strcpy(device.path, "/sys/devices/pci0000:00/0000:00:01.2/usb1/1-1");
strcpy(device.busid, "1-1");
device.busnum = htonl(1);
device.devnum = htonl(2);
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.bDeviceClass = 0x00; // <defined at interface level>
device.bDeviceSubClass = 0x00;
device.bDeviceProtocol = 0x00;
device.bConfigurationValue = 1;
device.bNumConfigurations = 1;
device.bNumInterfaces = 1;
write(&device, sizeof(usbip_stage1_usb_device));
}
int emulate(uint8_t *buffer, uint32_t length)
{
}

16
main/usbip_server.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef __USBIP_SERVER_H__
#define __USBIP_SERVER_H__
#include <stdint.h>
enum state_t
{
ACCEPTING,
ATTACHING,
EMULATING
};
extern uint32_t state;
extern int socket;
int attach(uint8_t *buffer, uint32_t length);
int emulate(uint8_t *buffer, uint32_t length);
#endif

18
main/wifi_configuration.h Normal file
View File

@ -0,0 +1,18 @@
/**
* @file wifi_configuration.h
* @brief Fill in your wifi configuration information here.
* @version 0.1
* @date 2020-01-22
*
* @copyright Copyright (c) 2020
*
*/
#ifndef __WIFI_CONFIGURATION__
#define __WIFI_CONFIGURATION__
#define EXAMPLE_WIFI_SSID "DAP"
#define EXAMPLE_WIFI_PASS "12345678"
#define PORT 22350
#endif