void BackEndTransport::OnConnectionReceived()

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());
        }
    });
    
}