public static Task <T> PerformControlTransferWithRetry <T>( this IUsbDevice usbDevice, Func <IUsbDevice, Task <T> > func, int retryCount = 3, int sleepDurationMilliseconds = 250) { var retryPolicy = Policy .Handle <ApiException>() .Or <ControlTransferException>() .WaitAndRetryAsync( retryCount, i => TimeSpan.FromMilliseconds(sleepDurationMilliseconds), onRetryAsync: (e, t) => usbDevice.ClearStatusAsync() ); return(retryPolicy.ExecuteAsync(() => func(usbDevice))); }
public static async Task PerformStmDfTest(IUsbDevice stmDfuDevice) { //////////////////////////////////////////////////////////// // required to perform a DFU Clear Status request beforehand await stmDfuDevice.ClearStatusAsync(); // this sequence aims to test the "send data to device" using the Control Transfer // executes a DFU "Set Address Pointer" command through the DFU DNLOAD request //////////////////////////////////// // 1st step: send DFU_DNLOAD request var dfuRequestResult = await stmDfuDevice.PerformControlTransferWithRetry(ud => ud.SendDownloadRequestAsync()); // Assert that the bytes transfered match the buffer lenght Assert.IsTrue(dfuRequestResult.BytesTransferred == StmDfuExtensions.DownloadRequestLength); /////////////////////////////////////// // 2nd step: send DFU_GETSTATUS request dfuRequestResult = await stmDfuDevice.PerformControlTransferWithRetry(ud => ud.GetStatusAsync()); // Assert that the received buffer has the requested lenght Assert.IsTrue(dfuRequestResult.BytesTransferred == StmDfuExtensions.GetStatusPacketLength); // check DFU status Assert.IsTrue(dfuRequestResult.Data[4] != STATE_DFU_IDLE); /////////////////////////////////////////////////////////////// // 3rd step: send new DFU_GETSTATUS request to check execution dfuRequestResult = await stmDfuDevice.PerformControlTransferWithRetry(ud => stmDfuDevice.GetStatusAsync()); // Assert that the received buffer has the requested lenght Assert.IsTrue(dfuRequestResult.BytesTransferred == StmDfuExtensions.GetStatusPacketLength); // check DFU status // status has to be different from STATUS_errTARGET // state has to be different from STATE_DFU_ERROR Assert.IsTrue( dfuRequestResult.Data[0] != STATUS_errTARGET && dfuRequestResult.Data[4] != STATE_DFU_ERROR); }