1 /* 2 * Copyright 2005-2008 Stephan Aßmus <superstippi@gmx.de>. All rights reserved. 3 * Distributed under the terms of the MIT license. 4 */ 5 #include "DeviceReader.h" 6 7 #include <malloc.h> 8 #include <string.h> 9 10 #include <File.h> 11 12 #include "MasterServerDevice.h" 13 14 15 static ssize_t kHeaderSize = 8; 16 17 18 // constructor 19 DeviceReader::DeviceReader() 20 : fDevicePath(NULL), 21 fDeviceFile(NULL), 22 fVendorID(0), 23 fProductID(0), 24 fMaxPackedSize(0) 25 { 26 } 27 28 // destructor 29 DeviceReader::~DeviceReader() 30 { 31 _Unset(); 32 } 33 34 // SetTo 35 status_t 36 DeviceReader::SetTo(const char* path) 37 { 38 status_t ret = B_BAD_VALUE; 39 if (path) { 40 _Unset(); 41 fDevicePath = strdup(path); 42 fDeviceFile = new BFile(path, B_READ_ONLY); 43 ret = fDeviceFile->InitCheck(); 44 if (ret >= B_OK) { 45 // read 8 bytes from the file and initialize 46 // the rest of the object variables 47 uint8 buffer[kHeaderSize]; 48 ret = fDeviceFile->Read(buffer, kHeaderSize); 49 if (ret == kHeaderSize) { 50 ret = B_OK; 51 uint16* ids = (uint16*)buffer; 52 fVendorID = ids[0]; 53 fProductID = ids[1]; 54 uint32* ps = (uint32*)buffer; 55 fMaxPackedSize = ps[1]; 56 } else { 57 _Unset(); 58 } 59 } 60 } 61 return ret; 62 } 63 64 // InitCheck 65 status_t 66 DeviceReader::InitCheck() const 67 { 68 return fDeviceFile && fDevicePath ? fDeviceFile->InitCheck() : B_NO_INIT; 69 } 70 71 // DevicePath 72 const char* 73 DeviceReader::DevicePath() const 74 { 75 return fDevicePath; 76 } 77 78 // DeviceFile 79 BFile* 80 DeviceReader::DeviceFile() const 81 { 82 return fDeviceFile; 83 } 84 85 // VendorID 86 uint16 87 DeviceReader::VendorID() const 88 { 89 return fVendorID; 90 } 91 92 // ProductID 93 uint16 94 DeviceReader::ProductID() const 95 { 96 return fProductID; 97 } 98 99 // MaxPacketSize 100 size_t 101 DeviceReader::MaxPacketSize() const 102 { 103 return fMaxPackedSize; 104 } 105 106 // ReadData 107 ssize_t 108 DeviceReader::ReadData(uint8* data, const size_t size) const 109 { 110 if (!fDeviceFile || fMaxPackedSize <= 0 || fMaxPackedSize > 128) 111 return B_NO_INIT; 112 status_t ret = fDeviceFile->InitCheck(); 113 if (ret < B_OK) 114 return (ssize_t)ret; 115 116 ssize_t requested = fMaxPackedSize + kHeaderSize; 117 uint8 buffer[requested]; 118 ssize_t read = fDeviceFile->Read(buffer, requested); 119 if (read > kHeaderSize) { 120 // make sure we don't copy too many bytes 121 size_t bytesToCopy = min_c(size, read - (size_t)kHeaderSize); 122 PRINT(("requested: %ld, read: %ld, user wants: %lu, copy bytes: %ld\n", 123 requested, read, size, bytesToCopy)); 124 memcpy(data, buffer + kHeaderSize, bytesToCopy); 125 // zero out any remaining bytes 126 if (size > bytesToCopy) 127 memset(data + bytesToCopy, 0, size - bytesToCopy); 128 // operation could be considered successful 129 // read = bytesToCopy; 130 // if (read != (ssize_t)size) 131 // PRINT(("user wanted: %lu, returning: %ld\n", size, read)); 132 read = size; 133 // pretend we could read as many bytes as requested 134 } else if (read == kHeaderSize || (status_t)read == B_TIMED_OUT) { 135 // it's ok if the operation timed out 136 memset(data, 0, size); 137 read = (size_t)B_OK; 138 } else { 139 PRINT(("requested: %ld, read: %ld, user wants: %lu\n", 140 requested, read, size)); 141 } 142 143 return read; 144 } 145 146 // _Unset 147 void 148 DeviceReader::_Unset() 149 { 150 free(fDevicePath); 151 fDevicePath = NULL; 152 delete fDeviceFile; 153 fDeviceFile = NULL; 154 fVendorID = 0; 155 fProductID = 0; 156 fMaxPackedSize = 0; 157 } 158