예제 #1
0
파일: xusb.py 프로젝트: ywg121020/libusb
def send_mass_storage_command(handle, endpoint, lun, cdb, direction,
                              data_length, ret_tag):

    global _tag

    #int i, r;

    cbw = command_block_wrapper()

    if not cdb:
        return -1

    if endpoint & usb.LIBUSB_ENDPOINT_IN:
        perr("send_mass_storage_command: cannot send command on IN endpoint\n")
        return -1

#ct.c_uint8 cdb_len;
    cdb_len = cdb_length[cdb[0]]
    if cdb_len == 0 or cdb_len > ct.sizeof(cbw.CBWCB):
        perr(
            "send_mass_storage_command: don't know how to handle this command ({:02X}, length {})\n",
            cdb[0], cdb_len)
        return -1

    cbw.dCBWSignature[0] = 'U'
    cbw.dCBWSignature[1] = 'S'
    cbw.dCBWSignature[2] = 'B'
    cbw.dCBWSignature[3] = 'C'
    ret_tag[0] = _tag
    cbw.dCBWTag = _tag
    cbw.dCBWDataTransferLength = data_length
    cbw.bmCBWFlags = direction
    cbw.bCBWLUN = lun
    _tag += 1
    # Subclass is 1 or 6 => cdb_len
    cbw.bCBWCBLength = cdb_len
    memcpy(cbw.CBWCB, cdb, cdb_len)

    i = 0
    while True:
        # The transfer length must always be exactly 31 bytes.
        size = ct.c_int()
        r = usb.bulk_transfer(handle, endpoint,
                              ct.cast(ct.pointer(cbw), ct.POINTER(ct.c_ubyte)),
                              31, ct.byref(size), 1000)
        if r == usb.LIBUSB_ERROR_PIPE:
            usb.clear_halt(handle, endpoint)
        i += 1
        if r != usb.LIBUSB_ERROR_PIPE or i >= RETRY_MAX:
            break
    if r != usb.LIBUSB_SUCCESS:
        perr("   send_mass_storage_command: {}\n", usb.strerror(usb.error(r)))
        return -1

    print("   sent {} CDB bytes".format(cdb_len))
    return 0
예제 #2
0
파일: xusb.py 프로젝트: ywg121020/libusb
def get_mass_storage_status(handle, endpoint, expected_tag):

    #int r;

    csw = command_status_wrapper()

    # The device is allowed to STALL this transfer. If it does, you have to
    # clear the stall and try again.
    i = 0
    while True:
        size = ct.c_int()
        r = usb.bulk_transfer(handle, endpoint,
                              ct.cast(ct.pointer(csw), ct.POINTER(ct.c_ubyte)),
                              13, ct.byref(size), 1000)
        if r == usb.LIBUSB_ERROR_PIPE:
            usb.clear_halt(handle, endpoint)
        i += 1
        if r != usb.LIBUSB_ERROR_PIPE or i >= RETRY_MAX:
            break
    if r != usb.LIBUSB_SUCCESS:
        perr("   get_mass_storage_status: {}\n", usb.strerror(usb.error(r)))
        return -1
    size = size.value
    if size != 13:
        perr("   get_mass_storage_status: received {} bytes (expected 13)\n",
             size)
        return -1
    if csw.dCSWTag != expected_tag:
        perr(
            "   get_mass_storage_status: mismatched tags (expected {:08X}, received {:08X})\n",
            expected_tag, csw.dCSWTag)
        return -1
    # For this test, we ignore the dCSWSignature check for validity...
    print("   Mass Storage Status: {:02X} ({})".format(
        csw.bCSWStatus, "FAILED" if csw.bCSWStatus else "Success"))
    if csw.dCSWTag != expected_tag:
        return -1
    if csw.bCSWStatus:
        # REQUEST SENSE is appropriate only if bCSWStatus is 1, meaning that the
        # command failed somehow.  Larger values (2 in particular) mean that
        # the command couldn't be understood.
        if csw.bCSWStatus == 1:
            return -2  # request Get Sense
        else:
            return -1

    # In theory we also should check dCSWDataResidue.  But lots of devices
    # set it wrongly.
    return 0
