From 4670b39070afd12483b2dd31e2ec6300ce73eb39 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Wed, 4 Nov 2009 07:14:38 +0000
Subject: [PATCH] Fixed HID report parser collection paths invalid due to
 misplaced semicolon in the free path item search loop. Increased the default
 number of collection paths allowable by the parser.

---
 LUFA/Drivers/USB/Class/Host/HIDParser.c | 42 ++++++-------------------
 LUFA/Drivers/USB/Class/Host/HIDParser.h |  2 +-
 LUFA/ManPages/ChangeLog.txt             |  1 +
 LUFA/ManPages/FutureChanges.txt         |  1 -
 4 files changed, 11 insertions(+), 35 deletions(-)

diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.c b/LUFA/Drivers/USB/Class/Host/HIDParser.c
index f3763081d..3090774ec 100644
--- a/LUFA/Drivers/USB/Class/Host/HIDParser.c
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.c
@@ -42,16 +42,12 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
 	uint16_t              UsageStack[HID_USAGE_STACK_DEPTH];
 	uint8_t               UsageStackSize          = 0;
 
-	ParserData->TotalReportItems   = 0;
-	ParserData->TotalDeviceReports = 1;
-	ParserData->UsingReportIDs     = false;
-	
-	for (uint8_t CurrCollection = 0; CurrCollection < HID_MAX_COLLECTIONS; CurrCollection++)
-	  ParserData->CollectionPaths[CurrCollection].Parent = NULL;
-
+	memset(ParserData,       0x00, sizeof(HID_ReportInfo_t));
 	memset(CurrStateTable,   0x00, sizeof(HID_StateTable_t));
 	memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
 
+	ParserData->TotalDeviceReports = 1;	
+
 	while (ReportSize)
 	{
 		uint8_t  HIDReportItem  = *ReportData;
@@ -177,7 +173,7 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
 			
 					CurrCollectionPath = &ParserData->CollectionPaths[1];
 
-					while (CurrCollectionPath->Parent != NULL);
+					while (CurrCollectionPath->Parent != NULL)
 					{
 						if (CurrCollectionPath == &ParserData->CollectionPaths[HID_MAX_COLLECTIONS - 1])
 						  return HID_PARSE_InsufficientCollectionPaths;
@@ -200,10 +196,6 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
 					  
 					UsageStackSize--;
 				}
-				else
-				{
-					CurrCollectionPath->Usage.Usage = 0;
-				}
 				
 				break;
 			case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION):
@@ -211,7 +203,6 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
 				  return HID_PARSE_UnexpectedEndCollection;
 		
 				CurrCollectionPath = CurrCollectionPath->Parent;
-
 				break;
 			case (TYPE_MAIN | TAG_MAIN_INPUT):
 			case (TYPE_MAIN | TAG_MAIN_OUTPUT):
@@ -237,39 +228,26 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
 						  
 						UsageStackSize--;
 					}
-					else
-					{
-						NewReportItem.Attributes.Usage.Usage = 0;
-					}
-
-					uint8_t ReportSizeIndex = 0;
 
 					switch (HIDReportItem & TAG_MASK)
 					{
 						case TAG_MAIN_INPUT:
 							NewReportItem.ItemType  = REPORT_ITEM_TYPE_In;
-							NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[REPORT_ITEM_TYPE_In];
-								
-							ReportSizeIndex = REPORT_ITEM_TYPE_In;
 							break;
 						case TAG_MAIN_OUTPUT:
 							NewReportItem.ItemType  = REPORT_ITEM_TYPE_Out;
-							NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[REPORT_ITEM_TYPE_Out];
-								
-							ReportSizeIndex = REPORT_ITEM_TYPE_Out;
 							break;
 						case TAG_MAIN_FEATURE:
 							NewReportItem.ItemType  = REPORT_ITEM_TYPE_Feature;						
-							NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[REPORT_ITEM_TYPE_Feature];
-								
-							ReportSizeIndex = REPORT_ITEM_TYPE_Feature;
 							break;
 					}
 					
-					CurrReportIDInfo->ReportSizeBits[ReportSizeIndex] += CurrStateTable->Attributes.BitSize;
+					NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType];
+
+					CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType] += CurrStateTable->Attributes.BitSize;
 
-					if (ParserData->LargestReportSizeBits < CurrReportIDInfo->ReportSizeBits[ReportSizeIndex])
-					  ParserData->LargestReportSizeBits = CurrReportIDInfo->ReportSizeBits[ReportSizeIndex];
+					if (ParserData->LargestReportSizeBits < NewReportItem.BitOffset)
+					  ParserData->LargestReportSizeBits = NewReportItem.BitOffset;
 					
 					if (!(ReportItemData & IOF_CONSTANT) && CALLBACK_HIDParser_FilterHIDReportItem(&NewReportItem))
 					{					
@@ -283,8 +261,6 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
 					}
 				}
 				
-				UsageStackSize = 0;
-				
 				break;
 		}
 	  
diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.h b/LUFA/Drivers/USB/Class/Host/HIDParser.h
index de98967a2..7a1563a3a 100644
--- a/LUFA/Drivers/USB/Class/Host/HIDParser.h
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.h
@@ -99,7 +99,7 @@
 			 *  overridden by defining HID_MAX_COLLECTIONS to another value in the user project makefile, passing
 			 *  the define to the compiler using the -D compiler switch.
 			 */
-			#define HID_MAX_COLLECTIONS           5
+			#define HID_MAX_COLLECTIONS           10
 		#endif
 		
 		#if !defined(HID_MAX_REPORTITEMS) || defined(__DOXYGEN__)
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 3e2ce86ee..38e6e8916 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -42,6 +42,7 @@
   *  - Fixed incorrect event name rule in demo/project/bootloader makefiles
   *  - Fixed HID device class driver not reselecting the correct endpoint once the user callback routines have been called
   *  - Corrected HID descriptor in the Joystick Device demos - buttons should be placed outside the pointer collection
+  *  - Fixed HID report parser collection paths invalid due to misplaced semicolon in the free path item search loop
   *
   *  \section Sec_ChangeLog090924 Version 090924
   *
diff --git a/LUFA/ManPages/FutureChanges.txt b/LUFA/ManPages/FutureChanges.txt
index 45e24aa90..1e2eaa731 100644
--- a/LUFA/ManPages/FutureChanges.txt
+++ b/LUFA/ManPages/FutureChanges.txt
@@ -27,7 +27,6 @@
   *  - Make new demos
   *      -# Keyboard/Mouse Dual Class Host
   *      -# Multiple-Report HID device
-  *      -# Joystick Host
   *  - Port LUFA to other architectures
   *      -# AVR32 UC3B series microcontrollers
   *      -# Atmel ARM7 series microcontrollers
-- 
GitLab