1/* 2 * @APPLE_LICENSE_HEADER_START@ 3 * 4 * Copyright (c) 1999-2012 Apple Computer, Inc. All Rights Reserved. 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 File: HIDProcessReportItem.c 25 26 Contains: xxx put contents here xxx 27 28 Version: xxx put version here xxx 29 30 Copyright: � 1999-2000 by Apple Computer, Inc., all rights reserved. 31 32 File Ownership: 33 34 DRI: xxx put dri here xxx 35 36 Other Contact: xxx put other contact here xxx 37 38 Technology: xxx put technology here xxx 39 40 Writers: 41 42 (KH) Keithen Hayenga 43 (DF) David Ferguson 44 (BWS) Brent Schorsch 45 46 Change History (most recent first): 47 48 <USB10> 1/11/00 KH Tweaking last fix. For logical maximum, limit shifting into the 49 sign bit only for report sizes of 32 bits or greater. 50 <USB9> 1/10/00 DF re-do last change (better fix). 51 <USB8> 1/10/00 DF do proper logical range test for 32-bit report items. 52 <USB7> 4/7/99 BWS Add support for reversed report items 53 <USB6> 3/20/99 BWS Oops, strict error checking does not work if there is no error. 54 We should only return error if it is not 0 55 <USB5> 3/17/99 BWS [2314839] Added flags field to HIDPreparsedData which is set in 56 new parameter to HIDOpenReportDescriptor. We check the 57 StrictErrorCheck bit to determine whether we return errors or 58 just try to work around problems we find 59 <USB4> 3/7/99 BWS [2311413] Do not error check min/max ranges for constants 60 <USB3> 3/7/99 BWS [2311412] We need to handle the cases where physical min/max is 61 either (0/0) which is valid according to the spec, and means to 62 use the logical min/max, and the invalid case, that some devices 63 exibit, which has (0/-1) which we will treat the same, 64 <USB2> 3/5/99 BWS [2311359] HIDProcessReportItem does not initialize startBit 65 field of HIDReportItem! 66 <USB1> 3/5/99 BWS first checked in 67*/ 68 69#include "HIDLib.h" 70 71/* 72 *------------------------------------------------------------------------------ 73 * 74 * HIDProcessReportItem - Process a Report Item MainItem 75 * 76 * Input: 77 * ptDescriptor - The Descriptor Structure 78 * ptPreparsedData - The PreParsedData Structure 79 * Output: 80 * ptDescriptor - The Descriptor Structure 81 * ptPreparsedData - The PreParsedData Structure 82 * Returns: 83 * kHIDSuccess - Success 84 * kHIDNullPointerErr - Argument, Pointer was Null 85 * 86 *------------------------------------------------------------------------------ 87*/ 88OSStatus HIDProcessReportItem(HIDReportDescriptor *ptDescriptor, HIDPreparsedDataPtr ptPreparsedData) 89{ 90 OSStatus error = 0; 91 HIDReportItem *ptReportItem; 92 HIDReportSizes *ptReport; 93 int iBits; 94/* 95 * Disallow NULL Pointers 96*/ 97 98 if ((ptDescriptor == NULL) || (ptPreparsedData == NULL)) 99 return kHIDNullPointerErr; 100/* 101 * Begin to initialize the new Report Item structure 102*/ 103 104 ptReportItem = &ptPreparsedData->reportItems[ptPreparsedData->reportItemCount++]; 105 ptReportItem->dataModes = ptDescriptor->item.unsignedValue; 106 ptReportItem->globals = ptDescriptor->globals; 107 ptReportItem->flags = 0; 108 109/* 110 * Reality Check on the Report Main Item 111*/ 112 // Don't check ranges for constants (MS Sidewinder, for one, does not reset) 113 //if (!(ptReportItem->dataModes & kHIDDataConstantBit)) // don't think we need this anymore 114 { 115 // Determine the maximum signed value for a given report size. 116 // (Don't allow shifting into sign bit.) 117 SInt32 posSize = (ptReportItem->globals.reportSize >= 32) ? 118 31 : ptReportItem->globals.reportSize; 119 SInt32 realMax = (1<<posSize) - 1; 120 121 if (ptReportItem->globals.logicalMinimum > realMax) 122 { 123 error = kHIDBadLogicalMinimumErr; 124 ptReportItem->globals.logicalMinimum = 0; 125 } 126 if (ptReportItem->globals.logicalMaximum > realMax) 127 { 128 if (!error) 129 error = kHIDBadLogicalMaximumErr; 130 ptReportItem->globals.logicalMaximum = realMax; 131 } 132 if (ptReportItem->globals.logicalMinimum > ptReportItem->globals.logicalMaximum) 133 { 134 SInt32 temp; 135 if (!error) 136 error = kHIDInvertedLogicalRangeErr; 137 138 // mark as a 'reversed' item 139 ptReportItem->flags |= kHIDReportItemFlag_Reversed; 140 141 temp = ptReportItem->globals.logicalMaximum; 142 ptReportItem->globals.logicalMaximum = ptReportItem->globals.logicalMinimum; 143 ptReportItem->globals.logicalMinimum = temp; 144 } 145 } 146 147 // check to see if we got half a range (we don't need to fix this, since 'isRange' will be false 148 if ((!error) && (ptDescriptor->haveUsageMin || ptDescriptor->haveUsageMax)) 149 error = kHIDUnmatchedUsageRangeErr; 150 if ((!error) && (ptDescriptor->haveStringMin || ptDescriptor->haveStringMax)) 151 error = kHIDUnmatchedStringRangeErr; 152 if ((!error) && (ptDescriptor->haveDesigMin || ptDescriptor->haveDesigMax)) 153 error = kHIDUnmatchedDesignatorRangeErr; 154 155 // if the physical min/max are out of wack, use the logical values 156 if (ptReportItem->globals.physicalMinimum >= ptReportItem->globals.physicalMaximum) 157 { 158 // equal to each other is not an error, just means to use the logical values 159 if ((!error) && 160 (ptReportItem->globals.physicalMinimum > ptReportItem->globals.physicalMaximum)) 161 error = kHIDInvertedPhysicalRangeErr; 162 163 ptReportItem->globals.physicalMinimum = ptReportItem->globals.logicalMinimum; 164 ptReportItem->globals.physicalMaximum = ptReportItem->globals.logicalMaximum; 165 } 166 167 // if strict error checking is true, return any errors 168 if (error && ptPreparsedData->flags & kHIDFlag_StrictErrorChecking) 169 return error; 170 171/* 172 * Continue to initialize the new Report Item structure 173*/ 174 175 ptReportItem->parent = ptDescriptor->parent; 176 ptReportItem->firstUsageItem = ptDescriptor->firstUsageItem; 177 ptDescriptor->firstUsageItem = ptPreparsedData->usageItemCount; 178 ptReportItem->usageItemCount = ptPreparsedData->usageItemCount - ptReportItem->firstUsageItem; 179 ptReportItem->firstStringItem = ptDescriptor->firstStringItem; 180 ptDescriptor->firstStringItem = ptPreparsedData->stringItemCount; 181 ptReportItem->stringItemCount = ptPreparsedData->stringItemCount - ptReportItem->firstStringItem; 182 ptReportItem->firstDesigItem = ptDescriptor->firstDesigItem; 183 ptDescriptor->firstDesigItem = ptPreparsedData->desigItemCount; 184 ptReportItem->desigItemCount = ptPreparsedData->desigItemCount - ptReportItem->firstDesigItem; 185/* 186 * Update the Report by the size of this item 187*/ 188 189 ptReport = &ptPreparsedData->reports[ptReportItem->globals.reportIndex]; 190 iBits = ptReportItem->globals.reportSize * ptReportItem->globals.reportCount; 191 switch (ptDescriptor->item.tag) 192 { 193 case kHIDTagFeature: 194 ptReportItem->reportType = kHIDFeatureReport; 195 ptReportItem->startBit = ptReport->featureBitCount; 196 ptReport->featureBitCount += iBits; 197 break; 198 case kHIDTagOutput: 199 ptReportItem->reportType = kHIDOutputReport; 200 ptReportItem->startBit = ptReport->outputBitCount; 201 ptReport->outputBitCount += iBits; 202 break; 203 case kHIDTagInput: 204 ptReportItem->reportType = kHIDInputReport; 205 ptReportItem->startBit = ptReport->inputBitCount; 206 ptReport->inputBitCount += iBits; 207 break; 208 default: 209 ptReportItem->reportType = kHIDUnknownReport; 210 ptReportItem->startBit = 0; 211 break; 212 } 213 return kHIDSuccess; 214} 215