📄 rndis.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//
// Copyright (c) Intrinsyc Corporation. All rights reserved.
//
//------------------------------------------------------------------------------
//
// File: rndis.c
//
#include <windows.h>
#include <omap2420.h>
#include <usbfntypes.h>
#include <usbfn.h>
#undef ZONE_ERROR
#undef ZONE_INIT
#undef ZONE_WARNING
#include <rndismini.h>
#include <linklist.h>
#include <halether.h>
#include <kitl.h>
#include <oal.h>
#include "pdd.h"
#pragma optimize ( "g", on )
#define CS_INTERFACE 0x24 // Class Interface
#define iCONF 18
#define CFGLEN 62
#define MANUFACTURER L"Microsoft"
#define PRODUCT L"Microsoft RNDIS KITL for OMAP3"
INTERRUPT_DATA g_InterruptData = {
0x01, // notification
0x00 // reserved
};
static UCHAR g_ucScratch = 0;
static UCHAR g_RndisMacAddress[6] = {0x00, 0x02, 0xb3, 0x92, 0xa8, 0xc4};
static UCHAR pucVendorID[] = "Microsoft.\0";
static UCHAR pucVendorDescription[] = "Microsoft RNDIS virtual adapter miniport.\0";
int PDDZONE0;
int PDDZONE;
int MDDZONE0;
int MDDZONE;
int MDDZONE2;
int MDDZONE3;
int MDDZONE4;
int MDDZONE5;
USB_DEVICE_REQUEST g_udr;
RNDIS_KITLDEV g_RndisKitlDev;
DATA_WRAPPER g_EP0DataWrapper;
DATA_WRAPPER *g_pEP1DataWrapper = NULL;
static USB_SERIAL_NUMBER gs_SerialNumber;
static const UCHAR gs_pucSupportedLanguage[] =
{
0x04,
USB_STRING_DESCRIPTOR_TYPE,
0x09, 0x04 // US English only..
};
static const USB_STRING gs_Manufacturer =
{
sizeof(MANUFACTURER) + 2,
USB_STRING_DESCRIPTOR_TYPE,
MANUFACTURER
};
static const USB_STRING gs_Product =
{
sizeof(PRODUCT) + 2,
USB_STRING_DESCRIPTOR_TYPE,
PRODUCT
};
static const UCHAR gs_pucUSBDescriptors[] =
{
////////////////////////////////////////////////////////////////////////////
// Standard Device Descriptor
//
/* 0 */ 18, // bLength = 18 bytes.
/* 1 */ USB_DEVICE_DESCRIPTOR_TYPE, // bDescriptorType = DEVICE
/* 2 */ 0x10, 0x01, // bcdUSB = 1.1
/* 4 */ 0x02, // bDeviceClass = Communication Device Class
/* 5 */ 0x00, // bDeviceSubClass = Unused at this time.
/* 6 */ 0x00, // bDeviceProtocol = Unused at this time.
/* 7 */ EP0MaxSize, // bMaxPacketSize0 = EP0 buffer size..
/* 8 */ 0x5E, 0x04, // idVendor = Microsoft Vendor ID.
/* 10 */ 0x01, 0x03, // idProduct = Microsoft generic RNDISMINI Product ID.
/* 12 */ 0x01, 0x00, // bcdDevice = 0.1
/* 14 */ 0x01, // iManufacturer = OEM should fill this..
/* 15 */ 0x02, // iProduct = OEM should fill this..
/* 16 */ 0x03, // iSerialNumber = OEM should fill this..
/* 17 */ 0x01, // bNumConfigs = 1
////////////////////////////////////////////////////////////////////////////
// RNDIS requires only one configuration as follows..
// And we have 2 interfaces (Communication Class if & Dataclass if).
//
/* 18 */ 9, // bLength = 9 bytes.
/* 19 */ USB_CONFIGURATION_DESCRIPTOR_TYPE, // bDescriptorType = CONFIGURATION
/* 20 */ 0x3e, 0x00, // wTotalLength = From offset 18 to end <---
/* 22 */ 0x02, // bNumInterfaces = 2 (RNDIS spec).
/* 23 */ 0x01, // bConfValue = 1
/* 24 */ 0x00, // iConfiguration = unused.
/* 25 */ 0x40, // bmAttributes = Self-Powered.
/* 26 */ 0x01, // MaxPower = x2mA
////////////////////////////////////////////////////////////////////////////
// Communication Class INTERFACE descriptor.
// RNDIS specifies 2 endpoints, EP0 & notification element (interrupt)
//
/* 27 */ 9, // bLength = 9 bytes.
/* 28 */ USB_INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType = INTERFACE
/* 29 */ 0x00, // bInterfaceNo = 0
/* 30 */ 0x00, // bAlternateSet = 0
/* 31 */ 0x01, // bNumEndPoints = 1 (RNDIS spec)
/* 32 */ 0x02, // bInterfaceClass = Comm if class (RNDIS spec)
/* 33 */ 0x02, // bIfSubClass = Comm if sub (ditto)
/* 34 */ 0xff, // bIfProtocol = Vendor specific (ditto)
/* 35 */ 0x00, // iInterface = unused.
////////////////////////////////////////////////////////////////////////////
// Functional Descriptors for Communication Class Interface
// per RNDIS spec.
//
/* 36 */ 5, // bFunctionLength = 5 bytes.
/* 37 */ CS_INTERFACE, // bDescriptorType = Class Interface
/* 38 */ 0x01, // bDescSubType = CALL MGMT func descriptor.
/* 39 */ 0x00, // bmCapabilities = See sect 5.2.3.2 USB CDC
/* 40 */ 0x01, // bDataInterface = 1 data class i/f.
/* 41 */ 4, // bFunctionLength = 5 bytes.
/* 42 */ CS_INTERFACE, // bDescriptorType = Class Interface
/* 43 */ 0x02, // bDescSubType = ABSTRACT ctrl mgmt desc.
/* 44 */ 0x00, // bmCapabilities = See sect 5.2.3.3 USB CDC
/* 45 */ 5, // bFunctionLength = 5 bytes.
/* 46 */ CS_INTERFACE, // bDescriptorType = Class Interface.
/* 47 */ 0x06, // bDescSubType = UNION func descriptor.
/* 48 */ 0x00, // bMasterIf = i/f 0 is the master if.
/* 49 */ 0x01, // bSlaveIf = i/f 1 is the slave if.
////////////////////////////////////////////////////////////////////////////
// Endpoint descriptors for Communication Class Interface
//
/* 50 */ 7, // bLength = 7 bytes.
/* 51 */ USB_ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType = ENDPOINT
/* 52 */ 0x83, // bEndpointAddr = IN - EP3
/* 53 */ 0x03, // bmAttributes = Interrupt endpoint.
/* 54 */ EPMaxSize, 0x00, // wMaxPacketSize
/* 56 */ 80, // bInterval = 1 ms polling from host.
////////////////////////////////////////////////////////////////////////////
// Data Class INTERFACE descriptor.
//
/* 57 */ 9, // bLength = 9 bytes.
/* 58 */ USB_INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType = INTERFACE
/* 59 */ 0x01, // bInterfaceNo = 1
/* 60 */ 0x00, // bAlternateSet = 0
/* 61 */ 0x02, // bNumEndPoints = 2 (RNDIS spec)
/* 62 */ 0x0A, // bInterfaceClass = Data if class (RNDIS spec)
/* 63 */ 0x00, // bIfSubClass = unused.
/* 64 */ 0x00, // bIfProtocol = unused.
/* 65 */ 0x00, // iInterface = unused.
////////////////////////////////////////////////////////////////////////////
// Endpoint descriptors for Data Class Interface
//
/* 66 */ 7, // bLength = 7 bytes.
/* 67 */ USB_ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType = ENDPOINT [IN]
/* 68 */ 0x82, // bEndpointAddr = IN -- EP2
/* 69 */ 0x02, // bmAttributes = BULK
/* 70 */ EPMaxSize, 0x00, // wMaxPacketSize
/* 72 */ 0, // bInterval = ignored for BULK.
/* 73 */ 7, // bLength = 7 bytes.
/* 74 */ USB_ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType = ENDPOINT [OUT]
/* 75 */ 0x01, // bEndpointAddr = OUT -- EP1
/* 76 */ 0x02, // bmAttributes = BULK
/* 77 */ EPMaxSize, 0x00, // wMaxPacketSize
/* 79 */ 0 // bInterval = ignored for BULK.
}; // gs_pucUSBDescriptors[]
const TCHAR DigitTable[] = TEXT("0123456789ABCDEF");
// when registering with the USBFN PDD layer, the PDD will fill in this
// structure with appropriate data and function pointers
UFN_MDD_INTERFACE_INFO g_mddInterface;
// contains the MDD callback functions to be called by the PDD layer
UFN_PDD_INTERFACE_INFO g_pddInterface;
// current transfer information for each endpoint
STransfer g_EP0Transfer; // EP0
STransfer g_EP1Transfer; // Bulk out
STransfer g_EP2Transfer; // Bulk in
STransfer g_EP3Transfer; // Int in
enum DEVICE_STATE g_devState = DS_DETACHED;
enum TRANSFER_STATE g_EP0TransferState = TS_IDLE;
enum TRANSFER_STATE g_EP1TransferState = TS_IDLE;
enum TRANSFER_STATE g_EP2TransferState = TS_IDLE;
enum TRANSFER_STATE g_EP3TransferState = TS_IDLE;
DWORD GetUniqueDeviceID(); // returns a 32 bit unique device ID used to compute the MAC address and serial number
void SetRNDISSerialNumber(void);
void SetRNDISMACAddress(void);
BOOL InitializeHardware(); // performs the hardware initialization (clock, I2C, OTG transceiver, OTG controller)
DWORD InterruptThread(VOID *pPddContext);
// after a message is successfully sent, this function will be called to indicate this fact to the KITL MDD
static VOID PDD_SendNotification(EP0_REQUEST *pRequest, PVOID pvUser)
{
DATA_WRAPPER *pWrapper = (DATA_WRAPPER *)pvUser;
if (pWrapper != g_RndisKitlDev.pEP0DataWrapper) {
ASSERT(FALSE);
return;
}
MddSendRndisMessageComplete(g_RndisKitlDev.pEP0DataWrapper);
g_RndisKitlDev.pEP0DataWrapper = NULL;
}
// after a message is successfully received, this function will be called to indicate this fact to the KITL MDD
static VOID PDD_RecvNotification(EP0_REQUEST *pRequest, PVOID pvUser)
{
DATA_WRAPPER *pWrapper = (DATA_WRAPPER *)pvUser;
if (pWrapper != &g_RndisKitlDev.EP0DataWrapper) {
ASSERT(FALSE);
return;
}
g_RndisKitlDev.EP0DataWrapper.pucData = pRequest->pucData;
g_RndisKitlDev.EP0DataWrapper.dwDataSize = pRequest->dwActualSize;
MddIndicateRndisMessage(&(g_RndisKitlDev.EP0DataWrapper));
}
// computes the descriptor data for a GET_DESCRIPTOR setup request
BOOL PDD_GetDescriptor(USB_DEVICE_REQUEST *pUdr, EP0_REQUEST *pRequest)
{
UCHAR *pucData;
WORD wLength;
WORD wType = pUdr->wValue;
BOOL fRet = TRUE;
switch (HIBYTE(wType)) {
case USB_DEVICE_DESCRIPTOR_TYPE:
pucData = (UCHAR *)gs_pucUSBDescriptors;
wLength = gs_pucUSBDescriptors[0];
break;
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
pucData = (UCHAR *)&gs_pucUSBDescriptors[iCONF];
wLength = CFGLEN;;
break;
case USB_STRING_DESCRIPTOR_TYPE:
switch (LOBYTE(wType)) {
case 0x00:
pucData = (UCHAR *)gs_pucSupportedLanguage;
wLength = gs_pucSupportedLanguage[0];
break;
case 0x01:
pucData = (UCHAR *)&gs_Manufacturer;
wLength = gs_Manufacturer.ucbLength;
break;
case 0x02:
pucData = (UCHAR *)&gs_Product;
wLength = gs_Product.ucbLength;
break;
case 0x03:
pucData = (UCHAR *)&gs_SerialNumber;
wLength = gs_SerialNumber.ucbLength;
break;
default:
OALMSG(OAL_ERROR, (L"*** Unknown STRING index %d\r\n", LOBYTE(wType)));
fRet = FALSE;
break;
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -