2 * Copyright 2007-2008, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Michael Lotz <mmlr@mlotz.ch>
7 * Salvatore Benedetto <salvatore.benedetto@gmail.com>
18 BUSBInterface::BUSBInterface(BUSBConfiguration
*config
, uint32 index
,
19 uint32 alternate
, int rawFD
)
20 : fConfiguration(config
),
22 fAlternate(alternate
),
27 fInterfaceString(NULL
)
29 _UpdateDescriptorAndEndpoints();
33 BUSBInterface::~BUSBInterface()
35 delete[] fInterfaceString
;
37 if (fEndpoints
!= NULL
) {
38 for (int32 i
= 0; i
< fDescriptor
.num_endpoints
; i
++)
43 if (fAlternates
!= NULL
) {
44 for (uint32 i
= 0; i
< fAlternateCount
; i
++)
45 delete fAlternates
[i
];
52 BUSBInterface::Index() const
59 BUSBInterface::AlternateIndex() const
61 if (fAlternate
== B_USB_RAW_ACTIVE_ALTERNATE
)
62 return ActiveAlternateIndex();
67 const BUSBConfiguration
*
68 BUSBInterface::Configuration() const
70 return fConfiguration
;
75 BUSBInterface::Device() const
77 return fConfiguration
->Device();
82 BUSBInterface::Class() const
84 return fDescriptor
.interface_class
;
89 BUSBInterface::Subclass() const
91 return fDescriptor
.interface_subclass
;
96 BUSBInterface::Protocol() const
98 return fDescriptor
.interface_protocol
;
103 BUSBInterface::InterfaceString() const
105 if (fDescriptor
.interface
== 0)
108 if (fInterfaceString
)
109 return fInterfaceString
;
111 fInterfaceString
= Device()->DecodeStringDescriptor(fDescriptor
.interface
);
112 if (fInterfaceString
== NULL
)
115 return fInterfaceString
;
119 const usb_interface_descriptor
*
120 BUSBInterface::Descriptor() const
127 BUSBInterface::OtherDescriptorAt(uint32 index
, usb_descriptor
*descriptor
,
130 if (length
<= 0 || descriptor
== NULL
)
133 usb_raw_command command
;
134 command
.generic_etc
.descriptor
= descriptor
;
135 command
.generic_etc
.config_index
= fConfiguration
->Index();
136 command
.generic_etc
.interface_index
= fIndex
;
137 command
.generic_etc
.alternate_index
= fAlternate
;
138 command
.generic_etc
.generic_index
= index
;
139 command
.generic_etc
.length
= length
;
140 if (ioctl(fRawFD
, B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR_ETC
, &command
,
141 sizeof(command
)) || command
.generic
.status
!= B_USB_RAW_STATUS_SUCCESS
)
149 BUSBInterface::CountEndpoints() const
151 return fDescriptor
.num_endpoints
;
156 BUSBInterface::EndpointAt(uint32 index
) const
158 if (index
>= fDescriptor
.num_endpoints
|| fEndpoints
== NULL
)
161 return fEndpoints
[index
];
166 BUSBInterface::CountAlternates() const
168 usb_raw_command command
;
169 command
.alternate
.config_index
= fConfiguration
->Index();
170 command
.alternate
.interface_index
= fIndex
;
171 if (ioctl(fRawFD
, B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT
, &command
,
172 sizeof(command
)) || command
.alternate
.status
!= B_USB_RAW_STATUS_SUCCESS
)
175 return command
.alternate
.alternate_info
;
179 const BUSBInterface
*
180 BUSBInterface::AlternateAt(uint32 alternateIndex
) const
182 if (fAlternateCount
> 0 && fAlternates
!= NULL
) {
183 if (alternateIndex
>= fAlternateCount
)
186 return fAlternates
[alternateIndex
];
189 if (fAlternateCount
== 0)
190 fAlternateCount
= CountAlternates();
191 if (alternateIndex
>= fAlternateCount
)
194 fAlternates
= new(std::nothrow
) BUSBInterface
*[fAlternateCount
];
195 if (fAlternates
== NULL
)
198 for (uint32 i
= 0; i
< fAlternateCount
; i
++) {
199 fAlternates
[i
] = new(std::nothrow
) BUSBInterface(fConfiguration
, fIndex
,
203 return fAlternates
[alternateIndex
];
208 BUSBInterface::ActiveAlternateIndex() const
210 usb_raw_command command
;
211 command
.alternate
.config_index
= fConfiguration
->Index();
212 command
.alternate
.interface_index
= fIndex
;
213 if (ioctl(fRawFD
, B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX
, &command
,
214 sizeof(command
)) || command
.alternate
.status
!= B_USB_RAW_STATUS_SUCCESS
)
217 return command
.alternate
.alternate_info
;
222 BUSBInterface::SetAlternate(uint32 alternateIndex
)
224 usb_raw_command command
;
225 command
.alternate
.alternate_info
= alternateIndex
;
226 command
.alternate
.config_index
= fConfiguration
->Index();
227 command
.alternate
.interface_index
= fIndex
;
228 if (ioctl(fRawFD
, B_USB_RAW_COMMAND_SET_ALT_INTERFACE
, &command
,
229 sizeof(command
)) || command
.alternate
.status
!= B_USB_RAW_STATUS_SUCCESS
)
232 _UpdateDescriptorAndEndpoints();
238 BUSBInterface::_UpdateDescriptorAndEndpoints()
240 usb_raw_command command
;
241 command
.interface_etc
.descriptor
= &fDescriptor
;
242 command
.interface_etc
.config_index
= fConfiguration
->Index();
243 command
.interface_etc
.interface_index
= fIndex
;
244 command
.interface_etc
.alternate_index
= fAlternate
;
245 if (ioctl(fRawFD
, B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC
, &command
,
246 sizeof(command
)) || command
.interface
.status
!= B_USB_RAW_STATUS_SUCCESS
)
247 memset(&fDescriptor
, 0, sizeof(fDescriptor
));
249 if (fEndpoints
!= NULL
) {
250 // Delete old endpoints
251 for (int32 i
= 0; i
< fDescriptor
.num_endpoints
; i
++)
252 delete fEndpoints
[i
];
256 fEndpoints
= new(std::nothrow
) BUSBEndpoint
*[fDescriptor
.num_endpoints
];
257 if (fEndpoints
== NULL
)
260 for (int32 i
= 0; i
< fDescriptor
.num_endpoints
; i
++)
261 fEndpoints
[i
] = new(std::nothrow
) BUSBEndpoint(this, i
, fRawFD
);