/// <summary> /// Cancel the pickUp process /// If this cancellation is due to changes in _target, then its state is not changed /// otherwise is set back to Idle. /// </summary> /// <param name="changeTargetState"></param> /// <returns></returns> public bool Cancel(bool changeTargetState = true) { if (State != FunctionState.Idle) { State = FunctionState.Idle; if (_Target != null) { _Target.TlfPosStateChanged -= OnTargetCallStateChanged; if (_TargetUris != null) { foreach (string uri in _TargetUris) { SipAgent.DestroyDialogSubscription(uri); } } if ((changeTargetState) || (_Target.State == TlfState.InProcess)) { _Target.State = TlfState.Idle; } _Target = null; _TargetUris = null; } if (_Captured != null) { _Captured = null; } foreach (int pos in _Ringing.Keys) { Top.Tlf[pos].State = TlfState.Idle; } _Ringing.Clear(); return(true); } return(false); }
private void PrepareCommon() { _TargetUris = _Target.GetUris(); if (_TargetUris != null) { _IgnoreNotify = false; _Target.State = TlfState.InProcess; bool error = false; foreach (string uri in _TargetUris) { error &= SipAgent.CreateDialogSubscription(_Target.Channels[0].AccId, uri, _UseProxy); } if (!error) { State = FunctionState.Executing; _Target.TlfPosStateChanged += OnTargetCallStateChanged; Top.WorkingThread.Enqueue("SetSnmp", delegate() { string snmpString = Top.Cfg.PositionId + "_" + "CAPTURE" + "_" + _Target.Literal; General.SafeLaunchEvent(SetSnmpString, this, new SnmpStringMsg <string, string>(Settings.Default.TlfFacilityOid, snmpString)); }); } else { State = FunctionState.Error; _Logger.Error("TlfPickUp::PrepareCommon CreateDialogSubscription error [0]", _Target.Literal); } } else { State = FunctionState.Error; _Logger.Error("TlfPickUp::PrepareCommon target [0] with no path", _Target.Literal); } }
/// <summary> /// /// </summary> private void MakeHangUpTx() { if (_SipCallTx != null) { if (_SipCallTx.IsActive) { Debug.Assert(_ActiveTx == this); switch (_TxState) { case LcTxState.Out: _CallTout.Enabled = false; break; case LcTxState.Tx: Top.Mixer.Unlink(_SipCallTx.Id); break; } SipAgent.HangupCall(_SipCallTx.Id); } else { Debug.Assert((_TxState == LcTxState.Congestion) || (_TxState == LcTxState.Busy)); } // Top.Recorder.Rec(CORESIP_CallType.CORESIP_CALL_IA, false); _SipCallTx = null; _ActiveTx = null; Top.Lc.HoldedTlf = false; } }
/// <summary> /// Al establecerse la llamada y terminar con exito la captura se envia el mensaje /// al target /// </summary> /// <param name="sender"></param> private void OnCapturedCallStateChanged(object sender) { TlfPosition tlf = (TlfPosition)sender; try { if (tlf.State == TlfState.Set) { _Captured.TlfPosStateChanged -= OnCapturedCallStateChanged; SipAgent.SendInstantMessage(_Target.Channels[0].AccId, _Target.Uri, PickUpTag + Top.Cfg.PositionId + Resources.HasCaptured + _Captured.Literal, _UseProxy); _Ringing.Remove(_Captured.Pos); foreach (int pos in _Ringing.Keys) { Top.Tlf[pos].State = TlfState.Idle; } _Ringing.Clear(); _Target.TlfPosStateChanged -= OnTargetCallStateChanged; _Target.State = TlfState.Idle; // se pasa a reposo al terminar la captura, no al entrar los ringing _Target = null; _TargetUris = null; State = FunctionState.Idle; Top.WorkingThread.Enqueue("SetSnmp", delegate() { string snmpString = Top.Cfg.PositionId + "_" + "CAPTURED" + "_" + _Captured.Literal; General.SafeLaunchEvent(SetSnmpString, this, new SnmpStringMsg <string, string>(Settings.Default.TlfFacilityOid, snmpString)); }); } } catch (Exception exc) { _Logger.Error("OnCapturedCallStateChanged exception {0}", exc.Message); } }
/// <summary> /// Evento recibido con el resultado de la transferencia /// Si se recibe un codigo de error se intenta la transferencia con el otro participante /// </summary> /// <param name="newRtxGroup"></param> /// <returns></returns> private void OnTransferStatus(object sender, int callId, int code) { if ((code > 101) && (code < 300) && (code != SipAgent.SIP_ACCEPTED)) { if (_AssociateCall != null) { _AssociateCall.HangUp(0); } Top.Sip.TlfTransferStatus -= OnTransferStatus; State = FunctionState.Idle; _ToTransfer = null; _FromTransferDisplayName = ""; } else if ((code >= 300) && !_FirstTransferTryKO && (_ToTransfer != null)) { _FirstTransferTryKO = true; //Try transfer with other participant SipAgent.TransferCall(_ToTransfer.CallId, AssociateCall.CallId, null, _FromTransferDisplayName); AssociateCall = _ToTransfer; _ToTransfer = null; _FromTransferDisplayName = ""; } else if ((code >= 300) && _FirstTransferTryKO) { AssociateCall = null; Top.Sip.TlfTransferStatus -= OnTransferStatus; State = FunctionState.Error; _ToTransfer = null; _FromTransferDisplayName = ""; } }
/// <summary> /// /// </summary> public void End() { if (LstDispositivos == null) { return; } #if _AUDIOGENERIC_ /** AGL.CMEDIA */ foreach (ISndDevIO sndDevice in LstDispositivos.Values) #else foreach (SndDev sndDevice in LstDispositivos.Values) #endif { // Bajar señal de grabación #if _AUDIOGENERIC_ sndDevice.SenGrabacion(false); #else sndDevice.SetGpio(HwManager.OUT_GRABACION, HwManager.OUT); #endif } for (int i = 0; i < 6; i++) { if (_SessionsFile[i] >= 0 && _GlpSessionsStarted[i]) { SipAgent.DestroyWavRecorder(_SessionsFile[i]); _SessionsFile[i] = -1; _SessionsFileName[i] = string.Empty; } } }
public void To(int id) { _FirstTransferTryKO = false; _ToTransfer = null; _FromTransferDisplayName = ""; if (_State == FunctionState.Idle) { List <TlfPosition> activeCalls = Top.Tlf.ActiveCalls; FunctionState st = FunctionState.Error; if (activeCalls.Count == 1) { if ((activeCalls[0].State == TlfState.Set) || (activeCalls[0].State == TlfState.Conf)) { TlfPosition tlf = activeCalls[0]; TlfPosition to = Top.Tlf[id]; bool transferDone = false; if (Top.Tlf[id].State == TlfState.Idle) { string toUri = to.Uri; if (TlfManager.GetDisplayName(to.Uri) == null && to.Literal.Length > 0) { //Si to.Uri no tiene display name se añade el Literal como display name en la transferencia directa toUri = "\"" + to.Literal + "\" " + to.Uri; } SipAgent.TransferCall(tlf.CallId, -1, toUri, null); transferDone = true; } else if (Top.Tlf[id].State == TlfState.Hold) { SipAgent.HoldCall(activeCalls[0].CallId); System.Threading.Thread.Sleep(50); SipAgent.TransferCall(tlf.CallId, to.CallId, null, "\"" + to.Literal + "\""); transferDone = true; _ToTransfer = to; _FromTransferDisplayName = "\"" + tlf.Literal + "\""; } if (transferDone) { _Logger.Debug("Iniciando transferencia..."); Top.Sip.TlfTransferStatus += OnTransferStatus; AssociateCall = tlf; st = FunctionState.Executing; Top.WorkingThread.Enqueue("SetSnmp", delegate() { string snmpString = Top.Cfg.PositionId + "_" + "TRANSFER" + "_" + tlf.Literal; General.SafeLaunchEvent(SetSnmpString, this, new SnmpStringMsg <string, string>(Settings.Default.TlfFacilityOid, snmpString)); }); } } } State = st; } }
/// <summary> /// /// </summary> /// <param name="funcion"></param> /// <param name="via"></param> /// <param name="fileName"></param> /// <param name="fileLength"></param> public void DoFunction(FunctionReplay funcion, ViaReplay via, string fileName, long fileLength) { switch (funcion) { case FunctionReplay.Stop: if (_ReplayTone != -1) { Top.Mixer.Unlink(_ReplayTone); SipAgent.DestroyWavPlayer(_ReplayTone); _ReplayTone = -1; _Replaying = false; _StopPlaying.Enabled = false; General.SafeLaunchEvent(PlayingChanged, this, new StateMsg <bool>(false)); if (Settings.Default.SNMPEnabled == 1) { Top.WorkingThread.Enqueue("SetSnmp", delegate() { string evento = Top.Cfg.PositionId + "_0"; General.SafeLaunchEvent(SetSnmpString, this, new SnmpStringMsg <string, string>(Settings.Default.StartingReplayOid, evento)); }); } } break; case FunctionReplay.Play: if (_ReplayTone == -1) { _ReplayTone = SipAgent.CreateWavPlayer(fileName, true); Top.Mixer.LinkReplay(_ReplayTone, via); _Replaying = true; _StopPlaying = new Timer(1000 * fileLength / 16000); _StopPlaying.Elapsed += new ElapsedEventHandler(StopPlayingElapsed); _StopPlaying.AutoReset = false; _StopPlaying.Enabled = true; General.SafeLaunchEvent(PlayingChanged, this, new StateMsg <bool>(true)); if (Settings.Default.SNMPEnabled == 1) { Top.WorkingThread.Enqueue("SetSnmp", delegate() { string evento = Top.Cfg.PositionId + "_1"; General.SafeLaunchEvent(SetSnmpString, this, new SnmpStringMsg <string, string>(Settings.Default.StartingReplayOid, evento)); }); } } break; case FunctionReplay.DisableSupervisor: case FunctionReplay.Pause: /* De momento no se va a implementar */ break; } }
private void OnFinished(object sender) { if ((_State == IntrusionState.On) && (_AssociateCall.CallId >= 0)) { SipAgent.SendInfo(_AssociateCall.CallId, INTRUSION_COMPLETED); } _Conference = null; Dispose(); }
/// <summary> /// /// </summary> /// <param name="rxSt"></param> /// <param name="txSt"></param> private void SetState(LcRxState rxSt, LcTxState txSt) { bool changed = false; _OldRxState = _RxState; _OldTxState = _TxState; if (_RxState != rxSt) { _RxState = rxSt; changed = true; if (_TxState == txSt) { if ((rxSt != LcRxState.Unavailable) && (_TxState == LcTxState.Unavailable)) { txSt = LcTxState.Idle; } else if ((rxSt == LcRxState.Unavailable) && (_TxState == LcTxState.Idle)) { txSt = LcTxState.Unavailable; } } } if (_TxState != txSt) { if (_Tone >= 0) { Top.Mixer.Unlink(_Tone); SipAgent.DestroyWavPlayer(_Tone); _Tone = -1; } switch (txSt) { case LcTxState.Congestion: _Tone = SipAgent.CreateWavPlayer("Resources/Tones/Congestion.wav", true); Top.Mixer.Link(_Tone, MixerDev.SpkLc, MixerDir.Send, Mixer.LC_PRIORITY, FuentesGlp.RxLc); break; case LcTxState.Busy: _Tone = SipAgent.CreateWavPlayer("Resources/Tones/Busy.wav", true); Top.Mixer.Link(_Tone, MixerDev.SpkLc, MixerDir.Send, Mixer.LC_PRIORITY, FuentesGlp.RxLc); break; } _TxState = txSt; changed = true; } if (changed) { General.SafeLaunchEvent(StateChanged, this); } }
/// <summary> /// /// </summary> /// <param name="_enabled"></param> /// <param name="tipo"></param> /// <returns></returns> static public int AddDevice(bool _enabled, CORESIP_SndDevType tipo) { int _device = -1; if (_enabled) { int _channel_in = tipo == CORESIP_SndDevType.CORESIP_SND_INSTRUCTOR_MHP || tipo == CORESIP_SndDevType.CORESIP_SND_ALUMN_MHP ? GetInputChannelFor(tipo) : -1; int _channel_out = GetOutputChannelFor(tipo); _device = SipAgent.AddSndDevice(tipo, _channel_in, _channel_out); _Logger.Info("Agregado Dispositivo de sonido ({0}) = {1:X}: IN:{2},OUT:{3}", tipo, _device, _channel_in, _channel_out); } return(_device); }
/// <summary> /// /// </summary> /// <param name="_enabled"></param> /// <param name="tipo"></param> /// <returns></returns> static public int AddDevice(bool _enabled, CORESIP_SndDevType tipo, CMediaDevMode mode) { int _device = -1; if (_enabled) { int _channel_in = mode != CMediaDevMode.Output ? GetInputChannelFor(tipo) : -1; int _channel_out = mode != CMediaDevMode.Input ? GetOutputChannelFor(tipo) : -1; _device = SipAgent.AddSndDevice(tipo, _channel_in, _channel_out); _Logger.Debug("Agregado Dispositivo de sonido ({0}) = {1:X}: IN:{2},OUT:{3}", tipo, _device, _channel_in, _channel_out); } return(_device); }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnCallTimeout(object sender, ElapsedEventArgs e) { Top.WorkingThread.Enqueue("OnLcCallTimeout", delegate() { if (_TxState == LcTxState.Out) { Debug.Assert((_SipCallTx != null) && _SipCallTx.IsActive); Debug.Assert(_ActiveTx == this); SipAgent.HangupCall(_SipCallTx.Id); _SipCallTx.Id = -1; TxState = LcTxState.Congestion; } }); }
/// <summary> /// Finaliza la captura de la llamada enviando un Invite con replaces y los datos del dialogo /// Se cancela la suscripcion /// </summary> /// <param name="id"></param> /// <returns></returns> public bool Capture(int id) { if (State == FunctionState.Idle) { return(false); } if (id < Tlf.NumDestinations + Tlf.NumIaDestinations) { _Captured = Top.Tlf[id]; DialogData dialog; if (_Ringing.TryGetValue(id, out dialog)) { //TODO que pasa si falla una captura, intento las otras? if (_Captured.CallPickUp(dialog)) { _IgnoreNotify = true; if (_TargetUris != null) { foreach (string uri in _TargetUris) { SipAgent.DestroyDialogSubscription(uri); } } _Captured.TlfPosStateChanged += OnCapturedCallStateChanged; return(true); } else { State = FunctionState.Error; _Logger.Warn(String.Format("TlfPickUp:Capture pickUp failed: {0}", _Captured.Literal)); return(true); } } else { _Logger.Error(String.Format("TlfPickUp:Capture not ringing in captured destination: {0}", _Captured.Literal)); } } else { _Logger.Error(String.Format("TlfPickUp:Capture out of range: {0}", id)); } return(false); }
public void To(uint prefix, string dst, string number) { _FirstTransferTryKO = false; _ToTransfer = null; _FromTransferDisplayName = ""; if (_State == FunctionState.Idle) { List <TlfPosition> activeCalls = Top.Tlf.ActiveCalls; FunctionState st = FunctionState.Error; if (activeCalls.Count == 1) { TlfPosition tlf = activeCalls[0]; if ((tlf.State == TlfState.Set) || (tlf.State == TlfState.Conf)) { using (TlfIaPosition to = new TlfIaPosition(prefix, dst)) { string toUri = to.Uri; if (TlfManager.GetDisplayName(to.Uri) == null && to.Literal.Length > 0) { //Si to.uri no tiene display name se añade el Literal como display name en la transferencia directa toUri = "\"" + to.Literal + "\" " + to.Uri; } SipAgent.TransferCall(tlf.CallId, -1, toUri, null); Top.Sip.TlfTransferStatus += OnTransferStatus; AssociateCall = tlf; st = FunctionState.Executing; Top.WorkingThread.Enqueue("SetSnmp", delegate() { string snmpString = Top.Cfg.PositionId + "_" + "TRANSFER" + "_" + tlf.Literal; General.SafeLaunchEvent(SetSnmpString, this, new SnmpStringMsg <string, string>(Settings.Default.TlfFacilityOid, snmpString)); }); } } } State = st; } }
/// <summary> /// /// </summary> private void MakeHangUpRx() { if (_SipCallRx != null) { Debug.Assert(_SipCallRx.IsActive); Debug.Assert(_ActiveRx == this); if (_RxState == LcRxState.Rx) { Top.Mixer.Unlink(_SipCallRx.Id); } SipAgent.HangupCall(_SipCallRx.Id); _ActiveRx = null; _SipCallRx = null; Top.Lc.HoldedTlf = false; } }
/// <summary> /// Construye y envía el notify con los miembros de la conferencia. /// El primer miembro soy yo mismo, con todos los numeros a los que atiendo. /// Se llama cuando alguien se suscribe (1) y cuando se añaden miembros a la conferencia (2). /// Tiene un parametro opcional callId. Si viene, se envia el notify al miembro que /// contiene ese callId (1). El comportamiento por defecto es que si no viene el parámetro /// se envia a todos los miembros de la conferencia (2). /// </summary> /// <param name="callId" parámetro opcional, callId ></param> /// <returns> </returns> private void NotifyConfInfo(int callId = -1) { _Logger.Trace("NotifyConfInfo "); if (_Members.Count > 0) { CORESIP_ConfInfo info = new CORESIP_ConfInfo(); info.Version = ++_Version; info.Users = new CORESIP_ConfInfo.ConfUser[SipAgent.CORESIP_MAX_CONF_USERS]; int j = 0; foreach (StrNumeroAbonado num in Top.Cfg.HostAddresses) { info.Users[j].Id = string.Format("<sip:{0}@{1}>", num.NumeroAbonado, Top.SipIp);; info.Users[j++].Name = Top.Cfg.PositionId; } int i; info.UsersCount = (uint)(_Members.Count + j);; for (i = j; i < info.UsersCount; i++) { TlfPosition member = _Members[i - j]; info.Users[i].Id = member.Uri; info.Users[i].Name = member.Literal; if (member == _Intruder) { info.Users[i].Role = "Intruder"; } } foreach (TlfPosition member in _Members) { if ((callId == -1) || (callId == member.CallId)) { SipAgent.SendConfInfo(member.CallId, info); } } } }