int hu_aap_stop () { // Sends Byebye, then stops USB/ACC/OAP // Send Byebye iaap_state = hu_STATE_STOPPIN; logd (" SET: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); int ret = hu_usb_stop (); // Stop USB/ACC/OAP iaap_state = hu_STATE_STOPPED; logd (" SET: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); return (ret); }
int iusb_bulk_transfer (int ep, byte * buf, int len, int tmo) { // 0 = unlimited timeout char * dir = "recv"; if (ep == iusb_ep_out) dir = "send"; if (iusb_state != hu_STATE_STARTED) { logd ("CHECK: iusb_bulk_transfer start iusb_state: %d (%s) dir: %s ep: 0x%02x buf: %p len: %d tmo: %d", iusb_state, state_get (iusb_state), dir, ep, buf, len, tmo); return (-1); } if (ena_log_extra) { logd ("Start dir: %s ep: 0x%02x buf: %p len: %d tmo: %d", dir, ep, buf, len, tmo); } #ifndef NDEBUG if (ena_log_send && ep == iusb_ep_out) hex_dump ("US: ", 16, buf, len); #endif int usb_err = -2; int total_bytes_xfrd = 0; int bytes_xfrd = 0; // You should also check the transferred parameter for bulk writes. Not all of the data may have been written. // Also check transferred when dealing with a timeout error code. libusb may have to split your transfer into a number of chunks to satisfy underlying O/S requirements, // meaning that the timeout may expire after the first few chunks have completed. libusb is careful not to lose any data that may have been transferred; // do not assume that timeout conditions indicate a complete lack of I/O. errno = 0; int continue_transfer = 1; while (continue_transfer) { usb_err = libusb_bulk_transfer (iusb_dev_hndl, ep, buf, len, & bytes_xfrd, tmo); continue_transfer = 0; if (bytes_xfrd > 0) total_bytes_xfrd += bytes_xfrd; if (bytes_xfrd > 0 && usb_err == LIBUSB_ERROR_TIMEOUT) { continue_transfer = 1; loge ("CONTINUE dir: %s len: %d bytes_xfrd: %d usb_err: %d (%s) errno: %d (%s)", dir, len, bytes_xfrd, usb_err, iusb_error_get (usb_err), errno, strerror (errno)); buf += bytes_xfrd; len -= bytes_xfrd; } else if (usb_err < 0 && usb_err != LIBUSB_ERROR_TIMEOUT) loge ("Done dir: %s len: %d bytes_xfrd: %d usb_err: %d (%s) errno: %d (%s)", dir, len, bytes_xfrd, usb_err, iusb_error_get (usb_err), errno, strerror (errno)); else if (ena_log_verbo && usb_err != LIBUSB_ERROR_TIMEOUT && (ena_log_send || ep == iusb_ep_in)) logd ("Done dir: %s len: %d bytes_xfrd: %d usb_err: %d (%s) errno: %d (%s)", dir, len, bytes_xfrd, usb_err, iusb_error_get (usb_err), errno, strerror (errno)); else if (ena_log_extra) logd ("Done dir: %s len: %d bytes_xfrd: %d usb_err: %d (%s) errno: %d (%s)", dir, len, bytes_xfrd, usb_err, iusb_error_get (usb_err), errno, strerror (errno)); bytes_xfrd = 0; } if (total_bytes_xfrd > 16384) { // Previously caused problems that seem fixed by raising USB Rx buffer from 16K to 64K // Streaming mode by first reading packet length may be better but may also create sync or other issues //loge ("total_bytes_xfrd: %d ???????????????? !!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ?????????????????????????", total_bytes_xfrd); } if (total_bytes_xfrd <= 0 && usb_err < 0) { if (errno == EAGAIN || errno == ETIMEDOUT || usb_err == LIBUSB_ERROR_TIMEOUT) return (0); hu_usb_stop (); // Other errors here are fatal, so stop USB return (-1); } //if (ena_log_verbo) // logd ("Done dir: %s len: %d total_bytes_xfrd: %d", dir, len, total_bytes_xfrd); if (ep == iusb_ep_in) { #ifndef NDEBUG hex_dump ("UR: ", 16, buf, total_bytes_xfrd); #endif } return (total_bytes_xfrd); }