diff --git a/class/wireless/ndis.h b/class/wireless/ndis.h new file mode 100644 index 00000000..80682ff3 --- /dev/null +++ b/class/wireless/ndis.h @@ -0,0 +1,263 @@ +/* This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ndis.h *************************************************************** + * + * \brief + * This file contains the possible external configuration of the USB. + * + * \addtogroup usbstick + * + * + ******************************************************************************/ + +/** + \ingroup usbstick + \defgroup RNDIS RNDIS Support + @{ + */ + +/* + * ndis.h + * + * Modified by Colin O'Flynn + * ntddndis.h modified by Benedikt Spranger + * + * Thanks to the cygwin development team, + * espacially to Casper S. Hornstrup + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef _LINUX_NDIS_H +#define _LINUX_NDIS_H + +#define NDIS_STATUS_MULTICAST_FULL 0xC0010009 +#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A +#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B + +/* from drivers/net/sk98lin/h/skgepnmi.h */ +#define OID_PNP_CAPABILITIES 0xFD010100 +#define OID_PNP_SET_POWER 0xFD010101 +#define OID_PNP_QUERY_POWER 0xFD010102 +#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 +#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 +#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 + +enum NDIS_DEVICE_POWER_STATE { + NdisDeviceStateUnspecified = 0, + NdisDeviceStateD0, + NdisDeviceStateD1, + NdisDeviceStateD2, + NdisDeviceStateD3, + NdisDeviceStateMaximum +}; + +struct NDIS_PM_WAKE_UP_CAPABILITIES { + enum NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp; + enum NDIS_DEVICE_POWER_STATE MinPatternWakeUp; + enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp; +}; + +/* NDIS_PNP_CAPABILITIES.Flags constants */ +#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001 +#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 +#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 + +/* +struct NDIS_PNP_CAPABILITIES { + __le32 Flags; + struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities; +}; + +struct NDIS_PM_PACKET_PATTERN { + __le32 Priority; + __le32 Reserved; + __le32 MaskSize; + __le32 PatternOffset; + __le32 PatternSize; + __le32 PatternFlags; +}; +*/ + +/* Required Object IDs (OIDs) */ +#define OID_GEN_SUPPORTED_LIST 0x00010101 +#define OID_GEN_HARDWARE_STATUS 0x00010102 +#define OID_GEN_MEDIA_SUPPORTED 0x00010103 +#define OID_GEN_MEDIA_IN_USE 0x00010104 +#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 +#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 +#define OID_GEN_LINK_SPEED 0x00010107 +#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 +#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 +#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A +#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B +#define OID_GEN_VENDOR_ID 0x0001010C +#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D +#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E +#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F +#define OID_GEN_DRIVER_VERSION 0x00010110 +#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 +#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 +#define OID_GEN_MAC_OPTIONS 0x00010113 +#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 +#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 +#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 +#define OID_GEN_SUPPORTED_GUIDS 0x00010117 +#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 +#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 +#define OID_GEN_MACHINE_NAME 0x0001021A +#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B +#define OID_GEN_VLAN_ID 0x0001021C + +/* Optional OIDs */ +#define OID_GEN_MEDIA_CAPABILITIES 0x00010201 +#define OID_GEN_PHYSICAL_MEDIUM 0x00010202 + +/* Required statistics OIDs */ +#define OID_GEN_XMIT_OK 0x00020101 +#define OID_GEN_RCV_OK 0x00020102 +#define OID_GEN_XMIT_ERROR 0x00020103 +#define OID_GEN_RCV_ERROR 0x00020104 +#define OID_GEN_RCV_NO_BUFFER 0x00020105 + +/* Optional statistics OIDs */ +#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 +#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 +#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 +#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 +#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 +#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 +#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 +#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 +#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 +#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A +#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B +#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C +#define OID_GEN_RCV_CRC_ERROR 0x0002020D +#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E +#define OID_GEN_GET_TIME_CAPS 0x0002020F +#define OID_GEN_GET_NETCARD_TIME 0x00020210 +#define OID_GEN_NETCARD_LOAD 0x00020211 +#define OID_GEN_DEVICE_PROFILE 0x00020212 +#define OID_GEN_INIT_TIME_MS 0x00020213 +#define OID_GEN_RESET_COUNTS 0x00020214 +#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215 +#define OID_GEN_FRIENDLY_NAME 0x00020216 +#define OID_GEN_MINIPORT_INFO 0x00020217 +#define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218 + +/* IEEE 802.3 (Ethernet) OIDs */ +#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 + +#define OID_802_3_PERMANENT_ADDRESS 0x01010101 +#define OID_802_3_CURRENT_ADDRESS 0x01010102 +#define OID_802_3_MULTICAST_LIST 0x01010103 +#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 +#define OID_802_3_MAC_OPTIONS 0x01010105 +#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 +#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 +#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 +#define OID_802_3_XMIT_DEFERRED 0x01020201 +#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 +#define OID_802_3_RCV_OVERRUN 0x01020203 +#define OID_802_3_XMIT_UNDERRUN 0x01020204 +#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 +#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 +#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 + +/* Wireless LAN OIDs */ +/* Mandatory */ +#define OID_802_11_BSSID 0x0D010101 /* Q S */ +#define OID_802_11_SSID 0x0D010102 /* Q S */ +#define OID_802_11_NETWORK_TYPE_IN_USE 0x0D010204 /* Q S */ +#define OID_802_11_RSSI 0x0D010206 /* Q I */ +#define OID_802_11_BSSID_LIST 0x0D010217 /* Q */ +#define OID_802_11_BSSID_LIST_SCAN 0x0D01011A /* S */ +#define OID_802_11_INFRASTRUCTURE_MODE 0x0D010108 /* Q S */ +#define OID_802_11_SUPPORTED_RATES 0x0D01020E /* Q */ +#define OID_802_11_CONFIGURATION 0x0D010211 /* Q S */ +#define OID_802_11_ADD_WEP 0x0D010113 /* S */ +#define OID_802_11_WEP_STATUS 0x0D01011B /* Q S */ +#define OID_802_11_REMOVE_WEP 0x0D010114 /* S */ +#define OID_802_11_DISASSOCIATE 0x0D010115 /* S */ +#define OID_802_11_AUTHENTICATION_MODE 0x0D010118 /* Q S */ +#define OID_802_11_RELOAD_DEFAULTS 0x0D01011C /* S */ + +/* OID_GEN_MINIPORT_INFO constants */ +#define NDIS_MINIPORT_BUS_MASTER 0x00000001 +#define NDIS_MINIPORT_WDM_DRIVER 0x00000002 +#define NDIS_MINIPORT_SG_LIST 0x00000004 +#define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008 +#define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010 +#define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020 +#define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040 +#define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080 +#define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100 +#define NDIS_MINIPORT_IS_NDIS_5 0x00000200 +#define NDIS_MINIPORT_IS_CO 0x00000400 +#define NDIS_MINIPORT_DESERIALIZE 0x00000800 +#define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000 +#define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000 +#define NDIS_MINIPORT_NETBOOT_CARD 0x00004000 +#define NDIS_MINIPORT_PM_SUPPORTED 0x00008000 +#define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000 +#define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000 +#define NDIS_MINIPORT_HIDDEN 0x00040000 +#define NDIS_MINIPORT_SWENUM 0x00080000 +#define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000 +#define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000 +#define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000 +#define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000 +#define NDIS_MINIPORT_64BITS_DMA 0x01000000 + +#define NDIS_MEDIUM_802_3 0x00000000 +#define NDIS_MEDIUM_802_5 0x00000001 +#define NDIS_MEDIUM_FDDI 0x00000002 +#define NDIS_MEDIUM_WAN 0x00000003 +#define NDIS_MEDIUM_LOCAL_TALK 0x00000004 +#define NDIS_MEDIUM_DIX 0x00000005 +#define NDIS_MEDIUM_ARCENT_RAW 0x00000006 +#define NDIS_MEDIUM_ARCENT_878_2 0x00000007 +#define NDIS_MEDIUM_ATM 0x00000008 +#define NDIS_MEDIUM_WIRELESS_LAN 0x00000009 +#define NDIS_MEDIUM_IRDA 0x0000000A +#define NDIS_MEDIUM_BPC 0x0000000B +#define NDIS_MEDIUM_CO_WAN 0x0000000C +#define NDIS_MEDIUM_1394 0x0000000D + +#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 +#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 +#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 +#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 +#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 +#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 +#define NDIS_PACKET_TYPE_SMT 0x00000040 +#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 +#define NDIS_PACKET_TYPE_GROUP 0x00000100 +#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200 +#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400 +#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800 + +#define NDIS_MEDIA_STATE_CONNECTED 0x00000000 +#define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001 + +#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 +#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 +#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 +#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 +#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 +#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 +#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 +#define NDIS_MAC_OPTION_RESERVED 0x80000000 + +#endif /* _LINUX_NDIS_H */ + +/** @} */ diff --git a/class/wireless/rndis_protocol.h b/class/wireless/rndis_protocol.h new file mode 100644 index 00000000..54b4ebf6 --- /dev/null +++ b/class/wireless/rndis_protocol.h @@ -0,0 +1,302 @@ +/** + * \file rndis_protocol.h + * RNDIS Defines + * + * \author + * Colin O'Flynn + * + * \addtogroup usbstick + */ + +/* Copyright (c) 2008 Colin O'Flynn + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _RNDIS_H +#define _RNDIS_H + +/** + \addtogroup RNDIS + @{ + */ + +#include + +#define RNDIS_MAJOR_VERSION 1 +#define RNDIS_MINOR_VERSION 0 + +#define RNDIS_STATUS_SUCCESS 0X00000000 +#define RNDIS_STATUS_FAILURE 0XC0000001 +#define RNDIS_STATUS_INVALID_DATA 0XC0010015 +#define RNDIS_STATUS_NOT_SUPPORTED 0XC00000BB +#define RNDIS_STATUS_MEDIA_CONNECT 0X4001000B +#define RNDIS_STATUS_MEDIA_DISCONNECT 0X4001000C + +/* Message set for Connectionless (802.3) Devices */ +#define REMOTE_NDIS_PACKET_MSG 0x00000001 +#define REMOTE_NDIS_INITIALIZE_MSG 0X00000002 +#define REMOTE_NDIS_HALT_MSG 0X00000003 +#define REMOTE_NDIS_QUERY_MSG 0X00000004 +#define REMOTE_NDIS_SET_MSG 0X00000005 +#define REMOTE_NDIS_RESET_MSG 0X00000006 +#define REMOTE_NDIS_INDICATE_STATUS_MSG 0X00000007 +#define REMOTE_NDIS_KEEPALIVE_MSG 0X00000008 +#define REMOTE_NDIS_INITIALIZE_CMPLT 0X80000002 +#define REMOTE_NDIS_QUERY_CMPLT 0X80000004 +#define REMOTE_NDIS_SET_CMPLT 0X80000005 +#define REMOTE_NDIS_RESET_CMPLT 0X80000006 +#define REMOTE_NDIS_KEEPALIVE_CMPLT 0X80000008 + +typedef uint32_t rndis_MessageType_t; +typedef uint32_t rndis_MessageLength_t; +typedef uint32_t rndis_RequestId_t; +typedef uint32_t rndis_MajorVersion_t; +typedef uint32_t rndis_MinorVersion_t; +typedef uint32_t rndis_MaxTransferSize_t; +typedef uint32_t rndis_Status_t; + +/* Device Flags */ +#define RNDIS_DF_CONNECTIONLESS 0x00000001 +#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002 +typedef uint32_t rndis_DeviceFlags_t; + +/* Mediums */ +#define RNDIS_MEDIUM_802_3 0x00000000 +typedef uint32_t rndis_Medium_t; + +typedef uint32_t rndis_MaxPacketsPerTransfer_t; +typedef uint32_t rndis_PacketAlignmentFactor_t; +typedef uint32_t rndis_AfListOffset_t; +typedef uint32_t rndis_AfListSize_t; + +/*** Remote NDIS Generic Message type ***/ +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; +} rndis_generic_msg_t; + +/*** Remote NDIS Initialize Message ***/ +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_MajorVersion_t MajorVersion; + rndis_MinorVersion_t MinorVersion; + rndis_MaxTransferSize_t MaxTransferSize; +} rndis_initialize_msg_t; + +/* Response: */ +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_Status_t Status; + rndis_MajorVersion_t MajorVersion; + rndis_MinorVersion_t MinorVersion; + rndis_DeviceFlags_t DeviceFlags; + rndis_Medium_t Medium; + rndis_MaxPacketsPerTransfer_t MaxPacketsPerTransfer; + rndis_MaxTransferSize_t MaxTransferSize; + rndis_PacketAlignmentFactor_t PacketAlignmentFactor; + rndis_AfListOffset_t AfListOffset; + rndis_AfListSize_t AfListSize; +} rndis_initialize_cmplt_t; + +/*** Remote NDIS Halt Message ***/ +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; +} rndis_halt_msg_t; + +typedef uint32_t rndis_Oid_t; +typedef uint32_t rndis_InformationBufferLength_t; +typedef uint32_t rndis_InformationBufferOffset_t; +typedef uint32_t rndis_DeviceVcHandle_t; + +/*** Remote NDIS Query Message ***/ +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_Oid_t Oid; + rndis_InformationBufferLength_t InformationBufferLength; + rndis_InformationBufferOffset_t InformationBufferOffset; + rndis_DeviceVcHandle_t DeviceVcHandle; +} rndis_query_msg_t; + +/* Response: */ + +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_Status_t Status; + rndis_InformationBufferLength_t InformationBufferLength; + rndis_InformationBufferOffset_t InformationBufferOffset; +} rndis_query_cmplt_t; + +/*** Remote NDIS Set Message ***/ +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_Oid_t Oid; + rndis_InformationBufferLength_t InformationBufferLength; + rndis_InformationBufferOffset_t InformationBufferOffset; + rndis_DeviceVcHandle_t DeviceVcHandle; +} rndis_set_msg_t; + +/* Response */ +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_Status_t Status; +} rndis_set_cmplt_t; + +/* Information buffer layout for OID_GEN_RNDIS_CONFIG_PARAMETER */ +typedef uint32_t rndis_ParameterNameOffset_t; +typedef uint32_t rndis_ParameterNameLength_t; +typedef uint32_t rndis_ParameterType_t; +typedef uint32_t rndis_ParameterValueOffset_t; +typedef uint32_t rndis_ParameterValueLength_t; + +#define PARAMETER_TYPE_STRING 2 +#define PARAMETER_TYPE_NUMERICAL 0 + +typedef struct { + rndis_ParameterNameOffset_t ParameterNameOffset; + rndis_ParameterNameLength_t ParameterNameLength; + rndis_ParameterType_t ParameterType; + rndis_ParameterValueOffset_t ParameterValueOffset; + rndis_ParameterValueLength_t ParameterValueLength; +} rndis_config_parameter_t; + +typedef uint32_t rndis_Reserved_t; + +/*** Remote NDIS Soft Reset Message ***/ +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_Reserved_t Reserved; +} rndis_reset_msg_t; + +typedef uint32_t rndis_AddressingReset_t; + +/* Response: */ +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_Status_t Status; + rndis_AddressingReset_t AddressingReset; +} rndis_reset_cmplt_t; + +/*** Remote NDIS Indicate Status Message ***/ +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_Status_t Status; + rndis_Status_t StatusBufferLength; + rndis_Status_t StatusBufferOffset; +} rndis_indicate_status_t; + +typedef uint32_t rndis_DiagStatus_t; +typedef uint32_t rndis_ErrorOffset_t; + +typedef struct { + rndis_DiagStatus_t DiagStatus; + rndis_ErrorOffset_t ErrorOffset; +} rndis_diagnostic_info_t; + +/*** Remote NDIS Keepalive Message */ +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; +} rndis_keepalive_msg_t; + +/* Response: */ +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_RequestId_t RequestId; + rndis_Status_t Status; +} rndis_keepalive_cmplt_t; + +/*** Remote NDIS Data Packet ***/ + +typedef uint32_t rndis_DataOffset_t; +typedef uint32_t rndis_DataLength_t; +typedef uint32_t rndis_OOBDataOffset_t; +typedef uint32_t rndis_OOBDataLength_t; +typedef uint32_t rndis_NumOOBDataElements_t; +typedef uint32_t rndis_PerPacketInfoOffset_t; +typedef uint32_t rndis_PerPacketInfoLength_t; + +typedef struct { + rndis_MessageType_t MessageType; + rndis_MessageLength_t MessageLength; + rndis_DataOffset_t DataOffset; + rndis_DataLength_t DataLength; + rndis_OOBDataOffset_t OOBDataOffset; + rndis_OOBDataLength_t OOBDataLength; + rndis_NumOOBDataElements_t NumOOBDataElements; + rndis_PerPacketInfoOffset_t PerPacketInfoOffset; + rndis_PerPacketInfoLength_t PerPacketInfoLength; + rndis_DeviceVcHandle_t DeviceVcHandle; + rndis_Reserved_t Reserved; +} rndis_data_packet_t; + +typedef uint32_t rndis_ClassInformationOffset_t; +typedef uint32_t rndis_Size_t; +typedef uint32_t rndis_Type_t; + +typedef struct { + rndis_Size_t Size; + rndis_Type_t Type; + rndis_ClassInformationOffset_t ClassInformationType; +} rndis_OOB_packet_t; + +#include "ndis.h" + +typedef enum rnids_state_e { + rndis_uninitialized, + rndis_initialized, + rndis_data_initialized +} rndis_state_t; + +typedef struct { + uint32_t txok; + uint32_t rxok; + uint32_t txbad; + uint32_t rxbad; +} usb_eth_stat_t; + +#endif /* _RNDIS_H */ + +/** @} */ diff --git a/class/wireless/usbd_rndis.c b/class/wireless/usbd_rndis.c new file mode 100644 index 00000000..5c5b31e8 --- /dev/null +++ b/class/wireless/usbd_rndis.c @@ -0,0 +1,424 @@ +/** + * @file usbd_rndis.c + * @brief + * + * Copyright (c) 2022 sakumisu + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + */ +#include "usbd_core.h" +#include "usbd_rndis.h" +#include "rndis_protocol.h" + +#define RNDIS_INQUIRY_PUT(src, len) (memcpy(infomation_buffer, src, len)) +#define RNDIS_INQUIRY_PUT_LE32(value) (*(uint32_t *)infomation_buffer = (value)) + +/* Device data structure */ +struct usbd_rndis_cfg_priv { + uint32_t drv_version; + uint32_t media_status; + uint32_t speed; + uint32_t mtu; + uint32_t net_filter; + usb_eth_stat_t eth_state; + rndis_state_t init_state; + 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" }; + +/* RNDIS options list */ +const uint32_t oid_supported_list[] = { + OID_GEN_SUPPORTED_LIST, + OID_GEN_HARDWARE_STATUS, + OID_GEN_MEDIA_SUPPORTED, + OID_GEN_MEDIA_IN_USE, + OID_GEN_MAXIMUM_FRAME_SIZE, + OID_GEN_LINK_SPEED, + OID_GEN_TRANSMIT_BLOCK_SIZE, + OID_GEN_RECEIVE_BLOCK_SIZE, + OID_GEN_VENDOR_ID, + OID_GEN_VENDOR_DESCRIPTION, + OID_GEN_VENDOR_DRIVER_VERSION, + OID_GEN_CURRENT_PACKET_FILTER, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_PROTOCOL_OPTIONS, + OID_GEN_MAC_OPTIONS, + OID_GEN_MEDIA_CONNECT_STATUS, + OID_GEN_MAXIMUM_SEND_PACKETS, + OID_802_3_PERMANENT_ADDRESS, + OID_802_3_CURRENT_ADDRESS, + OID_802_3_MULTICAST_LIST, + OID_802_3_MAXIMUM_LIST_SIZE, + OID_802_3_MAC_OPTIONS +}; + +static uint8_t rndis_encapsulated_resp_buffer[CONFIG_RNDIS_RESP_BUFFER_SIZE]; + +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); +/** + * @brief Handler called for Class requests not handled by the USB stack. + * + * @param setup Information about the request to execute. + * @param len Size of the buffer. + * @param data Buffer containing the request result. + * + * @return 0 on success, negative errno code on fail. + */ +static int rndis_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) +{ + switch (setup->bRequest) { + case CDC_REQUEST_SEND_ENCAPSULATED_COMMAND: + rndis_encapsulated_cmd_handler(data, len); + break; + case CDC_REQUEST_GET_ENCAPSULATED_RESPONSE: + *data = rndis_encapsulated_resp_buffer; + *len = ((rndis_generic_msg_t *)rndis_encapsulated_resp_buffer)->MessageLength; + break; + + default: + return -1; + } +} + +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); +static int rndis_set_cmd_handler(uint8_t *data, uint32_t len); +static int rndis_reset_cmd_handler(uint8_t *data, uint32_t len); +static int rndis_keepalive_cmd_handler(uint8_t *data, uint32_t len); + +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); + break; + case REMOTE_NDIS_HALT_MSG: + rndis_halt_cmd_handler(data, len); + break; + case REMOTE_NDIS_QUERY_MSG: + rndis_query_cmd_handler(data, len); + break; + case REMOTE_NDIS_SET_MSG: + rndis_set_cmd_handler(data, len); + break; + case REMOTE_NDIS_RESET_MSG: + rndis_reset_cmd_handler(data, len); + break; + case REMOTE_NDIS_KEEPALIVE_MSG: + rndis_keepalive_cmd_handler(data, len); + break; + + default: + break; + } +} + +static int rndis_init_cmd_handler(uint8_t *data, uint32_t len) +{ + rndis_initialize_msg_t *cmd = (rndis_initialize_msg_t *)data; + rndis_initialize_cmplt_t *resp; + + resp = ((rndis_initialize_cmplt_t *)rndis_encapsulated_resp_buffer); + resp->RequestId = cmd->RequestId; + resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT; + resp->MessageLength = sizeof(rndis_initialize_cmplt_t); + resp->MajorVersion = RNDIS_MAJOR_VERSION; + resp->MinorVersion = RNDIS_MINOR_VERSION; + resp->Status = RNDIS_STATUS_SUCCESS; + resp->DeviceFlags = RNDIS_DF_CONNECTIONLESS; + resp->Medium = RNDIS_MEDIUM_802_3; + resp->MaxPacketsPerTransfer = 1; + resp->MaxTransferSize = usbd_rndis_cfg.mtu + ETH_HEADER_SIZE + sizeof(rndis_data_packet_t); + resp->PacketAlignmentFactor = 0; + resp->AfListOffset = 0; + resp->AfListSize = 0; + + usbd_rndis_cfg.init_state = rndis_initialized; + + rndis_notify_rsp(); + return 0; +} + +static int rndis_halt_cmd_handler(uint8_t *data, uint32_t len) +{ + usbd_rndis_cfg.init_state = rndis_uninitialized; + + return 0; +} + +static int rndis_query_cmd_handler(uint8_t *data, uint32_t len) +{ + rndis_query_msg_t *cmd = (rndis_initialize_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->MessageType = REMOTE_NDIS_QUERY_CMPLT; + resp->InformationBufferOffset = 16; + + infomation_buffer = (uint8_t *)resp + sizeof(rndis_initialize_cmplt_t); + + switch (cmd->Oid) { + case OID_GEN_SUPPORTED_LIST: + RNDIS_INQUIRY_PUT(oid_supported_list, sizeof(oid_supported_list)); + infomation_len = sizeof(oid_supported_list); + break; + case OID_GEN_VENDOR_DRIVER_VERSION: + RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.drv_version); + infomation_len = 4; + break; + case OID_802_3_CURRENT_ADDRESS: + RNDIS_INQUIRY_PUT(usbd_rndis_cfg.mac, 6); + infomation_len = 6; + break; + case OID_802_3_PERMANENT_ADDRESS: + RNDIS_INQUIRY_PUT(usbd_rndis_cfg.mac, 6); + infomation_len = 6; + break; + case OID_GEN_MEDIA_SUPPORTED: + RNDIS_INQUIRY_PUT_LE32(NDIS_MEDIUM_802_3); + infomation_len = 4; + break; + case OID_GEN_MEDIA_IN_USE: + RNDIS_INQUIRY_PUT_LE32(NDIS_MEDIUM_802_3); + infomation_len = 4; + break; + case OID_GEN_PHYSICAL_MEDIUM: + RNDIS_INQUIRY_PUT_LE32(NDIS_MEDIUM_802_3); + infomation_len = 4; + break; + case OID_GEN_HARDWARE_STATUS: + RNDIS_INQUIRY_PUT_LE32(0); + infomation_len = 4; + break; + case OID_GEN_LINK_SPEED: + RNDIS_INQUIRY_PUT_LE32(RNDIS_LINK_SPEED / 100); + infomation_len = 4; + break; + case OID_GEN_VENDOR_ID: + RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.vendor_id); + infomation_len = 4; + break; + case OID_GEN_VENDOR_DESCRIPTION: + RNDIS_INQUIRY_PUT(usbd_rndis_cfg.vendor_desc, strlen(usbd_rndis_cfg.vendor_desc) + 1); + infomation_len = (strlen(usbd_rndis_cfg.vendor_desc) + 1); + break; + case OID_GEN_CURRENT_PACKET_FILTER: + RNDIS_INQUIRY_PUT_LE32(0x00FFFFFF); + infomation_len = 4; + break; + case OID_GEN_MAXIMUM_FRAME_SIZE: + RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.mtu); + infomation_len = 4; + break; + 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)); + infomation_len = 4; + break; + case OID_GEN_MEDIA_CONNECT_STATUS: + RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.media_status); + infomation_len = 4; + break; + case OID_GEN_RNDIS_CONFIG_PARAMETER: + RNDIS_INQUIRY_PUT_LE32(0); + infomation_len = 4; + break; + case OID_802_3_MAXIMUM_LIST_SIZE: + RNDIS_INQUIRY_PUT_LE32(1); /* one address */ + infomation_len = 4; + break; + case OID_802_3_MULTICAST_LIST: + RNDIS_INQUIRY_PUT_LE32(0xE0000000); /* 224.0.0.0 */ + infomation_len = 4; + break; + case OID_802_3_MAC_OPTIONS: + infomation_len = 0; + break; + case OID_GEN_MAC_OPTIONS: + RNDIS_INQUIRY_PUT_LE32(0); + infomation_len = 4; + break; + case OID_802_3_RCV_ERROR_ALIGNMENT: + RNDIS_INQUIRY_PUT_LE32(0); + infomation_len = 4; + break; + case OID_802_3_XMIT_ONE_COLLISION: + RNDIS_INQUIRY_PUT_LE32(0); + infomation_len = 4; + break; + case OID_802_3_XMIT_MORE_COLLISIONS: + RNDIS_INQUIRY_PUT_LE32(0); + infomation_len = 4; + break; + case OID_GEN_XMIT_OK: + RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.eth_state.txok); + infomation_len = 4; + break; + case OID_GEN_RCV_OK: + RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.eth_state.rxok); + infomation_len = 4; + break; + case OID_GEN_RCV_ERROR: + RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.eth_state.rxbad); + infomation_len = 4; + break; + case OID_GEN_XMIT_ERROR: + RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.eth_state.txbad); + infomation_len = 4; + break; + case OID_GEN_RCV_NO_BUFFER: + RNDIS_INQUIRY_PUT_LE32(0); + infomation_len = 4; + break; + default: + resp->Status = RNDIS_STATUS_NOT_SUPPORTED; + USB_LOG_WRN("Unhandled query for Object ID 0x%x\r\n", cmd->Oid); + break; + } + + resp->MessageLength = sizeof(rndis_query_cmplt_t) + infomation_len; + resp->InformationBufferLength = infomation_len; + + rndis_notify_rsp(); + return 0; +} + +static int rndis_set_cmd_handler(uint8_t *data, uint32_t len) +{ + rndis_set_msg_t *cmd = (rndis_set_msg_t *)data; + rndis_set_cmplt_t *resp; + rndis_config_parameter_t *param; + + resp = ((rndis_set_cmplt_t *)rndis_encapsulated_resp_buffer); + resp->RequestId = cmd->RequestId; + resp->MessageType = REMOTE_NDIS_SET_CMPLT; + resp->MessageLength = sizeof(rndis_set_cmplt_t); + resp->Status = RNDIS_STATUS_SUCCESS; + + switch (cmd->Oid) { + case OID_GEN_RNDIS_CONFIG_PARAMETER: + break; + case OID_GEN_CURRENT_PACKET_FILTER: + if (cmd->InformationBufferLength < sizeof(usbd_rndis_cfg.net_filter)) { + resp->Status = RNDIS_STATUS_INVALID_DATA; + } else { + /* Parameter starts at offset buf_offset of the req_id field */ + param = (rndis_config_parameter_t *)((uint8_t *)&cmd->RequestId + cmd->InformationBufferOffset); + + //usbd_rndis_cfg.net_filter = param->ParameterNameOffset; + } + break; + case OID_GEN_CURRENT_LOOKAHEAD: + break; + case OID_GEN_PROTOCOL_OPTIONS: + break; + case OID_802_3_MULTICAST_LIST: + break; + case OID_PNP_ADD_WAKE_UP_PATTERN: + case OID_PNP_REMOVE_WAKE_UP_PATTERN: + case OID_PNP_ENABLE_WAKE_UP: + default: + resp->Status = RNDIS_STATUS_FAILURE; + break; + } + + rndis_notify_rsp(); + + return 0; +} + +static int rndis_reset_cmd_handler(uint8_t *data, uint32_t len) +{ + rndis_reset_msg_t *cmd = (rndis_reset_msg_t *)data; + rndis_reset_cmplt_t *resp; + + resp = ((rndis_reset_cmplt_t *)rndis_encapsulated_resp_buffer); + resp->MessageType = REMOTE_NDIS_RESET_CMPLT; + resp->MessageLength = sizeof(rndis_reset_cmplt_t); + resp->Status = RNDIS_STATUS_SUCCESS; + resp->AddressingReset = 1; + + rndis_notify_rsp(); + + return 0; +} + +static int rndis_keepalive_cmd_handler(uint8_t *data, uint32_t len) +{ + rndis_keepalive_msg_t *cmd = (rndis_keepalive_msg_t *)data; + rndis_keepalive_cmplt_t *resp; + + resp = ((rndis_keepalive_cmplt_t *)rndis_encapsulated_resp_buffer); + resp->RequestId = cmd->RequestId; + resp->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT; + resp->MessageLength = sizeof(rndis_keepalive_cmplt_t); + resp->Status = RNDIS_STATUS_SUCCESS; + + rndis_notify_rsp(); + + return 0; +} + +static void rndis_notify_handler(uint8_t event, void *arg) +{ + switch (event) { + case USBD_EVENT_RESET: + + break; + + default: + break; + } +} + +void usbd_rndis_add_interface(usbd_class_t *devclass, usbd_interface_t *intf) +{ + static usbd_class_t *last_class = NULL; + + if (last_class != devclass) { + last_class = devclass; + usbd_class_register(devclass); + } + + intf->class_handler = rndis_class_request_handler; + intf->custom_handler = NULL; + intf->vendor_handler = NULL; + intf->notify_handler = rndis_notify_handler; + usbd_class_add_interface(devclass, intf); +} diff --git a/class/wireless/usbd_rndis.h b/class/wireless/usbd_rndis.h new file mode 100644 index 00000000..731c0de0 --- /dev/null +++ b/class/wireless/usbd_rndis.h @@ -0,0 +1,49 @@ +/** + * @file usbd_rndis.h + * @brief + * + * Copyright (c) 2022 sakumisu + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _USBD_RNDIS_H_ +#define _USBD_RNDIS_H_ + +#include "usb_cdc.h" + +#define ETH_HEADER_SIZE 14 +#define RNDIS_MTU 1500 /* MTU value */ + +#ifdef 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) */ +#endif + +#define CONFIG_RNDIS_RESP_BUFFER_SIZE 128 + +#ifdef __cplusplus +extern "C" { +#endif + +void usbd_rndis_add_interface(usbd_class_t *devclass, usbd_interface_t *intf); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file