diff options
| -rw-r--r-- | class/wireless/usbd_rndis.c | 118 | ||||
| -rw-r--r-- | class/wireless/usbd_rndis.h | 14 |
2 files changed, 82 insertions, 50 deletions
diff --git a/class/wireless/usbd_rndis.c b/class/wireless/usbd_rndis.c index f9197279..23535520 100644 --- a/class/wireless/usbd_rndis.c +++ b/class/wireless/usbd_rndis.c @@ -19,17 +19,18 @@ struct usbd_rndis_cfg_priv { uint32_t net_filter; usb_eth_stat_t eth_state; rndis_state_t init_state; + uint8_t int_ep; uint8_t mac[6]; uint32_t vendor_id; uint8_t *vendor_desc; } usbd_rndis_cfg = { .drv_version = 0x0001, - .media_status = NDIS_MEDIA_STATE_DISCONNECTED, - .mtu = RNDIS_MTU, - .speed = 0, - .init_state = rndis_uninitialized, - .mac = { 0x00, 0x00, 0x5E, 0x00, 0x53, 0x01 }, - .vendor_id = 0xffffffff, - .vendor_desc = "CherryUSB" }; + .media_status = NDIS_MEDIA_STATE_DISCONNECTED, + .mtu = CONFIG_USBDEV_RNDIS_MTU, + .speed = RNDIS_LINK_SPEED, + .init_state = rndis_uninitialized, + .mac = { 0x00, 0x00, 0x5E, 0x00, 0x53, 0x01 }, + .vendor_id = 0xffffffff, + .vendor_desc = "CherryUSB" }; /* RNDIS options list */ const uint32_t oid_supported_list[] = { @@ -57,13 +58,17 @@ const uint32_t oid_supported_list[] = { OID_802_3_MAC_OPTIONS }; -static uint8_t rndis_encapsulated_resp_buffer[CONFIG_RNDIS_RESP_BUFFER_SIZE]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t rndis_encapsulated_resp_buffer[CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t NOTIFY_RESPONSE_AVAILABLE[8] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static int rndis_encapsulated_cmd_handler(uint8_t *data, uint32_t len); -// static int rndis_encapsulated_resp_handler(uint8_t *data, uint32_t *len); -static void rndis_notify_rsp(void); -static int rndis_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) +static void rndis_notify_rsp(void) +{ + usbd_ep_start_write(usbd_rndis_cfg.int_ep, NOTIFY_RESPONSE_AVAILABLE, 8); +} + +static int rndis_class_interface_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) { switch (setup->bRequest) { case CDC_REQUEST_SEND_ENCAPSULATED_COMMAND: @@ -79,12 +84,6 @@ static int rndis_class_request_handler(struct usb_setup_packet *setup, uint8_t * } } -static void rndis_notify_rsp(void) -{ - uint8_t notify_buf[8] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - usbd_ep_write(0x81, notify_buf, 8, NULL); -} - static int rndis_init_cmd_handler(uint8_t *data, uint32_t len); static int rndis_halt_cmd_handler(uint8_t *data, uint32_t len); static int rndis_query_cmd_handler(uint8_t *data, uint32_t len); @@ -96,27 +95,28 @@ static int rndis_encapsulated_cmd_handler(uint8_t *data, uint32_t len) { switch (((rndis_generic_msg_t *)data)->MessageType) { case REMOTE_NDIS_INITIALIZE_MSG: - rndis_init_cmd_handler(data, len); + return rndis_init_cmd_handler(data, len); break; case REMOTE_NDIS_HALT_MSG: - rndis_halt_cmd_handler(data, len); + return rndis_halt_cmd_handler(data, len); break; case REMOTE_NDIS_QUERY_MSG: - rndis_query_cmd_handler(data, len); + return rndis_query_cmd_handler(data, len); break; case REMOTE_NDIS_SET_MSG: - rndis_set_cmd_handler(data, len); + return rndis_set_cmd_handler(data, len); break; case REMOTE_NDIS_RESET_MSG: - rndis_reset_cmd_handler(data, len); + return rndis_reset_cmd_handler(data, len); break; case REMOTE_NDIS_KEEPALIVE_MSG: - rndis_keepalive_cmd_handler(data, len); + return rndis_keepalive_cmd_handler(data, len); break; default: break; } + return -1; } static int rndis_init_cmd_handler(uint8_t *data, uint32_t len) @@ -147,6 +147,11 @@ static int rndis_init_cmd_handler(uint8_t *data, uint32_t len) static int rndis_halt_cmd_handler(uint8_t *data, uint32_t len) { + rndis_halt_msg_t *resp; + + resp = ((rndis_halt_msg_t *)rndis_encapsulated_resp_buffer); + resp->MessageLength = 0; + usbd_rndis_cfg.init_state = rndis_uninitialized; return 0; @@ -154,18 +159,18 @@ static int rndis_halt_cmd_handler(uint8_t *data, uint32_t len) static int rndis_query_cmd_handler(uint8_t *data, uint32_t len) { - rndis_query_msg_t *cmd = (rndis_initialize_msg_t *)data; + rndis_query_msg_t *cmd = (rndis_query_msg_t *)data; rndis_query_cmplt_t *resp; uint8_t *infomation_buffer; uint32_t infomation_len = 0; - resp = ((rndis_initialize_cmplt_t *)rndis_encapsulated_resp_buffer); - resp->Status = RNDIS_STATUS_SUCCESS; - resp->RequestId = cmd->RequestId; + resp = ((rndis_query_cmplt_t *)rndis_encapsulated_resp_buffer); resp->MessageType = REMOTE_NDIS_QUERY_CMPLT; - resp->InformationBufferOffset = 16; + resp->RequestId = cmd->RequestId; + resp->InformationBufferOffset = sizeof(rndis_query_cmplt_t) - sizeof(rndis_generic_msg_t); + resp->Status = RNDIS_STATUS_SUCCESS; - infomation_buffer = (uint8_t *)resp + sizeof(rndis_initialize_cmplt_t); + infomation_buffer = (uint8_t *)resp + sizeof(rndis_query_cmplt_t); switch (cmd->Oid) { case OID_GEN_SUPPORTED_LIST: @@ -213,7 +218,7 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len) infomation_len = (strlen(usbd_rndis_cfg.vendor_desc) + 1); break; case OID_GEN_CURRENT_PACKET_FILTER: - RNDIS_INQUIRY_PUT_LE32(0x00FFFFFF); + RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.net_filter); infomation_len = 4; break; case OID_GEN_MAXIMUM_FRAME_SIZE: @@ -223,7 +228,8 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len) case OID_GEN_MAXIMUM_TOTAL_SIZE: case OID_GEN_TRANSMIT_BLOCK_SIZE: case OID_GEN_RECEIVE_BLOCK_SIZE: - RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.mtu + ETH_HEADER_SIZE + sizeof(rndis_data_packet_t)); + //RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.mtu + ETH_HEADER_SIZE + sizeof(rndis_data_packet_t)); + RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.mtu + ETH_HEADER_SIZE); infomation_len = 4; break; case OID_GEN_MEDIA_CONNECT_STATUS: @@ -239,11 +245,16 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len) infomation_len = 4; break; case OID_802_3_MULTICAST_LIST: - RNDIS_INQUIRY_PUT_LE32(0xE0000000); /* 224.0.0.0 */ + //RNDIS_INQUIRY_PUT_LE32(0xE0000000); /* 224.0.0.0 */ + resp->Status = RNDIS_STATUS_NOT_SUPPORTED; + RNDIS_INQUIRY_PUT_LE32(0); infomation_len = 4; break; case OID_802_3_MAC_OPTIONS: - infomation_len = 0; + // infomation_len = 0; + resp->Status = RNDIS_STATUS_NOT_SUPPORTED; + RNDIS_INQUIRY_PUT_LE32(0); + infomation_len = 4; break; case OID_GEN_MAC_OPTIONS: RNDIS_INQUIRY_PUT_LE32(0); @@ -282,7 +293,8 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len) infomation_len = 4; break; default: - resp->Status = RNDIS_STATUS_NOT_SUPPORTED; + resp->Status = RNDIS_STATUS_FAILURE; + infomation_len = 0; USB_LOG_WRN("Unhandled query for Object ID 0x%x\r\n", cmd->Oid); break; } @@ -308,15 +320,27 @@ static int rndis_set_cmd_handler(uint8_t *data, uint32_t len) switch (cmd->Oid) { case OID_GEN_RNDIS_CONFIG_PARAMETER: + param = (rndis_config_parameter_t *)((uint8_t *)&(cmd->RequestId) + cmd->InformationBufferOffset); + USB_LOG_WRN("RNDIS cfg param: NameOfs=%d, NameLen=%d, ValueOfs=%d, ValueLen=%d\r\n", + param->ParameterNameOffset, param->ParameterNameLength, + param->ParameterValueOffset, param->ParameterValueLength); break; case OID_GEN_CURRENT_PACKET_FILTER: if (cmd->InformationBufferLength < sizeof(usbd_rndis_cfg.net_filter)) { + USB_LOG_WRN("PACKET_FILTER!\r\n"); resp->Status = RNDIS_STATUS_INVALID_DATA; } else { + uint32_t *filter; /* Parameter starts at offset buf_offset of the req_id field */ - param = (rndis_config_parameter_t *)((uint8_t *)&cmd->RequestId + cmd->InformationBufferOffset); + filter = (uint32_t *)((uint8_t *)&(cmd->RequestId) + cmd->InformationBufferOffset); //usbd_rndis_cfg.net_filter = param->ParameterNameOffset; + usbd_rndis_cfg.net_filter = *(uint32_t *)filter; + if (usbd_rndis_cfg.net_filter) { + usbd_rndis_cfg.init_state = rndis_data_initialized; + } else { + usbd_rndis_cfg.init_state = rndis_initialized; + } } break; case OID_GEN_CURRENT_LOOKAHEAD: @@ -330,6 +354,7 @@ static int rndis_set_cmd_handler(uint8_t *data, uint32_t len) case OID_PNP_ENABLE_WAKE_UP: default: resp->Status = RNDIS_STATUS_FAILURE; + USB_LOG_WRN("Unhandled query for Object ID 0x%x\r\n", cmd->Oid); break; } @@ -349,6 +374,8 @@ static int rndis_reset_cmd_handler(uint8_t *data, uint32_t len) resp->Status = RNDIS_STATUS_SUCCESS; resp->AddressingReset = 1; + usbd_rndis_cfg.init_state = rndis_uninitialized; + rndis_notify_rsp(); return 0; @@ -382,18 +409,23 @@ static void rndis_notify_handler(uint8_t event, void *arg) } } -void usbd_rndis_add_interface(usbd_class_t *devclass, usbd_interface_t *intf) +struct usbd_interface *usbd_rndis_alloc_intf(uint8_t int_ep, uint8_t mac[6], uint32_t vendor_id, uint8_t *vendor_desc) { - static usbd_class_t *last_class = NULL; - - if (last_class != devclass) { - last_class = devclass; - usbd_class_register(devclass); + struct usbd_interface *intf = (struct usbd_interface *)usb_malloc(sizeof(struct usbd_interface)); + if (intf == NULL) { + USB_LOG_ERR("no mem to alloc intf\r\n"); + return NULL; } - intf->class_interface_handler = rndis_class_request_handler; + usbd_rndis_cfg.int_ep = int_ep; + memcpy(usbd_rndis_cfg.mac, mac, 6); + usbd_rndis_cfg.vendor_id = vendor_id; + usbd_rndis_cfg.vendor_desc = vendor_desc; + + intf->class_interface_handler = rndis_class_interface_request_handler; intf->class_endpoint_handler = NULL; intf->vendor_handler = NULL; intf->notify_handler = rndis_notify_handler; - usbd_class_add_interface(devclass, intf); + + return intf; } diff --git a/class/wireless/usbd_rndis.h b/class/wireless/usbd_rndis.h index 905329ea..593dbf78 100644 --- a/class/wireless/usbd_rndis.h +++ b/class/wireless/usbd_rndis.h @@ -8,22 +8,22 @@ #include "usb_cdc.h" -#define ETH_HEADER_SIZE 14 -#define RNDIS_MTU 1500 /* MTU value */ +#define ETH_HEADER_SIZE 14 +#define CONFIG_USBDEV_RNDIS_MTU 1500 /* MTU value */ -#ifdef CONFIG_USB_HS -#define RNDIS_LINK_SPEED 12000000 /* Link baudrate (12Mbit/s for USB-FS) */ +#ifndef CONFIG_USB_HS +#define RNDIS_LINK_SPEED 12000000 /* Link baudrate (12Mbit/s for USB-FS) */ #else -#define RNDIS_LINK_SPEED 480000000 /* Link baudrate (480Mbit/s for USB-HS) */ +#define RNDIS_LINK_SPEED 480000000 /* Link baudrate (480Mbit/s for USB-HS) */ #endif -#define CONFIG_RNDIS_RESP_BUFFER_SIZE 128 +#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 128 #ifdef __cplusplus extern "C" { #endif -void usbd_rndis_add_interface(usbd_class_t *devclass, usbd_interface_t *intf); +struct usbd_interface *usbd_rndis_alloc_intf(uint8_t int_ep, uint8_t mac[6], uint32_t vendor_id, uint8_t *vendor_desc); #ifdef __cplusplus } |
