C# socket issue in receiving images - c#

i did create socket application to send and receive images over internet
i did test the application locally and on vmware , it did works fine
also test it on some devices over internet also worked fine
but there is other devices that the Server application receive only small amount of the sent data
here is an image of the server
image
and this is the server code
while(true)
{
Socket socket = listener.AcceptSocket();
label4.Text = "Connected";
byte[] image = new byte[99999999];
int offset = -1;
int ite = 0;
while (true)
{
byte[] data = new byte[1024];
int count = socket.Receive(data);
if (count > 0)
{
String txt = Encoding.ASCII.GetString(data, 0, count);
if (txt.Contains("hello"))
{
label8.Text = txt;
continue;
}
if (!txt.Contains("end"))
{
ite += 1;
label7.Text = ite.ToString();
label12.Text = offset.ToString();
for (int i = 0; i <= count - 1; i++)
{
offset += 1;
image[offset] = data[i];
}
try
{
MemoryStream stream = new MemoryStream(image, 0, offset);
Image x = Image.FromStream(stream);
pictureBox1.Image = x;
}
catch (Exception ex)
{
}
}
else
{
label7.Text = ite.ToString();
ite = 0;
label5.Text = label2.Text;
label2.Text = offset.ToString();
MemoryStream stream = new MemoryStream(image, 0, offset);
Image x = Image.FromStream(stream);
pictureBox1.Image = x;
image = new byte[99999999];
offset = -1;
break;
}
}
}
}
and this is the client code
while (true)
{
TcpClient client = new TcpClient(ip, port);
NetworkStream stream = client.GetStream();
byte[] data = Capture();
int dataSize = 1024;
int offset = 0;
byte[] start = ASCIIEncoding.ASCII.GetBytes("hello " + data.Length.ToString());
stream.Write(start, 0, start.Length);
while (offset < data.Length)
{
int sum = offset + dataSize;
if (sum > data.Length)
{
dataSize = data.Length - offset;
}
stream.Write(data, offset, dataSize);
offset += dataSize;
}
Thread.Sleep(1000);
byte[] end = ASCIIEncoding.ASCII.GetBytes("end");
stream.Write(end, 0, end.Length);
client.Close();
Thread.Sleep(interval);
Console.WriteLine("iter=" + iteration.ToString());
}

Related

How do I set sample rate and buffer size for VST plugin like vsthost config in VST.NET 2 Host

