Project - Network IFU+

I just posted Network IFU+ on Codeshare. Feel free to discuss and make suggestions here.

7 Likes

Nice work :slight_smile:
Thanks for sharing…

i just downloaded and will leverage it for IFU support in my applicaiton. Do you know of any updates (bug fixes or features added)?

No known issues. If you find something let me know and I’ll get it resolved. :slight_smile:

@ Skewworks, thanks for the library, it is a good basis for what I want to achieve (AMQP message containing a json body with the update commands). I have some comments to make your library more streamlined / readable:

Some code seems to be very repetitive, why not condense it into a single procedure and call it from DownloadFirmware(), the same can be applied to DownloadApplication().


        private void DownloadFirmware(string uri, string[] files)
        {
            GHI.Processor.InFieldUpdate.Initialize(GHI.Processor.InFieldUpdate.Types.Configuration | GHI.Processor.InFieldUpdate.Types.Firmware | GHI.Processor.InFieldUpdate.Types.Application);

            // Application is always first
            DownloadFirmwareFile(uri + files[0], GHI.Processor.InFieldUpdate.Types.Application);

            // Configuration is always second
            DownloadFirmwareFile(uri + files[1], GHI.Processor.InFieldUpdate.Types.Configuration);

            for (int i = 2; i < files.Length; i++)
            {
                DownloadFirmwareFile(uri + files[i], GHI.Processor.InFieldUpdate.Types.Firmware);
            }

            try
            {
                OnDownloadingFile("Preparing to restart", 0);
                GHI.Processor.InFieldUpdate.FlashAndReset();
            }
            catch (Exception) { }
        }


        private void DownloadFirmwareFile(string uri, GHI.Processor.InFieldUpdate.Types type)
        {
            using (WebRequest webRequest = WebRequest.Create(uri))
            {
                using (WebResponse webResponse = webRequest.GetResponse())
                {
                    using (Stream stream = webResponse.GetResponseStream())
                    {
                        long remainingLength = webResponse.ContentLength;
                        int read;
                        byte[] bytes = new byte[_bufferSize];
                        long downloaded, downloadSize;

                        downloaded = 0;
                        downloadSize = remainingLength;

                        OnUpdatesAvailable();
                        OnDownloadingFile(uri, webResponse.ContentLength);

                        while (remainingLength > 0)
                        {
                            if (remainingLength < bytes.Length)
                                bytes = new byte[remainingLength];
                            read = stream.Read(bytes, 0, bytes.Length);
                            downloaded += read;
                            try
                            {
                                GHI.Processor.InFieldUpdate.Load(type, bytes, read);
                                OnDownloadUpdate(downloaded, downloadSize);
                            }
                            catch (Exception)
                            {
                                GHI.Processor.InFieldUpdate.Abort();
                                return;
                            }
                            remainingLength -= read;
                        }
                    }
                }
            }
        }

I have wrapped some statements in the new procedure with using directives so they are disposed of correctly…

I also have one question… Why is the try / catch for IFU.Load called within the while loop? Surely it should be called after so that the whole file is downloaded…

Thanks! I’ll look at putting I’m the changes.

The try/catch is there in case of wrong/bad/corrupt firmware. Without it, I believe its a full system crash.