void SendFirmwareUpdateImage(byte[] fwUpdateImageFileBuffer, uint payloadOffset, uint payloadLength, uint crcWord) { int fwUpdateImageFileSize = fwUpdateImageFileBuffer.Length; uint packetSize = 64; //byte[] fwUpdateImageFileBuffer = new byte[fwUpdateImageFileSize]; uint bufferIndex; uint i; int sentNormalPacketCount;//= 5000; uint packetSequenceNum; byte[] inBuf = new byte[packetSize]; byte[] outBuf = new byte[packetSize]; int nakSeqNum; //prepare trace to output file if (false) { Trace.Listeners.Add(new TextWriterTraceListener("FirmwareUpdateLog.txt")); Trace.AutoFlush = true; } try { // send start packet CreateStartPacket(outBuf, payloadLength, crcWord, packetSize); Device.SetHidFeatureReport(outBuf); } catch { throw; } Debug.WriteLine("OK! start packet!!!"); UpdateFirmwareUpdateProtocolRevisionInDevice(); LastStateReport = new EgsDeviceFirmwareUpdateStateReport(); LastStateReport.Message = "Start sending boot image to device" + Environment.NewLine; LastStateReport.Message += "Current device firmware update protocol revision: " + FirmwareUpdateProtocolRevisionInDevice + Environment.NewLine; LastStateReport.Message += "Writing image file firmware update protocol revision: " + ImageFile.ProtocolRevision + Environment.NewLine; LastStateReport.Message += "Current device firmware revision: " + FirmwareVersionInDevice + Environment.NewLine; LastStateReport.Message += "Writing image file firmware revision: " + ImageFile.FirmwareVersion + Environment.NewLine; ProgressReport.ReportProgress(PercentProgress, LastStateReport); //-- check firmware version to update-- if (ImageFile.ProtocolRevision <= FirmwareUpdateProtocolRevisionInDevice) { Debug.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture, "Warning!! Image file protocol version= {0} is equal or older than device firmware protocol version= {1}", ImageFile.ProtocolRevision, FirmwareUpdateProtocolRevisionInDevice)); if (IsToShowWarningMessages) { // TODO: use Resources MessageBoxResult mbr = MessageBox.Show("Image file version is equal or older than device firmware version." + Environment.NewLine + "Are you sure to continue?", "[WARNING] Trying to Upload Older Image to Device", MessageBoxButton.YesNo); if (mbr == MessageBoxResult.No) { throw new OperationCanceledException(); } } } //-- send normal packet -- bufferIndex = 0; sentNormalPacketCount = 0; packetSequenceNum = 1; uint loopCounter = 0; uint errorCount = 0; uint totalByteToSend = (uint)fwUpdateImageFileSize - payloadOffset; while ((payloadOffset + bufferIndex) < (fwUpdateImageFileSize - 1)) { // NOTE: This is the long loop! if (ProgressReport.CancellationPending) { throw new OperationCanceledException(); } //--copy 64-4 bytes-- for (i = 0; i < (packetSize - 4); i++) { uint copyIndex = payloadOffset + bufferIndex + i; if (copyIndex < fwUpdateImageFileSize) { inBuf[i] = fwUpdateImageFileBuffer[copyIndex]; } else { //fill the rest with 0 inBuf[i] = 0; } } // Deleted (2016/7/28) if (false) { // NOTE: Added (2016/04/12) Thread.Sleep(20); } sentNormalPacketCount = (int)packetSequenceNum; CreateFeaturePacket(packetSequenceNum, inBuf, outBuf, packetSize); { // If it fails once, it continues to fail after Sleep(100) or waiting with debugger breaking. Handle is Valid, so DevicePath may be correct. SetFeature itself returns fail. // Mr.T said, "Before the USB library in the device firmware has a stall problem, so retry was meaningful. But now the bug is fixed so it may have no relation.". var trialCountMax = 1; // 10; bool hr = false; string errorMessage = ""; for (int trialCount = 0; trialCount < trialCountMax; trialCount++) { try { Device.SetHidFeatureReport(outBuf); hr = true; } catch (Exception ex) { if (false) { Debugger.Break(); } errorMessage = ex.Message; Debug.WriteLine(errorMessage); Thread.Sleep(100); } if (hr) { break; } } if (hr == false) { throw new InvalidOperationException(errorMessage); } } PercentProgressInOneFile = RatioOfSendingImageFileInUpdatingByOneFile * (int)(bufferIndex + 1) / (int)totalByteToSend; Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Sent OK[{4:N2}%]: seqNum= 0x{0:X} bufferIndex= {1} sentPktCnt= 0x{2:X} totalRetransmitCnt={3}", packetSequenceNum, bufferIndex, sentNormalPacketCount, errorCount, PercentProgress)); //-- get nak seq every 100 packets -- loopCounter++; if ((loopCounter % 100) == 0) { nakSeqNum = GetResponseFromDevice(); if (nakSeqNum > 0) { // resend NAK packet errorCount++; var report = new EgsDeviceFirmwareUpdateStateReport(); report.MessageForDebug = string.Format(CultureInfo.InvariantCulture, "Resend packet with seqNum= 0x{0:X}", nakSeqNum); ProgressReport.ReportProgress(PercentProgress, report); packetSequenceNum = (uint)nakSeqNum; } else { // not nak message, just skip packetSequenceNum++; } } else { packetSequenceNum++; } // update bufferIndex if ((packetSequenceNum - 1) >= 0) { bufferIndex = (packetSequenceNum - 1) * (packetSize - 4); } else { bufferIndex = 0; } } // send end packet, commandID= 1(transfer complete) CreateEndPacket(outBuf, sentNormalPacketCount, 64, 1); try { Device.SetHidFeatureReport(outBuf); } catch (Exception ex) { throw new InvalidOperationException("Failed to send end packet. Error Message: " + ex.Message); } // wait device to complete received buffer error checking if (WaitUpdateFinishResponse(1, 10000) == false) { throw new InvalidOperationException("No response from device."); } Debug.WriteLine("Finish transferring all image data to device successfully."); LastStateReport = new EgsDeviceFirmwareUpdateStateReport(); // TODO: use Resources LastStateReport.Message = "Complete transferring boot image to device." + Environment.NewLine + "Now start writing to device flash memory." + Environment.NewLine; ProgressReport.ReportProgress(PercentProgress, LastStateReport); Debug.WriteLine("TURN OFF device power after click OK prior to flash writing completion, will damage device!"); Debug.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture, "Sending start write to flash command to device.")); // send end packet, commandID= 2(start write to flash) CreateEndPacket(outBuf, sentNormalPacketCount, 64, 2); try { Device.SetHidFeatureReport(outBuf); } catch (Exception ex) { Debug.WriteLine(ex.Message); throw new InvalidOperationException("Sorry, but failed to send end packet."); } // wait device to complete write to flash if (WaitUpdateFinishResponse(2, 60000) == false) { throw new InvalidOperationException("No response from device."); } }
EgsDeviceFirmwareUpdateResult DoWorkInternal() { try { if (FirmwareImageFilePathList == null) { throw new ArgumentNullException("binaryFilepathList"); } if (FirmwareImageFilePathList.Count == 0) { throw new ArgumentException("binaryFilepathList.Count == 0"); } // TODO: MUSTDO: test! Device.WaitTimeInMillisecondsBeforeSetFeatureReport = 2; Device.WaitTimeInMillisecondsBeforeGetFeatureReport = 10; CurrentIndexInFirmwareImageFilePathList = 0; LastStateReport = new EgsDeviceFirmwareUpdateStateReport() { Message = "File List:" + Environment.NewLine }; foreach (var firmwareImageFilePath in FirmwareImageFilePathList) { LastStateReport.Message += " " + firmwareImageFilePath + Environment.NewLine; } ProgressReport.ReportProgress(PercentProgress, LastStateReport); // NOTE: Rebooting device is unnecessary before staring DFU. It is OK if the device is connected. LetUserConnectDevice(); _CurrentIndexInFirmwareImageFilePathList = -1; foreach (var firmwareImageFilePath in FirmwareImageFilePathList) { CurrentIndexInFirmwareImageFilePathList++; // NOTE: If it is not set to 0, ProgressReport become increase unexpectedly. PercentProgressInOneFile = 0; LastStateReport = new EgsDeviceFirmwareUpdateStateReport() { Message = "Sending image file path: " + firmwareImageFilePath + Environment.NewLine }; ProgressReport.ReportProgress(PercentProgress, LastStateReport); if (File.Exists(firmwareImageFilePath) == false) { throw new FileNotFoundException(Resources.EgsDeviceFirmwareUpdateModel_DfuImageFileIsInvalid, firmwareImageFilePath); } ImageFile = new EgsDeviceFirmwareUpdateImageFileModel(firmwareImageFilePath); if (ImageFile == null || ImageFile.LoadedImageAsByteArray == null) { throw new FileFormatException(Resources.EgsDeviceFirmwareUpdateModel_DfuImageFileIsInvalid); } bool hasOneFileCompleted = false; while (hasOneFileCompleted == false) { try { PercentProgressInOneFile = 0; var startDateTime = DateTime.Now; LastStateReport = new EgsDeviceFirmwareUpdateStateReport() { Message = "Start Time: " + startDateTime.ToString() + Environment.NewLine }; ProgressReport.ReportProgress(PercentProgress, LastStateReport); SendFirmwareUpdateImage(ImageFile.LoadedImageAsByteArray, ImageFile.PayloadOffset, ImageFile.PayloadLength, ImageFile.CrcWord); var endDateTime = DateTime.Now; LastStateReport = new EgsDeviceFirmwareUpdateStateReport() { Message = "End Time: " + DateTime.Now.ToString() + " Elapsed: " + (endDateTime - startDateTime).ToString() + Environment.NewLine }; ProgressReport.ReportProgress(PercentProgress, LastStateReport); hasOneFileCompleted = true; } catch (OperationCanceledException) { throw; } catch (Exception ex) { Debug.WriteLine(ex.Message); var msg = Resources.EgsDeviceFirmwareUpdateModel_DfuFailed + Environment.NewLine; msg += Resources.EgsDeviceFirmwareUpdateModel_AppWillRetrySendingImageAgain + Environment.NewLine; LastStateReport = new EgsDeviceFirmwareUpdateStateReport() { Message = msg, UserNotificationMessage = msg }; LastStateReport.MessageForDebug = ex.Message; ProgressReport.ReportProgress(PercentProgress, LastStateReport); } // NOTE: Whether it success or fails, reboot is necessary. LetUserRestartDeviceByReconnectingUsbConnector(); } } // succeeded LastStateReport = new EgsDeviceFirmwareUpdateStateReport(); LastStateReport.Message = Resources.EgsDeviceFirmwareUpdateModel_DfuCompleted + Environment.NewLine; LastStateReport.UserNotificationMessage = Resources.EgsDeviceFirmwareUpdateModel_DfuCompleted + Environment.NewLine; LastStateReport.MessageForDebug = Resources.EgsDeviceFirmwareUpdateModel_DfuCompleted; ProgressReport.ReportProgress(100, LastStateReport); MessageText = LastStateReport.Message; return(new EgsDeviceFirmwareUpdateResult(false, false, true, Resources.EgsDeviceFirmwareUpdateModel_DfuCompleted)); } catch (OperationCanceledException ex) { Debug.WriteLine(ex.Message); LastStateReport = new EgsDeviceFirmwareUpdateStateReport(); LastStateReport.Message = Resources.EgsDeviceFirmwareUpdateModel_DfuCanceled + Environment.NewLine + Resources.EgsDeviceFirmwareUpdateModel_RestartDfuFromBeginning + Environment.NewLine; LastStateReport.UserNotificationMessage = LastStateReport.Message; LastStateReport.MessageForDebug = ex.Message; ProgressReport.ReportProgress(PercentProgress, LastStateReport); MessageText = LastStateReport.Message; return(new EgsDeviceFirmwareUpdateResult(false, true, false, Resources.EgsDeviceFirmwareUpdateModel_DfuCanceled)); } }