XnStatus SyncSocketConnection::Receive(void* pData, XnUInt32& nSize) { XnStatus nRetVal = XN_STATUS_OK; LinkPacketHeader* pLinkPacketHeader = reinterpret_cast<LinkPacketHeader*>(pData); XnUInt32 nMaxSize = nSize; XnUInt32 nTotalBytesReceived = sizeof(LinkPacketHeader); nRetVal = xnOSReceiveNetworkBuffer(m_hSocket, (XnChar*)pData, &nTotalBytesReceived, RECEIVE_TIMEOUT); if (nRetVal == XN_STATUS_OS_NETWORK_TIMEOUT) // Do not use XN_IS_STATUS_OK_LOG_ERROR for timeout { return nRetVal; } //XN_IS_STATUS_OK_LOG_ERROR("Receive network buffer", nRetVal); XN_IS_STATUS_OK(nRetVal); if (nTotalBytesReceived < sizeof(LinkPacketHeader)) { xnLogError(XN_MASK_SYNC_SOCKET, "Partial link packet header received :("); XN_ASSERT(FALSE); return XN_STATUS_ERROR; } XnUInt32 nBytesToRead = pLinkPacketHeader->GetSize(); if (nBytesToRead > nMaxSize) { xnLogError(XN_MASK_SYNC_SOCKET, "Specified buffer of size %u is not large enough to hold received packet of size %u", nMaxSize, nBytesToRead); XN_ASSERT(FALSE); return XN_STATUS_INTERNAL_BUFFER_TOO_SMALL; } XnUInt32 nIterationBytesReceived = 0; while (nTotalBytesReceived < nBytesToRead) { nIterationBytesReceived = (nBytesToRead - nTotalBytesReceived); nRetVal = xnOSReceiveNetworkBuffer(m_hSocket, ((XnChar*)pData) + nTotalBytesReceived, &nIterationBytesReceived, RECEIVE_TIMEOUT); XN_IS_STATUS_OK_LOG_ERROR("Receive network buffer", nRetVal); nTotalBytesReceived += nIterationBytesReceived; } nSize = nTotalBytesReceived; return XN_STATUS_OK; }
XnStatus SocketInConnection::ReceivePacket(XN_SOCKET_HANDLE hSocket, void* pDestBuffer, XnUInt32& nSize, XnBool& bCanceled) { XnStatus nRetVal = XN_STATUS_OK; LinkPacketHeader* pPacket = reinterpret_cast<LinkPacketHeader*>(pDestBuffer); XN_ASSERT(nSize >= sizeof(LinkPacketHeader)); /* We first receive the packet's header to know its size, and then receive exactly as many bytes as needed. If we just received max packet size, we might overrun a smaller packet and receive part of the next packet. (We don't have this problem with USB cuz we always get a whole packet there).*/ nRetVal = ReceiveExactly(hSocket, pPacket, sizeof(LinkPacketHeader), bCanceled); if (bCanceled) { //The request to receive a packet was canceled return XN_STATUS_OK; } //XN_IS_STATUS_OK_LOG_ERROR("Receive packet header", nRetVal); XN_IS_STATUS_OK(nRetVal); if (!pPacket->IsMagicValid()) { xnLogError(XN_MASK_LINK, "Got bad link packet header magic :("); XN_ASSERT(FALSE); return XN_STATUS_ERROR; } XnUInt16 nPacketSize = pPacket->GetSize(); if (nSize < nPacketSize) { xnLogError(XN_MASK_LINK, "Insufficient buffer (%u bytes) to hold packet of %u bytes", nSize, nPacketSize); XN_ASSERT(FALSE); return XN_STATUS_INTERNAL_BUFFER_TOO_SMALL; } nSize = 0; //In case we get canceled nRetVal = ReceiveExactly(hSocket, pPacket->GetPacketData(), nPacketSize - sizeof(LinkPacketHeader), bCanceled); XN_IS_STATUS_OK_LOG_ERROR("Receive packet body", nRetVal); if (bCanceled) { //The request to receive a packet was canceled return XN_STATUS_OK; } nSize = nPacketSize; return XN_STATUS_OK; }
XnStatus LinkContInputStream::HandlePacket(const LinkPacketHeader& header, const XnUInt8* pData, XnBool& bPacketLoss) { XnStatus nRetVal = XN_STATUS_OK; xnl::AutoCSLocker csLock(m_hCriticalSection); if (!m_bInitialized) { return XN_STATUS_NOT_INIT; } // TODO: handle packet loss! bPacketLoss = FALSE; if(m_streamType == XN_LINK_STREAM_TYPE_LOG) { // begin parsing frame nRetVal = m_logParser.BeginParsing(m_pWorkingBuffer, CONT_STREAM_PREDEFINED_BUFFER_SIZE); XN_IS_STATUS_OK_LOG_ERROR("Begin parsing link log msg", nRetVal); nRetVal = m_logParser.ParsePacket(header, pData); if (nRetVal != XN_STATUS_OK) XN_IS_STATUS_OK_LOG_ERROR("Parse data from stream", nRetVal); } //Write new data to dump (if it's on) xnDumpFileWriteBuffer(m_pDumpFile, reinterpret_cast<const XnUInt8*>(m_logParser.GetParsedData()), m_logParser.GetParsedSize()); if (header.GetFragmentationFlags() & XN_LINK_FRAG_END) { //Notify that we have new data available m_bNewDataAvailable = TRUE; nRetVal = m_newDataAvailableEvent.Raise(); XN_IS_STATUS_OK_LOG_ERROR("Raise new data available event", nRetVal); } return XN_STATUS_OK; }