Example #1
0
        /// <summary>
        /// Stop the download process.
        /// This will close the binary writer and
        /// set the serial port back to ADCP mode.
        /// </summary>
        public void CancelDownload()
        {
            // Stop the trying to ask for a download
            _cancelDownload = true;

            // Stop the download watchdog
            //StopDownloadWatchDog();

            // Close the file stream
            CloseBinaryWriter();

            // The D command will cancel any pending downloads
            // Send it twice to first ignore the last packet sent, then
            // stop the download process
            SendData(string.Format("{0}", RTI.Commands.AdcpCommands.CMD_DS_CANCEL));
            SendData(string.Format("{0}", RTI.Commands.AdcpCommands.CMD_DS_CANCEL));

            // Set the mode of the ADCP
            // TODO: Should check if it was previously something else
            Mode = AdcpSerialModes.ADCP;

            // Set the interval back to default
            SetTimerInterval();
        }
Example #2
0
        /// <summary>
        /// Parse the packet received from the serial port.
        /// The system is in Download mode, so the serial port
        /// is sending packets of data in XMODEM format.
        /// This will determine what type of packet is received
        /// and handle the packet.
        /// </summary>
        /// <param name="data">Data received from the serial port.</param>
        private void ParseDownloadData(byte[] data)
        {
            // Check for end of transfer
            // 20 is the length for the message
            // "<EOT> Transfer Complete"
            if (data.Length == 20 && data[0] == EOT)
            {
                // Close the file stream
                CloseBinaryWriter();

                // Stop the Download process
                CompleteDownload(true);

                return;
            }

            // Set the buffer size based off in high speed mode or not
            int bufferSize = DEFAULT_DL_BUFF_SIZE;
            if (_isHighSpeedDownload)
            {
                bufferSize = DEFAULT_HSDL_BUFF_SIZE;
            }

            // Add the data to a buffer.
            // This is to wait until a complete packet has arrived
            _downloadDataBuffer.AddRange(data);

            // If there is not enough data in the buffer
            // wait for more data
            while (_downloadDataBuffer.Count >= bufferSize + 5)
            {

                int retry = XMODEM_RETRY_LIMIT;
                int slowdown = 0;

                // Find the type of packet
                switch (_downloadDataBuffer[0])
                {
                    default:
                        SetReceiveBuffer("I");
                        _downloadDataBuffer.RemoveAt(0);
                        break;
                    case CAN:
                        break;
                    case SOH:
                        break;
                    case STX:
                        // Stop the loop from requesting the
                        // start of data
                        _cancelWaitForDownload = true;

                        byte[] Fbuff;
                        if (VerifyPacketSTX(_downloadDataBuffer.ToArray(), _seqNum, out Fbuff))
                        {
                            // Should be nothing else in the buffer
                            // the buffer should have only contained the packet
                            _downloadDataBuffer.Clear();

                            // Set how many bytes have been written
                            _byteswritten += Fbuff.Length;

                            // Show in the serial port console progress.
                            //Debug.Write(".");

                            // Add data to codec to parse and
                            // add to the database
                            if (_parseDownloadedData)
                            {
                                if (ReceiveAdcpSerialDataEvent != null)
                                {
                                    // Parse and write the data to the database and file
                                    this.ReceiveAdcpSerialDataEvent(Fbuff);
                                }
                            }
                            else
                            {
                                try
                                {
                                    // Write the data to the file only
                                    _downloadDataBinWriter.Write(Fbuff);
                                }
                                catch (Exception e)
                                {
                                    log.Error("Error trying to write serial port download data to file.", e);
                                }
                            }

                            // Write ACK back to serial port
                            // So the next packet will be sent
                            if (!SendACK())
                            {
                                // If command not sent properly
                                // try again.  If still not sent
                                // properly, there may be an issue
                                // with the serial port and stop
                                // trying to download
                                if (!SendACK())
                                {
                                    break;
                                }
                            }

                            // Publish the event of the current
                            // progress of the file download
                            PublishDownloadProgressEvent();

                            // Used to slow down the reading
                            // It may be to fast for the serial
                            // port to handle
                            if (slowdown > 0)
                            {
                                System.Threading.Thread.Sleep(slowdown);
                            }

                            // Reset retry
                            retry = XMODEM_RETRY_LIMIT;

                            // Set the sequence number
                            _seqNum++;
                            if (_seqNum > 255)
                                _seqNum = 0;
                        }
                        else
                        {
                            // Packet in the buffer was bad
                            // clear the buffer and request another packet
                            _downloadDataBuffer.Clear();

                            // Send NAK that data was not received properly
                            if (!SendNAK())
                            {
                                // If command not sent properly
                                // try again.  If still not sent
                                // properly, there may be an issue
                                // with the serial port and stop
                                // trying to download
                                if (!SendNAK())
                                {
                                    break;
                                }
                            }

                            System.Threading.Thread.Sleep(slowdown);

                            // Maybe we are not waiting long enough
                            // for the complete packet to arrive
                            slowdown += 10;
                            if (slowdown > 150)
                                slowdown = 150;

                            // Limit the number of times to get the
                            // packet if it fails
                            retry--;
                            if (retry < 1)
                            {
                                break;
                            }
                        }
                        break;
                    case EOT:
                        // Close the file stream
                        CloseBinaryWriter();

                        // Set the mode of the ADCP
                        // TODO: Should check if it was previously something else
                        Mode = AdcpSerialModes.ADCP;

                        break;
                }
            }
        }
