summaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/Net/OVR_Session.h
diff options
context:
space:
mode:
Diffstat (limited to 'LibOVR/Src/Net/OVR_Session.h')
-rwxr-xr-x[-rw-r--r--]LibOVR/Src/Net/OVR_Session.h309
1 files changed, 176 insertions, 133 deletions
diff --git a/LibOVR/Src/Net/OVR_Session.h b/LibOVR/Src/Net/OVR_Session.h
index b6ef07b..3f329f9 100644..100755
--- a/LibOVR/Src/Net/OVR_Session.h
+++ b/LibOVR/Src/Net/OVR_Session.h
@@ -28,12 +28,16 @@ limitations under the License.
#ifndef OVR_Session_h
#define OVR_Session_h
+#include <atomic>
+
+#include <OVR_Version.h>
#include "OVR_Socket.h"
#include "OVR_PacketizedTCPSocket.h"
-#include "../Kernel/OVR_Array.h"
-#include "../Kernel/OVR_Threads.h"
-#include "../Kernel/OVR_Atomic.h"
-#include "../Kernel/OVR_RefCount.h"
+#include "Kernel/OVR_Array.h"
+#include "Kernel/OVR_Threads.h"
+#include "Kernel/OVR_RefCount.h"
+#include <stdint.h>
+
namespace OVR { namespace Net {
@@ -45,48 +49,82 @@ class Session;
//
// Please update changelog below:
// 1.0.0 - [SDK 0.4.0] Initial version (July 21, 2014)
-// 1.1.0 - Add Get/SetDriverMode_1, HMDCountUpdate_1
-// Version mismatch results (July 28, 2014)
+// 1.1.0 - [SDK 0.4.1] Add Get/SetDriverMode_1, HMDCountUpdate_1 Version mismatch results (July 28, 2014)
+// 1.2.0 - [SDK 0.4.4]
+// 1.2.1 - [SDK 0.5.0] Added DyLib model and SDKVersion
+// 1.3.0 - [SDK 0.5.0] Multiple shared memory regions for different objects
//-----------------------------------------------------------------------------
static const uint16_t RPCVersion_Major = 1; // MAJOR version when you make incompatible API changes,
-static const uint16_t RPCVersion_Minor = 2; // MINOR version when you add functionality in a backwards-compatible manner, and
+static const uint16_t RPCVersion_Minor = 3; // MINOR version when you add functionality in a backwards-compatible manner, and
static const uint16_t RPCVersion_Patch = 0; // PATCH version when you make backwards-compatible bug fixes.
+#define OVR_FEATURE_VERSION 0
+
+
+struct SDKVersion
+{
+ uint16_t ProductVersion; // CAPI DLL product number, 0 before first consumer release
+ uint16_t MajorVersion; // CAPI DLL version major number
+ uint16_t MinorVersion; // CAPI DLL version minor number
+ uint16_t RequestedMinorVersion; // Number provided by game in ovr_Initialize() arguments
+ uint16_t PatchVersion; // CAPI DLL version patch number
+ uint16_t BuildNumber; // Number increments per build
+ uint16_t FeatureVersion; // CAPI DLL feature version number
+
+ SDKVersion()
+ {
+ Reset();
+ }
+
+ void Reset()
+ {
+ ProductVersion = MajorVersion = MinorVersion = UINT16_MAX;
+ RequestedMinorVersion = PatchVersion = BuildNumber = UINT16_MAX;
+ FeatureVersion = UINT16_MAX;
+ }
+
+ void SetCurrent()
+ {
+ ProductVersion = OVR_PRODUCT_VERSION;
+ MajorVersion = OVR_MAJOR_VERSION;
+ MinorVersion = OVR_MINOR_VERSION;
+ RequestedMinorVersion = OVR_MINOR_VERSION;
+ PatchVersion = OVR_PATCH_VERSION;
+ BuildNumber = OVR_BUILD_NUMBER;
+ FeatureVersion = OVR_FEATURE_VERSION;
+ }
+};
+
+// This is the version that the OVR_CAPI client passes on to the server. It's a global variable
+// because it needs to be initialized in ovr_Initialize but read in the OVR_Session module.
+// This variable exists as a global in the server but it has no meaning.
+extern SDKVersion RuntimeSDKVersion;
+
+
// Client starts communication by sending its version number.
struct RPC_C2S_Hello
{
RPC_C2S_Hello() :
MajorVersion(0),
MinorVersion(0),
- PatchVersion(0)
+ PatchVersion(0),
+ CodeVersion()
{
+ CodeVersion.SetCurrent();
}
String HelloString;
- // Client version info
+ // Client protocol version info
uint16_t MajorVersion, MinorVersion, PatchVersion;
- void Serialize(Net::BitStream* bs)
- {
- bs->Write(HelloString);
- bs->Write(MajorVersion);
- bs->Write(MinorVersion);
- bs->Write(PatchVersion);
- }
-
- bool Deserialize(Net::BitStream* bs)
- {
- bs->Read(HelloString);
- bs->Read(MajorVersion);
- bs->Read(MinorVersion);
- return bs->Read(PatchVersion);
- }
-
- static void Generate(Net::BitStream* bs);
+ // Client runtime code version info
+ SDKVersion CodeVersion;
- bool Validate();
+ bool Serialize(bool writeToBitstream, Net::BitStream* bs);
+ static void ClientGenerate(Net::BitStream* bs);
+ bool ServerValidate();
};
// Server responds with an authorization accepted message, including the server's version number
@@ -95,8 +133,10 @@ struct RPC_S2C_Authorization
RPC_S2C_Authorization() :
MajorVersion(0),
MinorVersion(0),
- PatchVersion(0)
+ PatchVersion(0),
+ CodeVersion()
{
+ CodeVersion.SetCurrent();
}
String AuthString;
@@ -104,25 +144,13 @@ struct RPC_S2C_Authorization
// Server version info
uint16_t MajorVersion, MinorVersion, PatchVersion;
- void Serialize(Net::BitStream* bs)
- {
- bs->Write(AuthString);
- bs->Write(MajorVersion);
- bs->Write(MinorVersion);
- bs->Write(PatchVersion);
- }
+ // The SDK version that the server was built with.
+ // There's no concept of the server requesting an SDK version like the client does.
+ SDKVersion CodeVersion;
- bool Deserialize(Net::BitStream* bs)
- {
- bs->Read(AuthString);
- bs->Read(MajorVersion);
- bs->Read(MinorVersion);
- return bs->Read(PatchVersion);
- }
-
- static void Generate(Net::BitStream* bs, String errorString = "");
-
- bool Validate();
+ bool Serialize(bool writeToBitstream, Net::BitStream* bs);
+ static void ServerGenerate(Net::BitStream* bs, String errorString = "");
+ bool ClientValidate();
};
@@ -130,10 +158,10 @@ struct RPC_S2C_Authorization
// Result of a session function
enum SessionResult
{
- SessionResult_OK,
- SessionResult_BindFailure,
- SessionResult_ListenFailure,
- SessionResult_ConnectFailure,
+ SessionResult_OK,
+ SessionResult_BindFailure,
+ SessionResult_ListenFailure,
+ SessionResult_ConnectFailure,
SessionResult_ConnectInProgress,
SessionResult_AlreadyConnected,
};
@@ -166,10 +194,11 @@ public:
State(State_Zombie),
RemoteMajorVersion(0),
RemoteMinorVersion(0),
- RemotePatchVersion(0)
+ RemotePatchVersion(0),
+ RemoteCodeVersion()
{
}
- virtual ~Connection() // Allow delete from base
+ virtual ~Connection() // Allow delete from base
{
}
@@ -180,9 +209,10 @@ public:
EConnectionState State;
// Version number read from remote host just before connection completes
- int RemoteMajorVersion;
+ int RemoteMajorVersion; // RPC version
int RemoteMinorVersion;
int RemotePatchVersion;
+ SDKVersion RemoteCodeVersion;
};
@@ -192,42 +222,44 @@ class NetworkConnection : public Connection
{
protected:
NetworkConnection()
- {
- }
+ {
+ }
virtual ~NetworkConnection()
{
}
public:
- virtual void SetState(EConnectionState s)
+ // Thread-safe interface to set or wait on a connection state change.
+ // All modifications of the connection state should go through this function,
+ // on the client side.
+ void SetState(EConnectionState s)
{
+ Mutex::Locker locker(&StateMutex);
+
if (s != State)
{
- Mutex::Locker locker(&StateMutex);
+ State = s;
- if (s != State)
+ if (State != Client_Connecting &&
+ State != Client_ConnectedWait)
{
- State = s;
-
- if (State != Client_Connecting)
- {
- ConnectingWait.NotifyAll();
- }
+ ConnectingWait.NotifyAll();
}
}
}
+ // Call this function to wait for the state to change to a connected state.
void WaitOnConnecting()
{
Mutex::Locker locker(&StateMutex);
- while (State == Client_Connecting)
+ while (State == Client_Connecting || State == Client_ConnectedWait)
{
ConnectingWait.Wait(&StateMutex);
}
}
- SockAddr Address;
+ SockAddr Address;
Mutex StateMutex;
WaitCondition ConnectingWait;
};
@@ -246,7 +278,7 @@ public:
}
public:
- Ptr<TCPSocket> pSocket;
+ Ptr<TCPSocket> pSocket;
};
@@ -255,7 +287,7 @@ public:
class PacketizedTCPConnection : public TCPConnection
{
public:
- PacketizedTCPConnection()
+ PacketizedTCPConnection()
{
Transport = TransportType_PacketizedTCP;
}
@@ -284,16 +316,16 @@ public:
class BerkleyListenerDescription : public ListenerDescription
{
public:
- static const int DefaultMaxIncomingConnections = 64;
- static const int DefaultMaxConnections = 128;
+ static const int DefaultMaxIncomingConnections = 64;
+ static const int DefaultMaxConnections = 128;
- BerkleyListenerDescription() :
- MaxIncomingConnections(DefaultMaxIncomingConnections),
- MaxConnections(DefaultMaxConnections)
- {
- }
+ BerkleyListenerDescription() :
+ MaxIncomingConnections(DefaultMaxIncomingConnections),
+ MaxConnections(DefaultMaxConnections)
+ {
+ }
- Ptr<BerkleySocket> BoundSocketToListenWith;
+ Ptr<BerkleySocket> BoundSocketToListenWith;
int MaxIncomingConnections;
int MaxConnections;
};
@@ -303,9 +335,9 @@ public:
// Receive payload
struct ReceivePayload
{
- Connection* pConnection; // Source connection
- uint8_t* pData; // Pointer to data received
- int Bytes; // Number of bytes of data received
+ Connection* pConnection; // Source connection
+ uint8_t* pData; // Pointer to data received
+ int Bytes; // Number of bytes of data received
};
//-----------------------------------------------------------------------------
@@ -335,22 +367,22 @@ public:
class SendParameters
{
public:
- SendParameters() :
- pData(NULL),
- Bytes(0)
- {
- }
- SendParameters(Ptr<Connection> _pConnection, const void* _pData, int _bytes) :
- pConnection(_pConnection),
- pData(_pData),
- Bytes(_bytes)
- {
- }
+ SendParameters() :
+ pData(NULL),
+ Bytes(0)
+ {
+ }
+ SendParameters(Ptr<Connection> _pConnection, const void* _pData, int _bytes) :
+ pConnection(_pConnection),
+ pData(_pData),
+ Bytes(_bytes)
+ {
+ }
public:
- Ptr<Connection> pConnection; // Connection to use
- const void* pData; // Pointer to data to send
- int Bytes; // Number of bytes of data received
+ Ptr<Connection> pConnection; // Connection to use
+ const void* pData; // Pointer to data to send
+ int Bytes; // Number of bytes of data received
};
@@ -359,18 +391,18 @@ public:
struct ConnectParameters
{
public:
- ConnectParameters() :
- Transport(TransportType_None)
- {
- }
+ ConnectParameters() :
+ Transport(TransportType_None)
+ {
+ }
- TransportType Transport;
+ TransportType Transport;
};
struct ConnectParametersBerkleySocket : public ConnectParameters
{
- SockAddr RemoteAddress;
- Ptr<BerkleySocket> BoundSocketToConnectWith;
+ SockAddr RemoteAddress;
+ Ptr<BerkleySocket> BoundSocketToConnectWith;
bool Blocking;
ConnectParametersBerkleySocket(BerkleySocket* s, SockAddr* addr, bool blocking,
@@ -388,11 +420,11 @@ struct ConnectParametersBerkleySocket : public ConnectParameters
// Listener receive result
enum ListenerReceiveResult
{
- /// The SessionListener used this message and it shouldn't be given to the user.
- LRR_RETURN = 0,
+ /// The SessionListener used this message and it shouldn't be given to the user.
+ LRR_RETURN = 0,
- /// The SessionListener is going to hold on to this message. Do not deallocate it but do not pass it to other plugins either.
- LRR_BREAK,
+ /// The SessionListener is going to hold on to this message. Do not deallocate it but do not pass it to other plugins either.
+ LRR_BREAK,
/// This message will be processed by other SessionListeners, and at last by the user.
LRR_CONTINUE,
@@ -406,15 +438,15 @@ enum ListenerReceiveResult
class SessionListener
{
public:
- virtual ~SessionListener(){}
+ virtual ~SessionListener(){}
- // Data events
+ // Data events
virtual void OnReceive(ReceivePayload* pPayload, ListenerReceiveResult* lrrOut) { OVR_UNUSED2(pPayload, lrrOut); }
- // Connection was closed
+ // Connection was closed
virtual void OnDisconnected(Connection* conn) = 0;
- // Connection was created (some data was exchanged to verify protocol compatibility too)
+ // Connection was created (some data was exchanged to verify protocol compatibility too)
virtual void OnConnected(Connection* conn) = 0;
// Server accepted client
@@ -430,7 +462,7 @@ public:
// Disconnected during initial handshake
virtual void OnHandshakeAttemptFailed(Connection* conn) { OnConnectionAttemptFailed(conn); }
- // Other
+ // Other
virtual void OnAddedToSession(Session* session) { OVR_UNUSED(session); }
virtual void OnRemovedFromSession(Session* session) { OVR_UNUSED(session); }
};
@@ -442,32 +474,27 @@ public:
// Interface for network events such as listening on a socket, sending data, connecting, and disconnecting. Works independently of the transport medium and also implements loopback
class Session : public SocketEvent_TCP, public NewOverrideBase
{
- // Implement a policy to avoid releasing memory backing allBlockingTcpSockets
- struct ArrayNoShrinkPolicy : ArrayDefaultPolicy
- {
- bool NeverShrinking() const { return 1; }
- };
-
public:
Session() :
- HasLoopbackListener(false)
+ HaveFullConnections(false)
{
}
virtual ~Session()
{
// Ensure memory backing the sockets array is released
- allBlockingTcpSockets.ClearAndRelease();
+ AllBlockingTcpSockets.ClearAndRelease();
}
- virtual SessionResult Listen(ListenerDescription* pListenerDescription);
- virtual SessionResult Connect(ConnectParameters* cp);
- virtual int Send(SendParameters* payload);
+ virtual SessionResult Listen(ListenerDescription* pListenerDescription);
+ virtual SessionResult Connect(ConnectParameters* cp);
+ virtual int Send(SendParameters* payload);
virtual void Broadcast(BroadcastParameters* payload);
- // DO NOT CALL Poll() FROM MULTIPLE THREADS due to allBlockingTcpSockets being a member
+ // DO NOT CALL Poll() FROM MULTIPLE THREADS due to AllBlockingTcpSockets being a member
virtual void Poll(bool listeners = true);
- virtual void AddSessionListener(SessionListener* se);
- virtual void RemoveSessionListener(SessionListener* se);
- virtual SInt32 GetActiveSocketsCount();
+ virtual void AddSessionListener(SessionListener* se);
+ virtual void RemoveSessionListener(SessionListener* se);
+ // GetActiveSocketsCount() is not thread-safe: Socket count may change at any time.
+ virtual int GetActiveSocketsCount();
// Packetized TCP convenience functions
virtual SessionResult ListenPTCP(BerkleyBindParameters* bbp);
@@ -476,7 +503,15 @@ public:
// Closes all the sockets; useful for interrupting the socket polling during shutdown
void Shutdown();
+ // Returns true if there is at least one successful connection
+ // WARNING: This function may not be in sync across threads, but it IS atomic
+ bool ConnectionSuccessful() const
+ {
+ return HaveFullConnections.load(std::memory_order_relaxed);
+ }
+
// Get count of successful connections (past handshake point)
+ // WARNING: This function is not thread-safe
int GetConnectionCount() const
{
return FullConnections.GetSizeI();
@@ -484,15 +519,16 @@ public:
Ptr<Connection> GetConnectionAtIndex(int index);
protected:
- virtual Ptr<Connection> AllocConnection(TransportType transportType);
+ virtual Ptr<Connection> AllocConnection(TransportType transportType);
Lock SocketListenersLock, ConnectionsLock, SessionListenersLock;
- bool HasLoopbackListener; // Has loopback listener installed?
- Array< Ptr<TCPSocket> > SocketListeners; // List of active sockets
+ Array< Ptr<TCPSocket> > SocketListeners; // List of active sockets
Array< Ptr<Connection> > AllConnections; // List of active connections stuck at the versioning handshake
Array< Ptr<Connection> > FullConnections; // List of active connections past the versioning handshake
Array< SessionListener* > SessionListeners; // List of session listeners
- Array< Ptr< Net::TCPSocket >, ArrayNoShrinkPolicy > allBlockingTcpSockets; // Preallocated blocking sockets array
+ Array< Ptr< Net::TCPSocket > > AllBlockingTcpSockets; // Preallocated blocking sockets array
+
+ std::atomic<bool> HaveFullConnections;
// Tools
Ptr<PacketizedTCPConnection> findConnectionBySocket(Array< Ptr<Connection> >& connectionArray, Socket* s, int *connectionIndex = NULL); // Call with ConnectionsLock held
@@ -500,11 +536,18 @@ protected:
int invokeSessionListeners(ReceivePayload*);
void invokeSessionEvent(void(SessionListener::*f)(Connection*), Connection* pConnection);
- // TCP
- virtual void TCP_OnRecv(Socket* pSocket, uint8_t* pData, int bytesRead);
- virtual void TCP_OnClosed(TCPSocket* pSocket);
- virtual void TCP_OnAccept(TCPSocket* pListener, SockAddr* pSockAddr, SocketHandle newSock);
- virtual void TCP_OnConnected(TCPSocket* pSocket);
+ // TCP
+ virtual void TCP_OnRecv(Socket* pSocket, uint8_t* pData, int bytesRead);
+ virtual void TCP_OnClosed(TCPSocket* pSocket);
+ virtual void TCP_OnAccept(TCPSocket* pListener, SockAddr* pSockAddr, SocketHandle newSock);
+ virtual void TCP_OnConnected(TCPSocket* pSocket);
+
+public:
+ static void SetSingleProcess(bool enable);
+ static bool IsSingleProcess();
+
+protected:
+ Session* SingleTargetSession; // Target for SingleProcess mode
};