// %BANNER_BEGIN% // --------------------------------------------------------------------- // %COPYRIGHT_BEGIN% // Copyright (c) (2018-2022) Magic Leap, Inc. All Rights Reserved. // Use of this file is governed by the Software License Agreement, located here: https://www.magicleap.com/software-license-agreement-ml2 // Terms and conditions applicable to third-party materials accompanying this distribution may also be found in the top-level NOTICE file appearing herein. // %COPYRIGHT_END% // --------------------------------------------------------------------- // %BANNER_END% namespace UnityEngine.XR.MagicLeap { using System.Runtime.InteropServices; using UnityEngine.XR.MagicLeap.Native; /// /// MLWebRTC class contains the API to interface with the /// WebRTC C API. /// public partial class MLWebRTC { /// /// Class that represents a data channel used by the MLWebRTC API. /// public partial class DataChannel { /// /// The handle for this managed object. /// private GCHandle gcHandle; /// /// Gets or sets the handle of the data channel. /// internal ulong Handle { get; private set; } /// /// Initializes a new instance of the class. /// internal DataChannel() { } /// /// Initializes a new instance of the class. /// /// The handle to give the data channel. internal DataChannel(ulong handle) { this.Handle = handle; } /// /// Delegate that describes the requirements of the OnOpened callback. /// /// The data channel associated with the event. public delegate void OnOpenedDelegate(MLWebRTC.DataChannel dataChannel); /// /// Delegate that describes the requirements of the OnClosed callback. /// /// The data channel associated with the event. public delegate void OnClosedDelegate(MLWebRTC.DataChannel dataChannel); /// /// Delegate that describes the requirements of the OnMessageText callback. /// /// The data channel associated with the event. /// The message string. public delegate void OnMessageTextDelegate(MLWebRTC.DataChannel dataChannel, string message); /// /// Delegate that describes the requirements of the OnMessageBinary callback. /// /// The data channel associated with the event. /// The message byte array. public delegate void OnMessageBinaryDelegate(MLWebRTC.DataChannel dataChannel, byte[] message); /// /// Event invoked for when a data channel opens. /// public event OnOpenedDelegate OnOpened = delegate { }; /// /// Event invoked for when a data channel closes. /// public event OnClosedDelegate OnClosed = delegate { }; /// /// Event invoked for when a data channel receives a text message. /// public event OnMessageTextDelegate OnMessageText = delegate { }; /// /// Event invoked for when a data channel receives a binary message. /// public event OnMessageBinaryDelegate OnMessageBinary = delegate { }; /// /// Gets the label of the data channel. /// public string Label { get; internal set; } /// /// Gets the connection associated with the data channel. /// public PeerConnection ParentConnection { get; internal set; } /// /// Creates an initialized DataChannel object. /// /// The connection to create the data channel with. /// The label to give the data channel. /// The MLResult object of the inner platform call(s). /// An initialized DataChannel object. public static DataChannel CreateLocal(MLWebRTC.PeerConnection connection, out MLResult result, string label = "local") { DataChannel dataChannel = null; if (connection == null) { result = MLResult.Create(MLResult.Code.InvalidParam, "PeerConnection is null."); return dataChannel; } ulong dataChannelHandle = MagicLeapNativeBindings.InvalidHandle; MLResult.Code resultCode = NativeBindings.MLWebRTCDataChannelCreate(connection.Handle, label, out dataChannelHandle); if (!MLResult.DidNativeCallSucceed(resultCode, nameof(NativeBindings.MLWebRTCDataChannelCreate))) { result = MLResult.Create(resultCode); return dataChannel; } dataChannel = new DataChannel(dataChannelHandle) { Label = label, ParentConnection = connection }; resultCode = NativeBindings.SetCallbacks(dataChannel); if (!MLResult.IsOK(resultCode)) { result = MLResult.Create(resultCode); return dataChannel; } connection.LocalDataChannels.Add(dataChannel); result = MLResult.Create(resultCode); return dataChannel; } /// /// Sends a string message to a data channel. /// /// The string to send. /// /// MLResult.Result will be MLResult.Code.Ok if destroying all handles was successful. /// MLResult.Result will be MLResult.Code.WebRTCResultInstanceNotCreated if MLWebRTC instance was not created. /// MLResult.Result will be MLResult.Code.WebRTCResultMismatchingHandle if an incorrect handle was sent. /// MLResult.Result will be MLResult.Code.InvalidParam if an invalid parameter was passed. /// MLResult.Result will be MLResult.Code.WebRTCResultDataChannelIsClosed if data channel is closed. /// public MLResult SendMessage(string message) { MLResult.Code resultCode = NativeBindings.SendMessageToDataChannel(this, message); MLResult.DidNativeCallSucceed(resultCode, nameof(NativeBindings.SendMessageToDataChannel)); return MLResult.Create(resultCode); } /// /// Sends a byte array message to a data channel. /// /// The byte array to send. /// /// MLResult.Result will be MLResult.Code.Ok if destroying all handles was successful. /// MLResult.Result will be MLResult.Code.WebRTCResultInstanceNotCreated if MLWebRTC instance was not created. /// MLResult.Result will be MLResult.Code.WebRTCResultMismatchingHandle if an incorrect handle was sent. /// MLResult.Result will be MLResult.Code.InvalidParam if an invalid parameter was passed. /// MLResult.Result will be MLResult.Code.WebRTCResultDataChannelIsClosed if data channel is closed. /// public MLResult SendMessage(T[] message) { MLResult.Code resultCode = NativeBindings.SendMessageToDataChannel(this, message); MLResult.DidNativeCallSucceed(resultCode, nameof(NativeBindings.SendMessageToDataChannel)); return MLResult.Create(resultCode); } /// /// Checks if the data channel is currently open. /// /// True if data channel is open. /// /// MLResult.Result will be MLResult.Code.Ok if destroying all handles was successful. /// MLResult.Result will be MLResult.Code.WebRTCResultInstanceNotCreated if MLWebRTC instance was not created. /// MLResult.Result will be MLResult.Code.WebRTCResultMismatchingHandle if an incorrect handle was sent. /// MLResult.Result will be MLResult.Code.InvalidParam if an invalid parameter was passed. /// public MLResult IsOpen(out bool open) { bool isOpen = false; MLResult.Code resultCode = NativeBindings.MLWebRTCDataChannelIsOpen(this.Handle, out isOpen); MLResult.DidNativeCallSucceed(resultCode, nameof(NativeBindings.MLWebRTCDataChannelIsOpen)); open = isOpen; MLResult result = MLResult.Create(resultCode); return result; } /// /// Destroys the data channel object. /// /// /// MLResult.Result will be MLResult.Code.Ok if destroying all handles was successful. /// MLResult.Result will be MLResult.Code.WebRTCResultInstanceNotCreated if MLWebRTC instance was not created. /// MLResult.Result will be MLResult.Code.WebRTCResultMismatchingHandle if an incorrect handle was sent. /// public MLResult Destroy() { if (this.ParentConnection == null || !MagicLeapNativeBindings.MLHandleIsValid(this.Handle)) { return MLResult.Create(MLResult.Code.InvalidParam); } MLResult.Code resultCode = NativeBindings.MLWebRTCDataChannelDestroy(this.ParentConnection.Handle, this.Handle); if (MLResult.DidNativeCallSucceed(resultCode, nameof(NativeBindings.MLWebRTCDataChannelDestroy))) { this.Handle = MagicLeapNativeBindings.InvalidHandle; this.ParentConnection = null; } this.gcHandle.Free(); return MLResult.Create(resultCode); } } } }