Ejemplo n.º 1
0
 def _finish(self, command, do_wait=True):
     buffer = None
     cbk_fn, setup_packet, _ = command
     length_transferred = c_ulong()
     rc = WinUsb_GetOverlappedResult(self._winusb, self._overlapped.ptr,
                                     byref(length_transferred), do_wait)
     if rc == 0:  # failed (any value other than 0 is success)
         rc = kernel32.GetLastError()
         if rc not in [
                 kernel32.ERROR_IO_INCOMPLETE, kernel32.ERROR_IO_PENDING
         ]:
             kernel32.ResetEvent(self._event)
             log.warning('ControlTransferAsync._finish result: %s',
                         kernel32.get_error_str(rc))
     else:
         kernel32.ResetEvent(self._event)
         rc = 0
         pkt = usb_core.RequestType(value=setup_packet.request_type)
         duration = time.time() - self._time_start
         if pkt.direction == 'in' and setup_packet.length:
             log.debug(
                 'ControlTransferAsync._finish duration=%.6f s, length: %s, %s',
                 duration, setup_packet.length, length_transferred.value)
             buffer = bytes(
                 self._overlapped.data[:length_transferred.value])
         else:
             log.debug('ControlTransferAsync._finish duration=%.6f s',
                       duration)
     response = usb_core.ControlTransferResponse(setup_packet, rc, buffer)
     cbk_fn(response)
Ejemplo n.º 2
0
 def _issue(self):
     if not self._commands:
         return True
     cbk_fn, setup_packet, buffer = self._commands[0]
     pkt = usb_core.RequestType(value=setup_packet.request_type)
     self._overlapped.reset()
     if pkt.direction == 'out':
         if setup_packet.length > 0:
             log.debug('ControlTransferAsync._issue buffer type: %s',
                       type(buffer))
             self._overlapped.data[:setup_packet.length] = np.frombuffer(
                 buffer, dtype=np.uint8)
     result = WinUsb_ControlTransfer(self._winusb, setup_packet,
                                     self._overlapped.b,
                                     setup_packet.length, None,
                                     self._overlapped.ptr)
     result = sanitize_boolean_return_code(result)
     self._time_start = time.time()
     if result != kernel32.ERROR_IO_PENDING:
         if self.stop_code is None:
             self.stop_code = DeviceEvent.COMMUNICATION_ERROR
         log.warning('ControlTransferAsync._issue %s',
                     kernel32.get_error_str(result))
         response = usb_core.ControlTransferResponse(
             setup_packet, result, None)
         cbk_fn(response)
         return False
     return True
Ejemplo n.º 3
0
 def _abort_all(self):
     commands, self._commands = self._commands, []
     for cbk_fn, setup_packet, _ in commands:
         try:
             response = usb_core.ControlTransferResponse(setup_packet, TransferStatus.CANCELLED, None)
             cbk_fn(response)
         except Exception:
             log.exception('in callback while aborting')
Ejemplo n.º 4
0
 def _control_transfer_pend(self, cbk_fn, setup_packet, data):
     if self._control_transfer is None:
         rsp = usb_core.ControlTransferResponse(setup_packet,
                                                TransferStatus.NO_DEVICE,
                                                None)
         cbk_fn(rsp)
         return False
     return self._control_transfer.pend(cbk_fn, setup_packet, data)
Ejemplo n.º 5
0
 def close(self):
     commands, self._commands = self._commands, []
     if self._transfer_pending:
         log.info('ControlTransferAsync.close cancel pending transfer, %d',
                  len(commands))
         transfer, self._transfer_pending = self._transfer_pending, None
         transfer.transfer[0].callback = _transfer_callback_discard_fn
         _lib.libusb_cancel_transfer(transfer.transfer)
         # callback function will be invoked later
     else:
         log.info('ControlTransferAsync.close %d', len(commands))
     for cbk_fn, setup_packet, _ in commands:
         try:
             response = usb_core.ControlTransferResponse(
                 setup_packet, TransferStatus.CANCELLED, None)
             cbk_fn(response)
         except Exception:
             log.exception('while closing in callback')
Ejemplo n.º 6
0
 def close(self):
     self._commands, commands = [], self._commands
     # cannot abort control pipe using WinUSB!
     commands_len = len(commands)
     if commands:
         command = commands.pop(0)
         self._finish(command, do_wait=False)
     while commands:
         cbk_fn, setup_packet, _ = commands.pop(0)
         cbk_fn(usb_core.ControlTransferResponse(setup_packet, False, None))
     if commands_len == 0:
         if self._event:
             kernel32.CloseHandle(self._event)
             self._event = None
         if self._overlapped:
             self._overlapped = None
     else:
         pass  # defer to _close_event
Ejemplo n.º 7
0
 def _finish(self, command, transfer):
     buffer = None
     rc = transfer.transfer[0].status
     cbk_fn, setup_packet, _ = command
     pkt = usb_core.RequestType(value=setup_packet.request_type)
     duration = time.time() - self._time_start
     if rc == TransferStatus.NO_DEVICE:
         log.warning('device_removed')
         if self.stop_code is None:
             self.stop_code = DeviceEvent.COMMUNICATION_ERROR
     if pkt.direction == 'out':
         log.debug('ControlTransferAsync._finish rc=%d, duration=%.6f s', rc, duration)
     else:
         actual_length = transfer.transfer[0].actual_length
         log.debug('ControlTransferAsync._finish rc=%d, duration=%.6f s, length: %s, %s',
                   rc, duration, setup_packet.length, actual_length)
         buffer = bytes(transfer.buffer[8:(actual_length+8)])
     response = usb_core.ControlTransferResponse(setup_packet, rc, buffer)
     cbk_fn(response)
Ejemplo n.º 8
0
    def pend(self, cbk_fn, setup_packet: usb_core.SetupPacket, buffer=None):
        """Pend an asynchronous Control Transfer.

        :param cbk_fn: The function to call when the control transfer completes.
            A :class:`usb_core.ControlTransferResponse` is the sole argument.
        :param setup_packet:
        :param buffer: The buffer (if length > 0) for write transactions.
        :return: True if pending, False on error.
        """
        if self.stop_code is not None:
            response = usb_core.ControlTransferResponse(setup_packet, self.stop_code, None)
            cbk_fn(response)
            return False
        command = [cbk_fn, setup_packet, buffer]
        was_empty = not bool(self._commands)
        self._commands.append(command)
        if was_empty:
            return self._issue()
        return True
Ejemplo n.º 9
0
 def close(self):
     self._commands, commands = [], self._commands
     # cannot abort control pipe using WinUSB!
     commands_len = len(commands)
     if commands:
         command = commands.pop(0)
         rc = kernel32.WaitForSingleObject(self._event, int(CONTROL_TIMEOUT * 1100))
         if rc != kernel32.WAIT_OBJECT_0:  # transfer done
             log.warning('ControlTransferAsync.close but transaction hung')
         self._finish(command)
     while commands:
         cbk_fn, setup_packet, _ = commands.pop(0)
         cbk_fn(usb_core.ControlTransferResponse(setup_packet, False, None))
     if commands_len == 0:
         if self._event:
             kernel32.CloseHandle(self._event)
             self._event = None
         if self._overlapped:
             self._overlapped = None
     else:
         pass  # defer to _close_event