1/*
2 * Copyright 2007-2008, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Michael Lotz <mmlr@mlotz.ch>
7 */
8
9#include <USBKit.h>
10#include <usb_raw.h>
11#include <unistd.h>
12#include <string.h>
13#include <new>
14
15
16BUSBConfiguration::BUSBConfiguration(BUSBDevice *device, uint32 index, int rawFD)
17	:	fDevice(device),
18		fIndex(index),
19		fRawFD(rawFD),
20		fInterfaces(NULL),
21		fConfigurationString(NULL)
22{
23	usb_raw_command command;
24	command.config.descriptor = &fDescriptor;
25	command.config.config_index = fIndex;
26	if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR, &command,
27		sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS)
28		memset(&fDescriptor, 0, sizeof(fDescriptor));
29
30	fInterfaces = new(std::nothrow) BUSBInterface *[
31		fDescriptor.number_interfaces];
32	if (fInterfaces == NULL)
33		return;
34
35	for (uint32 i = 0; i < fDescriptor.number_interfaces; i++) {
36		fInterfaces[i] = new(std::nothrow) BUSBInterface(this, i,
37			B_USB_RAW_ACTIVE_ALTERNATE, fRawFD);
38	}
39}
40
41
42BUSBConfiguration::~BUSBConfiguration()
43{
44	delete[] fConfigurationString;
45	if (fInterfaces != NULL) {
46		for (int32 i = 0; i < fDescriptor.number_interfaces; i++)
47			delete fInterfaces[i];
48		delete[] fInterfaces;
49	}
50}
51
52
53uint32
54BUSBConfiguration::Index() const
55{
56	return fIndex;
57}
58
59
60const BUSBDevice *
61BUSBConfiguration::Device() const
62{
63	return fDevice;
64}
65
66
67const char *
68BUSBConfiguration::ConfigurationString() const
69{
70	if (fDescriptor.configuration == 0)
71		return "";
72
73	if (fConfigurationString)
74		return fConfigurationString;
75
76	fConfigurationString = Device()->DecodeStringDescriptor(
77		fDescriptor.configuration);
78	if (fConfigurationString == NULL)
79		return "";
80
81	return fConfigurationString;
82}
83
84
85const usb_configuration_descriptor *
86BUSBConfiguration::Descriptor() const
87{
88	return &fDescriptor;
89}
90
91
92uint32
93BUSBConfiguration::CountInterfaces() const
94{
95	return fDescriptor.number_interfaces;
96}
97
98
99const BUSBInterface *
100BUSBConfiguration::InterfaceAt(uint32 index) const
101{
102	if (index >= fDescriptor.number_interfaces || fInterfaces == NULL)
103		return NULL;
104
105	return fInterfaces[index];
106}
107