using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using SipComponent; namespace Dispatcher.Sip { class LinxForSafeDispatch : ISipComponent, ISocketIOComponent, IDisposable { #region Fields SipClientClass2 _sipClass = null; #endregion #region Constructor public LinxForSafeDispatch(string serverIp, int serverSipPort, int localSipPort, string userName, string password, int registrationInterval, int bufferMiliseconds, int requestTimeout, int socketIOport) { _sipClass = new SipClientClass2(serverIp, serverSipPort, localSipPort, userName, password, registrationInterval, bufferMiliseconds, requestTimeout, socketIOport, true); _sipClass.SmsConfirmationFromAsterisk = true; AddSipEventHandlers(); } #endregion #region ISipComponent Methods public void AcceptInvite(string callingSipID) { _sipClass.AcceptInvite(callingSipID); } public void StopPTT(string sipId) { if (_sipClass.InDialogWith(sipId)) _sipClass.Close(sipId); else _sipClass.CancelInvite(sipId); } 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 (groupCall) _sipClass.InviteGroup(sipId); else _sipClass.Invite(sipId); } public async Task SendSmsAsync(string idToSendSMS, string text) { return await _sipClass.SendSmsAsync(idToSendSMS, text); } public void Stop(bool async) { RemoveSipEventHandlers(); _sipClass.Stop(async); } #endregion #region ISocketIOComponent Methods public void SendSms(string seqID, int fromScID, int destinationSipID, int destinationScID, string text, bool isGroupSms) { _sipClass.SendSocketIOSms(seqID, fromScID, destinationSipID, destinationScID, text, isGroupSms); } #endregion #region IDisposableImplementation public void Dispose() { Stop(false); } #endregion #region ISipComponent Events public event EventHandler DialogClosed; public event EventHandler DialogCreated; public event EventHandler ErrorOnCreatingDialog; public event EventHandler InviteReceived; public event EventHandler RegistrationStateChanged; public event EventHandler SdCanSendVoice; public event EventHandler SdCannotSendVoice; public event EventHandler SdReceivesCallInit; // This event is not used by Linx. Stop ptt is when the dialog is closed public event EventHandler SdReceivesStopPTT; public event EventHandler SmsReceived; public event EventHandler VoiceReceived; #endregion #region ISocketIOComponent Events public event EventHandler SocketIOSmsReceived; public event EventHandler SocketIOSmsAckReceived; #endregion #region Private Methods private void AddSipEventHandlers() { _sipClass.InviteReceived += _sipClass_InviteReceived; _sipClass.RegistrationStateChanged += _sipClass_RegistrationStateChanged; _sipClass.SipSmsReceived += _sipClass_SipSmsReceived; _sipClass.DialogCreated += _sipClass_DialogCreated; _sipClass.VoiceReceived += _sipClass_VoiceReceived; _sipClass.DialogClosed += _sipClass_DialogClosed; _sipClass.ErrorOnCreatingDialog += _sipClass_ErrorOnCreatingDialog; _sipClass.SocketIOSmsReceived += _sipClass_SocketIOSmsReceived; _sipClass.SocketIOSmsAckReceived += _sipClass_SocketIOSmsAckReceived; } private void RemoveSipEventHandlers() { _sipClass.InviteReceived -= _sipClass_InviteReceived; _sipClass.RegistrationStateChanged -= _sipClass_RegistrationStateChanged; _sipClass.SipSmsReceived -= _sipClass_SipSmsReceived; _sipClass.DialogCreated -= _sipClass_DialogCreated; _sipClass.VoiceReceived -= _sipClass_VoiceReceived; _sipClass.DialogClosed -= _sipClass_DialogClosed; _sipClass.ErrorOnCreatingDialog -= _sipClass_ErrorOnCreatingDialog; _sipClass.SocketIOSmsReceived -= _sipClass_SocketIOSmsReceived; _sipClass.SocketIOSmsAckReceived -= _sipClass_SocketIOSmsAckReceived; } #region SipClientClass2 Event Handlers private void _sipClass_InviteReceived(object sender, InviteReceivedArgs e) { InviteReceived?.Invoke(this, e); } private void _sipClass_RegistrationStateChanged(object sender, RegistrationStateChangedEventArgs e) { RegistrationStateChanged?.Invoke(this, e); } private void _sipClass_SipSmsReceived(object sender, SmsReceivedEventsArgs e) { SmsReceived?.Invoke(this, e); } private void _sipClass_DialogCreated(object sender, LinxDialogCreatedEventArgs e) { int idWhoSentInvite = int.Parse(e.FromID); int idWhoReceivedInvite = int.Parse(e.ToID); int? groupCallId = null; if (e.IsGroupCall) groupCallId = int.Parse(e.GroupID); SipDialogCreatedEventArgs ev = new SipDialogCreatedEventArgs( idWhoSentInvite, idWhoReceivedInvite, groupCallId); DialogCreated?.Invoke(this, ev); if (e.FromID == _sipClass.UserName) { // I sent the invite, the other party accepted // Then SD can send voice SdCanSendVoice?.Invoke(this, new SdCanSendVoiceEventArgs(idWhoReceivedInvite, e.IsGroupCall)); } else { // I received the invite SdReceivedCallStatusEventArgs ev1 = new SdReceivedCallStatusEventArgs(idWhoSentInvite, groupCallId); SdReceivesCallInit?.Invoke(this, ev1); } } private void _sipClass_VoiceReceived(object sender, LinxAudioEventArgs e) { SipVoiceReceivedEventArgs ev = new SipVoiceReceivedEventArgs( e.CallSourceID, e.Buffer, e.GroupID); VoiceReceived?.Invoke(this, ev); } private void _sipClass_DialogClosed(object sender, LinxDialogClosedEventArgs e) { SipDialogClosedEventArgs ev = new SipDialogClosedEventArgs( int.Parse(e.SipIDinDialogWith), int.Parse(e.SipIDwhoClosed), e.GroupID); DialogClosed?.Invoke(this, ev); } private void _sipClass_ErrorOnCreatingDialog(object sender, ErrorEventArgs e) { // Fire error on creating dialog event ErrorOnCreatingDialog?.Invoke(this, e); // if invite was sent by me, i will fire SdCannotSendVoice event also if (_sipClass.UserName == e.FromID) { SdCannotSendVoiceEventArgs ev = new SdCannotSendVoiceEventArgs( int.Parse(e.ToID), e.Reason); SdCannotSendVoice?.Invoke(this, ev); } } private void _sipClass_SocketIOSmsReceived(object sender, SocketIOSmsEventArgs e) { SocketIOSmsReceived?.Invoke(this, e); } private void _sipClass_SocketIOSmsAckReceived(object sender, SocketIoSmsAckEventArgs e) { SocketIOSmsAckReceived?.Invoke(this, e); } #endregion #endregion } }