mirror of
https://github.com/hathach/tinyusb.git
synced 2025-02-11 00:39:57 +00:00
add CDC-ECM/RNDIS/CDC-EEM network device class with example
This commit is contained in:
parent
43025b2ae3
commit
fee79d7466
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -21,4 +21,7 @@
|
||||
url = https://github.com/hathach/microchip_driver.git
|
||||
[submodule "hw/mcu/nuvoton"]
|
||||
path = hw/mcu/nuvoton
|
||||
url = https://github.com/majbthrd/nuc_driver.git
|
||||
url = https://github.com/majbthrd/nuc_driver.git
|
||||
[submodule "lib/lwip"]
|
||||
path = lib/lwip
|
||||
url = https://git.savannah.nongnu.org/git/lwip.git
|
||||
|
57
examples/device/lwip_webserver/Makefile
Normal file
57
examples/device/lwip_webserver/Makefile
Normal file
@ -0,0 +1,57 @@
|
||||
include ../../../tools/top.mk
|
||||
include ../../make.mk
|
||||
|
||||
CFLAGS += \
|
||||
-DPBUF_POOL_SIZE=2 \
|
||||
-DTCP_WND=2*TCP_MSS \
|
||||
-DHTTPD_USE_CUSTOM_FSDATA=0
|
||||
|
||||
INC += \
|
||||
src \
|
||||
$(TOP)/hw \
|
||||
$(TOP)/lib/lwip/src/include \
|
||||
$(TOP)/lib/lwip/src/include/ipv4 \
|
||||
$(TOP)/lib/lwip/src/include/lwip/apps \
|
||||
$(TOP)/lib/networking
|
||||
|
||||
# Example source
|
||||
EXAMPLE_SOURCE += $(wildcard src/*.c)
|
||||
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
|
||||
SRC_C += \
|
||||
lib/lwip/src/core/altcp.c \
|
||||
lib/lwip/src/core/altcp_alloc.c \
|
||||
lib/lwip/src/core/altcp_tcp.c \
|
||||
lib/lwip/src/core/def.c \
|
||||
lib/lwip/src/core/dns.c \
|
||||
lib/lwip/src/core/inet_chksum.c \
|
||||
lib/lwip/src/core/init.c \
|
||||
lib/lwip/src/core/ip.c \
|
||||
lib/lwip/src/core/mem.c \
|
||||
lib/lwip/src/core/memp.c \
|
||||
lib/lwip/src/core/netif.c \
|
||||
lib/lwip/src/core/pbuf.c \
|
||||
lib/lwip/src/core/raw.c \
|
||||
lib/lwip/src/core/stats.c \
|
||||
lib/lwip/src/core/sys.c \
|
||||
lib/lwip/src/core/tcp.c \
|
||||
lib/lwip/src/core/tcp_in.c \
|
||||
lib/lwip/src/core/tcp_out.c \
|
||||
lib/lwip/src/core/timeouts.c \
|
||||
lib/lwip/src/core/udp.c \
|
||||
lib/lwip/src/core/ipv4/autoip.c \
|
||||
lib/lwip/src/core/ipv4/dhcp.c \
|
||||
lib/lwip/src/core/ipv4/etharp.c \
|
||||
lib/lwip/src/core/ipv4/icmp.c \
|
||||
lib/lwip/src/core/ipv4/igmp.c \
|
||||
lib/lwip/src/core/ipv4/ip4.c \
|
||||
lib/lwip/src/core/ipv4/ip4_addr.c \
|
||||
lib/lwip/src/core/ipv4/ip4_frag.c \
|
||||
lib/lwip/src/netif/ethernet.c \
|
||||
lib/lwip/src/netif/slipif.c \
|
||||
lib/lwip/src/apps/http/httpd.c \
|
||||
lib/lwip/src/apps/http/fs.c \
|
||||
lib/networking/dhserver.c \
|
||||
lib/networking/dnserver.c \
|
||||
lib/networking/rndis_reports.c
|
||||
|
||||
include ../../rules.mk
|
75
examples/device/lwip_webserver/src/arch/cc.h
Normal file
75
examples/device/lwip_webserver/src/arch/cc.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __CC_H__
|
||||
#define __CC_H__
|
||||
|
||||
//#include "cpu.h"
|
||||
|
||||
typedef int sys_prot_t;
|
||||
|
||||
|
||||
|
||||
/* define compiler specific symbols */
|
||||
#if defined (__ICCARM__)
|
||||
|
||||
#define PACK_STRUCT_BEGIN
|
||||
#define PACK_STRUCT_STRUCT
|
||||
#define PACK_STRUCT_END
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
#define PACK_STRUCT_USE_INCLUDES
|
||||
|
||||
#elif defined (__CC_ARM)
|
||||
|
||||
#define PACK_STRUCT_BEGIN __packed
|
||||
#define PACK_STRUCT_STRUCT
|
||||
#define PACK_STRUCT_END
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
|
||||
#elif defined (__GNUC__)
|
||||
|
||||
#define PACK_STRUCT_BEGIN
|
||||
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
|
||||
#define PACK_STRUCT_END
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
|
||||
#elif defined (__TASKING__)
|
||||
|
||||
#define PACK_STRUCT_BEGIN
|
||||
#define PACK_STRUCT_STRUCT
|
||||
#define PACK_STRUCT_END
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
|
||||
#endif
|
||||
|
||||
#define LWIP_PLATFORM_ASSERT(x) do { if(!(x)) while(1); } while(0)
|
||||
|
||||
#endif /* __CC_H__ */
|
57
examples/device/lwip_webserver/src/lwipopts.h
Normal file
57
examples/device/lwip_webserver/src/lwipopts.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Simon Goldschmidt
|
||||
*
|
||||
*/
|
||||
#ifndef __LWIPOPTS_H__
|
||||
#define __LWIPOPTS_H__
|
||||
|
||||
/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */
|
||||
#define NO_SYS 1
|
||||
#define MEM_ALIGNMENT 4
|
||||
#define LWIP_RAW 1
|
||||
#define LWIP_NETCONN 0
|
||||
#define LWIP_SOCKET 0
|
||||
#define LWIP_DHCP 0
|
||||
#define LWIP_ICMP 1
|
||||
#define LWIP_UDP 1
|
||||
#define LWIP_TCP 1
|
||||
#define ETH_PAD_SIZE 0
|
||||
#define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67))
|
||||
|
||||
#define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/)
|
||||
#define TCP_SND_BUF (2 * TCP_MSS)
|
||||
|
||||
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
|
||||
|
||||
#define LWIP_HTTPD_CGI 0
|
||||
#define LWIP_HTTPD_SSI 0
|
||||
#define LWIP_HTTPD_SSI_INCLUDE_TAG 0
|
||||
|
||||
#endif /* __LWIPOPTS_H__ */
|
214
examples/device/lwip_webserver/src/main.c
Normal file
214
examples/device/lwip_webserver/src/main.c
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Peter Lawrence
|
||||
*
|
||||
* influenced by lrndis https://github.com/fetisov/lrndis
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
depending on the value of CFG_TUD_NET (tusb_config.h), this can be a CDC-ECM, RNDIS, or CDC-EEM USB virtual network adapter
|
||||
|
||||
CDC-ECM should be valid on Linux and MacOS hosts
|
||||
RNDIS should be valid on Linux and Windows hosts
|
||||
CDC-EEM should be valid on Linux hosts
|
||||
|
||||
You *must* customize tusb_config.h to set the CFG_TUD_NET definition to the type of these network adapters to emulate.
|
||||
|
||||
The MCU appears to the host as IP address 192.168.7.1, and provides a DHCP server, DNS server, and web server.
|
||||
*/
|
||||
|
||||
#include "bsp/board.h"
|
||||
#include "tusb.h"
|
||||
|
||||
#include "dhserver.h"
|
||||
#include "dnserver.h"
|
||||
#include "lwip/init.h"
|
||||
#include "httpd.h"
|
||||
|
||||
/* lwip context */
|
||||
static struct netif netif_data;
|
||||
|
||||
/* shared between network_recv_callback() and service_traffic() */
|
||||
static struct pbuf *received_frame;
|
||||
|
||||
/* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */
|
||||
/* ideally speaking, this should be generated from the hardware's unique ID (if available) */
|
||||
const uint8_t network_mac_address[6] = {0x20,0x89,0x84,0x6A,0x96,0x00};
|
||||
|
||||
/* network parameters of this MCU */
|
||||
static const ip_addr_t ipaddr = IPADDR4_INIT_BYTES(192, 168, 7, 1);
|
||||
static const ip_addr_t netmask = IPADDR4_INIT_BYTES(255, 255, 255, 0);
|
||||
static const ip_addr_t gateway = IPADDR4_INIT_BYTES(0, 0, 0, 0);
|
||||
|
||||
/* database IP addresses that can be offered to the host; this must be in RAM to store assigned MAC addresses */
|
||||
static dhcp_entry_t entries[] =
|
||||
{
|
||||
/* mac ip address subnet mask lease time */
|
||||
{ {0}, {192, 168, 7, 2}, {255, 255, 255, 0}, 24 * 60 * 60 },
|
||||
{ {0}, {192, 168, 7, 3}, {255, 255, 255, 0}, 24 * 60 * 60 },
|
||||
{ {0}, {192, 168, 7, 4}, {255, 255, 255, 0}, 24 * 60 * 60 }
|
||||
};
|
||||
|
||||
/* DHCP configuration parameters, leveraging "entries" above */
|
||||
static const dhcp_config_t dhcp_config =
|
||||
{
|
||||
{192, 168, 7, 1}, 67, /* server address (self), port */
|
||||
{192, 168, 7, 1}, /* dns server (self) */
|
||||
"usb", /* dns suffix */
|
||||
TU_ARRAY_SIZE(entries), /* number of entries */
|
||||
entries /* pointer to entries */
|
||||
};
|
||||
|
||||
static err_t linkoutput_fn(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
(void)netif;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */
|
||||
if (!tud_ready())
|
||||
return ERR_USE;
|
||||
|
||||
/* if the network driver can accept another packet, we make it happen */
|
||||
if (network_can_xmit())
|
||||
{
|
||||
network_xmit(p);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/* transfer execution to TinyUSB in the hopes that it will finish transmitting the prior packet */
|
||||
tud_task();
|
||||
}
|
||||
}
|
||||
|
||||
static err_t output_fn(struct netif *netif, struct pbuf *p, const ip_addr_t *addr)
|
||||
{
|
||||
return etharp_output(netif, p, addr);
|
||||
}
|
||||
|
||||
static err_t netif_init_cb(struct netif *netif)
|
||||
{
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
netif->mtu = CFG_TUD_NET_MTU;
|
||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
|
||||
netif->state = NULL;
|
||||
netif->name[0] = 'E';
|
||||
netif->name[1] = 'X';
|
||||
netif->linkoutput = linkoutput_fn;
|
||||
netif->output = output_fn;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static void init_lwip(void)
|
||||
{
|
||||
struct netif *netif = &netif_data;
|
||||
|
||||
lwip_init();
|
||||
netif->hwaddr_len = sizeof(network_mac_address);
|
||||
memcpy(netif->hwaddr, network_mac_address, sizeof(network_mac_address));
|
||||
|
||||
netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, netif_init_cb, ip_input);
|
||||
netif_set_default(netif);
|
||||
}
|
||||
|
||||
/* handle any DNS requests from dns-server */
|
||||
bool dns_query_proc(const char *name, ip_addr_t *addr)
|
||||
{
|
||||
if (0 == strcmp(name, "tiny.usb"))
|
||||
{
|
||||
*addr = ipaddr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool network_recv_callback(struct pbuf *p)
|
||||
{
|
||||
/* this shouldn't happen, but if we get another packet before
|
||||
parsing the previous, we must signal our inability to accept it */
|
||||
if (received_frame) return false;
|
||||
|
||||
/* store away the pointer for service_traffic() to later handle */
|
||||
received_frame = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void service_traffic(void)
|
||||
{
|
||||
/* handle any packet received by network_recv_callback() */
|
||||
if (received_frame)
|
||||
{
|
||||
ethernet_input(received_frame, &netif_data);
|
||||
pbuf_free(received_frame);
|
||||
received_frame = NULL;
|
||||
network_recv_renew();
|
||||
}
|
||||
}
|
||||
|
||||
void network_init_callback(void)
|
||||
{
|
||||
/* if the network is re-initializing and we have a leftover packet, we must do a cleanup */
|
||||
if (received_frame)
|
||||
{
|
||||
pbuf_free(received_frame);
|
||||
received_frame = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* initialize TinyUSB */
|
||||
board_init();
|
||||
tusb_init();
|
||||
|
||||
/* initialize lwip, dhcp-server, dns-server, and http */
|
||||
init_lwip();
|
||||
while (!netif_is_up(&netif_data));
|
||||
while (dhserv_init(&dhcp_config) != ERR_OK);
|
||||
while (dnserv_init(&ipaddr, 53, dns_query_proc) != ERR_OK);
|
||||
httpd_init();
|
||||
|
||||
while (1)
|
||||
{
|
||||
tud_task();
|
||||
service_traffic();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* lwip has provision for using a mutex, when applicable */
|
||||
sys_prot_t sys_arch_protect(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void sys_arch_unprotect(sys_prot_t pval)
|
||||
{
|
||||
(void)pval;
|
||||
}
|
||||
|
||||
/* lwip needs a millisecond time source, and the TinyUSB board support code has one available */
|
||||
uint32_t sys_now(void)
|
||||
{
|
||||
return board_millis();
|
||||
}
|
90
examples/device/lwip_webserver/src/tusb_config.h
Normal file
90
examples/device/lwip_webserver/src/tusb_config.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// COMMON CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// defined by compiler flags for flexibility
|
||||
#ifndef CFG_TUSB_MCU
|
||||
#error CFG_TUSB_MCU must be defined
|
||||
#endif
|
||||
|
||||
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
|
||||
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
|
||||
#else
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||
* into those specific section.
|
||||
* e.g
|
||||
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
|
||||
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
|
||||
*/
|
||||
#ifndef CFG_TUSB_MEM_SECTION
|
||||
#define CFG_TUSB_MEM_SECTION
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_MEM_ALIGN
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// DEVICE CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||
#endif
|
||||
|
||||
//------------- CLASS -------------//
|
||||
#define CFG_TUD_CDC 0
|
||||
#define CFG_TUD_MSC 0
|
||||
#define CFG_TUD_HID 0
|
||||
#define CFG_TUD_MIDI 0
|
||||
#define CFG_TUD_VENDOR 0
|
||||
//#define CFG_TUD_NET OPT_NET_ECM
|
||||
#define CFG_TUD_NET OPT_NET_RNDIS
|
||||
//#define CFG_TUD_NET OPT_NET_EEM
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
199
examples/device/lwip_webserver/src/usb_descriptors.c
Normal file
199
examples/device/lwip_webserver/src/usb_descriptors.c
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tusb.h"
|
||||
#include "usb_descriptors.h"
|
||||
|
||||
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
|
||||
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
|
||||
*
|
||||
* Auto ProductID layout's Bitmap:
|
||||
* [MSB] NET1:NET0 | VENDOR | MIDI | HID | MSC | CDC [LSB]
|
||||
*/
|
||||
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
|
||||
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
|
||||
_PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) | _PID_MAP(NET, 5) )
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Device Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
tusb_desc_device_t const desc_device =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_device_t),
|
||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||
.bcdUSB = 0x0200,
|
||||
|
||||
.bDeviceClass = TUSB_CLASS_UNSPECIFIED,
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||
|
||||
.idVendor = 0xCafe,
|
||||
.idProduct = USB_PID,
|
||||
.bcdDevice = 0x0100,
|
||||
|
||||
.iManufacturer = 0x01,
|
||||
.iProduct = 0x02,
|
||||
.iSerialNumber = 0x03,
|
||||
|
||||
.bNumConfigurations = 0x01
|
||||
};
|
||||
|
||||
// Invoked when received GET DEVICE DESCRIPTOR
|
||||
// Application return pointer to descriptor
|
||||
uint8_t const * tud_descriptor_device_cb(void)
|
||||
{
|
||||
return (uint8_t const *) &desc_device;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Configuration Descriptor
|
||||
//--------------------------------------------------------------------+
|
||||
enum
|
||||
{
|
||||
ITF_NUM_CDC = 0,
|
||||
ITF_NUM_CDC_DATA,
|
||||
ITF_NUM_TOTAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
STR_LANGID = 0,
|
||||
STR_MANUFACTURER,
|
||||
STR_PRODUCT,
|
||||
STR_ITFNAME,
|
||||
STR_MAC,
|
||||
};
|
||||
|
||||
#if CFG_TUD_NET == OPT_NET_ECM
|
||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_ECM_DESC_LEN)
|
||||
#elif CFG_TUD_NET == OPT_NET_RNDIS
|
||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_RNDIS_DESC_LEN)
|
||||
#elif CFG_TUD_NET == OPT_NET_EEM
|
||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_EEM_DESC_LEN)
|
||||
#endif
|
||||
|
||||
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
|
||||
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
|
||||
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
|
||||
#define EPNUM_CDC 2
|
||||
#else
|
||||
#define EPNUM_CDC 2
|
||||
#endif
|
||||
|
||||
uint8_t const desc_configuration[] =
|
||||
{
|
||||
// Interface count, string index, total length, attribute, power in mA
|
||||
TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 100),
|
||||
|
||||
#if CFG_TUD_NET == OPT_NET_ECM
|
||||
// Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size.
|
||||
TUD_CDC_ECM_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, STR_MAC, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU),
|
||||
#elif CFG_TUD_NET == OPT_NET_RNDIS
|
||||
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||
TUD_RNDIS_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE),
|
||||
#elif CFG_TUD_NET == OPT_NET_EEM
|
||||
// Interface number, description string index, EP data address (out, in) and size.
|
||||
TUD_CDC_EEM_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE),
|
||||
#endif
|
||||
};
|
||||
|
||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||
// Application return pointer to descriptor
|
||||
// Descriptor contents must exist long enough for transfer to complete
|
||||
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
|
||||
{
|
||||
(void) index; // for multiple configurations
|
||||
return desc_configuration;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// String Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// array of pointer to string descriptors
|
||||
char const* string_desc_arr [] =
|
||||
{
|
||||
[STR_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409)
|
||||
[STR_MANUFACTURER] = "TinyUSB", // Manufacturer
|
||||
[STR_PRODUCT] = "TinyUSB Device", // Product
|
||||
[STR_ITFNAME] = // CDC-ECM Interface
|
||||
#if CFG_TUD_NET == OPT_NET_ECM
|
||||
"TinyUSB CDC-ECM",
|
||||
#elif CFG_TUD_NET == OPT_NET_RNDIS
|
||||
"TinyUSB RNDIS",
|
||||
#elif CFG_TUD_NET == OPT_NET_EEM
|
||||
"TinyUSB CDC-EEM",
|
||||
#endif
|
||||
};
|
||||
|
||||
static uint16_t _desc_str[32];
|
||||
|
||||
// Invoked when received GET STRING DESCRIPTOR request
|
||||
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
|
||||
{
|
||||
(void)langid;
|
||||
|
||||
unsigned chr_count = 0;
|
||||
|
||||
if (STR_LANGID == index)
|
||||
{
|
||||
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||
chr_count = 1;
|
||||
}
|
||||
else if (STR_MAC == index)
|
||||
{
|
||||
// Convert MAC address into UTF-16
|
||||
|
||||
for (unsigned i=0; i<sizeof(network_mac_address); i++)
|
||||
{
|
||||
_desc_str[1+chr_count++] = "0123456789ABCDEF"[(network_mac_address[i] >> 4) & 0xf];
|
||||
_desc_str[1+chr_count++] = "0123456789ABCDEF"[(network_mac_address[i] >> 0) & 0xf];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert ASCII string into UTF-16
|
||||
|
||||
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
|
||||
|
||||
const char* str = string_desc_arr[index];
|
||||
|
||||
// Cap at max char
|
||||
chr_count = strlen(str);
|
||||
if ( chr_count > (TU_ARRAY_SIZE(_desc_str) - 1)) chr_count = TU_ARRAY_SIZE(_desc_str) - 1;
|
||||
|
||||
for (unsigned i=0; i<chr_count; i++)
|
||||
{
|
||||
_desc_str[1+i] = str[i];
|
||||
}
|
||||
}
|
||||
|
||||
// first byte is length (including header), second byte is string type
|
||||
_desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);
|
||||
|
||||
return _desc_str;
|
||||
}
|
28
examples/device/lwip_webserver/src/usb_descriptors.h
Normal file
28
examples/device/lwip_webserver/src/usb_descriptors.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef USB_DESCRIPTORS_H_
|
||||
#define USB_DESCRIPTORS_H_
|
||||
|
||||
#endif /* USB_DESCRIPTORS_H_ */
|
@ -22,6 +22,7 @@ SRC_C += \
|
||||
src/class/midi/midi_device.c \
|
||||
src/class/usbtmc/usbtmc_device.c \
|
||||
src/class/vendor/vendor_device.c \
|
||||
src/class/net/net_device.c \
|
||||
src/portable/$(VENDOR)/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c
|
||||
|
||||
# TinyUSB stack include
|
||||
|
1
lib/lwip
Submodule
1
lib/lwip
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 0192fe773ec28e11f66ec76f4e827fbb58b7e257
|
347
lib/networking/dhserver.c
Normal file
347
lib/networking/dhserver.c
Normal file
@ -0,0 +1,347 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 by Sergey Fetisov <fsenok@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "dhserver.h"
|
||||
|
||||
/* DHCP message type */
|
||||
#define DHCP_DISCOVER 1
|
||||
#define DHCP_OFFER 2
|
||||
#define DHCP_REQUEST 3
|
||||
#define DHCP_DECLINE 4
|
||||
#define DHCP_ACK 5
|
||||
#define DHCP_NAK 6
|
||||
#define DHCP_RELEASE 7
|
||||
#define DHCP_INFORM 8
|
||||
|
||||
/* DHCP options */
|
||||
enum DHCP_OPTIONS
|
||||
{
|
||||
DHCP_PAD = 0,
|
||||
DHCP_SUBNETMASK = 1,
|
||||
DHCP_ROUTER = 3,
|
||||
DHCP_DNSSERVER = 6,
|
||||
DHCP_HOSTNAME = 12,
|
||||
DHCP_DNSDOMAIN = 15,
|
||||
DHCP_MTU = 26,
|
||||
DHCP_BROADCAST = 28,
|
||||
DHCP_PERFORMROUTERDISC = 31,
|
||||
DHCP_STATICROUTE = 33,
|
||||
DHCP_NISDOMAIN = 40,
|
||||
DHCP_NISSERVER = 41,
|
||||
DHCP_NTPSERVER = 42,
|
||||
DHCP_VENDOR = 43,
|
||||
DHCP_IPADDRESS = 50,
|
||||
DHCP_LEASETIME = 51,
|
||||
DHCP_OPTIONSOVERLOADED = 52,
|
||||
DHCP_MESSAGETYPE = 53,
|
||||
DHCP_SERVERID = 54,
|
||||
DHCP_PARAMETERREQUESTLIST = 55,
|
||||
DHCP_MESSAGE = 56,
|
||||
DHCP_MAXMESSAGESIZE = 57,
|
||||
DHCP_RENEWALTIME = 58,
|
||||
DHCP_REBINDTIME = 59,
|
||||
DHCP_CLASSID = 60,
|
||||
DHCP_CLIENTID = 61,
|
||||
DHCP_USERCLASS = 77, /* RFC 3004 */
|
||||
DHCP_FQDN = 81,
|
||||
DHCP_DNSSEARCH = 119, /* RFC 3397 */
|
||||
DHCP_CSR = 121, /* RFC 3442 */
|
||||
DHCP_MSCSR = 249, /* MS code for RFC 3442 */
|
||||
DHCP_END = 255
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t dp_op; /* packet opcode type */
|
||||
uint8_t dp_htype; /* hardware addr type */
|
||||
uint8_t dp_hlen; /* hardware addr length */
|
||||
uint8_t dp_hops; /* gateway hops */
|
||||
uint32_t dp_xid; /* transaction ID */
|
||||
uint16_t dp_secs; /* seconds since boot began */
|
||||
uint16_t dp_flags;
|
||||
uint8_t dp_ciaddr[4]; /* client IP address */
|
||||
uint8_t dp_yiaddr[4]; /* 'your' IP address */
|
||||
uint8_t dp_siaddr[4]; /* server IP address */
|
||||
uint8_t dp_giaddr[4]; /* gateway IP address */
|
||||
uint8_t dp_chaddr[16]; /* client hardware address */
|
||||
uint8_t dp_legacy[192];
|
||||
uint8_t dp_magic[4];
|
||||
uint8_t dp_options[275]; /* options area */
|
||||
} DHCP_TYPE;
|
||||
|
||||
DHCP_TYPE dhcp_data;
|
||||
static struct udp_pcb *pcb = NULL;
|
||||
static const dhcp_config_t *config = NULL;
|
||||
|
||||
char magic_cookie[] = {0x63,0x82,0x53,0x63};
|
||||
|
||||
static uint32_t get_ip(const uint8_t *pnt)
|
||||
{
|
||||
uint32_t result;
|
||||
memcpy(&result, pnt, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
static void set_ip(uint8_t *pnt, uint32_t value)
|
||||
{
|
||||
memcpy(pnt, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static dhcp_entry_t *entry_by_ip(uint32_t ip)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < config->num_entry; i++)
|
||||
if (get_ip(config->entries[i].addr) == ip)
|
||||
return &config->entries[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static dhcp_entry_t *entry_by_mac(uint8_t *mac)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < config->num_entry; i++)
|
||||
if (memcmp(config->entries[i].mac, mac, 6) == 0)
|
||||
return &config->entries[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static __inline bool is_vacant(dhcp_entry_t *entry)
|
||||
{
|
||||
return memcmp("\0\0\0\0\0", entry->mac, 6) == 0;
|
||||
}
|
||||
|
||||
static dhcp_entry_t *vacant_address(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < config->num_entry; i++)
|
||||
if (is_vacant(config->entries + i))
|
||||
return config->entries + i;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static __inline void free_entry(dhcp_entry_t *entry)
|
||||
{
|
||||
memset(entry->mac, 0, 6);
|
||||
}
|
||||
|
||||
uint8_t *find_dhcp_option(uint8_t *attrs, int size, uint8_t attr)
|
||||
{
|
||||
int i = 0;
|
||||
while ((i + 1) < size)
|
||||
{
|
||||
int next = i + attrs[i + 1] + 2;
|
||||
if (next > size) return NULL;
|
||||
if (attrs[i] == attr)
|
||||
return attrs + i;
|
||||
i = next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fill_options(void *dest,
|
||||
uint8_t msg_type,
|
||||
const char *domain,
|
||||
uint32_t dns,
|
||||
int lease_time,
|
||||
uint32_t serverid,
|
||||
uint32_t router,
|
||||
uint32_t subnet)
|
||||
{
|
||||
uint8_t *ptr = (uint8_t *)dest;
|
||||
/* ACK message type */
|
||||
*ptr++ = 53;
|
||||
*ptr++ = 1;
|
||||
*ptr++ = msg_type;
|
||||
|
||||
/* dhcp server identifier */
|
||||
*ptr++ = DHCP_SERVERID;
|
||||
*ptr++ = 4;
|
||||
set_ip(ptr, serverid);
|
||||
ptr += 4;
|
||||
|
||||
/* lease time */
|
||||
*ptr++ = DHCP_LEASETIME;
|
||||
*ptr++ = 4;
|
||||
*ptr++ = (lease_time >> 24) & 0xFF;
|
||||
*ptr++ = (lease_time >> 16) & 0xFF;
|
||||
*ptr++ = (lease_time >> 8) & 0xFF;
|
||||
*ptr++ = (lease_time >> 0) & 0xFF;
|
||||
|
||||
/* subnet mask */
|
||||
*ptr++ = DHCP_SUBNETMASK;
|
||||
*ptr++ = 4;
|
||||
set_ip(ptr, subnet);
|
||||
ptr += 4;
|
||||
|
||||
/* router */
|
||||
if (router != 0)
|
||||
{
|
||||
*ptr++ = DHCP_ROUTER;
|
||||
*ptr++ = 4;
|
||||
set_ip(ptr, router);
|
||||
ptr += 4;
|
||||
}
|
||||
|
||||
/* domain name */
|
||||
if (domain != NULL)
|
||||
{
|
||||
int len = strlen(domain);
|
||||
*ptr++ = DHCP_DNSDOMAIN;
|
||||
*ptr++ = len;
|
||||
memcpy(ptr, domain, len);
|
||||
ptr += len;
|
||||
}
|
||||
|
||||
/* domain name server (DNS) */
|
||||
if (dns != 0)
|
||||
{
|
||||
*ptr++ = DHCP_DNSSERVER;
|
||||
*ptr++ = 4;
|
||||
set_ip(ptr, dns);
|
||||
ptr += 4;
|
||||
}
|
||||
|
||||
/* end */
|
||||
*ptr++ = DHCP_END;
|
||||
return ptr - (uint8_t *)dest;
|
||||
}
|
||||
|
||||
static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
dhcp_entry_t *entry;
|
||||
struct pbuf *pp;
|
||||
|
||||
(void)arg;
|
||||
(void)addr;
|
||||
|
||||
unsigned n = p->len;
|
||||
if (n > sizeof(dhcp_data)) n = sizeof(dhcp_data);
|
||||
memcpy(&dhcp_data, p->payload, n);
|
||||
switch (dhcp_data.dp_options[2])
|
||||
{
|
||||
case DHCP_DISCOVER:
|
||||
entry = entry_by_mac(dhcp_data.dp_chaddr);
|
||||
if (entry == NULL) entry = vacant_address();
|
||||
if (entry == NULL) break;
|
||||
|
||||
dhcp_data.dp_op = 2; /* reply */
|
||||
dhcp_data.dp_secs = 0;
|
||||
dhcp_data.dp_flags = 0;
|
||||
set_ip(dhcp_data.dp_yiaddr, get_ip(entry->addr));
|
||||
memcpy(dhcp_data.dp_magic, magic_cookie, 4);
|
||||
|
||||
memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options));
|
||||
|
||||
fill_options(dhcp_data.dp_options,
|
||||
DHCP_OFFER,
|
||||
config->domain,
|
||||
get_ip(config->dns),
|
||||
entry->lease,
|
||||
get_ip(config->addr),
|
||||
get_ip(config->addr),
|
||||
get_ip(entry->subnet));
|
||||
|
||||
pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL);
|
||||
if (pp == NULL) break;
|
||||
memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data));
|
||||
udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port);
|
||||
pbuf_free(pp);
|
||||
break;
|
||||
|
||||
case DHCP_REQUEST:
|
||||
/* 1. find requested ipaddr in option list */
|
||||
ptr = find_dhcp_option(dhcp_data.dp_options, sizeof(dhcp_data.dp_options), DHCP_IPADDRESS);
|
||||
if (ptr == NULL) break;
|
||||
if (ptr[1] != 4) break;
|
||||
ptr += 2;
|
||||
|
||||
/* 2. does hw-address registered? */
|
||||
entry = entry_by_mac(dhcp_data.dp_chaddr);
|
||||
if (entry != NULL) free_entry(entry);
|
||||
|
||||
/* 3. find requested ipaddr */
|
||||
entry = entry_by_ip(get_ip(ptr));
|
||||
if (entry == NULL) break;
|
||||
if (!is_vacant(entry)) break;
|
||||
|
||||
/* 4. fill struct fields */
|
||||
memcpy(dhcp_data.dp_yiaddr, ptr, 4);
|
||||
dhcp_data.dp_op = 2; /* reply */
|
||||
dhcp_data.dp_secs = 0;
|
||||
dhcp_data.dp_flags = 0;
|
||||
memcpy(dhcp_data.dp_magic, magic_cookie, 4);
|
||||
|
||||
/* 5. fill options */
|
||||
memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options));
|
||||
|
||||
fill_options(dhcp_data.dp_options,
|
||||
DHCP_ACK,
|
||||
config->domain,
|
||||
get_ip(config->dns),
|
||||
entry->lease,
|
||||
get_ip(config->addr),
|
||||
get_ip(config->addr),
|
||||
get_ip(entry->subnet));
|
||||
|
||||
/* 6. send ACK */
|
||||
pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL);
|
||||
if (pp == NULL) break;
|
||||
memcpy(entry->mac, dhcp_data.dp_chaddr, 6);
|
||||
memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data));
|
||||
udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port);
|
||||
pbuf_free(pp);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
err_t dhserv_init(const dhcp_config_t *c)
|
||||
{
|
||||
err_t err;
|
||||
udp_init();
|
||||
dhserv_free();
|
||||
pcb = udp_new();
|
||||
if (pcb == NULL)
|
||||
return ERR_MEM;
|
||||
err = udp_bind(pcb, IP_ADDR_ANY, c->port);
|
||||
if (err != ERR_OK)
|
||||
{
|
||||
dhserv_free();
|
||||
return err;
|
||||
}
|
||||
udp_recv(pcb, udp_recv_proc, NULL);
|
||||
config = c;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void dhserv_free(void)
|
||||
{
|
||||
if (pcb == NULL) return;
|
||||
udp_remove(pcb);
|
||||
pcb = NULL;
|
||||
}
|
63
lib/networking/dhserver.h
Normal file
63
lib/networking/dhserver.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 by Sergey Fetisov <fsenok@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* version: 1.0 demo (7.02.2015)
|
||||
* brief: tiny dhcp ipv4 server using lwip (pcb)
|
||||
* ref: https://lists.gnu.org/archive/html/lwip-users/2012-12/msg00016.html
|
||||
*/
|
||||
|
||||
#ifndef DHSERVER_H
|
||||
#define DHSERVER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "netif/etharp.h"
|
||||
|
||||
typedef struct dhcp_entry
|
||||
{
|
||||
uint8_t mac[6];
|
||||
uint8_t addr[4];
|
||||
uint8_t subnet[4];
|
||||
uint32_t lease;
|
||||
} dhcp_entry_t;
|
||||
|
||||
typedef struct dhcp_config
|
||||
{
|
||||
uint8_t addr[4];
|
||||
uint16_t port;
|
||||
uint8_t dns[4];
|
||||
const char *domain;
|
||||
int num_entry;
|
||||
dhcp_entry_t *entries;
|
||||
} dhcp_config_t;
|
||||
|
||||
err_t dhserv_init(const dhcp_config_t *config);
|
||||
void dhserv_free(void);
|
||||
|
||||
#endif /* DHSERVER_H */
|
200
lib/networking/dnserver.c
Normal file
200
lib/networking/dnserver.c
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 by Sergey Fetisov <fsenok@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* version: 1.0 demo (7.02.2015)
|
||||
* brief: tiny dns ipv4 server using lwip (pcb)
|
||||
*/
|
||||
|
||||
#include "dnserver.h"
|
||||
|
||||
#define DNS_MAX_HOST_NAME_LEN 128
|
||||
|
||||
static struct udp_pcb *pcb = NULL;
|
||||
dns_query_proc_t query_proc = NULL;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
uint8_t rd: 1, /* Recursion Desired */
|
||||
tc: 1, /* Truncation Flag */
|
||||
aa: 1, /* Authoritative Answer Flag */
|
||||
opcode: 4, /* Operation code */
|
||||
qr: 1; /* Query/Response Flag */
|
||||
uint8_t rcode: 4, /* Response Code */
|
||||
z: 3, /* Zero */
|
||||
ra: 1; /* Recursion Available */
|
||||
#else
|
||||
uint8_t qr: 1, /* Query/Response Flag */
|
||||
opcode: 4, /* Operation code */
|
||||
aa: 1, /* Authoritative Answer Flag */
|
||||
tc: 1, /* Truncation Flag */
|
||||
rd: 1; /* Recursion Desired */
|
||||
uint8_t ra: 1, /* Recursion Available */
|
||||
z: 3, /* Zero */
|
||||
rcode: 4; /* Response Code */
|
||||
#endif
|
||||
} dns_header_flags_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t id;
|
||||
dns_header_flags_t flags;
|
||||
uint16_t n_record[4];
|
||||
} dns_header_t;
|
||||
|
||||
typedef struct dns_answer
|
||||
{
|
||||
uint16_t name;
|
||||
uint16_t type;
|
||||
uint16_t Class;
|
||||
uint32_t ttl;
|
||||
uint16_t len;
|
||||
uint32_t addr;
|
||||
} dns_answer_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct dns_query
|
||||
{
|
||||
char name[DNS_MAX_HOST_NAME_LEN];
|
||||
uint16_t type;
|
||||
uint16_t Class;
|
||||
} dns_query_t;
|
||||
|
||||
static uint16_t get_uint16(const uint8_t *pnt)
|
||||
{
|
||||
uint16_t result;
|
||||
memcpy(&result, pnt, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
static int parse_next_query(void *data, int size, dns_query_t *query)
|
||||
{
|
||||
int len;
|
||||
int lables;
|
||||
uint8_t *ptr;
|
||||
|
||||
len = 0;
|
||||
lables = 0;
|
||||
ptr = (uint8_t *)data;
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint8_t lable_len;
|
||||
if (size <= 0) return -1;
|
||||
lable_len = *ptr++;
|
||||
size--;
|
||||
if (lable_len == 0) break;
|
||||
if (lables > 0)
|
||||
{
|
||||
if (len == DNS_MAX_HOST_NAME_LEN) return -2;
|
||||
query->name[len++] = '.';
|
||||
}
|
||||
if (lable_len > size) return -1;
|
||||
if (len + lable_len >= DNS_MAX_HOST_NAME_LEN) return -2;
|
||||
memcpy(&query->name[len], ptr, lable_len);
|
||||
len += lable_len;
|
||||
ptr += lable_len;
|
||||
size -= lable_len;
|
||||
lables++;
|
||||
}
|
||||
|
||||
if (size < 4) return -1;
|
||||
query->name[len] = 0;
|
||||
query->type = get_uint16(ptr);
|
||||
ptr += 2;
|
||||
query->Class = get_uint16(ptr);
|
||||
ptr += 2;
|
||||
return ptr - (uint8_t *)data;
|
||||
}
|
||||
|
||||
static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
|
||||
{
|
||||
int len;
|
||||
dns_header_t *header;
|
||||
static dns_query_t query;
|
||||
struct pbuf *out;
|
||||
ip_addr_t host_addr;
|
||||
dns_answer_t *answer;
|
||||
|
||||
(void)arg;
|
||||
|
||||
if (p->len <= sizeof(dns_header_t)) goto error;
|
||||
header = (dns_header_t *)p->payload;
|
||||
if (header->flags.qr != 0) goto error;
|
||||
if (ntohs(header->n_record[0]) != 1) goto error;
|
||||
|
||||
len = parse_next_query(header + 1, p->len - sizeof(dns_header_t), &query);
|
||||
if (len < 0) goto error;
|
||||
if (!query_proc(query.name, &host_addr)) goto error;
|
||||
|
||||
len += sizeof(dns_header_t);
|
||||
out = pbuf_alloc(PBUF_TRANSPORT, len + 16, PBUF_POOL);
|
||||
if (out == NULL) goto error;
|
||||
|
||||
memcpy(out->payload, p->payload, len);
|
||||
header = (dns_header_t *)out->payload;
|
||||
header->flags.qr = 1;
|
||||
header->n_record[1] = htons(1);
|
||||
answer = (struct dns_answer *)((uint8_t *)out->payload + len);
|
||||
answer->name = htons(0xC00C);
|
||||
answer->type = htons(1);
|
||||
answer->Class = htons(1);
|
||||
answer->ttl = htonl(32);
|
||||
answer->len = htons(4);
|
||||
answer->addr = host_addr.addr;
|
||||
|
||||
udp_sendto(upcb, out, addr, port);
|
||||
pbuf_free(out);
|
||||
|
||||
error:
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
err_t dnserv_init(const ip_addr_t *bind, uint16_t port, dns_query_proc_t qp)
|
||||
{
|
||||
err_t err;
|
||||
udp_init();
|
||||
dnserv_free();
|
||||
pcb = udp_new();
|
||||
if (pcb == NULL)
|
||||
return ERR_MEM;
|
||||
err = udp_bind(pcb, bind, port);
|
||||
if (err != ERR_OK)
|
||||
{
|
||||
dnserv_free();
|
||||
return err;
|
||||
}
|
||||
udp_recv(pcb, udp_recv_proc, NULL);
|
||||
query_proc = qp;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void dnserv_free()
|
||||
{
|
||||
if (pcb == NULL) return;
|
||||
udp_remove(pcb);
|
||||
pcb = NULL;
|
||||
}
|
47
lib/networking/dnserver.h
Normal file
47
lib/networking/dnserver.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 by Sergey Fetisov <fsenok@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* version: 1.0 demo (7.02.2015)
|
||||
* brief: tiny dns ipv4 server using lwip (pcb)
|
||||
*/
|
||||
|
||||
#ifndef DNSERVER
|
||||
#define DNSERVER
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "netif/etharp.h"
|
||||
|
||||
typedef bool (*dns_query_proc_t)(const char *name, ip_addr_t *addr);
|
||||
|
||||
err_t dnserv_init(const ip_addr_t *bind, uint16_t port, dns_query_proc_t query_proc);
|
||||
void dnserv_free(void);
|
||||
|
||||
#endif
|
266
lib/networking/ndis.h
Normal file
266
lib/networking/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 */
|
||||
|
||||
/** @} */
|
307
lib/networking/rndis_protocol.h
Normal file
307
lib/networking/rndis_protocol.h
Normal file
@ -0,0 +1,307 @@
|
||||
/**
|
||||
* \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;
|
||||
} usb_eth_stat_t;
|
||||
|
||||
#endif /* _RNDIS_H */
|
||||
|
||||
/** @} */
|
303
lib/networking/rndis_reports.c
Normal file
303
lib/networking/rndis_reports.c
Normal file
@ -0,0 +1,303 @@
|
||||
/*
|
||||
The original version of this code was lrndis/usbd_rndis_core.c from https://github.com/fetisov/lrndis
|
||||
It has since been overhauled to suit this application
|
||||
*/
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 by Sergey Fetisov <fsenok@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdalign.h>
|
||||
#include <string.h>
|
||||
#include "class/net/net_device.h"
|
||||
#include "rndis_protocol.h"
|
||||
#include "netif/ethernet.h"
|
||||
|
||||
#define RNDIS_LINK_SPEED 12000000 /* Link baudrate (12Mbit/s for USB-FS) */
|
||||
#define RNDIS_VENDOR "TinyUSB" /* NIC vendor name */
|
||||
|
||||
static const uint8_t *const station_hwaddr = network_mac_address;
|
||||
static const uint8_t *const permanent_hwaddr = network_mac_address;
|
||||
|
||||
static usb_eth_stat_t usb_eth_stat = { 0, 0, 0, 0 };
|
||||
static uint32_t oid_packet_filter = 0x0000000;
|
||||
static rndis_state_t rndis_state;
|
||||
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t ndis_report[8] = { 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
|
||||
static const uint32_t OIDSupportedList[] =
|
||||
{
|
||||
OID_GEN_SUPPORTED_LIST,
|
||||
OID_GEN_HARDWARE_STATUS,
|
||||
OID_GEN_MEDIA_SUPPORTED,
|
||||
OID_GEN_MEDIA_IN_USE,
|
||||
OID_GEN_MAXIMUM_FRAME_SIZE,
|
||||
OID_GEN_LINK_SPEED,
|
||||
OID_GEN_TRANSMIT_BLOCK_SIZE,
|
||||
OID_GEN_RECEIVE_BLOCK_SIZE,
|
||||
OID_GEN_VENDOR_ID,
|
||||
OID_GEN_VENDOR_DESCRIPTION,
|
||||
OID_GEN_VENDOR_DRIVER_VERSION,
|
||||
OID_GEN_CURRENT_PACKET_FILTER,
|
||||
OID_GEN_MAXIMUM_TOTAL_SIZE,
|
||||
OID_GEN_PROTOCOL_OPTIONS,
|
||||
OID_GEN_MAC_OPTIONS,
|
||||
OID_GEN_MEDIA_CONNECT_STATUS,
|
||||
OID_GEN_MAXIMUM_SEND_PACKETS,
|
||||
OID_802_3_PERMANENT_ADDRESS,
|
||||
OID_802_3_CURRENT_ADDRESS,
|
||||
OID_802_3_MULTICAST_LIST,
|
||||
OID_802_3_MAXIMUM_LIST_SIZE,
|
||||
OID_802_3_MAC_OPTIONS
|
||||
};
|
||||
|
||||
#define OID_LIST_LENGTH TU_ARRAY_SIZE(OIDSupportedList)
|
||||
#define ENC_BUF_SIZE (OID_LIST_LENGTH * 4 + 32)
|
||||
|
||||
static uint8_t *encapsulated_buffer;
|
||||
|
||||
static void rndis_report(void)
|
||||
{
|
||||
netd_report(ndis_report, sizeof(ndis_report));
|
||||
}
|
||||
|
||||
static void rndis_query_cmplt32(int status, uint32_t data)
|
||||
{
|
||||
rndis_query_cmplt_t *c;
|
||||
c = (rndis_query_cmplt_t *)encapsulated_buffer;
|
||||
c->MessageType = REMOTE_NDIS_QUERY_CMPLT;
|
||||
c->MessageLength = sizeof(rndis_query_cmplt_t) + 4;
|
||||
c->InformationBufferLength = 4;
|
||||
c->InformationBufferOffset = 16;
|
||||
c->Status = status;
|
||||
memcpy(c + 1, &data, sizeof(data));
|
||||
rndis_report();
|
||||
}
|
||||
|
||||
static void rndis_query_cmplt(int status, const void *data, int size)
|
||||
{
|
||||
rndis_query_cmplt_t *c;
|
||||
c = (rndis_query_cmplt_t *)encapsulated_buffer;
|
||||
c->MessageType = REMOTE_NDIS_QUERY_CMPLT;
|
||||
c->MessageLength = sizeof(rndis_query_cmplt_t) + size;
|
||||
c->InformationBufferLength = size;
|
||||
c->InformationBufferOffset = 16;
|
||||
c->Status = status;
|
||||
memcpy(c + 1, data, size);
|
||||
rndis_report();
|
||||
}
|
||||
|
||||
#define MAC_OPT NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \
|
||||
NDIS_MAC_OPTION_RECEIVE_SERIALIZED | \
|
||||
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | \
|
||||
NDIS_MAC_OPTION_NO_LOOPBACK
|
||||
|
||||
static const char *rndis_vendor = RNDIS_VENDOR;
|
||||
|
||||
static void rndis_query(void)
|
||||
{
|
||||
switch (((rndis_query_msg_t *)encapsulated_buffer)->Oid)
|
||||
{
|
||||
case OID_GEN_SUPPORTED_LIST: rndis_query_cmplt(RNDIS_STATUS_SUCCESS, OIDSupportedList, 4 * OID_LIST_LENGTH); return;
|
||||
case OID_GEN_VENDOR_DRIVER_VERSION: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0x00001000); return;
|
||||
case OID_802_3_CURRENT_ADDRESS: rndis_query_cmplt(RNDIS_STATUS_SUCCESS, &station_hwaddr, 6); return;
|
||||
case OID_802_3_PERMANENT_ADDRESS: rndis_query_cmplt(RNDIS_STATUS_SUCCESS, &permanent_hwaddr, 6); return;
|
||||
case OID_GEN_MEDIA_SUPPORTED: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, NDIS_MEDIUM_802_3); return;
|
||||
case OID_GEN_MEDIA_IN_USE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, NDIS_MEDIUM_802_3); return;
|
||||
case OID_GEN_PHYSICAL_MEDIUM: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, NDIS_MEDIUM_802_3); return;
|
||||
case OID_GEN_HARDWARE_STATUS: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return;
|
||||
case OID_GEN_LINK_SPEED: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, RNDIS_LINK_SPEED / 100); return;
|
||||
case OID_GEN_VENDOR_ID: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0x00FFFFFF); return;
|
||||
case OID_GEN_VENDOR_DESCRIPTION: rndis_query_cmplt(RNDIS_STATUS_SUCCESS, rndis_vendor, strlen(rndis_vendor) + 1); return;
|
||||
case OID_GEN_CURRENT_PACKET_FILTER: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, oid_packet_filter); return;
|
||||
case OID_GEN_MAXIMUM_FRAME_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, CFG_TUD_NET_MTU - SIZEOF_ETH_HDR); return;
|
||||
case OID_GEN_MAXIMUM_TOTAL_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, CFG_TUD_NET_MTU); return;
|
||||
case OID_GEN_TRANSMIT_BLOCK_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, CFG_TUD_NET_MTU); return;
|
||||
case OID_GEN_RECEIVE_BLOCK_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, CFG_TUD_NET_MTU); return;
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, NDIS_MEDIA_STATE_CONNECTED); return;
|
||||
case OID_GEN_RNDIS_CONFIG_PARAMETER: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return;
|
||||
case OID_802_3_MAXIMUM_LIST_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 1); return;
|
||||
case OID_802_3_MULTICAST_LIST: rndis_query_cmplt32(RNDIS_STATUS_NOT_SUPPORTED, 0); return;
|
||||
case OID_802_3_MAC_OPTIONS: rndis_query_cmplt32(RNDIS_STATUS_NOT_SUPPORTED, 0); return;
|
||||
case OID_GEN_MAC_OPTIONS: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, /*MAC_OPT*/ 0); return;
|
||||
case OID_802_3_RCV_ERROR_ALIGNMENT: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return;
|
||||
case OID_802_3_XMIT_ONE_COLLISION: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return;
|
||||
case OID_802_3_XMIT_MORE_COLLISIONS: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return;
|
||||
case OID_GEN_XMIT_OK: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, usb_eth_stat.txok); return;
|
||||
case OID_GEN_RCV_OK: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, usb_eth_stat.rxok); return;
|
||||
case OID_GEN_RCV_ERROR: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, usb_eth_stat.rxbad); return;
|
||||
case OID_GEN_XMIT_ERROR: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, usb_eth_stat.txbad); return;
|
||||
case OID_GEN_RCV_NO_BUFFER: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return;
|
||||
default: rndis_query_cmplt(RNDIS_STATUS_FAILURE, NULL, 0); return;
|
||||
}
|
||||
}
|
||||
|
||||
#define INFBUF ((uint32_t *)((uint8_t *)&(m->RequestId) + m->InformationBufferOffset))
|
||||
|
||||
static void rndis_handle_config_parm(const char *data, int keyoffset, int valoffset, int keylen, int vallen)
|
||||
{
|
||||
(void)data;
|
||||
(void)keyoffset;
|
||||
(void)valoffset;
|
||||
(void)keylen;
|
||||
(void)vallen;
|
||||
}
|
||||
|
||||
static void rndis_packetFilter(uint32_t newfilter)
|
||||
{
|
||||
(void)newfilter;
|
||||
}
|
||||
|
||||
static void rndis_handle_set_msg(void)
|
||||
{
|
||||
rndis_set_cmplt_t *c;
|
||||
rndis_set_msg_t *m;
|
||||
rndis_Oid_t oid;
|
||||
|
||||
c = (rndis_set_cmplt_t *)encapsulated_buffer;
|
||||
m = (rndis_set_msg_t *)encapsulated_buffer;
|
||||
|
||||
oid = m->Oid;
|
||||
c->MessageType = REMOTE_NDIS_SET_CMPLT;
|
||||
c->MessageLength = sizeof(rndis_set_cmplt_t);
|
||||
c->Status = RNDIS_STATUS_SUCCESS;
|
||||
|
||||
switch (oid)
|
||||
{
|
||||
/* Parameters set up in 'Advanced' tab */
|
||||
case OID_GEN_RNDIS_CONFIG_PARAMETER:
|
||||
{
|
||||
rndis_config_parameter_t *p;
|
||||
char *ptr = (char *)m;
|
||||
ptr += sizeof(rndis_generic_msg_t);
|
||||
ptr += m->InformationBufferOffset;
|
||||
p = (rndis_config_parameter_t *)ptr;
|
||||
rndis_handle_config_parm(ptr, p->ParameterNameOffset, p->ParameterValueOffset, p->ParameterNameLength, p->ParameterValueLength);
|
||||
}
|
||||
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;
|
||||
|
||||
/* 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->Status = RNDIS_STATUS_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* c->MessageID is same as before */
|
||||
rndis_report();
|
||||
return;
|
||||
}
|
||||
|
||||
void rndis_class_set_handler(uint8_t *data, int size)
|
||||
{
|
||||
encapsulated_buffer = data;
|
||||
(void)size;
|
||||
|
||||
switch (((rndis_generic_msg_t *)data)->MessageType)
|
||||
{
|
||||
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_MINOR_VERSION;
|
||||
m->Status = RNDIS_STATUS_SUCCESS;
|
||||
m->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
|
||||
m->Medium = RNDIS_MEDIUM_802_3;
|
||||
m->MaxPacketsPerTransfer = 1;
|
||||
m->MaxTransferSize = CFG_TUD_NET_MTU + sizeof(rndis_data_packet_t);
|
||||
m->PacketAlignmentFactor = 0;
|
||||
m->AfListOffset = 0;
|
||||
m->AfListSize = 0;
|
||||
rndis_state = rndis_initialized;
|
||||
rndis_report();
|
||||
}
|
||||
break;
|
||||
|
||||
case REMOTE_NDIS_QUERY_MSG:
|
||||
rndis_query();
|
||||
break;
|
||||
|
||||
case REMOTE_NDIS_SET_MSG:
|
||||
rndis_handle_set_msg();
|
||||
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 */
|
||||
rndis_report();
|
||||
}
|
||||
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 */
|
||||
rndis_report();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
345
src/class/net/net_device.c
Normal file
345
src/class/net/net_device.c
Normal file
@ -0,0 +1,345 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Peter Lawrence
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "tusb_option.h"
|
||||
|
||||
#if ( TUSB_OPT_DEVICE_ENABLED && (CFG_TUD_NET != OPT_NET_NONE) )
|
||||
|
||||
#include "net_device.h"
|
||||
#include "device/usbd_pvt.h"
|
||||
#include "rndis_protocol.h"
|
||||
|
||||
void rndis_class_set_handler(uint8_t *data, int size); /* found in ./misc/networking/rndis_reports.c */
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF
|
||||
//--------------------------------------------------------------------+
|
||||
typedef struct
|
||||
{
|
||||
uint8_t itf_num;
|
||||
uint8_t ep_notif;
|
||||
uint8_t ep_in;
|
||||
uint8_t ep_out;
|
||||
} netd_interface_t;
|
||||
|
||||
#if CFG_TUD_NET == OPT_NET_ECM
|
||||
#define CFG_TUD_NET_PACKET_PREFIX_LEN 0
|
||||
#define CFG_TUD_NET_PACKET_SUFFIX_LEN 0
|
||||
#define CFG_TUD_NET_INTERFACESUBCLASS CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL
|
||||
#elif CFG_TUD_NET == OPT_NET_RNDIS
|
||||
#define CFG_TUD_NET_PACKET_PREFIX_LEN sizeof(rndis_data_packet_t)
|
||||
#define CFG_TUD_NET_PACKET_SUFFIX_LEN 0
|
||||
#define CFG_TUD_NET_INTERFACESUBCLASS TUD_RNDIS_ITF_SUBCLASS
|
||||
#elif CFG_TUD_NET == OPT_NET_EEM
|
||||
#define CFG_TUD_NET_PACKET_PREFIX_LEN 2
|
||||
#define CFG_TUD_NET_PACKET_SUFFIX_LEN 4
|
||||
#define CFG_TUD_NET_INTERFACESUBCLASS CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL
|
||||
#endif
|
||||
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t received[CFG_TUD_NET_PACKET_PREFIX_LEN + CFG_TUD_NET_MTU + CFG_TUD_NET_PACKET_PREFIX_LEN];
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t transmitted[CFG_TUD_NET_PACKET_PREFIX_LEN + CFG_TUD_NET_MTU + CFG_TUD_NET_PACKET_PREFIX_LEN];
|
||||
|
||||
#if CFG_TUD_NET == OPT_NET_RNDIS
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t rndis_buf[128];
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
CFG_TUSB_MEM_SECTION static netd_interface_t _netd_itf;
|
||||
|
||||
static bool can_xmit;
|
||||
|
||||
void network_recv_renew(void)
|
||||
{
|
||||
usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_out, received, sizeof(received));
|
||||
}
|
||||
|
||||
static void do_in_xfer(uint8_t *buf, uint16_t len)
|
||||
{
|
||||
can_xmit = false;
|
||||
usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_in, buf, len);
|
||||
}
|
||||
|
||||
void netd_report(uint8_t *buf, uint16_t len)
|
||||
{
|
||||
usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_notif, buf, len);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USBD Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void netd_init(void)
|
||||
{
|
||||
tu_memclr(&_netd_itf, sizeof(_netd_itf));
|
||||
}
|
||||
|
||||
void netd_reset(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
netd_init();
|
||||
}
|
||||
|
||||
bool netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length)
|
||||
{
|
||||
// sanity check the descriptor
|
||||
TU_ASSERT (CFG_TUD_NET_INTERFACESUBCLASS == itf_desc->bInterfaceSubClass);
|
||||
|
||||
// confirm interface hasn't already been allocated
|
||||
TU_ASSERT(0 == _netd_itf.ep_in);
|
||||
|
||||
//------------- first Interface -------------//
|
||||
_netd_itf.itf_num = itf_desc->bInterfaceNumber;
|
||||
|
||||
uint8_t const * p_desc = tu_desc_next( itf_desc );
|
||||
(*p_length) = sizeof(tusb_desc_interface_t);
|
||||
|
||||
#if CFG_TUD_NET != OPT_NET_EEM
|
||||
// Communication Functional Descriptors
|
||||
while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) )
|
||||
{
|
||||
(*p_length) += tu_desc_len(p_desc);
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
}
|
||||
|
||||
// notification endpoint (if any)
|
||||
if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) )
|
||||
{
|
||||
TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc) );
|
||||
|
||||
_netd_itf.ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
|
||||
|
||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
}
|
||||
|
||||
//------------- second Interface -------------//
|
||||
if ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) &&
|
||||
(TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
|
||||
{
|
||||
// next to endpoint descriptor
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
(*p_length) += sizeof(tusb_desc_interface_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
|
||||
{
|
||||
// Open endpoint pair
|
||||
TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &_netd_itf.ep_out, &_netd_itf.ep_in) );
|
||||
|
||||
(*p_length) += 2*sizeof(tusb_desc_endpoint_t);
|
||||
}
|
||||
|
||||
network_init_callback();
|
||||
|
||||
// we are ready to transmit a packet
|
||||
can_xmit = true;
|
||||
|
||||
// prepare for incoming packets
|
||||
network_recv_renew();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Invoked when class request DATA stage is finished.
|
||||
// return false to stall control endpoint (e.g Host send nonsense DATA)
|
||||
bool netd_control_complete(uint8_t rhport, tusb_control_request_t const * request)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
// Handle class request only
|
||||
TU_VERIFY (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
|
||||
|
||||
TU_VERIFY (_netd_itf.itf_num == request->wIndex);
|
||||
|
||||
#if CFG_TUD_NET == OPT_NET_RNDIS
|
||||
if (request->bmRequestType_bit.direction == TUSB_DIR_OUT)
|
||||
{
|
||||
rndis_class_set_handler(rndis_buf, request->wLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle class control request
|
||||
// return false to stall control endpoint (e.g unsupported request)
|
||||
bool netd_control_request(uint8_t rhport, tusb_control_request_t const * request)
|
||||
{
|
||||
// Handle class request only
|
||||
TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
|
||||
|
||||
TU_VERIFY (_netd_itf.itf_num == request->wIndex);
|
||||
|
||||
#if CFG_TUD_NET == OPT_NET_RNDIS
|
||||
tud_control_xfer(rhport, request, rndis_buf, sizeof(rndis_buf));
|
||||
#else
|
||||
(void)rhport;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct cdc_eem_packet_header
|
||||
{
|
||||
uint16_t length:14;
|
||||
uint16_t bmCRC:1;
|
||||
uint16_t bmType:1;
|
||||
};
|
||||
|
||||
static void handle_incoming_packet(uint32_t len)
|
||||
{
|
||||
uint8_t *pnt = received;
|
||||
uint32_t size = 0;
|
||||
|
||||
#if CFG_TUD_NET == OPT_NET_ECM
|
||||
size = len;
|
||||
#elif CFG_TUD_NET == OPT_NET_RNDIS
|
||||
rndis_data_packet_t *r = (rndis_data_packet_t *)pnt;
|
||||
if (len >= sizeof(rndis_data_packet_t))
|
||||
if ( (r->MessageType == REMOTE_NDIS_PACKET_MSG) && (r->MessageLength <= len))
|
||||
if ( (r->DataOffset + offsetof(rndis_data_packet_t, DataOffset) + r->DataLength) <= len)
|
||||
{
|
||||
pnt = &received[r->DataOffset + offsetof(rndis_data_packet_t, DataOffset)];
|
||||
size = r->DataLength;
|
||||
}
|
||||
#elif CFG_TUD_NET == OPT_NET_EEM
|
||||
struct cdc_eem_packet_header *hdr = (struct cdc_eem_packet_header *)pnt;
|
||||
|
||||
(void)len;
|
||||
|
||||
if (hdr->bmType)
|
||||
{
|
||||
/* EEM Control Packet: discard it */
|
||||
network_recv_renew();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* EEM Data Packet */
|
||||
pnt += CFG_TUD_NET_PACKET_PREFIX_LEN;
|
||||
size = hdr->length - 4; /* discard the unused CRC-32 */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (size)
|
||||
{
|
||||
struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL);
|
||||
bool accepted = true;
|
||||
|
||||
if (p)
|
||||
{
|
||||
memcpy(p->payload, pnt, size);
|
||||
p->len = size;
|
||||
accepted = network_recv_callback(p);
|
||||
}
|
||||
|
||||
if (!p || !accepted)
|
||||
{
|
||||
/* if a buffer couldn't be allocated or accepted by the callback, we must discard this packet */
|
||||
network_recv_renew();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
||||
{
|
||||
(void) rhport;
|
||||
(void) result;
|
||||
|
||||
/* new packet received */
|
||||
if ( ep_addr == _netd_itf.ep_out )
|
||||
{
|
||||
handle_incoming_packet(xferred_bytes);
|
||||
}
|
||||
|
||||
/* data transmission finished */
|
||||
if ( ep_addr == _netd_itf.ep_in )
|
||||
{
|
||||
/* TinyUSB requires the class driver to implement ZLP (since ZLP usage is class-specific) */
|
||||
|
||||
if ( xferred_bytes && (0 == (xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE)) )
|
||||
{
|
||||
do_in_xfer(NULL, 0); /* a ZLP is needed */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we're finally finished */
|
||||
can_xmit = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool network_can_xmit(void)
|
||||
{
|
||||
return can_xmit;
|
||||
}
|
||||
|
||||
void network_xmit(struct pbuf *p)
|
||||
{
|
||||
struct pbuf *q;
|
||||
uint8_t *data;
|
||||
uint16_t len;
|
||||
|
||||
if (!can_xmit)
|
||||
return;
|
||||
|
||||
len = CFG_TUD_NET_PACKET_PREFIX_LEN;
|
||||
data = transmitted + len;
|
||||
|
||||
for(q = p; q != NULL; q = q->next)
|
||||
{
|
||||
memcpy(data, (char *)q->payload, q->len);
|
||||
data += q->len;
|
||||
len += q->len;
|
||||
}
|
||||
|
||||
#if CFG_TUD_NET == OPT_NET_RNDIS
|
||||
rndis_data_packet_t *hdr = (rndis_data_packet_t *)transmitted;
|
||||
memset(hdr, 0, sizeof(rndis_data_packet_t));
|
||||
hdr->MessageType = REMOTE_NDIS_PACKET_MSG;
|
||||
hdr->MessageLength = len;
|
||||
hdr->DataOffset = sizeof(rndis_data_packet_t) - offsetof(rndis_data_packet_t, DataOffset);
|
||||
hdr->DataLength = len - sizeof(rndis_data_packet_t);
|
||||
#elif CFG_TUD_NET == OPT_NET_EEM
|
||||
struct cdc_eem_packet_header *hdr = (struct cdc_eem_packet_header *)transmitted;
|
||||
/* append a fake CRC-32; the standard allows 0xDEADBEEF, which takes less CPU time */
|
||||
data[0] = 0xDE; data[1] = 0xAD; data[2] = 0xBE; data[3] = 0xEF;
|
||||
/* adjust length to reflect added fake CRC-32 */
|
||||
len += 4;
|
||||
hdr->bmType = 0; /* EEM Data Packet */
|
||||
hdr->length = len - sizeof(struct cdc_eem_packet_header);
|
||||
hdr->bmCRC = 0; /* Ethernet Frame CRC-32 set to 0xDEADBEEF */
|
||||
#endif
|
||||
|
||||
do_in_xfer(transmitted, len);
|
||||
}
|
||||
|
||||
#endif
|
84
src/class/net/net_device.h
Normal file
84
src/class/net/net_device.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Peter Lawrence
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_NET_DEVICE_H_
|
||||
#define _TUSB_NET_DEVICE_H_
|
||||
|
||||
#include "common/tusb_common.h"
|
||||
#include "device/usbd.h"
|
||||
#include "class/cdc/cdc.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "netif/ethernet.h"
|
||||
|
||||
/* declared here, NOT in usb_descriptors.c, so that the driver can intelligently ZLP as needed */
|
||||
#define CFG_TUD_NET_ENDPOINT_SIZE ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64)
|
||||
|
||||
/* Maximum Tranmission Unit (in bytes) of the network, including Ethernet header */
|
||||
#define CFG_TUD_NET_MTU (1500 + SIZEOF_ETH_HDR)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Application API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// client must provide this: initialize any network state back to the beginning
|
||||
void network_init_callback(void);
|
||||
|
||||
// client must provide this: return false if the packet buffer was not accepted
|
||||
bool network_recv_callback(struct pbuf *p);
|
||||
|
||||
// client must provide this: 48-bit MAC address
|
||||
extern const uint8_t network_mac_address[6];
|
||||
|
||||
// indicate to network driver that client has finished with the packet provided to network_recv_callback()
|
||||
void network_recv_renew(void);
|
||||
|
||||
// poll network driver for its ability to accept another packet to transmit
|
||||
bool network_can_xmit(void);
|
||||
|
||||
// if network_can_xmit() returns true, network_xmit() can be called once
|
||||
void network_xmit(struct pbuf *p);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL USBD-CLASS DRIVER API
|
||||
//--------------------------------------------------------------------+
|
||||
void netd_init (void);
|
||||
void netd_reset (uint8_t rhport);
|
||||
bool netd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
|
||||
bool netd_control_request (uint8_t rhport, tusb_control_request_t const * request);
|
||||
bool netd_control_complete (uint8_t rhport, tusb_control_request_t const * request);
|
||||
bool netd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
|
||||
void netd_report (uint8_t *buf, uint16_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_NET_DEVICE_H_ */
|
@ -181,6 +181,24 @@ static usbd_class_driver_t const _usbd_driver[] =
|
||||
.sof = NULL
|
||||
},
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_NET
|
||||
{
|
||||
.class_code =
|
||||
#if CFG_TUD_NET == OPT_NET_RNDIS
|
||||
TUD_RNDIS_ITF_CLASS,
|
||||
#else
|
||||
TUSB_CLASS_CDC,
|
||||
#endif
|
||||
.init = netd_init,
|
||||
.reset = netd_reset,
|
||||
.open = netd_open,
|
||||
.control_request = netd_control_request,
|
||||
.control_complete = netd_control_complete,
|
||||
.xfer_cb = netd_xfer_cb,
|
||||
.sof = NULL
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
enum { USBD_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) };
|
||||
|
@ -326,6 +326,90 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re
|
||||
9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101)
|
||||
|
||||
|
||||
//------------- CDC-ECM -------------//
|
||||
|
||||
// Length of template descriptor: 62 bytes
|
||||
#define TUD_CDC_ECM_DESC_LEN (9+5+5+13+7+9+7+7)
|
||||
|
||||
// CDC-ECM Descriptor Template
|
||||
// Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size.
|
||||
#define TUD_CDC_ECM_DESCRIPTOR(_itfnum, _desc_stridx, _mac_stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize, _maxsegmentsize) \
|
||||
/* CDC Control Interface */\
|
||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0, _desc_stridx,\
|
||||
/* CDC-ECM Header */\
|
||||
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\
|
||||
/* CDC-ECM Union */\
|
||||
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\
|
||||
/* CDC-ECM Functional Descriptor */\
|
||||
13, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ETHERNET_NETWORKING, _mac_stridx, 0, 0, 0, 0, U16_TO_U8S_LE(_maxsegmentsize), U16_TO_U8S_LE(0), 0,\
|
||||
/* Endpoint Notification */\
|
||||
7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 1,\
|
||||
/* CDC Data Interface */\
|
||||
9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\
|
||||
/* Endpoint In */\
|
||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
||||
/* Endpoint Out */\
|
||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
||||
|
||||
|
||||
//------------- RNDIS -------------//
|
||||
|
||||
#if 0
|
||||
/* Windows XP */
|
||||
#define TUD_RNDIS_ITF_CLASS TUSB_CLASS_CDC
|
||||
#define TUD_RNDIS_ITF_SUBCLASS CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL
|
||||
#define TUD_RNDIS_ITF_PROTOCOL CDC_COMM_PROTOCOL_MICROSOFT_RNDIS
|
||||
#else
|
||||
/* Windows 7+ */
|
||||
#define TUD_RNDIS_ITF_CLASS 0xE0
|
||||
#define TUD_RNDIS_ITF_SUBCLASS 0x01
|
||||
#define TUD_RNDIS_ITF_PROTOCOL 0x03
|
||||
#endif
|
||||
|
||||
// Length of template descriptor: 66 bytes
|
||||
#define TUD_RNDIS_DESC_LEN (8+9+5+5+4+5+7+9+7+7)
|
||||
|
||||
// RNDIS Descriptor Template
|
||||
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||
#define TUD_RNDIS_DESCRIPTOR(_itfnum, _stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize) \
|
||||
/* Interface Association */\
|
||||
8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUD_RNDIS_ITF_CLASS, TUD_RNDIS_ITF_SUBCLASS, TUD_RNDIS_ITF_PROTOCOL, 0,\
|
||||
/* CDC Control Interface */\
|
||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUD_RNDIS_ITF_CLASS, TUD_RNDIS_ITF_SUBCLASS, TUD_RNDIS_ITF_PROTOCOL, _stridx,\
|
||||
/* CDC-ACM Header */\
|
||||
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0110),\
|
||||
/* CDC Call Management */\
|
||||
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (uint8_t)((_itfnum) + 1),\
|
||||
/* ACM */\
|
||||
4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 0,\
|
||||
/* CDC Union */\
|
||||
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\
|
||||
/* Endpoint Notification */\
|
||||
7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 1,\
|
||||
/* CDC Data Interface */\
|
||||
9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\
|
||||
/* Endpoint In */\
|
||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
||||
/* Endpoint Out */\
|
||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
||||
|
||||
|
||||
//------------- CDC-EEM -------------//
|
||||
|
||||
// Length of template descriptor: 23 bytes
|
||||
#define TUD_CDC_EEM_DESC_LEN (9+7+7)
|
||||
|
||||
// CDC-EEM Descriptor Template
|
||||
// Interface number, description string index, EP data address (out, in) and size.
|
||||
#define TUD_CDC_EEM_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \
|
||||
/* EEM Interface */\
|
||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL, CDC_COMM_PROTOCOL_ETHERNET_EMULATION_MODEL, _stridx,\
|
||||
/* Endpoint In */\
|
||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
||||
/* Endpoint Out */\
|
||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -91,6 +91,10 @@
|
||||
#if CFG_TUD_DFU_RT
|
||||
#include "class/dfu/dfu_rt_device.h"
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_NET
|
||||
#include "class/net/net_device.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -117,6 +117,15 @@
|
||||
#define OPT_MODE_HIGH_SPEED 0x10 ///< High speed
|
||||
/** @} */
|
||||
|
||||
/** \defgroup group_supported_netif Supported Network Interface
|
||||
* \ref CFG_TUD_NET must be defined to one of these
|
||||
* @{ */
|
||||
#define OPT_NET_NONE 0 ///< No network interface
|
||||
#define OPT_NET_ECM 1 ///< CDC-ECM
|
||||
#define OPT_NET_RNDIS 2 ///< RNDIS
|
||||
#define OPT_NET_EEM 3 ///< CDC-EEM
|
||||
/** @} */
|
||||
|
||||
#ifndef CFG_TUSB_RHPORT0_MODE
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE
|
||||
#endif
|
||||
@ -204,6 +213,9 @@
|
||||
#define CFG_TUD_DFU_RT 0
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUD_NET
|
||||
#define CFG_TUD_NET 0
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// HOST OPTIONS
|
||||
|
Loading…
x
Reference in New Issue
Block a user