Пример #1
0
        // ReSharper disable once MethodTooLong
        private async Task ParseAvlDataAsync(TcpClient client, NetworkStream stream, string imei)
        {
            Console.WriteLine("IMEI received : " + imei);
            Console.WriteLine("--------------------------------------------");
            Byte[] b = { 0x01 };
            await stream.WriteAsync(b, 0, 1).ConfigureAwait(false);

            var command = new CreateBoxCommand();

            command.Imei = imei;
            try
            {
                await _bus.Publish(command).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
            while (true)
            {
                stream = client.GetStream();
                byte[] buffer = new byte[client.ReceiveBufferSize];
                await stream.ReadAsync(buffer, 0, client.ReceiveBufferSize).ConfigureAwait(false);

                List <byte> list = new List <byte>();
                foreach (var b1 in buffer.Skip(9).Take(1))
                {
                    list.Add(b1);
                }
                int dataCount = Convert.ToInt32(list[0]);
                var bytes     = Convert.ToByte(dataCount);
                if (client.Connected)
                {
                    await stream.WriteAsync(new byte[] { 0x00, 0x00, 0x00, bytes }, 0, 4).ConfigureAwait(false);
                }

                var gpsResult = ParseAvlData(imei, buffer);

                if (!gpsResult.Any() && imei.Any())
                {
                    continue;
                }
                var events = new TLGpsDataEvents
                {
                    Id     = Guid.NewGuid(),
                    Events = gpsResult
                };
                await _bus.Publish(events).ConfigureAwait(false);

                // break;
            }
            // ReSharper disable once FunctionNeverReturns
        }
Пример #2
0
        // ReSharper disable once MethodTooLong
        private async Task ParseAvlDataAsync(TcpClient client, NetworkStream stream, string imei)
        {
            try
            {
                Trace.TraceInformation("IMEI received : " + imei);

                _log.Information($"{DateTime.Now} -IMEI received: {imei}");

                Trace.TraceInformation("--------------------------------------------");
                Byte[] b = { 0x01 };
                await stream.WriteAsync(b, 0, 1).ConfigureAwait(false);

                var modem = _redisCache.Get <CreateBoxCommand>(imei);

                while (true)
                {
                    stream = client.GetStream();
                    byte[] buffer = new byte[client.ReceiveBufferSize];
                    await stream.ReadAsync(buffer, 0, client.ReceiveBufferSize).ConfigureAwait(false);

                    List <byte> list = new List <byte>();
                    foreach (var b1 in buffer.Skip(9).Take(1))
                    {
                        list.Add(b1);
                    }
                    int dataCount = Convert.ToInt32(list[0]);
                    var bytes     = Convert.ToByte(dataCount);
                    if (client.Connected)
                    {
                        await stream.WriteAsync(new byte[] { 0x00, 0x00, 0x00, bytes }, 0, 4).ConfigureAwait(false);
                    }

                    var gpsResult = ParseAvlData(imei, buffer);

                    if (!gpsResult.Any() && imei.Any())
                    {
                        continue;
                    }
                    var events = new TLGpsDataEvents
                    {
                        Id     = Guid.NewGuid(),
                        Events = gpsResult
                    };
                    await _bus.Publish(events).ConfigureAwait(false);

                    var lastGpsData = gpsResult.Last();
                    if (modem == null)
                    {
                        modem      = new CreateBoxCommand();
                        modem.Imei = imei;
                    }
                    modem.Longitude           = lastGpsData.Long;
                    modem.Latitude            = lastGpsData.Lat;
                    modem.LastValidGpsDataUtc = lastGpsData.DateTimeUtc;
                    modem.Speed = lastGpsData.Speed;
                    await _bus.Publish(modem).ConfigureAwait(false);

                    // break;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                client.Close();
                throw;
            }
        }
Пример #3
0
        // ReSharper disable once ExcessiveIndentation
        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
                    // ReSharper disable once ComplexConditionExpression
                    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,
                                                       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 (true)
                        {
                            //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); });
                            Console.WriteLine("<" + data);
                        }


                        var decAvl = new DevicesParser();
                        decAvl.OnDataReceive += decAVL_OnDataReceive;
                        //if CRC not correct number of data returned by AVL parser = 0;
                        var avlData = decAvl.Decode(connection.TotalBuffer, connection.Imei);
                        if (!connection.IsPartialLoaded)
                        {
                            // send to device number of received data for confirmation.
                            if (avlData.Count > 0)
                            {
                                connection.Socket.Send(new byte[] { 0x00, 0x00, 0x00, Convert.ToByte(avlData.Count) });
                                LogAvlData(avlData);
                                var events = new TLGpsDataEvents
                                {
                                    Id     = Guid.NewGuid(),
                                    Events = avlData
                                };
                                var lastGpsData = events.Events.Last();

                                var command = new CreateBoxCommand();
                                command.Imei                = connection.Imei;
                                command.Longitude           = lastGpsData.Long;
                                command.Latitude            = lastGpsData.Lat;
                                command.LastValidGpsDataUtc = lastGpsData.DateTimeUtc;
                                command.Speed               = lastGpsData.Speed;
                                _bus.Publish(command).ConfigureAwait(false);
                                Thread.Sleep(1000);
                                _bus.Publish(events).ConfigureAwait(false);
                            }
                            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 -= decAVL_OnDataReceive;
                        Console.WriteLine("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 });
                        Console.WriteLine("Modem ID: " + connection.Imei + " connected");
                    }
                    // Get next data portion from device
                    connection.Socket.BeginReceive(connection.Buffer, 0, connection.Buffer.Length, SocketFlags.None,
                                                   ReceiveCallback, connection);
                }//if all data received then close connection
                else
                {
                    CloseConnection(connection);
                }
            }
            catch (SocketException exc)
            {
                CloseConnection(connection);
                Console.WriteLine("Socket exception: " + exc.SocketErrorCode);
            }
            catch (Exception exc)
            {
                CloseConnection(connection);
                Console.WriteLine("Exception: " + exc);
            }
        }
