/// <summary> /// TODO: Documentation StartTurnPeer /// </summary> /// <param name="sid"></param> private void StartTurnPeer(String sid) { JingleSession jingleSession = this.JingleManager.FindSession(sid); if (jingleSession != null && jingleSession.Remote.Action == ActionType.session_initiate) { JingleContent jingleContent = jingleSession.Remote.GetContent(0); JingleIce jingleIce = jingleContent.GetElement <JingleIce>(0); foreach (JingleIceCandidate candidate in jingleIce.GetCandidates()) { if (candidate.Type == IceCandidateType.relay) { if (this.OnTurnStart != null) { this.OnTurnStart(this, candidate.EndPoint, sid); } if (this.OnConnectionTryEnded != null) { this.OnConnectionTryEnded(this, sid); } this.CancelStartingSession(); break; } } } }
/// <summary> /// Constructs a Jingle IQ Paquet containing Jingle most common arguments /// </summary> /// <param name="to">Recipient of this Jingle IQ Paquet</param> /// <param name="action">Type of Action this request is about</param> /// <param name="sid"> /// SID of the session which can be created using JingleUtilities.GenerateSid for a session-initiate /// paquet construction or was given by a peer who initiated a session which had been accepted /// </param> /// <param name="contentName">The name of the content, only for informative purposes but mandatory</param> /// <param name="description">An XML element using root tag <description></description></param> /// <param name="transport">An XML element using root tag <transport></transport></param> /// <returns></returns> public JingleIQ SessionRequest(JID to, ActionType action, String sid, String contentName, Element description, Element transport) { JingleIQ jingleIq; if (description != null) { jingleIq = new JingleIQ(description.OwnerDocument); } else if (transport != null) { jingleIq = new JingleIQ(transport.OwnerDocument); } else { jingleIq = new JingleIQ(new XmlDocument()); } jingleIq.From = this.Stream.JID; jingleIq.To = to; jingleIq.Type = IQType.set; jingleIq.Instruction.Action = action; jingleIq.Instruction.Sid = sid; if (action == ActionType.session_initiate) { jingleIq.Instruction.Initiator = this.Stream.JID; } else if (action == ActionType.session_accept) { jingleIq.Instruction.Responder = this.Stream.JID; } if (!String.IsNullOrEmpty(contentName)) { JingleContent jcnt = jingleIq.Instruction.AddContent(contentName); if (description != null) { jcnt.AddChild(description); } if (transport != null) { jcnt.AddChild(transport); } } else { throw new InvalidOperationException("Content name cannot be null or an empty string"); } return(jingleIq); }
/// <summary> /// TODO: Documentation jingleManager_OnReceivedTransportInfo /// </summary> /// <param name="sender"></param> /// <param name="iq"></param> private void jingleManager_OnReceivedTransportInfo(object sender, IQ iq) { Jingle jingle = iq.Query as Jingle; JingleContent jingleContent = jingle.GetContent(0); if (jingleContent.ContentName == "checkConnectivity") { this.CheckConnectivity(jingle.Sid); iq.Handled = true; } }
/// <summary> /// TODO: Documentation CheckConnectivity /// </summary> /// <param name="sid"></param> private void CheckConnectivity(String sid) { if (this.turnSessions.ContainsKey(sid)) { this.holePuncher = new HolePuncher(this.turnSessions[sid].TurnManager.HostEP, sid); JingleSession jingleSession = this.JingleManager.FindSession(sid); JingleContent jingleContent = jingleSession.Remote.GetContent(0); JingleIce jingleIce = jingleContent.GetElement <JingleIce>(0); foreach (JingleIceCandidate remoteCandidate in jingleIce.GetCandidates()) { switch (remoteCandidate.Type) { case IceCandidateType.host: case IceCandidateType.prflx: case IceCandidateType.srflx: foreach (JingleIceCandidate localCandidate in this.localCandidates[sid]) { if (localCandidate.Type == remoteCandidate.Type) { this.holePuncher.AddEP(remoteCandidate.Priority, remoteCandidate.EndPoint); break; } } break; case IceCandidateType.relay: if (this.TurnSupported && jingleSession.Remote.Action == ActionType.session_accept) { this.turnSessions[sid].TurnManager.CreatePermission(new XorMappedAddress(remoteCandidate.RelatedEndPoint), this.turnSessions[sid].TurnAllocation); } break; } } if (!this.holePuncher.CanStart && this.TurnSupported) { this.StartTurnPeer(sid); } else { this.holePuncher.StartTcpPunch(this.HolePunchSuccess, this.HolePunchFailure); } } }
/// <summary> /// TODO: Documentation jingleManager_OnReceivedSessionAccept /// </summary> /// <param name="sender"></param> /// <param name="iq"></param> private void jingleManager_OnReceivedSessionAccept(object sender, IQ iq) { Jingle jingle = iq.Query as Jingle; JingleIQ jingleIq = new JingleIQ(this.Stream.Document); jingleIq.From = this.Stream.JID; jingleIq.To = iq.From; jingleIq.Type = IQType.set; jingleIq.Instruction.Action = ActionType.transport_info; jingleIq.Instruction.Sid = jingle.Sid; JingleContent jcnt = jingleIq.Instruction.AddContent("checkConnectivity"); this.Stream.Write(jingleIq); this.CheckConnectivity(jingle.Sid); iq.Handled = true; }