Example #3
0
        /// <summary>
        /// Start the upload process.  This will set all the
        /// settings in needed to do an upload.  This includes
        /// pausing the read thread and setting the mode to Upload.
        /// </summary>
        private void StartUpload()
        {
            // Pause the read thread
            // This will make the read thread not read data from the serial port
            PauseReadThread(true);

            // Set the mode of the ADCP
            Mode = AdcpSerialModes.UPLOAD;

            // Set the interval to a large number
            // because we will not be using the read thread
            SetTimerInterval(2000);
        }
Example #4
0
        /// <summary>
        /// Reset all the settings back to standard ADCP mode.
        /// This includes resuming the read thread and setting
        /// the mode back to ADCP.
        /// </summary>
        private void CompleteUpload()
        {
            // Stop the upload loop
            XMODEM = false;

            // This will make the read thread resume reading data from the serial port
            PauseReadThread(false);

            // Set the mode of the ADCP
            Mode = AdcpSerialModes.ADCP;

            // Set the interval back to default
            SetTimerInterval();
        }
Example #5
0
        /// <summary>
        /// Stop the download process.  If the download process is complete
        /// or needs to be stopped, then return the ADCP to ADCP mode
        /// and starting reading at a normal interval rate again.
        /// </summary>
        /// <param name="goodDownload">Set flag that the download was good or bad when complete.</param>
        private void CompleteDownload(bool goodDownload)
        {
            // The D command will cancel any pending downloads
            // Send it twice to first ignore the last packet sent, then
            // stop the download process
            SendData(string.Format("{0}", RTI.Commands.AdcpCommands.CMD_DS_CANCEL));
            SendData(string.Format("{0}", RTI.Commands.AdcpCommands.CMD_DS_CANCEL));

            // Publish that download is complete for the file
            PublishDownloadCompleteEvent(goodDownload);

            // Stop the download watchdog
            //StopDownloadWatchDog();

            // Set the mode of the ADCP
            // TODO: Should check if it was previously something else
            Mode = AdcpSerialModes.ADCP;

            // Set the interval back to default
            SetTimerInterval();
        }
