/// <summary> /// Intento de llamada saliente por alguno de los canales disponibles. /// Cuando hay configurados varios canales se intenta primero por el ATS IP y /// luego en turno rotatorio en cada llamada por los LCEN. /// Si una llamada no progresa se intenta por el siguiente canal en la misma llamada /// </summary> /// <returns></returns> private LcTxState TryCall() { SipChannel channel = null; SipPath path = null; Debug.Assert((_SipCallTx != null) && !_SipCallTx.IsActive); // Busco el path sobre el canal IP si lo hay, para hacer el primer intento foreach (SipChannel ch in _Channels) { if (ch is TlfNetChannel) { path = ch.GetPreferentPath(_SipCallTx.Priority); if ((path != null) && TryCall(ch, path)) { return(LcTxState.Out); } else { break; } } } for (int i = 0; i < _Channels.Count; i++) { //Rotación de canales _LastChannel = ++_LastChannel % _Channels.Count; channel = _Channels[_LastChannel]; path = channel.GetPreferentPath(_SipCallTx.Priority); while (path != null) { if (TryCall(channel, path)) { return(LcTxState.Out); } path = channel.GetPreferentPath(_SipCallTx.Priority); } } foreach (SipChannel ch in _Channels) { path = ch.GetDetourPath(_SipCallTx.Priority); while (path != null) { if (TryCall(ch, path)) { return(LcTxState.Out); } path = ch.GetDetourPath(_SipCallTx.Priority); } } _CallTout.Enabled = false; return(LcTxState.Congestion); }
protected override bool TryCall(SipChannel ch, SipPath path, int prio) { //Esta comprobación no se hace porque a veces la CORESIP pierde el NOTIFY del "deleted" //TODO Pendiente de hacer cuando se resuelva la CORESIP if (!_Subscribed) { SipAgent.CreateConferenceSubscription(ch.AccId, ch.Uri); _Subscribed = true; } return(base.TryCall(ch, path, prio)); }
public static SipCallInfo NewIncommingCall(IEnumerable <SipChannel> channels, int callId, CORESIP_CallInfo info, CORESIP_CallInInfo inInfo, bool findNoConfigured) { SipPath path = null; SipChannel channel = null; foreach (SipChannel ch in channels) { ch.First = false; } foreach (SipChannel ch in channels) { path = ch.FindPath(inInfo.SrcId, inInfo.SrcIp, inInfo.SrcSubId, inInfo.SrcRs); if (path != null) { channel = ch; break; } } //Si no se encuentra path en todos los canales, //se hace una busqueda sin comparar con el recurso. if ((path == null) && (findNoConfigured)) { foreach (SipChannel ch in channels) { path = ch.FindPathNoConfigured(inInfo.SrcId, inInfo.SrcSubId); if (path != null) { channel = ch; break; } } } if (path != null) { channel.First = true; return(new SipCallInfo(callId, inInfo.DstId, inInfo.SrcId, info.Priority, info.Type, channel, path.Remote, path.Line)); } return(null); }
/// <summary> /// /// </summary> /// <param name="ch"></param> /// <param name="path"></param> /// <returns></returns> protected bool TryCall(SipChannel ch, SipPath path) { string dstParams = ""; string remoteId = path.Remote.Ids[0]; if (!path.Line.centralIP) { //Estos parametros son internos, sirven para dar información a la pasarela //En encaminamiento IP no se deben usar if ((ch.Prefix != Cd40Cfg.INT_DST) && ((ch.Prefix != Cd40Cfg.PP_DST) || (string.Compare(remoteId, path.Line.Id) != 0))) { dstParams += string.Format(";cd40rs={0}", path.Line.Id); } } string dstUri = string.Format("<sip:{0}@{1}{2}>", remoteId, path.Line.Ip, dstParams); try { CORESIP_CallFlags flags = CORESIP_CallFlags.CORESIP_CALL_NO_FLAGS; if (path.ModoSinProxy == false) { flags |= CORESIP_CallFlags.CORESIP_CALL_EXTERNAL_IP; } int sipCallId = SipAgent.MakeLcCall(ch.AccId, dstUri, flags); _SipCallTx.Update(sipCallId, ch.AccId, remoteId, ch, path.Remote, path.Line); return(true); } catch (Exception ex) { ch.SetCallResult(path.Remote, path.Line, _SipCallTx.Priority, -1); _Logger.Warn("ERROR llamando a " + dstUri, ex); } return(false); }