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: HIDGetUsageValueArray.c 25 26 Contains: xxx put contents here xxx 27 28 Version: xxx put version here xxx 29 30 Copyright: � 1999-2001 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 (BWS) Brent Schorsch 44 45 Change History (most recent first): 46 47 <USB5> 1/18/01 KH Fix for complex descriptors only needed for buttons. 48 <USB4> 3/24/00 KH Complex report descriptors could lead to reporting 49 kHIDUsageNotFoundErr's as kHIDIncompatibleReportErr's instead. 50 <USB3> 11/1/99 BWS [2405720] We need a better check for 'bit padding' items, 51 rather than just is constant. We will check to make sure the 52 item is constant, and has no usage, or zero usage. This means we 53 need to pass an additional parameter to some internal functions 54 <USB2> 4/7/99 BWS Add support for reversed report items 55 <USB1> 3/5/99 BWS first checked in 56*/ 57 58#include "HIDLib.h" 59 60/* 61 *------------------------------------------------------------------------------ 62 * 63 * HIDP_GetUsageValueArray - Get the values for a usage 64 * 65 * Input: 66 * reportType - HIDP_Input, HIDP_Output, HIDP_Feature 67 * usagePage - Page Criteria 68 * iCollection - Collection Criteria or zero 69 * usage - usage Criteria 70 * psBuffer - Pointer to usage Buffer 71 * iByteLength - Length of usage Buffer 72 * ptPreparsedData - Pre-Parsed Data 73 * psReport - An HID Report 74 * iReportLength - The length of the Report 75 * Output: 76 * piValue - Pointer to usage Value 77 * Returns: 78 * 79 *------------------------------------------------------------------------------ 80*/ 81OSStatus HIDGetUsageValueArray(HIDReportType reportType, 82 HIDUsage usagePage, 83 UInt32 iCollection, 84 HIDUsage usage, 85 UInt8 *psUsageBuffer, 86 IOByteCount iByteLength, 87 HIDPreparsedDataRef preparsedDataRef, 88 void *psReport, 89 IOByteCount iReportLength) 90{ 91 HIDPreparsedDataPtr ptPreparsedData = (HIDPreparsedDataPtr) preparsedDataRef; 92 HIDCollection *ptCollection; 93 HIDReportItem *ptReportItem; 94 OSStatus iStatus; 95 int i; 96 int iR; 97 SInt32 iValue; 98 int iStart; 99 int iReportItem; 100 UInt32 iUsageIndex; 101 UInt32 iCount; 102 int byteCount; 103 Boolean bIncompatibleReport = false; 104/* 105 * Disallow Null Pointers 106*/ 107 if ((ptPreparsedData == NULL) 108 || (psUsageBuffer == NULL) 109 || (psReport == NULL)) 110 return kHIDNullPointerErr; 111 if (ptPreparsedData->hidTypeIfValid != kHIDOSType) 112 return kHIDInvalidPreparsedDataErr; 113/* 114 * The Collection must be in range 115*/ 116 if (iCollection >= ptPreparsedData->collectionCount) 117 return kHIDBadParameterErr; 118/* 119 * Search only the scope of the Collection specified 120 * Go through the ReportItems 121 * Filter on ReportType and usagePage 122*/ 123 ptCollection = &ptPreparsedData->collections[iCollection]; 124 for (iR=0; iR<ptCollection->reportItemCount; iR++) 125 { 126 iReportItem = ptCollection->firstReportItem + iR; 127 ptReportItem = &ptPreparsedData->reportItems[iReportItem]; 128 if (HIDIsVariable(ptReportItem, preparsedDataRef) 129 && HIDHasUsage(preparsedDataRef,ptReportItem,usagePage,usage,&iUsageIndex,&iCount)) 130 { 131/* 132 * This may be the proper data to get 133 * Let's check for the proper Report ID, Type, and Length 134*/ 135 iStatus = HIDCheckReport(reportType,preparsedDataRef,ptReportItem, 136 psReport,iReportLength); 137/* 138 * The Report ID or Type may not match. 139 * This may not be an error (yet) 140*/ 141 if (iStatus == kHIDIncompatibleReportErr) 142 bIncompatibleReport = true; 143 else if (iStatus != kHIDSuccess) 144 return iStatus; 145 else 146 { 147/* 148 * Disallow single count variables 149 * Count is set by HasUsage 150*/ 151 if (iCount <= 1) 152 return kHIDNotValueArrayErr; 153/* 154 * Get the data 155*/ 156 iStart = ptReportItem->startBit + (ptReportItem->globals.reportSize * iUsageIndex); 157 byteCount = (ptReportItem->globals.reportSize * iCount + 7)/8; 158 if (byteCount > iByteLength) 159 byteCount = iByteLength; 160 for (i=0; i<byteCount; i++) 161 { 162 iStatus = HIDGetData(psReport, iReportLength, iStart, 8, &iValue, 163 ((ptReportItem->globals.logicalMinimum < 0) 164 ||(ptReportItem->globals.logicalMaximum < 0))); 165 if (!iStatus) 166 iStatus = HIDPostProcessRIValue (ptReportItem, &iValue); 167 if (iStatus != kHIDSuccess) 168 return iStatus; 169 *psUsageBuffer++ = (char) iValue; 170 iStart += 8; 171 } 172 return kHIDSuccess; 173 } 174 } 175 } 176 if (bIncompatibleReport) 177 return kHIDIncompatibleReportErr; 178 return kHIDUsageNotFoundErr; 179} 180