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