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