Remote Control Protocol

Status
Not open for further replies.

SCPD

QRT
Joined
Feb 24, 2001
Messages
0
Location
Virginia
Does anybody have any experience with the Remote Control Protocol and C# (or a .NET language)? When I attempt to send the string "STX A ETX 10" or "STX A ETX 9", all it does is send the same thing back to me. Does anybody have any example code (possibly with an explanation)? Thanks

The protocol is found in the manual at http://www.greamerica.com/download/manuals/PSR-500v1.3_Manual.pdf

"Appendix A - Remote Control Protocol" - Page: 115
 

DonS

Member
Joined
Jun 17, 2003
Messages
4,102
Location
Franktown, CO
The PSR-500 shouldn't be echoing received characters back to the sender.

What, exactly, are you sending? The two examples you listed are not valid. The only command that starts with STX 'A' is the "get status" command, which has a fixed format of:
STX 'A' ETX 'D'
(0x02 0x41 0x03 0x44)

The PSR-500 will send a much longer response, which does start with STX 'A'.
 

SCPD

QRT
Joined
Feb 24, 2001
Messages
0
Location
Virginia
That's probably my problem, I don't know how to translate to hexadecimal (like 0x41, I have no idea how to get to that).

Here is my code (probably would have been best to post this first, I hope you can understand C#):

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static SerialPort _serialPort;
        static bool _continue;

        static void Main(string[] args)
        {
            //COM4
            string message;
            StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
            Thread readThread = new Thread(Read);

            _serialPort = new SerialPort();

            _serialPort.PortName = "COM4";
            _serialPort.BaudRate = 115200;
            _serialPort.Parity = Parity.None;
            _serialPort.StopBits = StopBits.One;
            _serialPort.Handshake = Handshake.None;
            _serialPort.ReadTimeout = 500;
            _serialPort.WriteTimeout = 500;

            _serialPort.Open();
            _continue = true;
            readThread.Start();
            String strSend = "STX A ETX";
            _serialPort.WriteLine(strSend + " " + strSend.Length.ToString());
            message = Console.ReadLine();
            readThread.Join();
            _serialPort.Close();
        }

        public static void Read()
        {
            while (_continue)
            {
                try
                {
                    string message = _serialPort.ReadLine();
                    Console.WriteLine(message);
                }
                catch (TimeoutException) { }
            }
        }
    }
}
 

slicerwizard

Member
Joined
Sep 19, 2002
Messages
7,643
Location
Toronto, Ontario
That's probably my problem, I don't know how to translate to hexadecimal (like 0x41, I have no idea how to get to that).
Start/Programs/Accessories/Calculator/View/Scientific

STX, ETX, 0x41... You need to spend some time with an ASCII chart. And with your language's docs on escape sequences.

And you're sending a string length value? Don't the GRE docs say you're supposed to send a checksum value?
 

SCPD

QRT
Joined
Feb 24, 2001
Messages
0
Location
Virginia
I've taken a day to experiment with this and have learned more about ASCII and am starting to understand it more. Has anybody had any luck with .NET and communications and can either post or send me some sample code to learn from?
 

gmclam

Member
Premium Subscriber
Joined
Sep 15, 2006
Messages
6,335
Location
Fair Oaks, CA
That's probably my problem, I don't know how to translate to hexadecimal (like 0x41, I have no idea how to get to that).
What it looks like you are doing is sending a string "STX ..." rather than converting the STX into the single hex byte it represents. Being able to change the radix between ASCII, HEX, DECIMAL, OCTAL or unique characters (such as CR, LF, STX) is pretty much programming 101.
 

SCPD

