Example #1
0
 def bulk_read(self, size, timeout=None):
     start = time.time()
     data = self.ep_in.read(size, timeout)
     end = time.time()
     data_size = len(data)
     if not data_size == size:
         _log.warn(
             "bulk_read: WRONG SIZE: 0x{:x} bytes instead of 0x{:x}".format(
                 data_size, size))
         _log.debug('\n' + hexdump(data))
         raise CanonError(
             "unexpected data length ({} instead of {})".format(
                 len(data), size))
     _log.info("bulk_read got {} (0x{:x}) b in {:.6f} sec".format(
         len(data), len(data), end - start))
     _log.debug("\n" + hexdump(data))
     return data
Example #2
0
 def __repr__(self):
     if self.is_rc:
         name = (commands.lookup_rc(self.payload[0x00])
                 or '-RC 0x{:x}-'.format(self.payload[0x00]))
     else:
         name = commands.lookup(self.cmd1, self.cmd2,
                                self.cmd3) or '-unknown-'
     name += '  ' + hexdump(
         self.payload[:0x10], with_ascii=False, with_offset=False)
     return "<CMD 0x{:02x} 0x{:02x} 0x{:03x} (0x{:02x}) (0x{:03x}) {}>".format(
         self.cmd1, self.cmd2, self.cmd3, len(self.payload),
         len(self.response), name)
Example #3
0
 def control_write(self, wValue, data='', timeout=None):
     # bRequest is 0x4 if length of data is >1, 0x0c otherwise (length >1 ? 0x04 : 0x0C)
     bRequest = 0x04 if len(data) > 1 else 0x0c
     _log.info(
         "control_write (rt: 0x{:x}, req: 0x{:x}, wValue: 0x{:x}) 0x{:x} bytes"
         .format(0x40, bRequest, wValue, len(data)))
     _log.debug("\n" + hexdump(data))
     # bmRequestType is 0xC0 during read and 0x40 during write.
     i = self.device.ctrl_transfer(0x40,
                                   bRequest,
                                   wValue=wValue,
                                   wIndex=0,
                                   data_or_wLength=data,
                                   timeout=timeout)
     if i != len(data):
         raise CanonError("control write was incomplete")
     return i
Example #4
0
    def control_read(self, wValue, data_length=0, timeout=None):
        """Read from the control pipe.

        ``bRequest`` is 0x4 if length of data is >1, 0x0c otherwise (length >1 ? 0x04 : 0x0C)
        ``bmRequestType`` is 0xC0 during read and 0x40 during write.

        """
        #
        bRequest = 0x04 if data_length > 1 else 0x0c
        _log.info(
            "control_read (req: 0x{:x} wValue: 0x{:x}) reading 0x{:x} bytes".
            format(bRequest, wValue, data_length))

        response = self.device.ctrl_transfer(0xc0,
                                             bRequest,
                                             wValue=wValue,
                                             wIndex=0,
                                             data_or_wLength=data_length,
                                             timeout=timeout)
        if len(response) != data_length:
            raise CanonError("incorrect response length form camera")
        _log.debug('\n' + hexdump(response))
        return response
Example #5
0
    return all(
        (is_transfer_bulk(data), is_direction_in(data), is_urb_complete(data)))


def get_commands(fname):
    cmds = []
    r = reader(fname)
    cmd = None
    for data in r:
        if is_cmd_start_packet(data):
            cmd = CanonUSBCommand.from_out_packet(data[0x40:])
            cmds.append(cmd)
        if is_cmd_response_packet(data):
            cmd.response.extend(data[0x40:])

    return cmds


if __name__ == '__main__':
    import sys
    fname = '/home/kiril/Desktop/G3/win_bootstrap.pcap'
    if len(sys.argv) > 1:
        fname = sys.argv[1]
    cmds = get_commands(fname)
    for i, c in enumerate(cmds):
        print "{:04d} {}".format(i, c)
        print " payload:"
        print hexdump(c.payload)
        print " response:"
        print hexdump(c.response[0x50:])
        print
