Example #1
0
        /// <summary>
        /// Create new GM862GPS instance
        /// </summary>
        /// <param name="Port">Serial Port to use</param>
        public GM862GPS(String Port)
        {
            // We begin in IDLE state
            _CurrentState           = GM862GPSStates.Idle;
            _SerialFIFO_CommandMode = "";
            _SerialFIFI_IdleMode    = "";

            try
            {
                // Create new SerialPort Object
                _ComPort           = new SerialPort(Port, 19200, Parity.None, 8, StopBits.One);
                _ComPort.Handshake = Handshake.None;
                _ComPort.Open();
            }
            catch
            {
                // If failed throw error
                throw new GM862GPSException(GM862GPSException.FAILED_TO_CREATE);
            }

            // DataRecieved Handler
            _ComPort.DataReceived += new SerialDataReceivedEventHandler(_ComPort_DataReceived);

            // Create thread that handles Unsolicited Responses
            _ParseUnsolicitatedResponses          = new Thread(new ThreadStart(ParseUnsolicitedResponse));
            _ParseUnsolicitatedResponses.Priority = ThreadPriority.AboveNormal;
            _ParseUnsolicitatedResponses.Start();

            // Add onUnsolicitedResponse Handler to check for incomming SMS and Call
            OnUnsolicitedResponse += new UnsolicitedResponseEvent(CheckForNewSMS);
            OnUnsolicitedResponse += new UnsolicitedResponseEvent(CheckForCall);
        }
Example #2
0
        /// <summary>
        /// Create new GM862GPS instance
        /// </summary>
        /// <param name="Port">Serial Port to use</param>
        public GM862GPS(String Port)
        {
            // We begin in IDLE state
            _CurrentState = GM862GPSStates.Idle;
            _SerialFIFO_CommandMode = "";
            _SerialFIFI_IdleMode = "";

            try
            {
                // Create new SerialPort Object
                _ComPort = new SerialPort(Port, 19200, Parity.None, 8, StopBits.One);
                _ComPort.Handshake = Handshake.None;
                _ComPort.Open();
            }
            catch
            {
                // If failed throw error
                throw new GM862GPSException(GM862GPSException.FAILED_TO_CREATE);
            }

            // DataRecieved Handler
            _ComPort.DataReceived += new SerialDataReceivedEventHandler(_ComPort_DataReceived);

            // Create thread that handles Unsolicited Responses
            _ParseUnsolicitatedResponses = new Thread(new ThreadStart(ParseUnsolicitedResponse));
            _ParseUnsolicitatedResponses.Priority = ThreadPriority.AboveNormal;
            _ParseUnsolicitatedResponses.Start();

            // Add onUnsolicitedResponse Handler to check for incomming SMS and Call
            OnUnsolicitedResponse += new UnsolicitedResponseEvent(CheckForNewSMS);
            OnUnsolicitedResponse += new UnsolicitedResponseEvent(CheckForCall);
        }
Example #3
0
        /// <summary>
        /// Send Escape Sequence '+++'
        /// </summary>
        /// <returns>Return code</returns>
        public ResponseCodes Escape()
        {
            // Check if disposed
            // if (_Disposed) throw new ObjectDisposedException();

            ResponseCodes RecievedResponse;
            int           ResponseStart;
            int           ResponseLength;

            // Set Command state
            lock (_CurrentStateLock)
            {
                // Now where in command state
                _CurrentState = GM862GPSStates.Command;
            }

            Thread.Sleep(2500);

            // Send Command to Serial Port
            byte[] OutBuffer = System.Text.Encoding.UTF8.GetBytes("+++");
            lock (_ComPort) { _ComPort.Write(OutBuffer, 0, OutBuffer.Length); }

            Thread.Sleep(2500);

            // Now we wait for a response to come in
            RecievedResponse = WaitForResponse(out ResponseStart, out ResponseLength, 5000);

            // Delete response from FIFO
            lock (_SerialFIFO_CommandMode)
            {
                _SerialFIFO_CommandMode = _SerialFIFO_CommandMode.Substring(ResponseStart + ResponseLength);
            }

            // Return recieved response
            return(RecievedResponse);
        }
