示例#1
0
        private static void ThreadProc(object state)
        {
            string        imei     = string.Empty;
            var           client   = ((TcpClient)state);
            NetworkStream nwStream = ((TcpClient)state).GetStream();

            byte[] buffer = new byte[client.ReceiveBufferSize];

            try
            {
                while (true)
                {
                    int bytesRead = nwStream.Read(buffer, 0, client.ReceiveBufferSize);

                    string dataReceived = Encoding.ASCII.GetString(buffer, 0, bytesRead);
                    if (imei == string.Empty)
                    {
                        imei = dataReceived;
                        Console.WriteLine("IMEI received : " + dataReceived);

                        Byte[] b = { 0x01 };
                        nwStream.Write(b, 0, 1);
                    }
                    else
                    {
                        int dataNumber = Convert.ToInt32(buffer.Skip(9).Take(1).ToList()[0]);;

                        var result = 0;
                        while (dataNumber > 0)
                        {
                            var parser = new TeltonikaDevicesParser(false);
                            result = parser.Decode(new List <byte>(buffer), imei);
                            dataNumber--;
                        }
                        nwStream.Write(
                            result > 0 ? new byte[] { 0x00, 0x00, 0x00, 0x01 } : new byte[] { 0x00, 0x00, 0x00, 0x00 }, 0,
                            4);
                    }
                }
            }
            catch (Exception e)
            {
                // Console.WriteLine(e);
                client.Close();
                //throw;
            }

            //throw new NotImplementedException();
        }
        private void ReceiveCallback(IAsyncResult result)
        {
            ConnectionInfo connection = (ConnectionInfo)result.AsyncState;

            try
            {
                //get a number of received bytes
                int bytesRead = connection.Socket.EndReceive(result);
                if (bytesRead > 0)
                {
                    //because device sends data with portions we need summary all portions to total buffer
                    if (connection.isPartialLoaded)
                    {
                        connection.TotalBuffer.AddRange(connection.Buffer.Take(bytesRead).ToList());
                    }
                    else
                    {
                        if (connection.TotalBuffer != null)
                        {
                            connection.TotalBuffer.Clear();
                        }
                        connection.TotalBuffer = connection.Buffer.Take(bytesRead).ToList();
                    }
                    //-------- Get Length of current received data ----------
                    string hexDataLength = string.Empty;

                    //Skip four zero bytes an take next four bytes with value of AVL data array length
                    connection.TotalBuffer.Skip(4).Take(4).ToList().ForEach(delegate(byte b) { hexDataLength += String.Format("{0:X2}", b); });

                    int dataLength = Convert.ToInt32(hexDataLength, 16);
                    //
                    //bytesRead = 17 when parser receive IMEI  from device
                    //if datalength encoded in data > then total buffer then is a partial data a device will send next part
                    //we send confirmation and wait next portion of data
                    if (dataLength + 12 > connection.TotalBuffer.Count && bytesRead != 17)
                    {
                        connection.isPartialLoaded = true;
                        connection.Socket.Send(new byte[] { 0x01 });
                        connection.Socket.BeginReceive(connection.Buffer, 0, connection.Buffer.Length, SocketFlags.None,
                                                       new AsyncCallback(ReceiveCallback), connection);
                        return;
                    }


                    bool isDataPacket = true;

                    //when device send AVL data first 4 bytes is 0
                    string firstRourBytes = string.Empty;
                    connection.TotalBuffer.Take(4).ToList().ForEach(delegate(byte b) { firstRourBytes += String.Format("{0:X2}", b); });
                    if (Convert.ToInt32(firstRourBytes, 16) > 0)
                    {
                        isDataPacket = false;
                    }

                    // if is true then is AVL data packet
                    // else that a IMEI sended
                    if (isDataPacket)
                    {
                        if (GPSParser.Properties.Settings.Default.ShowDiagnosticMessages)
                        {
                            //all data we convert this to string in hex format only for diagnostic
                            StringBuilder data = new StringBuilder();
                            connection.TotalBuffer.ForEach(delegate(byte b) { data.AppendFormat("{0:X2}", b); });
                            //LoggerInLogger("<" + data);
                        }
                        TeltonikaDevicesParser decAVL = new TeltonikaDevicesParser(GPSParser.Properties.Settings.Default.ShowDiagnosticMessages);
                        decAVL.OnDataReceive += new Action <string>(decAVL_OnDataReceive);
                        //if CRC not correct number of data returned by AVL parser = 0;
                        int numberOfData = decAVL.Decode(connection.TotalBuffer, connection.IMEI);
                        if (!connection.isPartialLoaded)
                        {
                            // send to device number of received data for confirmation.
                            if (numberOfData > 0)
                            {
                                connection.Socket.Send(new byte[] { 0x00, 0x00, 0x00, Convert.ToByte(numberOfData) });
                            }
                            else
                            {
                                //send 0 number of data if CRC not correct for resend data from device
                                connection.Socket.Send(new byte[] { 0x00, 0x00, 0x00, 0x00 });
                            }
                        }
                        decAVL.OnDataReceive -= new Action <string>(decAVL_OnDataReceive);
                        LoggerIn.Logger("Modem ID: " + connection.IMEI + " send data");
                    }
                    else
                    {
                        //if is not data packet then is it IMEI info send from device
                        connection.IMEI = Encoding.ASCII.GetString(connection.TotalBuffer.Skip(2).ToArray());
                        connection.Socket.Send(new byte[] { 0x01 });
                        LoggerIn.Logger("Modem ID: " + connection.IMEI + " connected");
                    }
                    // Get next data portion from device
                    connection.Socket.BeginReceive(connection.Buffer, 0, connection.Buffer.Length, SocketFlags.None,
                                                   new AsyncCallback(ReceiveCallback), connection);
                }//if all data received then close connection
                else
                {
                    CloseConnection(connection);
                }
            }
            catch (SocketException exc)
            {
                CloseConnection(connection);
                LoggerIn.Logger("Socket exception: " + exc.SocketErrorCode);
            }
            catch (Exception exc)
            {
                CloseConnection(connection);
                LoggerIn.Logger("Exception: " + exc);
            }
        }