Update README.md
[mfgtools.git] / libuuu / trans.cpp
blobfbda0c8ff8333e55e0e7bbd3b1c848cc2fcc5247
1 /*
2 * Copyright 2018 NXP.
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.
32 #include "trans.h"
33 #include "libcomm.h"
34 #include "libuuu.h"
35 #include "liberror.h"
36 #include "libusb.h"
37 #include "zip.h"
39 extern "C"
41 #include "libusb.h"
44 using namespace std;
46 TransBase::~TransBase()
50 int TransBase::write(void *buff, size_t size)
52 int ret;
54 for (int retry = 0; retry < m_retry; retry++) {
55 ret = write_simple(buff, size);
56 switch (ret) {
57 case 0:
58 return 0;
59 case LIBUSB_ERROR_TIMEOUT:
60 continue;
61 default:
62 return ret;
66 return LIBUSB_ERROR_TIMEOUT;
69 int TransBase::read(void *buff, size_t size, size_t *return_size)
71 int ret;
73 for (int retry = 0; retry < m_retry; retry++) {
74 ret = read_simple(buff, size, return_size);
75 switch (ret) {
76 case 0:
77 return 0;
78 case LIBUSB_ERROR_TIMEOUT:
79 continue;
80 default:
81 return ret;
85 return LIBUSB_ERROR_TIMEOUT;
88 int TransBase::read(vector<uint8_t> &buff)
90 size_t size;
91 const auto ret = read(buff.data(), buff.size(), &size);
92 if (ret)
93 return ret;
94 buff.resize(size);
95 return ret;
98 int USBTrans::open(void *p)
100 m_devhandle = p;
101 string_ex err;
102 int libusb_ret = 0;
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);
113 return libusb_ret;
117 if ((libusb_ret = libusb_claim_interface(handle, 0)))
119 err.format("Failure claim interface (%d)", libusb_ret);
120 set_last_err_string(err);
121 return libusb_ret;
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);
129 return libusb_ret;
132 m_EPs.clear();
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);
141 return 0;
144 int USBTrans::close()
146 /* needn't clean resource here
147 libusb_close will release all resource when finish running cmd
149 return 0;
152 int HIDTrans::open(void *p)
154 int ret;
156 if ((ret = USBTrans::open(p)))
157 return ret;
159 for (const auto &ep : m_EPs)
161 if (ep.addr > 0 && ((ep.addr & 0x80) == 0))
162 m_outEP = ep.addr;
165 return 0;
168 int HIDTrans::write_simple(void *buff, size_t size)
170 int ret;
171 uint8_t *p = (uint8_t *)buff;
172 int actual_size;
174 if (m_outEP)
176 ret = libusb_interrupt_transfer(
177 (libusb_device_handle *)m_devhandle,
178 m_outEP,
180 size,
181 &actual_size,
182 m_timeout
185 else
187 ret = libusb_control_transfer(
188 (libusb_device_handle *)m_devhandle,
189 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
190 m_set_report,
191 (2 << 8) | p[0],
194 size,
195 m_timeout
199 if (ret < 0)
201 string_ex err;
202 err.format("HID(W): %s (%d)", libusb_error_name(ret), ret);
203 set_last_err_string(err);
204 return ret;
207 return ret;
210 int HIDTrans::read_simple(void *buff, size_t size, size_t *rsize)
212 int ret;
213 int actual;
214 ret = libusb_interrupt_transfer(
215 (libusb_device_handle *)m_devhandle,
216 0x81,
217 (uint8_t*)buff,
218 size,
219 &actual,
220 m_timeout
223 *rsize = actual;
225 if (ret < 0)
227 string_ex err;
228 err.format("HID(R): %s (%d)", libusb_error_name(ret), ret);
229 set_last_err_string(err);
230 return ret;
233 return 0;
236 int BulkTrans::write_simple(void *buff, size_t size)
238 int ret = 0;
239 int actual_length;
240 for (size_t i = 0; i < size; i += m_MaxTransPreRequest)
242 uint8_t *p = (uint8_t *)buff;
243 p += i;
244 size_t sz;
245 sz = size - i;
246 if (sz > m_MaxTransPreRequest)
247 sz = m_MaxTransPreRequest;
249 ret = libusb_bulk_transfer(
250 (libusb_device_handle *)m_devhandle,
251 m_ep_out.addr,
254 &actual_length,
255 m_timeout
258 if (ret < 0)
260 string_ex err;
261 err.format("Bulk(W): %s (%d)", libusb_error_name(ret), ret);
262 set_last_err_string(err);
263 return ret;
267 //Send zero package
268 if (m_b_send_zero && ( (size%m_ep_out.package_size) == 0))
270 ret = libusb_bulk_transfer(
271 (libusb_device_handle *)m_devhandle,
272 m_ep_out.addr,
273 nullptr,
275 &actual_length,
276 2000
279 if (ret < 0)
281 string_ex err;
282 err.format("Bulk(W): %s (%d)", libusb_error_name(ret), ret);
283 set_last_err_string(err);
284 return ret;
288 return ret;
291 int BulkTrans::open(void *p)
293 int ret;
295 if ((ret = USBTrans::open(p)))
296 return ret;
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)
303 m_ep_in = m_EPs[i];
304 else if (m_ep_out.addr == 0)
305 m_ep_out = m_EPs[i];
308 return 0;
310 int BulkTrans::read_simple(void *buff, size_t size, size_t *rsize)
312 int ret;
313 int actual_length;
314 uint8_t *p = (uint8_t *)buff;
316 if (size == 0)
318 *rsize = 0;
319 return 0;
322 ret = libusb_bulk_transfer(
323 (libusb_device_handle *)m_devhandle,
324 m_ep_in.addr,
326 size,
327 &actual_length,
328 m_timeout
331 *rsize = actual_length;
333 if (ret < 0)
335 string_ex err;
336 err.format("Bulk(R): %s (%d)", libusb_error_name(ret), ret);
337 set_last_err_string(err);
338 return ret;
341 return ret;