Example #4
0
        /// <summary>
        /// Request HTML page from Server
        /// !!! UNFINISHED !!!
        /// </summary>
        /// <param name="SocketID">Socket ID to use</param>
        /// <param name="Host">Host of server</param>
        /// <param name="Path">Path to fetch data from</param>
        /// <returns>Recieved HTTP Response</returns>
        public String RequestHTML(int SocketID, String Host, String Path)
        {
            // Check if disposed
            //if (_Disposed) throw new ObjectDisposedException();

            // Say we want to connect to Socket
            if (ExecuteCommand("AT#SD=" + SocketID.ToString() + ", 0,80,\"" + Host + "\",0,0,0", 50000) != ResponseCodes.CONNECT)
            {
                throw new GM862GPSException("Did not recieve CONNECT response");
            }

            // Object used for recieving HTML
            String RecievedData = "";

            // Build request
            String Request = "GET " + Path + " HTTP/1.1\r\n";
            Request += "Host: " + Host + "\r\n";
            Request += "Connection: Close\r\n";
            Request += "\r\n";

            // Send request
            byte[] OutBuffer = System.Text.Encoding.UTF8.GetBytes(Request);
            lock (_ComPort) { _ComPort.Write(OutBuffer, 0, OutBuffer.Length); }

            // Recieve data
            while (true)
            {
                // Wait for .5 sec for data to arrive
                if (!WaitForDataToArrive.WaitOne(500, true))
                {
                    // When exit recieved exit now
                    if (RecievedData.IndexOf("\r\nNO CARRIER\r\n") != -1)
                    {
                        RecievedData = RecievedData.Substring(0, RecievedData.LastIndexOf("\r\nNO CARRIER\r\n"));
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        break;
                    }

                    // No exit? Give some more time to get data
                    if (!WaitForDataToArrive.WaitOne(10000, true))
                    {
                        // If still no data Escape data mode
                        try { Escape(); }
                        catch { lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; } }

                        // Close socket
                        ExecuteCommand("AT#SH=" + SocketID.ToString(), 1000);
                        break;
                    }
                }

                // Add data to recieve buffer
                lock (_SerialFIFO_CommandMode)
                {
                    RecievedData += _SerialFIFO_CommandMode;
                    _SerialFIFO_CommandMode = "";
                }
            }

            // Return HTTP response
            return RecievedData;
        }
Example #5
0
        /// <summary>
        /// Execute AT Command. Wait until response is recieved.
        /// </summary>
        /// <param name="Command">Command to execute</param>
        /// <param name="Timeout">Timeout for response in miliseconds</param>
        /// <param name="ResponseBody">Returns the Response body</param>
        /// <returns>Recieved response code</returns>
        public ResponseCodes ExecuteCommand(String Command, int Timeout, out String ResponseBody)
        {
            /*
             * Send Command
             * Wait until command is send
             * Wait for last unsolicited response text is recieved
             * Go to command mode
             * Send \r\n to execute command
             * Wait until \r\n is send
             * Wait for response
             * Save command response body
             * Return response
            */

            // Check if disposed
               // if (_Disposed) throw new ObjectDisposedException();

            // Recieved response code
            ResponseCodes RecievedResponse;

            // Check if we are ready for Command
            lock (_CurrentStateLock)
            {
                if (_CurrentState != GM862GPSStates.Idle)
                    throw new GM862GPSException(GM862GPSException.NOT_IN_IDLE_STATE);
            }

            // Send AT to Serial Port
            byte[] OutBuffer = System.Text.Encoding.UTF8.GetBytes(Command);
            lock (_ComPort)
            {
                _ComPort.Write(OutBuffer, 0, OutBuffer.Length);

                // Wait until command is send
                while (_ComPort.BytesToWrite > 0)
                {
                    WaitForDataToArrive.WaitOne(10, false);
                }
            }

            // Check if in Idle State and set Command state
            lock (_CurrentStateLock)
            {
                if (_CurrentState != GM862GPSStates.Idle)
                    throw new GM862GPSException(GM862GPSException.NOT_IN_IDLE_STATE);

                // Now where in command state
                _CurrentState = GM862GPSStates.Command;
            }

            // Wait for last data to arrive
            // WaitOne returns true when no data recieved in given time
            // So this loop exits when for the last 10 mSec no data has arrived
            while (WaitForDataToArrive.WaitOne(10, false)) { }

            // Clear input buffer
            lock (_SerialFIFO_CommandMode)
            {
                _SerialFIFO_CommandMode = "";
            }

            // Send \r\n
            OutBuffer = System.Text.Encoding.UTF8.GetBytes("\r\n");
            lock (_ComPort)
            {
                _ComPort.Write(OutBuffer, 0, OutBuffer.Length);

                // Wait until send
                while (_ComPort.BytesToWrite > 0)
                {
                    WaitForDataToArrive.WaitOne(10, false);
                }
            }

            // Now we wait for a response to come in
            int ResponseStart=0;
            int ResponseLength;
            RecievedResponse = WaitForResponse(out ResponseStart, out ResponseLength, Timeout);

                // Now get response body and delete response from FIFO
                lock (_SerialFIFO_CommandMode)
                {
                    ResponseBody = _SerialFIFO_CommandMode.Substring(0, ResponseStart);
                    _SerialFIFO_CommandMode = _SerialFIFO_CommandMode.Substring(ResponseStart + ResponseLength);
                }

            // Return recieved response
            return RecievedResponse;
        }