예제 #3
0
def err_exit(errcode):
    perr("   {}\n", usb.strerror(usb.error(errcode)))
    return -1
예제 #4
0
파일: xusb.py 프로젝트: sayyuf-shaik/libusb
def read_ms_winsub_feature_descriptors(handle, bRequest, iface_number):

    # Read the MS WinUSB Feature Descriptors, that are used on Windows 8 for automated driver installation

    MAX_OS_FD_LENGTH = 256

    #int r;

    os_desc = (ct.c_uint8 * MAX_OS_FD_LENGTH)()

    class struct_os_fd(ct.Structure):
        _fields_ = [
        ("desc",        ct.c_char_p),
        ("recipient",   ct.c_uint8),
        ("index",       ct.c_uint16),
        ("header_size", ct.c_uint16),
    ]
    os_fd = [
        struct_os_fd(b"Extended Compat ID",  usb.LIBUSB_RECIPIENT_DEVICE,    0x0004, 0x10),
        struct_os_fd(b"Extended Properties", usb.LIBUSB_RECIPIENT_INTERFACE, 0x0005, 0x0A),
    ]

    if iface_number < 0:
        return

    # WinUSB has a limitation that forces wIndex to the interface number when issuing
    # an Interface Request. To work around that, we can force a Device Request for
    # the Extended Properties, assuming the device answers both equally.
    if force_device_request:
        os_fd[1].recipient = usb.LIBUSB_RECIPIENT_DEVICE

    for i in range(2):

        print("\nReading {} OS Feature Descriptor (wIndex = 0x%04d):".format(
              os_fd[i].desc, os_fd[i].index))

        # Read the header part
        r = usb.control_transfer(handle,
                                 ct.c_uint8(usb.LIBUSB_ENDPOINT_IN |
                                            usb.LIBUSB_REQUEST_TYPE_VENDOR |
                                            os_fd[i].recipient),
                                 bRequest,
                                 ct.c_uint16((iface_number << 8) | 0x00), os_fd[i].index,
                                 os_desc, os_fd[i].header_size,
                                 1000)
        if r < os_fd[i].header_size:
            perr("   Failed: {}", usb.strerror(usb.error(r)) if r < 0 else "header size is too small")
            return
        le_type_punning_IS_fine = ct.cast(os_desc, ct.c_void_p)
        length = ct.cast(le_type_punning_IS_fine, ct.POINTER(ct.c_uint32))[0].value  # ct.c_uint32
        length = min(length, MAX_OS_FD_LENGTH)

        # Read the full feature descriptor
        r = usb.control_transfer(handle,
                                 ct.c_uint8(usb.LIBUSB_ENDPOINT_IN |
                                            usb.LIBUSB_REQUEST_TYPE_VENDOR |
                                            os_fd[i].recipient),
                                 bRequest,
                                 ct.c_uint16((iface_number << 8) | 0x00), os_fd[i].index,
                                 os_desc, ct.c_uint16(length),
                                 1000)
        if r < 0:
            perr("   Failed: {}", usb.strerror(usb.error(r)))
            return
        else:
            display_buffer_hex(os_desc, r)
