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 15static ssize_t kHeaderSize = 8; 16 17 18// constructor 19DeviceReader::DeviceReader() 20 : fDevicePath(NULL), 21 fDeviceFile(NULL), 22 fVendorID(0), 23 fProductID(0), 24 fMaxPackedSize(0) 25{ 26} 27 28// destructor 29DeviceReader::~DeviceReader() 30{ 31 _Unset(); 32} 33 34// SetTo 35status_t 36DeviceReader::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 65status_t 66DeviceReader::InitCheck() const 67{ 68 return fDeviceFile && fDevicePath ? fDeviceFile->InitCheck() : B_NO_INIT; 69} 70 71// DevicePath 72const char* 73DeviceReader::DevicePath() const 74{ 75 return fDevicePath; 76} 77 78// DeviceFile 79BFile* 80DeviceReader::DeviceFile() const 81{ 82 return fDeviceFile; 83} 84 85// VendorID 86uint16 87DeviceReader::VendorID() const 88{ 89 return fVendorID; 90} 91 92// ProductID 93uint16 94DeviceReader::ProductID() const 95{ 96 return fProductID; 97} 98 99// MaxPacketSize 100size_t 101DeviceReader::MaxPacketSize() const 102{ 103 return fMaxPackedSize; 104} 105 106// ReadData 107ssize_t 108DeviceReader::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); 122PRINT(("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 147void 148DeviceReader::_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