protected override bool StateMachine_TransferPacket(StepDefinition currentStep)
        {
            // check for connection
            if (!_comPortRef.IsConnected)
            {
                SetTransferState(TransferState.FailedConnection);
                MachineFunctions.JumpToLast(currentStep);
                return(StepReturn.JumpCommandUsed);
            }

            // update the users with % complete
            RunPercentUpdate();

            if (_payloadPage != _currentPage)
            {
                // calculate read length
                _readLength = PageSize * PagesTransmitted;
                if (_pointer + _readLength > _workingFile.Count)
                {
                    _readLength = _workingFile.Count - _pointer;
                }

                // load the array into a list with _page information
                _payload.Clear();
                _payload.AddRange(DataConversions.ConvertUInt16ToList(_currentPage));
                _payload.AddRange(_workingFile.GetRange(_pointer, _readLength));
                _payload.AddRange(Checksums.Fletcher16(_payload));

                // add escapes to the payload
                _payload.EscapeList();

                // add the command to the front of the payload
                _payload.InsertRange(0, Encoding.ASCII.GetBytes(_command));

                // update the housekeeping variables
                _payloadPage = _currentPage;
            }

            // send the data
            var returnString = _comPortRef.SendCommand(_payload, 1).FirstOrDefault();

            if (returnString?.Contains($"{_command}{_currentPage},{_readLength}") == true)
            {
                // housekeeping variables
                _pointer     += _readLength;
                _currentPage += PagesTransmitted;

                // we had a good transfer, determine next step
                if (_pointer == _workingFile.Count)
                {
                    // we are at the end of the file, so tell the system we are done
                    _payload.Clear();
                    _payload.AddRange(DataConversions.ConvertUInt16ToList(0xFFFF));
                    _payload.AddRange(Checksums.Fletcher16(_payload));

                    // add escapes to the payload
                    _payload.EscapeList();

                    // add the command to the front of the payload
                    _payload.InsertRange(0, Encoding.ASCII.GetBytes(_command));

                    // send command
                    _comPortRef.SendCommand(_payload, 1);

                    // let the user know
                    SetTransferState(TransferState.Succeeded);

                    // move to end
                    MachineFunctions.JumpToLast(currentStep);
                    return(StepReturn.JumpCommandUsed);
                }

                // not done with file, so send the next packet
                return(StepReturn.RepeatStep);
            }

            // switch to deal with packet error types
            switch (returnString)
            {
            case "&@f!c":
                // checksum error
                break;

            case "&@f!w":
                // flash write error
                break;

            case "&@f!r":
                // rebooting unit
                break;

            case "":
                // lost connection
                break;

            default:
                break;
            }

            // process the missed packet count
            return(ProcessMissedPage(_currentPage));
        }
        /// <summary>
        /// A function to upload an INI file to a unit for quick configuration.
        /// </summary>
        /// <param name="stream">The stream to upload to the unit.</param>
        /// <param name="message">A string containing any status messages from the uploader.</param>
        /// <param name="timeoutSeconds">Number of seconds to try the upload before canceling.</param>
        /// <returns>True if stream was uploaded successfully, false otherwise.</returns>
        public bool UploadIni(Stream stream, out string message, int timeoutSeconds = 5)
        {
            message = "";

            // make a local copy of the stream to upload
            var workingFile = new List <byte>();
            var payload     = new List <byte>();

            workingFile.AddRange(stream.ToByteArray());

            var          timeout         = DateTime.Now.AddSeconds(timeoutSeconds);
            var          pointer         = 0;
            ushort       page            = 0;
            ushort       missedPage      = 0;
            var          missedPageCount = 0;
            var          retransmit      = false;
            const string command         = "&@u";

            while (true)
            {
                if (timeout < DateTime.Now)
                {
                    message = "Download Timeout!";
                    return(false);
                }

                var payloadLength = Math.Min(workingFile.Count - pointer, 1024);

                if (!retransmit)
                {
                    // load the array into a list with page information
                    payload.Clear();
                    payload.AddRange(DataConversions.ConvertUInt16ToList(page));
                    payload.AddRange(workingFile.GetRange(pointer, payloadLength));
                    payload.AddRange(Checksums.Fletcher16(payload));

                    // add escapes to the payload
                    payload.EscapeList();

                    // add the command to the front of the payload
                    payload.InsertRange(0, Encoding.ASCII.GetBytes(command));
                }

                // send the data
                retransmit = false;
                var returnString = _port.SendCommand(payload, 1).FirstOrDefault();

                if (returnString?.Contains($"{command}{page},{payloadLength}") == true)
                {
                    // housekeeping variables
                    pointer += payloadLength;
                    page++;

                    // we had a good transfer, determine next step
                    if (pointer == workingFile.Count)
                    {
                        // we are at the end of the file, so tell the system we are done
                        payload.Clear();
                        payload.AddRange(DataConversions.ConvertUInt16ToList(0xFFFF));
                        payload.AddRange(Checksums.Fletcher16(payload));

                        // add escapes to the payload
                        payload.EscapeList();

                        // add the command to the front of the payload
                        payload.InsertRange(0, Encoding.ASCII.GetBytes(command));

                        // send command
                        var returnStrings = _port.SendCommand(payload, 5000);

                        if (returnStrings.Count > 0)
                        {
                            if (returnStrings[0].Contains("&@us"))
                            {
                                // upload successfull
                                message = "INI Upload Successfull!";
                                return(true);
                            }

                            if (returnStrings[0].Contains("&@ue"))
                            {
                                // file error
                                returnStrings[0] = returnStrings[0].Replace("&@ue", "");
                                returnStrings.RemoveRange(returnStrings.Count - 2, 2);
                                var substring = string.Join("\r\n", returnStrings.ToArray());
                                message = $"INI Upload Failed! The INI file had the following errors:{Environment.NewLine}{substring}";
                                return(false);
                            }
                        }
                        else
                        {
                            message = "Unable to parse INI file, unknown error!";
                            return(false);
                        }
                    }

                    // next loop
                    continue;
                }

                // switch to deal with packet error types
                switch (returnString)
                {
                case "&@u!c":
                    message = "Checksum Error!";
                    break;

                case "&@u!w":
                    message = "Data processing error!";
                    break;

                case "&@u!s":
                    message = "Upload Complete!";
                    break;

                case "&@u!e":
                    message = "Upload Error!";
                    break;

                case "":
                    message = "Lost Connection!";
                    break;

                default:
                    break;
                }

                // process the missed packet count
                if (page == missedPage)
                {
                    missedPageCount++;
                    if (missedPageCount > 5)
                    {
                        // upload failed
                        return(false);
                    }
                }
                else
                {
                    // missed a different page, so reset counter
                    missedPage      = page;
                    missedPageCount = 1;
                }

                // retransmit page
                retransmit = true;
            }
        }
