Re-added Pipe_IsEndpointBound() calls to the CDC and RNDIS host class drivers, not that the function has the correct behaviour for devices with bidirectional endpoints.
\r
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);\r
\r
\r
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);\r
\r
- if ((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT))\r
+ if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&\r
+ !(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress)))\r
{\r
return DESCRIPTOR_SEARCH_Found;\r
}\r
{\r
return DESCRIPTOR_SEARCH_Found;\r
}\r
\r
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);\r
\r
\r
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);\r
\r
- if ((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT))\r
+ if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&\r
+ !(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress)))\r
{\r
return DESCRIPTOR_SEARCH_Found;\r
}\r
{\r
return DESCRIPTOR_SEARCH_Found;\r
}\r
*/\r
#define ENDPOINT_EPNUM_MASK 0x07\r
\r
*/\r
#define ENDPOINT_EPNUM_MASK 0x07\r
\r
+ /** Endpoint direction mask, for masking against endpoint addresses to retrieve the endpoint's\r
+ * direction for comparing with the ENDPOINT_DESCRIPTOR_DIR_* masks.\r
+ */\r
+ #define ENDPOINT_EPDIR_MASK 0x80\r
+\r
/** Endpoint bank size mask, for masking against endpoint addresses to retrieve the endpoint's\r
* bank size in the device.\r
*/\r
/** Endpoint bank size mask, for masking against endpoint addresses to retrieve the endpoint's\r
* bank size in the device.\r
*/\r
{\r
Pipe_SelectPipe(PNum);\r
\r
{\r
Pipe_SelectPipe(PNum);\r
\r
- if (Pipe_IsConfigured() && (Pipe_BoundEndpointNumber() == (EndpointAddress & PIPE_EPNUM_MASK)))\r
- return true;\r
+ uint8_t PipeToken = Pipe_GetPipeToken();\r
+\r
+ if (PipeToken != PIPE_TOKEN_SETUP)\r
+ PipeToken = (PipeToken == ((EndpointAddress & PIPE_EPDIR_MASK) ? PIPE_TOKEN_IN : PIPE_TOKEN_OUT));\r
+ \r
+ if (Pipe_IsConfigured() && (Pipe_BoundEndpointNumber() == (EndpointAddress & PIPE_EPNUM_MASK)) && PipeToken)\r
+ { \r
+ return true;\r
+ }\r
}\r
\r
Pipe_SelectPipe(PrevPipeNumber);\r
}\r
\r
Pipe_SelectPipe(PrevPipeNumber);\r
*/\r
#define PIPE_EPNUM_MASK 0x0F\r
\r
*/\r
#define PIPE_EPNUM_MASK 0x0F\r
\r
+ /** Endpoint direction mask, for masking against endpoint addresses to retrieve the endpoint's\r
+ * direction for comparing with the ENDPOINT_DESCRIPTOR_DIR_* masks.\r
+ */\r
+ #define PIPE_EPDIR_MASK 0x80\r
+\r
/* Pseudo-Function Macros: */\r
#if defined(__DOXYGEN__)\r
/** Indicates the number of bytes currently stored in the current pipes's selected bank.\r
/* Pseudo-Function Macros: */\r
#if defined(__DOXYGEN__)\r
/** Indicates the number of bytes currently stored in the current pipes's selected bank.\r
/** Determines if a pipe has been bound to the given device endpoint address. If a pipe which is bound to the given\r
* endpoint is found, it is automatically selected.\r
*\r
/** Determines if a pipe has been bound to the given device endpoint address. If a pipe which is bound to the given\r
* endpoint is found, it is automatically selected.\r
*\r
- * \param[in] EndpointAddress Address of the endpoint within the attached device to check\r
+ * \param[in] EndpointAddress Address and direction mask of the endpoint within the attached device to check\r
- * \return Boolean true if a pipe bound to the given endpoint address is found, false otherwise\r
+ * \return Boolean true if a pipe bound to the given endpoint address of the specified direction is found, false\r
+ * otherwise\r
*/\r
bool Pipe_IsEndpointBound(const uint8_t EndpointAddress);\r
\r
*/\r
bool Pipe_IsEndpointBound(const uint8_t EndpointAddress);\r
\r
* - Fixed DFU bootloader programming not discarding the correct number of filler bytes from the host when non-aligned programming\r
* ranges are specified (thanks to Thomas Bleeker)\r
* - Fixed CDC and RNDIS host demos and class drivers - bidirectional endpoints should use two seperate pipes, not one half-duplex pipe\r
* - Fixed DFU bootloader programming not discarding the correct number of filler bytes from the host when non-aligned programming\r
* ranges are specified (thanks to Thomas Bleeker)\r
* - Fixed CDC and RNDIS host demos and class drivers - bidirectional endpoints should use two seperate pipes, not one half-duplex pipe\r
+ * - Fixed Pipe_IsEndpointBound() not taking the endpoint's direction into account\r
*\r
* \section Sec_ChangeLog091223 Version 091223\r
*\r
*\r
* \section Sec_ChangeLog091223 Version 091223\r
*\r
* packed into a single USB packet. This means that the sending of MIDI events will now be delayed until the MIDI send\r
* pipe bank is full. To override this new behaviour and revert to the previous behaviour, the user application may manually\r
* flush the queued event(s) to the device by calling \ref MIDI_Host_Flush().\r
* packed into a single USB packet. This means that the sending of MIDI events will now be delayed until the MIDI send\r
* pipe bank is full. To override this new behaviour and revert to the previous behaviour, the user application may manually\r
* flush the queued event(s) to the device by calling \ref MIDI_Host_Flush().\r
+ * - The Pipe_IsEndpointBound() function now takes the endpoint's direction into account, by checking if the MSB of the endpoint's address\r
+ * is set to denote IN endpoints. If the previous functionality where the direction is to be discounted is required, mask the endpoint\r
+ * address against the \ref PIPE_EPNUM_MASK token before calling Pipe_IsEndpointBound().\r
*\r
* <b>Device Mode</b>\r
* - The MIDI Device Class driver send and receive routines now operate on packed events, where multiple MIDI events may be\r
*\r
* <b>Device Mode</b>\r
* - The MIDI Device Class driver send and receive routines now operate on packed events, where multiple MIDI events may be\r
char PROGMEM HTTP200Header[] = "HTTP/1.1 200 OK\r\n"\r
"Server: LUFA RNDIS\r\n"\r
"Connection: close\r\n"\r
char PROGMEM HTTP200Header[] = "HTTP/1.1 200 OK\r\n"\r
"Server: LUFA RNDIS\r\n"\r
"Connection: close\r\n"\r
- "MIME-version: 1.0\r\n"\r
- "Content-Type: ";\r
+ "MIME-version: 1.0\r\n"\r
+ "Content-Type: ";\r
\r
/** HTTP server response header, for transmission before a resource not found error. This indicates to the host that the given\r
* given URL is invalid, and gives extra error information.\r
\r
/** HTTP server response header, for transmission before a resource not found error. This indicates to the host that the given\r
* given URL is invalid, and gives extra error information.\r
char PROGMEM HTTP404Header[] = "HTTP/1.1 404 Not Found\r\n"\r
"Server: LUFA RNDIS\r\n"\r
"Connection: close\r\n"\r
char PROGMEM HTTP404Header[] = "HTTP/1.1 404 Not Found\r\n"\r
"Server: LUFA RNDIS\r\n"\r
"Connection: close\r\n"\r
- "MIME-version: 1.0\r\n"\r
- "Content-Type: text/plain\r\n\r\n"\r
- "Error 404: File Not Found";\r
+ "MIME-version: 1.0\r\n"\r
+ "Content-Type: text/plain\r\n\r\n"\r
+ "Error 404: File Not Found";\r
\r
/** Default MIME type sent if no other MIME type can be determined */\r
char PROGMEM DefaultMIMEType[] = "text/plain";\r
\r
/** Default MIME type sent if no other MIME type can be determined */\r
char PROGMEM DefaultMIMEType[] = "text/plain";\r
\r
if (uip_aborted() || uip_timedout() || uip_closed())\r
{\r
\r
if (uip_aborted() || uip_timedout() || uip_closed())\r
{\r
- /* Connection is being terminated for some reason - close file handle if open */\r
- if (AppState->FileOpen)\r
- {\r
- f_close(&AppState->FileHandle);\r
- AppState->FileOpen = false;\r
- }\r
+ /* Connection is being terminated for some reason - close file handle */\r
+ f_close(&AppState->FileHandle);\r
+ AppState->FileOpen = false;\r
\r
/* Lock to the closed state so that no further processing will occur on the connection */\r
AppState->CurrentState = WEBSERVER_STATE_Closed;\r
\r
/* Lock to the closed state so that no further processing will occur on the connection */\r
AppState->CurrentState = WEBSERVER_STATE_Closed;\r
static void Webserver_OpenRequestedFile(void)\r
{\r
uip_tcp_appstate_t* const AppState = &uip_conn->appstate;\r
static void Webserver_OpenRequestedFile(void)\r
{\r
uip_tcp_appstate_t* const AppState = &uip_conn->appstate;\r
- char* AppData = (char*)uip_appdata;\r
+ char* const AppData = (char*)uip_appdata;\r
\r
/* No HTTP header received from the client, abort processing */\r
if (!(uip_newdata()))\r
\r
/* No HTTP header received from the client, abort processing */\r
if (!(uip_newdata()))\r
static void Webserver_SendResponseHeader(void)\r
{\r
uip_tcp_appstate_t* const AppState = &uip_conn->appstate;\r
static void Webserver_SendResponseHeader(void)\r
{\r
uip_tcp_appstate_t* const AppState = &uip_conn->appstate;\r
- char* AppData = (char*)uip_appdata;\r
+ char* const AppData = (char*)uip_appdata;\r
\r
char* HeaderToSend;\r
uint16_t HeaderLength;\r
\r
\r
char* HeaderToSend;\r
uint16_t HeaderLength;\r
\r
- /* Determine what HTTP header should be sent to the client */\r
+ /* Determine which HTTP header should be sent to the client */\r
if (AppState->FileOpen)\r
{\r
HeaderToSend = HTTP200Header;\r
if (AppState->FileOpen)\r
{\r
HeaderToSend = HTTP200Header;\r
AppState->NextState = WEBSERVER_STATE_Closing;\r
}\r
\r
AppState->NextState = WEBSERVER_STATE_Closing;\r
}\r
\r
+ /* Copy over the HTTP response header and send it to the receiving client */\r
HeaderLength = strlen_P(HeaderToSend);\r
strncpy_P(AppData, HeaderToSend, HeaderLength);\r
uip_send(AppData, HeaderLength);\r
HeaderLength = strlen_P(HeaderToSend);\r
strncpy_P(AppData, HeaderToSend, HeaderLength);\r
uip_send(AppData, HeaderLength);\r
static void Webserver_SendMIMETypeHeader(void)\r
{\r
uip_tcp_appstate_t* const AppState = &uip_conn->appstate;\r
static void Webserver_SendMIMETypeHeader(void)\r
{\r
uip_tcp_appstate_t* const AppState = &uip_conn->appstate;\r
- char* AppData = (char*)uip_appdata;\r
+ char* const AppData = (char*)uip_appdata;\r
\r
char* Extension = strpbrk(AppState->FileName, ".");\r
uint16_t MIMEHeaderLength = 0;\r
\r
char* Extension = strpbrk(AppState->FileName, ".");\r
uint16_t MIMEHeaderLength = 0;\r
static void Webserver_SendData(void)\r
{\r
uip_tcp_appstate_t* const AppState = &uip_conn->appstate;\r
static void Webserver_SendData(void)\r
{\r
uip_tcp_appstate_t* const AppState = &uip_conn->appstate;\r
- char* AppData = (char*)uip_appdata;\r
+ char* const AppData = (char*)uip_appdata;\r
\r
/* Must determine the maximum segment size to determine maximum file chunk size */\r
uint16_t MaxSegmentSize = uip_mss();\r
\r
/* Must determine the maximum segment size to determine maximum file chunk size */\r
uint16_t MaxSegmentSize = uip_mss();\r
Lib/DataflashManager.c \\r
Lib/uip/uip.c \\r
Lib/uip/uip_arp.c \\r
Lib/DataflashManager.c \\r
Lib/uip/uip.c \\r
Lib/uip/uip_arp.c \\r
- Lib/uip/uiplib.c \\r
- Lib/uip/psock.c \\r
Lib/uip/timer.c \\r
Lib/uip/uip-neighbor.c \\r
Lib/uip/conf/clock-arch.c \\r
Lib/uip/timer.c \\r
Lib/uip/uip-neighbor.c \\r
Lib/uip/conf/clock-arch.c \\r