Example #6
0
        /// <summary>
        /// Send Escape Sequence '+++'
        /// </summary>
        /// <returns>Return code</returns>
        public ResponseCodes Escape()
        {
            // Check if disposed
               // if (_Disposed) throw new ObjectDisposedException();

            ResponseCodes RecievedResponse;
            int ResponseStart;
            int ResponseLength;

            // Set Command state
            lock (_CurrentStateLock)
            {
                // Now where in command state
                _CurrentState = GM862GPSStates.Command;
            }

            Thread.Sleep(2500);

            // Send Command to Serial Port
            byte[] OutBuffer = System.Text.Encoding.UTF8.GetBytes("+++");
            lock (_ComPort) { _ComPort.Write(OutBuffer, 0, OutBuffer.Length); }

            Thread.Sleep(2500);

            // Now we wait for a response to come in
            RecievedResponse = WaitForResponse(out ResponseStart, out ResponseLength, 5000);

            // Delete response from FIFO
            lock (_SerialFIFO_CommandMode)
            {
                _SerialFIFO_CommandMode = _SerialFIFO_CommandMode.Substring(ResponseStart + ResponseLength);
            }

            // Return recieved response
            return RecievedResponse;
        }
Example #7
0
        /// <summary>
        /// Waits until it recieves a valid response code. 
        /// This command automaticly sets the state to IDLE or DATA
        /// Throws exception when no response is recieved within timeout time.
        /// </summary>
        /// <param name="ResponseStart">Returns the position in the FIFO of response</param>
        /// <param name="ResponseLength">Returns the length of the response</param>
        /// <param name="Timeout">Timeout in miliseconds</param>
        /// <returns>Received response code</returns>
        private ResponseCodes WaitForResponse(out int ResponseStart, out int ResponseLength, int Timeout)
        {
            // Check if disposed
               // if (_Disposed) throw new ObjectDisposedException();

            // Set TimeOut
            DateTime TimeOutAt = DateTime.Now.AddMilliseconds(Timeout);

            // Check if in Command or Data State
            lock (_CurrentStateLock)
            {
                if ((_CurrentState != GM862GPSStates.Command) && (_CurrentState != GM862GPSStates.Data))
                    throw new GM862GPSException(GM862GPSException.NOT_IN_COMMAND_OR_DATA_STATE);
            }

            // Search for response until timeout
            while (DateTime.Now < TimeOutAt)
            {
                // TODO:
                // Check if it's better to release/aquire lock for each response check
                lock (_SerialFIFO_CommandMode)
                {
                    //DebugMessage("Check");

                    // OK response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nOK\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nOK\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return ResponseCodes.OK;
                    }

                    // ERROR response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nERROR\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nERROR\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return ResponseCodes.ERROR;
                    }

                    // ERROR response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("+CMS ERROR: 321");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "+CMS ERROR: 321".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return ResponseCodes.ERROR;
                    }

                    // RING response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nRING\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nRING\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return ResponseCodes.RING;
                    }

                    // BUSY response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nBUSY\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nBUSY\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return ResponseCodes.BUSY;
                    }

                    // NO CARRIER response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nNO CARRIER\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nNO CARRIER\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return ResponseCodes.NO_CARRIER;
                    }

                    // NO DIALTONE response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nNO DIALTONE\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nNO DIALTONE\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return ResponseCodes.NO_DIALTONE;
                    }

                    // NO ANSWER response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nNO ANSWER\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nNO ANSWER\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return ResponseCodes.NO_ANSWER;
                    }

                    // CONNECT response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("CONNECT");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = _SerialFIFO_CommandMode.IndexOf("\r\n", ResponseStart + 2);
                        if (ResponseLength != -1)
                        {
                            ResponseLength = (ResponseLength - ResponseStart) + 2;
                            WaitForDataToArrive.Reset();
                            lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Data; }
                            return ResponseCodes.CONNECT;
                        }
                    }

                    // SEND_SMS_DATA (>) response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\n>");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\n>".Length;
                        WaitForDataToArrive.Reset();
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Data; }
                        return ResponseCodes.SEND_SMS_DATA;
                    }
                }

                WaitForDataToArrive.WaitOne(50, false);
            }

            // Response Timeout
            lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
            ResponseStart = -1;
            ResponseLength = 0;
            return ResponseCodes.ERROR;
        }
