How to open Thumbscache.db - c#

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 .

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);

Getting Error on Readprocessememory on c#

private static int FindPattern(byte[] Pattern)
{
Process[] P = Process.GetProcessesByName("example");
if (P.Length == 0)
{
return -1;
}
if (modules == exmaple())
{
modules = P[0].MainModule.BaseAddress;
}
byte[] _Buffer = new byte[268435457];
var tempVar = 0;
ReadProcessMemory(P[0].Handle, modules, out _Buffer, _Buffer.Length, ref tempVar);
int[] sBytes = new int[256];
int Len = Pattern.Length - 1;
var Dex = 0;
for (int i = 255; i >= 0; i--)
{
sBytes[i] = Pattern.Length;
}
for (int i = Len; i >= 0; i--)
{
sBytes[Pattern[i]] = Len;
}
while (Dex <= _Buffer.Length - Pattern.Length)
{
int i = Len;
while (_Buffer[Dex + i] == Pattern[i])
{
if (i == 0)
{
return Dex;
}
i -= 1;
}
Dex += sBytes[_Buffer[Dex + Len]];
}
return -1;
}
i tried a lot but i can't fix it.What did i did wrong?.
i am getting errors on this.Can anyone fix it for me please :
ReadProcessMemory(P[0].Handle, modules, out _Buffer, _Buffer.Length, ref tempVar);
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication81
{
class Program
{
[DllImport("kernel32.dll", SetLastError=true)]
static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,[Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
const int SIZE = 268435457;
static void Main(string[] args)
{
Process[] P = Process.GetProcessesByName("example");
if (P.Length == 0)
{
return -1;
}
if (modules == exmaple())
{
modules = P[0].MainModule.BaseAddress;
}
IntPtr buffer = Marshal.AllocHGlobal(SIZE);
var tempVar = 0;
ReadProcessMemory(P[0].Handle, modules, out buffer, SIZE, ref tempVar);
byte[] _Buffer = new byte[SIZE];
Marshal.PtrToStructure(buffer, _Buffer);
int[] sBytes = new int[256];
int Len = Pattern.Length - 1;
var Dex = 0;
for (int i = 255; i >= 0; i--)
{
sBytes[i] = Pattern.Length;
}
for (int i = Len; i >= 0; i--)
{
sBytes[Pattern[i]] = Len;
}
while (Dex <= _Buffer.Length - Pattern.Length)
{
int i = Len;
while (_Buffer[Dex + i] == Pattern[i])
{
if (i == 0)
{
return Dex;
}
i -= 1;
}
Dex += sBytes[_Buffer[Dex + Len]];
}
return -1;
}
}
}

AES to return Alphanumeric

I have an aes encryption code, i want to make it only return alphanumerical characters like {0123456789ABCDEFGHIJKLMNOPQRSTWUVYZ}
But however i could not figure out how to do that. I have almost no idea about encryption, could not figure out where to fix. I would really apreciate your feedback. Regards...
public class clsCrypto
{
private string _KEY = string.Empty;
protected internal string KEY
{
get
{
return _KEY;
}
set
{
if (!string.IsNullOrEmpty(value))
{
_KEY = value;
}
}
}
private string _IV = string.Empty;
protected internal string IV
{
get
{
return _IV;
}
set
{
if (!string.IsNullOrEmpty(value))
{
_IV = value;
}
}
}
private string CalcMD5(string strInput)
{
string strOutput = string.Empty;
if (!string.IsNullOrEmpty(strInput))
{
try
{
StringBuilder strHex = new StringBuilder();
using (MD5 md5 = MD5.Create())
{
byte[] bytArText = Encoding.Default.GetBytes(strInput);
byte[] bytArHash = md5.ComputeHash(bytArText);
for (int i = 0; i < bytArHash.Length; i++)
{
strHex.Append(bytArHash[i].ToString("X2"));
}
strOutput = strHex.ToString();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
return strOutput;
}
private byte[] GetBytesFromHexString(string strInput)
{
byte[] bytArOutput = new byte[] { };
if ((!string.IsNullOrEmpty(strInput)) && strInput.Length % 2 == 0)
{
SoapHexBinary hexBinary = null;
try
{
hexBinary = SoapHexBinary.Parse(strInput);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
bytArOutput = hexBinary.Value;
}
return bytArOutput;
}
private byte[] GenerateIV()
{
byte[] bytArOutput = new byte[] { };
try
{
string strIV = CalcMD5(IV);
bytArOutput = GetBytesFromHexString(strIV);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return bytArOutput;
}
private byte[] GenerateKey()
{
byte[] bytArOutput = new byte[] { };
try
{
string strKey = CalcMD5(KEY);
bytArOutput = GetBytesFromHexString(strKey);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return bytArOutput;
}
protected internal string Encrypt(string strInput, CipherMode cipherMode)
{
string strOutput = string.Empty;
if (!string.IsNullOrEmpty(strInput))
{
try
{
byte[] bytePlainText = Encoding.Default.GetBytes(strInput);
using (RijndaelManaged rijManaged = new RijndaelManaged())
{
rijManaged.Mode = cipherMode;
rijManaged.BlockSize = 128;
rijManaged.KeySize = 128;
rijManaged.IV = GenerateIV();
rijManaged.Key = GenerateKey();
rijManaged.Padding = PaddingMode.Zeros;
ICryptoTransform icpoTransform = rijManaged.CreateEncryptor(rijManaged.Key, rijManaged.IV);
using (MemoryStream memStream = new MemoryStream())
{
using (CryptoStream cpoStream = new CryptoStream(memStream, icpoTransform, CryptoStreamMode.Write))
{
cpoStream.Write(bytePlainText, 0, bytePlainText.Length);
cpoStream.FlushFinalBlock();
}
strOutput = Encoding.Default.GetString(memStream.ToArray());
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
return strOutput;
}
protected internal string Decrypt(string strInput, CipherMode cipherMode)
{
string strOutput = string.Empty;
if (!string.IsNullOrEmpty(strInput))
{
try
{
byte[] byteCipherText = Encoding.Default.GetBytes(strInput);
byte[] byteBuffer = new byte[strInput.Length];
using (RijndaelManaged rijManaged = new RijndaelManaged())
{
rijManaged.Mode = cipherMode;
rijManaged.BlockSize = 128;
rijManaged.KeySize = 128;
rijManaged.IV = GenerateIV();
rijManaged.Key = GenerateKey();
rijManaged.Padding = PaddingMode.Zeros;
ICryptoTransform icpoTransform = rijManaged.CreateDecryptor(rijManaged.Key, rijManaged.IV);
using (MemoryStream memStream = new MemoryStream(byteCipherText))
{
using (CryptoStream cpoStream = new CryptoStream(memStream, icpoTransform, CryptoStreamMode.Read))
{
cpoStream.Read(byteBuffer, 0, byteBuffer.Length);
}
strOutput = Encoding.Default.GetString(byteBuffer);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
return strOutput;
}
}
Encryption and decryption functions use byte arrays as parameters.
So, you must convert these arrays to base 36 string.
You can use the following class (Base36) to make these conversions:
All you have to do, is calling these two functions:
byte[] byteArray;
//To convert byte array to String
string byteArrayInBase36 = Base36.ByteArrayToBase36String(byteArray);
//To convert String to byte Array
byte[] byteArray2 = Base36.Base36StringToByteArray(byteArrayInBase36);
and, this is the class:
using System;
using System.Collections.Generic;
class Base36
{
#region public methods
public static string ByteArrayToBase36String(byte[] bytes)
{
string result = string.Empty;
result = Encode36((ulong)bytes.Length).PadLeft(BASE36_LENGTH_BLOC_SIZE_36, '0');
if (bytes.Length > 0)
{
List<byte[]> byteslist = SplitBytes(bytes, 8);
if (byteslist[byteslist.Count - 1].Length < 8)
{
byte[] newLastArray = new byte[8];
byteslist[byteslist.Count - 1].CopyTo(newLastArray, 0);
byteslist[byteslist.Count - 1] = newLastArray;
}
foreach (byte[] byteArray in byteslist)
{
ulong value = 0;
//for (int i = 0; i < byteArray.Length; i++) value = value * 256 + byteArray[i];
value = BitConverter.ToUInt64(byteArray, 0);
result = result + Encode36(value).PadLeft(BASE36_BLOC_SIZE_36, '0');
}
}
return result;
}
public static byte[] Base36StringToByteArray(string input)
{
byte[] result = new byte[0];
if (input.Length >= BASE36_LENGTH_BLOC_SIZE_36)
{
int arrayLength = (int)Decode36(input.Substring(0, BASE36_LENGTH_BLOC_SIZE_36));
string data = input.Remove(0, BASE36_LENGTH_BLOC_SIZE_36);
List<byte[]> bytesList = new List<byte[]>();
foreach (string value36 in new List<string>(SplitStringByLength(data, BASE36_BLOC_SIZE_36)))
{
byte[] byteArray = BitConverter.GetBytes(Decode36(value36));
bytesList.Add(byteArray);
}
result = JoinBytes(bytesList);
Array.Resize(ref result, arrayLength);
}
return result;
}
#endregion
#region Const
private const int BASE36_LENGTH_BLOC_SIZE_36 = 6;
private const int BASE36_BLOC_SIZE_36 = 13; //Encode36(ulong.MaxValue).Length;
#endregion
#region private methods
static string _CharList36 = string.Empty;
static private string CharList36
{
get
{
if (_CharList36.Length < 36)
{
char[] array = new char[36];
for (int i = 0; i < 10; i++) array[i] = (char)(i + 48);
for (int i = 0; i < 26; i++) array[i + 10] = (char)(i + 97);
_CharList36 = new string(array);
}
return _CharList36;
}
}
private static List<string> SplitStringByLength(string str, int chunkSize)
{
List<string> list = new List<string>();
int i;
for (i = 0; i < str.Length / chunkSize; i++)
{
list.Add(str.Substring(i * chunkSize, chunkSize));
}
i = i * chunkSize;
if (i < str.Length - 1)
list.Add(str.Substring(i, str.Length - i));
return list;
}
private static String Encode36(ulong input)
{
if (input < 0) throw new ArgumentOutOfRangeException("input", input, "input cannot be negative");
char[] clistarr = CharList36.ToCharArray();
var result = new Stack<char>();
while (input != 0)
{
result.Push(clistarr[input % 36]);
input /= 36;
}
return new string(result.ToArray()).ToUpper();
}
private static ulong Decode36(string input)
{
var reversed = ReverseString(input.ToLower());
ulong result = 0;
int pos = 0;
foreach (char c in reversed)
{
result += (ulong)CharList36.IndexOf(c) * (ulong)Math.Pow(36, pos);
pos++;
}
return result;
}
private static string ReverseString(string text)
{
char[] cArray = text.ToCharArray();
string reverse = String.Empty;
for (int i = 0; i < cArray.Length / 2; i++)
{
char c = cArray[i];
cArray[i] = cArray[cArray.Length - 1 - i];
cArray[cArray.Length - 1 - i] = c;
}
return new string(cArray);
}
private static byte[] StringToBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
private static List<byte[]> SplitBytes(byte[] bytes, int length)
{
List<byte[]> result = new List<byte[]>();
int position = 0;
while (bytes.Length - position > length)
{
byte[] temp = new byte[length];
for (int i = 0; i < temp.Length; i++) temp[i] = bytes[i + position];
position += length;
result.Add(temp);
}
if (position < bytes.Length)
{
byte[] temp = new byte[bytes.Length - position];
for (int i = 0; i + position < bytes.Length; i++) temp[i] = bytes[i + position];
result.Add(temp);
}
return result;
}
private static string BytesToString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
private static byte[] JoinBytes(List<byte[]> listBytes)
{
int totalLength = 0;
foreach (byte[] bytes in listBytes) totalLength += bytes.Length;
byte[] result = new byte[totalLength];
int position = 0;
foreach (byte[] bytes in listBytes)
for (int i = 0; i < bytes.Length; i++)
{
result[position] = bytes[i];
position++;
}
return result;
}
#endregion
}
You can encode the resulting bytes using Base36 or another such binary-to-text encoding.

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