Example #1
0
        public async Task <Call> ConnectAsync(List <List <CallDevice> > devices)
        {
            await mAPI.Setup();

            if (string.IsNullOrWhiteSpace(CallID))
            {
                throw new ArgumentNullException("CallID");
            }


            // Completion source and callbacks for detecting when an appropriate event is received
            TaskCompletionSource <bool> connectFinished   = new TaskCompletionSource <bool>();
            ConnectConnectedCallback    connectedCallback = (a, c, cc, cp) => connectFinished.SetResult(true);
            ConnectFailedCallback       failedCallback    = (a, c, cp) => connectFinished.SetResult(false);

            // Hook temporary callbacks for the completion source
            OnConnectConnected += connectedCallback;
            OnConnectFailed    += failedCallback;

            // TODO: Prevent connect on a call that is already being connected but may not yet have peer associated? or will FS error back if tried?

            Task <CallConnectResult> taskCallConnectResult = mAPI.LL_CallConnectAsync(new CallConnectParams()
            {
                CallID  = CallID,
                NodeID  = NodeID,
                Devices = devices,
            });

            bool connected = false;

            try
            {
                // The use of await ensures that exceptions are rethrown, or OperationCancelledException is thrown
                CallConnectResult callConnectResult = await taskCallConnectResult;
                // If there was an internal error of any kind then throw an exception
                mAPI.ThrowIfError(callConnectResult.Code, callConnectResult.Message);
                // Wait for completion source, either connected or failed connect state
                connected = await connectFinished.Task;
            }
            catch
            {
                // Rethrow the exception, we catch and throw to ensure the finally block is called in case the exception
                // isn't caught up the stack otherwise, which can cause the finally block not to be called
                throw;
            }
            finally
            {
                // Unhook the temporary callbacks whether an exception occurs or not
                OnConnectConnected -= connectedCallback;
                OnConnectFailed    -= failedCallback;
            }

            // We get here if no exceptions or errors occurred, this means it was connected and a peer will get returned,
            // or it failed and null is returned which means the call could not be connected but no real errors occurred
            if (!connected)
            {
                mLogger.LogWarning("Call {0} connect failed", CallID);
            }

            return(mPeer);
        }