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 toBeConfirmed = new Dictionary(); private List availableIDs = new List(); 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 tempToBeConfirmed = new Dictionary(); 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 toRemove = new KeyValuePair(); foreach (KeyValuePair 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; } }