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: HIDGetData.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 (BWS) Brent Schorsch 44 45 Change History (most recent first): 46 47 <USB3> 12/12/00 KH Correct cast of void * 48 <USB2> 3/5/99 BWS [2311353] HIDGetData not masking properly, so not work at all 49 <USB1> 3/5/99 BWS first checked in 50*/ 51 52#include "HIDLib.h" 53 54/* 55 *------------------------------------------------------------------------------ 56 * 57 * HIDGetData - Get a single data item from a report 58 * 59 * Input: 60 * psReport - The report 61 * iReportLength - The length of the report 62 * iStart - Start Bit in report 63 * iSize - Number of Bits 64 * piValue - The place to write the data 65 * bSignExtend - Sign extend? 66 * Output: 67 * piValue - The data 68 * Returns: 69 * kHidP_Success - Success 70 * kHidP_NullPointer - Argument, Pointer was Null 71 * 72 *------------------------------------------------------------------------------ 73*/ 74OSStatus HIDGetData(void * report, IOByteCount iReportLength, 75 UInt32 iStart, UInt32 iSize, SInt32 *piValue, 76 Boolean bSignExtend) 77{ 78 UInt8 * psReport = (UInt8 *)report; 79 unsigned data; 80 unsigned iSignBit; 81 unsigned iExtendMask; 82 unsigned iStartByte = iStart/8; 83 unsigned startBit = iStart&7; 84 unsigned iLastBit = iStart + iSize - 1; 85 unsigned iLastByte = iLastBit/8; 86 int iCurrentByte; // needs to be signed, we terminate loop on -1 87 unsigned iMask; 88 89 // Check the parameters 90 if ((iSize == 0) || (iLastByte >= iReportLength) || (iLastByte < iStartByte)) 91 return kHIDBadParameterErr; 92 93 // Pick up the data bytes backwards 94 data = 0; 95 for (iCurrentByte = iLastByte; iCurrentByte >= (int) iStartByte; iCurrentByte--) 96 { 97 data <<= 8; 98 99 iMask = 0xff; // 1111 1111 initial mask 100 // if this is the 'last byte', then we need to mask off the top part of the byte 101 // to find the mask, we: find the position in this byte (lastBit % 8) 102 // then shift one to the left that many times plus one (to get one bit further) 103 // then subtract 1 to get all ones starting from the lastBit to the least signif bit 104 // ex: if iLastBit is 9, or iLastBit is 15, then we get: 105 // 1 7 (x % 8) 106 // 0000 0100 1 0000 0000 (1 << (x + 1)) 107 // 0000 0011 0 1111 1111 (x - 1) 108 if (iCurrentByte == iLastByte) 109 iMask = ((1 << (((unsigned) iLastBit % 8) + 1)) - 1); 110 111 data |= (unsigned) psReport[iCurrentByte] & iMask; 112 } 113 114 // Shift to the right to byte align the least significant bit 115 data >>= startBit; 116 117 // Sign extend the report item 118 if (bSignExtend) 119 { 120 iSignBit = 1; 121 if (iSize > 1) 122 iSignBit <<= (iSize-1); 123 iExtendMask = (iSignBit << 1) - 1; 124 if ((data & iSignBit)==0) 125 data &= iExtendMask; 126 else 127 data |= ~iExtendMask; 128 } 129 130 // Return the value 131 *piValue = (SInt32) data; 132 133 return kHIDSuccess; 134} 135