nuclear@0: /************************************************************************************ nuclear@0: nuclear@0: Filename : Service_NetClient.cpp nuclear@0: Content : Client for service interface nuclear@0: Created : June 12, 2014 nuclear@0: Authors : Michael Antonov, Kevin Jenkins, Chris Taylor nuclear@0: nuclear@0: Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. nuclear@0: nuclear@0: Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); nuclear@0: you may not use the Oculus VR Rift SDK except in compliance with the License, nuclear@0: which is provided at the time of installation or download, or which nuclear@0: otherwise accompanies this software in either electronic or hard copy form. nuclear@0: nuclear@0: You may obtain a copy of the License at nuclear@0: nuclear@0: http://www.oculusvr.com/licenses/LICENSE-3.2 nuclear@0: nuclear@0: Unless required by applicable law or agreed to in writing, the Oculus VR SDK nuclear@0: distributed under the License is distributed on an "AS IS" BASIS, nuclear@0: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. nuclear@0: See the License for the specific language governing permissions and nuclear@0: limitations under the License. nuclear@0: nuclear@0: ************************************************************************************/ nuclear@0: nuclear@0: #include "Service_NetClient.h" nuclear@0: #include "../Net/OVR_MessageIDTypes.h" nuclear@0: nuclear@0: #if defined (OVR_OS_MAC) || defined(OVR_OS_LINUX) nuclear@0: #define GetCurrentProcessId getpid nuclear@0: #endif nuclear@0: OVR_DEFINE_SINGLETON(OVR::Service::NetClient); nuclear@0: nuclear@0: namespace OVR { namespace Service { nuclear@0: nuclear@0: using namespace OVR::Net; nuclear@0: nuclear@0: nuclear@0: //// NetClient nuclear@0: nuclear@0: NetClient::NetClient() : nuclear@0: LatencyTesterAvailable(false), nuclear@0: HMDCount(0), nuclear@0: EdgeTriggeredHMDCount(false) nuclear@0: { nuclear@0: GetSession()->AddSessionListener(this); nuclear@0: nuclear@0: // Register RPC functions nuclear@0: registerRPC(); nuclear@0: nuclear@0: Start(); nuclear@0: nuclear@0: // Must be at end of function nuclear@0: PushDestroyCallbacks(); nuclear@0: } nuclear@0: nuclear@0: NetClient::~NetClient() nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: void NetClient::OnSystemDestroy() nuclear@0: { nuclear@0: onSystemDestroy(); nuclear@0: } nuclear@0: nuclear@0: void NetClient::OnThreadDestroy() nuclear@0: { nuclear@0: onThreadDestroy(); nuclear@0: } nuclear@0: nuclear@0: int NetClient::Run() nuclear@0: { nuclear@0: SetThreadName("NetClient"); nuclear@0: nuclear@0: while (!Terminated) nuclear@0: { nuclear@0: // Note: There is no watchdog here because the watchdog is part of the private code nuclear@0: nuclear@0: GetSession()->Poll(false); nuclear@0: nuclear@0: if (GetSession()->GetActiveSocketsCount() == 0) nuclear@0: { nuclear@0: Thread::MSleep(10); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: void NetClient::OnReceive(ReceivePayload* pPayload, ListenerReceiveResult* lrrOut) nuclear@0: { nuclear@0: OVR_UNUSED(lrrOut); nuclear@0: OVR_UNUSED(pPayload); nuclear@0: } nuclear@0: nuclear@0: void NetClient::OnDisconnected(Connection* conn) nuclear@0: { nuclear@0: OVR_UNUSED(conn); nuclear@0: nuclear@0: OVR_DEBUG_LOG(("[NetClient] Disconnected")); nuclear@0: nuclear@0: EdgeTriggeredHMDCount = false; nuclear@0: } nuclear@0: nuclear@0: void NetClient::OnConnected(Connection* conn) nuclear@0: { nuclear@0: OVR_UNUSED(conn); nuclear@0: nuclear@0: OVR_DEBUG_LOG(("[NetClient] Connected to a server running version %d.%d.%d (my version=%d.%d.%d)", nuclear@0: conn->RemoteMajorVersion, conn->RemoteMinorVersion, conn->RemotePatchVersion, nuclear@0: RPCVersion_Major, RPCVersion_Minor, RPCVersion_Patch)); nuclear@0: nuclear@0: EdgeTriggeredHMDCount = false; nuclear@0: } nuclear@0: nuclear@0: bool NetClient::Connect(bool blocking) nuclear@0: { nuclear@0: // Set up bind parameters nuclear@0: OVR::Net::BerkleyBindParameters bbp; nuclear@0: bbp.Address = "::1"; // Bind to localhost only! nuclear@0: bbp.blockingTimeout = 5000; nuclear@0: OVR::Net::SockAddr sa; nuclear@0: sa.Set("::1", VRServicePort, SOCK_STREAM); nuclear@0: nuclear@0: // Attempt to connect nuclear@0: OVR::Net::SessionResult result = GetSession()->ConnectPTCP(&bbp, &sa, blocking); nuclear@0: nuclear@0: // Already connected counts as success too nuclear@0: return result == Net::SessionResult_OK || nuclear@0: result == Net::SessionResult_AlreadyConnected || nuclear@0: result == Net::SessionResult_ConnectInProgress; nuclear@0: } nuclear@0: nuclear@0: void NetClient::Disconnect() nuclear@0: { nuclear@0: GetSession()->Shutdown(); nuclear@0: } nuclear@0: nuclear@0: bool NetClient::IsConnected(bool attemptReconnect, bool blockOnReconnect) nuclear@0: { nuclear@0: // If it was able to connect, nuclear@0: if (GetSession()->GetConnectionCount() > 0) nuclear@0: { nuclear@0: return true; nuclear@0: } nuclear@0: else if (attemptReconnect) nuclear@0: { nuclear@0: // Attempt to connect here nuclear@0: Connect(blockOnReconnect); nuclear@0: nuclear@0: // If it connected, nuclear@0: if (GetSession()->GetConnectionCount() > 0) nuclear@0: { nuclear@0: return true; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: // No connections nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: void NetClient::GetLocalProtocolVersion(int& major, int& minor, int& patch) nuclear@0: { nuclear@0: major = RPCVersion_Major; nuclear@0: minor = RPCVersion_Minor; nuclear@0: patch = RPCVersion_Patch; nuclear@0: } nuclear@0: nuclear@0: bool NetClient::GetRemoteProtocolVersion(int& major, int& minor, int& patch) nuclear@0: { nuclear@0: Ptr conn = GetSession()->GetConnectionAtIndex(0); nuclear@0: nuclear@0: if (conn) nuclear@0: { nuclear@0: major = conn->RemoteMajorVersion; nuclear@0: minor = conn->RemoteMinorVersion; nuclear@0: patch = conn->RemotePatchVersion; nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: //// NetClient API nuclear@0: nuclear@0: const char* NetClient::GetStringValue(VirtualHmdId hmd, const char* key, const char* default_val) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return ""; nuclear@0: } nuclear@0: nuclear@0: // If a null value is provided, nuclear@0: if (!default_val) nuclear@0: { nuclear@0: default_val = ""; nuclear@0: } nuclear@0: nuclear@0: ProfileGetValue1_Str = default_val; nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: bsOut.Write(hmd); nuclear@0: bsOut.Write(key); nuclear@0: bsOut.Write(default_val); nuclear@0: if (!GetRPC1()->CallBlocking("GetStringValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return ""; nuclear@0: } nuclear@0: if (!returnData.Read(ProfileGetValue1_Str)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: } nuclear@0: return ProfileGetValue1_Str.ToCStr(); nuclear@0: } nuclear@0: bool NetClient::GetBoolValue(VirtualHmdId hmd, const char* key, bool default_val) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return default_val; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: bsOut.Write(hmd); nuclear@0: bsOut.Write(key); nuclear@0: bsOut.Write(default_val); nuclear@0: if (!GetRPC1()->CallBlocking("GetBoolValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return default_val; nuclear@0: } nuclear@0: uint8_t out = 0; nuclear@0: if (!returnData.Read(out)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: } nuclear@0: return out != 0; nuclear@0: } nuclear@0: int NetClient::GetIntValue(VirtualHmdId hmd, const char* key, int default_val) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return default_val; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: bsOut.Write(hmd); nuclear@0: bsOut.Write(key); nuclear@0: bsOut.Write(default_val); nuclear@0: if (!GetRPC1()->CallBlocking("GetIntValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return default_val; nuclear@0: } nuclear@0: int32_t out = (int32_t)default_val; nuclear@0: if (!returnData.Read(out)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: } nuclear@0: return out; nuclear@0: } nuclear@0: double NetClient::GetNumberValue(VirtualHmdId hmd, const char* key, double default_val) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return default_val; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: bsOut.Write(hmd); nuclear@0: bsOut.Write(key); nuclear@0: bsOut.Write(default_val); nuclear@0: if (!GetRPC1()->CallBlocking("GetNumberValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return default_val; nuclear@0: } nuclear@0: double out = 0.; nuclear@0: returnData.Read(out); nuclear@0: return out; nuclear@0: } nuclear@0: int NetClient::GetNumberValues(VirtualHmdId hmd, const char* key, double* values, int num_vals) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: bsOut.Write(hmd); nuclear@0: bsOut.Write(key); nuclear@0: nuclear@0: int32_t w = (int32_t)num_vals; nuclear@0: bsOut.Write(w); nuclear@0: nuclear@0: if (!GetRPC1()->CallBlocking("GetNumberValues_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: int32_t out = 0; nuclear@0: if (!returnData.Read(out)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: } nuclear@0: OVR_ASSERT(out >= 0 && out <= num_vals); nuclear@0: if (out < 0) nuclear@0: { nuclear@0: out = 0; nuclear@0: } nuclear@0: else if (out > num_vals) nuclear@0: { nuclear@0: out = num_vals; nuclear@0: } nuclear@0: nuclear@0: for (int i = 0; i < out && i < num_vals; i++) nuclear@0: { nuclear@0: if (!returnData.Read(values[i])) nuclear@0: { nuclear@0: return i; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: return out; nuclear@0: } nuclear@0: nuclear@0: bool NetClient::SetStringValue(VirtualHmdId hmd, const char* key, const char* val) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut; nuclear@0: bsOut.Write(hmd); nuclear@0: bsOut.Write(key); nuclear@0: nuclear@0: bsOut.Write(val); nuclear@0: nuclear@0: if (!GetRPC1()->Signal("SetStringValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: bool NetClient::SetBoolValue(VirtualHmdId hmd, const char* key, bool val) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut; nuclear@0: bsOut.Write(hmd); nuclear@0: bsOut.Write(key); nuclear@0: nuclear@0: uint8_t b = val ? 1 : 0; nuclear@0: bsOut.Write(b); nuclear@0: nuclear@0: if (!GetRPC1()->Signal("SetBoolValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: bool NetClient::SetIntValue(VirtualHmdId hmd, const char* key, int val) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut; nuclear@0: bsOut.Write(hmd); nuclear@0: bsOut.Write(key); nuclear@0: nuclear@0: int32_t w = (int32_t)val; nuclear@0: bsOut.Write(w); nuclear@0: nuclear@0: if (!GetRPC1()->Signal("SetIntValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: bool NetClient::SetNumberValue(VirtualHmdId hmd, const char* key, double val) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut; nuclear@0: bsOut.Write(hmd); nuclear@0: bsOut.Write(key); nuclear@0: nuclear@0: bsOut.Write(val); nuclear@0: nuclear@0: if (!GetRPC1()->Signal("SetNumberValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: bool NetClient::SetNumberValues(VirtualHmdId hmd, const char* key, const double* vals, int num_vals) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut; nuclear@0: bsOut.Write(hmd); nuclear@0: bsOut.Write(key); nuclear@0: nuclear@0: int32_t w_count = (int32_t)num_vals; nuclear@0: bsOut.Write(w_count); nuclear@0: nuclear@0: for (int i = 0; i < num_vals; i++) nuclear@0: { nuclear@0: bsOut.Write(vals[i]); nuclear@0: } nuclear@0: nuclear@0: if (!GetRPC1()->Signal("SetNumberValues_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: int NetClient::Hmd_Detect() nuclear@0: { nuclear@0: if (!IsConnected(true, false)) nuclear@0: { nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: // If using edge-triggered HMD counting, nuclear@0: if (EdgeTriggeredHMDCount) nuclear@0: { nuclear@0: // Return the last update from the server nuclear@0: return HMDCount; nuclear@0: } nuclear@0: nuclear@0: // Otherwise: We need to ask the first time nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: nuclear@0: if (!GetRPC1()->CallBlocking("Hmd_Detect_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: int32_t out = 0; nuclear@0: if (!returnData.Read(out)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: } nuclear@0: HMDCount = out; nuclear@0: EdgeTriggeredHMDCount = true; nuclear@0: return out; nuclear@0: } nuclear@0: nuclear@0: bool NetClient::Hmd_Create(int index, HMDNetworkInfo* netInfo) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: nuclear@0: int32_t w = (int32_t)index; nuclear@0: bsOut.Write(w); nuclear@0: nuclear@0: // Need the Pid for driver mode nuclear@0: pid_t pid = GetCurrentProcessId(); nuclear@0: bsOut.Write(pid); nuclear@0: nuclear@0: if (!GetRPC1()->CallBlocking("Hmd_Create_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: return netInfo->Deserialize(&returnData); nuclear@0: } nuclear@0: nuclear@0: bool NetClient::GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: nuclear@0: bsOut.Write(InvalidVirtualHmdId); nuclear@0: nuclear@0: if (!GetRPC1()->CallBlocking("GetDriverMode_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: int32_t w_driverInstalled = 0; nuclear@0: int32_t w_compatMode = 0; nuclear@0: int32_t w_hideDK1Mode = 0; nuclear@0: returnData.Read(w_driverInstalled); nuclear@0: returnData.Read(w_compatMode); nuclear@0: if (!returnData.Read(w_hideDK1Mode)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: driverInstalled = w_driverInstalled != 0; nuclear@0: compatMode = w_compatMode != 0; nuclear@0: hideDK1Mode = w_hideDK1Mode != 0; nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: bool NetClient::SetDriverMode(bool compatMode, bool hideDK1Mode) nuclear@0: { nuclear@0: if (!IsConnected(true, true)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: nuclear@0: bsOut.Write(InvalidVirtualHmdId); nuclear@0: nuclear@0: int32_t w_compatMode, w_hideDK1Mode; nuclear@0: w_compatMode = compatMode ? 1 : 0; nuclear@0: w_hideDK1Mode = hideDK1Mode ? 1 : 0; nuclear@0: bsOut.Write(w_compatMode); nuclear@0: bsOut.Write(w_hideDK1Mode); nuclear@0: nuclear@0: if (!GetRPC1()->CallBlocking("SetDriverMode_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: int32_t out = 0; nuclear@0: if (!returnData.Read(out)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: return out != 0; nuclear@0: } nuclear@0: nuclear@0: bool NetClient::Hmd_AttachToWindow(VirtualHmdId hmd, void* hWindow) nuclear@0: { nuclear@0: if (!IsConnected(false, false)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut; nuclear@0: bsOut.Write(hmd); nuclear@0: nuclear@0: #ifdef OVR_OS_LINUX nuclear@0: if (hWindow == NULL) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: unsigned long hWinWord = *(unsigned long *)hWindow; nuclear@0: #else nuclear@0: UInt64 hWinWord = (UPInt)hWindow; nuclear@0: #endif nuclear@0: bsOut.Write(hWinWord); nuclear@0: nuclear@0: if (!GetRPC1()->CallBlocking("Hmd_AttachToWindow_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: void NetClient::Hmd_Release(VirtualHmdId hmd) nuclear@0: { nuclear@0: if (!IsConnected(false, false)) nuclear@0: { nuclear@0: return; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut; nuclear@0: bsOut.Write(hmd); nuclear@0: bool result = GetRPC1()->CallBlocking("Hmd_Release_1", &bsOut, GetSession()->GetConnectionAtIndex(0)); nuclear@0: OVR_ASSERT_AND_UNUSED(result, result); nuclear@0: } nuclear@0: nuclear@0: void NetClient::SetLastError(String str) nuclear@0: { nuclear@0: Hmd_GetLastError_Str = str; nuclear@0: } nuclear@0: nuclear@0: // Last string is cached locally. nuclear@0: const char* NetClient::Hmd_GetLastError(VirtualHmdId hmd) nuclear@0: { nuclear@0: if (hmd == InvalidVirtualHmdId || !IsConnected(false, false)) nuclear@0: { nuclear@0: return Hmd_GetLastError_Str.ToCStr(); nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: bsOut.Write(hmd); nuclear@0: if (!GetRPC1()->CallBlocking("Hmd_GetLastError_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return Hmd_GetLastError_Str.ToCStr(); nuclear@0: } nuclear@0: if (!returnData.Read(Hmd_GetLastError_Str)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: } nuclear@0: return Hmd_GetLastError_Str.ToCStr(); nuclear@0: } nuclear@0: nuclear@0: nuclear@0: // Fills in description about HMD; this is the same as filled in by ovrHmd_Create. nuclear@0: // The actual descriptor is a par nuclear@0: bool NetClient::Hmd_GetHmdInfo(VirtualHmdId hmd, HMDInfo* hmdInfo) nuclear@0: { nuclear@0: if (!IsConnected(false, false)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: bsOut.Write(hmd); nuclear@0: if (!GetRPC1()->CallBlocking("Hmd_GetHmdInfo_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: return NetSessionCommon::DeserializeHMDInfo(&returnData, hmdInfo); nuclear@0: } nuclear@0: nuclear@0: nuclear@0: //------------------------------------------------------------------------------------- nuclear@0: unsigned int NetClient::Hmd_GetEnabledCaps(VirtualHmdId hmd) nuclear@0: { nuclear@0: if (!IsConnected(false, false)) nuclear@0: { nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: bsOut.Write(hmd); nuclear@0: if (!GetRPC1()->CallBlocking("Hmd_GetEnabledCaps_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: uint32_t c = 0; nuclear@0: if (!returnData.Read(c)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: } nuclear@0: return c; nuclear@0: } nuclear@0: nuclear@0: // Returns new caps after modification nuclear@0: unsigned int NetClient::Hmd_SetEnabledCaps(VirtualHmdId hmd, unsigned int hmdCaps) nuclear@0: { nuclear@0: if (!IsConnected(false, false)) nuclear@0: { nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: bsOut.Write(hmd); nuclear@0: nuclear@0: uint32_t c = (uint32_t)hmdCaps; nuclear@0: bsOut.Write(c); nuclear@0: nuclear@0: if (!GetRPC1()->CallBlocking("Hmd_SetEnabledCaps_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: c = 0; nuclear@0: if (!returnData.Read(c)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: } nuclear@0: return c; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: //------------------------------------------------------------------------------------- nuclear@0: // *** Tracking Setup nuclear@0: nuclear@0: bool NetClient::Hmd_ConfigureTracking(VirtualHmdId hmd, unsigned supportedCaps, unsigned requiredCaps) nuclear@0: { nuclear@0: if (!IsConnected(false, false)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: bsOut.Write(hmd); nuclear@0: nuclear@0: uint32_t w_sc = supportedCaps; nuclear@0: bsOut.Write(w_sc); nuclear@0: uint32_t w_rc = requiredCaps; nuclear@0: bsOut.Write(w_rc); nuclear@0: nuclear@0: if (!GetRPC1()->CallBlocking("Hmd_ConfigureTracking_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: uint8_t b; nuclear@0: if (!returnData.Read(b)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: } nuclear@0: nuclear@0: return b != 0; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: void NetClient::Hmd_ResetTracking(VirtualHmdId hmd) nuclear@0: { nuclear@0: if (!IsConnected(false, false)) nuclear@0: { nuclear@0: return; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut; nuclear@0: bsOut.Write(hmd); nuclear@0: if (!GetRPC1()->CallBlocking("Hmd_ResetTracking_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) nuclear@0: { nuclear@0: return; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: bool NetClient::LatencyUtil_ProcessInputs(double startTestSeconds, unsigned char rgbColorOut[3]) nuclear@0: { nuclear@0: if (!IsConnected(false, false)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: if (!LatencyTesterAvailable) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: bsOut.Write(startTestSeconds); nuclear@0: if (!GetRPC1()->CallBlocking("LatencyUtil_ProcessInputs_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: uint8_t u; nuclear@0: returnData.Read(u); nuclear@0: rgbColorOut[0] = u; nuclear@0: returnData.Read(u); nuclear@0: rgbColorOut[1] = u; nuclear@0: if (!returnData.Read(u)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: rgbColorOut[2] = u; nuclear@0: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: const char* NetClient::LatencyUtil_GetResultsString() nuclear@0: { nuclear@0: if (!IsConnected(false, false)) nuclear@0: { nuclear@0: return NULL; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut, returnData; nuclear@0: if (!GetRPC1()->CallBlocking("LatencyUtil_GetResultsString_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) nuclear@0: { nuclear@0: return NULL; nuclear@0: } nuclear@0: nuclear@0: if (!returnData.Read(LatencyUtil_GetResultsString_Str)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: } nuclear@0: nuclear@0: return LatencyUtil_GetResultsString_Str.ToCStr(); nuclear@0: } nuclear@0: nuclear@0: bool NetClient::ShutdownServer() nuclear@0: { nuclear@0: if (!IsConnected(false, false)) nuclear@0: { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: OVR::Net::BitStream bsOut; nuclear@0: GetRPC1()->BroadcastSignal("Shutdown_1", &bsOut); nuclear@0: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: //// Push Notifications: nuclear@0: nuclear@0: void NetClient::registerRPC() nuclear@0: { nuclear@0: #define RPC_REGISTER_SLOT(observerScope, functionName) \ nuclear@0: observerScope.SetHandler(OVR::Net::Plugins::RPCSlot::FromMember(this)); pRPC->RegisterSlot(OVR_STRINGIZE(functionName), observerScope); nuclear@0: nuclear@0: // Register RPC functions: nuclear@0: RPC_REGISTER_SLOT(InitialServerStateScope, InitialServerState_1); nuclear@0: RPC_REGISTER_SLOT(LatencyTesterAvailableScope, LatencyTesterAvailable_1); nuclear@0: RPC_REGISTER_SLOT(DefaultLogOutputScope, DefaultLogOutput_1); nuclear@0: RPC_REGISTER_SLOT(HMDCountUpdateScope, HMDCountUpdate_1); nuclear@0: } nuclear@0: nuclear@0: void NetClient::InitialServerState_1(BitStream* userData, ReceivePayload* pPayload) nuclear@0: { nuclear@0: LatencyTesterAvailable_1(userData, pPayload); nuclear@0: } nuclear@0: nuclear@0: void NetClient::LatencyTesterAvailable_1(BitStream* userData, ReceivePayload* pPayload) nuclear@0: { nuclear@0: OVR_UNUSED(pPayload); nuclear@0: nuclear@0: uint8_t b = 0; nuclear@0: if (!userData->Read(b)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: return; nuclear@0: } nuclear@0: nuclear@0: LatencyTesterAvailable = (b != 0); nuclear@0: } nuclear@0: nuclear@0: void NetClient::DefaultLogOutput_1(BitStream* userData, ReceivePayload* pPayload) nuclear@0: { nuclear@0: OVR_UNUSED(pPayload); nuclear@0: nuclear@0: String formattedText; nuclear@0: LogMessageType messageType = Log_Text; // Will normally be overwritten below. nuclear@0: userData->Read(messageType); nuclear@0: if (userData->Read(formattedText)) nuclear@0: { nuclear@0: if (OVR::Log::GetGlobalLog()) nuclear@0: { nuclear@0: OVR::String logStr = "[From Service] "; nuclear@0: logStr.AppendString(formattedText); nuclear@0: OVR::Log::GetGlobalLog()->LogMessage(messageType, "%s", logStr.ToCStr()); nuclear@0: } nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: void NetClient::HMDCountUpdate_1(BitStream* userData, ReceivePayload* pPayload) nuclear@0: { nuclear@0: OVR_UNUSED(pPayload); nuclear@0: nuclear@0: int32_t hmdCount = 0; nuclear@0: if (!userData->Read(hmdCount)) nuclear@0: { nuclear@0: OVR_ASSERT(false); nuclear@0: return; nuclear@0: } nuclear@0: nuclear@0: HMDCount = hmdCount; nuclear@0: EdgeTriggeredHMDCount = true; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: }} // namespace OVR::Service