I have TCP Listener in C# and its read the and store the data properly in Codec8 but in codec8E its give error
- Error
Error: Not enough data for 8B I/O element.
ArgumentOutOfRangeException: Value to add was out of range.
Parameter name: value - Code
using System;
using System.Collections.Generic;
using System.Linq;
using GPSParser.DBLogic;
namespace GPSParser.Teltonika
{
public class FMXXXX_Parser_8E : ParserBase
{
public FMXXXX_Parser_8E(bool showDiagnosticInfo)
{
_showDiagnosticInfo = showDiagnosticInfo;
}
public override int DecodeAVL(List<byte> receiveBytes, string IMEI)
{
try
{
// Log the raw data received
Console.WriteLine("Received Data: " + BitConverter.ToString(receiveBytes.ToArray()).Replace("-", ""));
// Parse AVL Data Length
if (receiveBytes.Count < 8)
{
Console.WriteLine("Error: Not enough data for AVL Data Length.");
return 0;
}
string hexDataLength = string.Empty;
receiveBytes.Skip(4).Take(4).ToList().ForEach(delegate (byte b) { hexDataLength += String.Format("{0:X2}", b); });
int dataLength = Convert.ToInt32(hexDataLength, 16);
Console.WriteLine("Data Length: " + dataLength);
// Validate data length
if (receiveBytes.Count < dataLength + 12) // 12 bytes: 8 header + 4 CRC
{
Console.WriteLine("Error: Received data length does not match expected length.");
return 0;
}
// Parse Codec ID
if (receiveBytes.Count < 9)
{
Console.WriteLine("Error: Not enough data for Codec ID.");
return 0;
}
int codecId = Convert.ToInt32(receiveBytes.Skip(8).Take(1).ToList()[0]);
Console.WriteLine("Codec ID: " + codecId);
// Parse Number of Data
if (receiveBytes.Count < 10)
{
Console.WriteLine("Error: Not enough data for Number of Data.");
return 0;
}
int numberOfData = Convert.ToInt32(receiveBytes.Skip(9).Take(1).ToList()[0]);
Console.WriteLine("Number of Data: " + numberOfData);
int tokenAddress = 10;
for (int n = 0; n < numberOfData; n++)
{
GPSdata gpsData = new GPSdata();
// Parse Timestamp
if (tokenAddress + 8 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for timestamp.");
break;
}
string hexTimeStamp = string.Empty;
receiveBytes.Skip(tokenAddress).Take(8).ToList().ForEach(delegate (byte b) { hexTimeStamp += String.Format("{0:X2}", b); });
long timeSt = Convert.ToInt64(hexTimeStamp, 16);
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
DateTime timestamp = origin.AddMilliseconds(Convert.ToDouble(timeSt));
gpsData.Timestamp = timestamp;
Console.WriteLine("Timestamp: " + timestamp);
tokenAddress += 8;
// Parse Priority
if (tokenAddress + 1 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for priority.");
break;
}
int priority = Convert.ToInt32(receiveBytes.Skip(tokenAddress).Take(1).ToList()[0]);
gpsData.Priority = (byte)priority;
Console.WriteLine("Priority: " + priority);
tokenAddress += 1;
// Parse Longitude
if (tokenAddress + 4 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for longitude.");
break;
}
string longt = string.Empty;
receiveBytes.Skip(tokenAddress).Take(4).ToList().ForEach(delegate (byte b) { longt += String.Format("{0:X2}", b); });
double longitude = ((double)Convert.ToInt32(longt, 16)) / 10000000;
gpsData.Long = longitude;
Console.WriteLine("Longitude: " + longitude);
tokenAddress += 4;
// Parse Latitude
if (tokenAddress + 4 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for latitude.");
break;
}
string lat = string.Empty;
receiveBytes.Skip(tokenAddress).Take(4).ToList().ForEach(delegate (byte b) { lat += String.Format("{0:X2}", b); });
double latitude = ((double)Convert.ToInt32(lat, 16)) / 10000000;
gpsData.Lat = latitude;
Console.WriteLine("Latitude: " + latitude);
tokenAddress += 4;
// Parse Altitude
if (tokenAddress + 2 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for altitude.");
break;
}
string alt = string.Empty;
receiveBytes.Skip(tokenAddress).Take(2).ToList().ForEach(delegate (byte b) { alt += String.Format("{0:X2}", b); });
int altitude = Convert.ToInt32(alt, 16);
gpsData.Altitude = (short)altitude;
Console.WriteLine("Altitude: " + altitude);
tokenAddress += 2;
// Parse Angle
if (tokenAddress + 2 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for angle.");
break;
}
string ang = string.Empty;
receiveBytes.Skip(tokenAddress).Take(2).ToList().ForEach(delegate (byte b) { ang += String.Format("{0:X2}", b); });
int angle = Convert.ToInt32(ang, 16);
gpsData.Direction = (short)angle;
Console.WriteLine("Angle: " + angle);
tokenAddress += 2;
// Parse Satellites
if (tokenAddress + 1 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for satellites.");
break;
}
int satellites = Convert.ToInt32(receiveBytes.Skip(tokenAddress).Take(1).ToList()[0]);
gpsData.Satellite = (byte)satellites;
Console.WriteLine("Satellites: " + satellites);
tokenAddress += 1;
// Parse Speed
if (tokenAddress + 2 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for speed.");
break;
}
string sp = string.Empty;
receiveBytes.Skip(tokenAddress).Take(2).ToList().ForEach(delegate (byte b) { sp += String.Format("{0:X2}", b); });
int speed = Convert.ToInt32(sp, 16);
gpsData.Speed = (short)speed;
Console.WriteLine("Speed: " + speed);
tokenAddress += 2;
// Parse Event IO Element ID
if (tokenAddress + 1 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for event IO element ID.");
break;
}
byte event_IO_element_ID = (byte)Convert.ToInt32(receiveBytes.Skip(tokenAddress).Take(1).ToList()[0]);
gpsData.Event_IO_element_ID = event_IO_element_ID;
Console.WriteLine("Event IO Element ID: " + event_IO_element_ID);
tokenAddress += 1;
// Parse IO Elements in Record
if (tokenAddress + 1 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for IO elements in record.");
break;
}
int IO_element_in_record = Convert.ToInt32(receiveBytes.Skip(tokenAddress).Take(1).ToList()[0]);
Console.WriteLine("IO Element in Record: " + IO_element_in_record);
tokenAddress += 1;
int currentCursor = tokenAddress;
// Handle 1B I/O elements
if (currentCursor < receiveBytes.Count)
{
int IO_Elements_1B_Quantity = Convert.ToInt32(receiveBytes.Skip(currentCursor).Take(1).ToList()[0]);
currentCursor++;
Console.WriteLine($"1B I/O Elements Quantity: {IO_Elements_1B_Quantity}");
for (int IO_1 = 0; IO_1 < IO_Elements_1B_Quantity; IO_1++)
{
if (currentCursor + 1 >= receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for 1B I/O element.");
break;
}
var parameterID = (byte)Convert.ToInt32(receiveBytes.Skip(currentCursor).Take(1).ToList()[0]);
var IO_Element_1B = (byte)Convert.ToInt32(receiveBytes.Skip(currentCursor + 1).ToList()[0]);
if (!gpsData.IO_Elements_1B.ContainsKey(parameterID))
{
gpsData.IO_Elements_1B.Add(parameterID, IO_Element_1B);
}
Console.WriteLine($"1B Element ID: {parameterID}, Value: {IO_Element_1B}");
currentCursor += 2;
}
}
// Handle 2B I/O elements
if (currentCursor < receiveBytes.Count)
{
int IO_Elements_2B_Quantity = Convert.ToInt32(receiveBytes.Skip(currentCursor).Take(1).ToList()[0]);
currentCursor++;
Console.WriteLine($"2B I/O Elements Quantity: {IO_Elements_2B_Quantity}");
for (int IO_2 = 0; IO_2 < IO_Elements_2B_Quantity; IO_2++)
{
if (currentCursor + 3 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for 2B I/O element.");
break;
}
var parameterID = (byte)Convert.ToInt32(receiveBytes.Skip(currentCursor).Take(1).ToList()[0]);
string value = string.Empty;
receiveBytes.Skip(currentCursor + 1).Take(2).ToList().ForEach(delegate (byte b) { value += String.Format("{0:X2}", b); });
var IO_Element_2B = Convert.ToInt16(value, 16);
if (!gpsData.IO_Elements_2B.ContainsKey(parameterID))
{
gpsData.IO_Elements_2B.Add(parameterID, IO_Element_2B);
}
Console.WriteLine($"2B Element ID: {parameterID}, Value: {IO_Element_2B}");
currentCursor += 3;
}
}
// Handle 4B I/O elements
if (currentCursor < receiveBytes.Count)
{
int IO_Elements_4B_Quantity = Convert.ToInt32(receiveBytes.Skip(currentCursor).Take(1).ToList()[0]);
currentCursor++;
Console.WriteLine($"4B I/O Elements Quantity: {IO_Elements_4B_Quantity}");
for (int IO_4 = 0; IO_4 < IO_Elements_4B_Quantity; IO_4++)
{
if (currentCursor + 5 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for 4B I/O element.");
break;
}
var parameterID = (byte)Convert.ToInt32(receiveBytes.Skip(currentCursor).Take(1).ToList()[0]);
string value = string.Empty;
receiveBytes.Skip(currentCursor + 1).Take(4).ToList().ForEach(delegate (byte b) { value += String.Format("{0:X2}", b); });
var IO_Element_4B = Convert.ToInt32(value, 16);
if (!gpsData.IO_Elements_4B.ContainsKey(parameterID))
{
gpsData.IO_Elements_4B.Add(parameterID, IO_Element_4B);
}
Console.WriteLine($"4B Element ID: {parameterID}, Value: {IO_Element_4B}");
currentCursor += 5;
}
}
// Handle 8B I/O elements
if (currentCursor < receiveBytes.Count)
{
int IO_Elements_8B_Quantity = Convert.ToInt32(receiveBytes.Skip(currentCursor).Take(1).ToList()[0]);
currentCursor++;
Console.WriteLine($"8B I/O Elements Quantity: {IO_Elements_8B_Quantity}");
for (int IO_8 = 0; IO_8 < IO_Elements_8B_Quantity; IO_8++)
{
if (currentCursor + 9 > receiveBytes.Count)
{
Console.WriteLine("Error: Not enough data for 8B I/O element.");
break;
}
var parameterID = (byte)Convert.ToInt32(receiveBytes.Skip(currentCursor).Take(1).ToList()[0]);
string value = string.Empty;
receiveBytes.Skip(currentCursor + 1).Take(8).ToList().ForEach(delegate (byte b) { value += String.Format("{0:X2}", b); });
var IO_Element_8B = Convert.ToInt64(value, 16);
if (!gpsData.IO_Elements_8B.ContainsKey(parameterID))
{
gpsData.IO_Elements_8B.Add(parameterID, IO_Element_8B);
}
Console.WriteLine($"8B Element ID: {parameterID}, Value: {IO_Element_8B}");
currentCursor += 9;
}
}
tokenAddress = currentCursor;
// Ensure IMEI is set before saving to database
if (string.IsNullOrEmpty(IMEI) || IMEI.Length < 15)
{
Console.WriteLine("Error: IMEI is not valid.");
continue;
}
gpsData.IMEI = IMEI.Substring(0, 15);
Data dt = new Data();
dt.SaveGPSPositionFMXXXX(gpsData);
FMXXXXIOB _fmElement = new FMXXXXIOB();
_fmElement._gpsData = gpsData;
_fmElement.Store1B();
_fmElement.Store2B();
_fmElement.Store4B();
_fmElement.Store8B();
dt.SaveGPSElementsFMXXXX(gpsData.IMEI, _fmElement._gpsElement);
}
// Calculate and verify CRC
string crcString = string.Empty;
receiveBytes.Skip(dataLength + 8).Take(4).ToList().ForEach(delegate (byte b) { crcString += String.Format("{0:X2}", b); });
int CRC = Convert.ToInt32(crcString, 16);
int calculatedCRC = GetCRC16(receiveBytes.Skip(8).Take(dataLength).ToArray());
Console.WriteLine("CRC: " + CRC);
Console.WriteLine("Calculated CRC: " + calculatedCRC);
return calculatedCRC == CRC ? numberOfData : 0;
}
catch (ArgumentOutOfRangeException ex)
{
Console.WriteLine("ArgumentOutOfRangeException: " + ex.Message);
return 0;
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
return 0;
}
}
private int GetCRC16(byte[] buffer)
{
return GetCRC16(buffer, buffer.Length, 0xA001);
}
private int GetCRC16(byte[] buffer, int bufLen, int polynom)
{
polynom &= 0xFFFF;
int crc = 0;
for (int i = 0; i < bufLen; i++)
{
int data = buffer[i] & 0xFF;
crc ^= data;
for (int j = 0; j < 8; j++)
{
if ((crc & 0x0001) != 0)
{
crc = (crc >> 1) ^ polynom;
}
else
{
crc = crc >> 1;
}
}
}
return crc & 0xFFFF;
}
}
}
please help me whether I have written parsing logic properly if not please help