QRT
Joined
Feb 24, 2001
Messages
0
Location
Virginia
Yeah, I skipped over that part when I was first learning to program 8-10 years ago. The following is my updated code, but running it gives me nothing. If I uncomment sending a blank line, I get a few symbols, but nothing expected. The checksum is from an example on the net as I didn't know what checksum it was looking for.

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static SerialPort _serialPort;
        static bool _continue;

        static void Main(string[] args)
        {
            //COM4
            string message;
            StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
            Thread readThread = new Thread(Read);

            _serialPort = new SerialPort();

            _serialPort.PortName = "COM4";
            _serialPort.BaudRate = 115200;
            _serialPort.Parity = Parity.None;
            _serialPort.StopBits = StopBits.One;
            _serialPort.Handshake = Handshake.None;
            _serialPort.ReadTimeout = 500;
            _serialPort.WriteTimeout = 500;

            _serialPort.Open();
            _continue = true;
            readThread.Start();



            ASCIIEncoding AsciiEncoding = new ASCIIEncoding();


            byte[] cmd = new byte[] { 2, 0x4b, 0x34, 3 };
            byte[] Checksum = Calculate(cmd);

            _serialPort.Write(cmd, 0, 4);
            _serialPort.Write(Checksum, 0, Checksum.Length);
            //_serialPort.WriteLine("");

            message = Console.ReadLine();
            readThread.Join();
            _serialPort.Close();
        }

        public static void Read()
        {
            while (_continue)
            {
                try
                {
                    string message = _serialPort.ReadLine();
                    Console.WriteLine(message);
                }
                catch (TimeoutException) { }
            }
        }


        // The CRC value table

        private static readonly UInt32[] CRCTable =
        {
            0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
            0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
            0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
            0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
            0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
            0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
            0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
            0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
            0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
            0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
            0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
            0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
            0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
            0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
            0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
            0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
            0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
            0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
            0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
            0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
            0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
            0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
            0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
            0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
            0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
            0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
            0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
            0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
            0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
            0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
            0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
            0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
            0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
            0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
            0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
            0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
            0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
            0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
            0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
            0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
            0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
            0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
            0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
            0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
            0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
            0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
            0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
            0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
            0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
            0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
            0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
            0x2d02ef8d
        };



        // The method that does the magic

        public static byte[] Calculate(byte[] Value)
        {

            UInt32 CRCVal = 0xffffffff;

            for (int i = 0; i < Value.Length; i++)
            {

                CRCVal = (CRCVal >> 8) ^ CRCTable[(CRCVal & 0xff) ^ Value[i]];

            }

            CRCVal ^= 0xffffffff; // Toggle operation

            byte[] Result = new byte[4];



            Result[0] = (byte)(CRCVal >> 24);

            Result[1] = (byte)(CRCVal >> 16);

            Result[2] = (byte)(CRCVal >> 8);

            Result[3] = (byte)(CRCVal);



            return Result;

        }
    }
}
 

mikey60

Member
Joined
Sep 15, 2003
Messages
3,543
Location
Oakland County Michigan
The Checksum is a single byte, and is the sum of all characters being transmitted following the STX up to and include the ETX character. It is not a CRC, as it appears you're trying to calculate if I read your code correctly.

Be careful when calculating the checksum as it can (and in most cases will) exceed the maximum value for a single byte.

Try this (syntax may not be 100% correct for C#):

byte[] cmd = new byte[] { 2, 0x4b, 0x34, 3 , 0 };

cmd[4] = (cmd[1]+cmd[2]+cmd[3]) & 0xff; // This is your checksum
_serialPort.Write(cmd, 0, 5);

Mike


Yeah, I skipped over that part when I was first learning to program 8-10 years ago. The following is my updated code, but running it gives me nothing. If I uncomment sending a blank line, I get a few symbols, but nothing expected. The checksum is from an example on the net as I didn't know what checksum it was looking for.

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static SerialPort _serialPort;
        static bool _continue;

        static void Main(string[] args)
        {
            //COM4
            string message;
            StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
            Thread readThread = new Thread(Read);

            _serialPort = new SerialPort();

            _serialPort.PortName = "COM4";
            _serialPort.BaudRate = 115200;
            _serialPort.Parity = Parity.None;
            _serialPort.StopBits = StopBits.One;
            _serialPort.Handshake = Handshake.None;
            _serialPort.ReadTimeout = 500;
            _serialPort.WriteTimeout = 500;

            _serialPort.Open();
            _continue = true;
            readThread.Start();



            ASCIIEncoding AsciiEncoding = new ASCIIEncoding();


            byte[] cmd = new byte[] { 2, 0x4b, 0x34, 3 };
            byte[] Checksum = Calculate(cmd);

            _serialPort.Write(cmd, 0, 4);
            _serialPort.Write(Checksum, 0, Checksum.Length);
            //_serialPort.WriteLine("");

            message = Console.ReadLine();
            readThread.Join();
            _serialPort.Close();
        }

        public static void Read()
        {
            while (_continue)
            {
                try
                {
                    string message = _serialPort.ReadLine();
                    Console.WriteLine(message);
                }
                catch (TimeoutException) { }
            }
        }


        // The CRC value table

        private static readonly UInt32[] CRCTable =
        {
            0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
            0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
            0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
            0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
            0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
            0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
            0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
            0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
            0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
            0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
            0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
            0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
            0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
            0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
            0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
            0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
            0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
            0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
            0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
            0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
            0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
            0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
            0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
            0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
            0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
            0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
            0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
            0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
            0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
            0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
            0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
            0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
            0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
            0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
            0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
            0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
            0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
            0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
            0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
            0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
            0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
            0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
            0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
            0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
            0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
            0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
            0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
            0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
            0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
            0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
            0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
            0x2d02ef8d
        };



        // The method that does the magic

        public static byte[] Calculate(byte[] Value)
        {

            UInt32 CRCVal = 0xffffffff;

            for (int i = 0; i < Value.Length; i++)
            {

                CRCVal = (CRCVal >> 8) ^ CRCTable[(CRCVal & 0xff) ^ Value[i]];

            }

            CRCVal ^= 0xffffffff; // Toggle operation

            byte[] Result = new byte[4];



            Result[0] = (byte)(CRCVal >> 24);

            Result[1] = (byte)(CRCVal >> 16);

            Result[2] = (byte)(CRCVal >> 8);

            Result[3] = (byte)(CRCVal);



            return Result;

        }
    }
}
 

