예제 #1
0
        /// <summary>
        /// This is used to initialize the last sequence number accepted by
        /// the Arduino.
        /// </summary>
        /// <param name="candidate">The candidate <c>Arduino</c> object to
        /// perform the initialization.</param>
        private static void InitializeLastSeqNr(Arduino candidate)
        {
            // So we start with a Read in contrast to the Run() method.  This
            // is because we can always expect the Arduino to be sending.  If
            // the program restarts, it will continue to send an ack for its
            // last received message, or an identify for its last detected
            // identify.
            int  seqNrAttemptsLeft = NUM_SEQ_NR_ATTEMPTS;
            bool identifiedSeqNr   = false;

            while (seqNrAttemptsLeft > 0 && !identifiedSeqNr)
            {
                try
                {
                    RxMessage receivedMessage = null;
                    // Read it, until it finds a complete message, or it times out.
                    while (receivedMessage == null)
                    {
                        receivedMessage = candidate.Read();
                    }
                    // Set the last sent sequence number according to what the
                    // Arduino is sending.
                    candidate.LastSentSeqNr = receivedMessage.Sequence > 0;
                    identifiedSeqNr         = true;
                }
                catch (TimeoutException)
                {
                    // If we time out, then the sent variable isn't going
                    // to be set, and it will be resent.
                }
                seqNrAttemptsLeft--;
            }
        }
예제 #2
0
        /// <summary>
        /// Tries to identify the arduino.
        /// </summary>
        /// <param name="candidate">The candidate to determine if it is an
        /// Arduino.</param>
        /// <returns>Whether or not the candidate was identified as an Arduino.
        /// </returns>
        private static bool TryIdentify(Arduino candidate)
        {
            // Setup the random numbers we will be sending.
            var identifyRequest = new APS.Data.Messages.Tx.Identify();

            identifyRequest.Random0 = (byte)candidate.Rand.Next();
            identifyRequest.Random1 = (byte)candidate.Rand.Next();
            // Sets the sequence, so it matches LastSentSeqNr.  The
            // LastSentSeqNr should already be set, so it is correct after a
            // Write().
            identifyRequest.Sequence = (byte)(candidate.LastSentSeqNr ? 1 : 0);

            // Position the identify request for sending.
            candidate.NextMessageToSend = identifyRequest;

            // Set the number of attempts we will allow to write.
            var numIdAttemptsLeft = NUM_ID_ATTEMPTS;
            var sent     = false;
            var received = false;

            candidate.Port.ReadExisting();
            // Do this until we run out of attempts, or until both are sent
            // and received.
            while (numIdAttemptsLeft > 0 && !(sent && received))
            {
                try
                {
                    if (numIdAttemptsLeft == NUM_ID_ATTEMPTS)
                    {
                        candidate.Write();
                    }
                    else
                    {
                        candidate.ReWrite(); // Write it.
                    }
                    sent = true;             // Mark that we wrote it.
                }
                catch (TimeoutException)
                {
                    // If we time out, then the sent variable isn't going
                    // to be set, and it will be resent.
                }

                // Set the number of attempts we will allow to read for this
                // write.
                var numIdReadAttemptsLeft = NUM_ID_READS_PER_SEND;
                // Read X times or until we have identified.
                while (numIdReadAttemptsLeft > 0 && !received)
                {
                    try
                    {
                        RxMessage receivedMessage = null;
                        while (receivedMessage == null) // Read it, until it finds a complete message.
                        {
                            receivedMessage = candidate.Read();
                        }
                        // Check to make sure we got the correct sequence number back.
                        var seqNrMatch = receivedMessage.Sequence == 0 && !candidate.LastSentSeqNr ||
                                         receivedMessage.Sequence == 1 && candidate.LastSentSeqNr;
                        // Make sure the sequence numbers match, and the received
                        // is message matches what is expected.
                        if (seqNrMatch && IsExpected(identifyRequest, receivedMessage))
                        {
                            received = true; // Mark that we successfully identified.
                            // Changes the last sequence number, so that it
                            // will represent what was last sent after the next Write().
                            candidate.LastSentSeqNr = !candidate.LastSentSeqNr;
                        }
                    }
                    catch (TimeoutException)
                    {
                        // If we time out, then the sent variable isn't going
                        // to be set, and it will be resent.
                    }

                    numIdReadAttemptsLeft--;
                }

                numIdAttemptsLeft--;
            }

            return(sent && received);
        }