// NOTE: STDFU_GetDFUDescriptor_Proxy handles the scenario where STDFU_GetDFUDescriptor never returns. uint STDFU_GetDFUDescriptor_Proxy( ref IntPtr phDevice, ref uint pDFUInterfaceNum, ref uint pNbOfAlternates, ref DFU_FUNCTIONAL_DESCRIPTOR pDesc) { uint returnValue = STDFU_DESCRIPTORNOTFOUND; /* NOTE: this appears to be the most appropriate error code. */ IntPtr temp_phDevice = phDevice; uint temp_pDFUInterfaceNum = pDFUInterfaceNum; uint temp_pNbOfAlternates = pNbOfAlternates; DFU_FUNCTIONAL_DESCRIPTOR temp_pDesc = pDesc; System.Threading.AutoResetEvent waitForComplete = new System.Threading.AutoResetEvent(false); var functionThread = new System.Threading.Thread( delegate() { returnValue = STDFU_GetDFUDescriptor(ref temp_phDevice, ref temp_pDFUInterfaceNum, ref temp_pNbOfAlternates, ref temp_pDesc); waitForComplete.Set(); } ); functionThread.Start(); bool success = waitForComplete.WaitOne(100); // wait 100 ms for completion if (!success) { functionThread.Abort(); /* NOTE: in our experience, this does not actually abort the thread. */ } phDevice = temp_phDevice; pDFUInterfaceNum = temp_pDFUInterfaceNum; pNbOfAlternates = temp_pNbOfAlternates; pDesc = temp_pDesc; return(returnValue); }
public STDfuDevice(string devicePath) { if (STDFU_Open(devicePath, out _handle) != STDFU_NOERROR) { throw new Exception(); // exception: could not open connection to device } try { // retrieve our device descriptor (to retrieve STDFU version) USB_DEVICE_DESCRIPTOR usbDeviceDescriptor = new USB_DEVICE_DESCRIPTOR(); if (STDFU_GetDeviceDescriptor(ref _handle, ref usbDeviceDescriptor) != STDFU_NOERROR) { throw new Exception(); // exception: could not retrieve device descriptor } // retrieve our DFU functional desscriptor uint dfuInterfaceNum = 0; uint nbOfAlternates = 0; DFU_FUNCTIONAL_DESCRIPTOR dfuFunctionalDescriptor = new DFU_FUNCTIONAL_DESCRIPTOR(); if (STDFU_GetDFUDescriptor_Proxy(ref _handle, ref dfuInterfaceNum, ref nbOfAlternates, ref dfuFunctionalDescriptor) != STDFU_NOERROR) { //if (STDFU_GetDFUDescriptor(ref _handle, ref dfuInterfaceNum, ref nbOfAlternates, ref dfuFunctionalDescriptor) != STDFU_NOERROR) throw new Exception(); // exception: could not retrieve DFU descriptor } // retrieve our block transfer size (# of bytes per block in upload/download requests) _blockTransferSize = dfuFunctionalDescriptor.wTransferSize; // verify that our DFU protocol version is valid. if (dfuFunctionalDescriptor.bcdDFUVersion < 0x011A || dfuFunctionalDescriptor.bcdDFUVersion > 0x0120) { throw new Exception(); // unknown DFU protocol version } // retrieve our attributes (supported operations, etc.) if ((dfuFunctionalDescriptor.bmAttributes & ATTR_DNLOAD_CAPABLE) > 0) { _isDownloadCapable = true; } if ((dfuFunctionalDescriptor.bmAttributes & ATTR_UPLOAD_CAPABLE) > 0) { _isUploadCapable = true; } if ((dfuFunctionalDescriptor.bmAttributes & ATTR_WILL_DETACH) > 0) { _isWillDetach = true; } if ((dfuFunctionalDescriptor.bmAttributes & ATTR_MANIFESTATION_TOLERANT) > 0) { _isManifestationTolerant = true; } if ((dfuFunctionalDescriptor.bmAttributes & ATTR_ST_CAN_ACCELERATE) > 0) { _isStCanAccelerate = true; } byte[] commands = new byte[4]; if (GetDownloadCommands(out commands) == true && commands.Length >= 4) { // we were able to load the command bytes for DOWNLOAD functions; set them now. _downloadCommandSetAddressPointer = commands[1]; _downloadCommandErase = commands[2]; _downloadCommandReadUnprotect = commands[3]; } else { // use defaults } } catch { STDFU_Close(ref _handle); } }
static extern uint STDFU_GetDFUDescriptor( ref IntPtr phDevice, ref uint pDFUInterfaceNum, ref uint pNbOfAlternates, ref DFU_FUNCTIONAL_DESCRIPTOR pDesc );