4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice, this
11 * list of conditions and the following disclaimer in the documentation and/or
12 * other materials provided with the distribution.
14 * Neither the name of the NXP Semiconductor nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
46 TransBase::~TransBase()
50 int TransBase::write(void *buff
, size_t size
)
54 for (int retry
= 0; retry
< m_retry
; retry
++) {
55 ret
= write_simple(buff
, size
);
59 case LIBUSB_ERROR_TIMEOUT
:
66 return LIBUSB_ERROR_TIMEOUT
;
69 int TransBase::read(void *buff
, size_t size
, size_t *return_size
)
73 for (int retry
= 0; retry
< m_retry
; retry
++) {
74 ret
= read_simple(buff
, size
, return_size
);
78 case LIBUSB_ERROR_TIMEOUT
:
85 return LIBUSB_ERROR_TIMEOUT
;
88 int TransBase::read(vector
<uint8_t> &buff
)
91 const auto ret
= read(buff
.data(), buff
.size(), &size
);
98 int USBTrans::open(void *p
)
103 libusb_device_handle
* handle
= (libusb_device_handle
*)m_devhandle
;
105 if (libusb_kernel_driver_active(handle
, 0))
107 libusb_ret
= libusb_detach_kernel_driver((libusb_device_handle
*)m_devhandle
, 0);
109 if(libusb_ret
< 0 && libusb_ret
!= LIBUSB_ERROR_NOT_SUPPORTED
)
111 err
.format("detach kernel driver failure (%d)", libusb_ret
);
112 set_last_err_string(err
);
117 if ((libusb_ret
= libusb_claim_interface(handle
, 0)))
119 err
.format("Failure claim interface (%d)", libusb_ret
);
120 set_last_err_string(err
);
124 libusb_config_descriptor
*config
;
125 if ((libusb_ret
= libusb_get_active_config_descriptor(libusb_get_device(handle
), &config
)))
127 err
.format("Can't get config descriptor (%d)", libusb_ret
);
128 set_last_err_string(err
);
133 for (int i
= 0; i
< config
->interface
[0].altsetting
[0].bNumEndpoints
; i
++)
135 m_EPs
.push_back(EPInfo(config
->interface
[0].altsetting
[0].endpoint
[i
].bEndpointAddress
,
136 config
->interface
[0].altsetting
[0].endpoint
[i
].wMaxPacketSize
));
139 libusb_free_config_descriptor(config
);
144 int USBTrans::close()
146 /* needn't clean resource here
147 libusb_close will release all resource when finish running cmd
152 int HIDTrans::open(void *p
)
156 if ((ret
= USBTrans::open(p
)))
159 for (const auto &ep
: m_EPs
)
161 if (ep
.addr
> 0 && ((ep
.addr
& 0x80) == 0))
168 int HIDTrans::write_simple(void *buff
, size_t size
)
171 uint8_t *p
= (uint8_t *)buff
;
176 ret
= libusb_interrupt_transfer(
177 (libusb_device_handle
*)m_devhandle
,
187 ret
= libusb_control_transfer(
188 (libusb_device_handle
*)m_devhandle
,
189 LIBUSB_ENDPOINT_OUT
| LIBUSB_REQUEST_TYPE_CLASS
| LIBUSB_RECIPIENT_INTERFACE
,
202 err
.format("HID(W): %s (%d)", libusb_error_name(ret
), ret
);
203 set_last_err_string(err
);
210 int HIDTrans::read_simple(void *buff
, size_t size
, size_t *rsize
)
214 ret
= libusb_interrupt_transfer(
215 (libusb_device_handle
*)m_devhandle
,
228 err
.format("HID(R): %s (%d)", libusb_error_name(ret
), ret
);
229 set_last_err_string(err
);
236 int BulkTrans::write_simple(void *buff
, size_t size
)
240 for (size_t i
= 0; i
< size
; i
+= m_MaxTransPreRequest
)
242 uint8_t *p
= (uint8_t *)buff
;
246 if (sz
> m_MaxTransPreRequest
)
247 sz
= m_MaxTransPreRequest
;
249 ret
= libusb_bulk_transfer(
250 (libusb_device_handle
*)m_devhandle
,
261 err
.format("Bulk(W): %s (%d)", libusb_error_name(ret
), ret
);
262 set_last_err_string(err
);
268 if (m_b_send_zero
&& ( (size
%m_ep_out
.package_size
) == 0))
270 ret
= libusb_bulk_transfer(
271 (libusb_device_handle
*)m_devhandle
,
282 err
.format("Bulk(W): %s (%d)", libusb_error_name(ret
), ret
);
283 set_last_err_string(err
);
291 int BulkTrans::open(void *p
)
295 if ((ret
= USBTrans::open(p
)))
298 for (size_t i
= 0; i
< m_EPs
.size(); i
++)
300 if (m_EPs
[i
].addr
> 0)
302 if ((m_EPs
[0].addr
& 0x80) && m_ep_in
.addr
== 0)
304 else if (m_ep_out
.addr
== 0)
310 int BulkTrans::read_simple(void *buff
, size_t size
, size_t *rsize
)
314 uint8_t *p
= (uint8_t *)buff
;
322 ret
= libusb_bulk_transfer(
323 (libusb_device_handle
*)m_devhandle
,
331 *rsize
= actual_length
;
336 err
.format("Bulk(R): %s (%d)", libusb_error_name(ret
), ret
);
337 set_last_err_string(err
);