inital
This commit is contained in:
414
F4SD-PhoneMonitor/Program.cs
Normal file
414
F4SD-PhoneMonitor/Program.cs
Normal file
@@ -0,0 +1,414 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.IO.Pipes;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Microsoft.Win32;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using C4IT.Logging;
|
||||
using C4IT.F4SD.TAPI;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
using FasdDesktopUi.Basics;
|
||||
|
||||
namespace F4SD_PhoneMonitor
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
public static string sendPipeName = null;
|
||||
public static string listenPipeName = null;
|
||||
public static string tapiLine = null;
|
||||
public static bool SignalOutgoingCall = false;
|
||||
public static string ExternalCallPrefix = "";
|
||||
public static bool IsSimulation = false;
|
||||
|
||||
public static int SendError = 0;
|
||||
|
||||
public static cCLMgrEvents lmg = null;
|
||||
|
||||
public static System.Timers.Timer timerPolling = new System.Timers.Timer(100);
|
||||
|
||||
public static cF4sdPipeServer pipeServer = null;
|
||||
|
||||
public static bool StopImmediate = false;
|
||||
|
||||
[STAThread]
|
||||
static int Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
cLogManagerFile.CreateInstance(false, SubFolder: "Logs");
|
||||
cLogManager.DefaultLogger.LogAssemblyInfo();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
if (args.Length < 3 || args.Length > 6)
|
||||
{
|
||||
LogEntry("No valid pipe names at command line. Terminating...", LogLevels.Fatal);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sendPipeName = args[0];
|
||||
listenPipeName = args[1];
|
||||
tapiLine = args[2];
|
||||
|
||||
if (args.Length >= 4)
|
||||
ExternalCallPrefix = args[3];
|
||||
|
||||
if (args.Length >= 5)
|
||||
{
|
||||
if (args[4] == "1")
|
||||
SignalOutgoingCall = true;
|
||||
}
|
||||
|
||||
if (args.Length >= 6)
|
||||
{
|
||||
if (args[5] == "simulation")
|
||||
IsSimulation = true;
|
||||
}
|
||||
|
||||
if (tapiLine.ToLowerInvariant() == "swyxitnative")
|
||||
{
|
||||
if (!ConnectSwyxit())
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ConnectTapi(tapiLine))
|
||||
{
|
||||
System.Environment.Exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
timerPolling.Elapsed += TimerPolling_Elapsed;
|
||||
timerPolling.Start();
|
||||
|
||||
var SessionId = 0;
|
||||
try
|
||||
{
|
||||
SessionId = Process.GetCurrentProcess().SessionId;
|
||||
}
|
||||
catch { }
|
||||
|
||||
pipeServer = new cF4sdPipeServer();
|
||||
pipeServer.PipeMessage += PipeServer_PipeMessage;
|
||||
pipeServer.Listen(listenPipeName, MaxSize: 255, LowerIntegrity: true);
|
||||
LogEntry($"Start listening on named pipe '{listenPipeName}'...", LogLevels.Debug);
|
||||
|
||||
|
||||
SystemEvents.SessionEnding += SystemEvents_SessionEnding;
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.ApplicationExit += OnApplicationExit;
|
||||
Application.Run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool ConnectSwyxit()
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
var regObj = Registry.GetValue("HKEY_CLASSES_ROOT\\CLSID\\{F8E552F8-4C00-11D3-80BC-00105A653379}\\VersionIndependentProgID", null, null);
|
||||
if (!(regObj is string strObj) || strObj.ToLowerInvariant() != "clmgr.clientlinemgr")
|
||||
{
|
||||
LogEntry("SwyxIt client seems not to be installed. Terminating...", LogLevels.Fatal);
|
||||
return false;
|
||||
}
|
||||
|
||||
lmg = new cCLMgrEvents();
|
||||
if (!lmg.Initialize())
|
||||
return false;
|
||||
|
||||
lmg.ActiveCallHandler += ActiveCallMessage;
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
static bool ConnectTapi(string Line)
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
C4TapiHelper.Instance = new C4TapiHelper();
|
||||
C4TapiHelper.Instance.Initialize(TapiMessageHandler);
|
||||
C4TapiHelper.Instance.GetLines();
|
||||
if (C4TapiHelper.Instance.ConnectLine(Line))
|
||||
return true;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
|
||||
{
|
||||
LogEntry("User logout detected. Terminating...", LogLevels.Debug);
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
private static void TimerPolling_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
timerPolling.Stop();
|
||||
if (StopImmediate)
|
||||
{
|
||||
Application.Exit();
|
||||
return;
|
||||
}
|
||||
|
||||
timerPolling.Interval = 10000;
|
||||
bool res = false;
|
||||
lock (sendPipeName)
|
||||
{
|
||||
res = Send("Hello", sendPipeName);
|
||||
};
|
||||
|
||||
if (res)
|
||||
SendError = 0;
|
||||
else
|
||||
{
|
||||
SendError++;
|
||||
if (SendError == 2)
|
||||
Application.Exit();
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
timerPolling.Start();
|
||||
}
|
||||
|
||||
static private void OnApplicationExit(object sender, EventArgs e)
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
timerPolling.Stop();
|
||||
|
||||
try
|
||||
{
|
||||
if (lmg != null)
|
||||
{
|
||||
lmg.ActiveCallHandler -= ActiveCallMessage;
|
||||
lmg.Disconnect();
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
if (C4TapiHelper.Instance != null)
|
||||
{
|
||||
C4TapiHelper.Instance.Dispose();
|
||||
C4TapiHelper.Instance = null;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (pipeServer != null)
|
||||
{
|
||||
LogEntry("stopping pipe server...", LogLevels.Debug);
|
||||
pipeServer.Stop();
|
||||
pipeServer.Dispose();
|
||||
pipeServer = null;
|
||||
LogEntry("...finished.", LogLevels.Debug);
|
||||
}
|
||||
|
||||
//Application.ApplicationExit -= OnApplicationExit;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void ActiveCallMessage(string phone, string name, bool isOutgoing)
|
||||
{
|
||||
if (isOutgoing && !SignalOutgoingCall)
|
||||
{
|
||||
LogEntry("An outgoing call is signaled but signaling outgoing calls is not enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sendPipeName == null)
|
||||
return;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(phone))
|
||||
return;
|
||||
|
||||
|
||||
if (name == null)
|
||||
name = "";
|
||||
|
||||
var phone2 = phone.Trim();
|
||||
if (!string.IsNullOrEmpty(ExternalCallPrefix) && phone2.StartsWith(ExternalCallPrefix))
|
||||
phone2 = phone2.Remove(0,ExternalCallPrefix.Length);
|
||||
|
||||
if (phone2.StartsWith("+"))
|
||||
{
|
||||
var _r = Math.Min(phone2.Length, 3);
|
||||
phone2 = phone2.Remove(0, _r);
|
||||
}
|
||||
else if (phone2.StartsWith("00"))
|
||||
{
|
||||
var _r = Math.Min(phone2.Length, 4);
|
||||
phone2 = phone2.Remove(0, _r);
|
||||
}
|
||||
if (phone2.StartsWith("0"))
|
||||
phone2 = phone2.Remove(0, 1);
|
||||
|
||||
var phone3 = "";
|
||||
foreach (var C in phone2)
|
||||
if ((C >= '0') && (C <= '9'))
|
||||
phone3 += C;
|
||||
|
||||
var name2 = name.Trim();
|
||||
var _strDir = isOutgoing ? "outgoing" : "incoming";
|
||||
LogEntry($"Signaling {_strDir} call: phone={phone2}, name={name2}", LogLevels.Debug);
|
||||
|
||||
var Info = JsonConvert.SerializeObject(new cPhoneSearchParameters() { phone = phone3, name = name2 });
|
||||
lock (sendPipeName)
|
||||
{
|
||||
Send($"phonesearch: {Info}", sendPipeName);
|
||||
}
|
||||
}
|
||||
|
||||
static public bool Send(string SendStr, string PipeName, int TimeOut = 1000)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
LogEntry($"simulatied pipe send: {SendStr}");
|
||||
return true;
|
||||
}
|
||||
NamedPipeClientStream pipeStream = new NamedPipeClientStream
|
||||
(".", PipeName, PipeDirection.Out, PipeOptions.WriteThrough);
|
||||
|
||||
// The connect function will indefinitely wait for the pipe to become available
|
||||
// If that is not acceptable specify a maximum waiting time (in ms)
|
||||
pipeStream.Connect(TimeOut);
|
||||
|
||||
byte[] _buffer = Encoding.UTF8.GetBytes(SendStr);
|
||||
pipeStream.Write(_buffer, 0, _buffer.Length);
|
||||
pipeStream.Flush();
|
||||
pipeStream.Close();
|
||||
pipeStream.Dispose();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (TimeoutException oEX)
|
||||
{
|
||||
if (DefaultLogger.IsDebug)
|
||||
cLogManager.DefaultLogger.LogException(oEX);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static private void PipeServer_PipeMessage(string Reply)
|
||||
{
|
||||
if (Reply.ToLowerInvariant() == "stop")
|
||||
{
|
||||
timerPolling.Stop();
|
||||
StopImmediate = true;
|
||||
timerPolling.Interval = 100;
|
||||
timerPolling.Start();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void TapiMessageHandler(C4TapiHelper.C4TapiLineInfo lineInfo)
|
||||
{
|
||||
if (lineInfo.eventType == C4TapiHelper.eTapiEventType.connected)
|
||||
{
|
||||
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
ActiveCallMessage(lineInfo.participantPhoneNumber, lineInfo.participantName, lineInfo.IsOutbound);
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class cPhoneSearchParameters
|
||||
{
|
||||
public string phone { get; set; }
|
||||
public string name { get; set; } = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user