Example #8
0
        /// <summary>
        /// Execute AT Command. Wait until response is recieved.
        /// </summary>
        /// <param name="Command">Command to execute</param>
        /// <param name="Timeout">Timeout for response in miliseconds</param>
        /// <param name="ResponseBody">Returns the Response body</param>
        /// <returns>Recieved response code</returns>
        public ResponseCodes ExecuteCommand(String Command, int Timeout, out String ResponseBody)
        {
            /*
             * Send Command
             * Wait until command is send
             * Wait for last unsolicited response text is recieved
             * Go to command mode
             * Send \r\n to execute command
             * Wait until \r\n is send
             * Wait for response
             * Save command response body
             * Return response
             */

            // Check if disposed
            // if (_Disposed) throw new ObjectDisposedException();

            // Recieved response code
            ResponseCodes RecievedResponse;

            // Check if we are ready for Command
            lock (_CurrentStateLock)
            {
                if (_CurrentState != GM862GPSStates.Idle)
                {
                    throw new GM862GPSException(GM862GPSException.NOT_IN_IDLE_STATE);
                }
            }

            // Send AT to Serial Port
            byte[] OutBuffer = System.Text.Encoding.UTF8.GetBytes(Command);
            lock (_ComPort)
            {
                _ComPort.Write(OutBuffer, 0, OutBuffer.Length);

                // Wait until command is send
                while (_ComPort.BytesToWrite > 0)
                {
                    WaitForDataToArrive.WaitOne(10, false);
                }
            }

            // Check if in Idle State and set Command state
            lock (_CurrentStateLock)
            {
                if (_CurrentState != GM862GPSStates.Idle)
                {
                    throw new GM862GPSException(GM862GPSException.NOT_IN_IDLE_STATE);
                }

                // Now where in command state
                _CurrentState = GM862GPSStates.Command;
            }

            // Wait for last data to arrive
            // WaitOne returns true when no data recieved in given time
            // So this loop exits when for the last 10 mSec no data has arrived
            while (WaitForDataToArrive.WaitOne(10, false))
            {
            }

            // Clear input buffer
            lock (_SerialFIFO_CommandMode)
            {
                _SerialFIFO_CommandMode = "";
            }


            // Send \r\n
            OutBuffer = System.Text.Encoding.UTF8.GetBytes("\r\n");
            lock (_ComPort)
            {
                _ComPort.Write(OutBuffer, 0, OutBuffer.Length);

                // Wait until send
                while (_ComPort.BytesToWrite > 0)
                {
                    WaitForDataToArrive.WaitOne(10, false);
                }
            }

            // Now we wait for a response to come in
            int ResponseStart = 0;
            int ResponseLength;

            RecievedResponse = WaitForResponse(out ResponseStart, out ResponseLength, Timeout);


            // Now get response body and delete response from FIFO
            lock (_SerialFIFO_CommandMode)
            {
                ResponseBody            = _SerialFIFO_CommandMode.Substring(0, ResponseStart);
                _SerialFIFO_CommandMode = _SerialFIFO_CommandMode.Substring(ResponseStart + ResponseLength);
            }

            // Return recieved response
            return(RecievedResponse);
        }
Example #9
0
        /// <summary>
        /// Request HTML page from Server
        /// !!! UNFINISHED !!!
        /// </summary>
        /// <param name="SocketID">Socket ID to use</param>
        /// <param name="Host">Host of server</param>
        /// <param name="Path">Path to fetch data from</param>
        /// <returns>Recieved HTTP Response</returns>
        public String RequestHTML(int SocketID, String Host, String Path)
        {
            // Check if disposed
            //if (_Disposed) throw new ObjectDisposedException();

            // Say we want to connect to Socket
            if (ExecuteCommand("AT#SD=" + SocketID.ToString() + ", 0,80,\"" + Host + "\",0,0,0", 50000) != ResponseCodes.CONNECT)
            {
                throw new GM862GPSException("Did not recieve CONNECT response");
            }

            // Object used for recieving HTML
            String RecievedData = "";

            // Build request
            String Request = "GET " + Path + " HTTP/1.1\r\n";

            Request += "Host: " + Host + "\r\n";
            Request += "Connection: Close\r\n";
            Request += "\r\n";

            // Send request
            byte[] OutBuffer = System.Text.Encoding.UTF8.GetBytes(Request);
            lock (_ComPort) { _ComPort.Write(OutBuffer, 0, OutBuffer.Length); }

            // Recieve data
            while (true)
            {
                // Wait for .5 sec for data to arrive
                if (!WaitForDataToArrive.WaitOne(500, true))
                {
                    // When exit recieved exit now
                    if (RecievedData.IndexOf("\r\nNO CARRIER\r\n") != -1)
                    {
                        RecievedData = RecievedData.Substring(0, RecievedData.LastIndexOf("\r\nNO CARRIER\r\n"));
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        break;
                    }

                    // No exit? Give some more time to get data
                    if (!WaitForDataToArrive.WaitOne(10000, true))
                    {
                        // If still no data Escape data mode
                        try { Escape(); }
                        catch { lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; } }

                        // Close socket
                        ExecuteCommand("AT#SH=" + SocketID.ToString(), 1000);
                        break;
                    }
                }

                // Add data to recieve buffer
                lock (_SerialFIFO_CommandMode)
                {
                    RecievedData           += _SerialFIFO_CommandMode;
                    _SerialFIFO_CommandMode = "";
                }
            }

            // Return HTTP response
            return(RecievedData);
        }
