SafeDispatch/ServiceGatewaySDR/Parser.cs
2024-02-22 18:43:59 +02:00

774 lines
41 KiB
C#

using SafeMobileLib;
using SDRGatewayService.Enums;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SDRGatewayService
{
class Parser
{
// byte index for binary msg parsing
int Bindex = 0;
// bit index
int bindex = 0;
public string ProcessCommand(byte[] tcp_data, uint len)
{
int i, j;
byte[] out_str = new byte[256];
byte[] xml = new byte[9600]; // xml message
byte[] alarm = new byte[256]; // the alarm (if no alarm -> alarm[0]=0;
byte[] msg_id = new byte[5], rsp = new byte[256];
string m = "";
ulong sid = 0;
long id;
int pos = 0;
int sub_len;
string issi = "";
byte[] buf = new byte[1024];
//tcp_data[len] = 0;
if (tcp_data[len - 1] == '\n' || tcp_data[len - 1] == '\r')
tcp_data[len - 1] = 0;
if (tcp_data[len - 2] == '\n' || tcp_data[len - 2] == '\r')
tcp_data[len - 2] = 0;
Utils.WriteEventLog(Program.COMPANY, String.Format("\n------------------------------------\n") + Environment.NewLine +
String.Format("\n[NAVL recv len=(" + len + ")]\n"), EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
StringBuilder sb = new StringBuilder();
for (i = 0; i < len; i++)
sb.AppendFormat(String.Format("{0:X} ", tcp_data[i]));
string result = sb.ToString().TrimEnd();//when converting to string we also want to trim the redundant new line at the very end
Utils.WriteEventLog(Program.COMPANY, String.Format("\n------------------------------------\n") + Environment.NewLine +
String.Format("\n[NAVL recv len=(" + len + ")]\n") + Environment.NewLine +
result, EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
while (pos < len)
{
byte hp = tcp_data[0], lp = tcp_data[1];
sub_len = hp & 0x00ff;
sub_len <<= 8;
sub_len |= (byte)lp & 0x00ff;
if (sub_len <= 0 || sub_len > 600)
{
Utils.WriteEventLog(Program.COMPANY, String.Format("\n>>> {0:D}[{1:X},{2:X}] : {3:D} : {4:D} \n\n",
sub_len, tcp_data[0], tcp_data[1], pos, len) + Environment.NewLine +
String.Format("err: length is {0:d}\n", sub_len), EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
return "";
}
Utils.WriteEventLog(Program.COMPANY, String.Format("\n>>> {0:D}[{1:X},{2:X}] : {3:D} : {4:D} \n\n",
sub_len, tcp_data[0], tcp_data[1], pos, len), EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
// strncpy(buf, tcp_data+2, sub_len);
for (i = 0; i < sub_len; i++)
buf[i] = tcp_data[pos + 2 + i];
pos += sub_len + 2;
// ***************************************************************************************** parse header
if (buf[0] == '<' && buf[1] == 'p' && buf[2] == 'i' &&
buf[3] == 'n' && buf[4] == 'g' && buf[5] == '>')
{
continue;
}
switch ((char)buf[0])
{
case '#': // ---------------------------------------------------- this is the nAVL IMEI
// IN: #IMEI
// OUT: (2.16 connection notice)
issi = System.Text.Encoding.UTF8.GetString(buf, 1, sub_len - 1);
//strncpy(issi, buf+1, sub_len-1);
Utils.WriteEventLog(Program.COMPANY, String.Format("imei registered {0}\n", issi), EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
m = String.Format("id=\"110000\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" soft_ver=\"\"", issi);
break;
case 'D': // ---------------------------------------------------- config response
// IN: D,T,I,SpH,SpM,SaH,SaM
// OUT: (2.15 Configuration Response)
// <rsp id="101111" sid="SID" mode="GPRS" Hw_Type="NAVL" subscriber="imei"
// sch_type="T" delay="I" Eh="SpH" Em="SpM" Sh="SaH" Sm="SaM" R="" Phone_Nr=""></rsp>
{
string T = "", I = "", SpH = "", SpM = "", SaH = "", SaM = "";
i = 2;
ParseTillComma(buf, ref i, out T); // T
ParseTillComma(buf, ref i, out I); // I
ParseTillComma(buf, ref i, out SpH); // SpH
ParseTillComma(buf, ref i, out SpM); // SpM
ParseTillComma(buf, ref i, out SaH); // SaH
ParseTillComma(buf, ref i, out SaM); // SaM
m = String.Format("id=\"101111\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" sch_type=\"{1}\" delay=\"{2}\" Eh=\"{3}\" Em=\"{4}\" Sh=\"{5}\" Sm=\"{6}\" R=\"\" Phone_Nr=\"\"",
issi, T, I, SpH, SpM, SaH, SaM);
}
break;
case 'H': // ---------------------------------------------------- config response
// IN: H,id,time,lat,lng,spd,dgr,ai1,..,ai8,di,do
// OUT: (2.10 Poll Response)
// <rsp id="101010" sid="SID" mode="GPRS" Hw_Type="NAVL" subscriber="imei"
// poll_id="id" time="time" latitude="lat" longitude="lng" speed="spd"
// ai1="ai1" .. ai8="ai8" di="di" do="do"></rsp>
{
int k;
string lat, lng, _id, time, spd;
string[] ai = new string[7];
string _di, _do, dgr;
char isno;
int type;
float flat, flng;
double speed;//used for conversion from knots to km
DateTime time70;
Utils.WriteEventLog(Program.COMPANY, String.Format("packet type: 'H' text\n"), EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
k = 2;
ParseTillComma(buf, ref k, out _id); // id
ParseTillComma(buf, ref k, out time); // time
ParseTillComma(buf, ref k, out lat); // lat
ParseTillComma(buf, ref k, out lng); // lng
ParseTillComma(buf, ref k, out spd); // spd
ParseTillComma(buf, ref k, out dgr); // degrees
//ParseTillComma(buf, &k, ai[0]); // ai8
//ParseTillComma(buf, &k, ai[1]); // ai1
//ParseTillComma(buf, &k, ai[2]); // ai2
//ParseTillComma(buf, &k, ai[3]); // ai3
//ParseTillComma(buf, &k, ai[4]); // ai4
//ParseTillComma(buf, &k, ai[5]); // ai5
//ParseTillComma(buf, &k, ai[6]); // ai6
//ParseTillComma(buf, &k, ai[7]); // ai7
ParseTillComma(buf, ref k, out _di); // di
ParseTillComma(buf, ref k, out _do); // do
time70 = DateTime.Parse(time);
//convert speed from knots/h to Km/h
speed = float.Parse(spd);
speed *= 1.85325;
spd = speed.ToString();
ProcessGPSPositions(long.Parse(lat), long.Parse(lng), out flat, out flng);
isno = '1';
for (i = 0; i < _id.Length; i++)
if (_id[i] < '0' || _id[i] > '9')
{
isno = '0';
break;
}
for (i = 0; i < 8; i++)
ai[i] = "0\0";
if (isno == '1')
{
m = String.Format("id=\"101010\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" poll_id=\"{1}\" time=\"{2}\" latitude=\"{3}\" longitude=\"{4}\" speed=\"{5}\" dgr=\"{6}\" ai1=\"{7}\" ai2=\"{8}\" ai3=\"{9}\" ai4=\"{10}\" ai5=\"{11}\" ai6=\"{12}\" ai7=\"{13}\" ai8=\"{14}\" di=\"0x{15}\" do=\"0x{16}\"",
issi, _id, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di, _do);
}
else
{
if (_id.Contains("CMDO")) type = 1;
else if (_id.Contains("CMDP-0")) type = 2;
else if (_id.Contains("CMDP-1")) type = 3;
else if (_id.Contains("CMDN-3")) type = 8;
else if (_id.Contains("CMDN")) type = 4;
else if (_id.Contains("CMDR")) type = 5;
else if (_id.Contains("CMDG")) type = 6;
else if (_id.Contains("CMDX")) type = 7;
else if (_id.Contains("CMDS")) type = 9;
else if (_id.Contains("ST0")) type = 10;
else if (_id.Contains("ST1")) type = 11;
else if (_id.Contains("ST2")) type = 12;
else if (_id.Contains("ST3")) type = 13;
else type = 0;
switch (type)
{
case 1: // CMDO
continue;
//break;
case 2: // zone message (CMDP-0, CMDP-1)
case 3:
m = String.Format("id=\"100010\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" zone_id=\"\" direction=\"{1}\" time=\"{2}\" latitude=\"{3}\" longitude=\"{4}\" speed=\"{5}\" dgr=\"{6}\" ai1=\"{7}\" ai2=\"{8}\" ai3=\"{9}\" ai4=\"{10}\" ai5=\"{11}\" ai6=\"{12}\" ai7=\"{13}\" ai8=\"{14}\" di=\"{15}\" do=\"{16}\"",
issi, (type == 2) ? 0 : 1, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di, _do);
break;
case 4: // digital alerts (CMDP-0, CMDP-1)
m = String.Format("id=\"100011\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"{14}\" do=\"{15}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di, _do);
break;
case 5: // idle alerts (CMDR)
m = String.Format("id=\"100100\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"{14}\" do=\"{15}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], int.Parse(ai[4]) / 6 + 1, ai[5], ai[6], ai[7],
_di, _do);
break;
case 6: // geo time (CMDG)
m = String.Format("id=\"100001\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"{14}\" do=\"{15}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di, _do);
break;
case 7: // RFID (CMDX)
{
string rfid, ver;
ParseTillComma(buf, ref k, out ver); // ver
ParseTillComma(buf, ref k, out rfid); // rfid
m = String.Format("id=\"100111\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"{14}\" do=\"{15}\" rfid=\"{16}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di, _do, rfid);
}
break;
case 8: // stop alarm (CMDN-3)
m = String.Format("id=\"100001\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"{14}\" do=\"{15}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di, _do);
break;
case 9: // speed alarm (CMDS)
m = String.Format("id=\"100001\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"{14}\" do=\"{15}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di, _do);
break;
case 10: // w,st
case 11:
case 12:
case 13:
m = String.Format("id=\"100001\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"{14}\" do=\"{15}\"",
issi, time70, type - 10, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di, _do);
break;
default:
Utils.WriteEventLog(Program.COMPANY, String.Format("warning: unknown type={0} for binary message\n", type), EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
continue;
//break;
}
}
}
break;
case 'G': // ---------------------------------------------------- software version
// IN: G,HW_VER-2.0,SW_VER-3.0
// OUT: (2.6 Soft ver)
// <rsp id="100110" sid="SID" mode="GPRS" Hw_Type="NAVL" subscriber="imei"
// prot="" hw="2.0" sw_asm="0" sw_c="3.0"></rsp>
{
string hw, sw;
i = 2;
ParseTillComma(buf, ref i, out hw);
ParseTillComma(buf, ref i, out sw);
m = String.Format("id=\"100110\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" prot=\"\" hw=\"{1}\" sw_asm=\"\" sw_c=\"{2}\"",
issi, hw, sw);
}
break;
case 'M': // ---------------------------------------------------- text message
// IN: M,text writen by user
// OUT: (2.12 text message)
// <rsp id="101100" sid="SID" mode="GPRS" Hw_Type="NAVL" subscriber="imei"
// message=""></rsp>
{
m = String.Format("id=\"101100\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" message=\"{1}\"",
issi, System.Text.Encoding.UTF8.GetString(buf, 2, sub_len - 2));
}
break;
case 'P': // ---------------------------------------------------- zone config
// IN: P,0,22,&,,,,,&,,,,,&,,,,,&,,,,,
// OUT: (2.13)
// <rsp id="101101" sid="SID" mode="GPRS" Hw_Type="NAVL" subscriber="imei"
// totalzones=""
// zone1_nr="" zone1_lat="" zone1_lng="" zone1_dlat="" zone1_dlng=""
// zone2_nr="" zone2_lat="" zone2_lng="" zone2_dlat="" zone2_dlng=""
// zone3_nr="" zone3_lat="" zone3_lng="" zone3_dlat="" zone3_dlng=""
// zone4_nr="" zone4_lat="" zone4_lng="" zone4_dlat="" zone4_dlng=""
// ></rsp>
{
string tz, _id;
string type, zlat, zlng, zdlat, zdlng;
int no = -1;
string aux;
float flat, flng;
i = 2;
ParseTillComma(buf, ref i, out tz);
ParseTillComma(buf, ref i, out _id);
m = String.Format("id=\"101101\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" totalzones=\"{1}\" ", issi, tz);
no = int.Parse(_id);
ParseTillComma(buf, ref i, out type);
ParseTillComma(buf, ref i, out zlat);
ParseTillComma(buf, ref i, out zlng);
ParseTillComma(buf, ref i, out zdlat);
ParseTillComma(buf, ref i, out zdlng);
ProcessGPSPositions(long.Parse(zlat), long.Parse(zlng), out flat, out flng);
aux = String.Format("zone1_nr=\"{0}\" zone1_lat=\"{1}\" zone1_lng=\"{2}\" zone1_dlat=\"{3}\" zone1_dlng=\"{4}\"", no, flat, flng, zdlat, zdlng);
m += aux;
no++;
ParseTillComma(buf, ref i, out type);
ParseTillComma(buf, ref i, out zlat);
ParseTillComma(buf, ref i, out zlng);
ParseTillComma(buf, ref i, out zdlat);
ParseTillComma(buf, ref i, out zdlng);
ProcessGPSPositions(long.Parse(zlat), long.Parse(zlng), out flat, out flng);
aux = String.Format("zone2_nr=\"{0}\" zone2_lat=\"{1}\" zone2_lng=\"{2}\" zone2_dlat=\"{3}\" zone2_dlng=\"{4}\"", no, flat, flng, zdlat, zdlng);
m += aux;
no++;
ParseTillComma(buf, ref i, out type);
ParseTillComma(buf, ref i, out zlat);
ParseTillComma(buf, ref i, out zlng);
ParseTillComma(buf, ref i, out zdlat);
ParseTillComma(buf, ref i, out zdlng);
ProcessGPSPositions(long.Parse(zlat), long.Parse(zlng), out flat, out flng);
aux = String.Format("zone3_nr=\"{0}\" zone3_lat=\"{1}\" zone3_lng=\"{2}\" zone3_dlat=\"{3}\" zone3_dlng=\"{4}\"", no, flat, flng, zdlat, zdlng);
m += aux;
no++;
ParseTillComma(buf, ref i, out type);
ParseTillComma(buf, ref i, out zlat);
ParseTillComma(buf, ref i, out zlng);
ParseTillComma(buf, ref i, out zdlat);
ParseTillComma(buf, ref i, out zdlng);
ProcessGPSPositions(long.Parse(zlat), long.Parse(zlng), out flat, out flng);
aux = String.Format("zone4_nr=\"{0}\" zone4_lat=\"{1}\" zone4_lng=\"{2}\" zone4_dlat=\"{3}\" zone4_dlng=\"{4}\"", no, flat, flng, zdlat, zdlng);
m += aux;
}
break;
case 'K': // ---------------------------------------------------- clock response
// IN: K,120105121033
// OUT: (2.14)
// <rsp id="100110" sid="SID" mode="GPRS" Hw_Type="NAVL" subscriber="imei"
// time="120105121033"></rsp>
{
m = String.Format("id=\"100110\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\"", issi, System.Text.Encoding.UTF8.GetString(buf, 2, sub_len - 2));
}
break;
case 'U': // ---------------------------------------------------- binary message
// IN: g,binary msg
// OUT: 2.2, .23, 2.4, 2.7, cmdx
{
ulong[] ai = new ulong[10];
ulong type = 0;
ulong lat = 0, lng = 0;
float flat, flng;
ulong spd = 0, _di = 0, _do = 0;
ulong year = 0, mon = 0, day = 0, hour = 0, min = 0, sec = 0;
ulong poll_id = 0;
string time;
DateTime time70;
ulong dgr = 0;
Utils.WriteEventLog(Program.COMPANY, String.Format("Packet Type: binary message\n"), EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
Bindex = 1; // get rid of 'g' and id
bindex = 0;
HGetBits(buf, 8, out type); // msg type
if (type == 0)
HGetBits(buf, 32, out poll_id);
//printf("(%d) bin=%x type=%x\n", Bindex, buf[0], type);
HGetBits(buf, 6, out year); // time
HGetBits(buf, 4, out mon);
HGetBits(buf, 6, out day);
HGetBits(buf, 6, out hour);
HGetBits(buf, 6, out min);
HGetBits(buf, 6, out sec);
Utils.WriteEventLog(Program.COMPANY, String.Format("'g' time = {0}:{1}:{2} {3}:{4}:{5}\n", year, mon, day, hour, min, sec), EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
time70 = new DateTime((int)year, (int)mon, (int)day, (int)hour, (int)min, (int)sec);
HGetBits(buf, 26, out lat); // LLC
HGetBits(buf, 26, out lng);
HGetBits(buf, 10, out spd);
HGetBits(buf, 8, out dgr);
dgr = dgr * 360 / 255;
//converts speed form knots/h in Km/h
spd = (ulong)(spd * 1.85325);
ProcessGPSPositions((long)lat, (long)lng, out flat, out flng);
//printf("(%d) rtc=%s LLC=%x.%x.%x\n", Bindex, time, lat, lng, spd);
for (i = 0; i < 8; i++) // IO
{
ai[i] = 0;
//HGetBits(buf, 16, &ai[i]);
//printf("(%d) ai[%d]=%x\n", Bindex, i, ai[i]);
}
HGetBits(buf, 8, out _di);
HGetBits(buf, 8, out _do);
//printf("(%d) di=%x do=%x\n", Bindex, _di, _do);
switch (type)
{
case 0:
m = String.Format("id=\"101010\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" poll_id=\"{1}\" time=\"{2}\" latitude=\"{3}\" longitude=\"{4}\" speed=\"{5}\" dgr=\"{6}\" ai1=\"{7}\" ai2=\"{8}\" ai3=\"{9}\" ai4=\"{10}\" ai5=\"{11}\" ai6=\"{12}\" ai7=\"{13}\" ai8=\"{14}\" di=\"0x{15}\" do=\"0x{16}\"",
issi, poll_id, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di & 0x00ff, _do & 0x00ff);
break;
case 1: // CMDO
continue;
//break;
case 2: // zone message (CMDP-0, CMDP-1)
case 3:
m = String.Format("id=\"101010\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" poll_id=\"{1}\" time=\"{2}\" latitude=\"{3}\" longitude=\"{4}\" speed=\"{5}\" dgr=\"{6}\" ai1=\"{7}\" ai2=\"{8}\" ai3=\"{9}\" ai4=\"{10}\" ai5=\"{11}\" ai6=\"{12}\" ai7=\"{13}\" ai8=\"{14}\" di=\"0x{15}\" do=\"0x{16}\"",
issi, (type == 2) ? 0 : 1, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di & 0x00ff, _do & 0x00ff);
break;
case 4: // digital alerts (CMDP-0, CMDP-1)
m = String.Format("id=\"100011\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"0x{14}\" do=\"0x{15}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di & 0x00ff, _do & 0x00ff);
break;
case 5: // idle alerts (CMDR)
m = String.Format("id=\"100011\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"0x{14}\" do=\"0x{15}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4] / 6 + 1, ai[5], ai[6], ai[7],
_di & 0x00ff, _do & 0x00ff);
break;
case 6: // geo time (CMDG)
m = String.Format("id=\"100011\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"0x{14}\" do=\"0x{15}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di & 0x00ff, _do & 0x00ff);
break;
case 7: // RFID (CMDX)
{
string rfid = "";
for (i = 0; i < 10; i++)
rfid += (char)buf[Bindex++];
m = String.Format("id=\"100011\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"0x{14}\" do=\"0x{15}\" rfid=\"{16}{17}{18}{19}{20}{21}{22}{23}{24}{25}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di & 0x00ff, _do & 0x00ff, rfid[0], rfid[1], rfid[2], rfid[3], rfid[4], rfid[5], rfid[6], rfid[7], rfid[8], rfid[9]);
}
break;
case 8: // stop alarm (CMDN-3)
m = String.Format("id=\"100011\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"0x{14}\" do=\"0x{15}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di & 0x00ff, _do & 0x00ff);
break;
case 10: // w,st alarm
case 11:
case 12:
case 13:
m = String.Format("id=\"100011\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"0x{14}\" do=\"0x{15}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di & 0x00ff, _do & 0x00ff);
break;
default:
Utils.WriteEventLog(Program.COMPANY, String.Format("warning: unknown type={0} for binary message\n", type), EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
continue;
//break;
}
}
break;
case (char)0xAA:
{ // PAD message
ulong[] ai = new ulong[10];
ulong type = 0, udelta = 0;
ulong lat = 0, lng = 0;
float flat, flng;
ulong spd = 0, _di = 0, _do = 0;
ulong year = 0, mon = 0, day = 0, hour = 0, min = 0, sec = 0;
string time;
DateTime time70;
ulong dgr = 0;
Utils.WriteEventLog(Program.COMPANY, String.Format("Packet type: binary message - PAD\n"), EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
Bindex = 1; // get rid of 'g' and id
bindex = 0;
HGetBits(buf, 6, out year); // time
HGetBits(buf, 4, out mon);
HGetBits(buf, 5, out day);
HGetBits(buf, 5, out hour);
HGetBits(buf, 6, out min);
HGetBits(buf, 6, out sec);
HGetBits(buf, 16, out udelta); // in seconds
Utils.WriteEventLog(Program.COMPANY, String.Format("'g' time = {0}:{1}:{2} {3}:{4}:{5}\n", year, mon, day, hour, min, sec), EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
time70 = new DateTime((int)year, (int)mon, (int)day, (int)hour, (int)min, (int)sec);
//printf("BINDEX=%d sublen=%d\n", Bindex, sub_len);
while (Bindex < sub_len)
{
lat = lng = 0;
flat = flng = 0;
spd = 0;
_di = _do = 0;
HGetBits(buf, 26, out lat); // LLC
HGetBits(buf, 26, out lng);
HGetBits(buf, 12, out spd);
ProcessGPSPositions((long)lat, (long)lng, out flat, out flng);
HGetBits(buf, 8, out dgr);
//convert speed from knots/h in Km/h
spd = (ulong)(spd * 1.85325);
dgr = dgr * 360 / 255;
//printf("(%d) rtc=%s LLC=%x.%x.%x\n", Bindex, time, lat, lng, spd);
for (i = 0; i < 8; i++) // IO
{
ai[i] = 0;
//HGetBits(buf, 16, &ai[i]);
//printf("(%d) ai[%d]=%x\n", Bindex, i, ai[i]);
}
HGetBits(buf, 8, out _di);
HGetBits(buf, 8, out _do);
m = String.Format("id=\"100001\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"{0}\" time=\"{1}\" latitude=\"{2}\" longitude=\"{3}\" speed=\"{4}\" dgr=\"{5}\" ai1=\"{6}\" ai2=\"{7}\" ai3=\"{8}\" ai4=\"{9}\" ai5=\"{10}\" ai6=\"{11}\" ai7=\"{12}\" ai8=\"{13}\" di=\"0x{14}\" do=\"0x{15}\"",
issi, time70, flat, flng, spd, dgr,
ai[0], ai[1], ai[2], ai[3], ai[4], ai[5], ai[6], ai[7],
_di & 0x00ff, _do & 0x00ff);
// this is a common type answer, so we just forward it
//m.mtype = NAVL_RSP;
//printf("[NAVL : put in OutputQueue %s\n", m.mtext);
//QueueSendMessage(outputQueue, &m, 0);
}
}
continue;
//break;
default: // ----------------------------------------------------
m = String.Format("id=\"110001\" mode=\"GPRS\" subscriber=\"{0}\" hw_type=\"NAVL\" Message_Id_number=\"00110011\" Response=\"{1}\"", issi, buf);
break;
}
// this is a common type answer, so we just forward it
//m.mtype = NAVL_RSP;
//printf("[NAVL : put in OutputQueue %s\n", m.mtext);
//QueueSendMessage(outputQueue, &m, 0);
} // end while (pos<len)
return m;
}
//aux
void ParseTillComma(byte[] buf, ref int index, out string param)
{
param = "";
int i = 0, k = index;
char val;
val = (char)buf[k];
while (val != ',' && val != 0 && val != '\n' && val != '\r')
{
param += val;
k++;
val = (char)buf[k];
}
k++;
index = k;
param += (char)0;
}
void ProcessGPSPositions(long pllat, long pllng, out float flat, out float flng)
{
long llat = pllat, llng = pllng;
flat = 0;
flng = 0;
if ((llat > 0) && (llng > 0))
{
llat -= 9000000;
if (llng >= 18000000)
{
llng -= 18000000;
llng *= -1;
}
flat = (float)llat / 100000;
flng = (float)llng / 100000;
}
if (flat < -90 || flat > 90 ||
flng < -180 || flng > 180)
{
Utils.WriteEventLog(Program.COMPANY, String.Format("[nAVL warning \"overflow lat/lng\": flat={0} lng={1}, llat={2} llng={3}]\n",
flat, flng, llat, llng), EventLogEntryType.Information, (int)EventId.EVENT_PARSE);
}
}
private bool strcmp(string a, string b)
{
return a.Contains(b);
}
//! Get a bit from a binary message
// *************************************************************************************
/*!
* \param buf = [i] binary message
* \param bit = [o] bit value
*/
// *************************************************************************************
void HGetBit(byte[] buf, out char bit)
{
char mask;
mask = (char)(1 << (7 - bindex)); // create a mask for the bit (according to the position)
if ((buf[Bindex] & mask) > 0)
bit = (char)1;
else
bit = (char)0;
// printf("Bi=%d bi=%d buf=%x mask=%x bit=%d\n", Bindex, bindex, buf[Bindex], mask, *bit);
if (bindex == 7) // step to next address
{
Bindex++; // if last bit increment byte index (HoB)
bindex = 0;
}
else
bindex++; // else increment the bit index
}
//! Get a number of bits from a binary message
// *************************************************************************************
/*!
* \param buf = [i] binary message
* \param no_bits = [i] number of bits to get
* \param val = [o] returned value
*/
// *************************************************************************************
void HGetBits(byte[] buf, int no_bits, out ulong val)
{
char bit;
ulong mask = 1;
val = 0;
int i;
if (no_bits == 0)
return;
for (i = 0; i < no_bits; i++) // add a bit at a time
{
HGetBit(buf, out bit); // get bit from buf
if (bit > 0) // if bit set
{
val = val | mask;
}
mask <<= (int)1L;
// printf("i=%d mask=%x val=%x\n", i, mask, *val);
}
}
}
}