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;	
}
示例#3
0
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;
}