I have VST2 plugin and when I add it into vsthost, It worked with Bypass equals true, when I set Bypass equals false, It only worked with Sample Rate = 48000hz and Buffer = 4800 samples (10b/s).
Below image:
vsthost image
So, I want to set that sample rate and buffer size into my code.
Below is code that I use plugin for convert audio wavein/waveout:
public static void ConnectPlugin(bool restartDevice = false, int? inputDeviceNumber = 0, int? outputDeviceNumber = 1, bool byPass = false)
{
if (!restartDevice && waveIn != null) return;
if (waveIn != null) waveIn.Dispose();
if (waveOut != null) waveOut.Dispose();
sampleRate = 48000;
blockSize = (int)(4800);
waveIn = new WaveInEvent();
waveIn.BufferMilliseconds = 50;
waveIn.DataAvailable += Plugin_DataAvailable;
waveIn.DeviceNumber = inputDeviceNumber ?? 0;
waveIn.WaveFormat = new WaveFormat((int)sampleRate, 16, 2);
waveProviderout = new BufferedWaveProvider(waveIn.WaveFormat) { DiscardOnBufferOverflow = true };
int inputCount = _vstPlugin.PluginInfo.AudioInputCount;
int outputCount = _vstPlugin.PluginInfo.AudioOutputCount;
var inputMgr = new VstAudioBufferManager(inputCount, blockSize);
var outputMgr = new VstAudioBufferManager(outputCount, blockSize);
_vstPlugin.PluginCommandStub.Commands.SetBlockSize(blockSize);
_vstPlugin.PluginCommandStub.Commands.SetSampleRate(sampleRate);
_vstPlugin.PluginCommandStub.Commands.SetProcessPrecision(VstProcessPrecision.Process32);
// set param
_vstPlugin.PluginCommandStub.Commands.SetBypass(byPass);
inputBuffers = inputMgr.Buffers.ToArray();
outputBuffers = outputMgr.Buffers.ToArray();
waveOut = new WaveOutEvent();
waveOut.DesiredLatency = 100;
waveOut.DeviceNumber = outputDeviceNumber ?? 1;
waveOut.Init(waveProviderout);
waveOut.Play();
waveIn.StartRecording();
_vstPlugin.PluginCommandStub.Commands.MainsChanged(true);
}
private static void Plugin_DataAvailable(object sender, WaveInEventArgs e)
{
var device = (WaveInEvent)sender;
var naudioBuf = e.Buffer;
try
{
unsafe
{
int j = 0;
for (int i = 0; i < e.BytesRecorded; i++)
{
byte[] tmpbytearr = new byte[2];
tmpbytearr[0] = naudioBuf[i];
i++;
tmpbytearr[1] = naudioBuf[i];
Int16 tmpint = BitConverter.ToInt16(tmpbytearr, 0);
float f = (((float)tmpint / (float)Int16.MaxValue));
inputBuffers[0][j] = f;
inputBuffers[1][j] = f;
j++;
}
}
_vstPlugin.PluginCommandStub.Commands.StartProcess();
_vstPlugin.PluginCommandStub.Commands.ProcessReplacing(inputBuffers, outputBuffers);
_vstPlugin.PluginCommandStub.Commands.StopProcess();
//_vstPlugin.PluginCommandStub.EditorIdle();
byte[] bytebuffer;
unsafe
{
float* tmpBufLeft = ((IDirectBufferAccess32)outputBuffers[0]).Buffer;
float* tmpBufRight = ((IDirectBufferAccess32)outputBuffers[1]).Buffer;
bytebuffer = new byte[outputBuffers[0].SampleCount * 2];
int j = 0;
for (int i = 0; i < (outputBuffers[0].SampleCount * 2); i++)
{
Int16 tmpint = (Int16)((float)outputBuffers[1][j] * (float)Int16.MaxValue);
byte[] tmparr = BitConverter.GetBytes(tmpint);
bytebuffer[i] = tmparr[0];
i++;
bytebuffer[i] = tmparr[1];
j++;
}
}
waveProviderout.AddSamples(bytebuffer, 0, bytebuffer.Length);
}
catch (Exception ex)
{
Console.Out.WriteLine(ex.Message);
}
}
How do I can set sample rate and buffer in my code like vsthost
vsthost image

How to write to a .wav file using a generated wave, complex[] array?

