GPS Socket communication (CONCOX)

后端 未结 2 635
梦毁少年i
梦毁少年i 2020-11-27 07:36

1]1i have a gps device that should send GPRMC Data but it require login packect Review the dataSheet Device DataSheet

i can recieve the login 787811010

相关标签:
2条回答
  • 2020-11-27 08:12

    Here is section 2 :

          public void ProcessMessages()
            {
                UInt16 sendCRC = 0;
                DateTime date;
                int year = 0;
                int month = 0;
                int day = 0;
                int hour = 0;
                int minute = 0;
                int second = 0;
    
                KeyValuePair<List<byte>, StateObject> byteState;
                KeyValuePair<UNPACK_STATUS, byte[]> status;
                byte[] receiveMessage = null;
                StateObject state = null;
                byte[] serialNumber = null;
                byte[] serverFlagBit = null;
                byte[] stringArray = null;
                string stringMessage = "";
                byte lengthOfCommand = 0;
                PROTOCOL_NUMBER protocolNumber = PROTOCOL_NUMBER.NONE;
    
                try
                {
                    Boolean firstMessage = true;
                    acceptDone.Set();
                    //loop forever
                    while (true)
                    {
                        allDone.WaitOne();
    
                        //read fifo until empty
                        while (true)
                        {
                            //read one connection until buffer doesn't contain any more packets
                            byteState = ReadWrite(PROCESS_STATE.PROCESS, null, null, -1);
    
                            if (byteState.Value.fifoCount == -1) break;
    
                            state = byteState.Value;
                            while (true)
                            {
                                status = Unpack(byteState);
                                if (status.Key == UNPACK_STATUS.NOT_ENOUGH_BYTES)
                                    break;
    
                                if (status.Key == UNPACK_STATUS.ERROR)
                                {
                                    Console.WriteLine("Error : Bad Receive Message, Data");
                                    break;
                                }
    
                                //message is 2 start bytes + 1 byte (message length) + 1 byte message length + 2 end bytes
                                receiveMessage = status.Value;
    
                                int messageLength = receiveMessage[2];
                                Console.WriteLine("Status : '{0}', Receive Message : '{1}'", status.Key == UNPACK_STATUS.GOOD_MESSAGE ? "Good" : "Bad", BytesToString(receiveMessage.Take(messageLength + 5).ToArray()));
    
                                if (status.Key != UNPACK_STATUS.GOOD_MESSAGE)
                                {
                                    break;
                                }
                                else
                                {
                                    if (firstMessage)
                                    {
                                        if (receiveMessage[3] != 0x01)
                                        {
                                            Console.WriteLine("Error : Expected Login Message : '{0}'", BytesToString(receiveMessage));
                                            break;
                                        }
                                        firstMessage = false;
                                    }
    
                                    //skip start bytes, message length.  then go back 4 bytes (CRC and serial number)
                                    serialNumber = receiveMessage.Skip(2 + 1 + messageLength - 4).Take(2).ToArray();
    
                                    protocolNumber = (PROTOCOL_NUMBER)receiveMessage[3];
                                    Console.WriteLine("Protocol Number : '{0}'",protocolNumber.ToString());
                                    switch (protocolNumber)
                                    {
                                        case PROTOCOL_NUMBER.LOGIN_MESSAGE:
                                            serialNumber.CopyTo(loginResponse, 4);
    
                                            sendCRC = crc_bytes(loginResponse.Skip(2).Take(loginResponse.Length - 6).ToArray());
    
                                            loginResponse[loginResponse.Length - 4] = (byte)((sendCRC >> 8) & 0xFF);
                                            loginResponse[loginResponse.Length - 3] = (byte)((sendCRC) & 0xFF);
    
                                            //
                                            string IMEI = Encoding.ASCII.GetString(receiveMessage.Skip(4).Take(messageLength - 5).ToArray());
                                            byteState.Value.IMEI = IMEI;
    
                                            Console.WriteLine("Received good login message from Serial Number : '{0}', Terminal ID = '{1}'", "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"), IMEI);
    
                                            Console.WriteLine("Send Message : '{0}'", BytesToString(loginResponse));
                                            Send(state.workSocket, loginResponse);
    
                                            WriteDBMessageLogin loginMessage = new WriteDBMessageLogin() { message = DATABASE_MESSAGE_TYPE.LOGIN, IMEI = IMEI, date = DateTime.Now };
    
                                            WriteDBAsync.ReadWriteFifo(WriteDBAsync.Mode.WRITE, loginMessage);
    
                                            Console.WriteLine("Wrote to database");
                                            break;
                                        case PROTOCOL_NUMBER.LOCATION_DATA:
                                            year = receiveMessage[4];
                                            month = receiveMessage[5];
                                            day = receiveMessage[6];
                                            hour = receiveMessage[7];
                                            minute = receiveMessage[8];
                                            second = receiveMessage[9];
    
                                            date = new DateTime(2000 + year, month, day, hour, minute, second);
    
                                            WriteDBMessageLocation locationMessage = new WriteDBMessageLocation();
                                            locationMessage.message = DATABASE_MESSAGE_TYPE.LOCATION;
    
                                            locationMessage.trackTime = date;
                                            locationMessage.currTime = DateTime.Now;
    
                                            locationMessage.lattitude = new byte[4];
                                            Array.Copy(receiveMessage, 11, locationMessage.lattitude, 0, 4);
    
                                            locationMessage.longitude = new byte[4];
                                            Array.Copy(receiveMessage, 15, locationMessage.longitude, 0, 4);
                                            locationMessage.speed = receiveMessage[19];
    
                                            locationMessage.courseStatus = new byte[2];
                                            Array.Copy(receiveMessage, 20, locationMessage.courseStatus, 0, 2);
    
                                            locationMessage.IMEI = byteState.Value.IMEI;
                                            WriteDBAsync.ReadWriteFifo(WriteDBAsync.Mode.WRITE, locationMessage);
    
    
                                            Console.WriteLine("Received good location message from Serial Number '{0}', Time = '{1}'", "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"), date.ToLongDateString());
                                            break;
    
                                        case PROTOCOL_NUMBER.ALARM_DATA:
    
                                            //first response
                                            int alarmPacketLen = alarmResponse.Length - 5;
                                            alarmResponse[2] = (byte)(alarmPacketLen & 0xFF);
    
                                            serialNumber.CopyTo(alarmResponse, alarmPacketLen - 1);
    
                                            sendCRC = crc_bytes(alarmResponse.Skip(2).Take(alarmPacketLen - 1).ToArray());
    
                                            alarmResponse[alarmPacketLen + 1] = (byte)((sendCRC >> 8) & 0xFF);
                                            alarmResponse[alarmPacketLen + 2] = (byte)((sendCRC) & 0xFF);
    
                                            Console.WriteLine("Send Alarm Response Message : '{0}'", BytesToString(alarmResponse));
                                            Send(state.workSocket, alarmResponse);
    
    
                                            //second response
                                            year = receiveMessage[4];
                                            month = receiveMessage[5];
                                            day = receiveMessage[6];
                                            hour = receiveMessage[7];
                                            minute = receiveMessage[8];
                                            second = receiveMessage[9];
    
                                            date = new DateTime(2000 + year, month, day, hour, minute, second);
                                            Console.WriteLine("Received good alarm message from Serial Number '{0}', Time = '{1}'", "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"), date.ToLongDateString());
                                            int alarmDataAddressPacketLen = alarmDataAddressResponse.Length - 5;
                                            alarmDataAddressResponse[2] = (byte)(alarmDataAddressPacketLen & 0xFF);
    
                                            serialNumber.CopyTo(alarmDataAddressResponse, alarmDataAddressPacketLen - 1);
    
                                            sendCRC = crc_bytes(alarmDataAddressResponse.Skip(2).Take(alarmDataAddressPacketLen - 1).ToArray());
    
                                            alarmDataAddressResponse[alarmDataAddressPacketLen + 1] = (byte)((sendCRC >> 8) & 0xFF);
                                            alarmDataAddressResponse[alarmDataAddressPacketLen + 2] = (byte)((sendCRC) & 0xFF);
    
                                            Console.WriteLine("Send Alarm Data Address Message : '{0}'", BytesToString(alarmDataAddressResponse));
                                            Send(state.workSocket, alarmDataAddressResponse);
    
                                            break;
    
                                        case PROTOCOL_NUMBER.STATUS_INFO:
                                            serialNumber.CopyTo(heartbeatResponse, 4);
    
                                            byte info = receiveMessage[4];
                                            byte voltage = receiveMessage[5];
                                            byte GSMsignalStrength = receiveMessage[6];
                                            UInt16 alarmLanguage = (UInt16)((receiveMessage[7] << 8) | receiveMessage[8]);
    
                                            ALARM alarm = (ALARM)((info >> 3) & 0x07);
    
                                            sendCRC = crc_bytes(heartbeatResponse.Skip(2).Take(heartbeatResponse.Length - 6).ToArray());
    
                                            heartbeatResponse[heartbeatResponse.Length - 4] = (byte)((sendCRC >> 8) & 0xFF);
                                            heartbeatResponse[heartbeatResponse.Length - 3] = (byte)((sendCRC) & 0xFF);
    
                                            Console.WriteLine("Received good status message from Serial Number : '{0}', INFO : '0x{1}{2}{3}{4}'",
                                                "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"),
                                                info.ToString("X2"), voltage.ToString("X2"), GSMsignalStrength.ToString("X2"),
                                                alarmLanguage.ToString("X4"));
    
                                            Console.WriteLine("Send Message : '{0}'", BytesToString(heartbeatResponse));
                                            Send(state.workSocket, heartbeatResponse);
    
                                            switch (alarm)
                                            {
                                                //reset cut off alarm
                                                case ALARM.POWER_CUT_ALARM:
                                                    int connectOilAndElectricityPacketLen = connectOilAndEletricity.Length - 5;
                                                    serialNumber.CopyTo(connectOilAndEletricity, connectOilAndElectricityPacketLen - 1);
                                                    sendCRC = crc_bytes(connectOilAndEletricity.Skip(2).Take(connectOilAndEletricity.Length - 6).ToArray());
                                                    connectOilAndEletricity[connectOilAndEletricity.Length - 4] = (byte)((sendCRC >> 8) & 0xFF);
                                                    connectOilAndEletricity[connectOilAndEletricity.Length - 3] = (byte)((sendCRC) & 0xFF);
    
                                                    serverFlagBit = new byte[4];
                                                    Array.Copy(connectOilAndEletricity, 5, serverFlagBit, 0, 4);
    
                                                    lengthOfCommand = connectOilAndEletricity[4];
                                                    stringArray = new byte[lengthOfCommand - 4]; //do not include server flag bit
                                                    Array.Copy(connectOilAndEletricity, 9, stringArray, 0, lengthOfCommand - 4);
                                                    stringMessage = Encoding.ASCII.GetString(stringArray);
    
                                                    Console.WriteLine("Reset Oil and Electricity, Server Flag Bit : '{0}{1}{2}{3}', Message : '{4}'",
                                                      serverFlagBit[0].ToString("X2"),
                                                      serverFlagBit[1].ToString("X2"),
                                                      serverFlagBit[2].ToString("X2"),
                                                      serverFlagBit[3].ToString("X2"),
                                                      stringMessage);
                                                    Send(state.workSocket, connectOilAndEletricity);
                                                    break;
                                             }
    
                                            break;
    
                                        case PROTOCOL_NUMBER.STRING_INFO :
                                            lengthOfCommand = receiveMessage[4];
                                            serverFlagBit = new byte[4];
                                            Array.Copy(receiveMessage, 5, serverFlagBit, 0, 4);
                                            stringArray = new byte[lengthOfCommand - 4]; //do not include server flag bit
                                            Array.Copy(receiveMessage, 9, stringArray, 0, lengthOfCommand - 4);
                                            stringMessage = Encoding.ASCII.GetString(stringArray);
    
                                            Console.WriteLine("String Message, Server Flag Bit : '{0}{1}{2}{3}', Message : '{4}'", 
                                                serverFlagBit[0].ToString("X2"),
                                                serverFlagBit[1].ToString("X2"),
                                                serverFlagBit[2].ToString("X2"),
                                                serverFlagBit[3].ToString("X2"),
                                                stringMessage);
    
                                            break;
    
                                    } //end switch
                                }// End if
                            } //end while
                        }//end while fifo > 0
                        allDone.Reset();
                    }//end while true
                }
                catch (Exception e)
                {
    
                    Console.WriteLine(e.Message);
                }
    
            }
    
            static string BytesToString(byte[] bytes)
            {
    
                return string.Join("", bytes.Select(x => x.ToString("X2")));
            }
            static KeyValuePair<UNPACK_STATUS, byte[]> Unpack(KeyValuePair<List<byte>, StateObject> bitState)
            {
                List<byte> working_buffer = bitState.Key;
                //return null indicates an error
                if (working_buffer.Count() < 3) return new KeyValuePair<UNPACK_STATUS, byte[]>(UNPACK_STATUS.NOT_ENOUGH_BYTES, null);
    
                int len = working_buffer[2];
    
                if (working_buffer.Count < len + 5) return new KeyValuePair<UNPACK_STATUS, byte[]>(UNPACK_STATUS.NOT_ENOUGH_BYTES, null);
                // check start and end bytes
                // remove message fro workig buffer and dictionary 
                KeyValuePair<List<byte>, StateObject> byteState = ReadWrite(PROCESS_STATE.UNPACK, null, null, bitState.Value.connectionNumber);
                if (byteState.Key.Count == 0) return new KeyValuePair<UNPACK_STATUS, byte[]>(UNPACK_STATUS.ERROR, null);
    
                List<byte> packet = byteState.Key;
    
                //crc test
                byte[] crc = packet.Skip(len + 1).Take(2).ToArray();
                ushort crcShort = (ushort)((crc[0] << 8) | crc[1]);
                //skip start bytes, crc, and end bytes
                ushort CalculatedCRC = crc_bytes(packet.Skip(2).Take(len - 1).ToArray());
    
                if (CalculatedCRC != crcShort)
                {
                    return new KeyValuePair<UNPACK_STATUS, byte[]>(UNPACK_STATUS.BAD_CRC, packet.ToArray());
                }
    
                return new KeyValuePair<UNPACK_STATUS, byte[]>(UNPACK_STATUS.GOOD_MESSAGE, packet.ToArray());
            }
            static public UInt16 crc_bytes(byte[] data)
            {
                ushort crc = 0xFFFF;
    
                for (int i = 0; i < data.Length; i++)
                {
                    crc ^= (ushort)(Reflect(data[i], 8) << 8);
                    for (int j = 0; j < 8; j++)
                    {
                        if ((crc & 0x8000) > 0)
                            crc = (ushort)((crc << 1) ^ 0x1021);
                        else
                            crc <<= 1;
                    }
                }
                crc = Reflect(crc, 16);
                crc = (ushort)~crc;
                return crc;
            }
            static public ushort Reflect(ushort data, int size)
            {
                ushort output = 0;
                for (int i = 0; i < size; i++)
                {
                    int lsb = data & 0x01;
                    output = (ushort)((output << 1) | lsb);
                    data >>= 1;
                }
                return output;
            }
    
            static KeyValuePair<List<byte>, StateObject> ReadWrite(PROCESS_STATE ps, Socket handler, IAsyncResult ar, long unpackConnectionNumber)
            {
                KeyValuePair<List<byte>, StateObject> byteState = new KeyValuePair<List<byte>, StateObject>(); ;
                StateObject stateObject = null;
                int bytesRead = -1;
                int workingBufferLen = 0;
                List<byte> working_buffer = null;
                byte[] buffer = null;
    
                Object thisLock1 = new Object();
    
                lock (thisLock1)
                {
                    switch (ps)
                    {
                        case PROCESS_STATE.ACCEPT:
    
                            acceptDone.WaitOne();
                            acceptDone.Reset();
                            stateObject = new StateObject();
                            stateObject.buffer = new byte[BUFFER_SIZE];
                            connectionDict.Add(connectionNumber, new KeyValuePair<List<byte>, StateObject>(new List<byte>(), stateObject));
                            stateObject.connectionNumber = connectionNumber++;
    
                            stateObject.workSocket = handler;
    
                            byteState = new KeyValuePair<List<byte>, StateObject>(null, stateObject);
                            acceptDone.Set();
                            break;
    
                        case PROCESS_STATE.READ:
                            //catch when client disconnects
    
                            //wait if accept is being called
                            //acceptDone.WaitOne();
                            try
                            {
                                stateObject = ar.AsyncState as StateObject;
                                // Read data from the client socket. 
                                bytesRead = stateObject.workSocket.EndReceive(ar);
    
                                if (bytesRead > 0)
                                {
                                    byteState = connectionDict[stateObject.connectionNumber];
    
                                    buffer = new byte[bytesRead];
                                    Array.Copy(byteState.Value.buffer, buffer, bytesRead);
    
                                    byteState.Key.AddRange(buffer);
                                }
                                //only put one instance of connection number into fifo
                                if (!fifo.Contains(byteState.Value.connectionNumber)) {
    
                                    fifo.Add(byteState.Value.connectionNumber);
                                }
                            }
                            catch (Exception ex)
                            {
                                //will get here if client disconnects
                                fifo.RemoveAll(x => x == byteState.Value.connectionNumber);
                                connectionDict.Remove(byteState.Value.connectionNumber);
                                byteState = new KeyValuePair<List<byte>, StateObject>(new List<byte>(), null);
                            }
                            break;
    
                        case PROCESS_STATE.PROCESS:
                            if (fifo.Count > 0)
                            {
                                //get message from working buffer
                                //unpack will later delete message
                                //remove connection number from fifo
                                // the list in the key in known as the working buffer
                                byteState = new KeyValuePair<List<byte>, StateObject>(connectionDict[fifo[0]].Key, connectionDict[fifo[0]].Value);
                                fifo.RemoveAt(0);
                                //put a valid value in fifoCount so -1 below can be detected.
                                byteState.Value.fifoCount = fifo.Count;
                            }
                            else
                            {
                                //getting here is normal when there is no more work to be performed
                                //set fifocount to zero so rest of code know fifo was empty so code waits for next receive message
                                byteState = new KeyValuePair<List<byte>, StateObject>(null, new StateObject() { fifoCount = -1 });
                            }
                            break;
    
                        case PROCESS_STATE.UNPACK:
                            try
                            {
                                working_buffer = connectionDict[unpackConnectionNumber].Key;
                                workingBufferLen = working_buffer[2];
                                if ((working_buffer[0] != 0x78) && (working_buffer[1] != 0x78) && (working_buffer[workingBufferLen + 3] != 0x0D) && (working_buffer[workingBufferLen + 4] != 0x0A))
                                {
    
    
    
                                    working_buffer.Clear();
                                    return new KeyValuePair<List<byte>, StateObject>(new List<byte>(), null);
                                }
                                List<byte> packet = working_buffer.GetRange(0, workingBufferLen + 5);
                                working_buffer.RemoveRange(0, workingBufferLen + 5);
                                byteState = new KeyValuePair<List<byte>, StateObject>(packet, null);
                            }
                            catch(Exception ex)
                            {
    
                                int testPoint = 0;
                            }
    
                            break;
                    }// end switch
                }
    
                return byteState;
            }
    
            static void Send(Socket handler, String data)
            {
                // Convert the string data to byte data using ASCII encoding.
                byte[] byteData = Encoding.ASCII.GetBytes(data);
    
                // Begin sending the data to the remote device.
                handler.BeginSend(byteData, 0, byteData.Length, 0,
                    new AsyncCallback(SendCallback), handler);
            }
            static void Send(Socket socket, byte[] data)
            {
                // Convert the string data to byte data using ASCII encoding.
                // byte[] byteData = Encoding.ASCII.GetBytes(data);
    
                // Begin sending the data to the remote device.
                socket.BeginSend(data, 0, data.Length, 0,
                    new AsyncCallback(SendCallback), socket);
            }
            static void SendCallback(IAsyncResult ar)
            {
                try
                {
                    // Retrieve the socket from the state object.
                    Socket handler = ar.AsyncState as Socket;
    
                    // Complete sending the data to the remote device.
                    int bytesSent = handler.EndSend(ar);
                    // Console.WriteLine("Sent {0} bytes to client.", bytesSent);
    
                }
                catch (Exception e)
                {
                    // Console.WriteLine(e.ToString());
                    int myerror = -1;
                }
            }
    
            public static void AcceptCallback(IAsyncResult ar)
            {
                try
                {
    
                    // Get the socket that handles the client request.
                    // Retrieve the state object and the handler socket
                    // from the asynchronous state object.
    
                    Socket listener = (Socket)ar.AsyncState;
                    Socket handler = listener.EndAccept(ar);
    
                    // Create the state object.
                    StateObject state = ReadWrite(PROCESS_STATE.ACCEPT, handler, ar, - 1).Value;
    
                    handler.BeginReceive(state.buffer, 0, BUFFER_SIZE, 0,
                        new AsyncCallback(ReadCallback), state);
    
                }
                catch (Exception ex)
                {
                    int myerror = -1;
                }
            }
    
            public static void ReadCallback(IAsyncResult ar)
            {
                try
                {
                    StateObject state = ar.AsyncState as StateObject;
                    Socket handler = state.workSocket;
    
                    // Read data from the client socket. 
                    KeyValuePair<List<byte>, StateObject> byteState = ReadWrite(PROCESS_STATE.READ, handler, ar, -1);
    
                    if (byteState.Value != null)
                    {
                        allDone.Set();
                        handler.BeginReceive(state.buffer, 0, BUFFER_SIZE, 0,
                            new AsyncCallback(ReadCallback), state);
                    }
                    else
                    {
                        int testPoint = 0;
                    }
                }
                catch (Exception ex)
                {
                    int myerror = -1;
                }
    
                // Signal the main thread to continue.  
                allDone.Set();
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 08:33

    Here is the modified code Section 1 :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    using System.Data;
    using System.Data.SqlClient;
    using System.ComponentModel;
    using System.Timers;
    
    namespace ConcoxServer
    {
        public class StateObject
        {
            public long connectionNumber = -1;
            public Socket workSocket { get; set; }
            public byte[] buffer { get; set; }
            public int fifoCount { get; set;}
            public string IMEI { get; set; }
        }
    
        public enum PROTOCOL_NUMBER
        {
            LOGIN_MESSAGE = 0x01,
            LOCATION_DATA = 0x12,
            STATUS_INFO = 0X13,
            STRING_INFO = 0X15,
            ALARM_DATA = 0X16,
            GPS_QUERY_ADDR_PHONE_NUM = 0X1A,
            COMMAND_INFO = 0X80,
            NONE
        }
        public enum UNPACK_STATUS
        {
            ERROR,
            NOT_ENOUGH_BYTES,
            BAD_CRC,
            GOOD_MESSAGE,
            DEFAULT
        }
        public enum PROCESS_STATE
        {
            ACCEPT,
            READ,
            PROCESS,
            UNPACK
        }
        public enum ALARM : Byte
        {
            NORMAL = 0,
            SHOCK_ALARM = 1,
            POWER_CUT_ALARM = 2,
            LOW_BATTERY = 3,
            SOS = 4
        }
    
        class Program
        {
            const string IP = "127.0.0.1";
            const int PORT = 8841;
            const Boolean test = true;
    
            static void Main(string[] args)
            {
    
                GPS gps = new GPS(IP, PORT, test);
    
                Console.WriteLine("Connection Ended");
    
            }
        }
        public class GPS
        {
            const int BUFFER_SIZE = 1024;
            const string CONNECT_STRING = @"Data Source=.\SQLEXPRESS;Initial Catalog=GPSTracker;Integrated Security=SSPI;";
            const string LOGIN_INSERT_COMMMAND_TEXT = "use GPSTracker INSERT INTO Login (TerminalID,Date) VALUES(@TerminalID,@Date)";
            const string LOCATION_INSERT_COMMMAND_TEXT = "INSERT INTO T_Tracking (IMEI,TrackTime, CurrTime, Longitude, Lattitude,speed)" +
                "VALUES (@IMEI, @TrackTime, @CurrTime, @Longitude, @Lattitude, @speed)";
            static SqlConnection conn = null;
            static SqlCommand cmdLogin = null;
            static SqlCommand cmdLocation = null;
    
            static byte[] loginResponse = { 0x78, 0x78, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A };
            static byte[] alarmResponse = { 0x78, 0x78, 0x05, 0x16, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A };
            static byte[] alarmDataAddressResponse = { 0x78, 0x78, 0x00, 0x97, 0x7E,
                                              0x00, 0x00, 0x00, 0x01,
                                              0x41, 0x4C, 0x41, 0x52, 0x4D, 0x53, 0x4D, 0x53,   //ALARMS
                                              0x26, 0x26,                                       //&&
                                              0x80, 0x00, 0x72, 0x00, 0x79, 0x00, 0x78, 0x00,   // PHONE HOME
                                              0x69, 0x00, 0x32, 0x00, 0x72, 0x00, 0x79, 0x00,
                                              0x77, 0x00, 0x69,
                                              0x26, 0x26,                                       //&&
                                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // Phone Numbe
                                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                              0x00, 0x00, 0x00, 0x00, 0x00,
                                              0x23, 0x23,                                       //##
                                              0x00, 0x00,                                       //serial number
                                              0x00, 0x00,                                       //check bytes
                                              0x0D, 0x0A                                        //stop bytes
                                          };
            static byte[] heartbeatResponse = { 0x78, 0x78, 0x05, 0x13, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A };
            static byte[] connectOilAndEletricity = {
                                              0x78, 0x78, 0x16, 0x80, 0x10, 0x12, 0x34, 0x56, 0x78, 0x48,  //server flag bit 0x12345678
                                              0x46, 0x59, 0x44, 0x2C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
                                              0x23, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A
                                         }; 
    
            static long connectionNumber = 0;
            //mapping of connection number to StateObject
            static Dictionary<long, KeyValuePair<List<byte>, StateObject>> connectionDict = new Dictionary<long, KeyValuePair<List<byte>, StateObject>>();
            //fifo contains list of connections number wait with receive data
            public static List<long> fifo = new List<long>();
    
            public static AutoResetEvent allDone = new AutoResetEvent(false);
            public static AutoResetEvent acceptDone = new AutoResetEvent(false);
    
            public GPS(string IP, int port, Boolean test)
            {
                try
                {
                    conn = new SqlConnection(CONNECT_STRING);
                    conn.Open();
    
                    cmdLogin = new SqlCommand(LOGIN_INSERT_COMMMAND_TEXT, conn);
                    cmdLogin.Parameters.Add("@TerminalID", SqlDbType.NVarChar, 8);
                    cmdLogin.Parameters.Add("@Date", SqlDbType.DateTime);
    
                    cmdLocation = new SqlCommand(LOCATION_INSERT_COMMMAND_TEXT, conn);
                    cmdLocation.Parameters.Add("@IMEI", SqlDbType.NVarChar, 50);
                    cmdLocation.Parameters.Add("@TrackTime", SqlDbType.DateTime);
                    cmdLocation.Parameters.Add("@currTime", SqlDbType.DateTime);
                    cmdLocation.Parameters.Add("@Longitude", SqlDbType.NChar, 50);
                    cmdLocation.Parameters.Add("@Lattitude", SqlDbType.NVarChar, 50);
                    cmdLocation.Parameters.Add("@speed", SqlDbType.Float);
    
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error : '{0}'", ex.Message);
                    //Console.ReadLine();
                    return;
                }
    
                try
                {
                    //initialize the timer for writing to database.
                    WriteDBAsync.WriteDatabase();
                    StartListening(IP, port, test);
    
                    // Open 2nd listener to simulate two devices, Only for testing
                    //StartListening(IP, port + 1, test);
    
                    ProcessMessages();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error : '{0}'", ex.Message);
                    //Console.ReadLine();
                    return;
                }
            }
            public enum DATABASE_MESSAGE_TYPE
            {
                LOGIN,
                LOCATION
            }
            public class WriteDBMessage
            {
                public DATABASE_MESSAGE_TYPE message { get; set; }
            }
            public class WriteDBMessageLogin : WriteDBMessage
            {
                public DateTime date { get; set; }
                public string IMEI { get; set; }
            }
            public class WriteDBMessageLocation : WriteDBMessage 
            {
                public string IMEI { get; set; }
                public DateTime trackTime { get; set; }
                public DateTime currTime { get; set; }
                public byte[] longitude { get; set; }
                public byte[] lattitude { get; set; }
                public float speed { get; set; }
                public byte[] courseStatus { get; set; }
            }
    
            public static class WriteDBAsync
            {
                public enum Mode
                {
                    READ,
                    WRITE
                }
                public static List<WriteDBMessage> fifo = new List<WriteDBMessage>();
                public static System.Timers.Timer timer = null;
    
                public static void WriteDatabase()
                {
                    timer = new System.Timers.Timer(1000);
                    timer.Elapsed += Timer_Elapsed;
                    timer.Start();
                }
                public static WriteDBMessage ReadWriteFifo(Mode mode, WriteDBMessage message)
                {
                    Object thisLock2 = new Object();
    
                    lock (thisLock2)
                    {
                        switch (mode)
                        {
                            case Mode.READ:
                                if(fifo.Count > 0)
                                {
                                    message = fifo[0];
                                    fifo.RemoveAt(0);
                                }
                                break;
                            case Mode.WRITE:
                                fifo.Add(message);
                                break;
                        }
    
                    }
                    return message;
                }
                static void Timer_Elapsed(object sender, ElapsedEventArgs e)
                {
                    timer.Enabled = false;
                    WriteDBMessage row = null;
                    int rowsAdded = 0;
                    uint number = 0;
                    double lat = 0;
                    string latStr = "";
                    double lon = 0;
                    string longStr = "";
                    int degrees = 0;
                    double minutes = 0;
                    try
                    {
    
                        while((row = ReadWriteFifo(Mode.READ, null)) != null)
                        {
                            switch(row.message)
                            {
                                case DATABASE_MESSAGE_TYPE.LOGIN:
                                    cmdLogin.Parameters["@TerminalID"].Value = ((WriteDBMessageLogin)row).IMEI;
                                    cmdLogin.Parameters["@Date"].Value = ((WriteDBMessageLogin)row).date;
                                    rowsAdded = cmdLogin.ExecuteNonQuery();
                                    break;
                                case DATABASE_MESSAGE_TYPE.LOCATION:
                                    cmdLocation.Parameters["@IMEI"].Value = ((WriteDBMessageLocation)row).IMEI;
                                    cmdLocation.Parameters["@TrackTime"].Value = ((WriteDBMessageLocation)row).trackTime;
                                    cmdLocation.Parameters["@currTime"].Value = ((WriteDBMessageLocation)row).currTime;
    
                                    number = BitConverter.ToUInt32(((WriteDBMessageLocation)row).longitude.Reverse().ToArray(), 0);
                                    lon = (180 * number) / 324000000.0;
    
                                    degrees = (int)lon;
                                    minutes = 60 * (lon - degrees);
                                    longStr = string.Format("{0}º{1}{2}", degrees, minutes, (((WriteDBMessageLocation)row).courseStatus[0] & 0x08) == 0 ? "E" : "W");
    
                                    cmdLocation.Parameters["@Longitude"].Value = longStr;
    
                                    number = BitConverter.ToUInt32(((WriteDBMessageLocation)row).lattitude.Reverse().ToArray(), 0);
                                    lat = (90 * number) / 162000000.0;
    
                                    degrees = (int)lat;
                                    minutes = 60 * (lat - degrees);
                                    latStr = string.Format("{0}º{1}{2}", degrees, minutes, (((WriteDBMessageLocation)row).courseStatus[0] & 0x04) == 0 ? "S" : "N");
    
                                    cmdLocation.Parameters["@Lattitude"].Value = latStr;
                                    cmdLocation.Parameters["@speed"].Value = ((WriteDBMessageLocation)row).speed;
                                    rowsAdded = cmdLocation.ExecuteNonQuery();
                                    break;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        //Console.WriteLine("Error : '{0}'", ex.Message);
                    }
                    timer.Enabled = true;
                }
            }
    
            public void StartListening(string IP, int port, Boolean test)
            {
                try
                {
                    // Establish the local endpoint for the socket.
                    // The DNS name of the computer
                    // running the listener is "host.contoso.com".
                    IPHostEntry ipHostInfo = Dns.GetHostEntry(IP);  //Dns.Resolve(Dns.GetHostName());
                    IPAddress ipAddress = ipHostInfo.AddressList[0];
                    //IPAddress local = IPAddress.Parse(IP);
    
                    IPEndPoint localEndPoint = null;
                    if (test)
                    {
                        localEndPoint = new IPEndPoint(IPAddress.Any, port);
                    }
                    else
                    {
                        localEndPoint = new IPEndPoint(ipAddress, port);
                    }
    
                    // Create a TCP/IP socket.
                    Socket listener = new Socket(AddressFamily.InterNetwork,
                        SocketType.Stream, ProtocolType.Tcp);
                    // Bind the socket to the local endpoint and listen for incoming connections.
    
    
                    allDone.Reset();
                    acceptDone.Reset();
                    listener.Bind(localEndPoint);
                    listener.Listen(100);
    
                    //login code, wait for 1st message
                    Console.WriteLine("Wait 5 seconds for login message");
    
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
    
    0 讨论(0)
提交回复
热议问题