We have a logger that streams CAN bus messages from e.g. a CAR via a C program and a pipe into Wireshark. This works great, though we are experiencing some packet loss, in some cases significant.
Right now the C code handles one byte at a time, incl. testing what type of byte it is and then handling it accordingly. This is most likely the cause of losses as we miss packets that are close together.
Is there a best practice for how to handle this "packet feeding" into Wireshark? Would it e.g. be better to create a "buffer array" of incoming bytes, then handle these via another function to avoid the loss - or is there another generally applied best practice?
Thank you. Best, Martin
EDIT 1:
We seem to encounter the issue at high traffic (e.g. frames every 10 ms or more frequent). Right now I'm reading byte by byte, checking the byte to identify frame Start and End, and then returning the frame. Does any of you know if there is a better way to read the data when I have to do this continuous manipulation of frames and output them?
In the below code example I have removed any error handling and task cancellation.
-----------------------TEXT-----------------------
-----------------------C# CODE-----------------------
private bool _listen = true;
private SerialPort _port = new SerialPort();
private async void serialListenStart()
{
if (_port != null && _port.IsOpen == true)
{
try
{
await listenForTraffic().ConfigureAwait(false);
}
catch{}
}
}
private async Task listenForTraffic()
{
while (_listen)
{
try
{
var _task = ReadFrameAsync();
await _task.ConfigureAwait(true);
byte[] frame = _task.Result;
// Do stuff with frame and output to user
}
catch{}
}
return;
}
private async Task<byte[]> ReadFrameAsync()
{
byte[] buffer = new byte[1];
byte[] resultFrame = new byte[32]; // a frame will be less than 32 bytes
int pos = 0;
bool destuffingNeeded = false;
while (true)
{
try
{
// Await a data byte from the serial port
await _port.BaseStream.ReadAsync(buffer, 0, 1).ConfigureAwait(true);
}
catch{}
if (pos == 0)
{
if (buffer[0] == 0x7E) // Identify start of frame byte
{
resultFrame[pos] = buffer[0];
pos++;
}
}
else
{
if (destuffingNeeded) // Do destuffing if needed
{
destuffingNeeded = false;
resultFrame[pos] = (byte)((byte)0x20 ^ buffer[0]); // Complement the byte's 6th bit
pos++;
}
else if (buffer[0] == 0x7D) // Identify byte 7D and transform the subsequent byte to 7D or 7E
{
destuffingNeeded = true; // Ignore byte - just advance to next byte
}
else if (buffer[0] == 0x7E) // Identify end of frame byte
{
resultFrame[pos] = buffer[0];
Array.Resize(ref resultFrame, pos + 1);
return resultFrame;
}
else // all bytes between Start and End that don't need destuffing
{
resultFrame[pos] = buffer[0];
pos++;
}
}
}
}
-----------------------C# CODE-----------------------