diff --git a/integrations/Unity3D/Assets/Demo.cs b/integrations/Unity3D/Assets/Demo.cs index 4151889..ef2a9e6 100644 --- a/integrations/Unity3D/Assets/Demo.cs +++ b/integrations/Unity3D/Assets/Demo.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Runtime.Serialization.Formatters.Binary; using System.IO; using UnityEngine.UI; +using UnityEngine.Networking; public class Demo : MonoBehaviour { @@ -131,13 +132,13 @@ public class Demo : MonoBehaviour input.text = "172.22.211.245"; go = GameObject.Find ("inputServerPort"); input = go.GetComponents () [0]; - input.text = "8888"; + input.text = "8887"; go = GameObject.Find ("inputMessage"); input = go.GetComponents () [0]; input.text = "Welcome to the machine"; // Create new instance of ZeroTier in separate thread - zt = new ZeroTierNetworkInterface ("/Users/Joseph/utest2"); + zt = new ZeroTierNetworkInterface ("/Users/Joseph/utest2/nc_565799d8f6e1c11a"); /* This new instance will communicate via a named pipe, so any * API calls (ZeroTier.Connect(), ZeroTier.Send(), etc) will be sent to the service @@ -153,6 +154,38 @@ public class Demo : MonoBehaviour // Update is called once per frame void Update () { + /* + if (text) { + text.text = IsRunning() ? "ZeroTier Status: Online" : "ZeroTier Status: Offline"; + } + */ + + // --- + + int recHostId; + int connectionId; + int channelId; + byte[] recBuffer = new byte[1024]; + int bufferSize = 1024; + int dataSize; + byte error; + NetworkEventType recData = zt.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error); + switch (recData) + { + case NetworkEventType.Nothing: //1 + break; + case NetworkEventType.ConnectEvent: //2 + Debug.Log("NetworkEventType.ConnectEvent"); + break; + case NetworkEventType.DataEvent: //3 + Debug.Log("NetworkEventType.DataEvent"); + break; + case NetworkEventType.DisconnectEvent: //4 + Debug.Log("NetworkEventType.DisconnectEvent"); + break; + } + + // --- /* GameObject go = GameObject.Find ("_txtStatusIndicator"); @@ -169,14 +202,8 @@ public class Demo : MonoBehaviour Vector3 rotvec = new Vector3 (10f, 10f, 10f); go.transform.Rotate (rotvec, speed * Time.deltaTime); } - */ - - /* GameObject go = GameObject.Find("ZTCube"); Text text = go.GetComponents ()[0]; - if (text) { - text.text = IsRunning() ? "ZeroTier Status: Online" : "ZeroTier Status: Offline"; - } */ } } \ No newline at end of file diff --git a/integrations/Unity3D/Assets/ZeroTier.cs b/integrations/Unity3D/Assets/ZeroTier.cs index acdd87a..4d618a0 100644 --- a/integrations/Unity3D/Assets/ZeroTier.cs +++ b/integrations/Unity3D/Assets/ZeroTier.cs @@ -114,7 +114,9 @@ public class ZeroTierNetworkInterface { [DllImport (DLL_PATH)] unsafe private static extern int zt_recv(int sockfd, string buf, int len); [DllImport (DLL_PATH)] - unsafe private static extern int zt_send(int sockfd, string buf, int len); + unsafe private static extern int zt_send(int sockfd, IntPtr buf, int len); + [DllImport (DLL_PATH)] + unsafe private static extern int zt_set_nonblock(int sockfd); // ZT Thread controls [DllImport (DLL_PATH)] @@ -140,6 +142,7 @@ public class ZeroTierNetworkInterface { Marshal.GetFunctionPointerForDelegate(callback_delegate); // Call the API passing along the function pointer. SetDebugFunction( intptr_delegate ); + Debug.Log ("rpc_path = " + rpc_path); unity_start_service (rpc_path); } @@ -202,6 +205,10 @@ public class ZeroTierNetworkInterface { GCHandle sockaddr_ptr = ZeroTierUtils.Generate_unmananged_sockaddr("0.0.0.0" + ":" + port); IntPtr pSockAddr = sockaddr_ptr.AddrOfPinnedObject (); int addrlen = Marshal.SizeOf (pSockAddr); + + // Set socket to non-blocking for RX polling in Receive() + zt_set_nonblock(sockfd); + return zt_bind (sockfd, pSockAddr, addrlen); } @@ -219,6 +226,10 @@ public class ZeroTierNetworkInterface { IntPtr pSockAddr = sockaddr_ptr.AddrOfPinnedObject (); int addrlen = Marshal.SizeOf (pSockAddr); error = (byte)zt_connect (sockfd, pSockAddr, addrlen); + + // Set socket to non-blocking for RX polling in Receive() + zt_set_nonblock(sockfd); + return sockfd; } @@ -239,32 +250,9 @@ public class ZeroTierNetworkInterface { { return zt_close (fd); } - - // Sends data out over the network - - /* - public int Send(int fd, char[] buf, int len, out byte error) - { - int bytes_written = 0; - error = 0; - - GCHandle buf_handle = GCHandle.Alloc (buf, GCHandleType.Pinned); - IntPtr pBufPtr = buf_handle.AddrOfPinnedObject (); - if((bytes_written = zt_send (fd, pBufPtr, len)) < 0) { - error = (byte)bytes_written; - } - return bytes_written; - } - */ - - // Structure used to house arrays meant to be sent to unmanaged memory and passed to the - // ZeroTier service - public struct UnityArrayInput - { - public IntPtr array; - } - + // Write data to a ZeroTier socket + /* public int Send(int fd, char[] buf, int len, out byte error) { GCHandle buf_handle = GCHandle.Alloc (buf, GCHandleType.Pinned); @@ -278,41 +266,52 @@ public class ZeroTierNetworkInterface { } return bytes_written; } - - // Sends data out over the network - /* - public int Send(int fd, char[] bufx, int len, out byte error) - { - char[] buf = "this is another test".ToCharArray(); - UnityArrayInput data = new UnityArrayInput (); - data.array = Marshal.AllocHGlobal (Marshal.SizeOf (typeof(char))*buf.Length); - //data.len = buf.Length; - int bytes_written = 0; - error = 0; - - try - { - //Marshal.Copy(buf, 0, data.array, buf.Length); - - Debug.Log(buf.Length); - // ZT API call - if((bytes_written = zt_send (fd, data.array, buf.Length)) < 0) { - error = (byte)bytes_written; - } - return bytes_written; - } - finally - { - Marshal.FreeHGlobal (data.array); - } - return 0; - } */ - // Checks for data to RX - public int OnReceive(int fd, byte[] buf, int len) + // Write data to a ZeroTier socket + public int Send(int fd, char[] buf, int len, out byte error) { - return 0; - //return zt_read(fd, buf, len); + GCHandle handle = GCHandle.Alloc(buf, GCHandleType.Pinned); + IntPtr ptr = handle.AddrOfPinnedObject(); + error = 0; + int bytes_written; + // FIXME: Sending a length of 2X the buffer size seems to fix the object pinning issue + if((bytes_written = zt_send(fd, ptr, len*2)) < 0) { + error = (byte)bytes_written; + } + return bytes_written; + } + + // Checks for data to RX + /* + public enum NetworkEventType + { + DataEvent, + ConnectEvent, + DisconnectEvent, + Nothing, + BroadcastEvent + } + */ + public NetworkEventType Receive(out int hostId, out int connectionId, out int channelId, byte[] buffer, int bufferSize, out int receivedSize, out byte error) + { + int res; + res = zt_recv (connectionId, buffer, bufferSize); + + // FIXME: Not quite semantically the same, but close enough for alpha release? + // FIXME: Get notifications of disconnect events? + if (res == -1) { + error = -1; + return NetworkEventType.DisconnectEvent; + } + if(res == 0) { + error = 0; + return NetworkEventType.Nothing; // No data read + } + if (res > 0) { + receivedSize = res; + Marshal.Copy(buffer, buffer, 0, res); + return NetworkEventType.DataEvent; // Data read into buffer + } } } diff --git a/src/SDK.h b/src/SDK.h index d6b1dcd..78c2ff5 100644 --- a/src/SDK.h +++ b/src/SDK.h @@ -74,6 +74,7 @@ ssize_t zt_recvmsg(RECVMSG_SIG); #if defined(__UNITY_3D__) ssize_t zt_recv(int fd, void *buf, int len); ssize_t zt_send(int fd, void *buf, int len); + int zt_set_nonblock(int fd); #endif diff --git a/src/SDK_Sockets.c b/src/SDK_Sockets.c index 2e93595..3a5245c 100644 --- a/src/SDK_Sockets.c +++ b/src/SDK_Sockets.c @@ -303,6 +303,8 @@ const char *get_netpath() { #if defined(__UNITY_3D__) + // Just expose some basic calls for configuring and RX/TXing through ZT sockets + ssize_t zt_send(int fd, void *buf, int len) { return write(fd, buf, len); @@ -313,17 +315,10 @@ const char *get_netpath() { return read(fd, buf, len); } - /* - ssize_t zt_send(int fd, struct UnityArrayInput *buf, int len) - { - return write(fd, buf->array, len); - } - - ssize_t zt_recv(int fd, struct UnityArrayInput *buf, int len) - { - return read(fd, buf->array, len); - } - */ + int zt_set_nonblock(int fd) + { + return fcntl(fd, F_SETFL, O_NONBLOCK); + } #endif // ------------------------------------------------------------------------------