Addition of USB files
This commit is contained in:
parent
a520fe4646
commit
219846f408
36 changed files with 11046 additions and 0 deletions
266
cpu/avr/dev/usb/rndis/ndis.h
Normal file
266
cpu/avr/dev/usb/rndis/ndis.h
Normal file
|
@ -0,0 +1,266 @@
|
|||
/* 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 <coflynn@newae.com>
|
||||
* ntddndis.h modified by Benedikt Spranger <b.spranger@pengutronix.de>
|
||||
*
|
||||
* Thanks to the cygwin development team,
|
||||
* espacially to Casper S. Hornstrup <chorns@users.sourceforge.net>
|
||||
*
|
||||
* 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 */
|
||||
|
||||
/** @} */
|
842
cpu/avr/dev/usb/rndis/rndis.c
Normal file
842
cpu/avr/dev/usb/rndis/rndis.c
Normal file
|
@ -0,0 +1,842 @@
|
|||
/**
|
||||
* \file rndis.c
|
||||
* RNDIS Functions for mounting USB device as network interface
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*/
|
||||
/* Copyright (c) 2008 Colin O'Flynn
|
||||
|
||||
The CDC code which this is based on is Copyright (c) Atmel Corporation 2008
|
||||
All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
RNDIS Status Information:
|
||||
|
||||
802.3 Support:
|
||||
More or less working
|
||||
|
||||
802.11 Support:
|
||||
Incomplete, would just error out if you tried probably
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup RNDIS
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
#include "radio.h"
|
||||
#include "contiki.h"
|
||||
#include "config.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "uip.h"
|
||||
#include "serial/uart_usb_lib.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
#include <avr/pgmspace.h>
|
||||
#include <string.h>
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
//_____ D E F I N I T I O N ________________________________________________
|
||||
|
||||
//_____ P R I V A T E D E C L A R A T I O N ______________________________
|
||||
|
||||
extern PGM_VOID_P pbuffer;
|
||||
extern U8 data_to_transfer;
|
||||
|
||||
//NB: If you change the OID list be sure to update this!!!
|
||||
//#define OID_LIST_LENGTH 50
|
||||
#define OID_LIST_LENGTH 35
|
||||
|
||||
/**
|
||||
* \brief List of supported RNDIS OID's
|
||||
*/
|
||||
prog_uint32_t OIDSupportedList[OID_LIST_LENGTH] = {
|
||||
/* Required General */
|
||||
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_CURRENT_PACKET_FILTER ,
|
||||
OID_GEN_MAXIMUM_TOTAL_SIZE ,
|
||||
OID_GEN_MEDIA_CONNECT_STATUS ,
|
||||
OID_GEN_VENDOR_DRIVER_VERSION ,
|
||||
OID_GEN_PHYSICAL_MEDIUM ,
|
||||
|
||||
/* Required Statistical */
|
||||
OID_GEN_XMIT_OK ,
|
||||
OID_GEN_RCV_OK ,
|
||||
OID_GEN_XMIT_ERROR ,
|
||||
OID_GEN_RCV_ERROR ,
|
||||
OID_GEN_RCV_NO_BUFFER ,
|
||||
|
||||
/* Please configure us */
|
||||
OID_GEN_RNDIS_CONFIG_PARAMETER ,
|
||||
|
||||
|
||||
/* IEEE 802.3 (Ethernet) OIDs */
|
||||
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 ,
|
||||
OID_802_3_RCV_ERROR_ALIGNMENT ,
|
||||
OID_802_3_XMIT_ONE_COLLISION ,
|
||||
OID_802_3_XMIT_MORE_COLLISIONS ,
|
||||
|
||||
/*802.11 OID's not fully implemented yet. Hence do not say we
|
||||
support them */
|
||||
#ifdef DONOTEVERDEFINETHISORBADSTUFFHAPPENS
|
||||
/* 802.11 OIDs */
|
||||
OID_802_11_BSSID ,
|
||||
OID_802_11_SSID ,
|
||||
OID_802_11_NETWORK_TYPE_IN_USE ,
|
||||
OID_802_11_RSSI ,
|
||||
OID_802_11_BSSID_LIST ,
|
||||
OID_802_11_BSSID_LIST_SCAN ,
|
||||
OID_802_11_INFRASTRUCTURE_MODE ,
|
||||
OID_802_11_SUPPORTED_RATES ,
|
||||
OID_802_11_CONFIGURATION ,
|
||||
OID_802_11_ADD_WEP ,
|
||||
OID_802_11_WEP_STATUS ,
|
||||
OID_802_11_REMOVE_WEP ,
|
||||
OID_802_11_DISASSOCIATE ,
|
||||
OID_802_11_AUTHENTICATION_MODE ,
|
||||
OID_802_11_RELOAD_DEFAULTS ,
|
||||
#endif
|
||||
|
||||
/* Minimum power managment needed for USB */
|
||||
|
||||
OID_PNP_CAPABILITIES ,
|
||||
OID_PNP_QUERY_POWER ,
|
||||
OID_PNP_SET_POWER ,
|
||||
|
||||
OID_PNP_ENABLE_WAKE_UP ,
|
||||
OID_PNP_ADD_WAKE_UP_PATTERN ,
|
||||
OID_PNP_REMOVE_WAKE_UP_PATTERN
|
||||
|
||||
};
|
||||
|
||||
|
||||
rndis_state_t rndis_state;
|
||||
|
||||
rndis_stat_t rndis_stat;
|
||||
|
||||
uint8_t schedule_interrupt = 0;
|
||||
|
||||
uint64_t rndis_ethernet_addr = 0x203478928323UL;
|
||||
|
||||
//_____ D E C L A R A T I O N ______________________________________________
|
||||
|
||||
|
||||
void rndis_packetFilter(uint32_t newfilter);
|
||||
|
||||
/******** RNDIS ********/
|
||||
|
||||
#define ENC_BUF_SIZE (4*OID_LIST_LENGTH + 32)
|
||||
|
||||
// Command buffer
|
||||
U8 encapsulated_buffer[ENC_BUF_SIZE];
|
||||
|
||||
//Do we have data to send back?
|
||||
U8 data_to_send = 0x00;
|
||||
|
||||
/**
|
||||
* \brief Handles a "SEND ENCAPSULATED COMMAND" message.
|
||||
*
|
||||
* \return True on success, false on failure.
|
||||
*/
|
||||
uint8_t send_encapsulated_command(uint16_t wLength)
|
||||
{
|
||||
U8 i = 0;
|
||||
|
||||
//Received setup message OK
|
||||
Usb_ack_receive_setup();
|
||||
|
||||
|
||||
//Crude bounds check
|
||||
if (wLength > ENC_BUF_SIZE)
|
||||
wLength = ENC_BUF_SIZE;
|
||||
|
||||
//For debugging: this shouldn't happen, just checked it didn't
|
||||
//if (data_to_send) {
|
||||
// while(1);
|
||||
//}
|
||||
|
||||
|
||||
//Read in all the bytes...
|
||||
|
||||
uint8_t nb_counter;
|
||||
|
||||
|
||||
while (wLength) {
|
||||
nb_counter = EP_CONTROL_LENGTH;
|
||||
|
||||
//Wait for data to come in
|
||||
while (!(Is_usb_receive_out()));
|
||||
|
||||
while(nb_counter && wLength) {
|
||||
encapsulated_buffer[i] = Usb_read_byte();
|
||||
i++;
|
||||
wLength--;
|
||||
nb_counter--;
|
||||
}
|
||||
|
||||
Usb_ack_receive_out();
|
||||
|
||||
}
|
||||
|
||||
Usb_send_control_in();
|
||||
|
||||
|
||||
switch(((rndis_generic_msg_t *)encapsulated_buffer)->MessageType)
|
||||
{
|
||||
/* Requests remote intilization. Respond with complete,
|
||||
eventually should probably do something */
|
||||
case REMOTE_NDIS_INITIALIZE_MSG:
|
||||
{
|
||||
rndis_initialize_cmplt_t * m;
|
||||
m = ((rndis_initialize_cmplt_t *)encapsulated_buffer);
|
||||
|
||||
//m->MessageID is same as before
|
||||
m->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
|
||||
m->MessageLength = sizeof(rndis_initialize_cmplt_t);
|
||||
m->MajorVersion = RNDIS_MAJOR_VERSION;
|
||||
m->MinorVersion = RNDIS_MAJOR_VERSION;
|
||||
m->Status = RNDIS_STATUS_SUCCESS;
|
||||
m->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
|
||||
m->Medium = RNDIS_MEDIUM_802_3;
|
||||
m->MaxPacketsPerTransfer = 1;
|
||||
m->MaxTransferSize = 1338; /* Space for 1280 IP buffer, Ethernet Header,
|
||||
RNDIS messages */
|
||||
m->PacketAlignmentFactor = 3;
|
||||
m->AfListOffset = 0;
|
||||
m->AfListSize = 0;
|
||||
|
||||
rndis_state = rndis_initialized;
|
||||
|
||||
data_to_send = m->MessageLength;
|
||||
}
|
||||
break;
|
||||
case REMOTE_NDIS_HALT_MSG:
|
||||
|
||||
Led0_on();
|
||||
Led1_on();
|
||||
Led2_on();
|
||||
Led3_on();
|
||||
|
||||
|
||||
Usb_send_control_in();
|
||||
|
||||
while(1);
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case REMOTE_NDIS_QUERY_MSG:
|
||||
rndis_query_process();
|
||||
break;
|
||||
|
||||
case REMOTE_NDIS_SET_MSG:
|
||||
{
|
||||
rndis_set_process();
|
||||
}
|
||||
break;
|
||||
|
||||
case REMOTE_NDIS_RESET_MSG:
|
||||
{
|
||||
rndis_reset_cmplt_t * m;
|
||||
m = ((rndis_reset_cmplt_t *)encapsulated_buffer);
|
||||
|
||||
rndis_state = rndis_uninitialized;
|
||||
|
||||
m->MessageType = REMOTE_NDIS_RESET_CMPLT;
|
||||
m->MessageLength = sizeof(rndis_reset_cmplt_t);
|
||||
m->Status = RNDIS_STATUS_SUCCESS;
|
||||
m->AddressingReset = 1; /* Make it look like we did something */
|
||||
// m->AddressingReset = 0; //Windows halts if set to 1 for some reason
|
||||
data_to_send = m->MessageLength;
|
||||
}
|
||||
break;
|
||||
|
||||
case REMOTE_NDIS_KEEPALIVE_MSG:
|
||||
{
|
||||
rndis_keepalive_cmplt_t * m;
|
||||
m = (rndis_keepalive_cmplt_t *)encapsulated_buffer;
|
||||
m->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
|
||||
m->MessageLength = sizeof(rndis_keepalive_cmplt_t);
|
||||
m->Status = RNDIS_STATUS_SUCCESS;
|
||||
|
||||
//We have data to send back
|
||||
data_to_send = m->MessageLength;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Led2_on();
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
while(!(Is_usb_read_control_enabled()));
|
||||
|
||||
if (Is_usb_receive_out()) Usb_ack_receive_out();
|
||||
|
||||
rndis_send_interrupt();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Send an interrupt over the interrupt endpoint to the host.
|
||||
*/
|
||||
void rndis_send_interrupt(void)
|
||||
{
|
||||
|
||||
//Schedule the interrupt to take place next
|
||||
//time USB task is run
|
||||
schedule_interrupt = 1;
|
||||
}
|
||||
|
||||
#define INFBUF ((uint32_t *)(encapsulated_buffer + sizeof(rndis_query_cmplt_t)))
|
||||
|
||||
uint32_t oid_packet_filter = 0x0000000;
|
||||
|
||||
uint16_t panid = 0xbaad;
|
||||
|
||||
/**
|
||||
* \brief Function to handle a RNDIS "QUERY" command in the encapsulated_buffer
|
||||
*/
|
||||
void rndis_query_process(void)
|
||||
{
|
||||
rndis_query_msg_t * m;
|
||||
rndis_query_cmplt_t * c;
|
||||
rndis_Status_t status = RNDIS_STATUS_SUCCESS;
|
||||
|
||||
m = (rndis_query_msg_t *)encapsulated_buffer;
|
||||
c = (rndis_query_cmplt_t *)encapsulated_buffer;
|
||||
|
||||
/* We set up packet for sending one 4-byte response, which a lot of
|
||||
these will do. If you need more or less just change the defaults in
|
||||
the specific case */
|
||||
|
||||
c->MessageType = REMOTE_NDIS_QUERY_CMPLT;
|
||||
//c->Status DO NOT SET YET - as m->Oid resides in this space. We still need it...
|
||||
c->InformationBufferLength = 4;
|
||||
c->InformationBufferOffset = 16;
|
||||
|
||||
switch (m->Oid) {
|
||||
|
||||
/**** GENERAL ****/
|
||||
case OID_GEN_SUPPORTED_LIST:
|
||||
c->InformationBufferLength = 4 * OID_LIST_LENGTH;
|
||||
|
||||
//Copy data to SRAM
|
||||
memcpy_P(INFBUF, OIDSupportedList, 4*OID_LIST_LENGTH);
|
||||
break;
|
||||
|
||||
case OID_GEN_HARDWARE_STATUS:
|
||||
*INFBUF = 0x00000000; /* Ready and Willing */
|
||||
break;
|
||||
|
||||
case OID_GEN_MEDIA_SUPPORTED:
|
||||
case OID_GEN_MEDIA_IN_USE:
|
||||
*INFBUF = NDIS_MEDIUM_802_3; /* NDIS_MEDIUM_WIRELESS_LAN instead? */
|
||||
break;
|
||||
|
||||
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
||||
*INFBUF = (uint32_t) 1280; //1280 //102; /* Assume 25 octet header on 15.4 */
|
||||
break;
|
||||
|
||||
case OID_GEN_LINK_SPEED:
|
||||
*INFBUF = (uint32_t) 100; /* in 100 bytes/sec units.. this is kinda a lie */
|
||||
break;
|
||||
|
||||
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
||||
case OID_GEN_RECEIVE_BLOCK_SIZE:
|
||||
*INFBUF = (uint32_t) 102;
|
||||
break;
|
||||
|
||||
case OID_GEN_VENDOR_ID:
|
||||
*INFBUF = 0xFFFFFF; /* No vendor ID ! */
|
||||
break;
|
||||
|
||||
case OID_GEN_VENDOR_DESCRIPTION:
|
||||
c->InformationBufferLength = 8;
|
||||
memcpy_P(INFBUF, PSTR("Atmel\0\0\0\0"), 8);
|
||||
break;
|
||||
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
*INFBUF = oid_packet_filter;
|
||||
break;
|
||||
|
||||
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||||
*INFBUF = (uint32_t) 1300; //127;
|
||||
break;
|
||||
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||
*INFBUF = NDIS_MEDIA_STATE_CONNECTED;
|
||||
break;
|
||||
|
||||
case OID_GEN_VENDOR_DRIVER_VERSION:
|
||||
*INFBUF = 0x00001000;
|
||||
break;
|
||||
|
||||
case OID_GEN_PHYSICAL_MEDIUM:
|
||||
*INFBUF = NDIS_MEDIUM_802_3; /*NDIS_MEDIUM_WIRELESS_LAN;*/
|
||||
break;
|
||||
|
||||
case OID_GEN_CURRENT_LOOKAHEAD:
|
||||
*INFBUF = (uint32_t) 1280; //102;
|
||||
|
||||
/******* 802.3 (Ethernet) *******/
|
||||
|
||||
/*The address of the NIC encoded in the hardware.*/
|
||||
case OID_802_3_PERMANENT_ADDRESS:
|
||||
|
||||
//Clear unused bytes
|
||||
*(INFBUF + 1) = 0;
|
||||
|
||||
//Set address
|
||||
*((uint8_t *)INFBUF + 0) = *(((uint8_t * ) &rndis_ethernet_addr) + 5);
|
||||
*((uint8_t *)INFBUF + 1) = *(((uint8_t * ) &rndis_ethernet_addr) + 4);
|
||||
*((uint8_t *)INFBUF + 2) = *(((uint8_t * ) &rndis_ethernet_addr) + 3);
|
||||
*((uint8_t *)INFBUF + 3) = *(((uint8_t * ) &rndis_ethernet_addr) + 2);
|
||||
*((uint8_t *)INFBUF + 4) = *(((uint8_t * ) &rndis_ethernet_addr) + 1);
|
||||
*((uint8_t *)INFBUF + 5) = *(((uint8_t * ) &rndis_ethernet_addr) + 0);
|
||||
|
||||
|
||||
/*4+2 = 6 Bytes of eth address */
|
||||
c->InformationBufferLength += 2;
|
||||
break;
|
||||
|
||||
/*The address the NIC is currently using.*/
|
||||
case OID_802_3_CURRENT_ADDRESS:
|
||||
//Clear unused bytes
|
||||
*(INFBUF + 1) = 0;
|
||||
|
||||
//Set address
|
||||
*((uint8_t *)INFBUF + 0) = *(((uint8_t * ) &rndis_ethernet_addr) + 5);
|
||||
*((uint8_t *)INFBUF + 1) = *(((uint8_t * ) &rndis_ethernet_addr) + 4);
|
||||
*((uint8_t *)INFBUF + 2) = *(((uint8_t * ) &rndis_ethernet_addr) + 3);
|
||||
*((uint8_t *)INFBUF + 3) = *(((uint8_t * ) &rndis_ethernet_addr) + 2);
|
||||
*((uint8_t *)INFBUF + 4) = *(((uint8_t * ) &rndis_ethernet_addr) + 1);
|
||||
*((uint8_t *)INFBUF + 5) = *(((uint8_t * ) &rndis_ethernet_addr) + 0);
|
||||
|
||||
/*4+2 = 6 Bytes of eth address */
|
||||
c->InformationBufferLength += 2;
|
||||
break;
|
||||
|
||||
/* The multicast address list on the NIC enabled for packet reception. */
|
||||
case OID_802_3_MULTICAST_LIST:
|
||||
*INFBUF = 0xE000000;
|
||||
break;
|
||||
|
||||
/* The maximum number of multicast addresses the NIC driver can manage. */
|
||||
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||
*INFBUF = 1;
|
||||
break;
|
||||
|
||||
/* Features supported by the underlying driver, which could be emulating Ethernet. */
|
||||
case OID_802_3_MAC_OPTIONS:
|
||||
*INFBUF = 0;
|
||||
break;
|
||||
|
||||
/* Frames received with alignment error */
|
||||
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
||||
*INFBUF = 0;
|
||||
break;
|
||||
|
||||
/* Frames transmitted with one collision */
|
||||
case OID_802_3_XMIT_ONE_COLLISION:
|
||||
*INFBUF = 0;
|
||||
break;
|
||||
|
||||
/* Frames transmitted with more than one collision */
|
||||
case OID_802_3_XMIT_MORE_COLLISIONS:
|
||||
*INFBUF = 0;
|
||||
break;
|
||||
|
||||
|
||||
/*** 802.11 OIDs ***/
|
||||
case OID_802_11_BSSID:
|
||||
*INFBUF = (uint32_t)panid;
|
||||
*(INFBUF + 1) = 0;
|
||||
|
||||
/*4+2 = 6 Bytes of eth address */
|
||||
c->InformationBufferLength += 2;
|
||||
break;
|
||||
|
||||
case OID_802_11_SSID:
|
||||
/* Our SSID is *always* "PANID: 0xXXXX", length = 13 */
|
||||
*INFBUF = 13;
|
||||
|
||||
strncpy_P((char*)(INFBUF + 1), PSTR("PANID: 0xBAAD"), 13);
|
||||
break;
|
||||
|
||||
case OID_802_11_NETWORK_TYPE_IN_USE:
|
||||
*INFBUF = 0; /* Ndis802_11FH - it's all lies anyway */
|
||||
break;
|
||||
|
||||
case OID_802_11_RSSI:
|
||||
*((int32_t *) INFBUF) = -20; //-20 dBm
|
||||
break;
|
||||
|
||||
case OID_802_11_BSSID_LIST:
|
||||
break;
|
||||
|
||||
/* todo: */
|
||||
case OID_802_11_INFRASTRUCTURE_MODE:
|
||||
case OID_802_11_SUPPORTED_RATES:
|
||||
case OID_802_11_CONFIGURATION:
|
||||
case OID_802_11_WEP_STATUS:
|
||||
case OID_802_11_AUTHENTICATION_MODE:
|
||||
break;
|
||||
|
||||
/*** Statistical ***/
|
||||
|
||||
/* Frames transmitted without errors */
|
||||
case OID_GEN_XMIT_OK:
|
||||
*INFBUF = rndis_stat.txok;
|
||||
break;
|
||||
|
||||
/* Frames received without errors */
|
||||
case OID_GEN_RCV_OK:
|
||||
*INFBUF = rndis_stat.rxok;
|
||||
break;
|
||||
|
||||
/* Frames received with errors */
|
||||
case OID_GEN_RCV_ERROR:
|
||||
*INFBUF = rndis_stat.rxbad;
|
||||
break;
|
||||
|
||||
/* Frames transmitted with errors */
|
||||
case OID_GEN_XMIT_ERROR:
|
||||
*INFBUF = rndis_stat.txbad;
|
||||
break;
|
||||
|
||||
/* Frames dropped due to lack of buffer space */
|
||||
case OID_GEN_RCV_NO_BUFFER:
|
||||
|
||||
*INFBUF = 0; /* Lies! */
|
||||
break;
|
||||
|
||||
/*** Power Managment ***/
|
||||
case OID_PNP_CAPABILITIES:
|
||||
c->InformationBufferLength = sizeof(struct NDIS_PM_WAKE_UP_CAPABILITIES);
|
||||
|
||||
//Sorry, I don't play ball. Power managment is for hippies
|
||||
memset((char *)INFBUF, 0, sizeof(struct NDIS_PM_WAKE_UP_CAPABILITIES));
|
||||
break;
|
||||
|
||||
case OID_PNP_QUERY_POWER:
|
||||
c->InformationBufferLength = 0;
|
||||
break;
|
||||
|
||||
case OID_PNP_ENABLE_WAKE_UP:
|
||||
*INFBUF = 0; /* Nothing Supported */
|
||||
break;
|
||||
|
||||
default:
|
||||
status = RNDIS_STATUS_FAILURE;
|
||||
c->InformationBufferLength = 0;
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Set Status now that we are done with Oid
|
||||
c->Status = status;
|
||||
|
||||
//Calculate message size
|
||||
c->MessageLength = sizeof (rndis_query_cmplt_t) + c->InformationBufferLength;
|
||||
|
||||
//Check if we are sending no information buffer
|
||||
if (c->InformationBufferLength == 0) {
|
||||
c->InformationBufferOffset = 0;
|
||||
}
|
||||
|
||||
//Set it up
|
||||
data_to_send = c->MessageLength;
|
||||
}
|
||||
|
||||
|
||||
#undef INFBUF
|
||||
#define INFBUF ((uint32_t *)((uint8_t *)&(m->RequestId) + m->InformationBufferOffset))
|
||||
#define CFGBUF ((rndis_config_parameter_t *) INFBUF)
|
||||
#define PARMNAME ((uint8_t *)CFGBUF + CFGBUF->ParameterNameOffset)
|
||||
#define PARMVALUE ((uint8_t *)CFGBUF + CFGBUF->ParameterValueOffset)
|
||||
|
||||
#define PARM_NAME_LENGTH 25 /* Maximum parameter name length */
|
||||
|
||||
/**
|
||||
* \brief Function to deal with a RNDIS "SET" command present in the
|
||||
* encapsulated_buffer
|
||||
*/
|
||||
void rndis_set_process(void)
|
||||
{
|
||||
rndis_set_cmplt_t * c;
|
||||
rndis_set_msg_t * m;
|
||||
|
||||
c = ((rndis_set_cmplt_t *)encapsulated_buffer);
|
||||
m = ((rndis_set_msg_t *)encapsulated_buffer);
|
||||
|
||||
//Never have longer parameter names than PARM_NAME_LENGTH
|
||||
char parmname[PARM_NAME_LENGTH];
|
||||
|
||||
uint8_t i;
|
||||
int8_t parmlength;
|
||||
|
||||
/* The parameter name seems to be transmitted in uint16_t, but
|
||||
we want this in uint8_t. Hence have to throw out some info... */
|
||||
if (CFGBUF->ParameterNameLength > (PARM_NAME_LENGTH*2)) {
|
||||
parmlength = PARM_NAME_LENGTH * 2;
|
||||
} else {
|
||||
parmlength = CFGBUF->ParameterNameLength;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while(parmlength > 0) {
|
||||
//Convert from uint16_t to char array.
|
||||
parmname[i] = (char)*(PARMNAME + 2*i);
|
||||
parmlength -= 2;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
switch(m->Oid) {
|
||||
|
||||
/* Parameters set up in 'Advanced' tab */
|
||||
case OID_GEN_RNDIS_CONFIG_PARAMETER:
|
||||
/* Parameter name: rawmode
|
||||
Parameter desc: Enables or disable raw capture of 802.15.4 Packets
|
||||
Parameter type: single octet
|
||||
Parameter values: '0' = disabled, '1' = enabled
|
||||
*/
|
||||
if (strncmp_P(parmname, PSTR("rawmode"), 7) == 0) {
|
||||
if (*PARMVALUE == '0') {
|
||||
usbstick_mode.raw = 0;
|
||||
} else {
|
||||
usbstick_mode.raw = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
/* Mandatory general OIDs */
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
oid_packet_filter = *INFBUF;
|
||||
|
||||
if (oid_packet_filter) {
|
||||
|
||||
rndis_packetFilter(oid_packet_filter);
|
||||
|
||||
rndis_state = rndis_data_initialized;
|
||||
} else {
|
||||
rndis_state = rndis_initialized;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case OID_GEN_CURRENT_LOOKAHEAD:
|
||||
break;
|
||||
|
||||
case OID_GEN_PROTOCOL_OPTIONS:
|
||||
break;
|
||||
|
||||
/* Mandatory 802_3 OIDs */
|
||||
case OID_802_3_MULTICAST_LIST:
|
||||
break;
|
||||
|
||||
/* Mandatory 802.11 OIDs */
|
||||
case OID_802_11_BSSID:
|
||||
panid = *INFBUF;
|
||||
break;
|
||||
|
||||
case OID_802_11_SSID:
|
||||
break;
|
||||
//TODO: rest of 802.11
|
||||
|
||||
/* Power Managment: fails for now */
|
||||
case OID_PNP_ADD_WAKE_UP_PATTERN:
|
||||
case OID_PNP_REMOVE_WAKE_UP_PATTERN:
|
||||
case OID_PNP_ENABLE_WAKE_UP:
|
||||
|
||||
default:
|
||||
//c->MessageID is same as before
|
||||
c->MessageType = REMOTE_NDIS_SET_CMPLT;
|
||||
c->MessageLength = sizeof(rndis_set_cmplt_t);
|
||||
c->Status = RNDIS_STATUS_FAILURE;
|
||||
data_to_send = c->MessageLength;
|
||||
return;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//c->MessageID is same as before
|
||||
c->MessageType = REMOTE_NDIS_SET_CMPLT;
|
||||
c->MessageLength = sizeof(rndis_set_cmplt_t);
|
||||
c->Status = RNDIS_STATUS_SUCCESS;
|
||||
data_to_send = c->MessageLength;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Handle "GET ENCAPSULATED COMMAND"
|
||||
*
|
||||
* \return True on success, false on failure.
|
||||
*
|
||||
* This function assumes the message has already set up in
|
||||
* the "encapsulated_buffer" variable. This will be done by
|
||||
* the "SEND ENCAPSULATED COMMAND" message, which will trigger
|
||||
* and interrupt on the host so it knows data is ready.
|
||||
*/
|
||||
uint8_t get_encapsulated_command(void)
|
||||
{
|
||||
U8 nb_byte, zlp, i;
|
||||
|
||||
//We assume this is already set up...
|
||||
|
||||
//Received setup message OK
|
||||
Usb_ack_receive_setup();
|
||||
|
||||
if ((data_to_send % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; }
|
||||
else { zlp = FALSE; } //!< no need of zero length packet
|
||||
|
||||
|
||||
i = 0;
|
||||
while((data_to_send != 0) && (!Is_usb_receive_out()))
|
||||
{
|
||||
while(!Is_usb_read_control_enabled());
|
||||
|
||||
nb_byte=0;
|
||||
while(data_to_send != 0) //!< Send data until necessary
|
||||
{
|
||||
if(nb_byte++==EP_CONTROL_LENGTH) //!< Check endpoint 0 size
|
||||
{
|
||||
break;
|
||||
}
|
||||
Usb_write_byte(encapsulated_buffer[i]);
|
||||
i++;
|
||||
data_to_send--;
|
||||
|
||||
}
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
if(Is_usb_receive_out()) { Usb_ack_receive_out(); return TRUE; } //!< abort from Host
|
||||
|
||||
if(zlp == TRUE)
|
||||
{
|
||||
while(!Is_usb_read_control_enabled());
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
while(!Is_usb_receive_out());
|
||||
Usb_ack_receive_out();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Send a status packet back to the host
|
||||
*
|
||||
* \return Sucess or Failure
|
||||
* \retval 1 Success
|
||||
* \retval 0 Failure
|
||||
*/
|
||||
uint8_t rndis_send_status(rndis_Status_t stat)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if(Is_usb_read_control_enabled() && !data_to_send) {
|
||||
|
||||
rndis_indicate_status_t * m;
|
||||
m = (rndis_indicate_status_t *)encapsulated_buffer;
|
||||
|
||||
m->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
|
||||
m->MessageLength = sizeof(rndis_indicate_status_t);
|
||||
m->Status = stat;
|
||||
|
||||
for(i = 0; i < sizeof(rndis_indicate_status_t); i++) {
|
||||
Usb_write_byte(encapsulated_buffer[i]);
|
||||
}
|
||||
|
||||
Usb_send_control_in();
|
||||
while(!(Is_usb_read_control_enabled()));
|
||||
|
||||
while(!Is_usb_receive_out());
|
||||
Usb_ack_receive_out();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************** Radio Interface ****************/
|
||||
|
||||
/**
|
||||
* \brief Set the packet filter - currently distinguishes
|
||||
* between promiscuous mode and normal mode
|
||||
*/
|
||||
void rndis_packetFilter(uint32_t newfilter)
|
||||
{
|
||||
|
||||
if (newfilter & NDIS_PACKET_TYPE_PROMISCUOUS) {
|
||||
rxMode = RX_ON;
|
||||
radio_set_trx_state(RX_ON);
|
||||
} else {
|
||||
rxMode = RX_AACK_ON;
|
||||
radio_set_trx_state(RX_AACK_ON);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** @} */
|
325
cpu/avr/dev/usb/rndis/rndis_protocol.h
Normal file
325
cpu/avr/dev/usb/rndis/rndis_protocol.h
Normal file
|
@ -0,0 +1,325 @@
|
|||
/**
|
||||
* \file rndis_protocol.h
|
||||
* RNDIS Defines
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
* \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 <stdint.h>
|
||||
|
||||
#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;
|
||||
} rndis_stat_t;
|
||||
|
||||
extern rndis_stat_t rndis_stat;
|
||||
|
||||
extern rndis_state_t rndis_state;
|
||||
|
||||
extern uint8_t schedule_interrupt;
|
||||
|
||||
extern uint64_t rndis_ethernet_addr;
|
||||
|
||||
uint8_t send_encapsulated_command(uint16_t wLength);
|
||||
uint8_t get_encapsulated_command(void);
|
||||
void rndis_send_interrupt(void);
|
||||
void rndis_query_process(void);
|
||||
void rndis_set_process(void);
|
||||
uint8_t rndis_send_status(rndis_Status_t stat);
|
||||
|
||||
#endif //_RNDIS_H
|
||||
|
||||
/** @} */
|
422
cpu/avr/dev/usb/rndis/rndis_task.c
Normal file
422
cpu/avr/dev/usb/rndis/rndis_task.c
Normal file
|
@ -0,0 +1,422 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file rndis_task.c *********************************************************
|
||||
*
|
||||
* \brief
|
||||
* Manages the RNDIS Dataclass for the USB Device
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
/**
|
||||
\addtogroup RNDIS
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ___________________________________________________
|
||||
|
||||
|
||||
#include "contiki.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "rndis/rndis_task.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "uip.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
#define PRINTF printf
|
||||
#define PRINTF_P printf_P
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
|
||||
#define IAD_TIMEOUT_DETACH 400
|
||||
#define IAD_TIMEOUT_ATTACH 800
|
||||
|
||||
#define RNDIS_TIMEOUT_DETACH 900
|
||||
#define RNDIS_TIMEOUT_ATTACH 1000
|
||||
|
||||
#define PBUF ((rndis_data_packet_t *) data_buffer)
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
//! Timers for LEDs
|
||||
uint8_t led1_timer, led2_timer;
|
||||
|
||||
//! Temp data buffer when adding RNDIS headers
|
||||
uint8_t data_buffer[64];
|
||||
|
||||
//! Usb is busy with RNDIS
|
||||
char usb_busy = 0;
|
||||
|
||||
|
||||
static struct etimer et;
|
||||
static struct timer flood_timer;
|
||||
static uint16_t iad_fail_timeout, rndis_fail_timeout;
|
||||
|
||||
static uint8_t doInit = 1;
|
||||
|
||||
extern uint8_t fingerPresent;
|
||||
|
||||
PROCESS(rndis_process, "RNDIS process");
|
||||
|
||||
/**
|
||||
* \brief RNDIS Process
|
||||
*
|
||||
* This is the link between USB and the "good stuff". In this routine data
|
||||
* is received and processed by RNDIS
|
||||
*/
|
||||
PROCESS_THREAD(rndis_process, ev, data_proc)
|
||||
{
|
||||
|
||||
PROCESS_BEGIN();
|
||||
uint8_t bytecounter, headercounter;
|
||||
uint16_t i, dataoffset;
|
||||
|
||||
while(1) {
|
||||
|
||||
// turn off LED's if necessary
|
||||
if (led1_timer) led1_timer--;
|
||||
else Led1_off();
|
||||
if (led2_timer) led2_timer--;
|
||||
else Led2_off();
|
||||
|
||||
/* Device is Enumerated but RNDIS not loading. We might
|
||||
have a system that does not support IAD (winXP). If so
|
||||
count the timeout then switch to just network interface. */
|
||||
if (usb_mode == rndis_debug) {
|
||||
//If we have timed out, detach
|
||||
if (iad_fail_timeout == IAD_TIMEOUT_DETACH) {
|
||||
|
||||
//Failed - BUT we are using "reverse logic", hence we force device
|
||||
//into this mode. This is used to allow Windows Vista have time to
|
||||
//install the drivers
|
||||
if (fingerPresent && (rndis_state != rndis_data_initialized) && Is_device_enumerated() ) {
|
||||
iad_fail_timeout = 0;
|
||||
} else {
|
||||
stdout = NULL;
|
||||
Usb_detach();
|
||||
doInit = 1; //Also mark system as needing intilizing
|
||||
}
|
||||
|
||||
//Then wait a few before re-attaching
|
||||
} else if (iad_fail_timeout == IAD_TIMEOUT_ATTACH) {
|
||||
|
||||
if (fingerPresent) {
|
||||
usb_mode = mass_storage;
|
||||
} else {
|
||||
usb_mode = rndis_only;
|
||||
}
|
||||
Usb_attach();
|
||||
}
|
||||
|
||||
//Increment timeout when device is not initializing, OR we have already detached,
|
||||
//OR the user had their finger on the device, indicating a reverse of logic
|
||||
if ( ( (rndis_state != rndis_data_initialized) && Is_device_enumerated() ) ||
|
||||
(iad_fail_timeout > IAD_TIMEOUT_DETACH) ||
|
||||
(fingerPresent) ) {
|
||||
iad_fail_timeout++;
|
||||
} else {
|
||||
iad_fail_timeout = 0;
|
||||
}
|
||||
} //usb_mode == rndis_debug
|
||||
|
||||
|
||||
/* Device is Enumerated but RNDIS STIL not loading. We just
|
||||
have RNDIS interface, so obviously no drivers on target.
|
||||
Just go ahead and mount ourselves as mass storage... */
|
||||
if (usb_mode == rndis_only) {
|
||||
//If we have timed out, detach
|
||||
if (rndis_fail_timeout == RNDIS_TIMEOUT_DETACH) {
|
||||
Usb_detach();
|
||||
//Then wait a few before re-attaching
|
||||
} else if (rndis_fail_timeout == RNDIS_TIMEOUT_ATTACH) {
|
||||
usb_mode = mass_storage;
|
||||
Usb_attach();
|
||||
}
|
||||
|
||||
//Increment timeout when device is not initializing, OR we are already
|
||||
//counting to detach
|
||||
if ( ( (rndis_state != rndis_data_initialized)) ||
|
||||
(rndis_fail_timeout > RNDIS_TIMEOUT_DETACH) ) {
|
||||
rndis_fail_timeout++;
|
||||
} else {
|
||||
rndis_fail_timeout = 0;
|
||||
}
|
||||
}//usb_mode == rnids_only
|
||||
|
||||
|
||||
if(rndis_state == rndis_data_initialized) //Enumeration processs OK ?
|
||||
{
|
||||
if (doInit) {
|
||||
//start flood timer
|
||||
timer_set(&flood_timer, CLOCK_SECOND / 5);
|
||||
|
||||
mac_ethernetSetup();
|
||||
doInit = 0;
|
||||
}
|
||||
|
||||
//Connected!
|
||||
Led0_on();
|
||||
|
||||
Usb_select_endpoint(RX_EP);
|
||||
|
||||
//If we have data and a free buffer
|
||||
if(Is_usb_receive_out() && (uip_len == 0)) {
|
||||
|
||||
//TODO: Fix this some better way
|
||||
//If you need a delay in RNDIS to slow down super-fast sending, insert it here
|
||||
//Also mark the USB as "in use"
|
||||
|
||||
//This is done as "flood control" by only allowing one IP packet per time limit
|
||||
clock_time_t timediff = clock_time() - flood_timer.start;
|
||||
|
||||
|
||||
//If timer not yet expired
|
||||
if (timediff < flood_timer.interval) {
|
||||
//Wait until timer expiers
|
||||
usb_busy = 1;
|
||||
etimer_set(&et, flood_timer.interval - timediff);
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
|
||||
|
||||
//Reselect endpoint in case we lost it
|
||||
Usb_select_endpoint(RX_EP);
|
||||
usb_busy = 0;
|
||||
}
|
||||
|
||||
//Restart flood timer
|
||||
timer_restart(&flood_timer);
|
||||
|
||||
//Read how much (endpoint only stores up to 64 bytes anyway)
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
|
||||
//Try and read the header in
|
||||
headercounter = sizeof(rndis_data_packet_t);
|
||||
|
||||
//Hmm.. what's going on here
|
||||
if (bytecounter < headercounter) {
|
||||
Usb_ack_receive_out();
|
||||
break;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (headercounter) {
|
||||
data_buffer[i] = Usb_read_byte();
|
||||
bytecounter--;
|
||||
headercounter--;
|
||||
i++;
|
||||
}
|
||||
|
||||
//This is no good. Probably lost syncronization... just drop it for now
|
||||
if(PBUF->MessageType != REMOTE_NDIS_PACKET_MSG) {
|
||||
Usb_ack_receive_out();
|
||||
break;
|
||||
}
|
||||
|
||||
//Looks like we've got a live one
|
||||
rx_start_led();
|
||||
|
||||
|
||||
//802.3 does not have OOB data, and we don't care about per-packet data
|
||||
//so that just leave regular packet data...
|
||||
if (PBUF->DataLength) {
|
||||
|
||||
//Get offset
|
||||
dataoffset = PBUF->DataOffset;
|
||||
|
||||
//Make it offset from start of message, not DataOffset field
|
||||
dataoffset += (sizeof(rndis_MessageType_t) + sizeof(rndis_MessageLength_t));
|
||||
|
||||
//Subtract what we already took
|
||||
dataoffset -= sizeof(rndis_data_packet_t);
|
||||
|
||||
//Read to the start of data
|
||||
while(dataoffset) {
|
||||
Usb_read_byte();
|
||||
dataoffset--;
|
||||
bytecounter--;
|
||||
|
||||
//If endpoint is done
|
||||
if (bytecounter == 0) {
|
||||
|
||||
Usb_ack_receive_out();
|
||||
|
||||
|
||||
//Wait for new data
|
||||
while (!Is_usb_receive_out());
|
||||
|
||||
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Read the data itself in
|
||||
uint8_t * uipdata = uip_buf;
|
||||
uint16_t datalen = PBUF->DataLength;
|
||||
|
||||
while(datalen) {
|
||||
*uipdata++ = Usb_read_byte();
|
||||
datalen--;
|
||||
bytecounter--;
|
||||
|
||||
//If endpoint is done
|
||||
if (bytecounter == 0) {
|
||||
//Might be everything we need!
|
||||
if (datalen) {
|
||||
Usb_ack_receive_out();
|
||||
//Wait for new data
|
||||
while (!Is_usb_receive_out());
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Ack final data packet
|
||||
Usb_ack_receive_out();
|
||||
|
||||
/*** SEND DATA TO UIP ***/
|
||||
if(BUF->type == htons(UIP_ETHTYPE_IPV6)) {
|
||||
|
||||
//Send data over RF or to local stack
|
||||
uip_len = PBUF->DataLength; //uip_len includes LLH_LEN
|
||||
mac_ethernetToLowpan(uip_buf);
|
||||
}
|
||||
|
||||
} //if (PBUF->DataLength)
|
||||
|
||||
|
||||
} //if(Is_usb_receive_out() && (uip_len == 0))
|
||||
|
||||
} // if (rndis_data_intialized)
|
||||
|
||||
if ((usb_mode == rndis_only) || (usb_mode == rndis_debug)) {
|
||||
etimer_set(&et, CLOCK_SECOND/80);
|
||||
} else {
|
||||
etimer_set(&et, CLOCK_SECOND);
|
||||
}
|
||||
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
|
||||
} // while(1)
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Send data over RNDIS interface, data is in uipbuf and length is uiplen
|
||||
*/
|
||||
uint8_t rndis_send(uint8_t * senddata, uint16_t sendlen)
|
||||
{
|
||||
|
||||
|
||||
uint16_t i;
|
||||
|
||||
//Setup Header
|
||||
PBUF->MessageType = REMOTE_NDIS_PACKET_MSG;
|
||||
PBUF->DataOffset = sizeof(rndis_data_packet_t) - sizeof(rndis_MessageType_t) - sizeof(rndis_MessageLength_t);
|
||||
PBUF->DataLength = sendlen;
|
||||
PBUF->OOBDataLength = 0;
|
||||
PBUF->OOBDataOffset = 0;
|
||||
PBUF->NumOOBDataElements = 0;
|
||||
PBUF->PerPacketInfoOffset = 0;
|
||||
PBUF->PerPacketInfoLength = 0;
|
||||
PBUF->DeviceVcHandle = 0;
|
||||
PBUF->Reserved = 0;
|
||||
PBUF->MessageLength = sizeof(rndis_data_packet_t) + PBUF->DataLength;
|
||||
|
||||
//Send Data
|
||||
Usb_select_endpoint(TX_EP);
|
||||
Usb_send_in();
|
||||
|
||||
//Wait for ready
|
||||
while(!Is_usb_write_enabled());
|
||||
|
||||
//Setup first part of transfer...
|
||||
for(i = 0; i < sizeof(rndis_data_packet_t); i++) {
|
||||
Usb_write_byte(data_buffer[i]);
|
||||
}
|
||||
|
||||
//Send packet
|
||||
while(sendlen) {
|
||||
Usb_write_byte(*senddata);
|
||||
senddata++;
|
||||
sendlen--;
|
||||
|
||||
//If endpoint is full, send data in
|
||||
//And then wait for data to transfer
|
||||
if (!Is_usb_write_enabled()) {
|
||||
Usb_send_in();
|
||||
|
||||
while(!Is_usb_write_enabled());
|
||||
}
|
||||
|
||||
tx_end_led();
|
||||
}
|
||||
|
||||
Usb_send_in();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief This will enable the RX_START LED for a period
|
||||
*/
|
||||
void rx_start_led(void)
|
||||
{
|
||||
Led1_on();
|
||||
led1_timer = 10;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief This will enable the TRX_END LED for a period
|
||||
*/
|
||||
void tx_end_led(void)
|
||||
{
|
||||
Led2_on();
|
||||
led2_timer = 10;
|
||||
}
|
||||
/** @} */
|
75
cpu/avr/dev/usb/rndis/rndis_task.h
Normal file
75
cpu/avr/dev/usb/rndis/rndis_task.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file rndis_task.h *********************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file manages the RNDIS task
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
Copyright (c) 2008 Colin O'Flynn
|
||||
All rights reserved.
|
||||
|
||||
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_TASK_H_
|
||||
#define _RNDIS_TASK_H_
|
||||
|
||||
/**
|
||||
\addtogroup RNDIS
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
uint8_t rndis_send(uint8_t * senddata, uint16_t sendlen);
|
||||
void sof_action(void);
|
||||
void rx_start_led(void);
|
||||
void tx_end_led(void);
|
||||
|
||||
extern char usb_busy;
|
||||
|
||||
PROCESS_NAME(rndis_process);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _RNDIS_TASK_H_ */
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue