ovr_sdk

annotate LibOVR/Src/Net/OVR_PacketizedTCPSocket.cpp @ 0:1b39a1b46319

initial 0.4.4
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 14 Jan 2015 06:51:16 +0200
parents
children
rev   line source
nuclear@0 1 /************************************************************************************
nuclear@0 2
nuclear@0 3 Filename : OVR_PacketizedTCPSocket.cpp
nuclear@0 4 Content : TCP with automated message framing.
nuclear@0 5 Created : June 10, 2014
nuclear@0 6 Authors : Kevin Jenkins
nuclear@0 7
nuclear@0 8 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
nuclear@0 9
nuclear@0 10 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
nuclear@0 11 you may not use the Oculus VR Rift SDK except in compliance with the License,
nuclear@0 12 which is provided at the time of installation or download, or which
nuclear@0 13 otherwise accompanies this software in either electronic or hard copy form.
nuclear@0 14
nuclear@0 15 You may obtain a copy of the License at
nuclear@0 16
nuclear@0 17 http://www.oculusvr.com/licenses/LICENSE-3.2
nuclear@0 18
nuclear@0 19 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
nuclear@0 20 distributed under the License is distributed on an "AS IS" BASIS,
nuclear@0 21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nuclear@0 22 See the License for the specific language governing permissions and
nuclear@0 23 limitations under the License.
nuclear@0 24
nuclear@0 25 ************************************************************************************/
nuclear@0 26
nuclear@0 27 #include "OVR_PacketizedTCPSocket.h"
nuclear@0 28
nuclear@0 29 namespace OVR { namespace Net {
nuclear@0 30
nuclear@0 31
nuclear@0 32 //-----------------------------------------------------------------------------
nuclear@0 33 // Constants
nuclear@0 34
nuclear@0 35 static const int LENGTH_FIELD_BYTES = 4;
nuclear@0 36
nuclear@0 37
nuclear@0 38 //-----------------------------------------------------------------------------
nuclear@0 39 // PacketizedTCPSocket
nuclear@0 40
nuclear@0 41 PacketizedTCPSocket::PacketizedTCPSocket()
nuclear@0 42 {
nuclear@0 43 pRecvBuff = 0;
nuclear@0 44 pRecvBuffSize = 0;
nuclear@0 45 Transport = TransportType_PacketizedTCP;
nuclear@0 46 }
nuclear@0 47
nuclear@0 48 PacketizedTCPSocket::PacketizedTCPSocket(SocketHandle _sock, bool isListenSocket) : PacketizedTCPSocketBase(_sock, isListenSocket)
nuclear@0 49 {
nuclear@0 50 pRecvBuff = 0;
nuclear@0 51 pRecvBuffSize = 0;
nuclear@0 52 Transport = TransportType_PacketizedTCP;
nuclear@0 53 }
nuclear@0 54
nuclear@0 55 PacketizedTCPSocket::~PacketizedTCPSocket()
nuclear@0 56 {
nuclear@0 57 OVR_FREE(pRecvBuff);
nuclear@0 58 }
nuclear@0 59
nuclear@0 60 int PacketizedTCPSocket::Send(const void* pData, int bytes)
nuclear@0 61 {
nuclear@0 62 Lock::Locker locker(&sendLock);
nuclear@0 63
nuclear@0 64 if (bytes <= 0)
nuclear@0 65 {
nuclear@0 66 return -1;
nuclear@0 67 }
nuclear@0 68
nuclear@0 69 // Convert length to 4 endian-neutral bytes
nuclear@0 70 uint32_t lengthWord = bytes;
nuclear@0 71 uint8_t lengthBytes[LENGTH_FIELD_BYTES] = {
nuclear@0 72 (uint8_t)lengthWord,
nuclear@0 73 (uint8_t)(lengthWord >> 8),
nuclear@0 74 (uint8_t)(lengthWord >> 16),
nuclear@0 75 (uint8_t)(lengthWord >> 24)
nuclear@0 76 };
nuclear@0 77
nuclear@0 78 int s = PacketizedTCPSocketBase::Send(lengthBytes, LENGTH_FIELD_BYTES);
nuclear@0 79 if (s > 0)
nuclear@0 80 {
nuclear@0 81 return PacketizedTCPSocketBase::Send(pData,bytes);
nuclear@0 82 }
nuclear@0 83 else
nuclear@0 84 {
nuclear@0 85 return s;
nuclear@0 86 }
nuclear@0 87 }
nuclear@0 88
nuclear@0 89 int PacketizedTCPSocket::SendAndConcatenate(const void** pDataArray, int* dataLengthArray, int arrayCount)
nuclear@0 90 {
nuclear@0 91 Lock::Locker locker(&sendLock);
nuclear@0 92
nuclear@0 93 if (arrayCount == 0)
nuclear@0 94 return 0;
nuclear@0 95
nuclear@0 96 int totalBytes = 0;
nuclear@0 97 for (int i = 0; i < arrayCount; i++)
nuclear@0 98 totalBytes += dataLengthArray[i];
nuclear@0 99
nuclear@0 100 // Convert length to 4 endian-neutral bytes
nuclear@0 101 uint32_t lengthWord = totalBytes;
nuclear@0 102 uint8_t lengthBytes[LENGTH_FIELD_BYTES] = {
nuclear@0 103 (uint8_t)lengthWord,
nuclear@0 104 (uint8_t)(lengthWord >> 8),
nuclear@0 105 (uint8_t)(lengthWord >> 16),
nuclear@0 106 (uint8_t)(lengthWord >> 24)
nuclear@0 107 };
nuclear@0 108
nuclear@0 109 int s = PacketizedTCPSocketBase::Send(lengthBytes, LENGTH_FIELD_BYTES);
nuclear@0 110 if (s > 0)
nuclear@0 111 {
nuclear@0 112 for (int i = 0; i < arrayCount; i++)
nuclear@0 113 {
nuclear@0 114 PacketizedTCPSocketBase::Send(pDataArray[i], dataLengthArray[i]);
nuclear@0 115 }
nuclear@0 116 }
nuclear@0 117
nuclear@0 118 return s;
nuclear@0 119 }
nuclear@0 120
nuclear@0 121 void PacketizedTCPSocket::OnRecv(SocketEvent_TCP* eventHandler, uint8_t* pData, int bytesRead)
nuclear@0 122 {
nuclear@0 123 uint8_t* dataSource = NULL;
nuclear@0 124 int dataSourceSize = 0;
nuclear@0 125
nuclear@0 126 recvBuffLock.DoLock();
nuclear@0 127
nuclear@0 128 if (pRecvBuff == NULL)
nuclear@0 129 {
nuclear@0 130 dataSource = pData;
nuclear@0 131 dataSourceSize = bytesRead;
nuclear@0 132 }
nuclear@0 133 else
nuclear@0 134 {
nuclear@0 135 uint8_t* pRecvBuffNew = (uint8_t*)OVR_REALLOC(pRecvBuff, bytesRead + pRecvBuffSize);
nuclear@0 136 if (!pRecvBuffNew)
nuclear@0 137 {
nuclear@0 138 OVR_FREE(pRecvBuff);
nuclear@0 139 pRecvBuff = NULL;
nuclear@0 140 pRecvBuffSize = 0;
nuclear@0 141 recvBuffLock.Unlock();
nuclear@0 142 return;
nuclear@0 143 }
nuclear@0 144 else
nuclear@0 145 {
nuclear@0 146 pRecvBuff = pRecvBuffNew;
nuclear@0 147
nuclear@0 148 memcpy(pRecvBuff + pRecvBuffSize, pData, bytesRead);
nuclear@0 149
nuclear@0 150 dataSourceSize = pRecvBuffSize + bytesRead;
nuclear@0 151 dataSource = pRecvBuff;
nuclear@0 152 }
nuclear@0 153 }
nuclear@0 154
nuclear@0 155 int bytesReadFromStream;
nuclear@0 156 while (bytesReadFromStream = BytesFromStream(dataSource, dataSourceSize),
nuclear@0 157 LENGTH_FIELD_BYTES + bytesReadFromStream <= dataSourceSize)
nuclear@0 158 {
nuclear@0 159 dataSource += LENGTH_FIELD_BYTES;
nuclear@0 160 dataSourceSize -= LENGTH_FIELD_BYTES;
nuclear@0 161
nuclear@0 162 TCPSocket::OnRecv(eventHandler, dataSource, bytesReadFromStream);
nuclear@0 163
nuclear@0 164 dataSource += bytesReadFromStream;
nuclear@0 165 dataSourceSize -= bytesReadFromStream;
nuclear@0 166 }
nuclear@0 167
nuclear@0 168 if (dataSourceSize > 0)
nuclear@0 169 {
nuclear@0 170 if (dataSource != NULL)
nuclear@0 171 {
nuclear@0 172 if (pRecvBuff == NULL)
nuclear@0 173 {
nuclear@0 174 pRecvBuff = (uint8_t*)OVR_ALLOC(dataSourceSize);
nuclear@0 175 if (!pRecvBuff)
nuclear@0 176 {
nuclear@0 177 pRecvBuffSize = 0;
nuclear@0 178 recvBuffLock.Unlock();
nuclear@0 179 return;
nuclear@0 180 }
nuclear@0 181 else
nuclear@0 182 {
nuclear@0 183 memcpy(pRecvBuff, dataSource, dataSourceSize);
nuclear@0 184 }
nuclear@0 185 }
nuclear@0 186 else
nuclear@0 187 {
nuclear@0 188 memmove(pRecvBuff, dataSource, dataSourceSize);
nuclear@0 189 }
nuclear@0 190 }
nuclear@0 191 }
nuclear@0 192 else
nuclear@0 193 {
nuclear@0 194 if (pRecvBuff != NULL)
nuclear@0 195 OVR_FREE(pRecvBuff);
nuclear@0 196
nuclear@0 197 pRecvBuff = NULL;
nuclear@0 198 }
nuclear@0 199 pRecvBuffSize = dataSourceSize;
nuclear@0 200
nuclear@0 201 recvBuffLock.Unlock();
nuclear@0 202 }
nuclear@0 203
nuclear@0 204 int PacketizedTCPSocket::BytesFromStream(uint8_t* pData, int bytesRead)
nuclear@0 205 {
nuclear@0 206 if (pData != 0 && bytesRead >= LENGTH_FIELD_BYTES)
nuclear@0 207 {
nuclear@0 208 return pData[0] | ((uint32_t)pData[1] << 8) | ((uint32_t)pData[2] << 16) | ((uint32_t)pData[3] << 24);
nuclear@0 209 }
nuclear@0 210
nuclear@0 211 return 0;
nuclear@0 212 }
nuclear@0 213
nuclear@0 214
nuclear@0 215 }} // OVR::Net