SafeDispatch/MotoTrbo_GW/SMSConfirm.cs
2024-02-22 18:43:59 +02:00

253 lines
7.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Timers;
namespace MotoTrbo_GW
{
public class SMSConfirm
{
private Boolean debug = false;
private Boolean listFilled = false;
private Boolean timerInitialized = false;
private Dictionary<int, SeqAndTime> toBeConfirmed = new Dictionary<int, SeqAndTime>();
private List<int> availableIDs = new List<int>();
private int recycleInterval = 60 * 56; //seconds
private int noACKindex = 1;
private static Int64 motoSeq = 1;
public Int32 radioId = 0;
public SMSConfirm(Int32 radioID)
{
this.radioId = radioID;
fillList();
}
private class SeqAndTime
{
public String seq_id;
public double timeStamp;
public int last_sched_timeGMT = 0;
public int numberOfRetries = 0;
public DateTime added = DateTime.Now;
public SeqAndTime(String seq, double tStamp)
{
seq_id = seq;
timeStamp = tStamp;
numberOfRetries = 0;
last_sched_timeGMT = 0;
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
public void fillList()
{
if (!listFilled)
{
for (int i = 1; i < 128; i++)
{
availableIDs.Add(i);
}
listFilled = true;
}
listFilled = true;
}
[MethodImpl(MethodImplOptions.Synchronized)]
public void recycleOldConfirmations()
{
if (debug)
{
SafeMobileLib.Utils.WriteLine("Recycling confirmations at " + DateTime.Now.ToString());
}
Dictionary<int, SeqAndTime> tempToBeConfirmed = new Dictionary<int, SeqAndTime>();
double currentTime = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
foreach (int index in toBeConfirmed.Keys)
{
if (toBeConfirmed[index].timeStamp < currentTime - recycleInterval)
{
availableIDs.Add(index);
if (debug)
{
SafeMobileLib.Utils.WriteLine("Removed " + toBeConfirmed[index].seq_id + " from the confirmation requests list");
}
}
else
{
tempToBeConfirmed.Add(index, toBeConfirmed[index]);
}
}
toBeConfirmed = tempToBeConfirmed;
if (debug)
{
SafeMobileLib.Utils.WriteLine("There are " + toBeConfirmed.Keys.Count + " messages waiting for confirmation,");
SafeMobileLib.Utils.WriteLine("and " + availableIDs.Count + " available confirmations left");
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
public int addToConfirmationQueue(String seq_idFromSD)
{
//SafeMobileLib.Utils.WriteLine("AVAILABLE " + availableIDs.Count, ConsoleColor.Yellow);
// remove the oldest message
if (availableIDs.Count == 0)
{
int key = 0;
DateTime oldest = DateTime.Now;
KeyValuePair<int, SeqAndTime> toRemove = new KeyValuePair<int, SeqAndTime>();
foreach (KeyValuePair<int, SeqAndTime> toC in toBeConfirmed)
{
if (toC.Value.added < oldest)
{
oldest = toC.Value.added;
key = toC.Key;
toRemove = toC;
}
}
// trigger event to announce that a message will be removed from the queue
if (OnRemoveFromQueue != null && toRemove.Value != null)
OnRemoveFromQueue(radioId, toRemove.Value.seq_id);
// remove from the queue
if (toRemove.Value != null)
toBeConfirmed.Remove(toRemove.Key);
availableIDs.Add(key);
}
if (availableIDs.Count > 0)
{
double timeStamp = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
SeqAndTime sT = new SeqAndTime(seq_idFromSD, timeStamp);
int index = (int)availableIDs[0];
availableIDs.RemoveAt(0);
if (debug)
{
SafeMobileLib.Utils.WriteLine("Removed from availableIDs, remaining " + availableIDs.Count);
}
toBeConfirmed.Add(index, sT);
return index;
}
else
{
return -1;
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
public String getFromConfirmationQueue(int index)
{
String toReturn = "";
if (toBeConfirmed.ContainsKey(index))
{
toReturn = toBeConfirmed[index].seq_id;
toBeConfirmed.Remove(index);
availableIDs.Add(index);
if (debug)
{
SafeMobileLib.Utils.WriteLine("Confirmed message with key " + index + ", removed from hashtable and added to availableIs");
SafeMobileLib.Utils.WriteLine("There are " + availableIDs.Count + " available confirmations left");
}
return toReturn;
}
else
{
return "0.0";
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
public int getFromConfirmationQueueBySeq(string seqNo)
{
foreach (var item in toBeConfirmed)
{
if (item.Value.seq_id.Equals(seqNo))
return item.Key;
}
return 0;
}
[MethodImpl(MethodImplOptions.Synchronized)]
public bool ExistsSequenceInQueue(string seq_no)
{
foreach (var item in toBeConfirmed.Values)
{
if (item.seq_id.Equals(seq_no))
return true;
}
return false;
}
[MethodImpl(MethodImplOptions.Synchronized)]
public int GetNumberOfRetries(string seq_no)
{
foreach (var item in toBeConfirmed.Values)
{
if (item.seq_id.Equals(seq_no))
return item.numberOfRetries;
}
return 0;
}
[MethodImpl(MethodImplOptions.Synchronized)]
public void UpdateNumberOfRetries(string seq_no)
{
foreach (var item in toBeConfirmed.Values)
{
if (item.seq_id.Equals(seq_no))
{
item.numberOfRetries++;
}
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
public int GetLastSchedTime(string seq_no)
{
foreach (var item in toBeConfirmed.Values)
{
if (item.seq_id.Equals(seq_no))
return item.last_sched_timeGMT;
}
return 0;
}
[MethodImpl(MethodImplOptions.Synchronized)]
public void UpdateLastSchedTime(string seq_no, int lastSchedTime)
{
foreach (var item in toBeConfirmed.Values)
{
if (item.seq_id.Equals(seq_no))
{
item.last_sched_timeGMT = lastSchedTime;
}
}
}
public delegate void RemoteFromQueue(Int32 radioID, String seqNo);
public static event RemoteFromQueue OnRemoveFromQueue;
}
}