Reputation: 11
I used this GitHub sample code to receive data from the Teltonika FMB920 GPS tracker. According to Teltonika documents (Codec documentation), to receive data from the Teltonika GPS tracker on TCP protocol, the tracker sends his IMEI to the server, and then the server sends back one byte of 0x01 (Accept) or 0x00 (Reject) as a response. then the GPS tracker sends GPS data packets to the server and the server should send back the count of received packets as the response. if not the GPS tracker tries to send duplicate data packets again and again until the server sends the count of data as a response.
The sample works in terms of receiving and accepting IMEI but always receives duplicate GPS data packets. Amazingly if I toggle a breakpoint on the line this.ResponseReverse(avlData.NumberOfData1, stream);
and then delete the breakpoint to continue the process, the GPS tracker sends new data packets correctly.
private void ClientHandler(object client)
{
var tcpClient = (TcpClient)client;
//tcpClient.NoDelay = true;
var stream = tcpClient.GetStream();
var imei = this.ReadImei(stream);
var commArgs = this.OnDeviceCnnected(imei);
if (commArgs.CommunicationAccepted)
{
this.Accept(stream);
this.OnStatusChanged(imei, AvlTcpStatus.Accepted);
}
else
{
this.Reject(stream);
this.OnStatusChanged(imei, AvlTcpStatus.Rejected);
}
while (true)
{
try
{
var memoryStream = this.ReadData(stream);
if (memoryStream.Length == 0)
{
this.OnStatusChanged(imei, AvlTcpStatus.Terminated);
break;
}
var packet = PacketParser.Parse<AvlTcpPacket>(memoryStream);
if (memoryStream.Position != memoryStream.Length)
throw new InvalidDataException("unfinished avl packet");
var avlData = packet.GetAvlDataArray();
this.OnDataFetched(imei, avlData);
//Thread.Sleep(1000);
this.ResponseReverse(avlData.NumberOfData1, stream);
//Thread.Sleep(1000);
}
catch (Exception exception)
{
this.OnErrorOccured(imei, exception);
}
}
}
I tried to use Thread.Sleep();
before and after this line to simulate what breakpoints do but not work. What do you think about this issue?
UPDATE: More info about methods:
private void Accept(NetworkStream stream)
{
// 1 as byte array response will determine if it would accept data from this module.
this.Response(1, stream);
}
private void Reject(NetworkStream stream)
{
// 0 as byte array response will determine if it would reject data from this module.
this.Response(0, stream);
}
private void Response(int count, NetworkStream stream)
{
var answer = BitConverter.GetBytes(count).ToArray();
stream.Write(answer, 0, answer.Length);
}
private void ResponseReverse(int count, NetworkStream stream)
{
var answer = BitConverter.GetBytes(count).Reverse().ToArray();
stream.Write(answer, 0, answer.Length);
}
private string ReadImei(NetworkStream stream)
{
var buffer = new byte[128]; //IMEI buffer
var length = stream.Read(buffer, 0, buffer.Length);
if (buffer[0] != 0 || buffer[1] != 0x0f) throw new InvalidDataException("Wrong IMEI");
var imei = Encoding.ASCII.GetString(buffer, 2, length - 2);
return imei;
}
private MemoryStream ReadData(NetworkStream stream)
{
var buffer = new byte[4096];
var memoryStream = new MemoryStream();
while (true)
{
var length = stream.Read(buffer, 0, buffer.Length);
if (length == 0) break;
memoryStream.Write(buffer, 0, length);
if (!stream.DataAvailable) break;
}
memoryStream.Position = 0;
return memoryStream;
}
Upvotes: 0
Views: 160