Example #6
0
        /// <summary>
        /// Download the file from the serial device using XMODE-CRC.
        /// Set parseData to determine what to do with the downloaded data.
        /// 
        /// About 3.5mb per minute download speed at 921600 baud rate.
        /// 
        /// If parseData is TRUE:
        /// The data will be published to the event: ReceiveAdcpSerialDataEvent.
        /// If parseData is FALSE:
        /// The data will be written to the file: dirName\fileName.
        /// </summary>
        /// <param name="dirName">Directory Name to store the files.</param>
        /// <param name="fileName">Filename to download.</param>
        /// <param name="parseData">Flag to parse and record data to the database. Default = FALSE.</param>
        /// <param name="isHighSpeed">Flag if we should download in high speed mode or not.  Default = TRUE.</param>
        /// <returns>TRUE = file successful download / FALSE = File not downloaded.</returns>
        public bool XModemDownload(string dirName, string fileName, bool parseData = false, bool isHighSpeed = true)
        {
            // Set the mode of the ADCP
            Mode = AdcpSerialModes.DOWNLOAD;
            _parseDownloadedData = parseData;
            _isHighSpeedDownload = isHighSpeed;

            // Clear the input buffer of any previous commands
            // and clear the Receive Buffer
            ClearInputBuffer();
            ReceiveBufferString = "";

            // Increase the time to check the serial port
            SetTimerInterval(DOWNLOAD_SERIAL_INTERVAL);

            _seqNum = 1;
            _byteswritten = 0;
            _fileName = fileName;
            _downloadDataBuffer = new List<byte>();

            bool C_ACK = false;
            _cancelWaitForDownload = false;
            _cancelDownload = false;
            bool xmodemCancel = false;
            byte[] buff = new byte[4];
            //byte[] bBuff = new byte[140000];
            //byte[] Dbuff = new byte[1024 + 5];

            long elapsedTicks;
            DateTime currentDate = DateTime.Now;
            long lastTicks = currentDate.Ticks;
            int retry = XMODEM_RETRY_LIMIT;

            // Create the file path
            string path = dirName + "\\" + fileName;

            try
            {
                // If we are not parsing the data, then
                // we will record the data here.  If we are
                // parsing the data, then the parser will also
                // record the data.
                if (!_parseDownloadedData)
                {
                    // Create a binarywriter to write the data to the file
                    _downloadDataBinWriter = CreateBinaryWriter(path);
                }

                // Ensure the serial port is open and accepting commands
                if (IsAvailable())
                {
                    {

                        // Send the command to download the file
                        // from the instrument
                        // It will choose if we are downloading in high speed mode or not
                        if (!SendCommandDSX(fileName))
                        {
                            // Command could not be sent
                            // so do not continue
                            return false;
                        }

                        elapsedTicks = 0;
                        currentDate = DateTime.Now;
                        lastTicks = currentDate.Ticks;
                        xmodemCancel = false;

                        // The response from the command is:
                        // "File Size = 0000000000"
                        // "READY"
                        // Wait for READY then begin
                        // If we never receive a READY,
                        // Complete the download for this file
                        long filesize = 0;
                        bool receivedREADY = CheckForREADY(out filesize);
                        while (!xmodemCancel && !receivedREADY && elapsedTicks < 100000000)
                        {
                            receivedREADY = CheckForREADY(out filesize);
                            currentDate = DateTime.Now;
                            elapsedTicks = currentDate.Ticks - lastTicks;
                        }

                        // READY was received from the ADCP
                        if (receivedREADY)
                        {
                            // Publish that a file size was found
                            PublishFileSizeEvent();

                            _downloadDataBuffer.Clear();

                            // Start the watchdog to monitor for a hanging download
                            //StartDownloadWatchDog();

                            xmodemCancel = false;

                            // Set the timeout to wait for data to come in
                            // 10000000 = 1 second
                            long TO = 10000000;
                            if (_isHighSpeedDownload)
                            {
                                switch (_serialOptions.BaudRate)
                                {
                                    default:
                                        TO = 100000000;
                                        break;
                                    case 921600:
                                        TO = 20000000;
                                        break;
                                    case 115200:
                                        TO = 40000000;
                                        break;
                                }
                            }

                            // _startTransfer is set set true when the incoming data is parsed
                            // and an STX packet is valid in ParseDownloadData()
                            // _cancelDownload is set true if the user tries to cancel the download
                            // When the serial port receives data, it will call the event handler.
                            // The event handler will then process the packets for file data in ParseDownloadData().
                            while (!_cancelWaitForDownload && !_cancelDownload)
                            {
                                try
                                {
                                    currentDate = DateTime.Now;
                                    elapsedTicks = currentDate.Ticks - lastTicks;

                                    // Wait for data
                                    if (elapsedTicks > TO)
                                    {
                                        lastTicks = currentDate.Ticks;

                                        // Send a Capital C character instead of a NAK to start
                                        // the transfer using XMODEM-CRC (16-Bit CRC instead of 8-Bit CRC)
                                        // If the sender responds by sending a packet, it is assumed the
                                        // sender knows XMODEM-CRC.  If no packet is sent, then assumed
                                        // the received does not know and fall back to traditional XMODEM.
                                        // Try at least 4 times to send C just in case one of the C was sent
                                        // bad.
                                        if (!C_ACK)
                                        {
                                            buff[0] = (byte)'C';
                                            SendData(buff, 0, 1);
                                        }
                                        // If not going to use XMODEM-CRC, then send
                                        // a NAK to start the file transfer
                                        else
                                        {
                                            buff[0] = NAK;
                                            SendData(buff, 0, 1);
                                        }

                                        // Monitor number of retries
                                        // Did not receive a C
                                        // So stop trying to download
                                        retry--;
                                        if (retry < 1)
                                        {
                                            xmodemCancel = true;
                                        }
                                    }
                                }
                                catch(Exception e)
                                {
                                    log.Error("Error downloading a file from the ADCP.", e);
                                }

                                // Canceled download
                                if (xmodemCancel)
                                {
                                    // Stop trying to download the file
                                    _cancelWaitForDownload = true;

                                    // Close the file stream
                                    //CloseBinaryWriter();
                                    CancelDownload();

                                    // File could not be downloaded
                                    return false;
                                }
                            }
                        }
                        else
                        {
                            // The file could not be started
                            // So complete the download
                            CompleteDownload(false);

                            // Close the file stream
                            CloseBinaryWriter();

                            return false;
                        }
                    }
                }
            }
            catch(Exception e)
            {
                //OK = false;
                //Debug.WriteLine("Exception: {0}", e.ToString());
                log.Error("Error trying to download a file.", e);
                // Close the file stream
                CloseBinaryWriter();

                return false;
            }

            return true;
        }
