SafeDispatch/Safedispatch_4_0/Sip/ExceraForSafeDispatch.cs
2024-02-22 18:43:59 +02:00

300 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SipComponent;
using System.Threading;
namespace Dispatcher.Sip
{
class ExceraForSafeDispatch : ISipComponent, IDisposable
{
#region Fields
private SipClientClassExcera _sipClass = null;
private HashSet<string> _sendPttRequestTo = new HashSet<string>();
#endregion
#region Constructor
public ExceraForSafeDispatch(string repeaterIP, int repeaterSipPort, int localSipPort,
string userName, IEnumerable<int> groupSipIdsToRegister, int registrationInterval, int bufferMiliseconds, int requestTimeout, string localIPAddress = null)
{
_sipClass = new SipClientClassExcera(repeaterIP, repeaterSipPort, localSipPort, userName, registrationInterval,
bufferMiliseconds, requestTimeout, localIPAddress);
AddSipEventHandlers();
RegisterToGroups(groupSipIdsToRegister);
}
#endregion
#region ISipComponent Methods
public void AcceptInvite(string callingSipID)
{
_sipClass.AcceptInvite(callingSipID);
}
public void Decline(string idToDeclineCall)
{
_sipClass.Decline(idToDeclineCall);
}
public void SendAudio(string idToSendVoice, byte[] audioBuffer, int bufferLength, AudioFormat format)
{
_sipClass.SendAudio(idToSendVoice, audioBuffer, bufferLength, format);
}
public void SendCallRequest(string sipId, bool groupCall)
{
if (_sipClass.InDialogWith(sipId))
{
// Send Ptt request
_sipClass.RequestPTT(sipId);
}
else
{
// Send Invite, then remember to send Ptt request after the dialog is created
// Add to hashSet
_sendPttRequestTo.Add(sipId);
// SendInvite
if (groupCall)
_sipClass.InviteGroup(sipId);
else
_sipClass.Invite(sipId);
}
}
public void StopPTT(string sipId)
{
_sipClass.EndPTT(sipId);
}
public async Task<bool> SendSmsAsync(string idToSendSMS, string text)
{
return await _sipClass.SendSmsAsync(idToSendSMS, text);
}
public void Stop(bool async)
{
RemoveSipEventHandlers();
_sipClass.Stop(async);
}
#endregion
#region ISipComponent Events
public event EventHandler<SipDialogClosedEventArgs> DialogClosed;
public event EventHandler<SipDialogCreatedEventArgs> DialogCreated;
public event EventHandler<ErrorEventArgs> ErrorOnCreatingDialog;
public event EventHandler<InviteReceivedArgs> InviteReceived;
public event EventHandler<RegistrationStateChangedEventArgs> RegistrationStateChanged;
public event EventHandler<SdCanSendVoiceEventArgs> SdCanSendVoice;
public event EventHandler<SdCannotSendVoiceEventArgs> SdCannotSendVoice;
public event EventHandler<SdReceivedCallStatusEventArgs> SdReceivesCallInit;
public event EventHandler<SdReceivedCallStatusEventArgs> SdReceivesStopPTT;
public event EventHandler<SmsReceivedEventsArgs> SmsReceived;
public event EventHandler<SipVoiceReceivedEventArgs> VoiceReceived;
#endregion
#region Excera specific events
public event EventHandler<SipEventArgs> ExceraEmergencyReceived;
#endregion
#region IDisposable Implementation
public void Dispose()
{
Stop(false);
}
#endregion
#region SipClientClassExcera Event Handlers
private void _sipClass_ErrorOnCreatingDialog(object sender, ErrorEventArgs e)
{
bool inviteSentByMe = _sipClass.UserName == e.FromID;
if (inviteSentByMe)
if (_sendPttRequestTo.Contains(e.ToID))
_sendPttRequestTo.Remove(e.ToID);
ErrorOnCreatingDialog?.Invoke(this, e);
}
private void _sipClass_DialogClosed(object sender, DialogClosedEventArgs e)
{
SipDialogClosedEventArgs ev = new SipDialogClosedEventArgs(
int.Parse(e.SipIDinDialogWith),
int.Parse(e.SipIDwhoClosed),
e.WasGroupCall ? e.SipIDinDialogWith : null);
DialogClosed?.Invoke(this, ev);
}
private void _sipClass_VoiceReceived(object sender, AudioEventArgs e)
{
SipVoiceReceivedEventArgs ev = new SipVoiceReceivedEventArgs(
e.CallSourceID,
e.Buffer,
e.SipIdInDialogWith != e.CallSourceID ? e.SipIdInDialogWith.ToString() : null);
VoiceReceived?.Invoke(this, ev);
}
private void _sipClass_DialogCreated(object sender, DialogCreatedEventArgs e)
{
int sipIdWhoSentInvite = int.Parse(e.FromID);
int sipIdWhoReceivedInvite = int.Parse(e.ToID);
bool inviteSentByMe = _sipClass.UserName == e.FromID;
int? groupCallSipId = null;
if (e.IsGroupCall)
{
groupCallSipId = inviteSentByMe ? sipIdWhoReceivedInvite : sipIdWhoSentInvite;
}
SipDialogCreatedEventArgs ev = new SipDialogCreatedEventArgs(
sipIdWhoSentInvite,
sipIdWhoReceivedInvite,
groupCallSipId);
// Fire dialog created event
DialogCreated?.Invoke(this, ev);
// Send Ptt request if necessary
if (inviteSentByMe)
if (_sendPttRequestTo.Contains(e.ToID))
{
_sipClass.RequestPTT(e.ToID);
_sendPttRequestTo.Remove(e.ToID);
}
}
private void _sipClass_SipSmsReceived(object sender, SmsReceivedEventsArgs e)
{
SmsReceived?.Invoke(this, e);
}
private void _sipClass_RegistrationStateChanged(object sender, RegistrationStateChangedEventArgs e)
{
RegistrationStateChanged?.Invoke(this, e);
}
private void _sipClass_InviteReceived(object sender, InviteReceivedArgs e)
{
InviteReceived?.Invoke(this, e);
}
private void _sipClass_PTTStartReceived(object sender, RtpEventArgs e)
{
int? groupSipId = null;
if (e.SipIDsendingRTP != e.SipIDinDialogWith)
groupSipId = int.Parse(e.SipIDinDialogWith);
SdReceivedCallStatusEventArgs ev = new SdReceivedCallStatusEventArgs(
int.Parse(e.SipIDsendingRTP), groupSipId);
SdReceivesCallInit?.Invoke(this, ev);
}
private void _sipClass_PTTrequestGranted(object sender, SipInfoEventArgs e)
{
SdCanSendVoiceEventArgs ev = new SdCanSendVoiceEventArgs(
int.Parse(e.SipIDinDialogWith), e.IsGroup);
SdCanSendVoice?.Invoke(this, ev);
}
private void _sipClass_PTTrequestFailed(object sender, SipEventArgs e)
{
SdCannotSendVoice?.Invoke(this, new SdCannotSendVoiceEventArgs(
int.Parse(e.SipIDinDialogWith), "No response to ptt request"));
}
private void _sipClass_PTTrequestDenied(object sender, SipEventArgs e)
{
SdCannotSendVoice?.Invoke(this, new SdCannotSendVoiceEventArgs(
int.Parse(e.SipIDinDialogWith), "Ptt request was denied"));
}
private void _sipClass_PTTEndReceived(object sender, RtpEventArgs e)
{
int? groupSipId = null;
if (e.SipIDinDialogWith != e.SipIDsendingRTP)
groupSipId = int.Parse(e.SipIDinDialogWith);
SdReceivedCallStatusEventArgs ev = new SdReceivedCallStatusEventArgs(
int.Parse(e.SipIDsendingRTP), groupSipId);
SdReceivesStopPTT?.Invoke(this, ev);
}
private void _sipClass_EmergencyReceived(object sender, SipEventArgs e)
{
ExceraEmergencyReceived?.Invoke(this, e);
}
#endregion
#region Private Helper Methods
private void AddSipEventHandlers()
{
_sipClass.InviteReceived += _sipClass_InviteReceived;
_sipClass.RegistrationStateChanged += _sipClass_RegistrationStateChanged;
_sipClass.SmsReceived += _sipClass_SipSmsReceived;
_sipClass.DialogCreated += _sipClass_DialogCreated;
_sipClass.VoiceReceived += _sipClass_VoiceReceived;
_sipClass.DialogClosed += _sipClass_DialogClosed;
_sipClass.ErrorOnCreatingDialog += _sipClass_ErrorOnCreatingDialog;
_sipClass.PTTStartReceived += _sipClass_PTTStartReceived;
_sipClass.PTTrequestGranted += _sipClass_PTTrequestGranted;
_sipClass.PTTrequestDenied += _sipClass_PTTrequestDenied;
_sipClass.PTTrequestFailed += _sipClass_PTTrequestFailed;
_sipClass.PTTEndReceived += _sipClass_PTTEndReceived;
_sipClass.EmergencyReceived += _sipClass_EmergencyReceived;
}
private void RemoveSipEventHandlers()
{
_sipClass.InviteReceived -= _sipClass_InviteReceived;
_sipClass.RegistrationStateChanged -= _sipClass_RegistrationStateChanged;
_sipClass.SmsReceived -= _sipClass_SipSmsReceived;
_sipClass.DialogCreated -= _sipClass_DialogCreated;
_sipClass.VoiceReceived -= _sipClass_VoiceReceived;
_sipClass.DialogClosed -= _sipClass_DialogClosed;
_sipClass.ErrorOnCreatingDialog -= _sipClass_ErrorOnCreatingDialog;
_sipClass.PTTStartReceived -= _sipClass_PTTStartReceived;
_sipClass.PTTrequestGranted -= _sipClass_PTTrequestGranted;
_sipClass.PTTrequestDenied -= _sipClass_PTTrequestDenied;
_sipClass.PTTrequestFailed -= _sipClass_PTTrequestFailed;
_sipClass.PTTEndReceived -= _sipClass_PTTEndReceived;
_sipClass.EmergencyReceived -= _sipClass_EmergencyReceived;
}
private void RegisterToGroups(IEnumerable<int> groupSipIdsToRegister)
{
Task.Factory.StartNew((stateObj) =>
{
IEnumerable<int> groupIds = (IEnumerable<int>)stateObj;
// Register to groups
foreach (int sipGroupId in groupIds)
{
_sipClass.RegisterToGroup(sipGroupId.ToString());
Thread.Sleep(20);
}
// Register to the all call group (16777215)
_sipClass.RegisterToGroup("16777215");
}, groupSipIdsToRegister);
}
#endregion
}
}