From 51910b450533fb7c335ee3d970d758fc25b05547 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Tue, 7 Apr 2009 11:46:54 +0000
Subject: [PATCH] Added support to the CDCHost demo for devices with mutiple
 CDC interfaces which are not the correct ACM type preceeding the desired ACM
 CDC interface.

---
 Demos/Host/CDCHost/ConfigDescriptor.c | 45 ++++++++++++++++++++++-----
 Demos/Host/CDCHost/ConfigDescriptor.h |  3 +-
 LUFA/ChangeLog.txt                    |  2 ++
 3 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/Demos/Host/CDCHost/ConfigDescriptor.c b/Demos/Host/CDCHost/ConfigDescriptor.c
index eb80ec3ea..3b919bd9b 100644
--- a/Demos/Host/CDCHost/ConfigDescriptor.c
+++ b/Demos/Host/CDCHost/ConfigDescriptor.c
@@ -69,8 +69,8 @@ uint8_t ProcessConfigurationDescriptor(void)
 	if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
 	  return InvalidConfigDataReturned;
 	
-	/* Get the CDC interface from the configuration descriptor */
-	if (USB_Host_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, NextCDCInterface))
+	/* Get the CDC control interface from the configuration descriptor */
+	if (USB_Host_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, NextCDCControlInterface))
 	{
 		/* Descriptor not found, error out */
 		return NoCDCInterfaceFound;
@@ -83,11 +83,24 @@ uint8_t ProcessConfigurationDescriptor(void)
 		if (USB_Host_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
 		                                   NextInterfaceCDCDataEndpoint))
 		{
-			/* Get the next CDC interface from the configuration descriptor (CDC class has two CDC interfaces) */
-			if (USB_Host_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, NextCDCInterface))
+			/* Check to see if the control interface's notification pipe has been found, if so search for the data interface */
+			if (FoundEndpoints & (1 << CDC_NOTIFICATIONPIPE))
 			{
-				/* Descriptor not found, error out */
-				return NoCDCInterfaceFound;
+				/* Get the next CDC data interface from the configuration descriptor (CDC class has two CDC interfaces) */
+				if (USB_Host_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, NextCDCDataInterface))
+				{
+					/* Descriptor not found, error out */
+					return NoCDCInterfaceFound;
+				}
+			}
+			else
+			{
+				/* Get the next CDC control interface from the configuration descriptor (CDC class has two CDC interfaces) */
+				if (USB_Host_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, NextCDCControlInterface))
+				{
+					/* Descriptor not found, error out */
+					return NoCDCInterfaceFound;
+				}
 			}
 
 			/* Fetch the next bulk or interrupt endpoint from the current CDC interface */
@@ -155,11 +168,11 @@ uint8_t ProcessConfigurationDescriptor(void)
  *  configuration descriptor, to search for a specific sub descriptor. It can also be used to abort the configuration
  *  descriptor processing if an incompatible descriptor configuration is found.
  *
- *  This comparator searches for the next Interface descriptor of the correct CDC Class, Subclass and Protocol values.
+ *  This comparator searches for the next Interface descriptor of the correct CDC control Class, Subclass and Protocol values.
  *
  *  \return A value from the DSEARCH_Return_ErrorCodes_t enum
  */
-DESCRIPTOR_COMPARATOR(NextCDCInterface)
+DESCRIPTOR_COMPARATOR(NextCDCControlInterface)
 {
 	if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
 	{
@@ -170,7 +183,23 @@ DESCRIPTOR_COMPARATOR(NextCDCInterface)
 		{
 			return Descriptor_Search_Found;
 		}
+	}
+	
+	return Descriptor_Search_NotFound;
+}
 
+/** Descriptor comparator function. This comparator function is can be called while processing an attached USB device's
+ *  configuration descriptor, to search for a specific sub descriptor. It can also be used to abort the configuration
+ *  descriptor processing if an incompatible descriptor configuration is found.
+ *
+ *  This comparator searches for the next Interface descriptor of the correct CDC data Class, Subclass and Protocol values.
+ *
+ *  \return A value from the DSEARCH_Return_ErrorCodes_t enum
+ */
+DESCRIPTOR_COMPARATOR(NextCDCDataInterface)
+{
+	if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
+	{
 		/* Check the CDC descriptor class, subclass and protocol, break out if correct data interface found */
 		if ((DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Class    == CDC_DATA_CLASS)    &&
 		    (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).SubClass == CDC_DATA_SUBCLASS) &&
diff --git a/Demos/Host/CDCHost/ConfigDescriptor.h b/Demos/Host/CDCHost/ConfigDescriptor.h
index 0ba614824..9db4b6505 100644
--- a/Demos/Host/CDCHost/ConfigDescriptor.h
+++ b/Demos/Host/CDCHost/ConfigDescriptor.h
@@ -77,7 +77,8 @@
 		};
 
 	/* Configuration Descriptor Comparison Functions: */
-		DESCRIPTOR_COMPARATOR(NextCDCInterface);
+		DESCRIPTOR_COMPARATOR(NextCDCControlInterface);
+		DESCRIPTOR_COMPARATOR(NextCDCDataInterface);
 		DESCRIPTOR_COMPARATOR(NextInterfaceCDCDataEndpoint);
 
 	/* Function Prototypes: */
diff --git a/LUFA/ChangeLog.txt b/LUFA/ChangeLog.txt
index 0b15df0b2..04b0e9757 100644
--- a/LUFA/ChangeLog.txt
+++ b/LUFA/ChangeLog.txt
@@ -24,6 +24,8 @@
   *    code without having to be itself patched and recompiled first
   *  - Added preprocessor checks and documentation to the bootloaders giving information about missing SIGNATURE_x defines due to
   *    outdated avr-libc versions.
+  *  - Added support to the CDCHost demo for devices with mutiple CDC interfaces which are not the correct ACM type preceeding the desired
+  *    ACM CDC interface
   *
   *  \section Sec_ChangeLog090401 Version 090401
   *
-- 
GitLab