// %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);
}
}
}
}