From 5e468010967b893feb7a623959d788d10e38940b Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Thu, 26 Nov 2009 11:40:15 +0000
Subject: [PATCH] Complete RNDIS Host Class driver code - add SendPacket
 function.

Correct CDC Host Class driver token handling for sending data on bidirectional data endpoints.
---
 LUFA/Drivers/USB/Class/Host/CDC.c   |  4 +--
 LUFA/Drivers/USB/Class/Host/RNDIS.c | 43 +++++++++++++++++++++++++++++
 LUFA/Drivers/USB/Class/Host/RNDIS.h | 11 ++++++++
 3 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/LUFA/Drivers/USB/Class/Host/CDC.c b/LUFA/Drivers/USB/Class/Host/CDC.c
index d1e63b591..20fa65988 100644
--- a/LUFA/Drivers/USB/Class/Host/CDC.c
+++ b/LUFA/Drivers/USB/Class/Host/CDC.c
@@ -280,7 +280,7 @@ uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, ch
 	if (CDCInterfaceInfo->State.BidirectionalDataEndpoints)
 	{
 		Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
-		Pipe_SetPipeToken(PIPE_TOKEN_IN);
+		Pipe_SetPipeToken(PIPE_TOKEN_OUT);
 	}
 	else
 	{
@@ -307,7 +307,7 @@ uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, cons
 	if (CDCInterfaceInfo->State.BidirectionalDataEndpoints)
 	{
 		Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
-		Pipe_SetPipeToken(PIPE_TOKEN_IN);
+		Pipe_SetPipeToken(PIPE_TOKEN_OUT);
 	}
 	else
 	{
diff --git a/LUFA/Drivers/USB/Class/Host/RNDIS.c b/LUFA/Drivers/USB/Class/Host/RNDIS.c
index e44d05fab..b22674855 100644
--- a/LUFA/Drivers/USB/Class/Host/RNDIS.c
+++ b/LUFA/Drivers/USB/Class/Host/RNDIS.c
@@ -443,4 +443,47 @@ uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceIn
 	return PIPE_RWSTREAM_NoError;
 }
 
+uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, void* Buffer, uint16_t PacketLength)
+{
+	uint8_t ErrorCode;
+
+	if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
+	  return PIPE_READYWAIT_DeviceDisconnected;
+
+	if (RNDISInterfaceInfo->State.BidirectionalDataEndpoints)
+	{
+		Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipeNumber);
+		Pipe_SetPipeToken(PIPE_TOKEN_OUT);
+	}
+	else
+	{
+		Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber);	
+	}
+
+	Pipe_Unfreeze();
+
+	RNDIS_Packet_Message_t DeviceMessage;
+	
+	DeviceMessage.MessageType = REMOTE_NDIS_PACKET_MSG;
+	DeviceMessage.MessageLength = (sizeof(RNDIS_Packet_Message_t) + PacketLength);
+	DeviceMessage.DataOffset = (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
+	DeviceMessage.DataLength = PacketLength;
+	
+	if ((ErrorCode = Pipe_Write_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
+	                                      NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+	{
+		return ErrorCode;
+	}
+	
+	Pipe_Write_Stream_LE(Buffer, PacketLength, NO_STREAM_CALLBACK);
+	Pipe_ClearOUT();
+
+	Pipe_Freeze();
+	
+	if (RNDISInterfaceInfo->State.BidirectionalDataEndpoints)
+	  Pipe_SetPipeToken(PIPE_TOKEN_IN);
+	
+	return PIPE_RWSTREAM_NoError;
+}
+
 #endif
diff --git a/LUFA/Drivers/USB/Class/Host/RNDIS.h b/LUFA/Drivers/USB/Class/Host/RNDIS.h
index 9b14055e7..b20e98946 100644
--- a/LUFA/Drivers/USB/Class/Host/RNDIS.h
+++ b/LUFA/Drivers/USB/Class/Host/RNDIS.h
@@ -209,6 +209,17 @@
 			uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, void* Buffer, uint16_t* PacketLength)
 			                              ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3);
 
+			/** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header.
+			 *
+			 *  \param[in,out] RNDISInterfaceInfo  Pointer to a structure containing an RNDIS Class host configuration and state
+			 *  \param[in] Buffer  Pointer to a buffer where the packer data is to be read from
+			 *  \param[in] PacketLength  Length in bytes of the packet to send
+			 *
+			 *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
+			 */
+			uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, void* Buffer, uint16_t PacketLength)
+			                              ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
 		/* Macros: */
-- 
GitLab