Пример #3
0
        protected override bool StateMachine_TransferPacket(StepDefinition currentStep)
        {
            // check for connection
            if (!_comPortRef.IsConnected)
            {
                SetTransferState(TransferState.FailedConnection);
                MachineFunctions.JumpToLast(currentStep);
                return(StepReturn.JumpCommandUsed);
            }

            // update the users with % complete
            RunPercentUpdate();

            var payloadLength = Math.Min(_workingFile.Count - _pointer, 1024);

            if (_payloadPage != _currentPage)
            {
                // calculate read length
                _readLength = PageSize * PagesTransmitted;
                if (_pointer + _readLength > _workingFile.Count)
                {
                    _readLength = _workingFile.Count - _pointer;
                }

                // load the array into a list with _currentPage information
                _payload.Clear();
                _payload.AddRange(DataConversions.ConvertUInt16ToList(_currentPage));
                _payload.AddRange(_workingFile.GetRange(_pointer, _readLength));
                _payload.AddRange(Checksums.Fletcher16(_payload));

                // add escapes to the payload
                _payload.EscapeList();

                // add the command to the front of the payload
                _payload.InsertRange(0, Encoding.ASCII.GetBytes(Command));

                // update the housekeeping variables
                _payloadPage = _currentPage;
            }

            // send the data
            var returnString = _comPortRef.SendCommand(_payload, 1).FirstOrDefault();

            if (returnString?.Contains($"{Command}{_currentPage},{payloadLength}") == true)
            {
                // housekeeping variables
                _pointer     += payloadLength;
                _currentPage += PagesTransmitted;

                // we had a good transfer, determine next step
                if (_pointer == _workingFile.Count)
                {
                    // we are at the end of the file, so tell the system we are done
                    _payload.Clear();
                    _payload.AddRange(DataConversions.ConvertUInt16ToList(0xFFFF));
                    _payload.AddRange(Checksums.Fletcher16(_payload));

                    // add escapes to the payload
                    _payload.EscapeList();

                    // add the command to the front of the payload
                    _payload.InsertRange(0, Encoding.ASCII.GetBytes(Command));

                    // send command
                    var returnStrings = _comPortRef.SendCommand(_payload, 5000);

                    if (returnStrings.Count > 0)
                    {
                        if (returnStrings[0].Contains("&@us"))
                        {
                            // upload successfull
                            SetTransferState(TransferState.Succeeded);

                            // move to end
                            MachineFunctions.JumpToLast(currentStep);
                            return(StepReturn.JumpCommandUsed);
                        }

                        if (returnStrings[0].Contains("&@ue"))
                        {
                            // file error
                            returnStrings[0] = returnStrings[0].Replace("&@ue", "");
                            returnStrings.RemoveRange(returnStrings.Count - 2, 2);
                            var substring = string.Join("\r\n", returnStrings.ToArray());
                            SetTransferState(TransferState.FailedInvalidFile, $"INI Upload Failed! The INI file had the following errors:{Environment.NewLine}{substring}");

                            // move to end
                            MachineFunctions.JumpToLast(currentStep);
                            return(StepReturn.JumpCommandUsed);
                        }
                    }
                    else
                    {
                        SetTransferState(TransferState.Failed, "Unable to parse INI file, unknown error!");

                        // move to end
                        MachineFunctions.JumpToLast(currentStep);
                        return(StepReturn.JumpCommandUsed);
                    }
                }

                // next loop
                return(StepReturn.RepeatStep);
            }

            // switch to deal with packet error types
            switch (returnString)
            {
            case "&@u!c":
                SetTransferState(_currentTransferState, "Checksum Error!");
                break;

            case "&@u!w":
                SetTransferState(_currentTransferState, "Data Processing Error");
                break;

            case "&@u!s":
                SetTransferState(_currentTransferState, "Upload Complete");
                break;

            case "&@u!e":
                SetTransferState(_currentTransferState, "Upload Error");
                break;

            case "":
                SetTransferState(_currentTransferState, "Lost Connection");
                break;

            default:
                break;
            }

            // process the missed packet count
            return(ProcessMissedPage(_currentPage));
        }