Example #10
0
        /// <summary>
        /// Waits until it recieves a valid response code.
        /// This command automaticly sets the state to IDLE or DATA
        /// Throws exception when no response is recieved within timeout time.
        /// </summary>
        /// <param name="ResponseStart">Returns the position in the FIFO of response</param>
        /// <param name="ResponseLength">Returns the length of the response</param>
        /// <param name="Timeout">Timeout in miliseconds</param>
        /// <returns>Received response code</returns>
        private ResponseCodes WaitForResponse(out int ResponseStart, out int ResponseLength, int Timeout)
        {
            // Check if disposed
            // if (_Disposed) throw new ObjectDisposedException();

            // Set TimeOut
            DateTime TimeOutAt = DateTime.Now.AddMilliseconds(Timeout);

            // Check if in Command or Data State
            lock (_CurrentStateLock)
            {
                if ((_CurrentState != GM862GPSStates.Command) && (_CurrentState != GM862GPSStates.Data))
                {
                    throw new GM862GPSException(GM862GPSException.NOT_IN_COMMAND_OR_DATA_STATE);
                }
            }

            // Search for response until timeout
            while (DateTime.Now < TimeOutAt)
            {
                // TODO:
                // Check if it's better to release/aquire lock for each response check
                lock (_SerialFIFO_CommandMode)
                {
                    //DebugMessage("Check");

                    // OK response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nOK\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nOK\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return(ResponseCodes.OK);
                    }

                    // ERROR response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nERROR\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nERROR\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return(ResponseCodes.ERROR);
                    }

                    // ERROR response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("+CMS ERROR: 321");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "+CMS ERROR: 321".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return(ResponseCodes.ERROR);
                    }


                    // RING response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nRING\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nRING\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return(ResponseCodes.RING);
                    }

                    // BUSY response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nBUSY\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nBUSY\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return(ResponseCodes.BUSY);
                    }

                    // NO CARRIER response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nNO CARRIER\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nNO CARRIER\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return(ResponseCodes.NO_CARRIER);
                    }

                    // NO DIALTONE response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nNO DIALTONE\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nNO DIALTONE\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return(ResponseCodes.NO_DIALTONE);
                    }

                    // NO ANSWER response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\nNO ANSWER\r\n");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\nNO ANSWER\r\n".Length;
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
                        return(ResponseCodes.NO_ANSWER);
                    }

                    // CONNECT response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("CONNECT");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = _SerialFIFO_CommandMode.IndexOf("\r\n", ResponseStart + 2);
                        if (ResponseLength != -1)
                        {
                            ResponseLength = (ResponseLength - ResponseStart) + 2;
                            WaitForDataToArrive.Reset();
                            lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Data; }
                            return(ResponseCodes.CONNECT);
                        }
                    }

                    // SEND_SMS_DATA (>) response
                    ResponseStart = _SerialFIFO_CommandMode.IndexOf("\r\n>");
                    if (ResponseStart != -1)
                    {
                        ResponseLength = "\r\n>".Length;
                        WaitForDataToArrive.Reset();
                        lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Data; }
                        return(ResponseCodes.SEND_SMS_DATA);
                    }
                }

                WaitForDataToArrive.WaitOne(50, false);
            }

            // Response Timeout
            lock (_CurrentStateLock) { _CurrentState = GM862GPSStates.Idle; }
            ResponseStart  = -1;
            ResponseLength = 0;
            return(ResponseCodes.ERROR);
        }