Example #7
0
        /// <summary>
        /// Stop the ADCP from being in Compass mode.
        /// This will set the compass to interval mode, 
        /// then set the ADCP back to ADCP mode.
        /// </summary>
        public void StopCompassMode()
        {
            // Turn on compass interval outputing
            byte[] startIntervalCmd = PniPrimeCompassBinaryCodec.StartIntervalModeCommand();
            SendData(startIntervalCmd, 0, startIntervalCmd.Length);

            // Stop ADCP from compass mode
            SendDataWaitReply(RTI.Commands.AdcpCommands.CMD_DIAGCPT_DISCONNECT, TIMEOUT);

            // Set the serial port to ADCP mode to decode ADCP data
            Mode = AdcpSerialPort.AdcpSerialModes.ADCP;
        }
Example #8
0
        /// <summary>
        /// Start Compass mode.  This make the ADCP output
        /// compass data instead of ADCP data.
        /// </summary>
        /// <returns>TRUE if command sent properly.</returns>
        public bool StartCompassMode()
        {
            bool startResult = false;

            // Try to send the command, if it fails try again
            startResult = SendDataWaitReply(RTI.Commands.AdcpCommands.CMD_DIAGCPT, TIMEOUT);

            // If the command was not good, try it again
            if (!startResult)
            {
                startResult = SendDataWaitReply(RTI.Commands.AdcpCommands.CMD_DIAGCPT, TIMEOUT);
            }

            // If was capable of putting
            // into compass mode, change the mode
            if (startResult)
            {
                // Set the serial port to COMPASS mode to decode compass data
                Mode = AdcpSerialPort.AdcpSerialModes.COMPASS;
            }

            // Return if either failed
            return startResult;
        }