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_ADD_INCLUDEDIRS ". $ENV{IDF_PATH}/components/esp8266/include/esp8266/")
set(COMPONENT_SRCS "main.c timer.c tcp_server.c usbip_server.c")
set(COMPONENT_ADD_INCLUDEDIRS ". $ENV{IDF_PATH}/components/esp8266/include/esp8266/ ../components/USBIP")
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/netdb.h>
#include "gpio.h"
#include "hw_timer.h"
#include "timer_struct.h"
#include "tcp_server.h"
#include "timer.h"
#include "wifi_configuration.h"
/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.
If you'd rather not, just change the below entries to strings with
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 */
static EventGroupHandle_t wifi_event_group;
@ -46,7 +42,6 @@ const int IPV4_GOTIP_BIT = BIT0;
const int IPV6_GOTIP_BIT = BIT1;
#endif
static const char *TAG = "example";
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");
}
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()
{
@ -274,6 +135,6 @@ void app_main()
initialise_wifi();
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);
}

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