Merge pull request #2764 from lymzzyh/rndis
[Components][USB][RNDIS/ECM] fix hotplug and "delay linkup"
This commit is contained in:
commit
5cd9adb5fd
|
@ -640,6 +640,13 @@ menu "Using USB"
|
||||||
string "msc class disk name"
|
string "msc class disk name"
|
||||||
default "flash0"
|
default "flash0"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if RT_USB_DEVICE_RNDIS
|
||||||
|
config RNDIS_DELAY_LINK_UP
|
||||||
|
bool "Delay linkup media connection"
|
||||||
|
default n
|
||||||
|
endif
|
||||||
|
|
||||||
if RT_USB_DEVICE_HID
|
if RT_USB_DEVICE_HID
|
||||||
config RT_USB_DEVICE_HID_KEYBOARD
|
config RT_USB_DEVICE_HID_KEYBOARD
|
||||||
bool "Use to HID device as Keyboard"
|
bool "Use to HID device as Keyboard"
|
||||||
|
|
|
@ -6,17 +6,16 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2017-11-19 ZYH first version
|
* 2017-11-19 ZYH first version
|
||||||
|
* 2019-06-10 ZYH fix hotplug
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtdevice.h>
|
#include <rtdevice.h>
|
||||||
|
#ifdef RT_USB_DEVICE_ECM
|
||||||
#include "cdc.h"
|
#include "cdc.h"
|
||||||
|
|
||||||
|
#define DBG_LEVEL DBG_WARNING
|
||||||
#ifdef ECM_DEBUG
|
#define DBG_SECTION_NAME "ECM"
|
||||||
#define ECM_PRINTF rt_kprintf("[ECM] "); rt_kprintf
|
#include <rtdbg.h>
|
||||||
#else
|
|
||||||
#define ECM_PRINTF(...)
|
|
||||||
#endif /* ECM_DEBUG */
|
|
||||||
|
|
||||||
/* RT-Thread LWIP ethernet interface */
|
/* RT-Thread LWIP ethernet interface */
|
||||||
#include <netif/ethernetif.h>
|
#include <netif/ethernetif.h>
|
||||||
|
@ -216,15 +215,21 @@ static rt_err_t _cdc_send_notifi(ufunction_t func,ucdc_notification_code_t notif
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static rt_err_t _ecm_set_eth_packet_filter(ufunction_t func, ureq_t setup)
|
static rt_err_t _ecm_set_eth_packet_filter(ufunction_t func, ureq_t setup)
|
||||||
{
|
{
|
||||||
rt_ecm_eth_t _ecm_eth = (rt_ecm_eth_t)func->user_data;
|
rt_ecm_eth_t _ecm_eth = (rt_ecm_eth_t)func->user_data;
|
||||||
dcd_ep0_send_status(func->device->dcd);
|
dcd_ep0_send_status(func->device->dcd);
|
||||||
|
|
||||||
|
|
||||||
/* send link up. */
|
/* send link up. */
|
||||||
eth_device_linkchange(&_ecm_eth->parent, RT_TRUE);
|
eth_device_linkchange(&_ecm_eth->parent, RT_TRUE);
|
||||||
_cdc_send_notifi(func, UCDC_NOTIFI_NETWORK_CONNECTION, 1, 0);
|
_cdc_send_notifi(func, UCDC_NOTIFI_NETWORK_CONNECTION, 1, 0);
|
||||||
|
|
||||||
|
#ifdef LWIP_USING_DHCPD
|
||||||
|
extern void dhcpd_start(const char *netif_name);
|
||||||
|
dhcpd_start("u0");
|
||||||
|
#endif
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -243,10 +248,11 @@ static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
|
||||||
switch(setup->bRequest)
|
switch(setup->bRequest)
|
||||||
{
|
{
|
||||||
case CDC_SET_ETH_PACKET_FILTER:
|
case CDC_SET_ETH_PACKET_FILTER:
|
||||||
|
LOG_D("CDC_SET_ETH_PACKET_FILTER");
|
||||||
_ecm_set_eth_packet_filter(func, setup);
|
_ecm_set_eth_packet_filter(func, setup);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rt_kprintf("setup->bRequest:0x%02X",setup->bRequest);
|
LOG_E("Unknow setup->bRequest: 0x%02X", setup->bRequest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
|
@ -402,14 +408,13 @@ rt_err_t rt_ecm_eth_tx(rt_device_t dev, struct pbuf* p)
|
||||||
|
|
||||||
if(!ecm_eth_dev->parent.link_status)
|
if(!ecm_eth_dev->parent.link_status)
|
||||||
{
|
{
|
||||||
ECM_PRINTF("linkdown, drop pkg\r\n");
|
LOG_D("linkdown, drop pkg");
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RT_ASSERT(p->tot_len < USB_ETH_MTU);
|
|
||||||
if(p->tot_len > USB_ETH_MTU)
|
if(p->tot_len > USB_ETH_MTU)
|
||||||
{
|
{
|
||||||
ECM_PRINTF("RNDIS MTU is:%d, but the send packet size is %d\r\n",
|
LOG_W("ECM MTU is:%d, but the send packet size is %d",
|
||||||
USB_ETH_MTU, p->tot_len);
|
USB_ETH_MTU, p->tot_len);
|
||||||
p->tot_len = USB_ETH_MTU;
|
p->tot_len = USB_ETH_MTU;
|
||||||
}
|
}
|
||||||
|
@ -461,10 +466,17 @@ static rt_err_t _function_enable(ufunction_t func)
|
||||||
{
|
{
|
||||||
cdc_eps_t eps;
|
cdc_eps_t eps;
|
||||||
rt_ecm_eth_t ecm_device = (rt_ecm_eth_t)func->user_data;
|
rt_ecm_eth_t ecm_device = (rt_ecm_eth_t)func->user_data;
|
||||||
|
|
||||||
|
LOG_D("plugged in");
|
||||||
|
|
||||||
eps = (cdc_eps_t)&ecm_device->eps;
|
eps = (cdc_eps_t)&ecm_device->eps;
|
||||||
eps->ep_out->buffer = ecm_device->rx_pool;
|
eps->ep_out->buffer = ecm_device->rx_pool;
|
||||||
|
|
||||||
|
/* reset eth rx tx */
|
||||||
|
rt_sem_release(&ecm_device->tx_buffer_free);
|
||||||
ecm_device->rx_size = 0;
|
ecm_device->rx_size = 0;
|
||||||
ecm_device->rx_offset = 0;
|
ecm_device->rx_offset = 0;
|
||||||
|
eth_device_ready(&ecm_device->parent);
|
||||||
|
|
||||||
eps->ep_out->request.buffer = (void *)eps->ep_out->buffer;
|
eps->ep_out->request.buffer = (void *)eps->ep_out->buffer;
|
||||||
eps->ep_out->request.size = EP_MAXPACKET(eps->ep_out);
|
eps->ep_out->request.size = EP_MAXPACKET(eps->ep_out);
|
||||||
|
@ -482,7 +494,16 @@ static rt_err_t _function_enable(ufunction_t func)
|
||||||
*/
|
*/
|
||||||
static rt_err_t _function_disable(ufunction_t func)
|
static rt_err_t _function_disable(ufunction_t func)
|
||||||
{
|
{
|
||||||
|
LOG_D("plugged out");
|
||||||
|
|
||||||
eth_device_linkchange(&((rt_ecm_eth_t)func->user_data)->parent, RT_FALSE);
|
eth_device_linkchange(&((rt_ecm_eth_t)func->user_data)->parent, RT_FALSE);
|
||||||
|
|
||||||
|
/* reset eth rx tx */
|
||||||
|
rt_sem_release(&((rt_ecm_eth_t)func->user_data)->tx_buffer_free);
|
||||||
|
((rt_ecm_eth_t)func->user_data)->rx_size = 0;
|
||||||
|
((rt_ecm_eth_t)func->user_data)->rx_offset = 0;
|
||||||
|
eth_device_ready(&((rt_ecm_eth_t)func->user_data)->parent);
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,3 +664,5 @@ int rt_usbd_ecm_class_register(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
INIT_PREV_EXPORT(rt_usbd_ecm_class_register);
|
INIT_PREV_EXPORT(rt_usbd_ecm_class_register);
|
||||||
|
|
||||||
|
#endif /* RT_USB_DEVICE_ECM */
|
||||||
|
|
|
@ -13,21 +13,21 @@
|
||||||
* 2013-07-09 aozima support respone chain list.
|
* 2013-07-09 aozima support respone chain list.
|
||||||
* 2013-07-18 aozima re-initial respone chain list when RNDIS restart.
|
* 2013-07-18 aozima re-initial respone chain list when RNDIS restart.
|
||||||
* 2017-11-25 ZYH fix it and add OS descriptor
|
* 2017-11-25 ZYH fix it and add OS descriptor
|
||||||
|
* 2019-06-10 ZYH fix hot plug and delay linkup
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtdevice.h>
|
#include <rtdevice.h>
|
||||||
|
#ifdef RT_USB_DEVICE_RNDIS
|
||||||
#include "cdc.h"
|
#include "cdc.h"
|
||||||
#include "rndis.h"
|
#include "rndis.h"
|
||||||
#include "ndis.h"
|
#include "ndis.h"
|
||||||
|
|
||||||
//#define RNDIS_DEBUG
|
/* define RNDIS_DELAY_LINK_UP by menuconfig for delay linkup */
|
||||||
//#define RNDIS_DELAY_LINK_UP
|
|
||||||
|
#define DBG_LEVEL DBG_WARNING
|
||||||
|
#define DBG_SECTION_NAME "RNDIS"
|
||||||
|
#include <rtdbg.h>
|
||||||
|
|
||||||
#ifdef RNDIS_DEBUG
|
|
||||||
#define RNDIS_PRINTF rt_kprintf("[RNDIS] "); rt_kprintf
|
|
||||||
#else
|
|
||||||
#define RNDIS_PRINTF(...)
|
|
||||||
#endif /* RNDIS_DEBUG */
|
|
||||||
|
|
||||||
/* RT-Thread LWIP ethernet interface */
|
/* RT-Thread LWIP ethernet interface */
|
||||||
#include <netif/ethernetif.h>
|
#include <netif/ethernetif.h>
|
||||||
|
@ -314,7 +314,7 @@ static rt_err_t _rndis_init_response(ufunction_t func, rndis_init_msg_t msg)
|
||||||
|
|
||||||
if( (response == RT_NULL) || (resp == RT_NULL) )
|
if( (response == RT_NULL) || (resp == RT_NULL) )
|
||||||
{
|
{
|
||||||
RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
|
LOG_E("%s,%d: no memory!", __func__, __LINE__);
|
||||||
|
|
||||||
if(response != RT_NULL)
|
if(response != RT_NULL)
|
||||||
rt_free(response);
|
rt_free(response);
|
||||||
|
@ -360,7 +360,7 @@ static rndis_query_cmplt_t _create_resp(rt_size_t size)
|
||||||
|
|
||||||
if(resp == RT_NULL)
|
if(resp == RT_NULL)
|
||||||
{
|
{
|
||||||
RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
|
LOG_E("%s,%d: no memory!", __func__, __LINE__);
|
||||||
return RT_NULL;
|
return RT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,7 +510,7 @@ static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
RNDIS_PRINTF("OID %X\n", msg->Oid);
|
LOG_W("Not support OID %X", msg->Oid);
|
||||||
ret = -RT_ERROR;
|
ret = -RT_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -518,7 +518,7 @@ static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg)
|
||||||
response = rt_malloc(sizeof(struct rt_rndis_response));
|
response = rt_malloc(sizeof(struct rt_rndis_response));
|
||||||
if( (response == RT_NULL) || (resp == RT_NULL) )
|
if( (response == RT_NULL) || (resp == RT_NULL) )
|
||||||
{
|
{
|
||||||
RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
|
LOG_E("%s,%d: no memory!", __func__, __LINE__);
|
||||||
|
|
||||||
if(response != RT_NULL)
|
if(response != RT_NULL)
|
||||||
rt_free(response);
|
rt_free(response);
|
||||||
|
@ -557,7 +557,7 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
|
||||||
|
|
||||||
if( (response == RT_NULL) || (resp == RT_NULL) )
|
if( (response == RT_NULL) || (resp == RT_NULL) )
|
||||||
{
|
{
|
||||||
RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
|
LOG_E("%s,%d: no memory!", __func__, __LINE__);
|
||||||
|
|
||||||
if(response != RT_NULL)
|
if(response != RT_NULL)
|
||||||
rt_free(response);
|
rt_free(response);
|
||||||
|
@ -577,8 +577,10 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
|
||||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||||
oid_packet_filter = *((rt_uint32_t *)((rt_uint8_t *)&(msg->RequestId) + \
|
oid_packet_filter = *((rt_uint32_t *)((rt_uint8_t *)&(msg->RequestId) + \
|
||||||
msg->InformationBufferOffset));
|
msg->InformationBufferOffset));
|
||||||
|
/* TODO: make complier happy */
|
||||||
oid_packet_filter = oid_packet_filter;
|
oid_packet_filter = oid_packet_filter;
|
||||||
RNDIS_PRINTF("OID_GEN_CURRENT_PACKET_FILTER\r\n");
|
|
||||||
|
LOG_D("OID_GEN_CURRENT_PACKET_FILTER");
|
||||||
|
|
||||||
#ifdef RNDIS_DELAY_LINK_UP
|
#ifdef RNDIS_DELAY_LINK_UP
|
||||||
/* link up. */
|
/* link up. */
|
||||||
|
@ -592,6 +594,7 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
LOG_W("Unknow rndis set 0x%02X", msg->Oid);
|
||||||
resp->Status = RNDIS_STATUS_FAILURE;
|
resp->Status = RNDIS_STATUS_FAILURE;
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
@ -609,6 +612,58 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static rt_err_t _rndis_reset_response(ufunction_t func,rndis_set_msg_t msg)
|
||||||
|
{
|
||||||
|
struct rndis_reset_cmplt * resp;
|
||||||
|
struct rt_rndis_response * response;
|
||||||
|
|
||||||
|
response = rt_malloc(sizeof(struct rt_rndis_response));
|
||||||
|
resp = rt_malloc(sizeof(struct rndis_reset_cmplt));
|
||||||
|
|
||||||
|
if( (response == RT_NULL) || (resp == RT_NULL) )
|
||||||
|
{
|
||||||
|
LOG_E("%s,%d: no memory!", __func__, __LINE__);
|
||||||
|
|
||||||
|
if(response != RT_NULL)
|
||||||
|
rt_free(response);
|
||||||
|
|
||||||
|
if(resp != RT_NULL)
|
||||||
|
rt_free(resp);
|
||||||
|
|
||||||
|
return -RT_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reset packet filter */
|
||||||
|
|
||||||
|
oid_packet_filter = 0x0000000;
|
||||||
|
|
||||||
|
/* link down eth */
|
||||||
|
|
||||||
|
eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
|
||||||
|
|
||||||
|
/* reset eth rx tx */
|
||||||
|
((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
|
||||||
|
((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
|
||||||
|
rt_sem_release(&((rt_rndis_eth_t)func->user_data)->tx_buffer_free);
|
||||||
|
eth_device_ready(&(((rt_rndis_eth_t)func->user_data)->parent));
|
||||||
|
|
||||||
|
|
||||||
|
resp->MessageType = REMOTE_NDIS_RESET_CMPLT;
|
||||||
|
resp->MessageLength = sizeof(struct rndis_reset_cmplt);
|
||||||
|
resp->Status = RNDIS_STATUS_SUCCESS;
|
||||||
|
resp->AddressingReset = 1;
|
||||||
|
|
||||||
|
response->buffer = resp;
|
||||||
|
|
||||||
|
{
|
||||||
|
rt_base_t level = rt_hw_interrupt_disable();
|
||||||
|
rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
static rt_err_t _rndis_keepalive_response(ufunction_t func,rndis_keepalive_msg_t msg)
|
static rt_err_t _rndis_keepalive_response(ufunction_t func,rndis_keepalive_msg_t msg)
|
||||||
{
|
{
|
||||||
rndis_keepalive_cmplt_t resp;
|
rndis_keepalive_cmplt_t resp;
|
||||||
|
@ -619,7 +674,7 @@ static rt_err_t _rndis_keepalive_response(ufunction_t func,rndis_keepalive_msg_t
|
||||||
|
|
||||||
if( (response == RT_NULL) || (resp == RT_NULL) )
|
if( (response == RT_NULL) || (resp == RT_NULL) )
|
||||||
{
|
{
|
||||||
RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
|
LOG_E("%s,%d: no memory!", __func__, __LINE__);
|
||||||
|
|
||||||
if(response != RT_NULL)
|
if(response != RT_NULL)
|
||||||
rt_free(response);
|
rt_free(response);
|
||||||
|
@ -652,34 +707,45 @@ static rt_err_t _rndis_msg_parser(ufunction_t func, rt_uint8_t *msg)
|
||||||
switch (((rndis_gen_msg_t) msg)->MessageType)
|
switch (((rndis_gen_msg_t) msg)->MessageType)
|
||||||
{
|
{
|
||||||
case REMOTE_NDIS_INITIALIZE_MSG:
|
case REMOTE_NDIS_INITIALIZE_MSG:
|
||||||
|
LOG_D("REMOTE_NDIS_INITIALIZE_MSG");
|
||||||
ret = _rndis_init_response(func, (rndis_init_msg_t) msg);
|
ret = _rndis_init_response(func, (rndis_init_msg_t) msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REMOTE_NDIS_HALT_MSG:
|
case REMOTE_NDIS_HALT_MSG:
|
||||||
RNDIS_PRINTF("halt\n");
|
LOG_D("REMOTE_NDIS_HALT_MSG");
|
||||||
/* link down. */
|
/* link down. */
|
||||||
eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
|
eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
|
||||||
|
|
||||||
|
/* reset eth rx tx */
|
||||||
|
((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
|
||||||
|
((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
|
||||||
|
rt_sem_release(&((rt_rndis_eth_t)func->user_data)->tx_buffer_free);
|
||||||
|
eth_device_ready(&(((rt_rndis_eth_t)func->user_data)->parent));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REMOTE_NDIS_QUERY_MSG:
|
case REMOTE_NDIS_QUERY_MSG:
|
||||||
|
LOG_D("REMOTE_NDIS_QUERY_MSG");
|
||||||
ret = _rndis_query_response(func,(rndis_query_msg_t) msg);
|
ret = _rndis_query_response(func,(rndis_query_msg_t) msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REMOTE_NDIS_SET_MSG:
|
case REMOTE_NDIS_SET_MSG:
|
||||||
|
LOG_D("REMOTE_NDIS_SET_MSG");
|
||||||
ret = _rndis_set_response(func,(rndis_set_msg_t) msg);
|
ret = _rndis_set_response(func,(rndis_set_msg_t) msg);
|
||||||
RNDIS_PRINTF("set\n");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REMOTE_NDIS_RESET_MSG:
|
case REMOTE_NDIS_RESET_MSG:
|
||||||
RNDIS_PRINTF("reset\n");
|
LOG_D("REMOTE_NDIS_RESET_MSG");
|
||||||
|
ret = _rndis_reset_response(func,(rndis_set_msg_t) msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REMOTE_NDIS_KEEPALIVE_MSG:
|
case REMOTE_NDIS_KEEPALIVE_MSG:
|
||||||
|
LOG_D("REMOTE_NDIS_KEEPALIVE_MSG");
|
||||||
ret = _rndis_keepalive_response(func,(rndis_keepalive_msg_t) msg);
|
ret = _rndis_keepalive_response(func,(rndis_keepalive_msg_t) msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
RNDIS_PRINTF("msg %X\n", ((rndis_gen_msg_t) msg)->MessageType);
|
LOG_W("not support RNDIS msg %X", ((rndis_gen_msg_t) msg)->MessageType);
|
||||||
ret = -RT_ERROR;
|
ret = -RT_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -718,7 +784,7 @@ static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
|
||||||
|
|
||||||
if(rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
|
if(rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
|
||||||
{
|
{
|
||||||
RNDIS_PRINTF("response_list is empty!\r\n");
|
LOG_D("response_list is empty!");
|
||||||
((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE;
|
((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE;
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
@ -741,7 +807,7 @@ static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
|
||||||
{
|
{
|
||||||
rt_uint32_t * data;
|
rt_uint32_t * data;
|
||||||
|
|
||||||
RNDIS_PRINTF("auto append next response!\r\n");
|
LOG_I("auto append next response!");
|
||||||
data = (rt_uint32_t *)((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->buffer;
|
data = (rt_uint32_t *)((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->buffer;
|
||||||
data[0] = RESPONSE_AVAILABLE;
|
data[0] = RESPONSE_AVAILABLE;
|
||||||
data[1] = 0;
|
data[1] = 0;
|
||||||
|
@ -758,55 +824,6 @@ static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RNDIS_DELAY_LINK_UP
|
|
||||||
/**
|
|
||||||
* This function will set rndis connect status.
|
|
||||||
*
|
|
||||||
* @param device the usb device object.
|
|
||||||
* @param status the connect status.
|
|
||||||
*
|
|
||||||
* @return RT_EOK on successful.
|
|
||||||
*/
|
|
||||||
static rt_err_t _rndis_indicate_status_msg(ufunction_t func, rt_uint32_t status)
|
|
||||||
{
|
|
||||||
rndis_indicate_status_msg_t resp;
|
|
||||||
struct rt_rndis_response * response;
|
|
||||||
|
|
||||||
response = rt_malloc(sizeof(struct rt_rndis_response));
|
|
||||||
resp = rt_malloc(sizeof(struct rndis_indicate_status_msg));
|
|
||||||
|
|
||||||
if( (response == RT_NULL) || (resp == RT_NULL) )
|
|
||||||
{
|
|
||||||
RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
|
|
||||||
|
|
||||||
if(response != RT_NULL)
|
|
||||||
rt_free(response);
|
|
||||||
|
|
||||||
if(resp != RT_NULL)
|
|
||||||
rt_free(resp);
|
|
||||||
|
|
||||||
return -RT_ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
|
|
||||||
resp->MessageLength = 20; /* sizeof(struct rndis_indicate_status_msg) */
|
|
||||||
resp->Status = status;
|
|
||||||
resp->StatusBufferLength = 0;
|
|
||||||
resp->StatusBufferOffset = 0;
|
|
||||||
|
|
||||||
response->buffer = resp;
|
|
||||||
{
|
|
||||||
rt_base_t level = rt_hw_interrupt_disable();
|
|
||||||
rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
|
|
||||||
rt_hw_interrupt_enable(level);
|
|
||||||
}
|
|
||||||
|
|
||||||
_rndis_response_available(func);
|
|
||||||
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
#endif /* RNDIS_DELAY_LINK_UP */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function will handle rndis interface request.
|
* This function will handle rndis interface request.
|
||||||
*
|
*
|
||||||
|
@ -831,7 +848,7 @@ static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
RNDIS_PRINTF("unkown setup->request!\r\n");
|
LOG_W("unkown setup->request 0x%02X !", setup->bRequest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -933,6 +950,8 @@ static rt_err_t _function_enable(ufunction_t func)
|
||||||
{
|
{
|
||||||
cdc_eps_t eps;
|
cdc_eps_t eps;
|
||||||
|
|
||||||
|
LOG_I("plugged in");
|
||||||
|
|
||||||
eps = (cdc_eps_t)&((rt_rndis_eth_t)func->user_data)->eps;
|
eps = (cdc_eps_t)&((rt_rndis_eth_t)func->user_data)->eps;
|
||||||
eps->ep_in->buffer = ((rt_rndis_eth_t)func->user_data)->tx_pool;
|
eps->ep_in->buffer = ((rt_rndis_eth_t)func->user_data)->tx_pool;
|
||||||
eps->ep_out->buffer = ((rt_rndis_eth_t)func->user_data)->rx_pool;
|
eps->ep_out->buffer = ((rt_rndis_eth_t)func->user_data)->rx_pool;
|
||||||
|
@ -945,6 +964,7 @@ static rt_err_t _function_enable(ufunction_t func)
|
||||||
|
|
||||||
((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
|
((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
|
||||||
((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
|
((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
|
||||||
|
eth_device_ready(&(((rt_rndis_eth_t)func->user_data)->parent));
|
||||||
|
|
||||||
#ifdef RNDIS_DELAY_LINK_UP
|
#ifdef RNDIS_DELAY_LINK_UP
|
||||||
/* stop link up timer. */
|
/* stop link up timer. */
|
||||||
|
@ -981,7 +1001,7 @@ static rt_err_t _function_enable(ufunction_t func)
|
||||||
*/
|
*/
|
||||||
static rt_err_t _function_disable(ufunction_t func)
|
static rt_err_t _function_disable(ufunction_t func)
|
||||||
{
|
{
|
||||||
RNDIS_PRINTF("plugged out\n");
|
LOG_I("plugged out");
|
||||||
|
|
||||||
#ifdef RNDIS_DELAY_LINK_UP
|
#ifdef RNDIS_DELAY_LINK_UP
|
||||||
/* stop link up timer. */
|
/* stop link up timer. */
|
||||||
|
@ -996,7 +1016,7 @@ static rt_err_t _function_disable(ufunction_t func)
|
||||||
while(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
|
while(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
|
||||||
{
|
{
|
||||||
response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next;
|
response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next;
|
||||||
RNDIS_PRINTF("remove resp chain list!\r\n");
|
LOG_D("remove resp chain list!");
|
||||||
|
|
||||||
rt_list_remove(&response->list);
|
rt_list_remove(&response->list);
|
||||||
rt_free((void *)response->buffer);
|
rt_free((void *)response->buffer);
|
||||||
|
@ -1007,8 +1027,16 @@ static rt_err_t _function_disable(ufunction_t func)
|
||||||
rt_hw_interrupt_enable(level);
|
rt_hw_interrupt_enable(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* link down. */
|
/* link down. */
|
||||||
eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
|
eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
|
||||||
|
|
||||||
|
/* reset eth rx tx */
|
||||||
|
((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
|
||||||
|
((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
|
||||||
|
rt_sem_release(&((rt_rndis_eth_t)func->user_data)->tx_buffer_free);
|
||||||
|
eth_device_ready(&(((rt_rndis_eth_t)func->user_data)->parent));
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1141,14 +1169,14 @@ rt_err_t rt_rndis_eth_tx(rt_device_t dev, struct pbuf* p)
|
||||||
|
|
||||||
if(!device->parent.link_status)
|
if(!device->parent.link_status)
|
||||||
{
|
{
|
||||||
RNDIS_PRINTF("linkdown, drop pkg\r\n");
|
LOG_I("linkdown, drop pkg");
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
RT_ASSERT(p->tot_len < sizeof(device->tx_buffer));
|
RT_ASSERT(p->tot_len < sizeof(device->tx_buffer));
|
||||||
if(p->tot_len > sizeof(device->tx_buffer))
|
if(p->tot_len > sizeof(device->tx_buffer))
|
||||||
{
|
{
|
||||||
RNDIS_PRINTF("RNDIS MTU is:%d, but the send packet size is %d\r\n",
|
LOG_W("RNDIS MTU is:%d, but the send packet size is %d",
|
||||||
sizeof(device->tx_buffer), p->tot_len);
|
sizeof(device->tx_buffer), p->tot_len);
|
||||||
p->tot_len = sizeof(device->tx_buffer);
|
p->tot_len = sizeof(device->tx_buffer);
|
||||||
}
|
}
|
||||||
|
@ -1215,11 +1243,59 @@ const static struct rt_device_ops rndis_device_ops =
|
||||||
#endif /* RT_USING_LWIP */
|
#endif /* RT_USING_LWIP */
|
||||||
|
|
||||||
#ifdef RNDIS_DELAY_LINK_UP
|
#ifdef RNDIS_DELAY_LINK_UP
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set rndis connect status.
|
||||||
|
*
|
||||||
|
* @param device the usb device object.
|
||||||
|
* @param status the connect status.
|
||||||
|
*
|
||||||
|
* @return RT_EOK on successful.
|
||||||
|
*/
|
||||||
|
static rt_err_t _rndis_indicate_status_msg(ufunction_t func, rt_uint32_t status)
|
||||||
|
{
|
||||||
|
rndis_indicate_status_msg_t resp;
|
||||||
|
struct rt_rndis_response * response;
|
||||||
|
|
||||||
|
response = rt_malloc(sizeof(struct rt_rndis_response));
|
||||||
|
resp = rt_malloc(sizeof(struct rndis_indicate_status_msg));
|
||||||
|
|
||||||
|
if( (response == RT_NULL) || (resp == RT_NULL) )
|
||||||
|
{
|
||||||
|
LOG_E("%s,%d: no memory!", __func__, __LINE__);
|
||||||
|
|
||||||
|
if(response != RT_NULL)
|
||||||
|
rt_free(response);
|
||||||
|
|
||||||
|
if(resp != RT_NULL)
|
||||||
|
rt_free(resp);
|
||||||
|
|
||||||
|
return -RT_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
|
||||||
|
resp->MessageLength = 20; /* sizeof(struct rndis_indicate_status_msg) */
|
||||||
|
resp->Status = status;
|
||||||
|
resp->StatusBufferLength = 0;
|
||||||
|
resp->StatusBufferOffset = 0;
|
||||||
|
|
||||||
|
response->buffer = resp;
|
||||||
|
{
|
||||||
|
rt_base_t level = rt_hw_interrupt_disable();
|
||||||
|
rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
_rndis_response_available(func);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
/* the delay linkup timer handler. */
|
/* the delay linkup timer handler. */
|
||||||
static void timer_timeout(void* parameter)
|
static void timer_timeout(void* parameter)
|
||||||
{
|
{
|
||||||
RNDIS_PRINTF("delay link up!\r\n");
|
LOG_I("delay link up!");
|
||||||
_rndis_indicate_status_msg(((rt_rndis_eth_t)parameter)->parent.parent.user_data,
|
_rndis_indicate_status_msg(((rt_rndis_eth_t)parameter)->func,
|
||||||
RNDIS_STATUS_MEDIA_CONNECT);
|
RNDIS_STATUS_MEDIA_CONNECT);
|
||||||
eth_device_linkchange(&((rt_rndis_eth_t)parameter)->parent, RT_TRUE);
|
eth_device_linkchange(&((rt_rndis_eth_t)parameter)->parent, RT_TRUE);
|
||||||
}
|
}
|
||||||
|
@ -1373,3 +1449,5 @@ int rt_usbd_rndis_class_register(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
INIT_PREV_EXPORT(rt_usbd_rndis_class_register);
|
INIT_PREV_EXPORT(rt_usbd_rndis_class_register);
|
||||||
|
|
||||||
|
#endif /* RT_USB_DEVICE_RNDIS */
|
||||||
|
|
|
@ -180,6 +180,15 @@ struct rndis_reset_msg
|
||||||
rt_uint32_t Reserved;
|
rt_uint32_t Reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Remote NDIS Soft Reset Response */
|
||||||
|
struct rndis_reset_cmplt
|
||||||
|
{
|
||||||
|
rt_uint32_t MessageType;
|
||||||
|
rt_uint32_t MessageLength;
|
||||||
|
rt_uint32_t Status;
|
||||||
|
rt_uint32_t AddressingReset;
|
||||||
|
};
|
||||||
|
|
||||||
/* Remote NDIS Indicate Status Message */
|
/* Remote NDIS Indicate Status Message */
|
||||||
struct rndis_indicate_status_msg
|
struct rndis_indicate_status_msg
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue