drivers/usbdev/rndis.c: fix packet receiving logic. The logic didn't take single-byte termination frames in account.
This commit is contained in:
parent
349b513978
commit
07b98ccbb5
@ -158,6 +158,7 @@ struct rndis_dev_s
|
||||
size_t current_rx_received; /* Number of bytes of current RX datagram received over USB */
|
||||
size_t current_rx_datagram_size; /* Total number of bytes of the current RX datagram */
|
||||
size_t current_rx_datagram_offset; /* Offset of current RX datagram */
|
||||
size_t current_rx_msglen; /* Length of the entire message to be received */
|
||||
bool rdreq_submitted; /* Indicates if the read request is submitted */
|
||||
bool rx_blocked; /* Indicates if we can receive packets on bulk in endpoint */
|
||||
bool ctrlreq_has_encap_response; /* Indicates if ctrlreq buffer holds a response */
|
||||
@ -824,7 +825,6 @@ static void rndis_rxdispatch(FAR void *arg)
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
if (hdr->type == HTONS(ETHTYPE_IP))
|
||||
{
|
||||
uinfo("IPv4 frame\n");
|
||||
NETDEV_RXIPV4(&priv->netdev);
|
||||
|
||||
/* Handle ARP on input then give the IPv4 packet to the network
|
||||
@ -839,7 +839,6 @@ static void rndis_rxdispatch(FAR void *arg)
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
if (hdr->type == HTONS(ETHTYPE_IP6))
|
||||
{
|
||||
uinfo("IPv6 frame\n");
|
||||
NETDEV_RXIPV6(&priv->netdev);
|
||||
|
||||
/* Give the IPv6 packet to the network layer */
|
||||
@ -851,7 +850,6 @@ static void rndis_rxdispatch(FAR void *arg)
|
||||
#ifdef CONFIG_NET_ARP
|
||||
if (hdr->type == htons(ETHTYPE_ARP))
|
||||
{
|
||||
uinfo("ARP packet received (%02x)\n", hdr->type);
|
||||
NETDEV_RXARP(&priv->netdev);
|
||||
|
||||
arp_arpin(&priv->netdev);
|
||||
@ -904,7 +902,7 @@ static int rndis_txpoll(FAR struct net_driver_s *dev)
|
||||
* the field d_len is set to a value > 0.
|
||||
*/
|
||||
|
||||
uinfo("Poll result: d_len=%d\n", priv->netdev.d_len);
|
||||
ninfo("Poll result: d_len=%d\n", priv->netdev.d_len);
|
||||
if (priv->netdev.d_len > 0)
|
||||
{
|
||||
/* Look up the destination MAC address and add it to the Ethernet
|
||||
@ -1123,6 +1121,17 @@ static inline int rndis_recvpacket(FAR struct rndis_dev_s *priv,
|
||||
{
|
||||
priv->current_rx_received = reqlen;
|
||||
priv->current_rx_datagram_size = msg->datalen;
|
||||
priv->current_rx_msglen = msg->msglen;
|
||||
|
||||
/* According to RNDIS-over-USB send, if the message length is a
|
||||
* multiple of endpoint max packet size, the host must send an
|
||||
* additional single-byte zero packet. Take that in account here.
|
||||
*/
|
||||
|
||||
if (priv->current_rx_msglen % 64 == 0)
|
||||
{
|
||||
priv->current_rx_msglen += 1;
|
||||
}
|
||||
|
||||
/* Data offset is defined as an offset from the beginning of the
|
||||
* offset field itself
|
||||
@ -1142,20 +1151,24 @@ static inline int rndis_recvpacket(FAR struct rndis_dev_s *priv,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (priv->current_rx_received >= priv->current_rx_datagram_offset &&
|
||||
priv->current_rx_received < priv->current_rx_datagram_size +
|
||||
priv->current_rx_datagram_offset)
|
||||
else
|
||||
{
|
||||
size_t index = priv->current_rx_received - priv->current_rx_datagram_offset;
|
||||
size_t copysize = min(reqlen, priv->current_rx_datagram_size +
|
||||
priv->current_rx_datagram_offset -
|
||||
priv->current_rx_received);
|
||||
memcpy(&priv->rx_req->req->buf[RNDIS_PACKET_HDR_SIZE + index], reqbuf,
|
||||
copysize);
|
||||
if (priv->current_rx_received >= priv->current_rx_datagram_offset &&
|
||||
priv->current_rx_received < priv->current_rx_datagram_size +
|
||||
priv->current_rx_datagram_offset)
|
||||
{
|
||||
|
||||
size_t index = priv->current_rx_received - priv->current_rx_datagram_offset;
|
||||
size_t copysize = min(reqlen, priv->current_rx_datagram_size +
|
||||
priv->current_rx_datagram_offset -
|
||||
priv->current_rx_received);
|
||||
memcpy(&priv->rx_req->req->buf[RNDIS_PACKET_HDR_SIZE + index], reqbuf,
|
||||
copysize);
|
||||
}
|
||||
|
||||
priv->current_rx_received += reqlen;
|
||||
|
||||
if (priv->current_rx_received >= priv->current_rx_datagram_size +
|
||||
priv->current_rx_datagram_offset)
|
||||
if (priv->current_rx_received >= priv->current_rx_msglen)
|
||||
{
|
||||
/* Check for a usable packet length (4 added for the CRC) */
|
||||
|
||||
@ -1165,6 +1178,7 @@ static inline int rndis_recvpacket(FAR struct rndis_dev_s *priv,
|
||||
uerr("ERROR: Bad packet size dropped (%d)\n",
|
||||
priv->current_rx_datagram_size);
|
||||
NETDEV_RXERRORS(&priv->netdev);
|
||||
priv->current_rx_datagram_size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1182,12 +1196,6 @@ static inline int rndis_recvpacket(FAR struct rndis_dev_s *priv,
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ignore the packet */
|
||||
|
||||
priv->current_rx_received += reqlen;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user