DonS

Member
Joined
Jun 17, 2003
Messages
4,102
Location
Franktown, CO
Presuming you're trying to send a keypress command with the "4" key...
Code:
  byte[] cmd = new byte[] { 2, 0x4b, 34, 3 }; // STX 'K' 34 ETX
  byte[] Checksum = new byte[] { Calculate(cmd) };
  _serialPort.Write(cmd, 0, cmd.Length);
  _serialPort.Write(Checksum, 0, 1 );

...
  public static byte Calculate(byte[] Value)
    {
    byte rv;
    int i;
    for ( i=1, rv=0; i < Value.Length; rv += Value[i++] );
    return rv;
    }

The checksum is just a sum of all bytes in the message - not including the initial STX.

Note that the key value 34 is not expressed as a hexadecimal constant. It's decimal. There are no keys in the PSR-500 protocol with hex value 0x34 (decimal 52).
 

SCPD

QRT
Joined
Feb 24, 2001
Messages
0
Location
Virginia
Success, that sent '4' to the scanner! Thank you guys for your help!! I'm going to play around with this for a bit (learning it all and hopefully ASCII) and post if I have any further questions. I hope this code can be useful to others who want to use C# and control GRE Scanners!
 

SCPD

QRT
Joined
Feb 24, 2001
Messages
0
Location
Virginia
The following image shows the result when I get the LCD. Is there anyway to extract certain information from this (I thought maybe it was separated by tabs \t but that didn't work).
 

Attachments

  • Capture.JPG
    Capture.JPG
    30.2 KB · Views: 1,102

DonS

Member
Joined
Jun 17, 2003
Messages
4,102
Location
Franktown, CO
The LCD data (the 'L' command) returns 64 bytes of LCD contents (4 rows of 16 characters) followed by 2 bytes of icon flags. The data is not delimited.

In your capture above, the data starting with "01-0015" is the first row of the LCD's text area. (You're in MAN mode, looking at a TGRP object in scan list 1).

You'll have to parse the returned data. Presuming you get back an array of 70 bytes:
result[0] = STX
result[1] = 'L' (0x4C)
result[2] - result[17] = contents of LCD line 1
result[18] - result[33] = contents of LCD line 2
result[34] - result[49] = contents of LCD line 3
result[50] - result[65] = contents of LCD line 4
result[66] - result[67] = icon flags (see GRE protocol document)
result[68] = ETX
result[69] = <checksum> (all bytes from 'L' through ETX)
 

DomW

Member
Joined
Nov 21, 2005
Messages
40
Location
St. Clairsville, Ohio
I too am having some trouble with the protocol. My issue is how to get the frequency from the "Get Status" command. The manual says its laid out as <freqL> <freq2> <freq3> <freqH>. I have the Mac talking to the radio but for the life of me can't figure out how to break out the freq from the returned bytes. Any help would be greatly appreciated.
 

SCPD

QRT
Joined
Feb 24, 2001
Messages
0
Location
Virginia
Those four bytes are the frequency as a 32 bit integer with the least significant byte first.
 

DonS

Member
Joined
Jun 17, 2003
Messages
4,102
Location
Franktown, CO
Which he needs to do if he is using a Big Endian machine and dealing with Little Endian formatted reply.

Depens on implementation and programming language, of course. Even with straight C on a big-endian machine, I can think of a couple of methods that don't involve explicit "bit shifting".
 
Status
Not open for further replies.
Top