예제 #5
0
파일: xusb.py 프로젝트: sayyuf-shaik/libusb
def test_hid(handle, endpoint_in):

    global binary_dump
    global binary_name

    #int r;

    hid_report_descriptor = (ct.c_uint8 * 256)()
    report_buffer = ct.POINTER(ct.c_uint8)

    print("\nReading HID Report Descriptors:")
    descriptor_size = usb.control_transfer(handle,
                                           usb.LIBUSB_ENDPOINT_IN |
                                           usb.LIBUSB_REQUEST_TYPE_STANDARD |
                                           usb.LIBUSB_RECIPIENT_INTERFACE,
                                           usb.LIBUSB_REQUEST_GET_DESCRIPTOR,
                                           usb.LIBUSB_DT_REPORT << 8, 0,
                                           hid_report_descriptor,
                                           ct.sizeof(hid_report_descriptor),
                                           1000)
    if descriptor_size < 0:
        print("   Failed")
        return -1
    display_buffer_hex(hid_report_descriptor, descriptor_size)
    if binary_dump:
        try:
            fd = open(binary_name, "w")
        except: pass
        else:
            with fd:
                if fd.fwrite(hid_report_descriptor, descriptor_size) != descriptor_size:
                    print("   Error writing descriptor to file")

    size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_FEATURE)
    if size <= 0:
        print("\nSkipping Feature Report readout (None detected)")
    else:
        report_buffer = ct.cast(calloc(size, 1), ct.POINTER(ct.c_uint8))
        if not report_buffer:
            return -1

        print("\nReading Feature Report (length {})...".format(size))
        r = usb.control_transfer(handle,
                                 usb.LIBUSB_ENDPOINT_IN |
                                 usb.LIBUSB_REQUEST_TYPE_CLASS |
                                 usb.LIBUSB_RECIPIENT_INTERFACE,
                                 HID_GET_REPORT,
                                 (HID_REPORT_TYPE_FEATURE << 8) | 0, 0,
                                 report_buffer, ct.c_uint16(size),
                                 5000)
        if r >= 0:
            display_buffer_hex(report_buffer, size)
        else:
            if r == usb.LIBUSB_ERROR_NOT_FOUND:
                print("   No Feature Report available for this device")
            elif r == usb.LIBUSB_ERROR_PIPE:
                print("   Detected stall - resetting pipe...")
                usb.clear_halt(handle, 0)
            else:
                print("   Error: {}".format(usb.strerror(usb.error(r))))

        free(report_buffer)

    size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_INPUT)
    if size <= 0:
        print("\nSkipping Input Report readout (None detected)")
    else:
        report_buffer = ct.cast(calloc(size, 1), ct.POINTER(ct.c_uint8))
        if not report_buffer:
            return -1

        print("\nReading Input Report (length {})...".format(size))
        r = usb.control_transfer(handle,
                                 usb.LIBUSB_ENDPOINT_IN |
                                 usb.LIBUSB_REQUEST_TYPE_CLASS |
                                 usb.LIBUSB_RECIPIENT_INTERFACE,
                                 HID_GET_REPORT,
                                 (HID_REPORT_TYPE_INPUT << 8) | 0x00, 0,
                                 report_buffer, ct.c_uint16(size),
                                 5000)
        if r >= 0:
            display_buffer_hex(report_buffer, size)
        else:
            if r == usb.LIBUSB_ERROR_TIMEOUT:
                print("   Timeout! Please make sure you act on the device within the 5 seconds allocated...")
            elif r == usb.LIBUSB_ERROR_PIPE:
                print("   Detected stall - resetting pipe...")
                usb.clear_halt(handle, 0)
            else:
                print("   Error: {}".format(usb.strerror(usb.error(r))))

        # Attempt a bulk read from endpoint 0 (this should just return a raw input report)
        print("\nTesting interrupt read using endpoint {:02X}...".format(endpoint_in))
        r = usb.interrupt_transfer(handle, endpoint_in, report_buffer, size, ct.byref(size), 5000)
        if r >= 0:
            display_buffer_hex(report_buffer, size)
        else:
            print("   {}".format(usb.strerror(usb.error(r))))

        free(report_buffer)

    return 0
