From a15f87374465c0600af9ebf04f18a8bc552f9186 Mon Sep 17 00:00:00 2001 From: windowsair Date: Wed, 22 Jan 2020 22:06:29 +0800 Subject: [PATCH] feat: Add USBIP component (partially completed) --- README.md | 5 + components/USBIP/usb_defs.h | 320 ++++++++++++++++++++++++++++++++++ components/USBIP/usbip_defs.h | 223 +++++++++++++++++++++++ main/CMakeLists.txt | 4 +- main/component.mk | 4 - main/main.c | 147 +--------------- main/tcp_server.c | 171 ++++++++++++++++++ main/tcp_server.h | 6 + main/timer.c | 29 +++ main/timer.h | 6 + main/usbip_server.c | 132 ++++++++++++++ main/usbip_server.h | 16 ++ main/wifi_configuration.h | 18 ++ 13 files changed, 932 insertions(+), 149 deletions(-) create mode 100644 components/USBIP/usb_defs.h create mode 100644 components/USBIP/usbip_defs.h delete mode 100644 main/component.mk create mode 100644 main/tcp_server.c create mode 100644 main/tcp_server.h create mode 100644 main/timer.c create mode 100644 main/timer.h create mode 100644 main/usbip_server.c create mode 100644 main/usbip_server.h create mode 100644 main/wifi_configuration.h diff --git a/README.md b/README.md index e69de29..e00d592 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,5 @@ +# Setup +1. DAP_Setup() +2. Server begin + +# Loop \ No newline at end of file diff --git a/components/USBIP/usb_defs.h b/components/USBIP/usb_defs.h new file mode 100644 index 0000000..d75f317 --- /dev/null +++ b/components/USBIP/usb_defs.h @@ -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 + + +#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 diff --git a/components/USBIP/usbip_defs.h b/components/USBIP/usbip_defs.h new file mode 100644 index 0000000..943989a --- /dev/null +++ b/components/USBIP/usbip_defs.h @@ -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 +#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 + * <<>>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 + * << -#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); } diff --git a/main/tcp_server.c b/main/tcp_server.c new file mode 100644 index 0000000..f28213b --- /dev/null +++ b/main/tcp_server.c @@ -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 +#include +#include +#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 + +#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); +} \ No newline at end of file diff --git a/main/tcp_server.h b/main/tcp_server.h new file mode 100644 index 0000000..877ab2a --- /dev/null +++ b/main/tcp_server.h @@ -0,0 +1,6 @@ +#ifndef __TCP_SERVER_H__ +#define __TCP_SERVER_H__ + +void tcp_server_task(void *pvParameters); + +#endif \ No newline at end of file diff --git a/main/timer.c b/main/timer.c new file mode 100644 index 0000000..18be76f --- /dev/null +++ b/main/timer.c @@ -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 +#include +#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); +} \ No newline at end of file diff --git a/main/timer.h b/main/timer.h new file mode 100644 index 0000000..bc569a9 --- /dev/null +++ b/main/timer.h @@ -0,0 +1,6 @@ +#ifndef __TIMER_H__ +#define __TIMER_H__ + +void timer_create_task(); + +#endif \ No newline at end of file diff --git a/main/usbip_server.c b/main/usbip_server.c new file mode 100644 index 0000000..56b3b06 --- /dev/null +++ b/main/usbip_server.c @@ -0,0 +1,132 @@ +#include +#include "lwip/err.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" +#include + +#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; // + 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) +{ +} \ No newline at end of file diff --git a/main/usbip_server.h b/main/usbip_server.h new file mode 100644 index 0000000..e1c05f3 --- /dev/null +++ b/main/usbip_server.h @@ -0,0 +1,16 @@ +#ifndef __USBIP_SERVER_H__ +#define __USBIP_SERVER_H__ +#include +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 \ No newline at end of file diff --git a/main/wifi_configuration.h b/main/wifi_configuration.h new file mode 100644 index 0000000..cb2701c --- /dev/null +++ b/main/wifi_configuration.h @@ -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 \ No newline at end of file