I would like to know how to write to a .wav file, I have written the following code which supposedly writes data to the file. But when I try to play the sound file it says the file is corrupt / empty.
try
{
SaveFileDialog save = new SaveFileDialog();
save.Filter = "Wave File (*.wav)|*.wav;";
if (save.ShowDialog() != System.Windows.Forms.DialogResult.OK)
return;
using (FileStream FS = new FileStream(save.FileName, FileMode.Open, FileAccess.Write))
{
BinaryWriter wr = new BinaryWriter(FS);
int subchunk1Size = 16;
short audioFormat = 1;
short bitsPerSample = 64;
short numChannels = 2;
int sampleRate = Convert.ToInt32(samplingRateBox.Text);
int byteRate = sampleRate * numChannels * (bitsPerSample / 8);
short blockAlign = (short)(numChannels * (bitsPerSample / 8));
int numSamples = Convert.ToInt32(numberOfsamplesBox.Text);
int subChunk2Size = numSamples * numChannels * (bitsPerSample / 8);
int chunkSize = 4 + (8 + subchunk1Size) + (8 + subChunk2Size);
wr.Write(getBytes("RIFF"));
wr.Write(chunkSize);
wr.Write(getBytes("WAVE"));
wr.Write(getBytes("fmt"));
wr.Write((byte)32);
wr.Write(subchunk1Size);
wr.Write(audioFormat);
wr.Write(numChannels);
wr.Write(sampleRate);
wr.Write(byteRate);
wr.Write(blockAlign);
wr.Write(bitsPerSample);
wr.Write(getBytes("data"));
wr.Write(subChunk2Size);
double[] primArray = new double[samples.Length];
byte[] byteArray = new byte[samples.Length * 8];
for (int i = 0; i < samples.Length; i++)
{
primArray[i] = Convert.ToDouble(samples[i].Real);
}
byteArray = doubleToBytes(primArray);
for (int i = 0; i < samples.Length; i++)
{
wr.Write(byteArray[i]);
}
for (int i = 0; i < samples.Length; i++)
{
primArray[i] = Convert.ToDouble(samples[i].Imaginary);
}
byteArray = doubleToBytes(primArray);
for (int i = 0; i < samples.Length; i++)
{
wr.Write(byteArray[i]);
}
wr.Close();
wr.Dispose();
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
As you can see I have tried converting from Complex to double, plus the header.
The sampling rate and number of samples all come from textboxes. Plus I am assuming the bit depth is that of a double.
I have also tried using this method, however the length of the audio file is 0.
This used the NAudio library.
NAudio.Wave.WaveFileWriter waveWriter = null;
WaveIn wi = new WaveIn();
double[] primArray = new double[samples.Length];
for (int i = 0; i < samples.Length; i++)
{
primArray[i] = Convert.ToDouble(samples[i].Real);
}
SaveFileDialog save = new SaveFileDialog();
save.Filter = "Wave File (*.wav)|*.wav;";
if (save.ShowDialog() != System.Windows.Forms.DialogResult.OK)
return;
wi = new NAudio.Wave.WaveIn();
wi.WaveFormat = new WaveFormat(samplingRate,1);
waveWriter = new WaveFileWriter(save.FileName, wi.WaveFormat);
byte[] byteArray = new byte[samples.Length*8];
byteArray = doubleToBytes(primArray);
waveWriter.Write(byteArray, 0, byteArray.Length);

How to open Thumbscache.db

I'm trying to open a thumbscache.db file, I've tried to open it like any other database but no use. I've also looked for any API or support in C#. Kindly suggest if there is another way.
BTW below is my approach so far.
1. Open it like any other db.
path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
path += #"\Microsoft\Windows\Explorer\thumbcache_1280.db";
datasource = "Data source = " + path;
SQLiteCommand cmd = new SQLiteCommand();
SQLiteConnection conn = new SQLiteConnection(datasource);
cmd.Connection = conn;
cmd.CommandText = "SELECT * FROM Filename";
conn.Open();
SQLiteDataAdapter sqda = new SQLiteDataAdapter(cmd);
DataTable dt = new DataTable();
sqda.Fill(dt);
dataGridView1.DataSource = dt;
conn.Close();
But this exception comes up.
2. Open it using ShellFile
ShellFile shellFile = ShellFile.FromFilePath(path);
Bitmap bitmap = shellFile.Thumbnail.ExtraLargeBitmap;
pbThumbs.Image = bitmap;
And instead of thumbscache it gives file thumb icon.
3. Opening as OLE Document using OpenMcdf
path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
path += #"\Microsoft\Windows\Explorer\thumbcache_1280.db";
CompoundFile cf = new CompoundFile(path);
CFStream foundStream = cf.RootStorage.GetStream("Filename");
byte[] temp = foundStream.GetData();
And this exception comes up.
Following is C# class to open thumbcache*.db files.
public class ThumbCache
{
private const int WindowsVista = 0x14;
private const int Windows7 = 0x15;
private const int Windows8 = 0x1A;
private const int Windows8v2 = 0x1C;
private const int Windows8v3 = 0x1E;
private const int Windows8_1 = 0x1F;
private const int Windows10 = 0x20;
private Stream stream;
private uint fileVersion;
private byte[] tempBytes = new byte[65536];
private uint[] entryOffsets;
public int ImageCount { get { return entryOffsets.Length; } }
public ThumbCache(string fileName)
{
stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
ReadFromStream(stream);
}
public ThumbCache(Stream stream)
{
ReadFromStream(stream);
}
~ThumbCache()
{
stream.Close();
}
private void ReadFromStream(Stream stream)
{
stream.Read(tempBytes, 0, 32);
string magic = Encoding.ASCII.GetString(tempBytes, 0, 4);
if (!magic.Equals("CMMM"))
throw new ApplicationException("This is not a valid ThumbCache file.");
fileVersion = BitConverter.ToUInt32(tempBytes, 4);
uint fileType = BitConverter.ToUInt32(tempBytes, 8);
uint firstEntryPtr = 0;
uint availableEntryPtr = 0;
if (fileVersion < Windows8v2)
{
firstEntryPtr = BitConverter.ToUInt32(tempBytes, 12);
availableEntryPtr = BitConverter.ToUInt32(tempBytes, 16);
}
else
{
firstEntryPtr = BitConverter.ToUInt32(tempBytes, 16);
availableEntryPtr = BitConverter.ToUInt32(tempBytes, 20);
}
stream.Seek(firstEntryPtr, SeekOrigin.Begin);
List<uint> entryOffsetList = new List<uint>();
try
{
uint entrySize;
while (stream.Position < stream.Length)
{
entryOffsetList.Add((uint)stream.Position);
stream.Read(tempBytes, 0, 8);
if ((tempBytes[0] != 'C') || (tempBytes[1] != 'M') || (tempBytes[2] != 'M') || (tempBytes[3] != 'M'))
break;
entrySize = BitConverter.ToUInt32(tempBytes, 4);
stream.Seek(entrySize - 8, SeekOrigin.Current);
}
}
catch { }
entryOffsets = entryOffsetList.ToArray();
}
public ThumbInfo GetImage(int imageIndex, bool needImage)
{
if (entryOffsets.Length == 0) return null;
if ((imageIndex < 0) || (imageIndex >= entryOffsets.Length)) return null;
return new ThumbInfo(stream, entryOffsets[imageIndex], tempBytes, fileVersion, needImage);
}
public Dictionary<string, string> GetMetadata(ThumbInfo info)
{
var dict = new Dictionary<string, string>();
if (entryOffsets.Length == 0) return dict;
if (info == null) return dict;
dict.Add("File offset", info.fileOffset.ToString());
dict.Add("Entry size", info.entrySize.ToString());
dict.Add("Entry hash", info.entryHash.ToString("X16"));
dict.Add("Filename length", info.fileNameLength.ToString());
dict.Add("Padding length", info.paddingLength.ToString());
dict.Add("Data length", info.dataLength.ToString());
dict.Add("Image width", info.imageWidth.ToString());
dict.Add("Image height", info.imageHeight.ToString());
dict.Add("Data checksum", info.dataChecksum.ToString("X16"));
dict.Add("Header checksum", info.headerChecksum.ToString("X16"));
return dict;
}
public class ThumbInfo
{
public Image image;
public long fileOffset;
public uint entrySize;
public ulong entryHash;
public uint fileNameLength;
public uint paddingLength;
public uint dataLength;
public ulong dataChecksum;
public ulong headerChecksum;
public uint imageWidth;
public uint imageHeight;
public ThumbInfo(Stream stream, long offset, byte[] tempBytes, uint fileVersion, bool needImage)
{
fileOffset = offset;
stream.Seek(fileOffset, SeekOrigin.Begin);
stream.Read(tempBytes, 0, 64);
int bytePtr = 0;
string magic = Encoding.ASCII.GetString(tempBytes, bytePtr, 4); bytePtr += 4;
if (!magic.Equals("CMMM"))
throw new ApplicationException("Incorrect format.");
entrySize = BitConverter.ToUInt32(tempBytes, bytePtr); bytePtr += 4;
entryHash = BitConverter.ToUInt64(tempBytes, bytePtr); bytePtr += 8;
if (fileVersion == WindowsVista)
{
bytePtr += 8; // wchar x 4
}
fileNameLength = BitConverter.ToUInt32(tempBytes, bytePtr); bytePtr += 4;
paddingLength = BitConverter.ToUInt32(tempBytes, bytePtr); bytePtr += 4;
dataLength = BitConverter.ToUInt32(tempBytes, bytePtr); bytePtr += 4;
if (fileVersion >= Windows8)
{
imageWidth = BitConverter.ToUInt32(tempBytes, bytePtr); bytePtr += 4;
imageHeight = BitConverter.ToUInt32(tempBytes, bytePtr); bytePtr += 4;
}
bytePtr += 4; // unknown
dataChecksum = BitConverter.ToUInt64(tempBytes, bytePtr); bytePtr += 8;
headerChecksum = BitConverter.ToUInt64(tempBytes, bytePtr); bytePtr += 8;
if (!needImage || dataLength == 0 || dataLength > 0x1000000)
return;
stream.Seek(fileOffset + entrySize - dataLength, SeekOrigin.Begin);
if (dataLength > tempBytes.Length)
tempBytes = new byte[dataLength];
stream.Read(tempBytes, 0, (int)dataLength);
using (var mstream = new MemoryStream(tempBytes))
{
image = new Bitmap(mstream);
}
}
}
}
Detailed solution here .

How can i manage sending and reciveing of data from serialport with timer?

I have 3 forms,form1,form2 and form3. I have to perform following things
Send data from form1 to serial port.
when form1 get value '1', show second form.
when click a button in form2 show form3.
when click a send button call a function in form1 and send data to serial port.
Wait for response.
When get a response again send data without clicking the button.
wait for response.
When get a response again send data without clicking the button.
continues this procedure so many times
my problem is that how can I manage this with timer. after getting acknowledgement am sending next data and I stop the timer. But when I get acknowledgement I cant send data, because I already stopped the timer. Is there any solution to this?
code in form3
private void button1_Click(object sender, EventArgs e)
{
int temp =Convert.ToInt32( comboBox1.Text);
if (comboBox1.Text == "25")
{
tempp[0] = 0;
}
else if (comboBox1.Text == "30")
{
tempp[0] = 1;
}
else if (comboBox1.Text == "37")
{
tempp[0] = 2;
}
int filter = Convert.ToInt32(comboBox2.Text);
int asp = Convert.ToInt32(textBox1.Text);
int prnt = Convert.ToInt32(textBox2.Text);
int abs = Convert.ToInt32(textBox3.Text);
byte[] cmdt = BitConverter.GetBytes(Form1.SETTEMPERATURE);
byte[] nn = BitConverter.GetBytes(Form1.SETFILTER);
byte[] len = new byte[1];
byte[] ERR = new byte[1];
// byte[] val = new byte[1];
len[0] = 3;
((Form1)this.Owner).SerialPortValueUpdated(len, cmdt, ERR, tempp);
}
private void Filter_Load(object sender, EventArgs e)
{
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (Form1.tflag == 1&&Form1.filflag==0)
{
label7.Text = "FILTER...";
rrr = 1;
}
if (Form1.filflag == 1&&Form1.tflag==0)
{
label7.Text = "ACK...";
fltflag = 1;
}
// }
if (rrr == 1)
{
// Form1.tflag = 0;
byte[] nn = BitConverter.GetBytes(Form1.SETFILTER);
byte[] len = new byte[1];
byte[] ERR = new byte[1];
byte[] val = new byte[1];
len[0] = 3;
((Form1)this.Owner).SerialPortValueUpdated(len, nn, ERR, val);
timer1.Stop();
}
if (fltflag == 1)
{
Form1.filflag = 0;
byte[] nn = BitConverter.GetBytes(Form1.GETRAWADS);
byte[] len = new byte[1];
byte[] ERR = new byte[1];
byte[] val = new byte[1];
len[0] = 3;
((Form1)this. Owner).SerialPortValueUpdated(len, nn, ERR, val);
}
}
code in form1
public void SerialPortValueUpdated(byte[]len,byte[]nn,byte[]err,byte[]val)
{
byte[] head = new byte[1] { 0xAA };
byte[] trail = new byte[1] { 0x55 };
byte[] len2 = len;
byte[] cmd2 = nn;
byte[] error = err;
byte[] value = val;
serialPort1.Write(head, 0, 1);
serialPort1.Write(len, 0, 1);
serialPort1.Write(cmd2, 0, 1);
serialPort1.Write(error, 0, 1);
serialPort1.Write(value, 0, 1);
serialPort1.Write(trail, 0, 1);
this.Activate();
}
int bytes = serialPort1.BytesToRead;
serialPort1.Read(byte_buffer, 0, bytes);
if (byte_buffer[0] == startup&&count==0)
{
if (this.InvokeRequired)
{
this.Invoke(((MethodInvoker)delegate
{
f2 = new Form2();
f2.Show(this);
// this.Close();
}));
// return;
}
}
else if(byte_buffer[0]==0XAA&&flag2!=1)
{
flag1 = 1;
}
count++;
if (flag1 == 1&& count==2)
{
length[0] = byte_buffer[0];
val = length[0] - 2;
flag2 = 1;
}
if (flag2 == 1&&count==3)
{
command[0] = byte_buffer[0];
flag3 = 1;
}
if (flag3 == 1&&count==4)
{
error[0] = byte_buffer[0];
flag4 = 1;
}
if (flag4 == 1&&count>4&&byte_buffer[0]!=0X55)
{
for (int i = 0; i < 1; i++)
{
value[K] = byte_buffer[0];
flag5 = 1;
K++;
}
}
if (command[0] == 3 && flag4==1&&flag5==1&&trailflag==1)
{
tflag = 1;
}
if (command[0] == 4 && flag4 == 1 && flag5 == 1 && trailflag == 1)
{
filflag = 1;
}

Reading GPS data from Teltonika FM4200

I have configured the GPS device and created a listener application in C#. I receive only the IMEI Number from the device and not any GPS NMEA data.
But for checking when i check the same in GPS Gate Server it displays the movement in map.
any suggestions!!!
Below is how the handling of data is performed
TcpClient client = (TcpClient)tcpClient;
Byte[] bytes = new Byte[10000];
String data = null;
int i;
NetworkStream stream = client.GetStream();
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
}
Console.WriteLine(data);
When it goes in the while loop it just waits and sleep :(
I think that device havaing pattern like
Step1:After Receving IMEI number
Step2:Replay "01" Status to the same newwork
Code:
TcpClient newClient = (TcpClient)client;
NetworkStream ns = newClient.GetStream()
byte[] bytes = new byte[1024];
bytes = Encoding.ASCII.GetBytes("X");
Console.WriteLine("X");
ns.Write(bytes, 0, bytes.Length);
First when module connects to server, module sends its IMEI. IMEI is
sent the same way as encoding barcode.
First comes short identifying number of bytes written and then goes IMEI as text
(bytes). For example IMEI 123456789012345 would be sent as
000F313233343536373839303132333435 After receiving IMEI,
server should determine if it would accept data from this module. If yes,server will reply to module 01 if not 00. Note that confirmation should be sent as binary packet.
Then module starts to send firstAVL data packet.
After server receives packet and parses it, server must report to module number of data received as integer(four bytes). If sent data number and reported by server doesn’t match module resends sent data.
Ref. FMXXXX Protocols V2.7
I think you need to do something like this (simple solution). If you can get it work, maybe you should check on some asynchronous sockets/tcp connections
TcpClient client = (TcpClient)tcpClient;
Byte[] bytes = new Byte[10000];
String data = null;
int i;
NetworkStream stream = client.GetStream();
// Will get data as long as data is available after 1st read
do
{
i = stream.Read(bytes, 0, bytes.Length)
data = String.Concat(data, System.Text.Encoding.ASCII.GetString(bytes, 0, i));
}
while(stream.DataAvailable);
// Write the data to console (first time it should be IMEI
Console.WriteLine(data);
// Write 1 to the stream, note it must probably be byte value 1 -> 0x01
// Flush output stream after writing to prevent buffering
data = "";
// Now try if more data comes in after IMEI and 0x01 reply
do
{
i = stream.Read(bytes, 0, bytes.Length)
data = String.Concat(data, System.Text.Encoding.ASCII.GetString(bytes, 0, i));
}
while(stream.DataAvailable);
// Write date to console - move inside the while loop if data keeps coming in
Console.WriteLine(data);
You have to configure your tracker first using below steps as in figure:
To initiate configuration process, configuration server sends binary initiation SMS (“Push” SMS) containing server host(ip address) and tcp port device should connect to and waits for TCP connection.
Upon reception of “push” SMS, device tries to establish TCP connection to configuration server using GPRS. If TCP connection attempt succeeds, server sends out configuration data to device over established connection, device confirms configuration reception and configures itself.
If device doesn‘t connect to server in TcpWaitTimeout time, server stops waiting for TCP connection, sends out configuration data using binary SMS, and waits for confirmation SMS from device. If confirmation SMS doesn‘t arrive in specified time, server assumes that configuration process failed.
Reference file:
https://sourceforge.net/p/opengts/discussion/579834/thread/6fd0ffe8/6213/attachment/FMXXXX%20Protocols%20v2.10.pdf
Here is a parser for FM1100 this may help you to write code for FM4200 model
https://github.com/temala/Teltonika-FM1100
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Data;
using System.Net.Sockets;
using System.Linq;
using System.IO;
namespace TeltonikaParser
{
public class Protocol_TeltonikaFMXXXX
{
private const int CODEC_FMXXX = 0x08;
private const int ACC = 1;
private const int DOOR = 2;
private const int Analog = 4;
private const int GSM = 5;
private const int SPEED = 6;
private const int VOLTAGE = 7;
private const int GPSPOWER = 8;
private const int TEMPERATURE = 9;
private const int ODOMETER = 16;
private const int STOP = 20;
private const int TRIP = 28;
private const int IMMOBILIZER = 29;
private const int AUTHORIZED = 30;
private const int GREEDRIVING = 31;
private const int OVERSPEED = 33;
private static string Parsebytes(Byte[] byteBuffer, int index, int Size)
{
return BitConverter.ToString(byteBuffer, index, Size).Replace("-", string.Empty);
}
private static string parseIMEI(Byte[] byteBuffer, int size)
{
int index = 0;
var result = Parsebytes(byteBuffer, index, 2);
return result;
}
private static bool checkIMEI(string data)
{
Console.WriteLine(data.Length);
if (data.Length == 15)
return true;
return false;
}
private static List<Position> ParsePositions(Byte[] byteBuffer, int linesNB)
{
int index = 0;
index += 7;
uint dataSize = byteBuffer[index];
index++;
uint codecID = byteBuffer[index];
if (codecID == CODEC_FMXXX)
{
index++;
uint NumberOfData = byteBuffer[index];
Console.WriteLine("{0} {1} {2} ", codecID, NumberOfData, dataSize);
List<Position> result = new List<Position>();
index++;
for (int i = 0; i < NumberOfData; i++)
{
Position position = new Position();
var timestamp = Int64.Parse(Parsebytes(byteBuffer, index, 8), System.Globalization.NumberStyles.HexNumber);
index += 8;
position.Time = DateTime.Now;
var Preority = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
index++;
position.Lo = Int32.Parse(Parsebytes(byteBuffer, index, 4), System.Globalization.NumberStyles.HexNumber) / 10000000.0;
index += 4;
position.La = Int32.Parse(Parsebytes(byteBuffer, index, 4), System.Globalization.NumberStyles.HexNumber) / 10000000.0;
index += 4;
var Altitude = Int16.Parse(Parsebytes(byteBuffer, index, 2), System.Globalization.NumberStyles.HexNumber);
index += 2;
var dir = Int16.Parse(Parsebytes(byteBuffer, index, 2), System.Globalization.NumberStyles.HexNumber);
if (dir < 90) position.Direction = 1;
else if (dir == 90) position.Direction = 2;
else if (dir < 180) position.Direction = 3;
else if (dir == 180) position.Direction = 4;
else if (dir < 270) position.Direction = 5;
else if (dir == 270) position.Direction = 6;
else if (dir > 270) position.Direction = 7;
index += 2;
var Satellite = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
index++;
if (Satellite >= 3)
position.Status = "A";
else
position.Status = "L";
position.Speed = Int16.Parse(Parsebytes(byteBuffer, index, 2), System.Globalization.NumberStyles.HexNumber);
index += 2;
int ioEvent = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
index++;
int ioCount = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
index++;
//read 1 byte
{
int cnt = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
index++;
for (int j = 0; j < cnt; j++)
{
int id = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
index++;
//Add output status
switch (id)
{
case ACC:
{
var value = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
position.Status += value == 1 ? ",ACC off" : ",ACC on";
index++;
break;
}
case DOOR:
{
var value = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
position.Status += value == 1 ? ",door close" : ",door open";
index++;
break;
}
case GSM:
{
var value = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
position.Status += string.Format(",GSM {0}", value);
index++;
break;
}
case STOP:
{
var value = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
position.StopFlag = value == 1;
position.IsStop = value == 1;
index++;
break;
}
case IMMOBILIZER:
{
var value = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
position.Alarm = value == 0 ? "Activate Anti-carjacking success" : "Emergency release success";
index++;
break;
}
case GREEDRIVING:
{
var value = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
switch (value)
{
case 1:
{
position.Alarm = "Acceleration intense !!";
break;
}
case 2:
{
position.Alarm = "Freinage brusque !!";
break;
}
case 3:
{
position.Alarm = "Virage serré !!";
break;
}
default:
break;
}
index++;
break;
}
default:
{
index++;
break;
}
}
}
}
//read 2 byte
{
int cnt = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
index++;
for (int j = 0; j < cnt; j++)
{
int id = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
index++;
switch (id)
{
case Analog:
{
var value = Int16.Parse(Parsebytes(byteBuffer, index, 2), System.Globalization.NumberStyles.HexNumber);
if (value < 12)
position.Alarm += string.Format("Low voltage", value);
index += 2;
break;
}
case SPEED:
{
var value = Int16.Parse(Parsebytes(byteBuffer, index, 2), System.Globalization.NumberStyles.HexNumber);
position.Alarm += string.Format("Speed", value);
index += 2;
break;
}
default:
{
index += 2;
break;
}
}
}
}
//read 4 byte
{
int cnt = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
index++;
for (int j = 0; j < cnt; j++)
{
int id = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
index++;
switch (id)
{
case TEMPERATURE:
{
var value = Int32.Parse(Parsebytes(byteBuffer, index, 4), System.Globalization.NumberStyles.HexNumber);
position.Alarm += string.Format("Temperature {0}", value);
index += 4;
break;
}
case ODOMETER:
{
var value = Int32.Parse(Parsebytes(byteBuffer, index, 4), System.Globalization.NumberStyles.HexNumber);
position.Mileage = value;
index += 4;
break;
}
default:
{
index += 4;
break;
}
}
}
}
//read 8 byte
{
int cnt = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
index++;
for (int j = 0; j < cnt; j++)
{
int id = byte.Parse(Parsebytes(byteBuffer, index, 1), System.Globalization.NumberStyles.HexNumber);
index++;
var io = Int64.Parse(Parsebytes(byteBuffer, index, 8), System.Globalization.NumberStyles.HexNumber);
position.Status += string.Format(",{0} {1}", id, io);
index += 8;
}
}
result.Add(position);
Console.WriteLine(position.ToString());
}
return result;
}
return null;
}
public static Byte[] DealingWithHeartBeat(string data)
{
Byte[] result = { 1 };
if (checkIMEI(data))
{
return result;
}
return null;
}
public static string ParseHeartBeatData(Byte[] byteBuffer, int size)
{
var IMEI = parseIMEI(byteBuffer, size);
if (checkIMEI(IMEI))
{
return IMEI;
}
else
{
int index = 0;
index += 7;
uint dataSize = byteBuffer[index];
index++;
uint codecID = byteBuffer[index];
if (codecID == CODEC_FMXXX)
{
index++;
uint NumberOfData = byteBuffer[index];
return NumberOfData.ToString();
}
}
return string.Empty;
}
public static List<Position> ParseData(Byte[] byteBuffer, int size)
{
List<Position> result = new List<Position>();
result = ParsePositions(byteBuffer, size);
return result;
}
public static Position GetGPRSPos(string oneLine)
{
return null;
}
}
}

Categories

Resources