private IEnumerator setRemoteDesc(RTCSdpType type, string sdp) { var desc = new RTCSessionDescription { type = type, sdp = sdp }; OnLogEvent.Invoke($"SetRemoteDescription {type}", ""); var opSetDesc = peer.SetRemoteDescription(ref desc); yield return(opSetDesc); if (opSetDesc.IsError) { OnErrorEvent.Invoke($"SetRemoteDescription {type}", opSetDesc.Error.message); yield break; } if (type == RTCSdpType.Offer) { yield return(CoroutineHandler.StartStaticCoroutine(sendDesc(RTCSdpType.Answer))); } else { OnOpen.Invoke(); } }
public RTCSessionDescription(RTCSdpType type, string sdp) { var strType = type.ToString().ToLower(); var dict = new Dictionary <string, string>(); dict.Add("type", strType); dict.Add("sdp", sdp); this.HostObject = new HostObject("RTCSessionDescription", dict); }
static void OnSuccessCreateSessionDesc(IntPtr ptr, RTCSdpType type, string sdp) { WebRTC.Sync(ptr, () => { if (WebRTC.Table[ptr] is RTCPeerConnection connection) { connection.m_opSessionDesc.Desc = new RTCSessionDescription { sdp = sdp, type = type }; connection.m_opSessionDesc.Done(); } }); }
private IEnumerator sendDesc(RTCSdpType type) { RTCSessionDescriptionAsyncOperation opCreate = null; if (type == RTCSdpType.Offer) { OnLogEvent.Invoke("CreateOffer()", ""); opCreate = peer.CreateOffer(ref offerOption); } else { OnLogEvent.Invoke("CreateAnswer()", ""); opCreate = peer.CreateAnswer(ref answerOptions); } yield return(opCreate); if (opCreate.IsError) { OnErrorEvent.Invoke($"Create {opCreate.Desc.type}", opCreate.Error.message); yield break; } else { OnLogEvent.Invoke($"Create {opCreate.Desc.type}", ""); } if (opCreate.Desc.sdp == null) { OnErrorEvent.Invoke("opCreate.Desc.sdp is null", ""); yield break; } else { OnLogEvent.Invoke($"SetLocalDescription {type}", $"{opCreate.Desc.sdp.Substring(0, 10)} ..."); } var desc = opCreate.Desc; var opSet = peer.SetLocalDescription(ref desc); yield return(opSet); if (opSet.IsError) { OnErrorEvent.Invoke($"SetLocalDescription {type}", opSet.Error.message); yield break; } OnLogEvent.Invoke($"Send {type}", ""); signaling.SendDesc(streamId, desc.type.ToString().ToLower(), desc.sdp); }
private IEnumerator createDesc(RTCSdpType type) { RTCSessionDescriptionAsyncOperation opCreate; if (type == RTCSdpType.Offer) { opCreate = peer.CreateOffer(ref offerOptions); } else { opCreate = peer.CreateAnswer(ref answerOptions); } yield return(opCreate); if (opCreate.IsError) { log(LogLevel.Error, $"Create {opCreate.Desc.type}: {opCreate.Error.message}"); yield break; } else { log(LogLevel.Log, $"Create {opCreate.Desc.type}"); } if (opCreate.Desc.sdp == null) { log(LogLevel.Error, $"opCreate.Desc.sdp is null"); yield break; } else { log(LogLevel.Log, $"SetLocalDescription {type}: {opCreate.Desc.sdp}"); } var desc = opCreate.Desc; var opSet = peer.SetLocalDescription(ref desc); yield return(opSet); if (opSet.IsError) { log(LogLevel.Error, $"SetLocalDescription {type}: {opSet.Error.message}"); yield break; } log(LogLevel.Log, $">>> Send \"takeConfiguration\" Command ({type}: '{desc.sdp.Substring(0, 10)} ...')"); signaling.SendDesc(streamId, desc.type.ToString().ToLower(), desc.sdp); }
IEnumerator CreateDescription(RTCSdpType type) { Debug.Log($"[Create {type}]"); var op = type == RTCSdpType.Offer ? localConnection.CreateOffer(ref offerOption) : localConnection.CreateAnswer(ref answerOptions); yield return(op); if (op.IsError) { Debug.LogError(op.Error.message); } else { yield return(SetDescription(op.Desc, Side.Local)); } }
IEnumerator createDesc(string id, RTCSdpType type) { Debug.Log($"[Create {type}] id:{id}"); var pc = pcs[id]; var op = type == RTCSdpType.Offer ? pc.CreateOffer(ref offerOption) : pc.CreateAnswer(ref answerOptions); yield return(op); if (op.IsError) { Debug.LogError(op.Error.message); } else { yield return(setDesc(id, Side.Local, op.Desc)); } }
private IEnumerator setRemoteDesc(RTCSdpType type, string sdp) { var desc = new RTCSessionDescription { type = type, sdp = sdp }; log(LogLevel.Log, $"SetRemoteDescription {type}"); var opSetDesc = peer.SetRemoteDescription(ref desc); yield return(opSetDesc); if (opSetDesc.IsError) { log(LogLevel.Error, $"SetRemoteDescription {type}: {opSetDesc.Error.message}"); yield break; } if (type == RTCSdpType.Offer) { yield return(StartCoroutine(createDesc(RTCSdpType.Answer))); } }
/// <summary> /// Handler for Signaller's OnMessageFromPeer event. /// </summary> /// <param name="peerId">ID of the peer.</param> /// <param name="message">Message from the peer.</param> private void Signaller_OnMessageFromPeer(int peerId, string message) { Task.Run(async() => { Debug.Assert(_peerId == peerId || _peerId == -1); Debug.Assert(message.Length > 0); if (_peerId != peerId && _peerId != -1) { Debug.WriteLine("[Error] Conductor: Received a message from unknown peer while already in a conversation with a different peer."); return; } JsonObject jMessage; if (!JsonObject.TryParse(message, out jMessage)) { Debug.WriteLine("[Error] Conductor: Received unknown message." + message); return; } string type = jMessage.ContainsKey(kSessionDescriptionTypeName) ? jMessage.GetNamedString(kSessionDescriptionTypeName) : null; #if ORTCLIB bool created = false; #endif if (_peerConnection == null) { if (!IsNullOrEmpty(type)) { // Create the peer connection only when call is // about to get initiated. Otherwise ignore the // messages from peers which could be a result // of old (but not yet fully closed) connections. if (type == "offer" || type == "answer" || type == "json") { Debug.Assert(_peerId == -1); _peerId = peerId; IEnumerable <Peer> enumerablePeer = Peers.Where(x => x.Id == peerId); Peer = enumerablePeer.First(); #if ORTCLIB created = true; _signalingMode = Helper.SignalingModeForClientName(Peer.Name); #endif _connectToPeerCancelationTokenSource = new CancellationTokenSource(); _connectToPeerTask = CreatePeerConnection(_connectToPeerCancelationTokenSource.Token); bool connectResult = await _connectToPeerTask; _connectToPeerTask = null; _connectToPeerCancelationTokenSource.Dispose(); if (!connectResult) { Debug.WriteLine("[Error] Conductor: Failed to initialize our PeerConnection instance"); await Signaller.SignOut(); return; } else if (_peerId != peerId) { Debug.WriteLine("[Error] Conductor: Received a message from unknown peer while already in a conversation with a different peer."); return; } } } else { Debug.WriteLine("[Warn] Conductor: Received an untyped message after closing peer connection."); return; } } if (_peerConnection != null && !IsNullOrEmpty(type)) { if (type == "offer-loopback") { // Loopback not supported Debug.Assert(false); } string sdp = null; #if ORTCLIB if (jMessage.ContainsKey(kSessionDescriptionJsonName)) { var containerObject = new JsonObject { { kSessionDescriptionJsonName, jMessage.GetNamedObject(kSessionDescriptionJsonName) } }; sdp = containerObject.Stringify(); } else if (jMessage.ContainsKey(kSessionDescriptionSdpName)) { sdp = jMessage.GetNamedString(kSessionDescriptionSdpName); } #else sdp = jMessage.ContainsKey(kSessionDescriptionSdpName) ? jMessage.GetNamedString(kSessionDescriptionSdpName) : null; #endif if (IsNullOrEmpty(sdp)) { Debug.WriteLine("[Error] Conductor: Can't parse received session description message."); return; } #if ORTCLIB RTCSessionDescriptionSignalingType messageType = RTCSessionDescriptionSignalingType.SdpOffer; switch (type) { case "json": messageType = RTCSessionDescriptionSignalingType.Json; break; case "offer": messageType = RTCSessionDescriptionSignalingType.SdpOffer; break; case "answer": messageType = RTCSessionDescriptionSignalingType.SdpAnswer; break; case "pranswer": messageType = RTCSessionDescriptionSignalingType.SdpPranswer; break; default: Debug.Assert(false, type); break; } #else RTCSdpType messageType = RTCSdpType.Offer; switch (type) { case "offer": messageType = RTCSdpType.Offer; break; case "answer": messageType = RTCSdpType.Answer; break; case "pranswer": messageType = RTCSdpType.Pranswer; break; default: Debug.Assert(false, type); break; } #endif Debug.WriteLine("Conductor: Received session description: " + message); await _peerConnection.SetRemoteDescription(new RTCSessionDescription(messageType, sdp)); #if ORTCLIB if ((messageType == RTCSessionDescriptionSignalingType.SdpOffer) || ((created) && (messageType == RTCSessionDescriptionSignalingType.Json))) #else if (messageType == RTCSdpType.Offer) #endif { var answer = await _peerConnection.CreateAnswer(); await _peerConnection.SetLocalDescription(answer); // Send answer SendSdp(answer); #if ORTCLIB OrtcStatsManager.Instance.StartCallWatch(SessionId, false); #endif } } else { RTCIceCandidate candidate = null; #if ORTCLIB if (RTCPeerConnectionSignalingMode.Json != _signalingMode) #endif { var sdpMid = jMessage.ContainsKey(kCandidateSdpMidName) ? jMessage.GetNamedString(kCandidateSdpMidName) : null; var sdpMlineIndex = jMessage.ContainsKey(kCandidateSdpMlineIndexName) ? jMessage.GetNamedNumber(kCandidateSdpMlineIndexName) : -1; var sdp = jMessage.ContainsKey(kCandidateSdpName) ? jMessage.GetNamedString(kCandidateSdpName) : null; //TODO: Check is this proper condition ((String.IsNullOrEmpty(sdpMid) && (sdpMlineIndex == -1)) || String.IsNullOrEmpty(sdp)) if (IsNullOrEmpty(sdpMid) || sdpMlineIndex == -1 || IsNullOrEmpty(sdp)) { Debug.WriteLine("[Error] Conductor: Can't parse received message.\n" + message); return; } #if ORTCLIB candidate = IsNullOrEmpty(sdpMid) ? RTCIceCandidate.FromSdpStringWithMLineIndex(sdp, (ushort)sdpMlineIndex) : RTCIceCandidate.FromSdpStringWithMid(sdp, sdpMid); #else candidate = new RTCIceCandidate(sdp, sdpMid, (ushort)sdpMlineIndex); #endif } #if ORTCLIB else { candidate = RTCIceCandidate.FromJsonString(message); } _peerConnection?.AddIceCandidate(candidate); #else await _peerConnection.AddIceCandidate(candidate); #endif Debug.WriteLine("Conductor: Received candidate : " + message); } }).Wait(); }
public void MessageFromPeerTaskRun(int peerId, string content) { PeerId = peerId; Task.Run(async() => { Debug.Assert(_peerId == PeerId || _peerId == -1); Debug.Assert(content.Length > 0); if (_peerId != PeerId && _peerId != -1) { Debug.WriteLine("Received a message from unknown peer " + "while already in a conversation with a different peer."); return; } if (!JsonObject.TryParse(content, out JsonObject jMessage)) { Debug.WriteLine($"Received unknown message: {content}"); return; } string type = jMessage.ContainsKey(NegotiationAtributes.Type) ? jMessage.GetNamedString(NegotiationAtributes.Type) : null; if (PeerConnection == null) { if (!string.IsNullOrEmpty(type)) { // Create the peer connection only when call is // about to get initiated. Otherwise ignore the // message from peers which could be result // of old (but not yet fully closed) connections. if (type == "offer" || type == "answer" || type == "json") { Debug.Assert(_peerId == -1); _peerId = PeerId; if (!CreatePeerConnection()) { Debug.WriteLine("Failed to initialize our PeerConnection instance"); OnSignedOut.Invoke(this, null); return; } else if (_peerId != PeerId) { Debug.WriteLine("Received a message from unknown peer while already " + "in a conversation with a different peer."); return; } } } else { Debug.WriteLine("[Warn] Received an untyped message after closing peer connection."); return; } } if (PeerConnection != null && !string.IsNullOrEmpty(type)) { if (type == "offer-loopback") { // Loopback not supported Debug.Assert(false); } string sdp = null; sdp = jMessage.ContainsKey(NegotiationAtributes.Sdp) ? jMessage.GetNamedString(NegotiationAtributes.Sdp) : null; if (string.IsNullOrEmpty(sdp)) { Debug.WriteLine("[Error] Can't parse received session description message."); return; } Debug.WriteLine($"Received session description:\n{content}"); RTCSdpType messageType = RTCSdpType.Offer; switch (type) { case "offer": messageType = RTCSdpType.Offer; break; case "answer": messageType = RTCSdpType.Answer; break; case "pranswer": messageType = RTCSdpType.Pranswer; break; default: Debug.Assert(false, type); break; } var sdpInit = new RTCSessionDescriptionInit(); sdpInit.Sdp = sdp; sdpInit.Type = messageType; var description = new RTCSessionDescription(sdpInit); await PeerConnection.SetRemoteDescription(description); if (messageType == RTCSdpType.Offer) { var answerOptions = new RTCAnswerOptions(); IRTCSessionDescription answer = await PeerConnection.CreateAnswer(answerOptions); await PeerConnection.SetLocalDescription(answer); string jsonString = SdpToJsonString(answer); // Send answer OnSendMessageToRemotePeer.Invoke(this, jsonString); } } else { RTCIceCandidate candidate = null; string sdpMid = jMessage.ContainsKey(NegotiationAtributes.SdpMid) ? jMessage.GetNamedString(NegotiationAtributes.SdpMid) : null; double sdpMLineIndex = jMessage.ContainsKey(NegotiationAtributes.SdpMLineIndex) ? jMessage.GetNamedNumber(NegotiationAtributes.SdpMLineIndex) : -1; string sdpCandidate = jMessage.ContainsKey(NegotiationAtributes.Candidate) ? jMessage.GetNamedString(NegotiationAtributes.Candidate) : null; if (string.IsNullOrEmpty(sdpMid) || sdpMLineIndex == -1 || string.IsNullOrEmpty(sdpCandidate)) { Debug.WriteLine($"[Error] Can't parse received message.\n{content}"); return; } var candidateInit = new RTCIceCandidateInit(); candidateInit.Candidate = sdpCandidate; candidateInit.SdpMid = sdpMid; candidateInit.SdpMLineIndex = (ushort)sdpMLineIndex; candidate = new RTCIceCandidate(candidateInit); await PeerConnection.AddIceCandidate(candidate); Debug.WriteLine($"Receiving ice candidate:\n{content}"); } }).Wait(); }
public static SdpType ToNativePort(this RTCSdpType platformNative) => (SdpType)platformNative;
public RTCSessionDescriptionInit(string sdp, RTCSdpType type) { HostObject = new JSObject(); HostObject.SetObjectProperty("type", type.ToString().ToLower()); HostObject.SetObjectProperty("sdp", sdp); }
public static SdpType ToNet(this RTCSdpType self) { return((SdpType)self); }