source: thomson/elec/CrO2/software/device_bekit.cpp@ 45825a3

main
Last change on this file since 45825a3 was 45825a3, checked in by Adrien Destugues <pulkomandy@…>, 11 years ago

Add some safety checks

git-svn-id: svn://localhost/thomson@31 85ae3b6b-dc8f-4344-a89d-598714f2e4e5

  • Property mode set to 100644
File size: 3.2 KB
Line 
1/* CrO2 datassette emulator
2 * Copyright 2013, Adrien Destugues <pulkomandy@pulkomandy.tk>
3 *
4 * Distributed under the terms of the MIT licence.
5 *
6 * Handles device communication through libusb
7 */
8
9#include "device_bekit.h"
10#include "k5.h"
11
12#include <typeinfo>
13#include <USBKit.h>
14
15class DeviceScanner: public BUSBRoster
16{
17 public:
18 DeviceScanner(uint32_t vid, uint32_t pid, const char* vendor, const char* product);
19 virtual ~DeviceScanner() {}
20
21 // BUSBRoster
22 virtual status_t DeviceAdded(BUSBDevice* device);
23 virtual void DeviceRemoved(BUSBDevice* device);
24
25 BUSBDevice* handle;
26 private:
27 uint32_t vid, pid;
28 const char* vendor, *product;
29};
30
31// Gets the device instance. Throws an error message if something bad happens.
32Device& Device::getDevice() throw(const char*)
33{
34 if (instance == NULL) {
35 DeviceScanner* scanner = new DeviceScanner(vid, pid, vendor, product);
36 scanner->Start();
37 // Can't be done in the cosntructor, we need a fully setup vtable
38
39 while(scanner->handle == NULL); // FIXME don't hog CPU, and timeout
40 //throw "Device not found. Is the USB cable plugged correctly?";
41
42 instance = new HaikuDevice(scanner->handle);
43
44 // We have our device, don't need the roster anymore.
45 //delete scanner;
46 }
47
48 return *instance;
49}
50
51
52HaikuDevice::HaikuDevice(BUSBDevice* handle) throw(const char*)
53{
54 this->handle = handle;
55}
56
57
58HaikuDevice::~HaikuDevice()
59{
60 delete handle;
61}
62
63
64int HaikuDevice::read(uint8_t* buffer, size_t max)
65{
66 return handle->ControlTransfer(USB_REQTYPE_VENDOR | USB_REQTYPE_ENDPOINT_IN,
67 PSCMD_GET, 0,0, max, (char*)buffer);
68
69}
70
71
72int HaikuDevice::write(const uint8_t* buffer, size_t size, int blktype)
73{
74 int rqtype = (size == 0) ? USB_REQTYPE_ENDPOINT_IN:USB_REQTYPE_ENDPOINT_OUT;
75 return handle->ControlTransfer(USB_REQTYPE_VENDOR | rqtype,
76 PSCMD_PUT, blktype,0 /*checksum*/, size, (char*)buffer);
77
78}
79
80
81uint8_t HaikuDevice::getStatus()
82{
83 uint8_t status;
84 handle->ControlTransfer(USB_REQTYPE_VENDOR | USB_REQTYPE_ENDPOINT_IN,
85 PSCMD_STATUS, 0,0, 1, (char*)&status);
86 // TODO handle errors (return value)
87 return status;
88}
89
90
91DeviceScanner::DeviceScanner(uint32_t vid, uint32_t pid, const char* vendor, const char* product)
92 : handle(NULL)
93 , vid(vid)
94 , pid(pid)
95 , vendor(vendor)
96 , product(product)
97{
98}
99
100
101status_t DeviceScanner::DeviceAdded(BUSBDevice* device)
102{
103 if (handle != NULL) {
104 // We already have a device !
105 return B_ERROR;
106 }
107
108 // Check if the device matches what we can handle
109
110 if (device->VendorID() != vid && device->ProductID() != pid)
111 return B_ERROR;
112
113 // Since we use V-USB shared vid/pid pair, we also have to check the
114 // manufacturer and product strings to actually identify the device amongst
115 // other users of the pair.
116 if (strcmp(device->ManufacturerString(), vendor) != 0)
117 return B_ERROR;
118
119 if (strcmp(device->ProductString(), product) != 0)
120 return B_ERROR;
121
122 // Ok, we have found our device !
123 handle = device;
124 return B_OK;
125}
126
127
128void DeviceScanner::DeviceRemoved(BUSBDevice* device)
129{
130 // This is only called for devices we accepted in DeviceAdded. We accept
131 // only one, so we can safely remove it.
132 handle = NULL;
133}
Note: See TracBrowser for help on using the repository browser.