in archived/VoIP/cs/VoipBackEnd/BackEndTransport.cpp [153:259]
void BackEndTransport::OnConnectionReceived(DatagramSocket^ socket, DatagramSocketMessageReceivedEventArgs^ eventArguments)
{
if (outputStream != nullptr)
{
try
{
EnterCriticalSection(&readLock);
DataReader^ reader = eventArguments->GetDataReader();
unsigned int dataSize = reader->ReadUInt32();
if(dataSize > MaxPacketSize)
{
dataSize = MaxPacketSize;
}
unsigned int dataType = reader->ReadUInt32();
UINT64 hnsPresentationTime = reader->ReadUInt64();
UINT64 hnsSampleDuration = reader->ReadUInt64();
IBuffer^ buffer = reader->ReadBuffer(dataSize);
String^ debugStr = "[BackEndTransport::OnConnectionReceived] Size:" + dataSize.ToString() +
L" Type:" + dataType.ToString() +
" Presentation:" + hnsPresentationTime.ToString() +
" Duration:" + hnsSampleDuration +
" Unconsumed buffer:" + reader->UnconsumedBufferLength +
" IBuffer:" + buffer->Length + "\n";
LeaveCriticalSection(&readLock);
OutputDebugString(debugStr->Data());
BYTE* pBuffer = NULL;
BYTE* pBufferCopy = NULL;
ComPtr<NativeBuffer> spNativeBuffer = NULL;
pBuffer = NativeBuffer::GetBytesFromIBuffer(buffer);
pBufferCopy = new BYTE[dataSize];
memcpy_s((void*) pBufferCopy, dataSize, (void*) pBuffer, dataSize);
buffer = nullptr;
pBuffer = NULL;
// Now wrap this buffer with our NativeBuffer object
if (FAILED(MakeAndInitialize<NativeBuffer>(&spNativeBuffer, pBufferCopy, dataSize, TRUE)))
{
return;
}
switch(dataType)
{
case TransportMessageType::Audio:
AudioMessageReceived(NativeBuffer::GetIBufferFromNativeBuffer(spNativeBuffer), hnsPresentationTime, hnsSampleDuration);
break;
case TransportMessageType::Video:
VideoMessageReceived(NativeBuffer::GetIBufferFromNativeBuffer(spNativeBuffer), hnsPresentationTime, hnsSampleDuration);
break;
default:
break;
}
}
catch (Exception^ exception)
{
SocketErrorStatus socketError = SocketError::GetStatus(exception->HResult);
if (socketError == SocketErrorStatus::ConnectionResetByPeer)
{
// This error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.
}
else if (socketError != SocketErrorStatus::Unknown)
{
}
else
{
throw;
}
}
return;
}
// We do not have an output stream yet so create one.
task<IOutputStream^>(socket->GetOutputStreamAsync(eventArguments->RemoteAddress, eventArguments->RemotePort)).then([this, socket, eventArguments] (IOutputStream^ stream)
{
// It might happen that the OnMessage was invoked more than once before the GetOutputStreamAsync completed.
// In this case we will end up with multiple streams - make sure we have just one of it.
EnterCriticalSection(&lock);
if (outputStream == nullptr)
{
OutputDebugString(eventArguments->RemoteAddress->RawName->Data());
outputStream = stream;
hostName = eventArguments->RemoteAddress;
port = eventArguments->RemotePort;
}
LeaveCriticalSection(&lock);
}).then([this, socket, eventArguments] (task<void> previousTask)
{
try
{
// Try getting all exceptions from the continuation chain above this point.
previousTask.get();
}
catch (Exception^ exception)
{
OutputDebugString(exception->Message->Data());
}
});
}