예제 #6
0
파일: xusb.py 프로젝트: sayyuf-shaik/libusb
def test_mass_storage(handle, endpoint_in, endpoint_out):

    # Mass Storage device to test bulk transfers (non destructive test)

    global binary_dump
    global binary_name

    #int r;
    #ct.c_uint32 i

    print("Reading Max LUN:")
    lun = ct.c_uint8()
    r = usb.control_transfer(handle,
                             usb.LIBUSB_ENDPOINT_IN |
                             usb.LIBUSB_REQUEST_TYPE_CLASS |
                             usb.LIBUSB_RECIPIENT_INTERFACE,
                             BOMS_GET_MAX_LUN,
                             0, 0,
                             ct.byref(lun), 1,
                             1000)
    lun = lun.value
    # Some devices send a STALL instead of the actual value.
    # In such cases we should set lun to 0.
    if r == 0:
        lun = 0
    elif r < 0:
        perr("   Failed: {}".format(usb.strerror(usb.error(r))))
    print("   Max LUN = {}".format(lun))

    # Send Inquiry
    print("Sending Inquiry:")
    buffer = (ct.c_uint8 * 64)()
    cdb    = (ct.c_uint8 * 16)()  # SCSI Command Descriptor Block
    cdb[0] = 0x12  # Inquiry
    cdb[4] = INQUIRY_LENGTH

    expected_tag = ct.c_uint32()
    send_mass_storage_command(handle, endpoint_out, lun, cdb, usb.LIBUSB_ENDPOINT_IN, INQUIRY_LENGTH, ct.pointer(expected_tag))
    size = ct.c_int()
    r = usb.bulk_transfer(handle, endpoint_in, ct.cast(ct.pointer(buffer), ct.POINTER(ct.c_ubyte)), INQUIRY_LENGTH, ct.byref(size), 1000)
    if r < 0:
        return err_exit(r)
    size = size.value
    print("   received {} bytes".format(size))
    # The following strings are not zero terminated
    vid = (ct.c_char * 9)()
    pid = (ct.c_char * 9)()
    rev = (ct.c_char * 5)()
    for i in range(8):
        vid[i]     = buffer[8  + i]
        pid[i]     = buffer[16 + i]
        rev[i / 2] = buffer[32 + i / 2]  # instead of another loop
    vid[8] = 0
    pid[8] = 0
    rev[4] = 0
    print("   VID:PID:REV \"%8s\":\"%8s\":\"%4s\"".format(vid, pid, rev))
    if get_mass_storage_status(handle, endpoint_in, expected_tag) == -2:
        get_sense(handle, endpoint_in, endpoint_out)

    # Read capacity
    print("Reading Capacity:")
    buffer = (ct.c_uint8 * 64)()
    cdb    = (ct.c_uint8 * 16)()  # SCSI Command Descriptor Block
    cdb[0] = 0x25  # Read Capacity

    expected_tag = ct.c_uint32()
    send_mass_storage_command(handle, endpoint_out, lun, cdb, usb.LIBUSB_ENDPOINT_IN, READ_CAPACITY_LENGTH, ct.pointer(expected_tag))
    size = ct.c_int()
    r = usb.bulk_transfer(handle, endpoint_in, ct.cast(ct.pointer(buffer), ct.POINTER(ct.c_ubyte)), READ_CAPACITY_LENGTH, ct.byref(size), 1000)
    if r < 0:
        return err_exit(r)
    size = size.value
    print("   received {} bytes".format(size))
    max_lba     = be_to_int32(buffer[0:])
    block_size  = be_to_int32(buffer[4:])
    device_size = (max_lba + 1.0) * block_size / (1024 * 1024 * 1024)
    print("   Max LBA: {:08X}, Block Size: {:08X} (%.2f GB)".format(
          max_lba, block_size, device_size))
    if get_mass_storage_status(handle, endpoint_in, expected_tag) == -2:
        get_sense(handle, endpoint_in, endpoint_out)

    # coverity[tainted_data]
    try:
        data = ct.cast(calloc(1, block_size), ct.POINTER(ct.c_ubyte)) # unsigned char*
    except:
        perr("   unable to allocate data buffer\n")
        return -1

    # Send Read
    print("Attempting to read %u bytes:".format(block_size))
    cdb    = (ct.c_uint8 * 16)()  # SCSI Command Descriptor Block
    cdb[0] = 0x28  # Read(10)
    cdb[8] = 0x01  # 1 block

    expected_tag = ct.c_uint32()
    send_mass_storage_command(handle, endpoint_out, lun, cdb, usb.LIBUSB_ENDPOINT_IN, block_size, ct.pointer(expected_tag))
    size = ct.c_int()
    usb.bulk_transfer(handle, endpoint_in, data, block_size, ct.byref(size), 5000)
    size = size.value
    print("   READ: received {} bytes".format(size))
    if get_mass_storage_status(handle, endpoint_in, expected_tag) == -2:
        get_sense(handle, endpoint_in, endpoint_out)
    else:
        display_buffer_hex(data, size)
        if binary_dump:
            try:
                fd = open(binary_name, "w")
            except: pass
            else:
                with fd:
                    if fd.fwrite(data, ct.c_size_t(size).value) != ct.c_uint(size).value:
                        perr("   unable to write binary data\n")

    free(data)

    return 0
