Commit of new class abstraction APIs for all device demos other than the MIDI demo - not documented yet.
Removed scheduler and memory allocation libraries. Added new EVENT_USB_StartOfFrame event in the library to indicate the start of each USB frame (when generated). Removed Tx interrupt from the USBtoSerial demo; now sends characters via polling to ensure more time for the Rx interrupt.
This commit is contained in:
parent
2440ca268a
commit
d1e5266036
106 changed files with 3072 additions and 5760 deletions
|
|
@ -38,9 +38,7 @@
|
|||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <LUFA/Scheduler/Scheduler.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
|
|
|
|||
|
|
@ -38,12 +38,6 @@
|
|||
#include "Ethernet.h"
|
||||
|
||||
/* Global Variables: */
|
||||
/** Ethernet Frame buffer structure, to hold the incoming Ethernet frame from the host. */
|
||||
Ethernet_Frame_Info_t FrameIN;
|
||||
|
||||
/** Ethernet Frame buffer structure, to hold the outgoing Ethernet frame to the host. */
|
||||
Ethernet_Frame_Info_t FrameOUT;
|
||||
|
||||
/** Constant for convenience when checking against or setting a MAC address to the virtual server MAC address. */
|
||||
const MAC_Address_t ServerMACAddress = {SERVER_MAC_ADDRESS};
|
||||
|
||||
|
|
@ -63,31 +57,31 @@ const IP_Address_t ClientIPAddress = {CLIENT_IP_ADDRESS};
|
|||
/** Processes an incoming Ethernet frame, and writes the appropriate response to the output Ethernet
|
||||
* frame buffer if the sub protocol handlers create a valid response.
|
||||
*/
|
||||
void Ethernet_ProcessPacket(void)
|
||||
void Ethernet_ProcessPacket(Ethernet_Frame_Info_t* FrameIN, Ethernet_Frame_Info_t* FrameOUT)
|
||||
{
|
||||
DecodeEthernetFrameHeader(FrameIN.FrameData);
|
||||
DecodeEthernetFrameHeader(FrameIN->FrameData);
|
||||
|
||||
/* Cast the incoming Ethernet frame to the Ethernet header type */
|
||||
Ethernet_Frame_Header_t* FrameINHeader = (Ethernet_Frame_Header_t*)&FrameIN.FrameData;
|
||||
Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;
|
||||
Ethernet_Frame_Header_t* FrameINHeader = (Ethernet_Frame_Header_t*)&FrameIN->FrameData;
|
||||
Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT->FrameData;
|
||||
|
||||
int16_t RetSize = NO_RESPONSE;
|
||||
|
||||
/* Ensure frame is addressed to either all (broadcast) or the virtual webserver, and is a type II frame */
|
||||
if ((MAC_COMPARE(&FrameINHeader->Destination, &ServerMACAddress) ||
|
||||
MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)) &&
|
||||
(SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE))
|
||||
MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)))
|
||||
{
|
||||
/* Process the packet depending on its protocol */
|
||||
switch (SwapEndian_16(FrameINHeader->EtherType))
|
||||
{
|
||||
case ETHERTYPE_ARP:
|
||||
RetSize = ARP_ProcessARPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],
|
||||
&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);
|
||||
RetSize = ARP_ProcessARPPacket(&FrameIN->FrameData[sizeof(Ethernet_Frame_Header_t)],
|
||||
&FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t)]);
|
||||
break;
|
||||
case ETHERTYPE_IPV4:
|
||||
RetSize = IP_ProcessIPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],
|
||||
&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);
|
||||
RetSize = IP_ProcessIPPacket(FrameIN,
|
||||
&FrameIN->FrameData[sizeof(Ethernet_Frame_Header_t)],
|
||||
&FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t)]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -100,8 +94,8 @@ void Ethernet_ProcessPacket(void)
|
|||
FrameOUTHeader->EtherType = FrameINHeader->EtherType;
|
||||
|
||||
/* Set the response length in the buffer and indicate that a response is ready to be sent */
|
||||
FrameOUT.FrameLength = (sizeof(Ethernet_Frame_Header_t) + RetSize);
|
||||
FrameOUT.FrameInBuffer = true;
|
||||
FrameOUT->FrameLength = (sizeof(Ethernet_Frame_Header_t) + RetSize);
|
||||
FrameOUT->FrameInBuffer = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +103,7 @@ void Ethernet_ProcessPacket(void)
|
|||
if (RetSize != NO_PROCESS)
|
||||
{
|
||||
/* Clear the frame buffer */
|
||||
FrameIN.FrameInBuffer = false;
|
||||
FrameIN->FrameInBuffer = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/Class/Device/RNDIS.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
|
|
@ -50,6 +52,9 @@
|
|||
#include "IP.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Physical MAC address of the USB RNDIS network adapter */
|
||||
#define ADAPTER_MAC_ADDRESS {0x00, 0x02, 0x00, 0x02, 0x00, 0x02}
|
||||
|
||||
/** Physical MAC address of the virtual server on the network */
|
||||
#define SERVER_MAC_ADDRESS {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}
|
||||
|
||||
|
|
@ -64,12 +69,6 @@
|
|||
* \return True if the addresses match, false otherwise
|
||||
*/
|
||||
#define MAC_COMPARE(MAC1, MAC2) (memcmp(MAC1, MAC2, sizeof(MAC_Address_t)) == 0)
|
||||
|
||||
/** Maximum size of an incoming or outgoing Ethernet frame in bytes */
|
||||
#define ETHERNET_FRAME_SIZE_MAX 1500
|
||||
|
||||
/** Minimum size of an Ethernet packet in bytes, to conform to the Ethernet V2 packet standard */
|
||||
#define ETHERNET_VER2_MINSIZE 0x0600
|
||||
|
||||
/** Return value for all sub protocol handling routines, indicating that no response packet has been generated */
|
||||
#define NO_RESPONSE 0
|
||||
|
|
@ -78,14 +77,6 @@
|
|||
#define NO_PROCESS -1
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for an Ethernet frame buffer. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */
|
||||
uint16_t FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */
|
||||
bool FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */
|
||||
} Ethernet_Frame_Info_t;
|
||||
|
||||
/** Type define for an Ethernet frame header */
|
||||
typedef struct
|
||||
{
|
||||
|
|
@ -100,9 +91,6 @@
|
|||
} Ethernet_Frame_Header_t;
|
||||
|
||||
/* External Variables: */
|
||||
extern Ethernet_Frame_Info_t FrameIN;
|
||||
extern Ethernet_Frame_Info_t FrameOUT;
|
||||
|
||||
extern const MAC_Address_t ServerMACAddress;
|
||||
extern const IP_Address_t ServerIPAddress;
|
||||
extern const MAC_Address_t BroadcastMACAddress;
|
||||
|
|
@ -110,7 +98,7 @@
|
|||
extern const IP_Address_t ClientIPAddress;
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Ethernet_ProcessPacket(void);
|
||||
void Ethernet_ProcessPacket(Ethernet_Frame_Info_t* FrameIN, Ethernet_Frame_Info_t* FrameOUT);
|
||||
uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -71,13 +71,7 @@
|
|||
#define PROTOCOL_OSPF 89
|
||||
#define PROTOCOL_SCTP 132
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a physical MAC address of a device on a network */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Octets[6]; /**< Individual bytes of a MAC address */
|
||||
} MAC_Address_t;
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a protocol IP address of a device on a network */
|
||||
typedef struct
|
||||
{
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
*
|
||||
* \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise
|
||||
*/
|
||||
int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart)
|
||||
int16_t ICMP_ProcessICMPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart)
|
||||
{
|
||||
ICMP_Header_t* ICMPHeaderIN = (ICMP_Header_t*)InDataStart;
|
||||
ICMP_Header_t* ICMPHeaderOUT = (ICMP_Header_t*)OutDataStart;
|
||||
|
|
@ -62,7 +62,7 @@ int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart)
|
|||
ICMPHeaderOUT->Id = ICMPHeaderIN->Id;
|
||||
ICMPHeaderOUT->Sequence = ICMPHeaderIN->Sequence;
|
||||
|
||||
uint16_t DataSize = FrameIN.FrameLength - ((((uint16_t)InDataStart + sizeof(ICMP_Header_t)) - (uint16_t)FrameIN.FrameData));
|
||||
uint16_t DataSize = FrameIN->FrameLength - ((((uint16_t)InDataStart + sizeof(ICMP_Header_t)) - (uint16_t)FrameIN->FrameData));
|
||||
|
||||
/* Copy the remaining payload to the response - echo requests should echo back any sent data */
|
||||
memcpy(&((uint8_t*)OutDataStart)[sizeof(ICMP_Header_t)],
|
||||
|
|
|
|||
|
|
@ -75,6 +75,6 @@
|
|||
} ICMP_Header_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart);
|
||||
int16_t ICMP_ProcessICMPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
* response was generated, NO_PROCESS if the packet processing was deferred until the
|
||||
* next Ethernet packet handler iteration
|
||||
*/
|
||||
int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart)
|
||||
int16_t IP_ProcessIPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart)
|
||||
{
|
||||
DecodeIPHeader(InDataStart);
|
||||
|
||||
|
|
@ -69,7 +69,8 @@ int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart)
|
|||
switch (IPHeaderIN->Protocol)
|
||||
{
|
||||
case PROTOCOL_ICMP:
|
||||
RetSize = ICMP_ProcessICMPPacket(&((uint8_t*)InDataStart)[HeaderLengthBytes],
|
||||
RetSize = ICMP_ProcessICMPPacket(FrameIN,
|
||||
&((uint8_t*)InDataStart)[HeaderLengthBytes],
|
||||
&((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);
|
||||
break;
|
||||
case PROTOCOL_TCP:
|
||||
|
|
|
|||
|
|
@ -88,6 +88,6 @@
|
|||
} IP_Header_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart);
|
||||
int16_t IP_ProcessIPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,394 +0,0 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* RNDIS command handler functions. This handles RNDIS commands according to
|
||||
* the Microsoft RNDIS specification, creating a USB Ethernet network adapter.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_RNDIS_C
|
||||
#include "RNDIS.h"
|
||||
|
||||
/* Global Variables: */
|
||||
/** Physical MAC address of the network adapter, which becomes the MAC address of the host for packets sent to the adapter. */
|
||||
static MAC_Address_t PROGMEM AdapterMACAddress = {ADAPTER_MAC_ADDRESS};
|
||||
|
||||
/** Vendor description of the adapter. This is overridden by the INF file required to install the appropriate RNDIS drivers for
|
||||
* the device, but may still be used by the OS in some circumstances.
|
||||
*/
|
||||
static char PROGMEM AdapterVendorDescription[] = "LUFA RNDIS Adapter";
|
||||
|
||||
/** List of RNDIS OID commands supported by this adapter. */
|
||||
static const uint32_t PROGMEM AdapterSupportedOIDList[] =
|
||||
{
|
||||
OID_GEN_SUPPORTED_LIST,
|
||||
OID_GEN_PHYSICAL_MEDIUM,
|
||||
OID_GEN_HARDWARE_STATUS,
|
||||
OID_GEN_MEDIA_SUPPORTED,
|
||||
OID_GEN_MEDIA_IN_USE,
|
||||
OID_GEN_MAXIMUM_FRAME_SIZE,
|
||||
OID_GEN_MAXIMUM_TOTAL_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_CURRENT_PACKET_FILTER,
|
||||
OID_GEN_MAXIMUM_TOTAL_SIZE,
|
||||
OID_GEN_MEDIA_CONNECT_STATUS,
|
||||
OID_GEN_XMIT_OK,
|
||||
OID_GEN_RCV_OK,
|
||||
OID_GEN_XMIT_ERROR,
|
||||
OID_GEN_RCV_ERROR,
|
||||
OID_GEN_RCV_NO_BUFFER,
|
||||
OID_802_3_PERMANENT_ADDRESS,
|
||||
OID_802_3_CURRENT_ADDRESS,
|
||||
OID_802_3_MULTICAST_LIST,
|
||||
OID_802_3_MAXIMUM_LIST_SIZE,
|
||||
OID_802_3_RCV_ERROR_ALIGNMENT,
|
||||
OID_802_3_XMIT_ONE_COLLISION,
|
||||
OID_802_3_XMIT_MORE_COLLISIONS,
|
||||
};
|
||||
|
||||
/** Buffer for RNDIS messages (as distinct from Ethernet frames sent through the adapter. This must be big enough to hold the entire
|
||||
* Supported OID list, plus the response header. The buffer is half-duplex, and is written to as it is read to save on SRAM - for this
|
||||
* reason, care must be taken when constructing RNDIS responses that unread data is not overwritten when writing in responses.
|
||||
*/
|
||||
uint8_t RNDISMessageBuffer[sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_QUERY_CMPLT_t)];
|
||||
|
||||
/** Pointer to the RNDIS message header at the top of the RNDIS message buffer, for convenience. */
|
||||
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISMessageBuffer;
|
||||
|
||||
/** Indicates if a RNDIS message response is ready to be sent back to the host. */
|
||||
bool ResponseReady = false;
|
||||
|
||||
/** Current RNDIS adapter state, a value from the RNDIS_States_t enum. */
|
||||
uint8_t CurrRNDISState = RNDIS_Uninitialized;
|
||||
|
||||
/** Current Ethernet packet filter mask. This is non-zero when the adapter is initialized, or zero when disabled. */
|
||||
uint32_t CurrPacketFilter = 0;
|
||||
|
||||
|
||||
/** Processes the RNDIS message received by the host and stored in the RNDISMessageBuffer global buffer. If a response is
|
||||
* created, the ResponseReady global is updated so that the response is written back to the host upon request.
|
||||
*/
|
||||
void ProcessRNDISControlMessage(void)
|
||||
{
|
||||
/* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
|
||||
this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
|
||||
|
||||
switch (MessageHeader->MessageType)
|
||||
{
|
||||
case REMOTE_NDIS_INITIALIZE_MSG:
|
||||
/* Initialize the adapter - return information about the supported RNDIS version and buffer sizes */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_INITIALIZE_MSG_t* INITIALIZE_Message = (RNDIS_INITIALIZE_MSG_t*)&RNDISMessageBuffer;
|
||||
RNDIS_INITIALIZE_CMPLT_t* INITIALIZE_Response = (RNDIS_INITIALIZE_CMPLT_t*)&RNDISMessageBuffer;
|
||||
|
||||
INITIALIZE_Response->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
|
||||
INITIALIZE_Response->MessageLength = sizeof(RNDIS_INITIALIZE_CMPLT_t);
|
||||
INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId;
|
||||
INITIALIZE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
|
||||
INITIALIZE_Response->MajorVersion = REMOTE_NDIS_VERSION_MAJOR;
|
||||
INITIALIZE_Response->MinorVersion = REMOTE_NDIS_VERSION_MINOR;
|
||||
INITIALIZE_Response->DeviceFlags = REMOTE_NDIS_DF_CONNECTIONLESS;
|
||||
INITIALIZE_Response->Medium = REMOTE_NDIS_MEDIUM_802_3;
|
||||
INITIALIZE_Response->MaxPacketsPerTransfer = 1;
|
||||
INITIALIZE_Response->MaxTransferSize = (sizeof(RNDIS_PACKET_MSG_t) + ETHERNET_FRAME_SIZE_MAX);
|
||||
INITIALIZE_Response->PacketAlignmentFactor = 0;
|
||||
INITIALIZE_Response->AFListOffset = 0;
|
||||
INITIALIZE_Response->AFListSize = 0;
|
||||
|
||||
CurrRNDISState = RNDIS_Initialized;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_HALT_MSG:
|
||||
/* Halt the adapter, reset the adapter state - note that no response should be returned when completed */
|
||||
|
||||
ResponseReady = false;
|
||||
MessageHeader->MessageLength = 0;
|
||||
|
||||
CurrRNDISState = RNDIS_Uninitialized;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_QUERY_MSG:
|
||||
/* Request for information about a parameter about the adapter, specified as an OID token */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_QUERY_MSG_t* QUERY_Message = (RNDIS_QUERY_MSG_t*)&RNDISMessageBuffer;
|
||||
RNDIS_QUERY_CMPLT_t* QUERY_Response = (RNDIS_QUERY_CMPLT_t*)&RNDISMessageBuffer;
|
||||
uint32_t Query_Oid = QUERY_Message->Oid;
|
||||
|
||||
void* QueryData = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
|
||||
QUERY_Message->InformationBufferOffset];
|
||||
void* ResponseData = &RNDISMessageBuffer[sizeof(RNDIS_QUERY_CMPLT_t)];
|
||||
uint16_t ResponseSize;
|
||||
|
||||
QUERY_Response->MessageType = REMOTE_NDIS_QUERY_CMPLT;
|
||||
QUERY_Response->MessageLength = sizeof(RNDIS_QUERY_CMPLT_t);
|
||||
|
||||
if (ProcessNDISQuery(Query_Oid, QueryData, QUERY_Message->InformationBufferLength,
|
||||
ResponseData, &ResponseSize))
|
||||
{
|
||||
QUERY_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
QUERY_Response->MessageLength += ResponseSize;
|
||||
|
||||
QUERY_Response->InformationBufferLength = ResponseSize;
|
||||
QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_QUERY_CMPLT_t) - sizeof(RNDIS_Message_Header_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
QUERY_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
|
||||
|
||||
QUERY_Response->InformationBufferLength = 0;
|
||||
QUERY_Response->InformationBufferOffset = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_SET_MSG:
|
||||
/* Request to set a parameter of the adapter, specified as an OID token */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_SET_MSG_t* SET_Message = (RNDIS_SET_MSG_t*)&RNDISMessageBuffer;
|
||||
RNDIS_SET_CMPLT_t* SET_Response = (RNDIS_SET_CMPLT_t*)&RNDISMessageBuffer;
|
||||
uint32_t SET_Oid = SET_Message->Oid;
|
||||
|
||||
SET_Response->MessageType = REMOTE_NDIS_SET_CMPLT;
|
||||
SET_Response->MessageLength = sizeof(RNDIS_SET_CMPLT_t);
|
||||
SET_Response->RequestId = SET_Message->RequestId;
|
||||
|
||||
void* SetData = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
|
||||
SET_Message->InformationBufferOffset];
|
||||
|
||||
if (ProcessNDISSet(SET_Oid, SetData, SET_Message->InformationBufferLength))
|
||||
SET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
else
|
||||
SET_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_RESET_MSG:
|
||||
/* Soft reset the adapter */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISMessageBuffer;
|
||||
|
||||
RESET_Response->MessageType = REMOTE_NDIS_RESET_CMPLT;
|
||||
RESET_Response->MessageLength = sizeof(RNDIS_RESET_CMPLT_t);
|
||||
RESET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
RESET_Response->AddressingReset = 0;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_KEEPALIVE_MSG:
|
||||
/* Keep alive message sent to the adapter every 5 seconds when idle to ensure it is still responding */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_KEEPALIVE_MSG_t* KEEPALIVE_Message = (RNDIS_KEEPALIVE_MSG_t*)&RNDISMessageBuffer;
|
||||
RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISMessageBuffer;
|
||||
|
||||
KEEPALIVE_Response->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
|
||||
KEEPALIVE_Response->MessageLength = sizeof(RNDIS_KEEPALIVE_CMPLT_t);
|
||||
KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
|
||||
KEEPALIVE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Processes RNDIS query commands, retrieving information from the adapter and reporting it back to the host. The requested
|
||||
* parameter is given as an OID value.
|
||||
*
|
||||
* \param OId OId value of the parameter being queried
|
||||
* \param QueryData Pointer to any extra query data being sent by the host to the device inside the RNDIS message buffer
|
||||
* \param QuerySize Size in bytes of the extra query data being sent by the host
|
||||
* \param ResponseData Pointer to the start of the query response inside the RNDIS message buffer
|
||||
* \param ResponseSize Pointer to the size in bytes of the response data being sent to the host
|
||||
*
|
||||
* \return Boolean true if the query was handled, false otherwise
|
||||
*/
|
||||
static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,
|
||||
void* ResponseData, uint16_t* ResponseSize)
|
||||
{
|
||||
/* Handler for REMOTE_NDIS_QUERY_MSG messages */
|
||||
|
||||
switch (OId)
|
||||
{
|
||||
case OID_GEN_SUPPORTED_LIST:
|
||||
*ResponseSize = sizeof(AdapterSupportedOIDList);
|
||||
|
||||
/* Copy the list of supported NDIS OID tokens to the response buffer */
|
||||
memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
|
||||
|
||||
return true;
|
||||
case OID_GEN_PHYSICAL_MEDIUM:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate that the device is a true ethernet link */
|
||||
*((uint32_t*)ResponseData) = 0;
|
||||
|
||||
return true;
|
||||
case OID_GEN_HARDWARE_STATUS:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Always indicate hardware ready */
|
||||
*((uint32_t*)ResponseData) = NdisHardwareStatusReady;
|
||||
|
||||
return true;
|
||||
case OID_GEN_MEDIA_SUPPORTED:
|
||||
case OID_GEN_MEDIA_IN_USE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate 802.3 (Ethernet) supported by the adapter */
|
||||
*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;
|
||||
|
||||
return true;
|
||||
case OID_GEN_VENDOR_ID:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
|
||||
*((uint32_t*)ResponseData) = 0x00FFFFFF;
|
||||
|
||||
return true;
|
||||
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
||||
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
||||
case OID_GEN_RECEIVE_BLOCK_SIZE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate that the maximum frame size is the size of the ethernet frame buffer */
|
||||
*((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;
|
||||
|
||||
return true;
|
||||
case OID_GEN_VENDOR_DESCRIPTION:
|
||||
*ResponseSize = sizeof(AdapterVendorDescription);
|
||||
|
||||
/* Copy vendor description string to the response buffer */
|
||||
memcpy_P(ResponseData, AdapterVendorDescription, sizeof(AdapterVendorDescription));
|
||||
|
||||
return true;
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Always indicate that the adapter is connected to a network */
|
||||
*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;
|
||||
|
||||
return true;
|
||||
case OID_GEN_LINK_SPEED:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate 10Mb/s link speed */
|
||||
*((uint32_t*)ResponseData) = 100000;
|
||||
|
||||
return true;
|
||||
case OID_802_3_PERMANENT_ADDRESS:
|
||||
case OID_802_3_CURRENT_ADDRESS:
|
||||
*ResponseSize = sizeof(MAC_Address_t);
|
||||
|
||||
/* Copy over the fixed adapter MAC to the response buffer */
|
||||
memcpy_P(ResponseData, &AdapterMACAddress, sizeof(MAC_Address_t));
|
||||
|
||||
return true;
|
||||
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate only one multicast address supported */
|
||||
*((uint32_t*)ResponseData) = 1;
|
||||
|
||||
return true;
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate the current packet filter mask */
|
||||
*((uint32_t*)ResponseData) = CurrPacketFilter;
|
||||
|
||||
return true;
|
||||
case OID_GEN_XMIT_OK:
|
||||
case OID_GEN_RCV_OK:
|
||||
case OID_GEN_XMIT_ERROR:
|
||||
case OID_GEN_RCV_ERROR:
|
||||
case OID_GEN_RCV_NO_BUFFER:
|
||||
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
||||
case OID_802_3_XMIT_ONE_COLLISION:
|
||||
case OID_802_3_XMIT_MORE_COLLISIONS:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Unused statistic OIDs - always return 0 for each */
|
||||
*((uint32_t*)ResponseData) = 0;
|
||||
|
||||
return true;
|
||||
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
|
||||
*((uint32_t*)ResponseData) = (sizeof(RNDISMessageBuffer) + ETHERNET_FRAME_SIZE_MAX);
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Processes RNDIS set commands, setting adapter parameters to values given by the host. The requested parameter is given
|
||||
* as an OID value.
|
||||
*
|
||||
* \param OId OId value of the parameter being set
|
||||
* \param SetData Pointer to the parameter value in the RNDIS message buffer
|
||||
* \param SetSize Size in bytes of the parameter value being sent by the host
|
||||
*
|
||||
* \return Boolean true if the set was handled, false otherwise
|
||||
*/
|
||||
static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize)
|
||||
{
|
||||
/* Handler for REMOTE_NDIS_SET_MSG messages */
|
||||
|
||||
switch (OId)
|
||||
{
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
/* Save the packet filter mask in case the host queries it again later */
|
||||
CurrPacketFilter = *((uint32_t*)SetData);
|
||||
|
||||
/* Set the RNDIS state to initialized if the packet filter is non-zero */
|
||||
CurrRNDISState = ((CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Data_Initialized);
|
||||
|
||||
return true;
|
||||
case OID_802_3_MULTICAST_LIST:
|
||||
/* Do nothing - throw away the value from the host as it is unused */
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,226 +0,0 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for RNDIS.c.
|
||||
*/
|
||||
|
||||
#ifndef _RNDIS_H_
|
||||
#define _RNDIS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "RNDISEthernet.h"
|
||||
#include "RNDISConstants.h"
|
||||
#include "Ethernet.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Physical MAC Address of the USB network adapter */
|
||||
#define ADAPTER_MAC_ADDRESS {0x02, 0x00, 0x02, 0x00, 0x02, 0x00}
|
||||
|
||||
/** Implemented RNDIS Version Major */
|
||||
#define REMOTE_NDIS_VERSION_MAJOR 0x01
|
||||
|
||||
/** Implemented RNDIS Version Minor */
|
||||
#define REMOTE_NDIS_VERSION_MINOR 0x00
|
||||
|
||||
/** RNDIS request to issue a host-to-device NDIS command */
|
||||
#define REQ_SendEncapsulatedCommand 0x00
|
||||
|
||||
/** RNDIS request to issue a device-to-host NDIS response */
|
||||
#define REQ_GetEncapsulatedResponse 0x01
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible NDIS adapter states. */
|
||||
enum RNDIS_States_t
|
||||
{
|
||||
RNDIS_Uninitialized = 0, /**< Adapter currently uninitialized */
|
||||
RNDIS_Initialized = 1, /**< Adapter currently initialized but not ready for data transfers */
|
||||
RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers */
|
||||
};
|
||||
|
||||
/** Enum for the NDIS hardware states */
|
||||
enum NDIS_Hardware_Status_t
|
||||
{
|
||||
NdisHardwareStatusReady, /**< Hardware Ready to accept commands from the host */
|
||||
NdisHardwareStatusInitializing, /**< Hardware busy initializing */
|
||||
NdisHardwareStatusReset, /**< Hardware reset */
|
||||
NdisHardwareStatusClosing, /**< Hardware currently closing */
|
||||
NdisHardwareStatusNotReady /**< Hardware not ready to accept commands from the host */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a RNDIS message header, sent before RNDIS messages */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType; /**< RNDIS message type, a REMOTE_NDIS_*_MSG constant */
|
||||
uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */
|
||||
} RNDIS_Message_Header_t;
|
||||
|
||||
/** Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t DataOffset;
|
||||
uint32_t DataLength;
|
||||
uint32_t OOBDataOffset;
|
||||
uint32_t OOBDataLength;
|
||||
uint32_t NumOOBDataElements;
|
||||
uint32_t PerPacketInfoOffset;
|
||||
uint32_t PerPacketInfoLength;
|
||||
uint32_t VcHandle;
|
||||
uint32_t Reserved;
|
||||
} RNDIS_PACKET_MSG_t;
|
||||
|
||||
/** Type define for a RNDIS Initialize command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
|
||||
uint32_t MajorVersion;
|
||||
uint32_t MinorVersion;
|
||||
uint32_t MaxTransferSize;
|
||||
} RNDIS_INITIALIZE_MSG_t;
|
||||
|
||||
/** Type define for a RNDIS Initialize complete response message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
|
||||
uint32_t MajorVersion;
|
||||
uint32_t MinorVersion;
|
||||
uint32_t DeviceFlags;
|
||||
uint32_t Medium;
|
||||
uint32_t MaxPacketsPerTransfer;
|
||||
uint32_t MaxTransferSize;
|
||||
uint32_t PacketAlignmentFactor;
|
||||
uint32_t AFListOffset;
|
||||
uint32_t AFListSize;
|
||||
} RNDIS_INITIALIZE_CMPLT_t;
|
||||
|
||||
/** Type define for a RNDIS Keepalive command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
} RNDIS_KEEPALIVE_MSG_t;
|
||||
|
||||
/** Type define for a RNDIS Keepalive complete message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
} RNDIS_KEEPALIVE_CMPLT_t;
|
||||
|
||||
/** Type define for a RNDIS Reset complete message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t Status;
|
||||
|
||||
uint32_t AddressingReset;
|
||||
} RNDIS_RESET_CMPLT_t;
|
||||
|
||||
/** Type define for a RNDIS Set command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
|
||||
uint32_t Oid;
|
||||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
uint32_t DeviceVcHandle;
|
||||
} RNDIS_SET_MSG_t;
|
||||
|
||||
/** Type define for a RNDIS Set complete response message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
} RNDIS_SET_CMPLT_t;
|
||||
|
||||
/** Type define for a RNDIS Query command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
|
||||
uint32_t Oid;
|
||||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
uint32_t DeviceVcHandle;
|
||||
} RNDIS_QUERY_MSG_t;
|
||||
|
||||
/** Type define for a RNDIS Query complete response message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
|
||||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
} RNDIS_QUERY_CMPLT_t;
|
||||
|
||||
/* External Variables: */
|
||||
extern uint8_t RNDISMessageBuffer[];
|
||||
extern RNDIS_Message_Header_t* MessageHeader;
|
||||
extern bool ResponseReady;
|
||||
extern uint8_t CurrRNDISState;
|
||||
|
||||
/* Function Prototypes: */
|
||||
void ProcessRNDISControlMessage(void);
|
||||
|
||||
#if defined(INCLUDE_FROM_RNDIS_C)
|
||||
static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,
|
||||
void* ResponseData, uint16_t* ResponseSize);
|
||||
static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* RNDIS specification related constants. For more information on these
|
||||
* constants, please refer to the Microsoft RNDIS specification.
|
||||
*/
|
||||
|
||||
#ifndef _RNDIS_CONSTANTS_H_
|
||||
#define _RNDIS_CONSTANTS_H_
|
||||
|
||||
/* Macros: */
|
||||
#define REMOTE_NDIS_PACKET_MSG 0x00000001UL
|
||||
#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002UL
|
||||
#define REMOTE_NDIS_HALT_MSG 0x00000003UL
|
||||
#define REMOTE_NDIS_QUERY_MSG 0x00000004UL
|
||||
#define REMOTE_NDIS_SET_MSG 0x00000005UL
|
||||
#define REMOTE_NDIS_RESET_MSG 0x00000006UL
|
||||
#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007UL
|
||||
#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008UL
|
||||
|
||||
#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002UL
|
||||
#define REMOTE_NDIS_QUERY_CMPLT 0x80000004UL
|
||||
#define REMOTE_NDIS_SET_CMPLT 0x80000005UL
|
||||
#define REMOTE_NDIS_RESET_CMPLT 0x80000006UL
|
||||
#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008UL
|
||||
|
||||
#define REMOTE_NDIS_STATUS_SUCCESS 0x00000000UL
|
||||
#define REMOTE_NDIS_STATUS_FAILURE 0xC0000001UL
|
||||
#define REMOTE_NDIS_STATUS_INVALID_DATA 0xC0010015UL
|
||||
#define REMOTE_NDIS_STATUS_NOT_SUPPORTED 0xC00000BBUL
|
||||
#define REMOTE_NDIS_STATUS_MEDIA_CONNECT 0x4001000BUL
|
||||
#define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT 0x4001000CUL
|
||||
|
||||
#define REMOTE_NDIS_MEDIA_STATE_CONNECTED 0x00000000UL
|
||||
#define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL
|
||||
|
||||
#define REMOTE_NDIS_MEDIUM_802_3 0x00000000UL
|
||||
|
||||
#define REMOTE_NDIS_DF_CONNECTIONLESS 0x00000001UL
|
||||
#define REMOTE_NDIS_DF_CONNECTION_ORIENTED 0x00000002UL
|
||||
|
||||
#define OID_GEN_SUPPORTED_LIST 0x00010101UL
|
||||
#define OID_GEN_HARDWARE_STATUS 0x00010102UL
|
||||
#define OID_GEN_MEDIA_SUPPORTED 0x00010103UL
|
||||
#define OID_GEN_MEDIA_IN_USE 0x00010104UL
|
||||
#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106UL
|
||||
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
|
||||
#define OID_GEN_LINK_SPEED 0x00010107UL
|
||||
#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010AUL
|
||||
#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010BUL
|
||||
#define OID_GEN_VENDOR_ID 0x0001010CUL
|
||||
#define OID_GEN_VENDOR_DESCRIPTION 0x0001010DUL
|
||||
#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010EUL
|
||||
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
|
||||
#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL
|
||||
#define OID_GEN_PHYSICAL_MEDIUM 0x00010202UL
|
||||
#define OID_GEN_XMIT_OK 0x00020101UL
|
||||
#define OID_GEN_RCV_OK 0x00020102UL
|
||||
#define OID_GEN_XMIT_ERROR 0x00020103UL
|
||||
#define OID_GEN_RCV_ERROR 0x00020104UL
|
||||
#define OID_GEN_RCV_NO_BUFFER 0x00020105UL
|
||||
#define OID_802_3_PERMANENT_ADDRESS 0x01010101UL
|
||||
#define OID_802_3_CURRENT_ADDRESS 0x01010102UL
|
||||
#define OID_802_3_MULTICAST_LIST 0x01010103UL
|
||||
#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104UL
|
||||
#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL
|
||||
#define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL
|
||||
#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL
|
||||
|
||||
#endif
|
||||
|
|
@ -56,7 +56,7 @@ TCP_ConnectionState_t ConnectionStateTable[MAX_TCP_CONNECTIONS];
|
|||
* level. If an application produces a response, this task constructs the appropriate Ethernet frame and places it into the Ethernet OUT
|
||||
* buffer for later transmission.
|
||||
*/
|
||||
TASK(TCP_Task)
|
||||
void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
|
||||
{
|
||||
/* Task to hand off TCP packets to and from the listening applications. */
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ TASK(TCP_Task)
|
|||
}
|
||||
|
||||
/* Bail out early if there is already a frame waiting to be sent in the Ethernet OUT buffer */
|
||||
if (FrameOUT.FrameInBuffer)
|
||||
if (RNDISInterfaceInfo->FrameOUT.FrameInBuffer)
|
||||
return;
|
||||
|
||||
/* Send response packets from each application as the TCP packet buffers are filled by the applications */
|
||||
|
|
@ -86,13 +86,13 @@ TASK(TCP_Task)
|
|||
if ((ConnectionStateTable[CSTableEntry].Info.Buffer.Direction == TCP_PACKETDIR_OUT) &&
|
||||
(ConnectionStateTable[CSTableEntry].Info.Buffer.Ready))
|
||||
{
|
||||
Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;
|
||||
IP_Header_t* IPHeaderOUT = (IP_Header_t*)&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];
|
||||
TCP_Header_t* TCPHeaderOUT = (TCP_Header_t*)&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
|
||||
sizeof(IP_Header_t)];
|
||||
void* TCPDataOUT = &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
|
||||
sizeof(IP_Header_t) +
|
||||
sizeof(TCP_Header_t)];
|
||||
Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData;
|
||||
IP_Header_t* IPHeaderOUT = (IP_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];
|
||||
TCP_Header_t* TCPHeaderOUT = (TCP_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
|
||||
sizeof(IP_Header_t)];
|
||||
void* TCPDataOUT = &RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
|
||||
sizeof(IP_Header_t) +
|
||||
sizeof(TCP_Header_t)];
|
||||
|
||||
uint16_t PacketSize = ConnectionStateTable[CSTableEntry].Info.Buffer.Length;
|
||||
|
||||
|
|
@ -145,8 +145,8 @@ TASK(TCP_Task)
|
|||
PacketSize += sizeof(Ethernet_Frame_Header_t);
|
||||
|
||||
/* Set the response length in the buffer and indicate that a response is ready to be sent */
|
||||
FrameOUT.FrameLength = PacketSize;
|
||||
FrameOUT.FrameInBuffer = true;
|
||||
RNDISInterfaceInfo->FrameOUT.FrameLength = PacketSize;
|
||||
RNDISInterfaceInfo->FrameOUT.FrameInBuffer = true;
|
||||
|
||||
ConnectionStateTable[CSTableEntry].Info.Buffer.Ready = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -38,9 +38,7 @@
|
|||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <LUFA/Scheduler/Scheduler.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
|
|
@ -229,14 +227,12 @@
|
|||
uint16_t Checksum; /**< TCP checksum */
|
||||
uint16_t UrgentPointer; /**< Urgent data pointer */
|
||||
} TCP_Header_t;
|
||||
|
||||
/* Tasks: */
|
||||
TASK(TCP_Task);
|
||||
|
||||
/* External Variables: */
|
||||
TCP_PortState_t PortStateTable[MAX_OPEN_TCP_PORTS];
|
||||
|
||||
/* Function Prototypes: */
|
||||
void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
|
||||
void TCP_Init(void);
|
||||
bool TCP_SetPortState(uint16_t Port, uint8_t State, void (*Handler)(TCP_ConnectionState_t*, TCP_ConnectionBuffer_t*));
|
||||
uint8_t TCP_GetPortState(uint16_t Port);
|
||||
|
|
|
|||
|
|
@ -28,27 +28,50 @@
|
|||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the RNDISEthernet demo. This file contains the main tasks of the demo and
|
||||
* is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "RNDISEthernet.h"
|
||||
|
||||
/* Scheduler Task List */
|
||||
TASK_LIST
|
||||
{
|
||||
{ .Task = USB_USBTask , .TaskStatus = TASK_STOP },
|
||||
{ .Task = Ethernet_Task , .TaskStatus = TASK_STOP },
|
||||
{ .Task = TCP_Task , .TaskStatus = TASK_STOP },
|
||||
{ .Task = RNDIS_Task , .TaskStatus = TASK_STOP },
|
||||
};
|
||||
USB_ClassInfo_RNDIS_t Ethernet_RNDIS_Interface =
|
||||
{
|
||||
.ControlInterfaceNumber = 0,
|
||||
|
||||
/** Main program entry point. This routine configures the hardware required by the application, then
|
||||
* starts the scheduler to run the USB management task.
|
||||
*/
|
||||
.DataINEndpointNumber = CDC_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
|
||||
.DataOUTEndpointNumber = CDC_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
|
||||
.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
|
||||
.AdapterVendorDescription = "LUFA RNDIS Demo Adapter",
|
||||
.AdapterMACAddress = {ADAPTER_MAC_ADDRESS},
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
|
||||
printf_P(PSTR("\r\n\r\n****** RNDIS Demo running. ******\r\n"));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (Ethernet_RNDIS_Interface.FrameIN.FrameInBuffer)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
Ethernet_ProcessPacket(&Ethernet_RNDIS_Interface.FrameIN, &Ethernet_RNDIS_Interface.FrameOUT);
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
TCP_TCPTask(&Ethernet_RNDIS_Interface);
|
||||
|
||||
USB_RNDIS_USBTask(&Ethernet_RNDIS_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
|
|
@ -60,279 +83,32 @@ int main(void)
|
|||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
SerialStream_Init(9600, false);
|
||||
|
||||
/* Webserver Initialization */
|
||||
TCP_Init();
|
||||
Webserver_Init();
|
||||
|
||||
printf_P(PSTR("\r\n\r\n****** RNDIS Demo running. ******\r\n"));
|
||||
|
||||
/* Indicate USB not ready */
|
||||
UpdateStatus(Status_USBNotReady);
|
||||
|
||||
/* Initialize Scheduler so that it can be used */
|
||||
Scheduler_Init();
|
||||
|
||||
/* Initialize USB Subsystem */
|
||||
USB_Init();
|
||||
|
||||
/* Scheduling - routine never returns, so put this last in the main function */
|
||||
Scheduler_Start();
|
||||
/* Initialize TCP and Webserver modules */
|
||||
TCP_Init();
|
||||
Webserver_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
|
||||
* starts the library USB task to begin the enumeration and USB management process.
|
||||
*/
|
||||
void EVENT_USB_Connect(void)
|
||||
{
|
||||
/* Start USB management task */
|
||||
Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
|
||||
|
||||
/* Indicate USB enumerating */
|
||||
UpdateStatus(Status_USBEnumerating);
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
|
||||
* the status LEDs and stops all the relevant tasks.
|
||||
*/
|
||||
void EVENT_USB_Disconnect(void)
|
||||
{
|
||||
/* Stop running TCP/IP and USB management tasks */
|
||||
Scheduler_SetTaskMode(RNDIS_Task, TASK_STOP);
|
||||
Scheduler_SetTaskMode(Ethernet_Task, TASK_STOP);
|
||||
Scheduler_SetTaskMode(TCP_Task, TASK_STOP);
|
||||
Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
|
||||
|
||||
/* Indicate USB not ready */
|
||||
UpdateStatus(Status_USBNotReady);
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration
|
||||
* of the USB device after enumeration, and configures the RNDIS device endpoints and starts the relevant tasks.
|
||||
*/
|
||||
void EVENT_USB_ConfigurationChanged(void)
|
||||
{
|
||||
/* Setup CDC Notification, Rx and Tx Endpoints */
|
||||
Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,
|
||||
ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
|
||||
Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
|
||||
ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
|
||||
/* Indicate USB connected and ready */
|
||||
UpdateStatus(Status_USBReady);
|
||||
|
||||
/* Start TCP/IP tasks */
|
||||
Scheduler_SetTaskMode(RNDIS_Task, TASK_RUN);
|
||||
Scheduler_SetTaskMode(Ethernet_Task, TASK_RUN);
|
||||
Scheduler_SetTaskMode(TCP_Task, TASK_RUN);
|
||||
if (!(USB_RNDIS_ConfigureEndpoints(&Ethernet_RNDIS_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
|
||||
* control requests that are not handled internally by the USB library (including the RNDIS control commands,
|
||||
* which set up the USB RNDIS network adapter), so that they can be handled appropriately for the application.
|
||||
*/
|
||||
void EVENT_USB_UnhandledControlPacket(void)
|
||||
{
|
||||
/* Process RNDIS class commands */
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case REQ_SendEncapsulatedCommand:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
/* Clear the SETUP packet, ready for data transfer */
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
/* Read in the RNDIS message into the message buffer */
|
||||
Endpoint_Read_Control_Stream_LE(RNDISMessageBuffer, USB_ControlRequest.wLength);
|
||||
|
||||
/* Finalize the stream transfer to clear the last packet from the host */
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Process the RNDIS message */
|
||||
ProcessRNDISControlMessage();
|
||||
}
|
||||
|
||||
break;
|
||||
case REQ_GetEncapsulatedResponse:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
/* Clear the SETUP packet, ready for data transfer */
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
/* Check if a response to the last message is ready */
|
||||
if (!(MessageHeader->MessageLength))
|
||||
{
|
||||
/* Set the response to a single 0x00 byte to indicate that no response is ready */
|
||||
RNDISMessageBuffer[0] = 0;
|
||||
MessageHeader->MessageLength = 1;
|
||||
}
|
||||
|
||||
/* Write the message response data to the endpoint */
|
||||
Endpoint_Write_Control_Stream_LE(RNDISMessageBuffer, MessageHeader->MessageLength);
|
||||
|
||||
/* Finalize the stream transfer to send the last packet or clear the host abort */
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
/* Reset the message header once again after transmission */
|
||||
MessageHeader->MessageLength = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
|
||||
* log to a serial port, or anything else that is suitable for status updates.
|
||||
*
|
||||
* \param CurrentStatus Current status of the system, from the RNDISEthernet_StatusCodes_t enum
|
||||
*/
|
||||
void UpdateStatus(uint8_t CurrentStatus)
|
||||
{
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
/* Set the LED mask to the appropriate LED mask based on the given status code */
|
||||
switch (CurrentStatus)
|
||||
{
|
||||
case Status_USBNotReady:
|
||||
LEDMask = (LEDS_LED1);
|
||||
break;
|
||||
case Status_USBEnumerating:
|
||||
LEDMask = (LEDS_LED1 | LEDS_LED2);
|
||||
break;
|
||||
case Status_USBReady:
|
||||
LEDMask = (LEDS_LED2 | LEDS_LED4);
|
||||
break;
|
||||
case Status_ProcessingEthernetFrame:
|
||||
LEDMask = (LEDS_LED2 | LEDS_LED3);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the board LEDs to the new LED mask */
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
|
||||
/** Task to manage the sending and receiving of encapsulated RNDIS data and notifications. This removes the RNDIS
|
||||
* wrapper from received Ethernet frames and places them in the FrameIN global buffer, or adds the RNDIS wrapper
|
||||
* to a frame in the FrameOUT global before sending the buffer contents to the host.
|
||||
*/
|
||||
TASK(RNDIS_Task)
|
||||
{
|
||||
/* Select the notification endpoint */
|
||||
Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM);
|
||||
|
||||
/* Check if a message response is ready for the host */
|
||||
if (Endpoint_IsINReady() && ResponseReady)
|
||||
{
|
||||
USB_Notification_t Notification = (USB_Notification_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bNotification = NOTIF_RESPONSE_AVAILABLE,
|
||||
.wValue = 0,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
/* Indicate that a message response is ready for the host */
|
||||
Endpoint_Write_Stream_LE(&Notification, sizeof(Notification));
|
||||
|
||||
/* Finalize the stream transfer to send the last packet */
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Indicate a response is no longer ready */
|
||||
ResponseReady = false;
|
||||
}
|
||||
|
||||
/* Don't process the data endpoints until the system is in the data initialized state, and the buffer is free */
|
||||
if ((CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))
|
||||
{
|
||||
/* Create a new packet header for reading/writing */
|
||||
RNDIS_PACKET_MSG_t RNDISPacketHeader;
|
||||
|
||||
/* Select the data OUT endpoint */
|
||||
Endpoint_SelectEndpoint(CDC_RX_EPNUM);
|
||||
|
||||
/* Check if the data OUT endpoint contains data, and that the IN buffer is empty */
|
||||
if (Endpoint_IsOUTReceived() && !(FrameIN.FrameInBuffer))
|
||||
{
|
||||
/* Read in the packet message header */
|
||||
Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t));
|
||||
|
||||
/* Stall the request if the data is too large */
|
||||
if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX)
|
||||
{
|
||||
Endpoint_StallTransaction();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read in the Ethernet frame into the buffer */
|
||||
Endpoint_Read_Stream_LE(FrameIN.FrameData, RNDISPacketHeader.DataLength);
|
||||
|
||||
/* Finalize the stream transfer to send the last packet */
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
/* Store the size of the Ethernet frame */
|
||||
FrameIN.FrameLength = RNDISPacketHeader.DataLength;
|
||||
|
||||
/* Indicate Ethernet IN buffer full */
|
||||
FrameIN.FrameInBuffer = true;
|
||||
}
|
||||
|
||||
/* Select the data IN endpoint */
|
||||
Endpoint_SelectEndpoint(CDC_TX_EPNUM);
|
||||
|
||||
/* Check if the data IN endpoint is ready for more data, and that the IN buffer is full */
|
||||
if (Endpoint_IsINReady() && FrameOUT.FrameInBuffer)
|
||||
{
|
||||
/* Clear the packet header with all 0s so that the relevant fields can be filled */
|
||||
memset(&RNDISPacketHeader, 0, sizeof(RNDIS_PACKET_MSG_t));
|
||||
|
||||
/* Construct the required packet header fields in the buffer */
|
||||
RNDISPacketHeader.MessageType = REMOTE_NDIS_PACKET_MSG;
|
||||
RNDISPacketHeader.MessageLength = (sizeof(RNDIS_PACKET_MSG_t) + FrameOUT.FrameLength);
|
||||
RNDISPacketHeader.DataOffset = (sizeof(RNDIS_PACKET_MSG_t) - sizeof(RNDIS_Message_Header_t));
|
||||
RNDISPacketHeader.DataLength = FrameOUT.FrameLength;
|
||||
|
||||
/* Send the packet header to the host */
|
||||
Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t));
|
||||
|
||||
/* Send the Ethernet frame data to the host */
|
||||
Endpoint_Write_Stream_LE(FrameOUT.FrameData, RNDISPacketHeader.DataLength);
|
||||
|
||||
/* Finalize the stream transfer to send the last packet */
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Indicate Ethernet OUT buffer no longer full */
|
||||
FrameOUT.FrameInBuffer = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Ethernet frame processing task. This task checks to see if a frame has been received, and if so hands off the processing
|
||||
* of the frame to the Ethernet processing routines.
|
||||
*/
|
||||
TASK(Ethernet_Task)
|
||||
{
|
||||
/* Task for Ethernet processing. Incoming ethernet frames are loaded into the FrameIN structure, and
|
||||
outgoing frames should be loaded into the FrameOUT structure. Both structures can only hold a single
|
||||
Ethernet frame at a time, so the FrameInBuffer bool is used to indicate when the buffers contain data. */
|
||||
|
||||
/* Check if a frame has been written to the IN frame buffer */
|
||||
if (FrameIN.FrameInBuffer)
|
||||
{
|
||||
/* Indicate packet processing started */
|
||||
UpdateStatus(Status_ProcessingEthernetFrame);
|
||||
|
||||
/* Process the ethernet frame - replace this with your own Ethernet handler code as desired */
|
||||
Ethernet_ProcessPacket();
|
||||
|
||||
/* Indicate packet processing complete */
|
||||
UpdateStatus(Status_USBReady);
|
||||
}
|
||||
USB_RNDIS_ProcessControlPacket(&Ethernet_RNDIS_Interface);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,56 +45,34 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include "Lib/RNDIS.h"
|
||||
|
||||
#include "Lib/Ethernet.h"
|
||||
#include "Lib/TCP.h"
|
||||
#include "Lib/ARP.h"
|
||||
#include "Lib/Webserver.h"
|
||||
|
||||
#include <LUFA/Version.h> // Library Version Information
|
||||
#include <LUFA/Drivers/USB/USB.h> // USB Functionality
|
||||
#include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
|
||||
#include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
|
||||
#include <LUFA/Drivers/Peripheral/SerialStream.h> // Serial stream driver
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/Device/RNDIS.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Notification value to indicate that a frame is ready to be read by the host. */
|
||||
#define NOTIF_RESPONSE_AVAILABLE 0x01
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a RNDIS notification message, for transmission to the RNDIS host via the notification
|
||||
* Endpoint.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bmRequestType; /**< Notification type, a mask of values from SrdRequestType.h */
|
||||
uint8_t bNotification; /**< Notification index, indicating what the RNDIS notification relates to */
|
||||
uint16_t wValue; /**< Two byte notification value parameter */
|
||||
uint16_t wIndex; /**< Two byte notification index parameter */
|
||||
uint16_t wLength; /**< Size of data payload following the notification header */
|
||||
} USB_Notification_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible status codes for passing to the UpdateStatus() function. */
|
||||
enum RNDISEthernet_StatusCodes_t
|
||||
{
|
||||
Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
|
||||
Status_USBEnumerating = 1, /**< USB interface is enumerating */
|
||||
Status_USBReady = 2, /**< USB interface is connected and ready */
|
||||
Status_ProcessingEthernetFrame = 3, /**< Currently processing an ethernet frame from the host */
|
||||
};
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
#define LEDMASK_USB_BUSY LEDS_LED2
|
||||
|
||||
/* Tasks: */
|
||||
TASK(RNDIS_Task);
|
||||
TASK(Ethernet_Task);
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Connect(void);
|
||||
void EVENT_USB_Disconnect(void);
|
||||
void EVENT_USB_ConfigurationChanged(void);
|
||||
void EVENT_USB_UnhandledControlPacket(void);
|
||||
|
||||
void UpdateStatus(uint8_t CurrentStatus);
|
||||
void EVENT_USB_StartOfFrame(void);
|
||||
|
||||
void CALLBACK_USB_RNDIS_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -125,7 +125,6 @@ LUFA_PATH = ../../..
|
|||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = $(TARGET).c \
|
||||
Descriptors.c \
|
||||
Lib/RNDIS.c \
|
||||
Lib/Ethernet.c \
|
||||
Lib/ProtocolDecoders.c \
|
||||
Lib/ICMP.c \
|
||||
|
|
@ -135,7 +134,6 @@ SRC = $(TARGET).c \
|
|||
Lib/ARP.c \
|
||||
Lib/IP.c \
|
||||
Lib/Webserver.c \
|
||||
$(LUFA_PATH)/LUFA/Scheduler/Scheduler.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \
|
||||
|
|
@ -148,7 +146,7 @@ SRC = $(TARGET).c \
|
|||
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c \
|
||||
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/RNDIS.c \
|
||||
|
||||
|
||||
# List C++ source files here. (C dependencies are automatically generated.)
|
||||
|
|
@ -195,7 +193,7 @@ CSTANDARD = -std=gnu99
|
|||
|
||||
# Place -D or -U options here for C sources
|
||||
CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
|
||||
CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
|
||||
CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
|
||||
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
|
||||
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
|
||||
CDEFS += -DNO_DECODE_ETHERNET -DNO_DECODE_ARP -DNO_DECODE_ICMP -DNO_DECODE_IP -DNO_DECODE_TCP -DNO_DECODE_UDP -DNO_DECODE_DHCP
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue