* Extend the usb_raw interface by alternate interface aware getters for
interfaces, endpoints and generic descriptors. * Add getter for active interface index and simplify the count operation as it isn't misused to also get interface descriptors anymore. * Refactor out some common code into helper functions. * Adapt the USBKit to the changed/new interface. * Change how alternate interfaces are exposed by USBKit by providing normal BUSBInterface objects for alternate interfaces that can easily be examined and used. * Make BUSBInterface class aware of its alternate index and use the alternate aware usb_raw functionallity to build the endpoint and descriptor lists. * Add ActiveAlternateIndex() to find out what alternate is currently active. * Style cleanup of the USBKit classes, use std::nothrow everywhere and check all allocations. Simplify some code by removing optimization where the benefit is questionable. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27409 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+30
-18
@@ -98,7 +98,8 @@ virtual status_t InitCheck();
|
|||||||
const char * ProductString() const;
|
const char * ProductString() const;
|
||||||
const char * SerialNumberString() const;
|
const char * SerialNumberString() const;
|
||||||
|
|
||||||
const usb_device_descriptor *Descriptor() const;
|
const usb_device_descriptor *
|
||||||
|
Descriptor() const;
|
||||||
|
|
||||||
// GetStringDescriptor() can be used to retrieve the raw
|
// GetStringDescriptor() can be used to retrieve the raw
|
||||||
// usb_string_descriptor with a given index. The strings contained
|
// usb_string_descriptor with a given index. The strings contained
|
||||||
@@ -177,8 +178,8 @@ public:
|
|||||||
// Otherwise an empty string is returned.
|
// Otherwise an empty string is returned.
|
||||||
const char * ConfigurationString() const;
|
const char * ConfigurationString() const;
|
||||||
|
|
||||||
const usb_configuration_descriptor
|
const usb_configuration_descriptor *
|
||||||
*Descriptor() const;
|
Descriptor() const;
|
||||||
|
|
||||||
// With CountInterfaces() and InterfaceAt() you can iterate through
|
// With CountInterfaces() and InterfaceAt() you can iterate through
|
||||||
// the child interfaces of this configuration. It is the only valid
|
// the child interfaces of this configuration. It is the only valid
|
||||||
@@ -215,10 +216,12 @@ class BUSBInterface {
|
|||||||
public:
|
public:
|
||||||
// Configuration() returns the parent configuration of this interface.
|
// Configuration() returns the parent configuration of this interface.
|
||||||
// This interface is located at the index returned by Index() in that
|
// This interface is located at the index returned by Index() in that
|
||||||
// parent configuration.
|
// parent configuration and represents the alternate interface returned
|
||||||
|
// by AlternateIndex().
|
||||||
// Device() is a convenience function to directly reach the parent
|
// Device() is a convenience function to directly reach the parent
|
||||||
// device of this interface instead of going through the configuration.
|
// device of this interface instead of going through the configuration.
|
||||||
uint32 Index() const;
|
uint32 Index() const;
|
||||||
|
uint32 AlternateIndex() const;
|
||||||
const BUSBConfiguration * Configuration() const;
|
const BUSBConfiguration * Configuration() const;
|
||||||
const BUSBDevice * Device() const;
|
const BUSBDevice * Device() const;
|
||||||
|
|
||||||
@@ -230,8 +233,8 @@ public:
|
|||||||
uint8 Protocol() const;
|
uint8 Protocol() const;
|
||||||
const char * InterfaceString() const;
|
const char * InterfaceString() const;
|
||||||
|
|
||||||
const usb_interface_descriptor
|
const usb_interface_descriptor *
|
||||||
*Descriptor() const;
|
Descriptor() const;
|
||||||
|
|
||||||
// Use OtherDescriptorAt() to get generic descriptors of an interface.
|
// Use OtherDescriptorAt() to get generic descriptors of an interface.
|
||||||
// These are usually vendor or device specific extensions.
|
// These are usually vendor or device specific extensions.
|
||||||
@@ -252,38 +255,46 @@ public:
|
|||||||
// that you are currently using the sole interface present.
|
// that you are currently using the sole interface present.
|
||||||
// AlternateAt() returns the interface descriptor of the alternate
|
// AlternateAt() returns the interface descriptor of the alternate
|
||||||
// interface with the specified index. Using that you can peek at the
|
// interface with the specified index. Using that you can peek at the
|
||||||
// information contained in the descriptor without having to switch
|
// attributes of that alternate (including endpoints) without having to
|
||||||
// to this alternate interface. Note that the alternate index set in
|
// switch to this alternate interface.
|
||||||
// the interface descriptor returned is not necessarily the same index
|
// Note that you cannot use any endpoint you retrieve through an
|
||||||
// you used to get the descriptor. Always use the zero based index you
|
// interface you get through AlternateAt(). Even if you switch to that
|
||||||
// used to get the information with and not the values of the returned
|
// alternate later on, you cannot use an interface returned by
|
||||||
// descriptor as the stack will handle that translation internally.
|
// AlternateAt(). Instead switch to that alternate using the interface
|
||||||
// The interface descriptor returned was allocated by new and is yours.
|
// you got from the configuration and then use this switched interface
|
||||||
// You need to delete it when you're done with it.
|
// to enumerate the endpoints.
|
||||||
|
// ActiveAlternateIndex() returns the index of the currently active
|
||||||
|
// alternate interface.
|
||||||
// With SetAlternate() you can switch this BUSBInterface object to the
|
// With SetAlternate() you can switch this BUSBInterface object to the
|
||||||
// alternate interface at the specified index. Note that all endpoints
|
// alternate interface at the specified index. Note that all endpoints
|
||||||
// retrieved through EndpointAt() will become invalid and will be
|
// retrieved through EndpointAt() will become invalid and will be
|
||||||
// deleted as soon as you set an alternate interface (even if the
|
// deleted as soon as you set an alternate interface (even if the
|
||||||
// resulting interface is the same you were using before).
|
// resulting interface is the same you were using before).
|
||||||
uint32 CountAlternates() const;
|
uint32 CountAlternates() const;
|
||||||
usb_interface_descriptor *AlternateAt(uint32 alternateIndex);
|
uint32 ActiveAlternateIndex() const;
|
||||||
|
const BUSBInterface * AlternateAt(uint32 alternateIndex) const;
|
||||||
status_t SetAlternate(uint32 alternateIndex);
|
status_t SetAlternate(uint32 alternateIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BUSBConfiguration;
|
friend class BUSBConfiguration;
|
||||||
BUSBInterface(BUSBConfiguration *config,
|
BUSBInterface(BUSBConfiguration *config,
|
||||||
uint32 index, int rawFD);
|
uint32 index, uint32 alternate,
|
||||||
|
int rawFD);
|
||||||
~BUSBInterface();
|
~BUSBInterface();
|
||||||
|
|
||||||
void _UpdateDescriptorAndEndpoints();
|
void _UpdateDescriptorAndEndpoints();
|
||||||
|
|
||||||
BUSBConfiguration * fConfiguration;
|
BUSBConfiguration * fConfiguration;
|
||||||
uint32 fIndex;
|
uint32 fIndex;
|
||||||
|
uint32 fAlternate;
|
||||||
int fRawFD;
|
int fRawFD;
|
||||||
|
|
||||||
usb_interface_descriptor fDescriptor;
|
usb_interface_descriptor fDescriptor;
|
||||||
BUSBEndpoint ** fEndpoints;
|
BUSBEndpoint ** fEndpoints;
|
||||||
|
|
||||||
|
mutable uint32 fAlternateCount;
|
||||||
|
mutable BUSBInterface ** fAlternates;
|
||||||
|
|
||||||
mutable char * fInterfaceString;
|
mutable char * fInterfaceString;
|
||||||
|
|
||||||
uint32 fReserved[10];
|
uint32 fReserved[10];
|
||||||
@@ -318,8 +329,8 @@ public:
|
|||||||
uint16 MaxPacketSize() const;
|
uint16 MaxPacketSize() const;
|
||||||
uint8 Interval() const;
|
uint8 Interval() const;
|
||||||
|
|
||||||
const usb_endpoint_descriptor
|
const usb_endpoint_descriptor *
|
||||||
*Descriptor() const;
|
Descriptor() const;
|
||||||
|
|
||||||
// These methods initiate transfers to or from the endpoint. All
|
// These methods initiate transfers to or from the endpoint. All
|
||||||
// transfers are synchronous and the actually transfered amount of
|
// transfers are synchronous and the actually transfered amount of
|
||||||
@@ -343,6 +354,7 @@ public:
|
|||||||
// send the corresponding requests.
|
// send the corresponding requests.
|
||||||
bool IsStalled() const;
|
bool IsStalled() const;
|
||||||
status_t ClearStall() const;
|
status_t ClearStall() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BUSBInterface;
|
friend class BUSBInterface;
|
||||||
BUSBEndpoint(BUSBInterface *interface,
|
BUSBEndpoint(BUSBInterface *interface,
|
||||||
|
|||||||
@@ -124,6 +124,58 @@ usb_raw_device_removed(void *cookie)
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
static const usb_configuration_info *
|
||||||
|
usb_raw_get_configuration(raw_device *device, uint32 configIndex,
|
||||||
|
status_t *status)
|
||||||
|
{
|
||||||
|
const usb_configuration_info *result = gUSBModule->get_nth_configuration(
|
||||||
|
device->device, configIndex);
|
||||||
|
if (result == NULL) {
|
||||||
|
*status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const usb_interface_info *
|
||||||
|
usb_raw_get_interface(raw_device *device, uint32 configIndex,
|
||||||
|
uint32 interfaceIndex, uint32 alternateIndex, status_t *status)
|
||||||
|
{
|
||||||
|
const usb_configuration_info *configurationInfo
|
||||||
|
= usb_raw_get_configuration(device, configIndex, status);
|
||||||
|
if (configurationInfo == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (interfaceIndex >= configurationInfo->interface_count) {
|
||||||
|
*status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const usb_interface_info *result = NULL;
|
||||||
|
if (alternateIndex == B_USB_RAW_ACTIVE_ALTERNATE)
|
||||||
|
result = configurationInfo->interface[interfaceIndex].active;
|
||||||
|
else {
|
||||||
|
const usb_interface_list *interfaceList =
|
||||||
|
&configurationInfo->interface[interfaceIndex];
|
||||||
|
if (alternateIndex >= interfaceList->alt_count) {
|
||||||
|
*status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = &interfaceList->alt[alternateIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//#pragma mark -
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
usb_raw_open(const char *name, uint32 flags, void **cookie)
|
usb_raw_open(const char *name, uint32 flags, void **cookie)
|
||||||
{
|
{
|
||||||
@@ -211,11 +263,12 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
|||||||
{
|
{
|
||||||
TRACE((DRIVER_NAME": ioctl\n"));
|
TRACE((DRIVER_NAME": ioctl\n"));
|
||||||
raw_device *device = (raw_device *)cookie;
|
raw_device *device = (raw_device *)cookie;
|
||||||
usb_raw_command *command = (usb_raw_command *)buffer;
|
|
||||||
|
|
||||||
if (device->device == 0)
|
if (device->device == 0)
|
||||||
return B_DEV_NOT_READY;
|
return B_DEV_NOT_READY;
|
||||||
|
|
||||||
|
usb_raw_command *command = (usb_raw_command *)buffer;
|
||||||
|
command->version.status = B_USB_RAW_STATUS_ABORTED;
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case B_USB_RAW_COMMAND_GET_VERSION: {
|
case B_USB_RAW_COMMAND_GET_VERSION: {
|
||||||
command->version.status = B_USB_RAW_PROTOCOL_VERSION;
|
command->version.status = B_USB_RAW_PROTOCOL_VERSION;
|
||||||
@@ -225,10 +278,8 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
|||||||
case B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR: {
|
case B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR: {
|
||||||
const usb_device_descriptor *deviceDescriptor =
|
const usb_device_descriptor *deviceDescriptor =
|
||||||
gUSBModule->get_device_descriptor(device->device);
|
gUSBModule->get_device_descriptor(device->device);
|
||||||
if (!deviceDescriptor) {
|
if (!deviceDescriptor)
|
||||||
command->device.status = B_USB_RAW_STATUS_ABORTED;
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(command->device.descriptor, deviceDescriptor,
|
memcpy(command->device.descriptor, deviceDescriptor,
|
||||||
sizeof(usb_device_descriptor));
|
sizeof(usb_device_descriptor));
|
||||||
@@ -238,12 +289,10 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
|||||||
|
|
||||||
case B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR: {
|
case B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR: {
|
||||||
const usb_configuration_info *configurationInfo =
|
const usb_configuration_info *configurationInfo =
|
||||||
gUSBModule->get_nth_configuration(device->device,
|
usb_raw_get_configuration(device, command->config.config_index,
|
||||||
command->config.config_index);
|
&command->config.status);
|
||||||
if (!configurationInfo) {
|
if (configurationInfo == NULL)
|
||||||
command->config.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(command->config.descriptor, configurationInfo->descr,
|
memcpy(command->config.descriptor, configurationInfo->descr,
|
||||||
sizeof(usb_configuration_descriptor));
|
sizeof(usb_configuration_descriptor));
|
||||||
@@ -251,154 +300,141 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
case B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR: {
|
case B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT:
|
||||||
|
case B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX: {
|
||||||
const usb_configuration_info *configurationInfo =
|
const usb_configuration_info *configurationInfo =
|
||||||
gUSBModule->get_nth_configuration(device->device,
|
usb_raw_get_configuration(device,
|
||||||
command->interface.config_index);
|
command->alternate.config_index,
|
||||||
if (!configurationInfo) {
|
&command->alternate.status);
|
||||||
command->interface.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
|
if (configurationInfo == NULL)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
if (command->alternate.interface_index
|
||||||
|
>= configurationInfo->interface_count) {
|
||||||
|
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command->interface.interface_index >= configurationInfo->interface_count) {
|
const usb_interface_list *interfaceList
|
||||||
command->interface.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
= &configurationInfo->interface[
|
||||||
|
command->alternate.interface_index];
|
||||||
|
if (op == B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT) {
|
||||||
|
command->alternate.alternate_info = interfaceList->alt_count;
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < interfaceList->alt_count; i++) {
|
||||||
|
if (&interfaceList->alt[i] == interfaceList->active) {
|
||||||
|
command->alternate.alternate_info = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
command->alternate.status = B_USB_RAW_STATUS_SUCCESS;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const usb_interface_info *interfaceInfo =
|
case B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR:
|
||||||
configurationInfo->interface[command->interface.interface_index].active;
|
case B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC: {
|
||||||
if (!interfaceInfo) {
|
const usb_interface_info *interfaceInfo = NULL;
|
||||||
command->interface.status = B_USB_RAW_STATUS_ABORTED;
|
if (op == B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR) {
|
||||||
return B_OK;
|
interfaceInfo = usb_raw_get_interface(device,
|
||||||
|
command->interface.config_index,
|
||||||
|
command->interface.interface_index,
|
||||||
|
B_USB_RAW_ACTIVE_ALTERNATE,
|
||||||
|
&command->interface.status);
|
||||||
|
} else {
|
||||||
|
interfaceInfo = usb_raw_get_interface(device,
|
||||||
|
command->interface_etc.config_index,
|
||||||
|
command->interface_etc.interface_index,
|
||||||
|
command->interface_etc.alternate_index,
|
||||||
|
&command->interface_etc.status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (interfaceInfo == NULL)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
memcpy(command->interface.descriptor, interfaceInfo->descr,
|
memcpy(command->interface.descriptor, interfaceInfo->descr,
|
||||||
sizeof(usb_interface_descriptor));
|
sizeof(usb_interface_descriptor));
|
||||||
command->interface.status = B_USB_RAW_STATUS_SUCCESS;
|
command->interface.status = B_USB_RAW_STATUS_SUCCESS;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
case B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT: {
|
case B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR:
|
||||||
const usb_configuration_info *configurationInfo =
|
case B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC: {
|
||||||
gUSBModule->get_nth_configuration(device->device,
|
uint32 endpointIndex = 0;
|
||||||
command->alternate.config_index);
|
const usb_interface_info *interfaceInfo = NULL;
|
||||||
if (!configurationInfo) {
|
if (op == B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR) {
|
||||||
command->alternate.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
|
interfaceInfo = usb_raw_get_interface(device,
|
||||||
return B_OK;
|
command->endpoint.config_index,
|
||||||
|
command->endpoint.interface_index,
|
||||||
|
B_USB_RAW_ACTIVE_ALTERNATE,
|
||||||
|
&command->endpoint.status);
|
||||||
|
endpointIndex = command->endpoint.endpoint_index;
|
||||||
|
} else {
|
||||||
|
interfaceInfo = usb_raw_get_interface(device,
|
||||||
|
command->endpoint_etc.config_index,
|
||||||
|
command->endpoint_etc.interface_index,
|
||||||
|
command->endpoint_etc.alternate_index,
|
||||||
|
&command->endpoint_etc.status);
|
||||||
|
endpointIndex = command->endpoint_etc.endpoint_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command->alternate.interface_index >= configurationInfo->interface_count) {
|
if (!interfaceInfo)
|
||||||
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
|
||||||
|
|
||||||
*command->alternate.alternate_count
|
if (endpointIndex >= interfaceInfo->endpoint_count) {
|
||||||
= configurationInfo->interface[command->alternate.interface_index].alt_count;
|
|
||||||
command->alternate.status = B_USB_RAW_STATUS_SUCCESS;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
case B_USB_RAW_COMMAND_GET_ALT_INTERFACE_DESCRIPTOR: {
|
|
||||||
const usb_configuration_info *configurationInfo =
|
|
||||||
gUSBModule->get_nth_configuration(device->device,
|
|
||||||
command->alternate.config_index);
|
|
||||||
if (!configurationInfo) {
|
|
||||||
command->alternate.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command->alternate.interface_index >= configurationInfo->interface_count) {
|
|
||||||
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
const usb_interface_list *interfaceList =
|
|
||||||
&configurationInfo->interface[command->alternate.interface_index];
|
|
||||||
if (command->alternate.alternate_index >= interfaceList->alt_count) {
|
|
||||||
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(command->alternate.descriptor,
|
|
||||||
&interfaceList->alt[command->alternate.alternate_index],
|
|
||||||
sizeof(usb_interface_descriptor));
|
|
||||||
command->alternate.status = B_USB_RAW_STATUS_SUCCESS;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
case B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR: {
|
|
||||||
const usb_configuration_info *configurationInfo =
|
|
||||||
gUSBModule->get_nth_configuration(device->device,
|
|
||||||
command->endpoint.config_index);
|
|
||||||
if (!configurationInfo) {
|
|
||||||
command->endpoint.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command->endpoint.interface_index >= configurationInfo->interface_count) {
|
|
||||||
command->endpoint.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
const usb_interface_info *interfaceInfo =
|
|
||||||
configurationInfo->interface[command->endpoint.interface_index].active;
|
|
||||||
if (!interfaceInfo) {
|
|
||||||
command->endpoint.status = B_USB_RAW_STATUS_ABORTED;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command->endpoint.endpoint_index >= interfaceInfo->endpoint_count) {
|
|
||||||
command->endpoint.status = B_USB_RAW_STATUS_INVALID_ENDPOINT;
|
command->endpoint.status = B_USB_RAW_STATUS_INVALID_ENDPOINT;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(command->endpoint.descriptor,
|
memcpy(command->endpoint.descriptor,
|
||||||
interfaceInfo->endpoint[command->endpoint.endpoint_index].descr,
|
interfaceInfo->endpoint[endpointIndex].descr,
|
||||||
sizeof(usb_endpoint_descriptor));
|
sizeof(usb_endpoint_descriptor));
|
||||||
command->endpoint.status = B_USB_RAW_STATUS_SUCCESS;
|
command->endpoint.status = B_USB_RAW_STATUS_SUCCESS;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
case B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR: {
|
case B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR:
|
||||||
const usb_configuration_info *configurationInfo =
|
case B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR_ETC: {
|
||||||
gUSBModule->get_nth_configuration(device->device,
|
uint32 genericIndex = 0;
|
||||||
command->generic.config_index);
|
size_t genericLength = 0;
|
||||||
if (!configurationInfo) {
|
const usb_interface_info *interfaceInfo = NULL;
|
||||||
command->generic.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
|
if (op == B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR) {
|
||||||
|
interfaceInfo = usb_raw_get_interface(device,
|
||||||
|
command->generic.config_index,
|
||||||
|
command->generic.interface_index,
|
||||||
|
B_USB_RAW_ACTIVE_ALTERNATE,
|
||||||
|
&command->generic.status);
|
||||||
|
genericIndex = command->generic.generic_index;
|
||||||
|
genericLength = command->generic.length;
|
||||||
|
} else {
|
||||||
|
interfaceInfo = usb_raw_get_interface(device,
|
||||||
|
command->generic_etc.config_index,
|
||||||
|
command->generic_etc.interface_index,
|
||||||
|
command->generic_etc.alternate_index,
|
||||||
|
&command->generic_etc.status);
|
||||||
|
genericIndex = command->generic_etc.generic_index;
|
||||||
|
genericLength = command->generic_etc.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!interfaceInfo)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
if (genericIndex >= interfaceInfo->generic_count) {
|
||||||
|
command->endpoint.status = B_USB_RAW_STATUS_INVALID_ENDPOINT;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command->generic.interface_index >= configurationInfo->interface_count) {
|
usb_descriptor *descriptor = interfaceInfo->generic[genericIndex];
|
||||||
command->generic.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
if (!descriptor)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
|
||||||
|
|
||||||
const usb_interface_info *interfaceInfo =
|
|
||||||
configurationInfo->interface[command->generic.interface_index].active;
|
|
||||||
if (!interfaceInfo) {
|
|
||||||
command->generic.status = B_USB_RAW_STATUS_ABORTED;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command->generic.generic_index >= interfaceInfo->generic_count) {
|
|
||||||
// ToDo: add B_USB_RAW_STATUS_INVALID_GENERIC
|
|
||||||
command->generic.status = B_USB_RAW_STATUS_INVALID_ENDPOINT;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
usb_descriptor *descriptor = interfaceInfo->generic[command->generic.generic_index];
|
|
||||||
if (!descriptor) {
|
|
||||||
command->generic.status = B_USB_RAW_STATUS_ABORTED;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (descriptor->generic.length > command->generic.length) {
|
|
||||||
command->generic.status = B_USB_RAW_STATUS_NO_MEMORY;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(command->generic.descriptor, descriptor,
|
memcpy(command->generic.descriptor, descriptor,
|
||||||
descriptor->generic.length);
|
min_c(genericLength, descriptor->generic.length));
|
||||||
|
|
||||||
|
if (descriptor->generic.length > genericLength)
|
||||||
|
command->generic.status = B_USB_RAW_STATUS_NO_MEMORY;
|
||||||
|
else
|
||||||
command->generic.status = B_USB_RAW_STATUS_SUCCESS;
|
command->generic.status = B_USB_RAW_STATUS_SUCCESS;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -485,12 +521,10 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
|||||||
|
|
||||||
case B_USB_RAW_COMMAND_SET_CONFIGURATION: {
|
case B_USB_RAW_COMMAND_SET_CONFIGURATION: {
|
||||||
const usb_configuration_info *configurationInfo =
|
const usb_configuration_info *configurationInfo =
|
||||||
gUSBModule->get_nth_configuration(device->device,
|
usb_raw_get_configuration(device, command->config.config_index,
|
||||||
command->config.config_index);
|
&command->config.status);
|
||||||
if (!configurationInfo) {
|
if (configurationInfo == NULL)
|
||||||
command->config.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
|
||||||
|
|
||||||
if (gUSBModule->set_configuration(device->device,
|
if (gUSBModule->set_configuration(device->device,
|
||||||
configurationInfo) < B_OK) {
|
configurationInfo) < B_OK) {
|
||||||
@@ -504,27 +538,27 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
|||||||
|
|
||||||
case B_USB_RAW_COMMAND_SET_ALT_INTERFACE: {
|
case B_USB_RAW_COMMAND_SET_ALT_INTERFACE: {
|
||||||
const usb_configuration_info *configurationInfo =
|
const usb_configuration_info *configurationInfo =
|
||||||
gUSBModule->get_nth_configuration(device->device,
|
usb_raw_get_configuration(device,
|
||||||
command->alternate.config_index);
|
command->alternate.config_index,
|
||||||
if (!configurationInfo) {
|
&command->alternate.status);
|
||||||
command->alternate.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
|
if (configurationInfo == NULL)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
|
||||||
|
|
||||||
if (command->alternate.interface_index >= configurationInfo->interface_count) {
|
if (command->alternate.interface_index
|
||||||
|
>= configurationInfo->interface_count) {
|
||||||
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const usb_interface_list *interfaceList =
|
const usb_interface_list *interfaceList =
|
||||||
&configurationInfo->interface[command->alternate.interface_index];
|
&configurationInfo->interface[command->alternate.interface_index];
|
||||||
if (command->alternate.alternate_index >= interfaceList->alt_count) {
|
if (command->alternate.alternate_info >= interfaceList->alt_count) {
|
||||||
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gUSBModule->set_alt_interface(device->device,
|
if (gUSBModule->set_alt_interface(device->device,
|
||||||
&interfaceList->alt[command->alternate.alternate_index]) < B_OK) {
|
&interfaceList->alt[command->alternate.alternate_info]) < B_OK) {
|
||||||
command->alternate.status = B_USB_RAW_STATUS_FAILED;
|
command->alternate.status = B_USB_RAW_STATUS_FAILED;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <USB3.h>
|
#include <USB3.h>
|
||||||
|
|
||||||
#define B_USB_RAW_PROTOCOL_VERSION 0x0015
|
#define B_USB_RAW_PROTOCOL_VERSION 0x0015
|
||||||
|
#define B_USB_RAW_ACTIVE_ALTERNATE 0xffffffff
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
B_USB_RAW_COMMAND_GET_VERSION = 0x1000,
|
B_USB_RAW_COMMAND_GET_VERSION = 0x1000,
|
||||||
@@ -20,7 +21,10 @@ typedef enum {
|
|||||||
B_USB_RAW_COMMAND_GET_STRING_DESCRIPTOR,
|
B_USB_RAW_COMMAND_GET_STRING_DESCRIPTOR,
|
||||||
B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR,
|
B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR,
|
||||||
B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT,
|
B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT,
|
||||||
B_USB_RAW_COMMAND_GET_ALT_INTERFACE_DESCRIPTOR,
|
B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX,
|
||||||
|
B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC,
|
||||||
|
B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC,
|
||||||
|
B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR_ETC,
|
||||||
|
|
||||||
B_USB_RAW_COMMAND_SET_CONFIGURATION = 0x3000,
|
B_USB_RAW_COMMAND_SET_CONFIGURATION = 0x3000,
|
||||||
B_USB_RAW_COMMAND_SET_FEATURE,
|
B_USB_RAW_COMMAND_SET_FEATURE,
|
||||||
@@ -70,6 +74,13 @@ typedef union {
|
|||||||
uint32 config_index;
|
uint32 config_index;
|
||||||
} config;
|
} config;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
status_t status;
|
||||||
|
uint32 alternate_info;
|
||||||
|
uint32 config_index;
|
||||||
|
uint32 interface_index;
|
||||||
|
} alternate;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
status_t status;
|
status_t status;
|
||||||
usb_interface_descriptor *descriptor;
|
usb_interface_descriptor *descriptor;
|
||||||
@@ -79,12 +90,11 @@ typedef union {
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
status_t status;
|
status_t status;
|
||||||
uint32 *alternate_count;
|
|
||||||
usb_interface_descriptor *descriptor;
|
usb_interface_descriptor *descriptor;
|
||||||
uint32 config_index;
|
uint32 config_index;
|
||||||
uint32 interface_index;
|
uint32 interface_index;
|
||||||
uint32 alternate_index;
|
uint32 alternate_index;
|
||||||
} alternate;
|
} interface_etc;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
status_t status;
|
status_t status;
|
||||||
@@ -96,10 +106,12 @@ typedef union {
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
status_t status;
|
status_t status;
|
||||||
usb_string_descriptor *descriptor;
|
usb_endpoint_descriptor *descriptor;
|
||||||
uint32 string_index;
|
uint32 config_index;
|
||||||
size_t length;
|
uint32 interface_index;
|
||||||
} string;
|
uint32 alternate_index;
|
||||||
|
uint32 endpoint_index;
|
||||||
|
} endpoint_etc;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
status_t status;
|
status_t status;
|
||||||
@@ -110,6 +122,23 @@ typedef union {
|
|||||||
size_t length;
|
size_t length;
|
||||||
} generic;
|
} generic;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
status_t status;
|
||||||
|
usb_descriptor *descriptor;
|
||||||
|
uint32 config_index;
|
||||||
|
uint32 interface_index;
|
||||||
|
uint32 alternate_index;
|
||||||
|
uint32 generic_index;
|
||||||
|
size_t length;
|
||||||
|
} generic_etc;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
status_t status;
|
||||||
|
usb_string_descriptor *descriptor;
|
||||||
|
uint32 string_index;
|
||||||
|
size_t length;
|
||||||
|
} string;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
status_t status;
|
status_t status;
|
||||||
uint8 type;
|
uint8 type;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2007, Haiku Inc. All rights reserved.
|
* Copyright 2007-2008, Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <usb_raw.h>
|
#include <usb_raw.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
|
||||||
BUSBConfiguration::BUSBConfiguration(BUSBDevice *device, uint32 index, int rawFD)
|
BUSBConfiguration::BUSBConfiguration(BUSBDevice *device, uint32 index, int rawFD)
|
||||||
@@ -26,19 +27,27 @@ BUSBConfiguration::BUSBConfiguration(BUSBDevice *device, uint32 index, int rawFD
|
|||||||
sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS)
|
sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS)
|
||||||
memset(&fDescriptor, 0, sizeof(fDescriptor));
|
memset(&fDescriptor, 0, sizeof(fDescriptor));
|
||||||
|
|
||||||
fInterfaces = new BUSBInterface *[fDescriptor.number_interfaces];
|
fInterfaces = new(std::nothrow) BUSBInterface *[
|
||||||
for (uint32 i = 0; i < fDescriptor.number_interfaces; i++)
|
fDescriptor.number_interfaces];
|
||||||
fInterfaces[i] = new BUSBInterface(this, i, fRawFD);
|
if (fInterfaces == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < fDescriptor.number_interfaces; i++) {
|
||||||
|
fInterfaces[i] = new(std::nothrow) BUSBInterface(this, i,
|
||||||
|
B_USB_RAW_ACTIVE_ALTERNATE, fRawFD);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BUSBConfiguration::~BUSBConfiguration()
|
BUSBConfiguration::~BUSBConfiguration()
|
||||||
{
|
{
|
||||||
delete[] fConfigurationString;
|
delete[] fConfigurationString;
|
||||||
|
if (fInterfaces != NULL) {
|
||||||
for (int32 i = 0; i < fDescriptor.number_interfaces; i++)
|
for (int32 i = 0; i < fDescriptor.number_interfaces; i++)
|
||||||
delete fInterfaces[i];
|
delete fInterfaces[i];
|
||||||
delete[] fInterfaces;
|
delete[] fInterfaces;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
@@ -64,11 +73,10 @@ BUSBConfiguration::ConfigurationString() const
|
|||||||
if (fConfigurationString)
|
if (fConfigurationString)
|
||||||
return fConfigurationString;
|
return fConfigurationString;
|
||||||
|
|
||||||
fConfigurationString = Device()->DecodeStringDescriptor(fDescriptor.configuration);
|
fConfigurationString = Device()->DecodeStringDescriptor(
|
||||||
if (!fConfigurationString) {
|
fDescriptor.configuration);
|
||||||
fConfigurationString = new char[1];
|
if (fConfigurationString == NULL)
|
||||||
fConfigurationString[0] = 0;
|
return "";
|
||||||
}
|
|
||||||
|
|
||||||
return fConfigurationString;
|
return fConfigurationString;
|
||||||
}
|
}
|
||||||
@@ -91,7 +99,7 @@ BUSBConfiguration::CountInterfaces() const
|
|||||||
const BUSBInterface *
|
const BUSBInterface *
|
||||||
BUSBConfiguration::InterfaceAt(uint32 index) const
|
BUSBConfiguration::InterfaceAt(uint32 index) const
|
||||||
{
|
{
|
||||||
if (index >= fDescriptor.number_interfaces)
|
if (index >= fDescriptor.number_interfaces || fInterfaces == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return fInterfaces[index];
|
return fInterfaces[index];
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2007, Haiku Inc. All rights reserved.
|
* Copyright 2007-2008, Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -8,9 +8,10 @@
|
|||||||
|
|
||||||
#include <USBKit.h>
|
#include <USBKit.h>
|
||||||
#include <usb_raw.h>
|
#include <usb_raw.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <malloc.h>
|
#include <new>
|
||||||
|
|
||||||
|
|
||||||
BUSBDevice::BUSBDevice(const char *path)
|
BUSBDevice::BUSBDevice(const char *path)
|
||||||
@@ -69,9 +70,15 @@ BUSBDevice::SetTo(const char *path)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fConfigurations = new BUSBConfiguration *[fDescriptor.num_configurations];
|
fConfigurations = new(std::nothrow) BUSBConfiguration *[
|
||||||
for (uint32 i = 0; i < fDescriptor.num_configurations; i++)
|
fDescriptor.num_configurations];
|
||||||
fConfigurations[i] = new BUSBConfiguration(this, i, fRawFD);
|
if (fConfigurations == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < fDescriptor.num_configurations; i++) {
|
||||||
|
fConfigurations[i] = new(std::nothrow) BUSBConfiguration(this, i,
|
||||||
|
fRawFD);
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -92,10 +99,14 @@ BUSBDevice::Unset()
|
|||||||
delete[] fSerialNumberString;
|
delete[] fSerialNumberString;
|
||||||
fManufacturerString = fProductString = fSerialNumberString = NULL;
|
fManufacturerString = fProductString = fSerialNumberString = NULL;
|
||||||
|
|
||||||
|
if (fConfigurations != NULL) {
|
||||||
for (int32 i = 0; i < fDescriptor.num_configurations; i++)
|
for (int32 i = 0; i < fDescriptor.num_configurations; i++)
|
||||||
delete fConfigurations[i];
|
delete fConfigurations[i];
|
||||||
|
|
||||||
delete[] fConfigurations;
|
delete[] fConfigurations;
|
||||||
|
fConfigurations = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&fDescriptor, 0, sizeof(fDescriptor));
|
memset(&fDescriptor, 0, sizeof(fDescriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,10 +194,8 @@ BUSBDevice::ManufacturerString() const
|
|||||||
return fManufacturerString;
|
return fManufacturerString;
|
||||||
|
|
||||||
fManufacturerString = DecodeStringDescriptor(fDescriptor.manufacturer);
|
fManufacturerString = DecodeStringDescriptor(fDescriptor.manufacturer);
|
||||||
if (!fManufacturerString) {
|
if (fManufacturerString == NULL)
|
||||||
fManufacturerString = new char[1];
|
return "";
|
||||||
fManufacturerString[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fManufacturerString;
|
return fManufacturerString;
|
||||||
}
|
}
|
||||||
@@ -202,10 +211,8 @@ BUSBDevice::ProductString() const
|
|||||||
return fProductString;
|
return fProductString;
|
||||||
|
|
||||||
fProductString = DecodeStringDescriptor(fDescriptor.product);
|
fProductString = DecodeStringDescriptor(fDescriptor.product);
|
||||||
if (!fProductString) {
|
if (fProductString == NULL)
|
||||||
fProductString = new char[1];
|
return "";
|
||||||
fProductString[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fProductString;
|
return fProductString;
|
||||||
}
|
}
|
||||||
@@ -221,10 +228,8 @@ BUSBDevice::SerialNumberString() const
|
|||||||
return fSerialNumberString;
|
return fSerialNumberString;
|
||||||
|
|
||||||
fSerialNumberString = DecodeStringDescriptor(fDescriptor.serial_number);
|
fSerialNumberString = DecodeStringDescriptor(fDescriptor.serial_number);
|
||||||
if (!fSerialNumberString) {
|
if (fSerialNumberString == NULL)
|
||||||
fSerialNumberString = new char[1];
|
return "";
|
||||||
fSerialNumberString[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fSerialNumberString;
|
return fSerialNumberString;
|
||||||
}
|
}
|
||||||
@@ -272,7 +277,10 @@ BUSBDevice::DecodeStringDescriptor(uint32 index) const
|
|||||||
|
|
||||||
// pseudo convert unicode string
|
// pseudo convert unicode string
|
||||||
stringLength = (stringLength - 2) / 2;
|
stringLength = (stringLength - 2) / 2;
|
||||||
char *result = new char[stringLength + 1];
|
char *result = new(std::nothrow) char[stringLength + 1];
|
||||||
|
if (result == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
for (size_t i = 0; i < stringLength; i++)
|
for (size_t i = 0; i < stringLength; i++)
|
||||||
result[i] = stringDescriptor->string[i * 2];
|
result[i] = stringDescriptor->string[i * 2];
|
||||||
result[stringLength] = 0;
|
result[stringLength] = 0;
|
||||||
@@ -312,7 +320,7 @@ BUSBDevice::CountConfigurations() const
|
|||||||
const BUSBConfiguration *
|
const BUSBConfiguration *
|
||||||
BUSBDevice::ConfigurationAt(uint32 index) const
|
BUSBDevice::ConfigurationAt(uint32 index) const
|
||||||
{
|
{
|
||||||
if (index >= fDescriptor.num_configurations)
|
if (index >= fDescriptor.num_configurations && fConfigurations != NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return fConfigurations[index];
|
return fConfigurations[index];
|
||||||
@@ -322,6 +330,9 @@ BUSBDevice::ConfigurationAt(uint32 index) const
|
|||||||
const BUSBConfiguration *
|
const BUSBConfiguration *
|
||||||
BUSBDevice::ActiveConfiguration() const
|
BUSBDevice::ActiveConfiguration() const
|
||||||
{
|
{
|
||||||
|
if (fConfigurations == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return fConfigurations[fActiveConfiguration];
|
return fConfigurations[fActiveConfiguration];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2007, Haiku Inc. All rights reserved.
|
* Copyright 2007-2008, Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -18,11 +18,12 @@ BUSBEndpoint::BUSBEndpoint(BUSBInterface *interface, uint32 index, int rawFD)
|
|||||||
fRawFD(rawFD)
|
fRawFD(rawFD)
|
||||||
{
|
{
|
||||||
usb_raw_command command;
|
usb_raw_command command;
|
||||||
command.endpoint.descriptor = &fDescriptor;
|
command.endpoint_etc.descriptor = &fDescriptor;
|
||||||
command.endpoint.config_index = fInterface->Configuration()->Index();
|
command.endpoint_etc.config_index = fInterface->Configuration()->Index();
|
||||||
command.endpoint.interface_index = fInterface->Index();
|
command.endpoint_etc.interface_index = fInterface->Index();
|
||||||
command.endpoint.endpoint_index = fIndex;
|
command.endpoint_etc.alternate_index = fInterface->AlternateIndex();
|
||||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR, &command,
|
command.endpoint_etc.endpoint_index = fIndex;
|
||||||
|
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC, &command,
|
||||||
sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS)
|
sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS)
|
||||||
memset(&fDescriptor, 0, sizeof(fDescriptor));
|
memset(&fDescriptor, 0, sizeof(fDescriptor));
|
||||||
}
|
}
|
||||||
@@ -64,42 +65,48 @@ BUSBEndpoint::Device() const
|
|||||||
bool
|
bool
|
||||||
BUSBEndpoint::IsBulk() const
|
BUSBEndpoint::IsBulk() const
|
||||||
{
|
{
|
||||||
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_BULK;
|
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK)
|
||||||
|
== USB_ENDPOINT_ATTR_BULK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BUSBEndpoint::IsInterrupt() const
|
BUSBEndpoint::IsInterrupt() const
|
||||||
{
|
{
|
||||||
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_INTERRUPT;
|
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK)
|
||||||
|
== USB_ENDPOINT_ATTR_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BUSBEndpoint::IsIsochronous() const
|
BUSBEndpoint::IsIsochronous() const
|
||||||
{
|
{
|
||||||
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_ISOCHRONOUS;
|
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK)
|
||||||
|
== USB_ENDPOINT_ATTR_ISOCHRONOUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BUSBEndpoint::IsControl() const
|
BUSBEndpoint::IsControl() const
|
||||||
{
|
{
|
||||||
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_CONTROL;
|
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK)
|
||||||
|
== USB_ENDPOINT_ATTR_CONTROL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BUSBEndpoint::IsInput() const
|
BUSBEndpoint::IsInput() const
|
||||||
{
|
{
|
||||||
return (fDescriptor.endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) == USB_ENDPOINT_ADDR_DIR_IN;
|
return (fDescriptor.endpoint_address & USB_ENDPOINT_ADDR_DIR_IN)
|
||||||
|
== USB_ENDPOINT_ADDR_DIR_IN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BUSBEndpoint::IsOutput() const
|
BUSBEndpoint::IsOutput() const
|
||||||
{
|
{
|
||||||
return (fDescriptor.endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) == USB_ENDPOINT_ADDR_DIR_OUT;
|
return (fDescriptor.endpoint_address & USB_ENDPOINT_ADDR_DIR_IN)
|
||||||
|
== USB_ENDPOINT_ADDR_DIR_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,11 +15,15 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
BUSBInterface::BUSBInterface(BUSBConfiguration *config, uint32 index, int rawFD)
|
BUSBInterface::BUSBInterface(BUSBConfiguration *config, uint32 index,
|
||||||
|
uint32 alternate, int rawFD)
|
||||||
: fConfiguration(config),
|
: fConfiguration(config),
|
||||||
fIndex(index),
|
fIndex(index),
|
||||||
|
fAlternate(alternate),
|
||||||
fRawFD(rawFD),
|
fRawFD(rawFD),
|
||||||
fEndpoints(NULL),
|
fEndpoints(NULL),
|
||||||
|
fAlternateCount(0),
|
||||||
|
fAlternates(NULL),
|
||||||
fInterfaceString(NULL)
|
fInterfaceString(NULL)
|
||||||
{
|
{
|
||||||
_UpdateDescriptorAndEndpoints();
|
_UpdateDescriptorAndEndpoints();
|
||||||
@@ -29,11 +33,20 @@ BUSBInterface::BUSBInterface(BUSBConfiguration *config, uint32 index, int rawFD)
|
|||||||
BUSBInterface::~BUSBInterface()
|
BUSBInterface::~BUSBInterface()
|
||||||
{
|
{
|
||||||
delete[] fInterfaceString;
|
delete[] fInterfaceString;
|
||||||
|
|
||||||
|
if (fEndpoints != NULL) {
|
||||||
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
|
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
|
||||||
delete fEndpoints[i];
|
delete fEndpoints[i];
|
||||||
delete[] fEndpoints;
|
delete[] fEndpoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fAlternates != NULL) {
|
||||||
|
for (uint32 i = 0; i < fAlternateCount; i++)
|
||||||
|
delete fAlternates[i];
|
||||||
|
delete[] fAlternates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
BUSBInterface::Index() const
|
BUSBInterface::Index() const
|
||||||
@@ -42,6 +55,15 @@ BUSBInterface::Index() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
BUSBInterface::AlternateIndex() const
|
||||||
|
{
|
||||||
|
if (fAlternate == B_USB_RAW_ACTIVE_ALTERNATE)
|
||||||
|
return ActiveAlternateIndex();
|
||||||
|
return fAlternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const BUSBConfiguration *
|
const BUSBConfiguration *
|
||||||
BUSBInterface::Configuration() const
|
BUSBInterface::Configuration() const
|
||||||
{
|
{
|
||||||
@@ -87,10 +109,8 @@ BUSBInterface::InterfaceString() const
|
|||||||
return fInterfaceString;
|
return fInterfaceString;
|
||||||
|
|
||||||
fInterfaceString = Device()->DecodeStringDescriptor(fDescriptor.interface);
|
fInterfaceString = Device()->DecodeStringDescriptor(fDescriptor.interface);
|
||||||
if (!fInterfaceString) {
|
if (fInterfaceString == NULL)
|
||||||
fInterfaceString = new char[1];
|
return "";
|
||||||
fInterfaceString[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fInterfaceString;
|
return fInterfaceString;
|
||||||
}
|
}
|
||||||
@@ -111,11 +131,12 @@ BUSBInterface::OtherDescriptorAt(uint32 index, usb_descriptor *descriptor,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
usb_raw_command command;
|
usb_raw_command command;
|
||||||
command.generic.descriptor = descriptor;
|
command.generic_etc.descriptor = descriptor;
|
||||||
command.generic.config_index = fConfiguration->Index();
|
command.generic_etc.config_index = fConfiguration->Index();
|
||||||
command.generic.interface_index = fIndex;
|
command.generic_etc.interface_index = fIndex;
|
||||||
command.generic.length = length;
|
command.generic_etc.alternate_index = fAlternate;
|
||||||
command.generic.generic_index = index;
|
command.generic_etc.generic_index = index;
|
||||||
|
command.generic_etc.length = length;
|
||||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR, &command,
|
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR, &command,
|
||||||
sizeof(command)) || command.generic.status != B_USB_RAW_STATUS_SUCCESS)
|
sizeof(command)) || command.generic.status != B_USB_RAW_STATUS_SUCCESS)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -134,7 +155,7 @@ BUSBInterface::CountEndpoints() const
|
|||||||
const BUSBEndpoint *
|
const BUSBEndpoint *
|
||||||
BUSBInterface::EndpointAt(uint32 index) const
|
BUSBInterface::EndpointAt(uint32 index) const
|
||||||
{
|
{
|
||||||
if (index >= fDescriptor.num_endpoints)
|
if (index >= fDescriptor.num_endpoints && fEndpoints != NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return fEndpoints[index];
|
return fEndpoints[index];
|
||||||
@@ -144,39 +165,56 @@ BUSBInterface::EndpointAt(uint32 index) const
|
|||||||
uint32
|
uint32
|
||||||
BUSBInterface::CountAlternates() const
|
BUSBInterface::CountAlternates() const
|
||||||
{
|
{
|
||||||
uint32 alternateCount;
|
|
||||||
usb_raw_command command;
|
usb_raw_command command;
|
||||||
command.alternate.alternate_count = &alternateCount;
|
|
||||||
command.alternate.config_index = fConfiguration->Index();
|
command.alternate.config_index = fConfiguration->Index();
|
||||||
command.alternate.interface_index = fIndex;
|
command.alternate.interface_index = fIndex;
|
||||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT, &command,
|
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT, &command,
|
||||||
sizeof(command)) || command.alternate.status != B_USB_RAW_STATUS_SUCCESS)
|
sizeof(command)) || command.alternate.status != B_USB_RAW_STATUS_SUCCESS)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return alternateCount;
|
return command.alternate.alternate_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
usb_interface_descriptor *
|
const BUSBInterface *
|
||||||
BUSBInterface::AlternateAt(uint32 alternateIndex)
|
BUSBInterface::AlternateAt(uint32 alternateIndex) const
|
||||||
{
|
{
|
||||||
usb_interface_descriptor *descriptor
|
if (fAlternateCount > 0 && fAlternates != NULL) {
|
||||||
= new(std::nothrow) usb_interface_descriptor;
|
if (alternateIndex >= fAlternateCount)
|
||||||
if (descriptor == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
return fAlternates[alternateIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fAlternateCount == 0)
|
||||||
|
fAlternateCount = CountAlternates();
|
||||||
|
if (alternateIndex >= fAlternateCount)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fAlternates = new(std::nothrow) BUSBInterface *[fAlternateCount];
|
||||||
|
if (fAlternates == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < fAlternateCount; i++) {
|
||||||
|
fAlternates[i] = new(std::nothrow) BUSBInterface(fConfiguration, fIndex,
|
||||||
|
i, fRawFD);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fAlternates[alternateIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
BUSBInterface::ActiveAlternateIndex() const
|
||||||
|
{
|
||||||
usb_raw_command command;
|
usb_raw_command command;
|
||||||
command.alternate.descriptor = descriptor;
|
|
||||||
command.alternate.config_index = fConfiguration->Index();
|
command.alternate.config_index = fConfiguration->Index();
|
||||||
command.alternate.interface_index = fIndex;
|
command.alternate.interface_index = fIndex;
|
||||||
command.alternate.alternate_index = alternateIndex;
|
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX, &command,
|
||||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ALT_INTERFACE_DESCRIPTOR, &command,
|
sizeof(command)) || command.alternate.status != B_USB_RAW_STATUS_SUCCESS)
|
||||||
sizeof(command)) || command.alternate.status != B_USB_RAW_STATUS_SUCCESS) {
|
return 0;
|
||||||
delete descriptor;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return descriptor;
|
return command.alternate.alternate_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -184,9 +222,9 @@ status_t
|
|||||||
BUSBInterface::SetAlternate(uint32 alternateIndex)
|
BUSBInterface::SetAlternate(uint32 alternateIndex)
|
||||||
{
|
{
|
||||||
usb_raw_command command;
|
usb_raw_command command;
|
||||||
|
command.alternate.alternate_info = alternateIndex;
|
||||||
command.alternate.config_index = fConfiguration->Index();
|
command.alternate.config_index = fConfiguration->Index();
|
||||||
command.alternate.interface_index = fIndex;
|
command.alternate.interface_index = fIndex;
|
||||||
command.alternate.alternate_index = alternateIndex;
|
|
||||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_ALT_INTERFACE, &command,
|
if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_ALT_INTERFACE, &command,
|
||||||
sizeof(command)) || command.alternate.status != B_USB_RAW_STATUS_SUCCESS)
|
sizeof(command)) || command.alternate.status != B_USB_RAW_STATUS_SUCCESS)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -200,21 +238,25 @@ void
|
|||||||
BUSBInterface::_UpdateDescriptorAndEndpoints()
|
BUSBInterface::_UpdateDescriptorAndEndpoints()
|
||||||
{
|
{
|
||||||
usb_raw_command command;
|
usb_raw_command command;
|
||||||
command.interface.descriptor = &fDescriptor;
|
command.interface_etc.descriptor = &fDescriptor;
|
||||||
command.interface.config_index = fConfiguration->Index();
|
command.interface_etc.config_index = fConfiguration->Index();
|
||||||
command.interface.interface_index = fIndex;
|
command.interface_etc.interface_index = fIndex;
|
||||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR, &command,
|
command.interface_etc.alternate_index = fAlternate;
|
||||||
|
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC, &command,
|
||||||
sizeof(command)) || command.interface.status != B_USB_RAW_STATUS_SUCCESS)
|
sizeof(command)) || command.interface.status != B_USB_RAW_STATUS_SUCCESS)
|
||||||
memset(&fDescriptor, 0, sizeof(fDescriptor));
|
memset(&fDescriptor, 0, sizeof(fDescriptor));
|
||||||
|
|
||||||
if (fEndpoints) {
|
if (fEndpoints != NULL) {
|
||||||
// Delete old endpoints
|
// Delete old endpoints
|
||||||
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
|
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
|
||||||
delete fEndpoints[i];
|
delete fEndpoints[i];
|
||||||
delete fEndpoints;
|
delete fEndpoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
fEndpoints = new BUSBEndpoint *[fDescriptor.num_endpoints];
|
fEndpoints = new(std::nothrow) BUSBEndpoint *[fDescriptor.num_endpoints];
|
||||||
|
if (fEndpoints == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
|
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
|
||||||
fEndpoints[i] = new BUSBEndpoint(this, i, fRawFD);
|
fEndpoints[i] = new(std::nothrow) BUSBEndpoint(this, i, fRawFD);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2007, Haiku Inc. All rights reserved.
|
* Copyright 2007-2008, Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
|
||||||
class WatchedEntry {
|
class WatchedEntry {
|
||||||
@@ -75,7 +76,11 @@ WatchedEntry::WatchedEntry(BUSBRoster *roster, BMessenger *messenger,
|
|||||||
if (entry.GetRef(ref) < B_OK)
|
if (entry.GetRef(ref) < B_OK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
WatchedEntry *child = new WatchedEntry(fRoster, fMessenger, ref);
|
WatchedEntry *child = new(std::nothrow) WatchedEntry(fRoster,
|
||||||
|
fMessenger, ref);
|
||||||
|
if (child == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
child->fLink = fEntries;
|
child->fLink = fEntries;
|
||||||
fEntries = child;
|
fEntries = child;
|
||||||
}
|
}
|
||||||
@@ -88,13 +93,15 @@ WatchedEntry::WatchedEntry(BUSBRoster *roster, BMessenger *messenger,
|
|||||||
|
|
||||||
BPath path;
|
BPath path;
|
||||||
entry.GetPath(&path);
|
entry.GetPath(&path);
|
||||||
fDevice = new BUSBDevice(path.Path());
|
fDevice = new(std::nothrow) BUSBDevice(path.Path());
|
||||||
|
if (fDevice != NULL) {
|
||||||
if (fRoster->DeviceAdded(fDevice) != B_OK) {
|
if (fRoster->DeviceAdded(fDevice) != B_OK) {
|
||||||
delete fDevice;
|
delete fDevice;
|
||||||
fDevice = NULL;
|
fDevice = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WatchedEntry::~WatchedEntry()
|
WatchedEntry::~WatchedEntry()
|
||||||
@@ -132,7 +139,11 @@ WatchedEntry::EntryCreated(entry_ref *ref)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
WatchedEntry *child = new WatchedEntry(fRoster, fMessenger, ref);
|
WatchedEntry *child = new(std::nothrow) WatchedEntry(fRoster, fMessenger,
|
||||||
|
ref);
|
||||||
|
if (child == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
child->fLink = fEntries;
|
child->fLink = fEntries;
|
||||||
fEntries = child;
|
fEntries = child;
|
||||||
return true;
|
return true;
|
||||||
@@ -181,12 +192,14 @@ RosterLooper::RosterLooper(BUSBRoster *roster)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Run();
|
Run();
|
||||||
fMessenger = new BMessenger(this);
|
fMessenger = new(std::nothrow) BMessenger(this);
|
||||||
|
if (fMessenger == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
entry_ref ref;
|
entry_ref ref;
|
||||||
entry.GetRef(&ref);
|
entry.GetRef(&ref);
|
||||||
fRoot = new WatchedEntry(fRoster, fMessenger, &ref);
|
fRoot = new(std::nothrow) WatchedEntry(fRoster, fMessenger, &ref);
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,7 +266,7 @@ BUSBRoster::Start()
|
|||||||
if (fLooper)
|
if (fLooper)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fLooper = new RosterLooper(this);
|
fLooper = new(std::nothrow) RosterLooper(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user