예제 #7
0
파일: xusb.py 프로젝트: sayyuf-shaik/libusb
def main(argv=sys.argv):

    global VID, PID
    global test_mode
    global binary_dump
    global binary_name

    show_help  = False  # bool
    debug_mode = False  # bool
    error_lang = None   # char*

    # Default to generic, expecting VID:PID
    VID = 0
    PID = 0

    test_mode = USE_GENERIC

    endian_test = ct.c_uint16(0xBE00)
    if ct.cast(ct.pointer(endian_test), ct.POINTER(ct.c_uint8))[0] == 0xBE:
        print("Despite their natural superiority for end users, big endian\n"
              "CPUs are not supported with this program, sorry.")
        return 0

   #if len(argv) >= 2:
    for j in range(1, len(argv)):
        arglen = len(argv[j])
        if argv[j][0] in ('-', '/') and arglen >= 2:
            opt = argv[j][1]
            if opt == 'd':
                debug_mode = True
            elif opt == 'i':
                extra_info = True
            elif opt == 'w':
                force_device_request = True
            elif opt == 'b':
                j += 1
                if j >= len(argv) or argv[j][0] in ('-', '/'):
                    print("   Option -b requires a file name")
                    return 1
                binary_name = argv[j]
                binary_dump = True
            elif opt == 'l':
                j += 1
                if j >= len(argv) or argv[j][0] in ('-', '/'):
                    print("   Option -l requires an ISO 639-1 language parameter")
                    return 1
                error_lang = argv[j]
            elif opt == 'j':
                # OLIMEX ARM-USB-TINY JTAG, 2 channel composite device - 2 interfaces
                if not VID and not PID:
                    VID = 0x15BA
                    PID = 0x0004
            elif opt == 'k':
                # Generic 2 GB USB Key (SCSI Transparent/Bulk Only) - 1 interface
                if not VID and not PID:
                    VID = 0x0204
                    PID = 0x6025
            # The following tests will force VID:PID if already provided
            elif opt == 'p':
                # Sony PS3 Controller - 1 interface
                VID = 0x054C
                PID = 0x0268
                test_mode = USE_PS3
            elif opt == 's':
                # Microsoft Sidewinder Precision Pro Joystick - 1 HID interface
                VID = 0x045E
                PID = 0x0008
                test_mode = USE_HID
            elif opt == 'x':
                # Microsoft XBox Controller Type S - 1 interface
                VID = 0x045E
                PID = 0x0289
                test_mode = USE_XBOX
            else:
                show_help = True
        else:
            for i in range(arglen):
                if argv[j][i] == ':':
                    tmp_vid = 0  # unsigned int
                    tmp_pid = 0  # unsigned int
                    if sscanf(argv[j], "%x:%x" , ct.pointer(tmp_vid), ct.pointer(tmp_pid)) != 2:
                        print("   Please specify VID & PID as \"vid:pid\" in hexadecimal format")
                        return 1
                    VID = ct.c_uint16(tmp_vid)
                    PID = ct.c_uint16(tmp_pid)
                    break
            else:
                show_help = True

    if show_help or len(argv) == 1 or len(argv) > 7:
        print("usage: {} [-h] [-d] [-i] [-k] [-b file] [-l lang] [-j] [-x] [-s] [-p] [-w] [vid:pid]".format(argv[0]))
        print("   -h      : display usage")
        print("   -d      : enable debug output")
        print("   -i      : print topology and speed info")
        print("   -j      : test composite FTDI based JTAG device")
        print("   -k      : test Mass Storage device")
        print("   -b file : dump Mass Storage data to file 'file'")
        print("   -p      : test Sony PS3 SixAxis controller")
        print("   -s      : test Microsoft Sidewinder Precision Pro (HID)")
        print("   -x      : test Microsoft XBox Controller Type S")
        print("   -l lang : language to report errors in (ISO 639-1)")
        print("   -w      : force the use of device requests when querying WCID descriptors")
        print("If only the vid:pid is provided, xusb attempts to run the most appropriate test")
        return 0

    # xusb is commonly used as a debug tool, so it's convenient to have debug output
    # during usb.init(), but since we can't call on usb.set_option() before usb.init(),
    # we use the env variable method
    old_dbg_str = os.environ.get("LIBUSB_DEBUG", None)
    if debug_mode:
        try:
            os.environ["LIBUSB_DEBUG"] = "4"  # usb.LIBUSB_LOG_LEVEL_DEBUG
        except:
            print("Unable to set debug level")

    version = usb.get_version()[0]
    print("Using libusb v{}.{}.{}.{}\n".format(
          version.major, version.minor, version.micro, version.nano))
    r = usb.init(None)
    if r < 0:
        return r

    try:
        # If not set externally, and no debug option was given, use info log level
        if old_dbg_str is None and not debug_mode:
            usb.set_option(None, usb.LIBUSB_OPTION_LOG_LEVEL, usb.LIBUSB_LOG_LEVEL_INFO)
        if error_lang is not None:
            r = usb.setlocale(error_lang)
            if r < 0:
                print("Invalid or unsupported locale '{}': {}".format(
                      error_lang, usb.strerror(usb.error(r))))

        test_device(VID, PID)
    finally:
        usb.exit(None)

    if debug_mode:
        #char string[256];
        string = "LIBUSB_DEBUG={}".format("" if old_dbg_str is None else old_dbg_str)

    return 0
