The original (sample code version) USB Kit from Be, as from ftp.be.com/samples/usb_kit/usbkit_99-03-23.tgz
Some files renamed. Won't build yet with our usb_raw driver due to different namings. classes need to be B-prefixed anyway. USBKit.h needs to be split like in zeta as well. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19901 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,211 @@
|
|||||||
|
|
||||||
|
// USBKit.h
|
||||||
|
//
|
||||||
|
// Copyright 1999, Be Incorporated.
|
||||||
|
//
|
||||||
|
// Prototype USB Kit / Prerelease Sample Code
|
||||||
|
// Contents may change massively before official release.
|
||||||
|
|
||||||
|
#ifndef _USBKIT_H
|
||||||
|
#define _USBKIT_H
|
||||||
|
|
||||||
|
// Provides definitions for usb_xxx_descriptor structures.
|
||||||
|
#include <USB.h>
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
|
class USBDevice;
|
||||||
|
class USBEndpoint;
|
||||||
|
class USBInterface;
|
||||||
|
class USBConfiguration;
|
||||||
|
class USBRosterLooper;
|
||||||
|
|
||||||
|
class USBEndpoint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Connectivity functions (this endpoint belongs to an Interface that
|
||||||
|
// belongs to a Configuration that belongs to a Device)
|
||||||
|
const USBInterface *Interface(void) const;
|
||||||
|
const USBConfiguration *Configuration(void) const;
|
||||||
|
const USBDevice *Device(void) const;
|
||||||
|
|
||||||
|
// Raw descriptor data
|
||||||
|
const usb_endpoint_descriptor *Descriptor(void) const;
|
||||||
|
|
||||||
|
// Descriptor Accessor Functions
|
||||||
|
bool IsBulk(void) const;
|
||||||
|
bool IsInterrupt(void) const;
|
||||||
|
bool IsIsochronous(void) const;
|
||||||
|
bool IsInput(void) const;
|
||||||
|
bool IsOutput(void) const;
|
||||||
|
uint16 MaxPacketSize(void) const;
|
||||||
|
uint8 Interval(void) const;
|
||||||
|
|
||||||
|
// Initiate a USB Transaction
|
||||||
|
status_t InterruptTransfer(void *data, size_t length) const;
|
||||||
|
status_t BulkTransfer(void *data, size_t length) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend USBDevice; // Only created by a USBDevice
|
||||||
|
friend USBInterface; // Only destroyed by a containing USBInterface
|
||||||
|
USBEndpoint(uint32 n, USBInterface *ifc);
|
||||||
|
~USBEndpoint();
|
||||||
|
|
||||||
|
USBInterface *interface;
|
||||||
|
usb_endpoint_descriptor descriptor;
|
||||||
|
uint32 endpoint_num;
|
||||||
|
};
|
||||||
|
|
||||||
|
class USBInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Connectivity functions (this Interface belongs to a Configuration which
|
||||||
|
// belongs to a Device)
|
||||||
|
const USBConfiguration *Configuration(void) const;
|
||||||
|
const USBDevice *Device(void) const;
|
||||||
|
|
||||||
|
// Iterate over the Endpoints defined by this Interface
|
||||||
|
uint32 CountEndpoints(void) const;
|
||||||
|
const USBEndpoint *EndpointAt(uint32 n) const;
|
||||||
|
|
||||||
|
// Access the raw descriptor
|
||||||
|
const usb_interface_descriptor *Descriptor(void) const;
|
||||||
|
|
||||||
|
// Accessors for useful bits in the descriptor
|
||||||
|
uint8 Class(void) const;
|
||||||
|
uint8 Subclass(void) const;
|
||||||
|
uint8 Protocol(void) const;
|
||||||
|
const char *InterfaceString(void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend USBDevice; // only created by USBDevice
|
||||||
|
friend USBConfiguration; // only destroyed by the containing Configuration
|
||||||
|
USBInterface(uint32 n, USBConfiguration *cfc);
|
||||||
|
~USBInterface();
|
||||||
|
|
||||||
|
USBConfiguration *configuration;
|
||||||
|
usb_interface_descriptor descriptor;
|
||||||
|
uint32 interface_num;
|
||||||
|
BList endpoints;
|
||||||
|
};
|
||||||
|
|
||||||
|
class USBConfiguration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Connectivity functions (this Configuration belongs to a Device)
|
||||||
|
const USBDevice *Device(void) const;
|
||||||
|
|
||||||
|
// Iterators for the Interfaces provided by this Configuration
|
||||||
|
uint32 CountInterfaces(void) const;
|
||||||
|
const USBInterface *InterfaceAt(uint32 n) const;
|
||||||
|
|
||||||
|
// Access the raw descriptor
|
||||||
|
const usb_configuration_descriptor *Descriptor(void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend USBDevice;
|
||||||
|
USBConfiguration(uint n, USBDevice *dev);
|
||||||
|
~USBConfiguration();
|
||||||
|
|
||||||
|
USBDevice *device;
|
||||||
|
uint configuration_num;
|
||||||
|
usb_configuration_descriptor descriptor;
|
||||||
|
BList interfaces;
|
||||||
|
};
|
||||||
|
|
||||||
|
class USBDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
USBDevice(const char *path = NULL);
|
||||||
|
virtual ~USBDevice();
|
||||||
|
virtual status_t InitCheck(void);
|
||||||
|
status_t SetTo(const char *path);
|
||||||
|
|
||||||
|
// Bus Topology information methods:
|
||||||
|
|
||||||
|
// Return the logical path (eg 0/0/1 of the device), or NULL if unconfigured
|
||||||
|
const char *Location(void) const;
|
||||||
|
// Return true if this device is a usb hub
|
||||||
|
bool IsHub(void) const;
|
||||||
|
|
||||||
|
// Accessors for useful bits in the descriptor
|
||||||
|
uint16 USBVersion(void) const;
|
||||||
|
uint8 Class(void) const;
|
||||||
|
uint8 Subclass(void) const;
|
||||||
|
uint8 Protocol(void) const;
|
||||||
|
uint8 MaxEndpoint0PacketSize(void) const;
|
||||||
|
uint16 VendorID(void) const;
|
||||||
|
uint16 ProductID(void) const;
|
||||||
|
uint16 Version(void) const;
|
||||||
|
const char *ManufacturerString(void) const;
|
||||||
|
const char *ProductString(void) const;
|
||||||
|
const char *SerialNumberString(void) const;
|
||||||
|
|
||||||
|
// Access the raw descriptor
|
||||||
|
const usb_device_descriptor *Descriptor(void) const;
|
||||||
|
|
||||||
|
// Read a string descriptor from the Device into a buffer
|
||||||
|
size_t GetStringDescriptor(uint32 n, usb_string_descriptor *desc, size_t length) const;
|
||||||
|
|
||||||
|
// Read a string descriptor, convert it from Unicode to UTF8, return a new char[]
|
||||||
|
// containing the string (must be delete'd by the caller)
|
||||||
|
char *DecodeStringDescriptor(uint32 n) const;
|
||||||
|
|
||||||
|
// Iterate over the possible configurations
|
||||||
|
uint32 CountConfigurations(void) const;
|
||||||
|
const USBConfiguration *ConfigurationAt(uint32 n) const;
|
||||||
|
|
||||||
|
// View and select the active configuration
|
||||||
|
const USBConfiguration *ActiveConfiguration(void) const;
|
||||||
|
status_t SetConfiguration(const USBConfiguration *conf);
|
||||||
|
|
||||||
|
// Initiate a Control (endpoint 0) transaction
|
||||||
|
status_t ControlTransfer(uint8 request_type, uint8 request, uint16 value,
|
||||||
|
uint16 index, uint16 length, void *data) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t InterruptTransfer(const USBEndpoint *e, void *data, size_t length) const;
|
||||||
|
status_t BulkTransfer(const USBEndpoint *e, void *data, size_t length) const;
|
||||||
|
|
||||||
|
void Release(void);
|
||||||
|
void PopulateInterface(USBInterface *ifc, usb_interface_descriptor *descr);
|
||||||
|
void PopulateConfig(USBConfiguration *conf, usb_configuration_descriptor *descr);
|
||||||
|
void PopulateDevice(void);
|
||||||
|
|
||||||
|
mutable char *serial_string; // Cache the string descriptors
|
||||||
|
mutable char *manufacturer_string;
|
||||||
|
mutable char *product_string;
|
||||||
|
char *location; // Bus Topology info
|
||||||
|
bool ishub;
|
||||||
|
int fd; // Connection to /dev/bus/usb/...
|
||||||
|
usb_device_descriptor descriptor; // Cache the descriptor
|
||||||
|
USBConfiguration *active; // Current active configuration
|
||||||
|
BList configurations; // All possible configurations
|
||||||
|
|
||||||
|
friend USBEndpoint; // USBEndpoint uses the XxxTransfer() methods
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class USBRoster
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
USBRoster(void);
|
||||||
|
virtual ~USBRoster();
|
||||||
|
|
||||||
|
// DeviceAdded() is called when a new device appears on the Bus.
|
||||||
|
// If the result is not B_OK, the USBDevice instance is deleted and
|
||||||
|
// there will be no DeviceRemoved notification.
|
||||||
|
virtual status_t DeviceAdded(USBDevice *dev) = 0;
|
||||||
|
|
||||||
|
// DeviceRemoved() is called when a device is disconnected from the Bus.
|
||||||
|
// The USBDevice WILL BE deleted after this method returns.
|
||||||
|
virtual void DeviceRemoved(USBDevice *dev) = 0;
|
||||||
|
|
||||||
|
void Start(void);
|
||||||
|
void Stop(void);
|
||||||
|
private:
|
||||||
|
USBRosterLooper *rlooper;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
#include <USBKit.h>
|
||||||
|
|
||||||
|
// USBConfiguration ------------------------------------------------------------------
|
||||||
|
|
||||||
|
uint32
|
||||||
|
USBConfiguration::CountInterfaces(void) const
|
||||||
|
{
|
||||||
|
return descriptor.number_interfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
const USBInterface *
|
||||||
|
USBConfiguration::InterfaceAt(uint32 n) const
|
||||||
|
{
|
||||||
|
return (USBInterface *) interfaces.ItemAt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
const usb_configuration_descriptor *
|
||||||
|
USBConfiguration::Descriptor(void) const
|
||||||
|
{
|
||||||
|
return &descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const USBDevice *
|
||||||
|
USBConfiguration::Device(void) const
|
||||||
|
{
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
USBConfiguration::USBConfiguration(uint n, USBDevice *dev)
|
||||||
|
{
|
||||||
|
configuration_num = n;
|
||||||
|
device = dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
USBConfiguration::~USBConfiguration()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
USBInterface *ifc;
|
||||||
|
|
||||||
|
for(i=0;(ifc = (USBInterface *) interfaces.ItemAt(i)); i++){
|
||||||
|
delete ifc;
|
||||||
|
}
|
||||||
|
interfaces.MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,419 @@
|
|||||||
|
|
||||||
|
#include <USBKit.h>
|
||||||
|
#include <usbraw.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// USBDevice -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
USBDevice::USBDevice(const char *path)
|
||||||
|
{
|
||||||
|
fd = -1;
|
||||||
|
serial_string = NULL;
|
||||||
|
manufacturer_string = NULL;
|
||||||
|
product_string = NULL;
|
||||||
|
active = NULL;
|
||||||
|
ishub = false;
|
||||||
|
location = NULL;
|
||||||
|
|
||||||
|
SetTo(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
USBDevice::~USBDevice()
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
USBDevice::Location(void) const
|
||||||
|
{
|
||||||
|
return (const char *) location;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
USBDevice::IsHub(void) const
|
||||||
|
{
|
||||||
|
return ishub;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release allocated resources (for destructor or reinit)
|
||||||
|
void USBDevice::Release(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
USBConfiguration *cfg;
|
||||||
|
|
||||||
|
ishub = false;
|
||||||
|
|
||||||
|
if(fd != -1) {
|
||||||
|
close(fd);
|
||||||
|
fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(location){
|
||||||
|
free(location);
|
||||||
|
location = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(serial_string) {
|
||||||
|
delete[] serial_string;
|
||||||
|
serial_string = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(manufacturer_string) {
|
||||||
|
delete[] manufacturer_string;
|
||||||
|
manufacturer_string = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(product_string) {
|
||||||
|
delete[] product_string;
|
||||||
|
product_string = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0;(cfg = (USBConfiguration *) configurations.ItemAt(i)); i++){
|
||||||
|
delete cfg;
|
||||||
|
}
|
||||||
|
configurations.MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
USBDevice::PopulateInterface(USBInterface *ifc, usb_interface_descriptor *descr)
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
memcpy(&(ifc->descriptor),descr,sizeof(usb_interface_descriptor));
|
||||||
|
for(i=0;i<ifc->CountEndpoints();i++){
|
||||||
|
usb_raw_command cmd;
|
||||||
|
usb_endpoint_descriptor descr;
|
||||||
|
cmd.endpoint.descr = &descr;
|
||||||
|
cmd.endpoint.config_num = ifc->configuration->configuration_num;
|
||||||
|
cmd.endpoint.interface_num = ifc->interface_num;
|
||||||
|
cmd.endpoint.endpoint_num = i;
|
||||||
|
ioctl(fd,get_endpoint_descriptor,&cmd,sizeof(cmd));
|
||||||
|
if(!cmd.endpoint.status){
|
||||||
|
USBEndpoint *ept = new USBEndpoint(i,ifc);
|
||||||
|
memcpy(&(ept->descriptor),&descr,sizeof(usb_endpoint_descriptor));
|
||||||
|
ept->endpoint_num = i;
|
||||||
|
ifc->endpoints.AddItem(ept);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
USBDevice::PopulateConfig(USBConfiguration *conf, usb_configuration_descriptor *descr)
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
memcpy(&(conf->descriptor),descr,sizeof(usb_configuration_descriptor));
|
||||||
|
for(i=0;i<conf->CountInterfaces();i++){
|
||||||
|
usb_raw_command cmd;
|
||||||
|
usb_interface_descriptor descr;
|
||||||
|
cmd.interface.descr = &descr;
|
||||||
|
cmd.interface.config_num = conf->configuration_num;
|
||||||
|
cmd.interface.interface_num = i;
|
||||||
|
ioctl(fd,get_interface_descriptor,&cmd,sizeof(cmd));
|
||||||
|
if(!cmd.interface.status){
|
||||||
|
USBInterface *ifc = new USBInterface(i,conf);
|
||||||
|
ifc->interface_num = i;
|
||||||
|
PopulateInterface(ifc,&descr);
|
||||||
|
conf->interfaces.AddItem(ifc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
USBDevice::PopulateDevice(void)
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
for(i=0;i<CountConfigurations();i++){
|
||||||
|
usb_raw_command cmd;
|
||||||
|
usb_configuration_descriptor descr;
|
||||||
|
cmd.config.descr = &descr;
|
||||||
|
cmd.config.config_num = i;
|
||||||
|
ioctl(fd,get_configuration_descriptor,&cmd,sizeof(cmd));
|
||||||
|
if(!cmd.config.status){
|
||||||
|
USBConfiguration *conf = new USBConfiguration(i,this);
|
||||||
|
PopulateConfig(conf,&descr);
|
||||||
|
configurations.AddItem(conf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
USBDevice::InitCheck(void)
|
||||||
|
{
|
||||||
|
return (fd != -1) ? B_OK : B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
USBDevice::SetTo(const char *path)
|
||||||
|
{
|
||||||
|
usb_raw_command cmd;
|
||||||
|
|
||||||
|
Release();
|
||||||
|
|
||||||
|
if(strncmp("/dev/bus/usb/",path,12)) {
|
||||||
|
fprintf(stderr,"USBKit: Not a usb raw device '%s'\n",path);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((fd = open(path,O_RDWR)) < 0) {
|
||||||
|
fprintf(stderr,"USBKit: Cannot open '%s'\n",path);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ioctl(fd, check_version, &cmd, sizeof(cmd))){
|
||||||
|
fprintf(stderr,"USBKit: Device won't verify version\n");
|
||||||
|
close(fd);
|
||||||
|
fd = -1;
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cmd.generic.status != USB_RAW_DRIVER_VERSION){
|
||||||
|
fprintf(stderr,"USBKit: Driver version 0x%04x != expected version 0x%04x\n",
|
||||||
|
cmd.generic.status, USB_RAW_DRIVER_VERSION);
|
||||||
|
close(fd);
|
||||||
|
fd = -1;
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.device.descr = &descriptor;
|
||||||
|
if(ioctl(fd,get_device_descriptor,&cmd,sizeof(cmd))){
|
||||||
|
fprintf(stderr,"USBKit: Device won't return device descriptor\n");
|
||||||
|
fd = -1;
|
||||||
|
return B_ERROR;
|
||||||
|
} else {
|
||||||
|
PopulateDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
location = strdup(path+12);
|
||||||
|
if(location[strlen(location)-1]=='b'){
|
||||||
|
ishub = true;
|
||||||
|
location[strlen(location)-4] = 0;
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
const usb_device_descriptor *
|
||||||
|
USBDevice::Descriptor(void) const
|
||||||
|
{
|
||||||
|
return &descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16
|
||||||
|
USBDevice::USBVersion(void) const
|
||||||
|
{
|
||||||
|
return descriptor.usb_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8
|
||||||
|
USBDevice::Class(void) const
|
||||||
|
{
|
||||||
|
return descriptor.device_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8
|
||||||
|
USBDevice::Subclass(void) const
|
||||||
|
{
|
||||||
|
return descriptor.device_subclass;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8
|
||||||
|
USBDevice::Protocol(void) const
|
||||||
|
{
|
||||||
|
return descriptor.device_protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8
|
||||||
|
USBDevice::MaxEndpoint0PacketSize(void) const
|
||||||
|
{
|
||||||
|
return descriptor.max_packet_size_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16
|
||||||
|
USBDevice::VendorID(void) const
|
||||||
|
{
|
||||||
|
return descriptor.vendor_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16
|
||||||
|
USBDevice::ProductID(void) const
|
||||||
|
{
|
||||||
|
return descriptor.product_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16
|
||||||
|
USBDevice::Version(void) const
|
||||||
|
{
|
||||||
|
return descriptor.device_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
USBDevice::ManufacturerString(void) const
|
||||||
|
{
|
||||||
|
if(descriptor.manufacturer){
|
||||||
|
if(manufacturer_string) delete[] manufacturer_string;
|
||||||
|
manufacturer_string = DecodeStringDescriptor(descriptor.manufacturer);
|
||||||
|
if(manufacturer_string){
|
||||||
|
return (const char *) manufacturer_string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (const char *) "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
USBDevice::ProductString(void) const
|
||||||
|
{
|
||||||
|
if(descriptor.product){
|
||||||
|
if(product_string) delete[] product_string;
|
||||||
|
product_string = DecodeStringDescriptor(descriptor.product);
|
||||||
|
if(product_string) {
|
||||||
|
return (const char *) product_string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (const char *) "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
USBDevice::SerialNumberString(void) const
|
||||||
|
{
|
||||||
|
if(descriptor.serial_number){
|
||||||
|
if(serial_string) delete[] serial_string;
|
||||||
|
serial_string = DecodeStringDescriptor(descriptor.serial_number);
|
||||||
|
if(serial_string){
|
||||||
|
return (const char *) serial_string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (const char *) "";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
USBDevice::DecodeStringDescriptor(uint32 n) const
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
size_t l;
|
||||||
|
uint i;
|
||||||
|
union {
|
||||||
|
usb_string_descriptor str;
|
||||||
|
uint16 raw[128];
|
||||||
|
} x;
|
||||||
|
|
||||||
|
l = GetStringDescriptor(n, &x.str, 255);
|
||||||
|
if(l < 3) return NULL;
|
||||||
|
if((l != x.str.length) || (x.str.length > 255)) return NULL;
|
||||||
|
l = (l-2)/2;
|
||||||
|
s = new char[l+1];
|
||||||
|
for(i=0;i<l;i++) {
|
||||||
|
s[i] = x.raw[i+1];
|
||||||
|
}
|
||||||
|
s[i] = 0;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
USBDevice::GetStringDescriptor(uint32 n, usb_string_descriptor *desc, size_t length) const
|
||||||
|
{
|
||||||
|
usb_raw_command raw;
|
||||||
|
raw.string.descr = desc;
|
||||||
|
raw.string.string_num = n;
|
||||||
|
raw.string.length = length;
|
||||||
|
|
||||||
|
if(ioctl(fd,get_string_descriptor,&raw,sizeof(raw)) || (raw.string.status)){
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return raw.string.length;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
USBDevice::CountConfigurations(void) const
|
||||||
|
{
|
||||||
|
if(fd == -1){
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return descriptor.num_configurations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const USBConfiguration *
|
||||||
|
USBDevice::ActiveConfiguration(void) const
|
||||||
|
{
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
const USBConfiguration *
|
||||||
|
USBDevice::ConfigurationAt(uint32 n) const
|
||||||
|
{
|
||||||
|
return (USBConfiguration *) configurations.ItemAt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
USBDevice::SetConfiguration(const USBConfiguration *conf)
|
||||||
|
{
|
||||||
|
usb_raw_command cmd;
|
||||||
|
cmd.config.config_num = conf->configuration_num;
|
||||||
|
if(ioctl(fd, set_configuration, &cmd, sizeof(cmd))){
|
||||||
|
return B_ERROR;
|
||||||
|
} else {
|
||||||
|
if(!cmd.generic.status) active = (USBConfiguration *) conf;
|
||||||
|
return cmd.generic.status ? B_ERROR : B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
USBDevice::ControlTransfer(uint8 request_type, uint8 request, uint16 value,
|
||||||
|
uint16 index, uint16 length, void *data) const
|
||||||
|
{
|
||||||
|
usb_raw_command cmd;
|
||||||
|
cmd.control.request_type = request_type;
|
||||||
|
cmd.control.request = request;
|
||||||
|
cmd.control.value = value;
|
||||||
|
cmd.control.index = index;
|
||||||
|
cmd.control.length = length;
|
||||||
|
cmd.control.data = data;
|
||||||
|
|
||||||
|
if(ioctl(fd, do_control, &cmd, sizeof(cmd))){
|
||||||
|
return B_ERROR;
|
||||||
|
} else {
|
||||||
|
return cmd.generic.status ? B_ERROR : B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
USBDevice::InterruptTransfer(const USBEndpoint *e, void *data, size_t length) const
|
||||||
|
{
|
||||||
|
if(!e || (e->Device() != this)) return B_ERROR;
|
||||||
|
|
||||||
|
usb_raw_command cmd;
|
||||||
|
cmd.interrupt.interface = e->interface->interface_num;
|
||||||
|
cmd.interrupt.endpoint = e->endpoint_num;
|
||||||
|
cmd.interrupt.data = data;
|
||||||
|
cmd.interrupt.length = length;
|
||||||
|
|
||||||
|
if(ioctl(fd, do_interrupt, &cmd, sizeof(cmd))){
|
||||||
|
return B_ERROR;
|
||||||
|
} else {
|
||||||
|
return cmd.generic.status ? B_ERROR : B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
USBDevice::BulkTransfer(const USBEndpoint *e, void *data, size_t length) const
|
||||||
|
{
|
||||||
|
if(!e || (e->Device() != this)) return B_ERROR;
|
||||||
|
|
||||||
|
usb_raw_command cmd;
|
||||||
|
cmd.bulk.interface = e->interface->interface_num;
|
||||||
|
cmd.bulk.endpoint = e->endpoint_num;
|
||||||
|
cmd.bulk.data = data;
|
||||||
|
cmd.bulk.length = length;
|
||||||
|
|
||||||
|
if(ioctl(fd, do_bulk, &cmd, sizeof(cmd))){
|
||||||
|
return B_ERROR;
|
||||||
|
} else {
|
||||||
|
return cmd.generic.status ? B_ERROR : B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
|
||||||
|
// USBEndpoint ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <USBKit.h>
|
||||||
|
|
||||||
|
const USBInterface *
|
||||||
|
USBEndpoint::Interface(void) const
|
||||||
|
{
|
||||||
|
return interface;
|
||||||
|
}
|
||||||
|
|
||||||
|
const USBConfiguration *
|
||||||
|
USBEndpoint::Configuration(void) const
|
||||||
|
{
|
||||||
|
return interface->Configuration();
|
||||||
|
}
|
||||||
|
|
||||||
|
const USBDevice *
|
||||||
|
USBEndpoint::Device(void) const
|
||||||
|
{
|
||||||
|
return interface->Configuration()->Device();
|
||||||
|
}
|
||||||
|
|
||||||
|
const usb_endpoint_descriptor *
|
||||||
|
USBEndpoint::Descriptor(void) const
|
||||||
|
{
|
||||||
|
return &descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
USBEndpoint::IsBulk(void) const
|
||||||
|
{
|
||||||
|
return (descriptor.attributes & 0x03) == 0x02;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
USBEndpoint::IsInterrupt(void) const
|
||||||
|
{
|
||||||
|
return (descriptor.attributes & 0x03) == 0x03;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
USBEndpoint::IsIsochronous(void) const
|
||||||
|
{
|
||||||
|
return (descriptor.attributes & 0x03) == 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
USBEndpoint::IsInput(void) const
|
||||||
|
{
|
||||||
|
return (descriptor.endpoint_address & 0x01) == 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
USBEndpoint::IsOutput(void) const
|
||||||
|
{
|
||||||
|
return (descriptor.endpoint_address & 0x01) == 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16
|
||||||
|
USBEndpoint::MaxPacketSize(void) const
|
||||||
|
{
|
||||||
|
return descriptor.max_packet_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8
|
||||||
|
USBEndpoint::Interval(void) const
|
||||||
|
{
|
||||||
|
return descriptor.interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
USBEndpoint::InterruptTransfer(void *data, size_t length) const
|
||||||
|
{
|
||||||
|
return Device()->InterruptTransfer(this,data,length);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
USBEndpoint::BulkTransfer(void *data, size_t length) const
|
||||||
|
{
|
||||||
|
return Device()->BulkTransfer(this,data,length);
|
||||||
|
}
|
||||||
|
|
||||||
|
USBEndpoint::USBEndpoint(uint32 n, USBInterface *ifc)
|
||||||
|
{
|
||||||
|
endpoint_num = n;
|
||||||
|
interface = ifc;
|
||||||
|
}
|
||||||
|
|
||||||
|
USBEndpoint::~USBEndpoint()
|
||||||
|
{
|
||||||
|
// nothing to do here really.
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
|
||||||
|
#include <USBKit.h>
|
||||||
|
|
||||||
|
// USBInterface ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
uint32
|
||||||
|
USBInterface::CountEndpoints(void) const
|
||||||
|
{
|
||||||
|
return descriptor.num_endpoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
const USBEndpoint *
|
||||||
|
USBInterface::EndpointAt(uint32 n) const
|
||||||
|
{
|
||||||
|
return (USBEndpoint *) endpoints.ItemAt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
const usb_interface_descriptor *
|
||||||
|
USBInterface::Descriptor(void) const
|
||||||
|
{
|
||||||
|
return &descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8
|
||||||
|
USBInterface::Class(void) const
|
||||||
|
{
|
||||||
|
return descriptor.interface_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8
|
||||||
|
USBInterface::Subclass(void) const
|
||||||
|
{
|
||||||
|
return descriptor.interface_subclass;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8
|
||||||
|
USBInterface::Protocol(void) const
|
||||||
|
{
|
||||||
|
return descriptor.interface_protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
USBInterface::InterfaceString(void) const
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const USBConfiguration *
|
||||||
|
USBInterface::Configuration(void) const
|
||||||
|
{
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
const USBDevice *
|
||||||
|
USBInterface::Device(void) const
|
||||||
|
{
|
||||||
|
return configuration->Device();
|
||||||
|
}
|
||||||
|
|
||||||
|
USBInterface::USBInterface(uint32 n, USBConfiguration *cfg)
|
||||||
|
{
|
||||||
|
interface_num = n;
|
||||||
|
configuration = cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
USBInterface::~USBInterface()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
USBEndpoint *ept;
|
||||||
|
|
||||||
|
for(i=0;(ept = (USBEndpoint *) endpoints.ItemAt(i)); i++){
|
||||||
|
delete ept;
|
||||||
|
}
|
||||||
|
endpoints.MakeEmpty();
|
||||||
|
}
|
||||||
@@ -0,0 +1,344 @@
|
|||||||
|
|
||||||
|
#include <USBKit.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <Application.h>
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <List.h>
|
||||||
|
#include <MessageFilter.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <NodeInfo.h>
|
||||||
|
#include <NodeMonitor.h>
|
||||||
|
#include <Path.h>
|
||||||
|
|
||||||
|
static int __directory = 0;
|
||||||
|
static void *DIRECTORY = (void *) &__directory;
|
||||||
|
|
||||||
|
struct WatchItem
|
||||||
|
{
|
||||||
|
ino_t inode;
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
WatchItem *children;
|
||||||
|
WatchItem *next;
|
||||||
|
WatchItem *parent;
|
||||||
|
|
||||||
|
~WatchItem(){
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *LongName(void){
|
||||||
|
WatchItem *w;
|
||||||
|
int sz;
|
||||||
|
char *n;
|
||||||
|
for(w=parent,sz=1+strlen(name);w;w=w->parent){
|
||||||
|
sz += 1+strlen(w->name);
|
||||||
|
}
|
||||||
|
n = (char*) malloc(sz);
|
||||||
|
sz--;
|
||||||
|
n[sz] = 0;
|
||||||
|
for(w=this;w;w=w->parent){
|
||||||
|
sz -= strlen(w->name);
|
||||||
|
memcpy(n + sz, w->name, strlen(w->name));
|
||||||
|
if(sz){
|
||||||
|
sz--;
|
||||||
|
n[sz]='/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchItem(ino_t inode, const char *name, void *data = NULL){
|
||||||
|
parent = NULL;
|
||||||
|
children = NULL;
|
||||||
|
next = NULL;
|
||||||
|
|
||||||
|
this->inode = inode;
|
||||||
|
this->name = strdup(name);
|
||||||
|
this->data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchItem *Find(const char *name0){
|
||||||
|
WatchItem *w;
|
||||||
|
for(w=children;w;w=w->next){
|
||||||
|
if(!strcmp(name0,w->name)) return w;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchItem *Find(ino_t inode0){
|
||||||
|
WatchItem *w;
|
||||||
|
|
||||||
|
if(inode == inode0) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(w=children;w;w=w->next){
|
||||||
|
WatchItem *r = w->Find(inode0);
|
||||||
|
if(r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchItem *Remove(WatchItem *w){
|
||||||
|
char *n = w->LongName();
|
||||||
|
free(n);
|
||||||
|
|
||||||
|
if(w->parent != this) return w;
|
||||||
|
w->parent = NULL;
|
||||||
|
|
||||||
|
if(children == w){
|
||||||
|
children = w->next;
|
||||||
|
w->next = NULL;
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
WatchItem *w0;
|
||||||
|
for(w0=children;w0;w0=w0->next){
|
||||||
|
if(w0->next == w){
|
||||||
|
w0->next = w->next;
|
||||||
|
w->next = NULL;
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add(WatchItem *w){
|
||||||
|
w->parent = this;
|
||||||
|
w->next = children;
|
||||||
|
children = w;
|
||||||
|
|
||||||
|
char *n = w->LongName();
|
||||||
|
free(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class USBRosterLooper : public BLooper
|
||||||
|
{
|
||||||
|
friend USBRoster;
|
||||||
|
|
||||||
|
void DestroyItem(WatchItem *item);
|
||||||
|
void ItemAdded(WatchItem *item);
|
||||||
|
void WatchDirectory(BEntry &dir, WatchItem *parent);
|
||||||
|
BMessenger *messenger;
|
||||||
|
WatchItem *root;
|
||||||
|
USBRoster *roster;
|
||||||
|
dev_t dev;
|
||||||
|
|
||||||
|
public:
|
||||||
|
USBRosterLooper(USBRoster *roster);
|
||||||
|
virtual void MessageReceived(BMessage *msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
USBRosterLooper::WatchDirectory(BEntry &_entry, WatchItem *parent)
|
||||||
|
{
|
||||||
|
node_ref nref;
|
||||||
|
BEntry entry;
|
||||||
|
BDirectory dir(&_entry);
|
||||||
|
if(dir.GetNodeRef(&nref)) return; // Not a directory
|
||||||
|
BPath path(&_entry);
|
||||||
|
WatchItem *item;
|
||||||
|
|
||||||
|
// fprintf(stderr,"Watching %s\n",path.Path());
|
||||||
|
|
||||||
|
item = parent ? parent->Find(nref.node) : NULL;
|
||||||
|
if(!item) {
|
||||||
|
item = new WatchItem(nref.node,path.Leaf(), DIRECTORY);
|
||||||
|
watch_node(&nref, B_WATCH_DIRECTORY, *messenger);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!parent){
|
||||||
|
// fprintf(stderr,"create root\n");
|
||||||
|
parent = root = item;
|
||||||
|
} else {
|
||||||
|
parent->Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
while(dir.GetNextEntry(&entry) == B_NO_ERROR){
|
||||||
|
BPath path(&entry);
|
||||||
|
if(entry.IsDirectory()){
|
||||||
|
WatchDirectory(entry, item);
|
||||||
|
} else {
|
||||||
|
if(!strcmp(path.Leaf(),"unload")) continue;
|
||||||
|
// fprintf(stderr,"File %s\n",path.Path());
|
||||||
|
if(!item->Find(path.Leaf())){
|
||||||
|
struct stat s;
|
||||||
|
if(!entry.GetStat(&s)){
|
||||||
|
USBDevice *dev = new USBDevice(path.Path());
|
||||||
|
if(dev->InitCheck() == B_OK){
|
||||||
|
WatchItem *wi = new WatchItem(s.st_ino,path.Leaf(),dev);
|
||||||
|
item->Add(wi);
|
||||||
|
ItemAdded(wi);
|
||||||
|
} else {
|
||||||
|
delete dev;
|
||||||
|
item->Add(new WatchItem(s.st_ino,path.Leaf()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
USBRosterLooper::MessageReceived(BMessage *msg)
|
||||||
|
{
|
||||||
|
int32 opcode;
|
||||||
|
if (msg->FindInt32("opcode", &opcode) != B_NO_ERROR) return;
|
||||||
|
|
||||||
|
switch(opcode){
|
||||||
|
case B_ENTRY_CREATED: {
|
||||||
|
ino_t dir;
|
||||||
|
dev_t device;
|
||||||
|
const char *name;
|
||||||
|
if (msg->FindInt32("device", &device) != B_NO_ERROR ||
|
||||||
|
msg->FindInt64("directory", &dir) != B_NO_ERROR ||
|
||||||
|
msg->FindString("name", &name) != B_NO_ERROR) break;
|
||||||
|
|
||||||
|
if(!strcmp(name,"unload")) break;
|
||||||
|
|
||||||
|
// fprintf(stderr,"created - %s (in %Ld)\n",name,dir);
|
||||||
|
// Locate the directory by its inode
|
||||||
|
WatchItem *item = root->Find(dir);
|
||||||
|
if(item){
|
||||||
|
// Item already exists?
|
||||||
|
if(!item->Find(name)){
|
||||||
|
entry_ref entryRef(device, dir, name);
|
||||||
|
BEntry entry(&entryRef);
|
||||||
|
if(entry.IsDirectory()){
|
||||||
|
WatchDirectory(entry,item);
|
||||||
|
} else {
|
||||||
|
struct stat s;
|
||||||
|
entry.GetStat(&s);
|
||||||
|
BPath path(&entry);
|
||||||
|
USBDevice *dev = new USBDevice(path.Path());
|
||||||
|
if(dev->InitCheck() == B_OK){
|
||||||
|
WatchItem *wi = new WatchItem(s.st_ino,name,dev);
|
||||||
|
item->Add(wi);
|
||||||
|
ItemAdded(wi);
|
||||||
|
} else {
|
||||||
|
delete dev;
|
||||||
|
item->Add(new WatchItem(s.st_ino,name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,"no item\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_ENTRY_REMOVED: {
|
||||||
|
ino_t dir;
|
||||||
|
dev_t device;
|
||||||
|
ino_t node;
|
||||||
|
if (msg->FindInt32("device", &device) != B_NO_ERROR ||
|
||||||
|
msg->FindInt64("directory", &dir) != B_NO_ERROR ||
|
||||||
|
msg->FindInt64("node", &node) != B_NO_ERROR) break;
|
||||||
|
// fprintf(stderr,"removed - %Ld (in %Ld)\n",node,dir);
|
||||||
|
|
||||||
|
// Locate the item by its inode
|
||||||
|
WatchItem *item = root->Find(node);
|
||||||
|
if(item && item->parent){
|
||||||
|
DestroyItem(item->parent->Remove(item));
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,"no item\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
USBRosterLooper::DestroyItem(WatchItem *item)
|
||||||
|
{
|
||||||
|
if(!item) return;
|
||||||
|
if(item->data) {
|
||||||
|
if(item->data == DIRECTORY){
|
||||||
|
node_ref nref;
|
||||||
|
nref.device = dev;
|
||||||
|
nref.node = item->inode;
|
||||||
|
watch_node(&nref, B_STOP_WATCHING, *messenger);
|
||||||
|
} else {
|
||||||
|
roster->DeviceRemoved((USBDevice *)item->data);
|
||||||
|
delete ((USBDevice *)item->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(item->children){
|
||||||
|
WatchItem *w = item->children;
|
||||||
|
while(w) {
|
||||||
|
WatchItem *next = w->next;
|
||||||
|
DestroyItem(w);
|
||||||
|
w = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
USBRosterLooper::ItemAdded(WatchItem *item)
|
||||||
|
{
|
||||||
|
if(!item) return;
|
||||||
|
if(item->data && (item->data != DIRECTORY)){
|
||||||
|
if(roster->DeviceAdded((USBDevice *)item->data) != B_OK){
|
||||||
|
delete ((USBDevice *) item->data);
|
||||||
|
item->data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
USBRosterLooper::USBRosterLooper(USBRoster *r)
|
||||||
|
{
|
||||||
|
BEntry path("/dev/bus/usb");
|
||||||
|
if(path.InitCheck()) fprintf(stderr,"BLAGHR!");
|
||||||
|
|
||||||
|
roster = r;
|
||||||
|
node_ref nref;
|
||||||
|
path.GetNodeRef(&nref);
|
||||||
|
dev = nref.device;
|
||||||
|
|
||||||
|
Run();
|
||||||
|
messenger = new BMessenger(this);
|
||||||
|
Lock();
|
||||||
|
WatchDirectory(path,NULL);
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
USBRoster::Start(void)
|
||||||
|
{
|
||||||
|
if(!rlooper){
|
||||||
|
rlooper = new USBRosterLooper(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
USBRoster::Stop(void)
|
||||||
|
{
|
||||||
|
if(rlooper){
|
||||||
|
rlooper->Lock();
|
||||||
|
rlooper->DestroyItem(rlooper->root);
|
||||||
|
rlooper->Quit();
|
||||||
|
rlooper = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
USBRoster::USBRoster(void)
|
||||||
|
{
|
||||||
|
rlooper = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
USBRoster::~USBRoster()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user