예제 #1
0
        public void SetAddress(int address)
        {
            var mem = Marshal.AllocHGlobal(5);

            try {
                Marshal.WriteByte(mem, 0, 0x21);
                Marshal.WriteByte(mem, 1, (byte)((address >> 0) & 0xff));
                Marshal.WriteByte(mem, 2, (byte)((address >> 8) & 0xff));
                Marshal.WriteByte(mem, 3, (byte)((address >> 16) & 0xff));
                Marshal.WriteByte(mem, 4, (byte)((address >> 24) & 0xff));


                var ret = LibUsb.libusb_control_transfer(
                    handle,
                    0x00 /*LIBUSB_ENDPOINT_OUT*/ | (0x1 << 5) /*LIBUSB_REQUEST_TYPE_CLASS*/ | 0x01 /*LIBUSB_RECIPIENT_INTERFACE*/,
                    1 /*DFU_DNLOAD*/,
                    0,
                    interface_descriptor.bInterfaceNumber,
                    mem,
                    5,
                    5000);

                if (ret < 0)
                {
                    throw new Exception(string.Format("Error with ERASE_SECTOR: {0}", ret));
                }

                var status = GetStatus(handle, interface_descriptor.bInterfaceNumber);

                while (status == 4)
                {
                    Thread.Sleep(100);
                    status = GetStatus(handle, interface_descriptor.bInterfaceNumber);
                }
            } finally {
                Marshal.FreeHGlobal(mem);
            }
        }
예제 #2
0
        public void Download(byte[] block, int address, int altSetting = 0)
        {
            int size = block.Length;

            var mem = Marshal.AllocHGlobal(size);

            try {
                ushort transaction = 2;

                Clear();
                ClaimInterface();
                if (altSetting != 0)
                {
                    SetInterfaceAltSetting(altSetting);
                }
                SetAddress(address);
                Clear();

                int ret = LibUsb.libusb_control_transfer(
                    handle,
                    0x80 /*LIBUSB_ENDPOINT_IN*/ | (0x1 << 5) /*LIBUSB_REQUEST_TYPE_CLASS*/ | 0x01 /*LIBUSB_RECIPIENT_INTERFACE*/,
                    2 /*DFU_UPLOAD*/,
                    transaction++,
                    interface_descriptor.bInterfaceNumber,
                    mem,
                    (ushort)size,
                    5000);
                if (ret < 0)
                {
                    throw new Exception(string.Format("Error with DFU_UPLOAD: {0}", ret));
                }

                Marshal.Copy(mem, block, 0, ret);
            } finally {
                Marshal.FreeHGlobal(mem);
                Clear();
            }
        }
예제 #3
0
        public void BeginListeningForHotplugEvents()
        {
            if (_callbackHandle != IntPtr.Zero)
            {
                Debug.WriteLine("Already listening for events.");
                return;
            }

            if (!HasCapability(Capabilities.HasCapabilityAPI))
            {
                Debug.WriteLine("Capability API not supported.");
                return;
            }

            if (!HasCapability(Capabilities.SupportsHotplug))
            {
                Debug.WriteLine("Hotplug notifications not supported.");
                return;
            }

            int    vendorID    = -1; // wildcard match (all)
            int    productID   = -1;
            int    deviceClass = -1;
            IntPtr userData    = IntPtr.Zero;

            ErrorCodes success = LibUsb.libusb_hotplug_register_callback(this.handle, HotplugEventType.DeviceArrived | HotplugEventType.DeviceLeft, HotplugFlags.DefaultNoFlags,
                                                                         vendorID, productID, deviceClass, this._hotplugCallbackHandler, userData, out _callbackHandle);

            if (success == ErrorCodes.Success)
            {
                Debug.WriteLine("Callback registration successful");
            }
            else
            {
                throw new Exception("callback registration failed, error: " + success.ToString());
            }
        }
예제 #4
0
 public bool HasCapability(Capabilities caps)
 {
     return(LibUsb.libusb_has_capability(caps) == 0 ? false : true);
 }
예제 #5
0
        public List <DfuDevice> GetDfuDevices(List <ushort> idVendors)
        {
            var list        = IntPtr.Zero;
            var dfu_devices = new List <DfuDevice>();
            var ret         = LibUsb.libusb_get_device_list(handle, ref list);

            if (ret < 0)
            {
                throw new Exception(string.Format("Error: {0} while trying to get the device list", ret));
            }

            var devices = new IntPtr[ret];

            Marshal.Copy(list, devices, 0, ret);

            // This is awful nested looping -- we should fix it.
            for (int i = 0; i < ret; i++)
            {
                var device_descriptor = new DeviceDescriptor();
                var ptr = IntPtr.Zero;

                if (LibUsb.libusb_get_device_descriptor(devices[i], ref device_descriptor) != 0)
                {
                    continue;
                }

                //if (!idVendors.Contains(device_descriptor.idVendor))
                //    continue;

                for (int j = 0; j < device_descriptor.bNumConfigurations; j++)
                {
                    var ret2 = LibUsb.libusb_get_config_descriptor(devices[i], (ushort)j, out ptr);

                    if (ret2 < 0)
                    {
                        continue;
                    }
                    //throw new Exception(string.Format("Error: {0} while trying to get the config descriptor", ret2));

                    var config_descriptor = Marshal.PtrToStructure <ConfigDescriptor>(ptr);

                    for (int k = 0; k < config_descriptor.bNumInterfaces; k++)
                    {
                        var p = config_descriptor.interfaces + j * Marshal.SizeOf <@Interface>();

                        if (p == IntPtr.Zero)
                        {
                            continue;
                        }

                        var @interface = Marshal.PtrToStructure <@Interface>(p);
                        for (int l = 0; l < @interface.num_altsetting; l++)
                        {
                            var interface_descriptor = @interface.Altsetting[l];

                            // Ensure this is a DFU descriptor
                            if (interface_descriptor.bInterfaceClass != 0xfe || interface_descriptor.bInterfaceSubClass != 0x1)
                            {
                                continue;
                            }

                            var dfu_descriptor = FindDescriptor(interface_descriptor.extra, interface_descriptor.extra_length, (byte)Consts.USB_DT_DFU);
                            if (dfu_descriptor != null)
                            {
                                dfu_devices.Add(new DfuDevice(devices[i], interface_descriptor, dfu_descriptor.Value));
                            }
                        }
                    }
                }
            }

            LibUsb.libusb_free_device_list(list, 1);
            return(dfu_devices);
        }
예제 #6
0
 public void Dispose()
 {
     //this.StopListeningForHotplugEvents(); // not needed, they're automatically deregistered in libusb_exit.
     LibUsb.libusb_exit(handle);
 }
예제 #7
0
 public void Dispose()
 {
     LibUsb.libusb_close(handle);
 }
예제 #8
0
 public void SetInterfaceAltSetting(int alt_setting)
 {
     LibUsb.libusb_set_interface_alt_setting(handle, interface_descriptor.bInterfaceNumber, alt_setting);
 }
예제 #9
0
 public void ClaimInterface()
 {
     LibUsb.libusb_claim_interface(handle, interface_descriptor.bInterfaceNumber);
 }