SafeNet/PAL_SOC/ConnectionThread.cs
2021-02-24 13:50:23 +02:00

489 lines
19 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using SafeNetLib;
using System.Net.Sockets;
using System.Threading;
using System.Collections;
namespace PAL_SOC
{
// ---------------------------------------------------
// This class handles a client connection
// ---------------------------------------------------
class ConnectionThread
{
public TcpClient client;
private static int connections = 0;
private static int MAX_IMEI = 14;
private static int MAX_XML = 600;
private static int MAX_BUFFER = 2000;
string imei = "";
enum ERR
{
NO_ERROR,
CRC_ERROR,
LEN_ERROR
};
enum CLIENT
{
GPRS,
COMMAND
};
enum CMD_RSP
{
IMEI_NOT_REG,
IMEI_PROCESSING_CMD,
CMD_ACCEPTED
};
CLIENT threadType;
// ------------------------------------------------------
public ConnectionThread()
{
}
~ConnectionThread()
{
}
static string old = "";
public void HandleConnection()
{
byte[] data = new byte[2048];
NetworkStream ns = client.GetStream();
ns.ReadTimeout = 60000;
//Console.WriteLine("read timeout = " + ns.ReadTimeout);
connections++;
Utils.ConsWrite(DebugMSG_Type.Debug, "New client accepted: " + connections + " active connections");
while (true)
{
try
{
if (ns.CanRead)
{
byte[] myReadBuffer = new byte[2048];
StringBuilder myCompleteMessage = new StringBuilder();
int numberOfBytesRead = 0;
Thread.Sleep(1);
// check for new data available on the socket
try
{
do
{
numberOfBytesRead = ns.Read(myReadBuffer, 0, myReadBuffer.Length);
old = ProcessPacket(myReadBuffer, numberOfBytesRead, old);
}
while (ns.DataAvailable);
if (myCompleteMessage.Length == 0)
{
break;
}
}
catch (Exception ee)
{
//Console.WriteLine(ee.ToString());
break;
}
Utils.ConsWrite(DebugMSG_Type.GPS, "Recived : (len=" + numberOfBytesRead + ")\n");
}
else
{
Utils.ConsWrite(DebugMSG_Type.Debug, "Sorry. You cannot read from this NetworkStream.");
break;
}
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "HandleConnection ERRROR!!! \n: " + ex.ToString());
break;
}
}
ns.Close();
client.Close();
connections--;
Utils.ConsWrite(DebugMSG_Type.Debug, "Client disconnected: " + connections + " active connections");
}
float ProcessGPSLat(String latitude, String lat_dir)
{
try
{
long LAT, LAT2;
char LAT3;
long llat, grade, zec;
char[] param = new char[50];
String[] latList;
float flat;
param = lat_dir.ToCharArray();
if (param[0] != 'N' && param[0] != 'S')
return 0;
//Console.WriteLine("Latitude " + latitude + " dir " + lat_dir);
latList = latitude.Split('.');
LAT = Convert.ToInt32(latList[0]);
if (latList[1].Length > 4)
latList[1] = latList[1].Remove(4);
LAT2 = Convert.ToInt32(latList[1]);
LAT3 = param[0];
// process the lat and lng for display
grade = (LAT / 100L);
zec = (LAT % 100L) * 1000L + LAT2 / 10; // get MMMMM*1000, from MM.mmmmm by MM*1000+mmm (0-59999)
zec = (zec * 100L) / 60L; // translate MMMMM*1000 to DD * 100 * 1000 (0-99998)
grade = grade * 100000 + zec; // translate all to DDddddd
llat = grade;
flat = (float)llat / 100000;
if (param[0] == 'S')
flat = -flat;
if (flat < -90 || flat > 90)
{
Console.WriteLine("[warning \"overflow lat\": flat={0} llat={1}]",
flat, llat);
return 0;
}
return flat;
}
catch (Exception ee)
{
Console.WriteLine("Error in ProcessGPSLat" + ee.ToString());
return 0;
}
}
float ProcessGPSLong(String longitude, String lng_dir)
{
try
{
long LNG, LNG2;
char LNG3;
long llng, grade, zec;
char[] param = new char[50];
String[] lngList;
float flong;
param = lng_dir.ToCharArray();
if (param[0] != 'E' && param[0] != 'W')
return 0;
lngList = longitude.Split('.');
LNG = Convert.ToInt32(lngList[0]);
if (lngList[1].Length > 4)
lngList[1] = lngList[1].Remove(4);
LNG2 = Convert.ToInt32(lngList[1]);
LNG3 = param[0];
grade = LNG / 100; // get DD (0-90)
zec = (LNG % 100L) * 1000L + LNG2 / 10; // get MMMMM*1000, from MM.mmmmm by MM*1000+mmm (0-59999)
zec = (zec * 100L) / 60L; // translate MMMMM*1000 to DD * 100 * 1000 (0-99998)
grade = grade * 100000 + zec; // translate all to DDddddd
llng = grade;
flong = (float)llng / 100000;
if (param[0] == 'W')
flong = -flong;
if (flong < -180 || flong > 180)
{
Console.WriteLine("[warning \"overflow lng\": flng={0} llng={1}]",
flong, llng);
return 0;
}
return flong;
}
catch (Exception ee)
{
Console.WriteLine("Error in ProcessGPSLong" + ee.ToString());
return 0;
}
}
// ---------------------------------------------------
// Packet and command processing
// ---------------------------------------------------
public string ProcessPacket(byte[] data, int len, String remains)
{
try
{
int i, pos, pos1, itime70, xmlnr;
string xml = "", auxStr = ""; // this is the xml message that will be feeded into the DB
char[] dataC = new char[30000];
char[] auxC = new char[3500];
String[] pList;
ArrayList xmls = new ArrayList();
String cmdCS = "", latDir = "", longDir = "", param;
String imei = "", pTime, pLat, pLong, hdop, alt, fix, cog, skmh, sknt, date, nsat, gpio = "", gpi = "", gpo = "", RFID = "",Alarm ="";
int year = 0, mon = 0, day = 0, hour = 0, min = 0, sec = 0;
pLong = "0.0";
pLat = "0.0";
float flat, flong;
double fhdop;
for (i = 0; i < len; i++)
{
dataC[i] = (char)data[i];
auxStr += dataC[i];
}
//add unprocessed string bits from last command
//Console.WriteLine("\r\nLength:{0}:\r\n({1})\r\n({2})\r\n", len, remains, auxStr);
auxStr = remains + auxStr;
xmlnr = 0;
i = 0;
while (auxStr.Contains("<<<") && auxStr.Contains(">>>"))
{
i++;
pos = auxStr.IndexOf("<<<");
pos1 = auxStr.IndexOf(">>>");
cmdCS = auxStr.Substring(pos + 3, pos1 - pos - 3);
auxStr = auxStr.Substring(pos1 + 3, auxStr.Length - pos1 - 3);
Console.WriteLine("got{0}:<{1}>", i, cmdCS);
//valid...
pList = cmdCS.Split(',');
if (pList[1].IndexOf("gna") == 0)
continue;
pTime = pList[1];
date = pList[10];
nsat = pList[11];
//get only the integer part
pos = pList[8].IndexOf(".");
if (pos > 0)
skmh = pList[8].Remove(pos);
else
skmh = "0";
//Console.WriteLine("ID param: " + pList[0]);
//extract '<<<' from the imei
if (pList[0].Contains("<<<"))
{
//!!!! testez daca e imei de telit //ar trebui +3 - din cauza ca db are 14 lungime imei si telit are 15
if (pList[0].Length == 18)
{
pos = pList[0].IndexOf("<<<") + 4;
}
else
{
pos = pList[0].IndexOf("<<<") + 3;
}
pList[0] = pList[0].Substring(pos, pList[0].Length - pos);
}
else
{
//!!!! testez daca imei de telit //ar trebui 0 nu 1 - din cauza ca db are 14 lungime imei si telit are 15
if (pList[0].Length == 15)
{
//pList[0] = pList[0].Substring(1, pList[0].Length - 1);
}
}
//extract '>>>' from the gpio
gpi = "0";
gpo = "0";
imei = pList[0];
//if the fix is valid - 2d or 3d
if (pList[6].Contains("2") || pList[6].Contains("3"))
{
hdop = pList[4];
if (pList[2].Length > 1)
{
pos = pList[2].Length - 1;
latDir = pList[2].Substring(pos, 1);
pLat = pList[2].Remove(pos);
}
else
{
latDir = "N";
pLat = "0.0";
}
if (pList[3].Length > 1)
{
pos = pList[3].Length - 1;
longDir = pList[3].Substring(pos, 1);
pLong = pList[3].Remove(pos);
}
else
{
longDir = "E";
pLong = "0.0";
}
param = pTime.Substring(0, 2);
hour = Convert.ToInt32(param);
param = pTime.Substring(2, 2);
min = Convert.ToInt32(param);
param = pTime.Substring(4, 2);
sec = Convert.ToInt32(param);
param = date.Substring(0, 2);
day = Convert.ToInt32(param);
param = date.Substring(2, 2);
mon = Convert.ToInt32(param);
param = date.Substring(4, 2);
year = Convert.ToInt32(param);
System.DateTime dateTime = new DateTime(2000 + year, mon, day, hour, min, sec, DateTimeKind.Utc);
if (2000 + year != DateTime.Now.Year)
{
Console.WriteLine("{0}:::::{1}", 2000 + year, DateTime.Now.Year);
return auxStr;
}
TimeSpan diff = new DateTime(2000 + year, mon, day, hour, min, sec, DateTimeKind.Utc) -
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime d = new DateTime();
if (d.IsDaylightSavingTime())
{
Console.WriteLine("Time: Is daylight");
itime70 = Convert.ToInt32(diff.TotalSeconds) + 3600;
}
else
itime70 = Convert.ToInt32(diff.TotalSeconds);
flat = ProcessGPSLat(pLat, latDir);
flong = ProcessGPSLong(pLong, longDir);
cog = pList[7].Remove(pList[7].IndexOf("."));
if (pList.Length > 13)
{
gpio = pList[13];
if (gpio.Length == 5)
{
int tmpgp = 0;
if (gpio[0] == '1') tmpgp = tmpgp + 1;
if (gpio[1] == '1') tmpgp = tmpgp + 2;
gpo = tmpgp.ToString();
tmpgp = 0;
if (gpio[2] == '1') tmpgp = tmpgp + 1;
if (gpio[3] == '1') tmpgp = tmpgp + 2;
if (gpio[4] == '1') tmpgp = tmpgp + 4;
gpi = tmpgp.ToString();
}
}
//check for alarm
if (pList.Length > 14)
{
Alarm = pList[14];
}
String plat, plong;
plat = Convert.ToString(flat);
plong = Convert.ToString(flong);
plat = plat.Replace(',', '.');
plong = plong.Replace(',', '.');
xml += "\" time=\"" + itime70.ToString() + "\" latitude=\"" + plat + "\" longitude=\"" + plong;
xml += "\" speed=\"" + skmh + "\" dgr=\"" + cog;
xml += "\" ai1=\"" + "0" + "\" ai2=\"" + "0";
xml += "\" ai3=\"" + "0" + "\" ai4=\"" + "0";
xml += "\" ai5=\"" + "0" + "\" ai6=\"" + "0";
xml += "\" ai7=\"" + "0" + "\" ai8=\"" + "0";
xml += "\" di=\"" + gpi + "\" do=\"" + gpo;
xml += "\" RFID=\"" + RFID + "\"";
//add data to location QUEUE
try
{
//locManager.SendLoc2messagebus(imei, (Int32)(itime70/1000), iSpeed.ToString(), pLat, pLong);
htCell_t cell = new htCell_t();
cell.suid = imei;
cell.spd = skmh.ToString();
cell.lat = pLat;
cell.lng = pLong;
cell.d_lat = flat;
cell.d_lng = flong;
cell.location_time = dateTime;//Utils.UnixTimeStampToDateTime(itime70 / 1000);
Utils.ConsWrite(DebugMSG_Type.GPS, "GPS for SUID: " + imei + " with time: " + cell.location_time + " lat: " + pLat + " lng: " + pLong);
SN_Queues.DBQueueLocation.PostItem(cell);
Utils.ConsWrite(DebugMSG_Type.GPS, "Message added to queue!!!");
//process ALERTS
if (SN_Queues.ht_SUInfo.ContainsKey(imei))
{
Utils.ConsWrite(DebugMSG_Type.ALERTS, "Processing alerts for: " + imei);
Utils.ConsWrite(DebugMSG_Type.ALERTS, "Message mask: " + gpi);
Utils.ConsWrite(DebugMSG_Type.ALERTS, "Message contains alarm token: " + Alarm);
SUinfo sui = (SUinfo)SN_Queues.ht_SUInfo[imei];
foreach (Alert alert in sui.alertList)
{
if (Alarm.Contains("!") || Alarm.Contains("ALARM"))
{
if (alert.Type == Alert_TYPE.DI)
if (alert.DImask1 == Convert.ToInt32(gpi))
{
SN_Queues.alertQueue.PostItem(alert);
Utils.ConsWrite(DebugMSG_Type.ALERTS, "********* Alert (DI): " + alert.Alert_name + " added to queue ********");
}
}
if (alert.Type == Alert_TYPE.SPEED)
{
if (((alert.Speed *16)/10) < Int32.Parse(skmh))
{
SN_Queues.alertQueue.PostItem(alert);
Utils.ConsWrite(DebugMSG_Type.ALERTS, "@@@@@@@@@@ Alert (SPEED): " + alert.Alert_name + " added to queue @@@@@@@@");
}
}
}
}
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "ConnectionThread.cs =>> Error adding location to queue!!!");
Utils.ConsWrite(DebugMSG_Type.always, ex.ToString());
}
}
} // while
return auxStr;
}
catch (Exception ee)
{
Console.WriteLine("Erorr in Procces packet" + ee.ToString());
return " ";
}
}
}
}