Пример #4
0
        public override async Task OnConnectedAsync(ConnectionContext connection)
        {
            _logger.LogInformation("new connection: " + connection.ConnectionId + ":" + connection.RemoteEndPoint.AddressFamily);
            var imei = string.Empty;

            while (true)
            {
                try
                {
                    await semaphore.WaitAsync().ConfigureAwait(false);

                    var result = await connection.Transport.Input.ReadAsync().ConfigureAwait(false);

                    var           buffer       = result.Buffer;
                    StringBuilder builder      = new StringBuilder();
                    var           receivedData = new List <byte []>();
                    foreach (var segment in buffer)
                    {
                        builder.Append(Encoding.ASCII.GetString(segment.ToArray(), 0, segment.ToArray().Length));
                        receivedData.Add(segment.ToArray());
                    }
                    var data = builder.ToString();
                    // remove bad characters
                    data = Regex.Replace(data, @"[^\w\.@-]", "", RegexOptions.None);
                    // if the data  received is  valid imei we send to modem 1
                    if (Commonhelper.IsValidImei(data))
                    {
                        byte[] b = { 0x01 };
                        _logger.LogInformation($"new modem connected with id : {data}");
                        imei = data;
                        var command = new CreateBoxCommand();
                        command.Imei = imei;
                        await _mediator.Send(command).ConfigureAwait(false);

                        await connection.Transport.Output.WriteAsync(b).ConfigureAwait(false);
                    }
                    // if the data received is avl data we parse the avl data and send to the modem the number of data received
                    else
                    {
                        foreach (var receivedBytes in receivedData)
                        {
                            var gpsResult = await ParseAvlDataAsync(imei, receivedBytes).ConfigureAwait(false);

                            var events = new TLGpsDataEvents
                            {
                                Id     = Guid.NewGuid(),
                                Events = gpsResult
                            };
                            var bytes = Convert.ToByte(gpsResult.Count);
                            await connection.Transport.Output.WriteAsync(new byte[] { 0x00, 0x00, 0x00, bytes }).ConfigureAwait(false);

                            _mediator.Publish(events).GetAwaiter();
                        }
                    }
                    if (result.IsCompleted)
                    {
                        break;
                    }
                    semaphore.Release();
                    connection.Transport.Input.AdvanceTo(buffer.End);
                }
                catch (Exception e)
                {
                    _logger.LogError(e.Message);
                    _logger.LogError(e.InnerException?.Message);
                    semaphore.Release();
                    break;
                }
            }

            Console.WriteLine(connection.ConnectionId + " disconnected");
        }