Exemplo n.º 1
0
        private async Task <ConnectResult> InternalConnectAsync(List <List <CallDevice> > devices)
        {
            await API.API.SetupAsync();

            ConnectResult resultConnect = new ConnectResult();
            TaskCompletionSource <bool> tcsCompletion = new TaskCompletionSource <bool>();

            // Hook callbacks temporarily to catch required events
            ConnectConnectedCallback connectedCallback = (a, c, cp, e, p) =>
            {
                resultConnect.Event = new Event(e.EventType, JObject.FromObject(p));
                resultConnect.Call  = cp;
                tcsCompletion.SetResult(true);
            };
            ConnectFailedCallback failedCallback = (a, c, e, p) =>
            {
                resultConnect.Event = new Event(e.EventType, JObject.FromObject(p));
                tcsCompletion.SetResult(false);
            };

            OnConnectConnected += connectedCallback;
            OnConnectFailed    += failedCallback;

            try
            {
                Task <LL_ConnectResult> taskLLConnect = mAPI.LL_ConnectAsync(new LL_ConnectParams()
                {
                    CallID  = ID,
                    NodeID  = NodeID,
                    Devices = devices,
                });

                // The use of await rethrows exceptions from the task
                LL_ConnectResult resultLLConnect = await taskLLConnect;
                if (resultLLConnect.Code == "200")
                {
                    mLogger.LogDebug("Connect for call {0} waiting for completion events", ID);

                    resultConnect.Successful = await tcsCompletion.Task;

                    mLogger.LogDebug("Connect for call {0} {1}", ID, resultConnect.Successful ? "successful" : "unsuccessful");
                }
            }
            catch (Exception exc)
            {
                mLogger.LogError(exc, "Connect for call {0} exception", ID);
            }

            // Unhook temporary callbacks
            OnConnectConnected -= connectedCallback;
            OnConnectFailed    -= failedCallback;

            return(resultConnect);
        }
Exemplo n.º 2
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);
        }