SafeNet/.svn/pristine/64/64fe3c3513637baa6ef6d4ab2a942625b7a65a76.svn-base
2021-02-24 13:50:23 +02:00

958 lines
36 KiB
Plaintext

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using MySql.Data.MySqlClient;
using System.Collections;
using SafeNetLib;
namespace MotoTRBO_SOC
{
class WatcherServerThread
{
private TcpClient client;
private IPEndPoint serverEndPoint;
private Thread listenThread;
private Thread intervalThread;
private Thread checkThread;
private Thread subscribThread;
private System.Threading.Timer tResendSub;
private System.Threading.Timer tResendGPS;
private DateTime lastPingTime;
private NetworkStream clientStream;
byte[] message;
private string ctrIP;
private int port;
string connString;
string gwID;
string report;
int totalUsers;
public DateTime dt_lastSUB;
bool connDown = false;
public WatcherServerThread(string ctrlIP, int port, string p_connString, string p_gwID, string p_report)
{
Utils.ConsWrite(DebugMSG_Type.CTRL, "WatcherServerThread Constructor");
message = new byte[128];
ctrIP = ctrlIP;
this.port = port;
totalUsers = 0;
connString = p_connString;
gwID = p_gwID;
report = p_report;
try
{
client = new TcpClient();
serverEndPoint = new IPEndPoint(IPAddress.Parse(ctrIP), port);
client.Connect(serverEndPoint);
Utils.ConsWrite(DebugMSG_Type.CTRL, "WatcherServerThread connected on " + port);
clientStream = client.GetStream();
//set read timeout to 35 seconds, according to Motorola Connect Plus PN_Watcher specifications
clientStream.ReadTimeout = 35000;
connDown = false;
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, ex.ToString());
connDown = true;
}
}
public void Stop()
{
if (clientStream != null)
{
clientStream.Close();
}
if (listenThread.IsAlive)
{
listenThread.Abort();
}
if (intervalThread.IsAlive)
{
intervalThread.Abort();
}
}
public void Start()
{
listenThread = new Thread(new ThreadStart(HandleClientComm));
listenThread.IsBackground = true;
listenThread.Start();
Utils.ConsWrite(DebugMSG_Type.CTRL, "============WatcherServerThread Listenning=====================================");
intervalThread = new Thread(new ThreadStart(HandleInterval));
intervalThread.IsBackground = true;
intervalThread.Start();
checkThread = new Thread(new ThreadStart(CheckLastPing));
checkThread.IsBackground = true;
checkThread.Start();
subscribThread = new Thread(new ParameterizedThreadStart(SubscribeALLinDB_del));
subscribThread.IsBackground = true;
tResendSub = new System.Threading.Timer(ResendSUB, null, new TimeSpan(1, 0, 0), new TimeSpan(1, 0, 0));
tResendGPS = new System.Threading.Timer(ResendGPS, null, new TimeSpan(0, 1, 0), new TimeSpan(0, 1, 0));
}
public void RestartTCP()
{
try
{
//add gateway status!!
GWstatus gws = new GWstatus();
gws.gw_id = gwID;
gws.status = 0;
SN_Queues.gwstatusQueue.PostItem(gws);
LOGS.LOG("Reconnecting to controller ip:" + ctrIP + " port:" + port.ToString());
Utils.ConsWrite(DebugMSG_Type.CTRL, "Reconnecting to controller ip:"+ctrIP+" port:"+ port.ToString());
if (client != null)
{
if (client.Connected)
client.Close();
}
client = new TcpClient();
serverEndPoint = new IPEndPoint(IPAddress.Parse(ctrIP), port);
client.Connect(serverEndPoint);
Utils.ConsWrite(DebugMSG_Type.CTRL, "WatcherServerThread connected on " + port);
LOGS.LOG("WatcherServerThread connected on " + port);
clientStream = client.GetStream();
//set read timeout to 35 seconds, according to Motorola Connect Plus PN_Watcher specifications
clientStream.ReadTimeout = 35000;
//resend subscribe all
Thread.Sleep(100);
SubscribeALL(1234);
//SubscribeALLinDB(1234);
dt_lastSUB = DateTime.UtcNow;
connDown = false;
//restart check ping thread
if (checkThread != null)
{
checkThread.Abort();
checkThread = null;
}
checkThread = new Thread(new ThreadStart(CheckLastPing));
checkThread.IsBackground = true;
checkThread.Start();
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "Restart FAILED!!!! " + ex.Message);
}
}
//IF THE UNIT IS NOT IN ht_SUInfo dont process the message
private void HandleClientComm()
{
while (true)
{
try
{
clientStream.ReadTimeout = 30000;
//Console.WriteLine("Waiting for stuff...");
//read LEN first
byte[] msgLen = new byte[2];
int result = clientStream.Read(msgLen, 0, msgLen.Length);
int msgLength = msgLen[0] * 265 + msgLen[1];
message = new byte[msgLength];
result = clientStream.Read(message, 0, msgLength);
//Console.Write(DateTime.Now + "-> ");
//if we got PING send Pong
if (message[0] == 0xff)
{
LOGS.LOG("PING received");
lastPingTime = DateTime.Now;
//Print(message, result, true, "PING");
Utils.ConsWrite(DebugMSG_Type.CTRL, "########### PING received ##########################");
//add to GW status queue for DB entry
GWstatus gws = new GWstatus();
gws.gw_id = gwID;
gws.status = 1;
SN_Queues.gwstatusQueue.PostItem(gws);
Thread.Sleep(500);
PONG();
}
else
{
//Print(message, result, true);
NotifyRespons resp = Decode(message, result);
if (resp.Error)
{
Utils.ConsWrite(DebugMSG_Type.DEV, "Response error suid:" + resp.SUID);
}
if (resp.DialogID != 1234)
{
Utils.ConsWrite(DebugMSG_Type.DEV, "Got one time resp from suid:" + resp.SUID);
}
//test if unit is in DB
if (SN_Queues.ht_SUInfo != null)
{
if (!SN_Queues.ht_SUInfo.ContainsKey(resp.SUID))
{
LOGS.LOG("Unit :" + resp.SUID + " NOT assigned to GWID:" + gwID);
Utils.ConsWrite(DebugMSG_Type.ARS, "Unit :" + resp.SUID + " NOT assigned to GWID:" + gwID);
continue;
}
}
if (resp.Active)
{
totalUsers++;
Utils.ConsWrite(DebugMSG_Type.CTRL, "SU " + resp.SUID + " ON ### Total users: " + totalUsers);
int repInter = Convert.ToInt32(report);
//add ars info to HT
((SUinfo)SN_Queues.ht_SUInfo[resp.SUID]).arsCheckTime = DateTime.UtcNow;
((SUinfo)SN_Queues.ht_SUInfo[resp.SUID]).ARSon = true;
//get reporting interval
repInter = ((SUinfo)SN_Queues.ht_SUInfo[resp.SUID]).repInterval;
Utils.ConsWrite(DebugMSG_Type.GPS, "Interval for SUID:" + resp.SUID + " =" + repInter);
if (resp.DialogID != 1234) Utils.ConsWrite(DebugMSG_Type.DEV, "new Interval for SUID:" + resp.SUID + " =" + repInter);
//create location message!!
MotoTRBOcmdMsg msg = new MotoTRBOcmdMsg();
msg.m_cmd = (byte)MotoTRBOcmd.SET_REPORT_INTERVAL;
msg.m_suid = resp.SUID;
msg.m_payload = repInter.ToString();
if (repInter != 0)
{
SN_Queues.locationQueue.PostItem(msg);
}
else
{
Utils.ConsWrite(DebugMSG_Type.GPS, "SUID:" + resp.SUID + " interval=0 , no GPS reporting needed.");
}
//send sms reg msq
SendSMSThread.Send_Reg_msg(resp.SUID + ".1");
if (resp.DialogID != 1234)
{
//poll ars
LOGS.LOG("Received ARS ON from one time request. unit:" + resp.SUID);
//if previous ars state was OFF mark unit as ON
if (((SUinfo)SN_Queues.ht_SUInfo[resp.SUID]).ARSon == false)
{
InsertARSinQueue(resp.SUID, "ON");
LOGS.LOG("Adding ARS ON prev state was OFF:" + resp.SUID);
}
}
else
{
//normal ARS
InsertARSinQueue(resp.SUID, "ON");
LOGS.LOG("ARS ON " + resp.SUID);
}
}// if (resp.Active)
else
{
totalUsers++;
if (resp.DialogID != 1234)
{
LOGS.LOG("Received ARS OFF from one time request. unit:" + resp.SUID);
if (SN_Queues.ht_SUInfo.ContainsKey(resp.SUID))
{
//if previous ars state was OFF mark unit as ON
if (((SUinfo)SN_Queues.ht_SUInfo[resp.SUID]).ARSon == false)
{
InsertARSinQueue(resp.SUID, "OFF");
LOGS.LOG("Adding ARS OFF prev state was ON:" + resp.SUID);
}
}
}
else
{
InsertARSinQueue(resp.SUID, "OFF");
LOGS.LOG("ARS OFF " + resp.SUID);
}
Utils.ConsWrite(DebugMSG_Type.CTRL, "SU " + resp.SUID + " OFF ### Total users: " + totalUsers);
//mark ARS off in SUinfo
//add ars info to HT
((SUinfo)SN_Queues.ht_SUInfo[resp.SUID]).arsCheckTime = DateTime.UtcNow;
((SUinfo)SN_Queues.ht_SUInfo[resp.SUID]).ARSon = false;
}
}
}
catch (System.IO.IOException ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "I/O exception!!");
Utils.ConsWrite(DebugMSG_Type.always, ex.ToString());
Thread.Sleep(1000);
connDown = true;
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, ex.ToString());
Thread.Sleep(30000);
connDown = true;
}
while (connDown==true)
{
RestartTCP();
Thread.Sleep(10000);
}
//Thread.Sleep(100);
}
}
private void HandleInterval()
{
while (true)
{
string suid = "";
int dialogID = -1;
try
{
//test if we have a change in reporting interval
SUinfo info = SN_Queues.NewIntervalQueue.GetItem(100);
if (info != null)
{
Utils.ConsWrite(DebugMSG_Type.DEV, "Sending SubscribeOneTime to:" + info.suid);
dialogID = 0x1111;
SubscribeOneTime(dialogID, info.suid);
}
}
catch (Exception ex)
{ Utils.ConsWrite(DebugMSG_Type.always, "Error HandleInterval for suid:" + suid + " dialogID:" + dialogID); }
}
}
private void CheckLastPing()
{
lastPingTime = DateTime.Now;
while (!connDown)
{
Thread.Sleep(10000);
Utils.ConsWrite(DebugMSG_Type.CTRL, "Curent time:" + DateTime.Now.ToString("HH:mm:ss")
+ " LastPing:" + lastPingTime.ToString("HH:mm:ss"));
//test if we have a change in reporting interval
TimeSpan ts = DateTime.Now.Subtract(lastPingTime);
if (ts.TotalSeconds > 30)
{
Utils.ConsWrite(DebugMSG_Type.CTRL, "Last ping was >30 sec forcing TCP restart.");
LOGS.LOG("<<<CheckLastPing>>>Curent time:" + DateTime.Now.ToString("HH:mm:ss")
+ " LastPing:" + lastPingTime.ToString("HH:mm:ss"));
RestartTCP();
}
}
}
private void ResendSUB(Object state)
{
// This method is executed by a thread pool thread
try
{
if (DateTime.UtcNow.DayOfYear > dt_lastSUB.DayOfYear)
{
if (DateTime.UtcNow.Hour > 5)
{
SubscribeALL(1234);
//SubscribeALLinDB(1234);
LOGS.LOG("<<<ResendingSubscribeALL>>>Curent time:" + DateTime.UtcNow.ToString()
+ " LastPing:" + dt_lastSUB.ToString());
dt_lastSUB = DateTime.UtcNow;
Utils.ConsWrite(DebugMSG_Type.CTRL, "Resending SubscribeALL.");
}
}
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "Error on ResendSUB:" + ex.ToString());
}
}
int countGPSrefresh = 0;
private void ResendGPS(Object state)
{
// This method is executed by a thread pool thread
try
{
countGPSrefresh++;
if (countGPSrefresh > 1024) countGPSrefresh = 0;
Utils.ConsWrite(DebugMSG_Type.CTRL, "ResendGPS check starded.");
Hashtable temp = (Hashtable)SN_Queues.ht_SUInfo.Clone();
foreach (DictionaryEntry de in temp)
{
SUinfo info = (SUinfo)de.Value;
DateTime lastARStime = info.arsCheckTime;
if (info.ARSon == false)
continue;
//check if more then "ConnectPlus_GW.cfg.GPS_refresh" time has passed since last ARS
if (DateTime.UtcNow.Subtract(new TimeSpan(ConnectPlus_GW.cfg.GPS_refresh, 0, 0)) > lastARStime)
{
Utils.ConsWrite(DebugMSG_Type.CTRL, "Sending SubscribeOneTime to:" + info.suid);
LOGS.LOG("<<<GPS expired for unit:" + info.suid + ">>>Curent time:" + DateTime.UtcNow.ToString()
+ " ||||| Last GPS refresh:" + info.arsCheckTime.ToString());
int dialogID = 0x1111;
SubscribeOneTime(dialogID, info.suid);
}
else
{
//Utils.ConsWrite(DebugMSG_Type.CTRL, "Unit:" + info.suid + " GPS not expired yet!");
if((countGPSrefresh % 30)==0)
LOGS.LOG("<<<GPS not expired yet for unit:" + info.suid + ">>>Curent time:" + DateTime.UtcNow.ToString()
+ " ||||| Last GPS refresh:" + info.arsCheckTime.ToString());
}
}
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "Error on ResendSUB:" + ex.ToString());
}
}
public delegate void MessageRecv(NotifyRespons resp);
public event MessageRecv OnMessageRecv;
private NotifyRespons Decode(byte[] data, int recv)
{
//Console.WriteLine("Got notify message");
NotifyRespons nResp = new NotifyRespons();
nResp.Active = false; nResp.DialogID = 0; nResp.Error = true; nResp.SUID = "0";
//int msgLength = data[0] * 265 + data[1];
//length doesent match... return error
//if (msgLength != recv-2) { Console.WriteLine("Received length({0}) doesent match with message length({1})..returning errror!!!",recv-2,msgLength); return nResp; }
//test if we got at least msgLen, msgID,dialogID,subscription state
if (recv < 6)
{
Utils.ConsWrite(DebugMSG_Type.always, "Incorect message.Message does not have the minimum size of 6bytes. actual length=" + recv);
Utils.ConsWrite(DebugMSG_Type.always, "!!!!!!!!!!!!subscription state TLV missing!!!!!!!!!!!");
return nResp;
}
//decode message ID
int msgID = data[0];
if (msgID != 4) { Console.WriteLine("Incorect msgID:{0}. MsgID must be 4(reliable notify message)", msgID); return nResp; }
//decode dialog ID
int dialogID = data[1] * 256 + data[2];
nResp.DialogID = dialogID;
//Console.WriteLine("DialogID:" + dialogID);
//next TLV are optional
for (int i = 3; i < data.Length; i++)
{
switch (data[i])
{
case 3:
//decode subscription state TLV
byte tag = data[i];
byte len = data[i + 1];
byte value = data[i + 2];
if (tag == 0x03 && len == 0x01)
{
switch (value)
{
case (byte)SubscriptionState.Accepted:
//Console.WriteLine("Subscription State:" + SubscriptionState.Accepted + " value:" + value);
break;
case (byte)SubscriptionState.RefreshAccepted:
//Console.WriteLine("Subscription State:" + SubscriptionState.RefreshAccepted + " value:" + value);
break;
case (byte)SubscriptionState.Rejected:
//Console.WriteLine("Subscription State:" + SubscriptionState.Rejected + " value:" + value);
break;
case (byte)SubscriptionState.Terminated:
//Console.WriteLine("Subscription State:" + SubscriptionState.Terminated + " value:" + value);
break;
}
}
else
{
Utils.ConsWrite(DebugMSG_Type.CTRL, "Unknown subscription state:" + value);
}
//jump to next tlv
i += 1 + len;
break;
//decode Expires TLV
case 1:
tag = data[i];
len = data[i + 1];
byte[] value_arr = new byte[len];
Array.Copy(data, i + 2, value_arr, 0, len);
int expireTime = ConvertByteArr2Int(value_arr);
//Console.WriteLine("Expire time:" + expireTime);
//jump to next tlv
i += 1 + len;
break;
//Decode Entity TLV
case 10:
tag = data[i];
len = data[i + 1];
value_arr = new byte[len];
Array.Copy(data, i + 2, value_arr, 0, len);
string suid = Encoding.Unicode.GetString(value_arr);
nResp.SUID = suid;
//Console.WriteLine("Entity(SUID):" + suid);
//jump to next tlv
i += 1 + len;
nResp.Error = false;
break;
//Decode Event TLV ... "1" - Present, "2" - Absent
case 2:
tag = data[i];
len = data[i + 1];
value_arr = new byte[len];
Array.Copy(data, i + 2, value_arr, 0, len);
string event_string = Encoding.Unicode.GetString(value_arr);
//nResp.Active = (event_string == "1");
//Console.WriteLine("Event TLV:" + event_string);
//jump to next tlv
i += 1 + len;
break;
case 14:
tag = data[i];
len = data[i + 1];
value_arr = new byte[len];
Array.Copy(data, i + 2, value_arr, 0, len);
string presence = Encoding.Unicode.GetString(value_arr);
switch (presence)
{
case "0":
//Console.WriteLine("Presence state TLV: unknown value:" + presence);
break;
case "1":
nResp.Active = true;
//Console.WriteLine("Presence state TLV: present value:" + presence);
break;
case "2":
nResp.Active = false;
//Console.WriteLine("Presence state TLV: absent value:" + presence);
break;
}
//jump to next tlv
i += 1 + len;
break;
}
}
return nResp;
}
public void Send(byte[] data, int len)
{
if (clientStream != null)
{
clientStream.Write(data, 0, len);
clientStream.Flush();
}
}
#region Subscribe messages and PONG message
/// <summary>
/// Send the subcribe message to the controler
/// </summary>
/// <param name="dialogID">unique dialog ID</param>
/// <param name="ID">ID of radio subscriber that is being watched</param>
/// <param name="expiresTime">time to live of the subscription</param>
public void Subscribe(int dialogID, int ID, byte expiresTime)
{
Utils.ConsWrite(DebugMSG_Type.DEV, "DialogID:" + dialogID);
byte[] tempID = convertInt2ByteLE(ID);
byte[] msg = new byte[18 + tempID.Length];
//length
msg[0] = 0x00;
msg[1] = Convert.ToByte(0x10 + tempID.Length);
// message ID
msg[2] = 0x03;
// Dialog ID
byte[] tempDialogID = BitConverter.GetBytes(dialogID);
msg[3] = tempDialogID[1];
msg[4] = tempDialogID[0];
//Message BODY
//The Expires TLV Field
msg[5] = 0x01;
msg[6] = 0x01;
msg[7] = expiresTime;
//The TCPPort TLV Field
msg[8] = 0x06;
msg[9] = 0x02;
byte[] tempPort = BitConverter.GetBytes(0x3344);
msg[10] = tempPort[1];
msg[11] = tempPort[0];
//The Entities TLV Field
msg[12] = 0x0a;
msg[13] = Convert.ToByte(tempID.Length);
// ID
for (int i = 0; i < tempID.Length; i++)
{
msg[14 + i] = tempID[i];
}
//The Events TLV Field
msg[14 + tempID.Length] = 0x02;
msg[14 + tempID.Length + 1] = 0x02;
msg[14 + tempID.Length + 2] = 0x31;
msg[14 + tempID.Length + 3] = 0x00;
Send(msg, msg.Length);
//Console.WriteLine("-----------Sent Subscribe to the controller-----");
//Print(msg, msg.Length, false);
}
public void SubscribeALL(int dialogID)
{
byte[] msg = new byte[23];
//length
msg[0] = 0x00;
msg[1] = 0x15;
// message ID
msg[2] = 0x03;
// Dialog ID
byte[] tempDialogID = BitConverter.GetBytes(dialogID);
msg[3] = tempDialogID[1];
msg[4] = tempDialogID[0];
//Message BODY
//The Expires TLV Field (2^32 secs = ~ 136 years)
msg[5] = 0x01;
msg[6] = 0x04;
msg[7] = 0xff;
msg[8] = 0xff;
msg[9] = 0xff;
msg[10] = 0xff;
//The Entities TLV Field
msg[11] = 0x0a;
msg[12] = 0x02;
// ID:all
msg[13] = 0x2a;
msg[14] = 0x00;
//The Events TLV Field
msg[15] = 0x02;
msg[16] = 0x06;
msg[17] = (byte)'1';
msg[18] = 0x00;
msg[19] = (byte)',';
msg[20] = 0x00;
msg[21] = (byte)'2';
msg[22] = 0x00;
Send(msg, msg.Length);
//Console.WriteLine("-----------Sent Subscribe ALL to the controller-----");
//Print(msg, msg.Length, false);
}
public void SubscribeOneTime(int dialogID, string suid)// TLV expire =0
{
//Utils.ConsWrite(DebugMSG_Type.DEV, "DialogID:" + dialogID);
char[] suidARR = suid.ToCharArray();
byte[] msg = new byte[18 + suidARR.Length*2];
//length
msg[0] = 0x00;
msg[1] = (byte)(16 + suidARR.Length * 2);
// message ID
msg[2] = 0x03;
// Dialog ID
byte[] tempDialogID = BitConverter.GetBytes(dialogID);
msg[3] = tempDialogID[1];
msg[4] = tempDialogID[0];
//Message BODY
//The Expires TLV Field
msg[5] = 0x01;
msg[6] = 0x01;
msg[7] = 0x00;//one time
//The Entities TLV Field
msg[8] = 0x0a;
msg[9] = (byte)(suidARR.Length*2);
for (int i = 0; i < suidARR.Length; i++)
{
byte b = (byte)suidARR[i];
//Console.WriteLine(b);
msg[10 + i * 2] = b;
msg[10 + i * 2 + 1] = 0x00;
}
//The Events TLV Field
msg[10 + suidARR.Length * 2] = 0x02;
msg[10 + suidARR.Length * 2 + 1] = 0x06;
msg[10 + suidARR.Length * 2 + 2] = (byte)'1';
msg[10 + suidARR.Length * 2 + 3] = 0x00;
msg[10 + suidARR.Length * 2 + 4] = (byte)',';
msg[10 + suidARR.Length * 2 + 5] = 0x00;
msg[10 + suidARR.Length * 2 + 6] = (byte)'2';
msg[10 + suidARR.Length * 2 + 7] = 0x00;
Send(msg, msg.Length);
//Console.WriteLine("-----------Sent Subscribe ALL to the controller-----");
//Print(msg, msg.Length, false);
}
public void SubscribeALL()
{
byte[] msg = new byte[20];
//length
msg[0] = 0x00;
msg[1] = 0x12;
// message ID
msg[2] = 0x03;
// Dialog ID
msg[3] = 0x33;
msg[4] = 0x44;
//Message BODY
//The Expires TLV Field
msg[5] = 0x01;
msg[6] = 0x01;
msg[7] = 0xff;
//The TCPPort TLV Field
msg[8] = 0x06;
msg[9] = 0x02;
byte[] temp = BitConverter.GetBytes(0x3344);
msg[10] = temp[1];
msg[11] = temp[0];
//The Entities TLV Field
msg[12] = 0x0a;
msg[13] = 0x02;
// ID:all
msg[14] = 0x2a;
msg[15] = 0x00;
//The Events TLV Field
msg[16] = 0x02;
msg[17] = 0x02;
msg[18] = 0x2a;
msg[19] = 0x00;
Send(msg, msg.Length);
Utils.ConsWrite(DebugMSG_Type.CTRL, "-----------Sent Subscribe to the controller-----");
//Print(msg, msg.Length, false);
}
public void SubscribeList(int dialogID, List<string> suids)// TLV expire =0
{
//Utils.ConsWrite(DebugMSG_Type.DEV, "DialogID:" + dialogID);
//create arr string: suid1,suid2,....,suidn
string strSUIDS="";
for (int i = 0; i < suids.Count; i++)
{
if (i != (suids.Count - 1))
{
strSUIDS += suids[i] + ",";
}
else
{
strSUIDS += suids[i];
}
}
Utils.ConsWrite(DebugMSG_Type.ARS, "suids string:" + strSUIDS);
char[] suidARR = strSUIDS.ToCharArray();
byte[] msg = new byte[15 + suidARR.Length * 2];
//length
msg[0] = 0x00;
msg[1] = (byte)(13 + suidARR.Length * 2);
// message ID
msg[2] = 0x03;
// Dialog ID
byte[] tempDialogID = BitConverter.GetBytes(dialogID);
msg[3] = tempDialogID[1];
msg[4] = tempDialogID[0];
//Message BODY
//The Expires TLV Field
//msg[5] = 0x01;
//msg[6] = 0x01;
//msg[7] = 0x00;//one time
//The Entities TLV Field
msg[5] = 0x0a;
msg[6] = (byte)(suidARR.Length * 2);
for (int i = 0; i < suidARR.Length; i++)
{
byte b = (byte)suidARR[i];
//Console.WriteLine(b);
msg[7 + i * 2] = b;
msg[7 + i * 2 + 1] = 0x00;
}
//The Events TLV Field
msg[7 + suidARR.Length * 2] = 0x02;
msg[7 + suidARR.Length * 2 + 1] = 0x06;
msg[7 + suidARR.Length * 2 + 2] = (byte)'1';
msg[7 + suidARR.Length * 2 + 3] = 0x00;
msg[7 + suidARR.Length * 2 + 4] = (byte)',';
msg[7 + suidARR.Length * 2 + 5] = 0x00;
msg[7 + suidARR.Length * 2 + 6] = (byte)'2';
msg[7 + suidARR.Length * 2 + 7] = 0x00;
Send(msg, msg.Length);
//Console.WriteLine("-----------Sent Subscribe ALL to the controller-----");
//Print(msg, msg.Length, false);
}
public void SubscribeALLinDB(int dialogID)
{
//start subscription thread
subscribThread.Start(dialogID);
}
private void SubscribeALLinDB_del(object dialogID)
{
//wait for su info to be retrived from DB
while(SN_Queues.ht_SUInfo.Count < 1)
{
Utils.ConsWrite(DebugMSG_Type.ARS, "SubscribeALLinDB waiting for SU info from DB sleeping 500ms <------> or no unit present in DB for gwid:" + gwID);
Thread.Sleep(500);
}
List<string> suids = null;
if (SN_Queues.ht_SUInfo != null)
{
suids = new List<string>();
foreach (DictionaryEntry de in SN_Queues.ht_SUInfo)
{
suids.Add(((SUinfo)de.Value).suid);
}
}
if(suids != null)
SubscribeList((int)dialogID, suids);
}
//send PONG back to controller
public void PONG()
{
byte[] msg = new byte[12];
//length
msg[0] = 0x00;
msg[1] = 0x0a;
// message ID
msg[2] = 0xff;
// body length
msg[3] = 0x08;
//PONG -utf16 LE string
//P
msg[4] = 0x50;
msg[5] = 0x00;
//O
msg[6] = 0x4f;
msg[7] = 0x00;
//N
msg[8] = 0x4e;
msg[9] = 0x00;
//G
msg[10] = 0x47;
msg[11] = 0x00;
Send(msg, msg.Length);
Console.WriteLine("-----------Sent PONG to the controller-----");
//Print(msg, msg.Length, false, "PONG:");
}
bool InsertARSinQueue(string p_radioID, string p_message)
{
try
{
ArsMSG ars = new ArsMSG();
ars.imei = p_radioID;
ars.msg = p_message;
SN_Queues.arsMsgQueue.PostItem(ars);
return true;
}
catch (Exception e)
{
Utils.ConsWrite(DebugMSG_Type.always, "Error inserting ARS in Queue");
Utils.ConsWrite(DebugMSG_Type.always, e.Message);
return false;
}
}
#endregion
#region AUX methods
private void Print(byte[] data, int length, bool inOut)
{
//Console.Clear();
Console.WriteLine("--------------------------------------------------------------------------- " + length);
Console.Write("Data (" + ((inOut) ? "RECEIVED" : "SENT") + "): ");
for (int i = 0; i < length; i++)
Console.Write(" 0x" + data[i].ToString("X2"));
Console.WriteLine("");
Console.WriteLine("--------------------------------------------------------------------------- ");
}
private static byte[] convertInt2ByteLE(int id)
{
Byte[] retBytes = Encoding.Unicode.GetBytes(id.ToString());
return retBytes;
}
private int ConvertByteArr2Int(byte[] arr)
{
byte[] worker = new byte[4];
arr.CopyTo(worker, 0);
return BitConverter.ToInt32(worker, 0);
}
#endregion
}
public class NotifyRespons
{
private string suid;
public string SUID
{
get { return suid; }
set { suid = value; }
}
private bool active;
public bool Active
{
get { return active; }
set { active = value; }
}
private int dialogID;
public int DialogID
{
get { return dialogID; }
set { dialogID = value; }
}
private bool error;
public bool Error
{
get { return error; }
set { error = value; }
}
}
public enum SubscriptionState
{
Rejected = 1,
Accepted = 2,
Terminated = 3,
RefreshAccepted = 4
}
}