Example #6
0
class CanonUSB(object):
    """USB Link to the camera.
    """
    def __init__(self, device):
        self.max_chunk_size = MAX_CHUNK_SIZE
        self.device = device
        self.device.default_timeout = 500
        self.iface = iface = device[0][0, 0]

        # Other models may have different endpoint addresses
        self.ep_in = usb.util.find_descriptor(iface, bEndpointAddress=0x81)
        self.ep_out = usb.util.find_descriptor(iface, bEndpointAddress=0x02)
        self.ep_int = usb.util.find_descriptor(iface, bEndpointAddress=0x83)
        self._cmd_serial = 0
        self._poller = None

    @contextmanager
    def timeout_ctx(self, new):
        old = self.device.default_timeout
        self.device.default_timeout = new
        _log.info("timeout_ctx: {} ms -> {} ms".format(old, new))
        now = time.time()
        try:
            yield
        finally:
            _log.info("timeout_ctx: {} ms <- {} ms; back in {:.3f} ms".format(
                old, new, (time.time() - now) * 1000))
            self.device.default_timeout = old

    def start_poller(self, size=None, timeout=None):
        if self._poller and self._poller.isAlive():
            raise CanonError("Poller already started.")
        self._poller = InterruptPoller(self, size, timeout=timeout)
        self._poller.start()

    def stop_poller(self):
        if not self._poller:
            raise CanonError("There's no poller to stop.")
        if self._poller.isAlive():
            self._poller.stop()
        self._poller = None

    @property
    def is_polling(self):
        return bool(self._poller and self._poller.isAlive())

    @property
    def poller(self):
        return self._poller

    @contextmanager
    def poller_ctx(self, size=None, timeout=None):
        if self.is_polling:
            _log.warn("poller_ctx: -> entered while poller was active!")
            yield self._poller
            _log.warn("poller_ctx: <- pretending this isn't real")
        else:
            started = time.time()
            _log.info("poller_ctx: -> ({}, {})".format(size, timeout))
            self.start_poller(size, timeout)
            yield self._poller
            if self.is_polling:
                self.stop_poller()
            _log.info("poller_ctx: <- back in {:.3} ms".format(
                (time.time() - started) * 1000))

    def control_read(self, wValue, data_length=0, timeout=None):
        """Read from the control pipe.

        ``bRequest`` is 0x4 if length of data is >1, 0x0c otherwise (length >1 ? 0x04 : 0x0C)
        ``bmRequestType`` is 0xC0 during read and 0x40 during write.

        """
        #
        bRequest = 0x04 if data_length > 1 else 0x0c
        _log.info(
            "control_read (req: 0x{:x} wValue: 0x{:x}) reading 0x{:x} bytes".
            format(bRequest, wValue, data_length))

        response = self.device.ctrl_transfer(0xc0,
                                             bRequest,
                                             wValue=wValue,
                                             wIndex=0,
                                             data_or_wLength=data_length,
                                             timeout=timeout)
        if len(response) != data_length:
            raise CanonError("incorrect response length form camera")
        _log.debug('\n' + hexdump(response))
        return response

    def control_write(self, wValue, data='', timeout=None):
        # bRequest is 0x4 if length of data is >1, 0x0c otherwise (length >1 ? 0x04 : 0x0C)
        bRequest = 0x04 if len(data) > 1 else 0x0c
        _log.info(
            "control_write (rt: 0x{:x}, req: 0x{:x}, wValue: 0x{:x}) 0x{:x} bytes"
            .format(0x40, bRequest, wValue, len(data)))
        _log.debug("\n" + hexdump(data))
        # bmRequestType is 0xC0 during read and 0x40 during write.
        i = self.device.ctrl_transfer(0x40,
                                      bRequest,
                                      wValue=wValue,
                                      wIndex=0,
                                      data_or_wLength=data,
                                      timeout=timeout)
        if i != len(data):
            raise CanonError("control write was incomplete")
        return i

    def bulk_read(self, size, timeout=None):
        start = time.time()
        data = self.ep_in.read(size, timeout)
        end = time.time()
        data_size = len(data)
        if not data_size == size:
            _log.warn(
                "bulk_read: WRONG SIZE: 0x{:x} bytes instead of 0x{:x}".format(
                    data_size, size))
            _log.debug('\n' + hexdump(data))
            raise CanonError(
                "unexpected data length ({} instead of {})".format(
                    len(data), size))
        _log.info("bulk_read got {} (0x{:x}) b in {:.6f} sec".format(
            len(data), len(data), end - start))
        _log.debug("\n" + hexdump(data))
        return data

    def interrupt_read(self, size, timeout=100, ignore_timeouts=False):
        try:
            data = self.ep_int.read(size, timeout)
        except USBError, e:
            if ignore_timeouts and e.errno == 110:
                return array('B')
            raise
        if data is not None and len(data):
            dlen = len(data)
            _log.info("interrupt_read: got 0x{:x} bytes".format(dlen))
            _log.debug("\n" + hexdump(data))
            return data
        return array('B')