Ejemplo n.º 1
0
        /// <summary>
        /// Reads the data from the TCP port and verifies the target acknowledged the message. Target acknowledges
        /// the message sent from the application when no data is sent back from the target (i.e. a command was sent)
        /// </summary>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 ReceiveTargetAcknowledge()
        {
            // Allocate memory for the acknowledge
            byte[] rxMessage = new Byte[1];

            Int32 bytesRead = 0;

            while (bytesRead == 0)
            {
                // Read the TCP socket
                bytesRead = ReceiveMessage(rxMessage, 0);
                if (bytesRead < 0)
                {
                    return(bytesRead);
                }

                if (bytesRead == 1)
                {
                    // Verify ACK received
                    if (rxMessage[0] != ProtocolPTU.PTU_ACK)
                    {
                        m_TCPError = ProtocolPTU.Errors.AckNotReceieved;
                        return(-1);
                    }
                }
                else if (bytesRead > 1)
                {
                    // too many bytes read
                    m_TCPError = ProtocolPTU.Errors.ExcessiveBytesReceived;
                    return(-1);
                }
            }

            return(0);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This method is responsible for reading all available chars that are in the serial port
        /// sent by the embedded PTU. All characters are copied to the <paramref name="rxMessage"/>
        /// starting at the <paramref name="bufferOffset"/>. This feature allows multiple calls to
        /// this method until the entire message is received.
        /// </summary>
        /// <param name="rxMessage">buffer where the received message is stored</param>
        /// <param name="bufferOffset">offset into the receive buffer</param>
        /// <returns>less than 0 if any failure occurs; number of bytes read if successful</returns>
        private Int32 ReceiveMessage(Byte[] rxMessage, Int32 bufferOffset)
        {
            try
            {
                // Reset all variables
                m_BytesRead            = 0;
                m_AsyncExceptionThrown = false;
                // Start the asynchronous receive
                m_Client.Client.BeginReceive(rxMessage, bufferOffset, rxMessage.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);

                // AutoResetEvent signaled as soon as data is received
                Boolean rxSuccessful = m_ReceiveDone.WaitOne(SOCKET_ACTIVE_WAIT_TIME_MS);

                // Check for a message timeout
                if (!rxSuccessful)
                {
                    m_TCPError         = ProtocolPTU.Errors.ReceiveMessage;
                    m_ExceptionMessage = "RX Message Timeout";
                    return(-1);
                }
                // Check if asynchronous receive function threw an exception
                else if (m_AsyncExceptionThrown)
                {
                    return(-1);
                }
            }
            catch (Exception e)
            {
                m_TCPError         = ProtocolPTU.Errors.ReceiveMessage;
                m_ExceptionMessage = e.Message;
                return(-1);
            }

            return(m_BytesRead);
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Flushes the serial port transmit buffer
 /// </summary>
 /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
 private Int32 FlushTxBuffer()
 {
     try
     {
         m_SerialPort.DiscardOutBuffer();
     }
     catch (Exception e)
     {
         m_SerialError      = ProtocolPTU.Errors.SerialBufferFlush;
         m_ExceptionMessage = e.Message;
         return(-1);
     }
     return(0);
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Sends a message to the target via the serial port
 /// </summary>
 /// <param name="txMessage">the byte array to be sent to the embedded PTU</param>
 /// <returns>less than 0 if any failure occurs; number of bytes sent if successful</returns>
 private Int32 TransmitMessage(Byte[] txMessage)
 {
     // Send the entire message to the serial port
     try
     {
         m_SerialPort.Write(txMessage, 0, txMessage.Length);
     }
     catch (Exception e)
     {
         m_SerialError      = ProtocolPTU.Errors.TransmitMessage;
         m_ExceptionMessage = e.Message;
         return(-1);
     }
     return(txMessage.Length);
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Closes the serial port
        /// </summary>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 Close()
        {
            try
            {
                m_SerialPort.Close();
            }
            catch (Exception e)
            {
                m_SerialError      = ProtocolPTU.Errors.Close;
                m_ExceptionMessage = e.Message;
                return(-1);
            }

            return(0);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Receives a message from the target. It is assumed that the target sends a message with the first 2 bytes
        /// indicating the size of the message.
        /// </summary>
        /// <param name="rxMessage">array where the received message will be stored</param>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 ReceiveTargetDataPacket(Byte[] rxMessage)
        {
            // Verify the target responds with a SOM first
            Int32 errorCode = ReceiveStartOfMessage();

            if (errorCode < 0)
            {
                return(errorCode);
            }

            Int32 bytesRead      = 0;
            Int32 totalBytesRead = 0;
            // When the first 2 bytes are read, the received message size will be calculated
            UInt16 messageSize = UInt16.MaxValue;

            while (totalBytesRead != messageSize)
            {
                // read the serial receive buffer
                bytesRead = ReceiveMessage(rxMessage, totalBytesRead);
                if (bytesRead < 0)
                {
                    return(bytesRead);
                }

                // adjust the index into the receive buffer in case the entire message wasn't received
                totalBytesRead += bytesRead;

                if ((totalBytesRead >= 2) && (messageSize == UInt16.MaxValue))
                {
                    // 1st 2 bytes of the message is the message length
                    messageSize = BitConverter.ToUInt16(rxMessage, 0);
                    if (IsTargetBigEndian())
                    {
                        messageSize = Utils.ReverseByteOrder(messageSize);
                    }
                }
                // Verify the expected receive message length isn't too long
                if (totalBytesRead > messageSize)
                {
                    // too many bytes read
                    m_SerialError = ProtocolPTU.Errors.ExcessiveBytesReceived;
                    FlushRxBuffer();
                    return(-1);
                }
            }

            return(0);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Send a message to the embedded PTU target. The SOM is sent and then waits for an echo from the target.
        /// The message is then sent and an echo that is identical to the message sent is verified.
        /// </summary>
        /// <param name="txMessage">the message to be sent to the target</param>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 SendMessageToTarget(byte[] txMessage)
        {
            // Transmit the message to the target
            Int32 errorCode = TransmitMessage(txMessage);

            if (errorCode < 0)
            {
                return(errorCode);
            }

            // Create a buffer for the receive message which should be identical to the
            // message just sent
            Byte[] rxMessage = new Byte[txMessage.Length];

            // wait for the target logic to echo back the exact message just sent by the application
            // (NOTE: this is different than TCP which doesn't expect an echo)
            Int32 bytesRead      = 0;
            Int32 totalBytesRead = 0;

            while (totalBytesRead != rxMessage.Length)
            {
                bytesRead = ReceiveMessage(rxMessage, totalBytesRead);
                if (bytesRead < 0)
                {
                    return(bytesRead);
                }
                totalBytesRead += bytesRead;
                if (totalBytesRead > rxMessage.Length)
                {
                    // too many bytes read
                    m_SerialError = ProtocolPTU.Errors.ExcessiveBytesReceived;
                    FlushRxBuffer();
                    return(-1);
                }
            }

            // This compares the contents of the 2 arrays
            if (txMessage.SequenceEqual(rxMessage) == false)
            {
                // log error
                m_SerialError = ProtocolPTU.Errors.MessageEcho;
                return(-1);
            }

            return(0);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Closes the TCP connection gracefully by issuing a shutdown which effectively disables sends
        /// and receives on the socket and then closes the socket (issues a [FIN,ACK]).
        /// </summary>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 Close()
        {
            // TODO need to kill asynchronous threads when application closes because task lingers in task manager when closing
            // via  "x" on form
            try
            {
                m_Client.Client.Shutdown(SocketShutdown.Both);
                m_Client.Client.Dispose();
                m_Client.Close();
            }
            catch (Exception e)
            {
                m_TCPError         = ProtocolPTU.Errors.Close;
                m_ExceptionMessage = e.Message;
                return(-1);
            }

            return(0);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// This callback is invoked when data is received on the socket.
 /// </summary>
 /// <param name="ar">Required parameter for asynchronous callback; contains info about the socket</param>
 private void ReceiveCallback(IAsyncResult ar)
 {
     try
     {
         // Read data from the remote device.
         m_BytesRead = m_Client.Client.EndReceive(ar);
     }
     catch (Exception e)
     {
         m_AsyncExceptionThrown = true;
         m_ExceptionMessage     = e.Message;
         m_TCPError             = ProtocolPTU.Errors.ReceiveMessageAsync;
     }
     finally
     {
         // Signal that bytes have been received or an exception thrown
         m_ReceiveDone.Set();
     }
 }
Ejemplo n.º 10
0
 /// <summary>
 /// This callback is invoked when data is transmitted on the socket.
 /// </summary>
 /// <param name="ar">Required parameter for asynchronous callback; contains info about the socket</param>
 private void TransmitCallback(IAsyncResult ar)
 {
     try
     {
         // Complete sending the data to the remote device.
         m_BytesSent = m_Client.Client.EndSend(ar);
     }
     catch (Exception e)
     {
         m_TCPError             = ProtocolPTU.Errors.TransmitMessageAsync;
         m_AsyncExceptionThrown = true;
         m_ExceptionMessage     = e.Message;
     }
     finally
     {
         // Signal that bytes have been sent or an exception thrown
         m_TransmitDone.Set();
     }
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Receives the Start of Message byte from the target
        /// </summary>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        private Int32 ReceiveStartOfMessage()
        {
            // Allocate memory for the received byte
            byte[] startOfMessage = new byte[1];

            Int32 bytesRead = 0;

            while (bytesRead == 0)
            {
                bytesRead = ReceiveMessage(startOfMessage, 0);

                // Verify a valid call was made to ReceiveMessage()
                if (bytesRead < 0)
                {
                    return(bytesRead);
                }
                // Verify only 1 byte was read; if so save the byte
                if (bytesRead == 1)
                {
                    // Verify a valid SOM
                    if ((startOfMessage[0] == ProtocolPTU.THE_SOM) || (startOfMessage[0] == ProtocolPTU.TARGET_BIG_ENDIAN_SOM))
                    {
                        m_TargetStartOfMessage = startOfMessage[0];
                    }
                    else
                    {
                        m_TargetStartOfMessage = 0;
                        m_SerialError          = ProtocolPTU.Errors.InvalidSOM;
                        return(-1);
                    }
                }
                else if (bytesRead > 1)
                {
                    // too many bytes read
                    m_SerialError = ProtocolPTU.Errors.ExcessiveBytesReceived;
                    FlushRxBuffer();
                    return(-1);
                }
            }

            return(0);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Sends a message to the target via the serial port
        /// </summary>
        /// <param name="txMessage">the byte array to be sent to the embedded PTU</param>
        /// <returns>less than 0 if any failure occurs; number of bytes sent if successful</returns>
        private Int32 TransmitMessage(Byte[] txMessage)
        {
#if DAS
            // Send the entire message to the serial port
            try
            {
                m_SerialPort.Write(txMessage, 0, txMessage.Length);
            }
            catch (Exception e)
            {
                m_SerialError      = ProtocolPTU.Errors.TransmitMessage;
                m_ExceptionMessage = e.Message;
                return(-1);
            }
#else
            // Send the entire message to the serial port
            try
            {
                int i = 0;
                while (i < txMessage.Length)
                {
                    m_SerialPort.Write(txMessage, i, 1);
                    i++;
#if DAS
                    if ((i % 16) == 0)
                    {
                        Thread.Sleep(50);
                    }
#endif
                }
            }
            catch (Exception e)
            {
                m_SerialError      = ProtocolPTU.Errors.TransmitMessage;
                m_ExceptionMessage = e.Message;
                return(-1);
            }
#endif
            return(txMessage.Length);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// This method is invoked after a successful TCP connection (3 way handshake) with the embedded PTU
        /// is established. It sets a flag to inform the connection was established.
        /// </summary>
        /// <param name="result">delegate parameter required; UNUSED</param>
        private void ConnectCallback(IAsyncResult result)
        {
            try
            {
                // Retrieve the socket from the state object.
                Socket client = (Socket)result.AsyncState;

                // Complete the connection.
                client.EndConnect(result);
            }
            catch (Exception e)
            {
                m_TCPError             = ProtocolPTU.Errors.ConnectionErrorAsync;
                m_AsyncExceptionThrown = true;
                m_ExceptionMessage     = e.Message;
            }
            finally
            {
                // Signal that the connection has been made or an exception thrown
                m_ConnectDone.Set();
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Sends a message to the embedded TCP server target from the TCP client
        /// </summary>
        /// <param name="txMessage">the byte array to be sent to the embedded PTU</param>
        /// <returns>less than 0 if any failure occurs; number of bytes sent if successful</returns>
        private Int32 TransmitMessage(Byte[] txMessage)
        {
            // Send the entire message to the serial port
            try
            {
                // Reset all of the variables prior to starting an Asynchronous send
                m_BytesSent            = -1;
                m_AsyncExceptionThrown = false;

                // Start the transmit, the callback will set the AutoResetEvent when complete. NOTE: Asynchronous transmit
                // and receive calls are required because the PTU will "hang" (i.e. the main form thread will block) if someone
                // pulls the cable if synchronous calls were used.
                m_Client.Client.BeginSend(txMessage, 0, txMessage.Length, 0, new AsyncCallback(TransmitCallback), null);
                Boolean txSuccessful = m_TransmitDone.WaitOne(SOCKET_ACTIVE_WAIT_TIME_MS);

                // Verify a successful transmit
                if (!txSuccessful)
                {
                    // It wasn't log this a timeout error
                    m_TCPError         = ProtocolPTU.Errors.TransmitMessage;
                    m_ExceptionMessage = "TX Message Timeout";
                    return(-1);
                }
                // Determine if an exception was thrown in the callback
                else if (m_AsyncExceptionThrown)
                {
                    return(-1);
                }
            }
            catch (Exception e)
            {
                m_TCPError         = ProtocolPTU.Errors.TransmitMessage;
                m_ExceptionMessage = e.Message;
                return(-1);
            }

            return(m_BytesSent);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Reads the serial port and verifies the target acknowledged the message. Target acknowledges
        /// the message sent from the application when no data is sent back from the target (i.e. a command was sent)
        /// </summary>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 ReceiveTargetAcknowledge()
        {
            // Allocate memory for the acknowledge
            byte[] rxMessage = new Byte[1];

            Int32 bytesRead = 0;

            while (bytesRead == 0)
            {
                // Read the serial port
                bytesRead = ReceiveMessage(rxMessage, 0);
                if (bytesRead < 0)
                {
                    // bytesRead in this case is an error code
                    return(bytesRead);
                }

                if (bytesRead == 1)
                {
                    // Verify ACK received
                    if (rxMessage[0] != ProtocolPTU.PTU_ACK)
                    {
                        m_SerialError = ProtocolPTU.Errors.AckNotReceieved;
                        return(-1);
                    }
                }
                else if (bytesRead > 1)
                {
                    // too many bytes read
                    m_SerialError = ProtocolPTU.Errors.ExcessiveBytesReceived;
                    FlushRxBuffer();
                    return(-1);
                }
            }

            return(0);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// This method is responsible for reading all available chars that are in the serial port
        /// sent by the embedded PTU. All characters are copied to the <paramref name="rxMessage"/>
        /// starting at the <paramref name="bufferOffset"/>. This feature allows multiple calls to
        /// this method until the entire message is received.
        /// </summary>
        /// <param name="rxMessage">buffer where the received message is stored</param>
        /// <param name="bufferOffset">offset into the receive buffer</param>
        /// <returns>less than 0 if any failure occurs; number of bytes read if successful</returns>
        private Int32 ReceiveMessage(Byte[] rxMessage, Int32 bufferOffset)
        {
            Int32 bytesRead = 0;

            try
            {
                bytesRead = m_SerialPort.Read(rxMessage, bufferOffset, rxMessage.Length - bufferOffset);
            }
            catch (Exception e)
            {
                m_SerialError      = ProtocolPTU.Errors.ReceiveMessage;
                m_ExceptionMessage = e.Message;
                return(-1);
            }

            // Should always read bytes when this function is invoked, otherwise the buffer may be full
            if (bytesRead == 0)
            {
                m_ExceptionMessage = "Zero bytes read when expecting bytes";
                return(-1);
            }

            return(bytesRead);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// This function attempts to open a new connection with an embedded PTU.
        /// </summary>
        /// <param name="commaDelimitedOptions">valid URL or valid IP address</param>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 Open(String commaDelimitedOptions)
        {
            String url;

            IPAddress [] ipAddress;

            // There are no other options supported except passing the URL (could be IP address or
            // IPTCOM address)
            url = commaDelimitedOptions;

            // Any PTU object can only support 1 TCP client; ensures Open() is called only once per created object
            if (m_Client != null)
            {
                m_TCPError = ProtocolPTU.Errors.ClientPreviouslyCreated;
                return(-1);
            }

            // Create the TCPClient object
            m_Client = new TcpClient();

            // Attempt to resolve the URL to an IP address
            try
            {
                ipAddress = Dns.GetHostAddresses(url);
            }
            catch (Exception e)
            {
                m_TCPError         = ProtocolPTU.Errors.InvalidURL;
                m_ExceptionMessage = e.Message;
                return(-1);
            }

            // Verify at least one IP address is resolved
            if (ipAddress.Length == 0)
            {
                m_TCPError = ProtocolPTU.Errors.InvalidURL;
                return(-1);
            }

            // Scan through all of the resolved IP addresses and try connecting to the first
            // IP v4 address in the list; ignore the rest
            IPAddress ipv4Addr = null;

            foreach (IPAddress addr in ipAddress)
            {
                if (addr.AddressFamily == AddressFamily.InterNetwork)
                {
                    ipv4Addr = addr;
                    break;
                }
            }

            // Can't resolve URL into IPv4 Address
            if (ipv4Addr == null)
            {
                m_TCPError = ProtocolPTU.Errors.UnresolvableURL;
                return(-1);
            }

            // Try to establish a connection with the embedded PTU. This establishes the 3 way handshake with the
            // target
            try
            {
                m_AsyncExceptionThrown = false;
                // This is an asynchronous (non--blocking) TCP connection attempt. If a successful connection
                // occurs, the ConnectCallback() method will be invoked and m_Connected will be made true
                m_Client.BeginConnect(ipv4Addr, PTU_SERVER_SOCKET, new AsyncCallback(ConnectCallback), m_Client.Client);
                // Allow time for the connection to establish, if the connection is made and m_ConnectDone is signaled
                // in the callback, this function wakes up and moves so no extra time is wasted.
                bool connected = m_ConnectDone.WaitOne(SOCKET_ACTIVE_WAIT_TIME_MS);
                if (!connected)
                {
                    // It wasn't log this a timeout error
                    m_TCPError         = ProtocolPTU.Errors.ConnectionError;
                    m_ExceptionMessage = "Connection Timeout";
                    return(-1);
                }
                // Determine if an exception was thrown in the callback
                else if (m_AsyncExceptionThrown)
                {
                    return(-1);
                }
            }
            catch (SocketException e)
            {
                m_TCPError         = ProtocolPTU.Errors.ConnectionError;
                m_ExceptionMessage = e.Message;
                return(-1);
            }

            // Connection to PTU server was successful
            return(0);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Reads the serial port and verifies the target acknowledged the message. Target acknowledges
        /// the message sent from the application when no data is sent back from the target (i.e. a command was sent)
        /// </summary>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 ReceiveTargetAcknowledge()
        {
            // Allocate memory for the acknowledge
            byte[] rxMessage = new Byte[1];

            Int32 bytesRead = 0;
            while (bytesRead == 0)
            {
                // Read the serial port
                bytesRead = ReceiveMessage(rxMessage, 0);
                if (bytesRead < 0)
                {
                    // bytesRead in this case is an error code
                    return bytesRead;
                }

                if (bytesRead == 1)
                {
                    // Verify ACK received
                    if (rxMessage[0] != ProtocolPTU.PTU_ACK)
                    {
                        m_SerialError = ProtocolPTU.Errors.AckNotReceieved;
                        return -1;
                    }
                }
                else if (bytesRead > 1)
                {
                    // too many bytes read
                    m_SerialError = ProtocolPTU.Errors.ExcessiveBytesReceived;
                    FlushRxBuffer();
                    return -1;
                }
            }

            return 0;
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Sends a message to the embedded TCP server target from the TCP client
        /// </summary>
        /// <param name="txMessage">the byte array to be sent to the embedded PTU</param>
        /// <returns>less than 0 if any failure occurs; number of bytes sent if successful</returns>
        private Int32 TransmitMessage(Byte[] txMessage)
        {
            // Send the entire message to the serial port
            try
            {
                // Reset all of the variables prior to starting an Asynchronous send
                m_BytesSent = -1;
                m_AsyncExceptionThrown = false;

                // Start the transmit, the callback will set the AutoResetEvent when complete. NOTE: Asynchronous transmit
                // and receive calls are required because the PTU will "hang" (i.e. the main form thread will block) if someone
                // pulls the cable if synchronous calls were used.
                m_Client.Client.BeginSend(txMessage, 0, txMessage.Length, 0, new AsyncCallback(TransmitCallback), null);
                Boolean txSuccessful = m_TransmitDone.WaitOne(SOCKET_ACTIVE_WAIT_TIME_MS);

                // Verify a successful transmit
                if (!txSuccessful)
                {
                    // It wasn't log this a timeout error
                    m_TCPError = ProtocolPTU.Errors.TransmitMessage;
                    m_ExceptionMessage = "TX Message Timeout";
                    return -1;
                }
                // Determine if an exception was thrown in the callback
                else if (m_AsyncExceptionThrown)
                {
                    return -1;
                }
            }
            catch (Exception e)
            {
                m_TCPError = ProtocolPTU.Errors.TransmitMessage;
                m_ExceptionMessage = e.Message;
                return -1;
            }

            return m_BytesSent;
        }
Ejemplo n.º 20
0
 /// <summary>
 /// This callback is invoked when data is transmitted on the socket. 
 /// </summary>
 /// <param name="ar">Required parameter for asynchronous callback; contains info about the socket</param>
 private void TransmitCallback(IAsyncResult ar)
 {
     try
     {
         // Complete sending the data to the remote device.
         m_BytesSent = m_Client.Client.EndSend(ar);
     }
     catch (Exception e)
     {
         m_TCPError = ProtocolPTU.Errors.TransmitMessageAsync;
         m_AsyncExceptionThrown = true;
         m_ExceptionMessage = e.Message;
     }
     finally
     {
         // Signal that bytes have been sent or an exception thrown
         m_TransmitDone.Set();
     }
 }
Ejemplo n.º 21
0
 /// <summary>
 /// This method is responsible for reading all available chars that are in the serial port
 /// sent by the embedded PTU. All characters are copied to the <paramref name="rxMessage"/>
 /// starting at the <paramref name="bufferOffset"/>. This feature allows multiple calls to
 /// this method until the entire message is received.
 /// </summary>
 /// <param name="rxMessage">buffer where the received message is stored</param>
 /// <param name="bufferOffset">offset into the receive buffer</param>
 /// <returns>less than 0 if any failure occurs; number of bytes read if successful</returns>
 private Int32 ReceiveMessage(Byte[] rxMessage, Int32 bufferOffset)
 {
     Int32 bytesRead = 0;
     try
     {
         bytesRead = m_SerialPort.Read(rxMessage, bufferOffset, rxMessage.Length - bufferOffset);
     }
     catch (Exception e)
     {
         m_SerialError = ProtocolPTU.Errors.ReceiveMessage;
         m_ExceptionMessage = e.Message;
         return -1;
     }
     return bytesRead;
 }
Ejemplo n.º 22
0
        /// <summary>
        /// Opens the desired serial port based on the comma delimited string passed as the argument. The first argument
        /// is the COM port (e.g. COM1). The 2nd argument in the string is the baud rate (e.g. 19200). The 3rd argument is
        /// the parity (e.g. none, odd, or even). The 4th argument is the number of data bits (e.g. 8). The 5th argument is
        /// the number of stop bits (e.g. 1).
        /// </summary>
        /// <param name="commaDelimitedOptions">COM port settings - "COMX,BaudRate,Parity,DataBits,StopBits"</param>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 Open(string commaDelimitedOptions)
        {
            String[] options;
            options = commaDelimitedOptions.Split(',');

            // verify 5 comma delimited arguments
            if (options.Length != 5)
            {
                m_SerialError = ProtocolPTU.Errors.OptionsLengthIncorrect;
                return(-1);
            }

            // Save the port name (e.g. COM1)
            String portName = options[0];

            Int32 baudRate;

            try
            {
                baudRate = Convert.ToInt32(options[1]);
            }
            catch (Exception e)
            {
                m_SerialError      = ProtocolPTU.Errors.BaudRateConversion;
                m_ExceptionMessage = e.Message;
                return(-1);
            }

            // Default to no parity check
            Parity parity = Parity.None;

            switch (options[2].ToLower())
            {
            case "odd":
                parity = Parity.Odd;
                break;

            case "even":
                parity = Parity.Even;
                break;

            default:
                break;
            }

            // Set the number of data bits
            Int32 dataBits;

            try
            {
                dataBits = Convert.ToInt32(options[3]);
            }
            catch (Exception e)
            {
                m_SerialError      = ProtocolPTU.Errors.DataBitsConversion;
                m_ExceptionMessage = e.Message;
                return(-1);
            }

            // Default to 1 stop bit
            StopBits stopBits = StopBits.One;

            switch (options[4].ToLower())
            {
            case "0":
                stopBits = StopBits.None;
                break;

            case "2":
                stopBits = StopBits.Two;
                break;

            default:
                break;
            }

            // Open the serial port
            try
            {
                m_SerialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
                m_SerialPort.Open();
                m_SerialPort.ReadTimeout = m_ReadTimeout;
            }
            catch (Exception e)
            {
                m_SerialError      = ProtocolPTU.Errors.OpenSerialPort;
                m_ExceptionMessage = e.Message;
                return(-1);
            }

            // Flush the receive buffer
            Int32 errorCode = FlushRxBuffer();

            if (errorCode < 0)
            {
                return(errorCode);
            }

            // Flush the transmit buffer
            errorCode = FlushTxBuffer();
            if (errorCode < 0)
            {
                return(errorCode);
            }

            return(0);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// This method is invoked after a successful TCP connection (3 way handshake) with the embedded PTU
        /// is established. It sets a flag to inform the connection was established.
        /// </summary>
        /// <param name="result">delegate parameter required; UNUSED</param>
        private void ConnectCallback(IAsyncResult result)
        {
            try
            {
                // Retrieve the socket from the state object.
                Socket client = (Socket)result.AsyncState;

                // Complete the connection.
                client.EndConnect(result);
            }
            catch (Exception e)
            {
                m_TCPError = ProtocolPTU.Errors.ConnectionErrorAsync;
                m_AsyncExceptionThrown = true;
                m_ExceptionMessage = e.Message;
            }
            finally
            {
                // Signal that the connection has been made or an exception thrown
                m_ConnectDone.Set();
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Receives a message from the target. It is assumed that the target sends a message with the first 2 bytes
        /// indicating the size of the message.
        /// </summary>
        /// <param name="rxMessage">array where the received message will be stored</param>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 ReceiveTargetDataPacket(Byte[] rxMessage)
        {
            // Verify the target responds with a SOM first
            Int32 errorCode = ReceiveStartOfMessage();
            if (errorCode < 0)
            {
                return errorCode;
            }

            Int32 bytesRead = 0;
            Int32 totalBytesRead = 0;
            // When the first 2 bytes are read, the received message size will be calculated
            UInt16 messageSize = UInt16.MaxValue;
            while (totalBytesRead != messageSize)
            {
                // read the TCP receive buffer
                bytesRead = ReceiveMessage(rxMessage, totalBytesRead);
                if (bytesRead < 0)
                {
                    return bytesRead;
                }

                // adjust the index into the receive buffer in case the entire message wasn't received
                totalBytesRead += bytesRead;

                if ((totalBytesRead >= 2) && (messageSize == UInt16.MaxValue))
                {
                    // 1st 2 bytes of the message is the message length
                    messageSize = BitConverter.ToUInt16(rxMessage, 0);
                    if (IsTargetBigEndian())
                    {
                        messageSize = Utils.ReverseByteOrder(messageSize);
                    }
                }
                // Verify the expected receive message length isn't too long
                if (totalBytesRead > messageSize)
                {
                    // too many bytes read
                    m_TCPError = ProtocolPTU.Errors.ExcessiveBytesReceived;
                    return -1;
                }
            }

            return 0;
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Reads the data from the TCP port and verifies the target acknowledged the message. Target acknowledges
        /// the message sent from the application when no data is sent back from the target (i.e. a command was sent)
        /// </summary>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 ReceiveTargetAcknowledge()
        {
            // Allocate memory for the acknowledge
            byte[] rxMessage = new Byte[1];

            Int32 bytesRead = 0;
            while (bytesRead == 0)
            {
                // Read the TCP socket
                bytesRead = ReceiveMessage(rxMessage, 0);
                if (bytesRead < 0)
                {
                    return bytesRead;
                }

                if (bytesRead == 1)
                {
                    // Verify ACK received
                    if (rxMessage[0] != ProtocolPTU.PTU_ACK)
                    {
                        m_TCPError = ProtocolPTU.Errors.AckNotReceieved;
                        return -1;
                    }
                }
                else if (bytesRead > 1)
                {
                    // too many bytes read
                    m_TCPError = ProtocolPTU.Errors.ExcessiveBytesReceived;
                    return -1;
                }
            }

            return 0;
        }
Ejemplo n.º 26
0
        /// <summary>
        /// This function attempts to open a new connection with an embedded PTU.
        /// </summary>
        /// <param name="commaDelimitedOptions">valid URL or valid IP address</param>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 Open(String commaDelimitedOptions)
        {
            String url;
            IPAddress []ipAddress;

            // There are no other options supported except passing the URL (could be IP address or
            // IPTCOM address)
            url = commaDelimitedOptions;

            // Any PTU object can only support 1 TCP client; ensures Open() is called only once per created object
            if (m_Client != null)
            {
                m_TCPError = ProtocolPTU.Errors.ClientPreviouslyCreated;
                return -1;
            }

            // Create the TCPClient object
            m_Client = new TcpClient();

            // Attempt to resolve the URL to an IP address
            try
            {
                ipAddress = Dns.GetHostAddresses(url);
            }
            catch (Exception e)
            {
                m_TCPError = ProtocolPTU.Errors.InvalidURL;
                m_ExceptionMessage = e.Message;
                return -1;
            }

            // Verify at least one IP address is resolved
            if (ipAddress.Length == 0)
            {
                m_TCPError = ProtocolPTU.Errors.InvalidURL;
                return -1;
            }

            // Scan through all of the resolved IP addresses and try connecting to the first
            // IP v4 address in the list; ignore the rest
            IPAddress ipv4Addr = null;
            foreach (IPAddress addr in ipAddress)
            {
                if (addr.AddressFamily == AddressFamily.InterNetwork)
                {
                    ipv4Addr = addr;
                    break;
                }
            }

            // Can't resolve URL into IPv4 Address
            if (ipv4Addr == null)
            {
                m_TCPError = ProtocolPTU.Errors.UnresolvableURL;
                return -1;
            }

            // Try to establish a connection with the embedded PTU. This establishes the 3 way handshake with the
            // target
            try
            {
                m_AsyncExceptionThrown = false;
                // This is an asynchronous (non--blocking) TCP connection attempt. If a successful connection
                // occurs, the ConnectCallback() method will be invoked and m_Connected will be made true
                m_Client.BeginConnect(ipv4Addr, PTU_SERVER_SOCKET, new AsyncCallback(ConnectCallback), m_Client.Client);
                // Allow time for the connection to establish, if the connection is made and m_ConnectDone is signaled
                // in the callback, this function wakes up and moves so no extra time is wasted.
                bool connected = m_ConnectDone.WaitOne(SOCKET_ACTIVE_WAIT_TIME_MS);
                if (!connected)
                {
                    // It wasn't log this a timeout error
                    m_TCPError = ProtocolPTU.Errors.ConnectionError; 
                    m_ExceptionMessage = "Connection Timeout";
                    return -1;
                }
                // Determine if an exception was thrown in the callback
                else if (m_AsyncExceptionThrown)
                {
                    return -1;
                }
            }
            catch (SocketException e)
            {
                m_TCPError = ProtocolPTU.Errors.ConnectionError;
                m_ExceptionMessage = e.Message;
                return -1;
            }

            // Connection to PTU server was successful
            return 0;
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Send a message to the embedded PTU target. The SOM is sent and then waits for an echo from the target.
        /// The message is then sent and an echo that is identical to the message sent is verified.
        /// </summary>
        /// <param name="txMessage">the message to be sent to the target</param>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 SendMessageToTarget(byte[] txMessage)
        {
            // Transmit the message to the target
            Int32 errorCode = TransmitMessage(txMessage);
            if (errorCode < 0)
            {
                return errorCode;
            }

            // Create a buffer for the receive message which should be identical to the
            // message just sent
            Byte[] rxMessage = new Byte[txMessage.Length];

            // wait for the target logic to echo back the exact message just sent by the application
            // (NOTE: this is different than TCP which doesn't expect an echo)
            Int32 bytesRead = 0;
            Int32 totalBytesRead = 0;
            while (totalBytesRead != rxMessage.Length)
            {
                bytesRead = ReceiveMessage(rxMessage, totalBytesRead);
                if (bytesRead < 0)
                {
                    return bytesRead;
                }
                totalBytesRead += bytesRead;
                if (totalBytesRead > rxMessage.Length)
                {
                    // too many bytes read
                    m_SerialError = ProtocolPTU.Errors.ExcessiveBytesReceived;
                    FlushRxBuffer();
                    return -1;
                }
            }

            // This compares the contents of the 2 arrays
            if (txMessage.SequenceEqual(rxMessage) == false)
            {
                // log error
                m_SerialError = ProtocolPTU.Errors.MessageEcho;
                return -1;
            }

            return 0;
        }
Ejemplo n.º 28
0
 /// <summary>
 /// Sends a message to the target via the serial port
 /// </summary>
 /// <param name="txMessage">the byte array to be sent to the embedded PTU</param>
 /// <returns>less than 0 if any failure occurs; number of bytes sent if successful</returns>
 private Int32 TransmitMessage(Byte[] txMessage)
 {
     // Send the entire message to the serial port
     try
     {
         m_SerialPort.Write(txMessage, 0, txMessage.Length);
     }
     catch (Exception e)
     {
         m_SerialError = ProtocolPTU.Errors.TransmitMessage;
         m_ExceptionMessage = e.Message;
         return -1;
     }
     return txMessage.Length;
 }
Ejemplo n.º 29
0
        /// <summary>
        /// Opens the desired serial port based on the comma delimited string passed as the argument. The first argument
        /// is the COM port (e.g. COM1). The 2nd argument in the string is the baud rate (e.g. 19200). The 3rd argument is
        /// the parity (e.g. none, odd, or even). The 4th argument is the number of data bits (e.g. 8). The 5th argument is
        /// the number of stop bits (e.g. 1).
        /// </summary>
        /// <param name="commaDelimitedOptions">COM port settings - "COMX,BaudRate,Parity,DataBits,StopBits"</param>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 Open(string commaDelimitedOptions)
        {
            String[] options;
            options = commaDelimitedOptions.Split(',');

            // verify 5 comma delimited arguments
            if (options.Length != 5)
            {
                m_SerialError = ProtocolPTU.Errors.OptionsLengthIncorrect;
                return -1;
            }

            // Save the port name (e.g. COM1)
            String portName = options[0];

            Int32 baudRate;
            try
            {
                baudRate = Convert.ToInt32(options[1]);
            }
            catch (Exception e)
            {
                m_SerialError = ProtocolPTU.Errors.BaudRateConversion;
                m_ExceptionMessage = e.Message;
                return -1;
            }

            // Default to no parity check
            Parity parity = Parity.None;
            switch (options[2].ToLower())
            {
                case "odd":
                    parity = Parity.Odd;
                    break;

                case "even":
                    parity = Parity.Even;
                    break;

                default:
                    break;
            }

            // Set the number of data bits
            Int32 dataBits;
            try
            {
                dataBits = Convert.ToInt32(options[3]);
            }
            catch (Exception e)
            {
                m_SerialError = ProtocolPTU.Errors.DataBitsConversion;
                m_ExceptionMessage = e.Message;
                return -1;
            }

            // Default to 1 stop bit
            StopBits stopBits = StopBits.One;
            switch (options[4].ToLower())
            {
                case "0":
                    stopBits = StopBits.None;
                    break;

                case "2":
                    stopBits = StopBits.Two;
                    break;

                default:
                    break;
            }

            // Open the serial port
            try
            {
                m_SerialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
                m_SerialPort.Open();
                m_SerialPort.ReadTimeout = m_ReadTimeout;
            }
            catch (Exception e)
            {
                m_SerialError = ProtocolPTU.Errors.OpenSerialPort;
                m_ExceptionMessage = e.Message;
                return -1;
            }

            // Flush the receive buffer
            Int32 errorCode = FlushRxBuffer();
            if (errorCode < 0)
            {
                return errorCode;
            }

            // Flush the transmit buffer
            errorCode = FlushTxBuffer();
            if (errorCode < 0)
            {
                return errorCode;
            }

            return 0;
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Closes the serial port
        /// </summary>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 Close()
        {
            try
            {
                m_SerialPort.Close();
            }
            catch (Exception e)
            {
                m_SerialError = ProtocolPTU.Errors.Close;
                m_ExceptionMessage = e.Message;
                return -1;
            }

            return 0;
        }
Ejemplo n.º 31
0
 /// <summary>
 /// This callback is invoked when data is received on the socket. 
 /// </summary>
 /// <param name="ar">Required parameter for asynchronous callback; contains info about the socket</param>
 private void ReceiveCallback(IAsyncResult ar)
 {
     try
     {
         // Read data from the remote device.
         m_BytesRead = m_Client.Client.EndReceive(ar);
     }
     catch (Exception e)
     {
         m_AsyncExceptionThrown = true;
         m_ExceptionMessage = e.Message;
         m_TCPError = ProtocolPTU.Errors.ReceiveMessageAsync;
     }
     finally
     {
         // Signal that bytes have been received or an exception thrown
         m_ReceiveDone.Set();
     }
 }
Ejemplo n.º 32
0
        /// <summary>
        /// This method is responsible for reading all available chars that are in the serial port
        /// sent by the embedded PTU. All characters are copied to the <paramref name="rxMessage"/>
        /// starting at the <paramref name="bufferOffset"/>. This feature allows multiple calls to
        /// this method until the entire message is received.
        /// </summary>
        /// <param name="rxMessage">buffer where the received message is stored</param>
        /// <param name="bufferOffset">offset into the receive buffer</param>
        /// <returns>less than 0 if any failure occurs; number of bytes read if successful</returns>
        private Int32 ReceiveMessage(Byte[] rxMessage, Int32 bufferOffset)
        {
            try
            {
                // Reset all variables
                m_BytesRead = 0;
                m_AsyncExceptionThrown = false;
                // Start the asynchronous receive
                m_Client.Client.BeginReceive(rxMessage, bufferOffset, rxMessage.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);

                // AutoResetEvent signaled as soon as data is received
                Boolean rxSuccessful = m_ReceiveDone.WaitOne(SOCKET_ACTIVE_WAIT_TIME_MS);
                
                // Check for a message timeout 
                if (!rxSuccessful)
                {
                    m_TCPError = ProtocolPTU.Errors.ReceiveMessage;
                    m_ExceptionMessage = "RX Message Timeout";
                    return -1;
                }
                // Check if asynchronous receive function threw an exception
                else if (m_AsyncExceptionThrown)
                {
                    return -1;
                }
            }
            catch (Exception e)
            {
                m_TCPError = ProtocolPTU.Errors.ReceiveMessage;
                m_ExceptionMessage = e.Message;
                return -1;
            }

            return m_BytesRead;
        }
Ejemplo n.º 33
0
        /// <summary>
        /// Receives the Start Of Message (SOM) from the embedded the embedded PTU
        /// </summary>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        private Int32 ReceiveStartOfMessage()
        {
            // Allocate memory for the received byte
            byte[] startOfMessage = new byte[1];

            Int32 bytesRead = 0;
            while (bytesRead == 0)
            {
                bytesRead = ReceiveMessage(startOfMessage, 0);

                // Verify a valid call was made to ReceiveMessage()
                if (bytesRead < 0)
                {
                    return bytesRead;
                }
                // Verify only 1 byte was read; if so save the byte
                if (bytesRead == 1)
                {
                    if ((startOfMessage[0] == ProtocolPTU.THE_SOM) || (startOfMessage[0] == ProtocolPTU.TARGET_BIG_ENDIAN_SOM))
                    {
                        m_TargetStartOfMessage = startOfMessage[0];
                    }
                    else
                    {
                        m_TargetStartOfMessage = 0;
                        m_TCPError = ProtocolPTU.Errors.InvalidSOM;
                        return -1;
                    }
                }
                else if (bytesRead > 1)
                {
                    // too many bytes read
                    m_TCPError = ProtocolPTU.Errors.ExcessiveBytesReceived;
                    return -1;
                }
            }

            return 0;
        }
Ejemplo n.º 34
0
        /// <summary>
        /// Closes the TCP connection gracefully by issuing a shutdown which effectively disables sends
        /// and receives on the socket and then closes the socket (issues a [FIN,ACK]).
        /// </summary>
        /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
        public Int32 Close()
        {
            // TODO need to kill asynchronous threads when application closes because task lingers in task manager when closing
            // via  "x" on form
            try
            {
                
                m_Client.Client.Shutdown(SocketShutdown.Both);
                m_Client.Client.Dispose(); 
                m_Client.Close();
            }
            catch (Exception e)
            {
                m_TCPError = ProtocolPTU.Errors.Close;
                m_ExceptionMessage = e.Message;
                return -1;
            }

            return 0;
        }
Ejemplo n.º 35
0
 /// <summary>
 /// Flushes the serial port transmit buffer
 /// </summary>
 /// <returns>less than 0 if any failure occurs; greater than or equal to 0 if successful</returns>
 private Int32 FlushTxBuffer()
 {
     try
     {
         m_SerialPort.DiscardOutBuffer();
     }
     catch (Exception e)
     {
         m_SerialError = ProtocolPTU.Errors.SerialBufferFlush;
         m_ExceptionMessage = e.Message;
         return -1;
     }
     return 0;
 }