ovr_sdk

diff LibOVR/Src/Net/OVR_Session.h @ 0:1b39a1b46319

initial 0.4.4
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 14 Jan 2015 06:51:16 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/LibOVR/Src/Net/OVR_Session.h	Wed Jan 14 06:51:16 2015 +0200
     1.3 @@ -0,0 +1,513 @@
     1.4 +/************************************************************************************
     1.5 +
     1.6 +PublicHeader:   n/a
     1.7 +Filename    :   OVR_Session.h
     1.8 +Content     :   One network session that provides connection/disconnection events.
     1.9 +Created     :   June 10, 2014
    1.10 +Authors     :   Kevin Jenkins, Chris Taylor
    1.11 +
    1.12 +Copyright   :   Copyright 2014 Oculus VR, LLC All Rights reserved.
    1.13 +
    1.14 +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); 
    1.15 +you may not use the Oculus VR Rift SDK except in compliance with the License, 
    1.16 +which is provided at the time of installation or download, or which 
    1.17 +otherwise accompanies this software in either electronic or hard copy form.
    1.18 +
    1.19 +You may obtain a copy of the License at
    1.20 +
    1.21 +http://www.oculusvr.com/licenses/LICENSE-3.2 
    1.22 +
    1.23 +Unless required by applicable law or agreed to in writing, the Oculus VR SDK 
    1.24 +distributed under the License is distributed on an "AS IS" BASIS,
    1.25 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1.26 +See the License for the specific language governing permissions and
    1.27 +limitations under the License.
    1.28 +
    1.29 +************************************************************************************/
    1.30 +
    1.31 +#ifndef OVR_Session_h
    1.32 +#define OVR_Session_h
    1.33 +
    1.34 +#include "OVR_Socket.h"
    1.35 +#include "OVR_PacketizedTCPSocket.h"
    1.36 +#include "../Kernel/OVR_Array.h"
    1.37 +#include "../Kernel/OVR_Threads.h"
    1.38 +#include "../Kernel/OVR_Atomic.h"
    1.39 +#include "../Kernel/OVR_RefCount.h"
    1.40 +
    1.41 +namespace OVR { namespace Net {
    1.42 +
    1.43 +class Session;
    1.44 +
    1.45 +
    1.46 +//-----------------------------------------------------------------------------
    1.47 +// Based on Semantic Versioning ( http://semver.org/ )
    1.48 +//
    1.49 +// Please update changelog below:
    1.50 +// 1.0.0 - [SDK 0.4.0] Initial version (July 21, 2014)
    1.51 +// 1.1.0 - Add Get/SetDriverMode_1, HMDCountUpdate_1
    1.52 +//         Version mismatch results (July 28, 2014)
    1.53 +//-----------------------------------------------------------------------------
    1.54 +
    1.55 +static const uint16_t RPCVersion_Major = 1; // MAJOR version when you make incompatible API changes,
    1.56 +static const uint16_t RPCVersion_Minor = 2; // MINOR version when you add functionality in a backwards-compatible manner, and
    1.57 +static const uint16_t RPCVersion_Patch = 0; // PATCH version when you make backwards-compatible bug fixes.
    1.58 +
    1.59 +// Client starts communication by sending its version number.
    1.60 +struct RPC_C2S_Hello
    1.61 +{
    1.62 +    RPC_C2S_Hello() :
    1.63 +        MajorVersion(0),
    1.64 +        MinorVersion(0),
    1.65 +        PatchVersion(0)
    1.66 +    {
    1.67 +    }
    1.68 +
    1.69 +    String HelloString;
    1.70 +
    1.71 +    // Client version info
    1.72 +    uint16_t MajorVersion, MinorVersion, PatchVersion;
    1.73 +
    1.74 +    void Serialize(Net::BitStream* bs)
    1.75 +    {
    1.76 +        bs->Write(HelloString);
    1.77 +        bs->Write(MajorVersion);
    1.78 +        bs->Write(MinorVersion);
    1.79 +        bs->Write(PatchVersion);
    1.80 +    }
    1.81 +
    1.82 +    bool Deserialize(Net::BitStream* bs)
    1.83 +    {
    1.84 +        bs->Read(HelloString);
    1.85 +        bs->Read(MajorVersion);
    1.86 +        bs->Read(MinorVersion);
    1.87 +        return bs->Read(PatchVersion);
    1.88 +    }
    1.89 +
    1.90 +    static void Generate(Net::BitStream* bs);
    1.91 +
    1.92 +    bool Validate();
    1.93 +};
    1.94 +
    1.95 +// Server responds with an authorization accepted message, including the server's version number
    1.96 +struct RPC_S2C_Authorization
    1.97 +{
    1.98 +    RPC_S2C_Authorization() :
    1.99 +        MajorVersion(0),
   1.100 +        MinorVersion(0),
   1.101 +        PatchVersion(0)
   1.102 +    {
   1.103 +    }
   1.104 +
   1.105 +    String AuthString;
   1.106 +
   1.107 +    // Server version info
   1.108 +    uint16_t MajorVersion, MinorVersion, PatchVersion;
   1.109 +
   1.110 +    void Serialize(Net::BitStream* bs)
   1.111 +    {
   1.112 +        bs->Write(AuthString);
   1.113 +        bs->Write(MajorVersion);
   1.114 +        bs->Write(MinorVersion);
   1.115 +        bs->Write(PatchVersion);
   1.116 +    }
   1.117 +
   1.118 +    bool Deserialize(Net::BitStream* bs)
   1.119 +    {
   1.120 +        bs->Read(AuthString);
   1.121 +        bs->Read(MajorVersion);
   1.122 +        bs->Read(MinorVersion);
   1.123 +        return bs->Read(PatchVersion);
   1.124 +    }
   1.125 +
   1.126 +    static void Generate(Net::BitStream* bs, String errorString = "");
   1.127 +
   1.128 +    bool Validate();
   1.129 +};
   1.130 +
   1.131 +
   1.132 +//-----------------------------------------------------------------------------
   1.133 +// Result of a session function
   1.134 +enum SessionResult
   1.135 +{
   1.136 +	SessionResult_OK,
   1.137 +	SessionResult_BindFailure,
   1.138 +	SessionResult_ListenFailure,
   1.139 +	SessionResult_ConnectFailure,
   1.140 +    SessionResult_ConnectInProgress,
   1.141 +    SessionResult_AlreadyConnected,
   1.142 +};
   1.143 +
   1.144 +
   1.145 +//-----------------------------------------------------------------------------
   1.146 +// Connection state
   1.147 +enum EConnectionState
   1.148 +{
   1.149 +    State_Zombie,          // Disconnected
   1.150 +
   1.151 +    // Client-only:
   1.152 +    Client_Connecting,     // Waiting for TCP connection
   1.153 +    Client_ConnectedWait,  // Connected! Waiting for server to authorize
   1.154 +
   1.155 +    // Server-only:
   1.156 +    Server_ConnectedWait,  // Connected! Waiting for client handshake
   1.157 +
   1.158 +    State_Connected        // Connected
   1.159 +};
   1.160 +
   1.161 +
   1.162 +//-----------------------------------------------------------------------------
   1.163 +// Generic connection over any transport
   1.164 +class Connection : public RefCountBase<Connection>
   1.165 +{
   1.166 +public:
   1.167 +    Connection() :
   1.168 +        Transport(TransportType_None),
   1.169 +        State(State_Zombie),
   1.170 +        RemoteMajorVersion(0),
   1.171 +        RemoteMinorVersion(0),
   1.172 +        RemotePatchVersion(0)
   1.173 +    {
   1.174 +    }
   1.175 +	virtual ~Connection() // Allow delete from base
   1.176 +    {
   1.177 +    }
   1.178 +
   1.179 +public:
   1.180 +    virtual void SetState(EConnectionState s) {State = s;}
   1.181 +
   1.182 +    TransportType    Transport;
   1.183 +    EConnectionState State;
   1.184 +
   1.185 +    // Version number read from remote host just before connection completes
   1.186 +    int              RemoteMajorVersion;
   1.187 +    int              RemoteMinorVersion;
   1.188 +    int              RemotePatchVersion;
   1.189 +};
   1.190 +
   1.191 +
   1.192 +//-----------------------------------------------------------------------------
   1.193 +// Generic network connection over any network transport
   1.194 +class NetworkConnection : public Connection
   1.195 +{
   1.196 +protected:
   1.197 +    NetworkConnection()
   1.198 +	{
   1.199 +	}
   1.200 +    virtual ~NetworkConnection()
   1.201 +    {
   1.202 +    }
   1.203 +
   1.204 +public:
   1.205 +    virtual void SetState(EConnectionState s)
   1.206 +    {
   1.207 +        if (s != State)
   1.208 +        {
   1.209 +            Mutex::Locker locker(&StateMutex);
   1.210 +
   1.211 +            if (s != State)
   1.212 +            {
   1.213 +                State = s;
   1.214 +
   1.215 +                if (State != Client_Connecting)
   1.216 +                {
   1.217 +                    ConnectingWait.NotifyAll();
   1.218 +                }
   1.219 +            }
   1.220 +        }
   1.221 +    }
   1.222 +
   1.223 +    void WaitOnConnecting()
   1.224 +    {
   1.225 +        Mutex::Locker locker(&StateMutex);
   1.226 +
   1.227 +        while (State == Client_Connecting)
   1.228 +        {
   1.229 +            ConnectingWait.Wait(&StateMutex);
   1.230 +        }
   1.231 +    }
   1.232 +
   1.233 +	SockAddr      Address;
   1.234 +    Mutex         StateMutex;
   1.235 +    WaitCondition ConnectingWait;
   1.236 +};
   1.237 +
   1.238 +
   1.239 +//-----------------------------------------------------------------------------
   1.240 +// TCP Connection
   1.241 +class TCPConnection : public NetworkConnection
   1.242 +{
   1.243 +public:
   1.244 +    TCPConnection()
   1.245 +    {
   1.246 +    }
   1.247 +    virtual ~TCPConnection()
   1.248 +    {
   1.249 +    }
   1.250 +
   1.251 +public:
   1.252 +	Ptr<TCPSocket> pSocket;
   1.253 +};
   1.254 +
   1.255 +
   1.256 +//-----------------------------------------------------------------------------
   1.257 +// Packetized TCP Connection
   1.258 +class PacketizedTCPConnection : public TCPConnection
   1.259 +{
   1.260 +public:
   1.261 +	PacketizedTCPConnection()
   1.262 +    {
   1.263 +        Transport = TransportType_PacketizedTCP;
   1.264 +    }
   1.265 +    virtual ~PacketizedTCPConnection()
   1.266 +    {
   1.267 +    }
   1.268 +};
   1.269 +
   1.270 +
   1.271 +//-----------------------------------------------------------------------------
   1.272 +// Generic socket listener description
   1.273 +class ListenerDescription
   1.274 +{
   1.275 +public:
   1.276 +    ListenerDescription() :
   1.277 +        Transport(TransportType_None)
   1.278 +    {
   1.279 +    }
   1.280 +
   1.281 +    TransportType Transport;
   1.282 +};
   1.283 +
   1.284 +
   1.285 +//-----------------------------------------------------------------------------
   1.286 +// Description for a Berkley socket listener
   1.287 +class BerkleyListenerDescription : public ListenerDescription
   1.288 +{
   1.289 +public:
   1.290 +	static const int DefaultMaxIncomingConnections =  64;
   1.291 +	static const int DefaultMaxConnections         = 128;
   1.292 +
   1.293 +	BerkleyListenerDescription() :
   1.294 +		MaxIncomingConnections(DefaultMaxIncomingConnections),
   1.295 +		MaxConnections(DefaultMaxConnections)
   1.296 +	{
   1.297 +	}
   1.298 +
   1.299 +	Ptr<BerkleySocket> BoundSocketToListenWith;
   1.300 +    int                MaxIncomingConnections;
   1.301 +    int                MaxConnections;
   1.302 +};
   1.303 +
   1.304 +
   1.305 +//-----------------------------------------------------------------------------
   1.306 +// Receive payload
   1.307 +struct ReceivePayload
   1.308 +{
   1.309 +	Connection* pConnection; // Source connection
   1.310 +	uint8_t*    pData;       // Pointer to data received
   1.311 +	int         Bytes;       // Number of bytes of data received
   1.312 +};
   1.313 +
   1.314 +//-----------------------------------------------------------------------------
   1.315 +// Broadcast parameters
   1.316 +class BroadcastParameters
   1.317 +{
   1.318 +public:
   1.319 +    BroadcastParameters() :
   1.320 +        pData(NULL),
   1.321 +        Bytes(0)
   1.322 +    {
   1.323 +    }
   1.324 +
   1.325 +    BroadcastParameters(const void* _pData, int _bytes) :
   1.326 +        pData(_pData),
   1.327 +        Bytes(_bytes)
   1.328 +    {
   1.329 +    }
   1.330 +
   1.331 +public:
   1.332 +    const void*     pData;       // Pointer to data to send
   1.333 +    int             Bytes;       // Number of bytes of data received
   1.334 +};
   1.335 +
   1.336 +//-----------------------------------------------------------------------------
   1.337 +// Send parameters
   1.338 +class SendParameters
   1.339 +{
   1.340 +public:
   1.341 +	SendParameters() :
   1.342 +		pData(NULL),
   1.343 +		Bytes(0)
   1.344 +	{
   1.345 +	}
   1.346 +	SendParameters(Ptr<Connection> _pConnection, const void* _pData, int _bytes) :
   1.347 +		pConnection(_pConnection),
   1.348 +		pData(_pData),
   1.349 +		Bytes(_bytes)
   1.350 +	{
   1.351 +	}
   1.352 +
   1.353 +public:
   1.354 +	Ptr<Connection> pConnection; // Connection to use
   1.355 +	const void*     pData;       // Pointer to data to send
   1.356 +	int             Bytes;       // Number of bytes of data received
   1.357 +};
   1.358 +
   1.359 +
   1.360 +//-----------------------------------------------------------------------------
   1.361 +// Parameters to connect
   1.362 +struct ConnectParameters
   1.363 +{
   1.364 +public:
   1.365 +	ConnectParameters() :
   1.366 +		Transport(TransportType_None)
   1.367 +	{
   1.368 +	}
   1.369 +
   1.370 +	TransportType Transport;
   1.371 +};
   1.372 +
   1.373 +struct ConnectParametersBerkleySocket : public ConnectParameters
   1.374 +{
   1.375 +	SockAddr           RemoteAddress;
   1.376 +	Ptr<BerkleySocket> BoundSocketToConnectWith;
   1.377 +    bool               Blocking;
   1.378 +
   1.379 +    ConnectParametersBerkleySocket(BerkleySocket* s, SockAddr* addr, bool blocking,
   1.380 +                                   TransportType transport) :
   1.381 +        RemoteAddress(*addr),
   1.382 +        BoundSocketToConnectWith(s),
   1.383 +        Blocking(blocking)
   1.384 +    {
   1.385 +        Transport = transport;
   1.386 +    }
   1.387 +};
   1.388 +
   1.389 +
   1.390 +//-----------------------------------------------------------------------------
   1.391 +// Listener receive result
   1.392 +enum ListenerReceiveResult
   1.393 +{
   1.394 +	/// The SessionListener used this message and it shouldn't be given to the user.
   1.395 +	LRR_RETURN = 0,
   1.396 +
   1.397 +	/// The SessionListener is going to hold on to this message.  Do not deallocate it but do not pass it to other plugins either.
   1.398 +	LRR_BREAK,
   1.399 +
   1.400 +    /// This message will be processed by other SessionListeners, and at last by the user.
   1.401 +    LRR_CONTINUE,
   1.402 +};
   1.403 +
   1.404 +
   1.405 +//-----------------------------------------------------------------------------
   1.406 +// SessionListener
   1.407 +
   1.408 +// Callback interface for network events such as connecting, disconnecting, getting data, independent of the transport medium
   1.409 +class SessionListener
   1.410 +{
   1.411 +public:
   1.412 +	virtual ~SessionListener(){}
   1.413 +
   1.414 +	// Data events
   1.415 +    virtual void OnReceive(ReceivePayload* pPayload, ListenerReceiveResult* lrrOut) { OVR_UNUSED2(pPayload, lrrOut);  }
   1.416 +
   1.417 +	// Connection was closed
   1.418 +    virtual void OnDisconnected(Connection* conn) = 0;
   1.419 +
   1.420 +	// Connection was created (some data was exchanged to verify protocol compatibility too)
   1.421 +    virtual void OnConnected(Connection* conn) = 0;
   1.422 +
   1.423 +    // Server accepted client
   1.424 +    virtual void OnNewIncomingConnection(Connection* conn)     { OnConnected(conn); }
   1.425 +    // Client was accepted
   1.426 +    virtual void OnConnectionRequestAccepted(Connection* conn) { OnConnected(conn); }
   1.427 +
   1.428 +    // Connection attempt failed for some reason
   1.429 +    virtual void OnConnectionAttemptFailed(Connection* conn)   { OnDisconnected(conn); }
   1.430 +
   1.431 +    // Incompatible protocol
   1.432 +    virtual void OnIncompatibleProtocol(Connection* conn)      { OnConnectionAttemptFailed(conn); }
   1.433 +    // Disconnected during initial handshake
   1.434 +    virtual void OnHandshakeAttemptFailed(Connection* conn)    { OnConnectionAttemptFailed(conn); }
   1.435 +
   1.436 +	// Other
   1.437 +    virtual void OnAddedToSession(Session* session)            { OVR_UNUSED(session); }
   1.438 +    virtual void OnRemovedFromSession(Session* session)        { OVR_UNUSED(session); }
   1.439 +};
   1.440 +
   1.441 +
   1.442 +//-----------------------------------------------------------------------------
   1.443 +// Session
   1.444 +
   1.445 +//  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
   1.446 +class Session : public SocketEvent_TCP, public NewOverrideBase
   1.447 +{
   1.448 +    // Implement a policy to avoid releasing memory backing allBlockingTcpSockets
   1.449 +	struct ArrayNoShrinkPolicy : ArrayDefaultPolicy
   1.450 +	{
   1.451 +		bool NeverShrinking() const { return 1; }
   1.452 +	};
   1.453 +
   1.454 +public:
   1.455 +    Session() :
   1.456 +        HasLoopbackListener(false)
   1.457 +    {
   1.458 +    }
   1.459 +    virtual ~Session()
   1.460 +    {
   1.461 +        // Ensure memory backing the sockets array is released
   1.462 +		allBlockingTcpSockets.ClearAndRelease();
   1.463 +    }
   1.464 +
   1.465 +	virtual SessionResult Listen(ListenerDescription* pListenerDescription);
   1.466 +	virtual SessionResult Connect(ConnectParameters* cp);
   1.467 +	virtual int           Send(SendParameters* payload);
   1.468 +    virtual void          Broadcast(BroadcastParameters* payload);
   1.469 +    // DO NOT CALL Poll() FROM MULTIPLE THREADS due to allBlockingTcpSockets being a member
   1.470 +    virtual void          Poll(bool listeners = true);
   1.471 +	virtual void          AddSessionListener(SessionListener* se);
   1.472 +	virtual void          RemoveSessionListener(SessionListener* se);
   1.473 +    virtual SInt32        GetActiveSocketsCount();
   1.474 +
   1.475 +    // Packetized TCP convenience functions
   1.476 +    virtual SessionResult ListenPTCP(BerkleyBindParameters* bbp);
   1.477 +    virtual SessionResult ConnectPTCP(BerkleyBindParameters* bbp, SockAddr* RemoteAddress, bool blocking);
   1.478 +
   1.479 +    // Closes all the sockets; useful for interrupting the socket polling during shutdown
   1.480 +    void            Shutdown();
   1.481 +
   1.482 +    // Get count of successful connections (past handshake point)
   1.483 +    int             GetConnectionCount() const
   1.484 +    {
   1.485 +        return FullConnections.GetSizeI();
   1.486 +    }
   1.487 +    Ptr<Connection> GetConnectionAtIndex(int index);
   1.488 +
   1.489 +protected:
   1.490 +	virtual Ptr<Connection> AllocConnection(TransportType transportType);
   1.491 +
   1.492 +    Lock SocketListenersLock, ConnectionsLock, SessionListenersLock;
   1.493 +    bool                      HasLoopbackListener; // Has loopback listener installed?
   1.494 +	Array< Ptr<TCPSocket> >   SocketListeners;     // List of active sockets
   1.495 +    Array< Ptr<Connection> >  AllConnections;      // List of active connections stuck at the versioning handshake
   1.496 +    Array< Ptr<Connection> >  FullConnections;     // List of active connections past the versioning handshake
   1.497 +    Array< SessionListener* > SessionListeners;    // List of session listeners
   1.498 +    Array< Ptr< Net::TCPSocket >, ArrayNoShrinkPolicy > allBlockingTcpSockets; // Preallocated blocking sockets array
   1.499 +
   1.500 +    // Tools
   1.501 +    Ptr<PacketizedTCPConnection> findConnectionBySocket(Array< Ptr<Connection> >& connectionArray, Socket* s, int *connectionIndex = NULL); // Call with ConnectionsLock held
   1.502 +    Ptr<PacketizedTCPConnection> findConnectionBySockAddr(SockAddr* address); // Call with ConnectionsLock held
   1.503 +    int                   invokeSessionListeners(ReceivePayload*);
   1.504 +    void                  invokeSessionEvent(void(SessionListener::*f)(Connection*), Connection* pConnection);
   1.505 +
   1.506 +	// TCP
   1.507 +	virtual void          TCP_OnRecv(Socket* pSocket, uint8_t* pData, int bytesRead);
   1.508 +	virtual void          TCP_OnClosed(TCPSocket* pSocket);
   1.509 +	virtual void          TCP_OnAccept(TCPSocket* pListener, SockAddr* pSockAddr, SocketHandle newSock);
   1.510 +	virtual void          TCP_OnConnected(TCPSocket* pSocket);
   1.511 +};
   1.512 +
   1.513 +
   1.514 +}} // OVR::Net
   1.515 +
   1.516 +#endif