예제 #8
0
def main():

    global devh
    global img_transfer
    global irq_transfer
    global do_exit

    exit_sem = sem_open(SEM_NAME, O_CREAT, 0)
    if not exit_sem:
        print("failed to initialise semaphore error {}".format(errno), file=sys.stderr)
        sys.exit(1)

    # only using this semaphore in this process so go ahead and unlink it now
    sem_unlink(SEM_NAME)

    r = usb.init(None)
    if r < 0:
        print("failed to initialise libusb", file=sys.stderr)
        sys.exit(1)

    r = find_dpfp_device()
    try:
        if r < 0:
            print("Could not find/open device", file=sys.stderr)
            return abs(r)

        r = usb.claim_interface(devh, 0)
        if r < 0:
            print("usb_claim_interface error {} {}".format(r, usb.strerror(usb.error(r))), file=sys.stderr)
            return abs(r)
        print("claimed interface")

        r = print_f0_data()
        if r < 0:
            usb.release_interface(devh, 0)
            return abs(r)

        r = do_init()
        try:
            if r < 0:
                return abs(r)

            # async from here onwards

            #sigact = struct_sigaction()
            #sigact.sa_handler = sighandler
            #sigemptyset(ct.byref(sigact.sa_mask))
            #sigact.sa_flags = 0
            signal.signal(signal.SIGINT,  sighandler)
            signal.signal(signal.SIGTERM, sighandler)
            if hasattr(signal, "SIGQUIT"):
                signal.signal(signal.SIGQUIT, sighandler)

            r = pthread_create(ct.byref(poll_thread), NULL, poll_thread_main, NULL)
            if r:
                return abs(r)

            r = alloc_transfers()
            if r < 0:
                request_exit(1)
                pthread_join(poll_thread, NULL)
                return abs(r)

            r = init_capture()
            if r < 0:
                request_exit(1)
                pthread_join(poll_thread, NULL)
                return abs(r)

            while not do_exit:
                sem_wait(exit_sem)

            print("shutting down...")
            pthread_join(poll_thread, NULL)

            r = usb.cancel_transfer(irq_transfer)
            if r < 0:
                request_exit(1)
                return abs(r)

            r = usb.cancel_transfer(img_transfer)
            if r < 0:
                request_exit(1)
                return abs(r)

            while irq_transfer or img_transfer:
                if usb.handle_events(None) < 0:
                    break

            r = 0 if do_exit == 1 else 1

        finally:
            usb.free_transfer(img_transfer)
            usb.free_transfer(irq_transfer)
            set_mode(0);
            set_hwstat(0x80)
            usb.release_interface(devh, 0)
    finally:
        usb.close(devh)
        usb.exit(None)

    return abs(r)