779 lines
29 KiB
C#
779 lines
29 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Collections;
|
|||
|
using SafeMobileLib;
|
|||
|
using System.Threading;
|
|||
|
using SafeMobileLib.MessageDecoders;
|
|||
|
|
|||
|
namespace MotoRepeater
|
|||
|
{
|
|||
|
public class DataBaseSN : DataBaseInterface
|
|||
|
{
|
|||
|
private DBconnThread dbConnection;
|
|||
|
|
|||
|
public static Thread DBThreadobjARS = null;
|
|||
|
public static Thread DBThreadobjGPS = null;
|
|||
|
public static Thread DBThreadobjAux = null;
|
|||
|
public static Thread DBThreadobjSMS = null;
|
|||
|
public static Thread DBThreadobjSMS_conf = null;
|
|||
|
public static Thread DBThreadobjAddr = null;
|
|||
|
public static Thread DBThreadobjPOLL = null;
|
|||
|
public static Thread DBThreadobjTallysman = null;
|
|||
|
|
|||
|
private Thread checkUpdateInQueue = null;
|
|||
|
|
|||
|
|
|||
|
public static InterthreadMessageQueue<TallysmanEventArgs> tallysmanEventsQueue
|
|||
|
= new InterthreadMessageQueue<TallysmanEventArgs>();
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Default Constructor
|
|||
|
/// </summary>
|
|||
|
public DataBaseSN()
|
|||
|
{
|
|||
|
/*string MyConString = "SERVER=" + MotoRepeater_GW.cfg.DB_SERVER + "; " +
|
|||
|
"DATABASE=" + MotoRepeater_GW.cfg.DB_DATABASE + "; " +
|
|||
|
"UID=" + MotoRepeater_GW.cfg.DB_USERNAME + "; " +
|
|||
|
"PASSWORD=" + MotoRepeater_GW.cfg.DB_PASSWORD + "; Pooling=true;max pool size = 100";*/
|
|||
|
|
|||
|
dbConnection = new DBconnThread(MotoRepeater_GW.cfg.DB_SERVER, MotoRepeater_GW.cfg.DB_DATABASE,
|
|||
|
MotoRepeater_GW.cfg.DB_USERNAME, MotoRepeater_GW.cfg.DB_PASSWORD, MotoRepeater_GW.cfg.GWCODE + "");
|
|||
|
dbConnection.StartDB();
|
|||
|
|
|||
|
// start the threads which will bring the list of smss, polls, etc
|
|||
|
StartDBService();
|
|||
|
|
|||
|
checkUpdateInQueue = new Thread(delegate()
|
|||
|
{
|
|||
|
while (MotoRepeater_GW.isRunning)
|
|||
|
{
|
|||
|
CheckForPollRequests();
|
|||
|
Thread.Sleep(50);
|
|||
|
CheckForSMSRequests();
|
|||
|
Thread.Sleep(950);
|
|||
|
}
|
|||
|
});
|
|||
|
checkUpdateInQueue.Start();
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
// add event listener for when a Poll request is received
|
|||
|
mBus.OnPollRequest += delegate(Int64 radioID)
|
|||
|
{
|
|||
|
PollRequestEventArgs e = new PollRequestEventArgs();
|
|||
|
e.RadioID = radioID;
|
|||
|
|
|||
|
// raise the event
|
|||
|
OnPollRequestReceived(null, e);
|
|||
|
};
|
|||
|
|
|||
|
// add event listener for when a radio needs to be enabled/disabled
|
|||
|
mBus.OnRadioEnableDisableRequest += delegate(Int64 radioID, bool enable, Wireline.SlotNumber slot)
|
|||
|
{
|
|||
|
RadioEnableDisableRequestEventArgs e = new RadioEnableDisableRequestEventArgs();
|
|||
|
e.Enabled = enable;
|
|||
|
e.RadioID = radioID;
|
|||
|
e.Slot = slot;
|
|||
|
|
|||
|
// raise the event
|
|||
|
this.OnRadioEnableDisableRequest(null, e);
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
mBus.OnEmergencyAckRequest += delegate(Int64 radioID, Wireline.SlotNumber slot)
|
|||
|
{
|
|||
|
EmergencyAckEventArgs e = new EmergencyAckEventArgs();
|
|||
|
e.RadioID = radioID;
|
|||
|
e.Slot = slot;
|
|||
|
|
|||
|
// raise the event
|
|||
|
this.OnEmergencyAckRequest(null, e);
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
mBus.OnChannelQueryRequest += delegate(Int64 radioGWID)
|
|||
|
{
|
|||
|
ChannelQueryEventArgs e = new ChannelQueryEventArgs();
|
|||
|
e.RadioGwID = radioGWID;
|
|||
|
|
|||
|
// raise the event
|
|||
|
OnChannelQuery(null, e);
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
#region PRIVATECALL
|
|||
|
// intercept events for Private Call
|
|||
|
mBus.OnInitPrivateCallRequest += delegate(Int64 radioID, string broadcastAddress, Wireline.SlotNumber slot)
|
|||
|
{
|
|||
|
this.OnInitPrivateCallRequest(radioID, broadcastAddress, slot);
|
|||
|
};
|
|||
|
|
|||
|
mBus.OnEndPrivateCallRequest += delegate(Int64 radioID, string broadcastAddress, Wireline.SlotNumber slot)
|
|||
|
{
|
|||
|
this.OnEndPrivateCallRequest(radioID, broadcastAddress, slot);
|
|||
|
};
|
|||
|
#endregion
|
|||
|
|
|||
|
#region GROUPCALL
|
|||
|
// intercept events for Group Call
|
|||
|
mBus.OnInitGroupCallRequest += delegate(Int64 groupID, string broadcastAddress, Wireline.SlotNumber slot)
|
|||
|
{
|
|||
|
this.OnInitGroupCallRequest(groupID, broadcastAddress, slot);
|
|||
|
};
|
|||
|
|
|||
|
mBus.OnEndGroupCallRequest += delegate(Int64 groupID, string broadcastAddress, Wireline.SlotNumber slot)
|
|||
|
{
|
|||
|
this.OnEndGroupCallRequest(groupID, broadcastAddress, slot);
|
|||
|
};
|
|||
|
#endregion
|
|||
|
|
|||
|
#region ALLCALL
|
|||
|
// intercept events for All Call
|
|||
|
mBus.OnInitAllCallRequest += delegate(string broadcastAddress, Wireline.SlotNumber slot)
|
|||
|
{
|
|||
|
this.OnInitAllCallRequest(broadcastAddress, slot);
|
|||
|
};
|
|||
|
|
|||
|
mBus.OnEndAllCallRequest += delegate(string broadcastAddress, Wireline.SlotNumber slot)
|
|||
|
{
|
|||
|
this.OnEndAllCallRequest(broadcastAddress, slot);
|
|||
|
};
|
|||
|
#endregion
|
|||
|
|
|||
|
*/
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void PollResponseReceived(long radioID, DateTime locationTime, int speed, double latitude, double longitude, Int64 seqID)
|
|||
|
{
|
|||
|
htCell_t cell = new htCell_t();
|
|||
|
cell.suid = radioID + "";
|
|||
|
cell.d_lat = latitude;
|
|||
|
cell.d_lng = longitude;
|
|||
|
cell.seqID = seqID;
|
|||
|
cell.lat = latitude + "";
|
|||
|
cell.lng = longitude + "";
|
|||
|
cell.spd = speed+"";
|
|||
|
cell.location_time = locationTime;
|
|||
|
|
|||
|
lock (SN_Queues.ht_POLL_List.SyncRoot)
|
|||
|
{
|
|||
|
foreach (DictionaryEntry item in SN_Queues.ht_POLL_List)
|
|||
|
{
|
|||
|
Utils.WriteLine("REQ " + ((POLLmsg)item.Value).requestID + " | seqID " + seqID , ConsoleColor.Red);
|
|||
|
|
|||
|
// check to see if this poll will ACK a poll request
|
|||
|
if (((POLLmsg)item.Value).requestID == seqID)
|
|||
|
{
|
|||
|
((POLLmsg)item.Value).response = cell.location_time;
|
|||
|
((POLLmsg)item.Value).lat = cell.lat;
|
|||
|
((POLLmsg)item.Value).lng = cell.lng;
|
|||
|
((POLLmsg)item.Value).speed = cell.spd;
|
|||
|
|
|||
|
// add position to the queue
|
|||
|
SN_Queues.DBQueueLocation.PostItem(cell);
|
|||
|
|
|||
|
// add poll to the queue
|
|||
|
SN_Queues.recvPOLLQueue.PostItem((POLLmsg)item.Value);
|
|||
|
|
|||
|
SN_Queues.ht_POLL_List.Remove(item);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// remove poll from pending list
|
|||
|
lock (SafeMobileLib.SN_Queues.ht_pendingMsg.SyncRoot)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
Hashtable tmp = new Hashtable();
|
|||
|
foreach (DictionaryEntry de in SafeMobileLib.SN_Queues.ht_pendingMsg)
|
|||
|
{
|
|||
|
MotoTRBOcmdMsg m = (MotoTRBOcmdMsg)de.Value;
|
|||
|
|
|||
|
// add message in the pending hash is the response is stil not received
|
|||
|
if (m.m_seqID != seqID)
|
|||
|
tmp.Add(m.m_seqID, m);
|
|||
|
}
|
|||
|
SafeMobileLib.SN_Queues.ht_pendingMsg = tmp;
|
|||
|
lastHashVerify = DateTime.Now;
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
//LOGS.LOG("Error: cannot reset pending messages HashTable" + e.ToString(), ConsoleColor.Red);
|
|||
|
}
|
|||
|
}//release lock
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void LocationResponseReceived(long radioID, DateTime locationTime, int speed, double latitude, double longitude)
|
|||
|
{
|
|||
|
htCell_t cell = new htCell_t();
|
|||
|
cell.suid = radioID + "";
|
|||
|
cell.d_lat = latitude;
|
|||
|
cell.d_lng = longitude;
|
|||
|
cell.lat = latitude + "";
|
|||
|
cell.lng = longitude + "";
|
|||
|
cell.spd = speed + "";
|
|||
|
cell.location_time = locationTime;
|
|||
|
|
|||
|
// add location to the queue
|
|||
|
SN_Queues.DBQueueLocation.PostItem(cell);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void LocationReceived(LocationEventArgs e)
|
|||
|
{
|
|||
|
htCell_t cell = new htCell_t();
|
|||
|
cell.suid = e.RadioID+"";
|
|||
|
cell.d_lat = e.Latitude;
|
|||
|
cell.d_lng = e.Longitude;
|
|||
|
cell.lat = e.Latitude + "";
|
|||
|
cell.lng = e.Longitude + "";
|
|||
|
cell.spd = e.Speed + "";
|
|||
|
cell.location_time = (new DateTime(1970, 1, 1)).AddSeconds(e.GPSTime); //Utils.UnixTimeStampToDateTime(e.Time);
|
|||
|
|
|||
|
// add level of confidence only if received
|
|||
|
if (e.LevelOfConfidence > -1)
|
|||
|
cell.level_confidence = (int)e.LevelOfConfidence;
|
|||
|
|
|||
|
// add location to the queue
|
|||
|
SN_Queues.DBQueueLocation.PostItem(cell);
|
|||
|
}
|
|||
|
|
|||
|
public void ARSStateReceived(long radioID, bool isON)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
ArsMSG ars = new ArsMSG();
|
|||
|
ars.imei = radioID+"";
|
|||
|
ars.msg = isON ? "ON" : "OFF";
|
|||
|
SN_Queues.arsMsgQueue.PostItem(ars);
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Utils.WriteLine("ERROR ARS " + e.ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// radioID is equal with the suID
|
|||
|
public void SMSReceived(long radioID, byte[] received)
|
|||
|
{
|
|||
|
// NOT IN SAFENET
|
|||
|
}
|
|||
|
|
|||
|
public void SMSReceived(long radioID, string message)
|
|||
|
{
|
|||
|
bool result = dbConnection.DB.insertSMSinDB("" + radioID, message);
|
|||
|
|
|||
|
if(!result)
|
|||
|
{
|
|||
|
Utils.WriteLine("COULD NOT INSERT SMS", ConsoleColor.Red);
|
|||
|
}
|
|||
|
else
|
|||
|
Utils.WriteLine("SMS INSERTED", ConsoleColor.Gray);
|
|||
|
}
|
|||
|
|
|||
|
public void SMSAckReceived(byte[] received, string seq_no)
|
|||
|
{
|
|||
|
|
|||
|
Utils.WriteLine("»»» SMS ACK with sequence nr. " + seq_no);
|
|||
|
lock (SN_Queues.waitConfSMSList.SyncRoot)
|
|||
|
{
|
|||
|
int index = -1;
|
|||
|
int count = 0;
|
|||
|
foreach (SMSmsg msg in SN_Queues.waitConfSMSList)
|
|||
|
{
|
|||
|
Int16 seqNo = 0;
|
|||
|
Int16.TryParse(seq_no, out seqNo);
|
|||
|
if (msg.seq_no == seqNo)
|
|||
|
{
|
|||
|
index = count;
|
|||
|
SN_Queues.confSMSQueue.PostItem(msg);
|
|||
|
}
|
|||
|
count++;
|
|||
|
}
|
|||
|
if (index > -1) //we've found the message
|
|||
|
SN_Queues.waitConfSMSList.RemoveAt(index);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void TelemetryReceived(long radioID, byte[] received)
|
|||
|
{
|
|||
|
// NOT IN SAFENET
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void TelemetryReceived(TelemetryReceivedEventArgs telemetryArgs)
|
|||
|
{
|
|||
|
// NOT IN SAFENET
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void RadioEnableDisableStatusReceived(long radioID, Wireline.SlotNumber slot, bool isEnabled)
|
|||
|
{
|
|||
|
//mBus.RadioEnableDisableStatusBroadcast(radioID, isEnabled);
|
|||
|
}
|
|||
|
|
|||
|
public void EmergencyReceived(long radioID, Wireline.SlotNumber slot)
|
|||
|
{
|
|||
|
//mBus.SendEmergencyReceived(radioID);
|
|||
|
}
|
|||
|
|
|||
|
public void CallStatusBroadcastReceived(long sourceID, long targertID, CallType callType, CallStatus callStatus, Wireline.SlotNumber slot)
|
|||
|
{
|
|||
|
//mBus.CallStatusBroadcast(sourceID, targertID, (int)callType, (int)callStatus, slot);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
public void TallysmanEventReceived(TallysmanEventArgs tallysmanArgs)
|
|||
|
{
|
|||
|
|
|||
|
// add received event to a queue
|
|||
|
tallysmanEventsQueue.PostItem(tallysmanArgs);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void SendChannelBroadcastMessage(long radioGWID)
|
|||
|
{
|
|||
|
//mBus.sendChannelBroadcastMessage(radioGWID);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void Stop()
|
|||
|
{
|
|||
|
StopDBService();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Start threads and database connections
|
|||
|
/// </summary>
|
|||
|
void StartDBService()
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
dbConnection.OnGPSInsertedBlocked += delegate ()
|
|||
|
{
|
|||
|
OnGPSInsertedBlocked?.Invoke();
|
|||
|
DBThreadobjGPS?.Abort();
|
|||
|
DBThreadobjGPS = null;
|
|||
|
|
|||
|
DBThreadobjGPS = new Thread(new ThreadStart(dbConnection.HandleConnectionGPS));
|
|||
|
DBThreadobjGPS.IsBackground = true;
|
|||
|
DBThreadobjGPS.Start();
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
//Start GPS DB thread
|
|||
|
DBThreadobjGPS = new Thread(new ThreadStart(dbConnection.HandleConnectionGPS));
|
|||
|
DBThreadobjGPS.IsBackground = true;
|
|||
|
DBThreadobjGPS.Start();
|
|||
|
Thread.Sleep(200);
|
|||
|
|
|||
|
//Start ARS DB thread
|
|||
|
DBThreadobjARS = new Thread(new ThreadStart(dbConnection.HandleConnectionARS));
|
|||
|
DBThreadobjARS.IsBackground = true;
|
|||
|
DBThreadobjARS.Start();
|
|||
|
Thread.Sleep(200);
|
|||
|
|
|||
|
//Start Units DB thread
|
|||
|
DBThreadobjAux = new Thread(new ThreadStart(dbConnection.HandleConnectionAux));
|
|||
|
DBThreadobjAux.IsBackground = true;
|
|||
|
DBThreadobjAux.Start();
|
|||
|
Thread.Sleep(200);
|
|||
|
|
|||
|
//Start SMS DB thread
|
|||
|
DBThreadobjSMS = new Thread(new ThreadStart(dbConnection.HandleConnectionSMS));
|
|||
|
DBThreadobjSMS.IsBackground = true;
|
|||
|
DBThreadobjSMS.Start();
|
|||
|
Thread.Sleep(200);
|
|||
|
|
|||
|
//Start SMS DB thread
|
|||
|
DBThreadobjSMS_conf = new Thread(new ThreadStart(dbConnection.HandleConnectionSMS_conf));
|
|||
|
DBThreadobjSMS_conf.IsBackground = true;
|
|||
|
DBThreadobjSMS_conf.Start();
|
|||
|
Thread.Sleep(200);
|
|||
|
|
|||
|
//Start Addres insert thread
|
|||
|
DBThreadobjAddr = new Thread(new ThreadStart(dbConnection.HandleConnectionAddr));
|
|||
|
DBThreadobjAddr.IsBackground = true;
|
|||
|
//DBThreadobjAddr.Start();
|
|||
|
Thread.Sleep(200);
|
|||
|
|
|||
|
//Start POLL thread
|
|||
|
DBThreadobjPOLL = new Thread(new ThreadStart(dbConnection.HandleConnectionPOLL));
|
|||
|
DBThreadobjPOLL.IsBackground = true;
|
|||
|
DBThreadobjPOLL.Start();
|
|||
|
Thread.Sleep(200);
|
|||
|
|
|||
|
|
|||
|
//Start Tallysman thread
|
|||
|
DBThreadobjTallysman = new Thread(new ThreadStart(dbConnection.HandleTallysmanEvents));
|
|||
|
DBThreadobjTallysman.IsBackground = true;
|
|||
|
DBThreadobjTallysman.Start();
|
|||
|
Thread.Sleep(200);
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Utils.WriteLine("Could not intialize the connection with location server!\r\n" + e.Message + "\r\nPlease check your internet connection !!", ConsoleColor.Red);
|
|||
|
//System.Environment.Exit(1);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Stop all threads and database connections
|
|||
|
/// </summary>
|
|||
|
private void StopDBService()
|
|||
|
{
|
|||
|
if (dbConnection != null)
|
|||
|
{
|
|||
|
dbConnection.StopDB();
|
|||
|
}
|
|||
|
|
|||
|
if (DBThreadobjARS != null)
|
|||
|
{
|
|||
|
DBThreadobjARS.Abort();
|
|||
|
}
|
|||
|
|
|||
|
if (DBThreadobjGPS != null)
|
|||
|
{
|
|||
|
DBThreadobjGPS.Abort();
|
|||
|
}
|
|||
|
|
|||
|
if (DBThreadobjAux != null)
|
|||
|
{
|
|||
|
DBThreadobjAux.Abort();
|
|||
|
}
|
|||
|
|
|||
|
if (DBThreadobjSMS != null)
|
|||
|
{
|
|||
|
DBThreadobjSMS.Abort();
|
|||
|
}
|
|||
|
|
|||
|
if (DBThreadobjSMS_conf != null)
|
|||
|
{
|
|||
|
DBThreadobjSMS_conf.Abort();
|
|||
|
}
|
|||
|
|
|||
|
if (DBThreadobjAddr != null)
|
|||
|
{
|
|||
|
DBThreadobjAddr.Abort();
|
|||
|
}
|
|||
|
|
|||
|
if (DBThreadobjPOLL != null)
|
|||
|
{
|
|||
|
DBThreadobjPOLL.Abort();
|
|||
|
}
|
|||
|
|
|||
|
if (DBThreadobjTallysman != null)
|
|||
|
{
|
|||
|
DBThreadobjTallysman.Abort();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#region POLL REQUESTS MANAGEMENT
|
|||
|
private int reqID_send = 0;
|
|||
|
private DateTime lastHashVerify = DateTime.Now;
|
|||
|
private void CheckForPollRequests()
|
|||
|
{
|
|||
|
|
|||
|
MotoTRBOcmdMsg msg = SN_Queues.locationQueue.GetItem(100);
|
|||
|
if (msg != null)
|
|||
|
{
|
|||
|
//Console.WriteLine("Processing command");
|
|||
|
//Console.WriteLine("SN_Queues.locationQueue.Count:" + SN_Queues.locationQueue.Count);
|
|||
|
ProcessPollCommand(msg); //this will update the m_seqID and m_time
|
|||
|
SafeMobileLib.SN_Queues.ht_pendingMsg.Add(msg.m_seqID, msg);
|
|||
|
msg = null;
|
|||
|
//Console.WriteLine("Processing end");
|
|||
|
}
|
|||
|
|
|||
|
//is now answer within 30 secconds resend
|
|||
|
if (SafeMobileLib.SN_Queues.ht_pendingMsg.Count > 0)
|
|||
|
{
|
|||
|
if ((DateTime.Now.Ticks - lastHashVerify.Ticks) > 5 * 1000 * 10000)
|
|||
|
{
|
|||
|
lock (SafeMobileLib.SN_Queues.ht_pendingMsg.SyncRoot)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
Hashtable tmp = new Hashtable();
|
|||
|
//Utils.WriteLine("GPS answers check at :" + DateTime.Now);
|
|||
|
foreach (DictionaryEntry de in SafeMobileLib.SN_Queues.ht_pendingMsg)
|
|||
|
{
|
|||
|
MotoTRBOcmdMsg m = (MotoTRBOcmdMsg)de.Value;
|
|||
|
|
|||
|
// resend after 30 seconds if no response received
|
|||
|
if (DateTime.Now.Ticks - m.m_created.Ticks > 180 * 1000 * 10000)
|
|||
|
{
|
|||
|
//Utils.WriteLine("I CAN DELETE postItem", ConsoleColor.Cyan);
|
|||
|
// do not add the message again in the queue
|
|||
|
}
|
|||
|
else if (DateTime.Now.Ticks - m.m_created.Ticks > 30 * 1000 * 10000)
|
|||
|
{
|
|||
|
if (DateTime.Now.Ticks - m.m_time.Ticks > 30 * 1000 * 10000)
|
|||
|
{
|
|||
|
//Utils.WriteLine("I HAVE TO RESEND MESSAGE", ConsoleColor.Magenta);
|
|||
|
m.m_cmd = (byte)MotoTRBOcmd.SEND_POLL;
|
|||
|
//LOGS.LOG("PUT back in ht_pendingMsg :" + m.m_suid);
|
|||
|
//Utils.WriteLine("PUT back in ht_pendingMsg :" + m.m_suid);
|
|||
|
SN_Queues.locationQueue.PostItem(m);
|
|||
|
}
|
|||
|
else
|
|||
|
tmp.Add(m.m_seqID, m);
|
|||
|
}
|
|||
|
else
|
|||
|
tmp.Add(m.m_seqID, m);
|
|||
|
|
|||
|
}
|
|||
|
SafeMobileLib.SN_Queues.ht_pendingMsg = tmp;
|
|||
|
lastHashVerify = DateTime.Now;
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
//LOGS.LOG("Error: cannot reset pending messages HashTable" + e.ToString(), ConsoleColor.Red);
|
|||
|
}
|
|||
|
}//release lock
|
|||
|
//LOGS.LOG("Debug: UN-LOCK1");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Process a poll request which needs to be send and then added to
|
|||
|
/// the Poll Hashtable where all the pending requests are stored
|
|||
|
/// </summary>
|
|||
|
/// <param name="p_msg">A custom message containing the poll values</param>
|
|||
|
private void ProcessPollCommand(MotoTRBOcmdMsg p_msg)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
reqID_send++;
|
|||
|
if (reqID_send == byte.MaxValue)
|
|||
|
reqID_send = 1;
|
|||
|
|
|||
|
p_msg.m_seqID = BitConverter.ToInt32(new byte[] { (byte)reqID_send, 0xAC, 0x68, 0x24 }, 0);
|
|||
|
p_msg.m_time = DateTime.Now;
|
|||
|
|
|||
|
if (p_msg.m_cmd == (byte)MotoTRBOcmd.SEND_POLL)
|
|||
|
{
|
|||
|
PollRequestEventArgs e = new PollRequestEventArgs();
|
|||
|
e.RadioID = p_msg.m_suid;
|
|||
|
e.SeqID = reqID_send;
|
|||
|
|
|||
|
OnPollRequestReceived(null, e);
|
|||
|
|
|||
|
//SendPollRequest(p_msg.m_suid, reqID_send);
|
|||
|
//Utils.ConsWrite(DebugMSG_Type.GPS, "Poll request sent for unit:" + p_msg.m_suid);
|
|||
|
|
|||
|
lock (SN_Queues.ht_POLL_List.SyncRoot)
|
|||
|
{
|
|||
|
foreach (DictionaryEntry item in SN_Queues.ht_POLL_List)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
if (((POLLmsg)item.Value).suid == p_msg.m_suid && ((POLLmsg)item.Value).DBid.ToString() == p_msg.m_payload)
|
|||
|
{
|
|||
|
((POLLmsg)item.Value).sent = DateTime.Now.ToUniversalTime();
|
|||
|
((POLLmsg)item.Value).requestID = 0x24*256*256*256 + 0x68*256*256 + 0xAC*256 + reqID_send;
|
|||
|
|
|||
|
//Utils.WriteLine("ADDED POLL WITH REQID : " + ((POLLmsg)item.Value).requestID + " [0x24 0x68 0xAC 0x" + reqID_send + "]", ConsoleColor.Cyan);
|
|||
|
|
|||
|
//Utils.ConsWrite(DebugMSG_Type.DB, "Poll request found in MotoTRBOGW.ht_POLL_List for unit:" + p_msg.m_suid);
|
|||
|
//Utils.ConsWrite(DebugMSG_Type.DB, "reqID_send:" + reqID_send);
|
|||
|
SN_Queues.sentPOLLQueue.PostItem((POLLmsg)item.Value);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
Utils.WriteLine("ERROR in foreach (DictionaryEntry item in SN_Queues.ht_POLL_List):" + ex.ToString(), ConsoleColor.Red);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Utils.WriteLine("Could not send Location Request to unit: " + e.ToString(), ConsoleColor.Red);
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#region SMS REQUESTS MANAGEMENT
|
|||
|
private int reqID_sms = 2;
|
|||
|
|
|||
|
//private DateTime lastHashVerify = DateTime.Now;
|
|||
|
private void CheckForSMSRequests()
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
//MotoTRBOcmdMsg msg = MotoTRBOGW.locationQueue.GetItem(100);
|
|||
|
SMSmsg msg = SN_Queues.sendSMSQueue.GetItem(100);//block until message is in queue
|
|||
|
// exit if not message
|
|||
|
if (msg == null)
|
|||
|
return;
|
|||
|
// set the sequence number
|
|||
|
msg.seq_no = reqID_sms++;
|
|||
|
|
|||
|
SMSRequestEventArgs e = new SMSRequestEventArgs();
|
|||
|
e.RadioID = msg.suid;
|
|||
|
e.seqID = msg.seq_no;
|
|||
|
e.isACKWanted = msg.req_conf;
|
|||
|
e.message = msg.msg;
|
|||
|
|
|||
|
// trigger event
|
|||
|
OnSMSRequestReceived(null, e);
|
|||
|
|
|||
|
if (msg.req_conf)
|
|||
|
{
|
|||
|
//Utils.ConsWrite(DebugMSG_Type.SMS, "Requesting SMS Confirmation!!!!");
|
|||
|
lock (SN_Queues.waitConfSMSList.SyncRoot)
|
|||
|
{
|
|||
|
msg.waitConfSMSList_time = DateTime.Now;
|
|||
|
|
|||
|
SN_Queues.waitConfSMSList.Add(msg);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Thread.Sleep(1200);//minimum interval between SMS as per MotoTRBO specs
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
Utils.WriteLine("MUST HANDLE THIS EXCEPTION : " + ex.ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
/// <summary>
|
|||
|
/// Get the reporting interval from the Database for a particular unit
|
|||
|
/// </summary>
|
|||
|
/// <param name="radioID">Radio Id of the unit for which </param>
|
|||
|
/// <returns></returns>
|
|||
|
public int GetReportingIntervalForUnit(string radioID)
|
|||
|
{
|
|||
|
int reportInterval = 60;
|
|||
|
if (SN_Queues.ht_SUInfo.ContainsKey(radioID))
|
|||
|
reportInterval = ((SUinfo)SN_Queues.ht_SUInfo[radioID]).repInterval;
|
|||
|
else
|
|||
|
reportInterval = -1;
|
|||
|
|
|||
|
return reportInterval;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
public bool UnitIsAssignedToGw(string radioID)
|
|||
|
{
|
|||
|
if (SN_Queues.ht_SUInfo.ContainsKey(radioID))
|
|||
|
return true;
|
|||
|
else
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
#region EVENTS
|
|||
|
#region AUDIO EVENTS
|
|||
|
public delegate void InitPrivateCallRequest(Int64 radioID, String broadcastAddress, Wireline.SlotNumber slot);
|
|||
|
public event InitPrivateCallRequest OnInitPrivateCallRequest;
|
|||
|
public delegate void EndPrivateCallRequest(Int64 radioID, String broadcastAddress, Wireline.SlotNumber slot);
|
|||
|
public event EndPrivateCallRequest OnEndPrivateCallRequest;
|
|||
|
|
|||
|
public delegate void InitGroupCallRequest(Int64 groupID, String broadcastAddress, Wireline.SlotNumber slot);
|
|||
|
public event InitGroupCallRequest OnInitGroupCallRequest;
|
|||
|
public delegate void EndGroupCallRequest(Int64 groupID, String broadcastAddress, Wireline.SlotNumber slot);
|
|||
|
public event EndGroupCallRequest OnEndGroupCallRequest;
|
|||
|
|
|||
|
public delegate void InitAllCallRequest(String broadcastAddress, Wireline.SlotNumber slot);
|
|||
|
public event InitAllCallRequest OnInitAllCallRequest;
|
|||
|
public delegate void EndAllCallRequest(String broadcastAddress, Wireline.SlotNumber slot);
|
|||
|
public event EndAllCallRequest OnEndAllCallRequest;
|
|||
|
#endregion
|
|||
|
|
|||
|
#region POLL EVENT
|
|||
|
/// <summary>
|
|||
|
/// Events for Poll Request Received
|
|||
|
/// </summary>
|
|||
|
private object _lockPoll = new object();
|
|||
|
public event EventHandler<PollRequestEventArgs> OnPollRequestReceived;
|
|||
|
event EventHandler<PollRequestEventArgs> DataBaseInterface.OnPollRequestReceived
|
|||
|
{
|
|||
|
add { lock (_lockPoll) { OnPollRequestReceived += value; } }
|
|||
|
remove { lock (_lockPoll) { OnPollRequestReceived -= value; } }
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region RADIO ENABLE DISABLE EVENT
|
|||
|
private object _lockRadioED = new object();
|
|||
|
public event EventHandler<RadioEnableDisableRequestEventArgs> OnRadioEnableDisableRequest;
|
|||
|
event EventHandler<RadioEnableDisableRequestEventArgs> DataBaseInterface.OnRadioEnableDisableRequest
|
|||
|
{
|
|||
|
add { lock (_lockRadioED) { OnRadioEnableDisableRequest += value; } }
|
|||
|
remove { lock (_lockRadioED) { OnRadioEnableDisableRequest -= value; } }
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region EMERGENCY ACK EVENT
|
|||
|
private object _lockEmergencyAck = new object();
|
|||
|
public event EventHandler<EmergencyAckEventArgs> OnEmergencyAckRequest;
|
|||
|
event EventHandler<EmergencyAckEventArgs> DataBaseInterface.OnEmergencyAckRequest
|
|||
|
{
|
|||
|
add { lock (_lockEmergencyAck) { OnEmergencyAckRequest += value; } }
|
|||
|
remove { lock (_lockEmergencyAck) { OnEmergencyAckRequest -= value; } }
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region CHANNEL QUERY EVENT
|
|||
|
private object _lockChannelQuery = new object();
|
|||
|
public event EventHandler<ChannelQueryEventArgs> OnChannelQuery;
|
|||
|
event EventHandler<ChannelQueryEventArgs> DataBaseInterface.OnChannelQuery
|
|||
|
{
|
|||
|
add { lock (_lockChannelQuery) { OnChannelQuery += value; } }
|
|||
|
remove { lock (_lockChannelQuery) { OnChannelQuery -= value; } }
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region SMS REQUEST EVENT
|
|||
|
private object _lockSMSRequest = new object();
|
|||
|
public event EventHandler<SMSRequestEventArgs> OnSMSRequestReceived;
|
|||
|
event EventHandler<SMSRequestEventArgs> DataBaseInterface.OnSMSRequestReceived
|
|||
|
{
|
|||
|
add { lock (_lockSMSRequest) { OnSMSRequestReceived += value; } }
|
|||
|
remove { lock (_lockSMSRequest) { OnSMSRequestReceived -= value; } }
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region GROUP SMS REQUEST EVENT
|
|||
|
private object _lockGroupSMSRequest = new object();
|
|||
|
public event EventHandler<SMSRequestEventArgs> OnGroupSMSRequestReceived;
|
|||
|
event EventHandler<SMSRequestEventArgs> DataBaseInterface.OnGroupSMSRequestReceived
|
|||
|
{
|
|||
|
add { lock (_lockGroupSMSRequest) { OnGroupSMSRequestReceived += value; } }
|
|||
|
remove { lock (_lockGroupSMSRequest) { OnGroupSMSRequestReceived -= value; } }
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region TELEMETRY REQUEST EVENT
|
|||
|
private object _lockTelemetryRequest = new object();
|
|||
|
public event EventHandler<TelemetryRequestEventArgs> OnTelemetryRequestReceived;
|
|||
|
event EventHandler<TelemetryRequestEventArgs> DataBaseInterface.OnTelemetryRequestReceived
|
|||
|
{
|
|||
|
add { lock (_lockTelemetryRequest) { OnTelemetryRequestReceived += value; } }
|
|||
|
remove { lock (_lockTelemetryRequest) { OnTelemetryRequestReceived -= value; } }
|
|||
|
}
|
|||
|
#endregion
|
|||
|
#endregion
|
|||
|
|
|||
|
public delegate void GPSInsertedBlockedDel();
|
|||
|
public event GPSInsertedBlockedDel OnGPSInsertedBlocked;
|
|||
|
}
|
|||
|
}
|