// 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 }
// 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; } }
// 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); } }
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"); }