public IAsyncResult BeginAccountSetLoginProperties(ParticipantPropertyUpdateFrequency participantPropertyFrequency, AsyncCallback callback) { AssertLoggedIn(); AsyncNoResult ar = new AsyncNoResult(callback); var request = new vx_req_account_set_login_properties_t { account_handle = _accountHandle, participant_property_frequency = (int)participantPropertyFrequency }; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); _participantPropertyFrequency = participantPropertyFrequency; ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); return(ar); }
public IAsyncResult BeginRemovePresenceSubscription(AccountId userId, AsyncCallback callback) { AssertLoggedIn(); AsyncNoResult ar = new AsyncNoResult(callback); if (!_presenceSubscriptions.ContainsKey((userId))) { ar.SetCompletedSynchronously(); return(ar); } var request = new vx_req_account_buddy_delete_t(); request.account_handle = _accountHandle; request.buddy_uri = userId.ToString(); VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); _presenceSubscriptions.Remove(userId); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); return(ar); }
public IAsyncResult BeginSetActiveDevice(IAudioDevice device, AsyncCallback callback) { if (device == null) { throw new ArgumentNullException(); } AsyncNoResult result = new AsyncNoResult(callback); var request = new vx_req_aux_set_render_device_t(); request.render_device_specifier = device.Key; return(_client.BeginIssueRequest(request, ar => { try { _client.EndIssueRequest(ar); // When trying to set the active device to what is already the active device, return. if (_activeDevice.Key == device.Key) { return; } _activeDevice = (AudioDevice)device; if (_activeDevice == AvailableDevices["Default System Device"]) { _effectiveDevice = new AudioDevice { Key = _systemDevice.Key, Name = _systemDevice.Name }; } else if (_activeDevice == AvailableDevices["Default Communication Device"]) { _effectiveDevice = new AudioDevice { Key = _communicationDevice.Key, Name = _communicationDevice.Name }; } else { _effectiveDevice = new AudioDevice { Key = device.Key, Name = device.Name }; } PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(EffectiveDevice))); result.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); result.SetComplete(e); } })); }
public IAsyncResult BeginRefresh(AsyncCallback callback) { AsyncNoResult result = new AsyncNoResult(callback); var request = new vx_req_aux_get_render_devices_t(); _client.BeginIssueRequest(request, ar => { vx_resp_aux_get_render_devices_t response; try { response = _client.EndIssueRequest(ar); _devices.Clear(); for (var i = 0; i < response.count; ++i) { var device = VivoxCoreInstance.get_device(i, response.render_devices); var id = device.device; var name = device.display_name; _devices[id] = new AudioDevice { Key = id, Name = name }; } _systemDevice = new AudioDevice { Key = response.default_render_device.device, Name = response.default_render_device.display_name }; _communicationDevice = new AudioDevice { Key = response.default_communication_render_device.device, Name = response.default_communication_render_device.display_name }; var effectiveDevice = new AudioDevice { Key = response.effective_render_device.device, Name = response.effective_render_device.display_name, }; if (!effectiveDevice.Equals(_effectiveDevice)) { // Only fire the event if the effective device has truly changed. _effectiveDevice = effectiveDevice; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(EffectiveDevice))); } result.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); result.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); return(result); }
public IAsyncResult BeginSendText(string language, string message, string applicationStanzaNamespace, string applicationStanzaBody, AsyncCallback callback) { AssertSessionNotDeleted(); if (string.IsNullOrEmpty(message)) { throw new ArgumentNullException(nameof(message)); } if (TextState != ConnectionState.Connected) { throw new InvalidOperationException($"{GetType().Name}: TextState must equal ChannelState.Connected"); } var ar = new AsyncNoResult(callback); var request = new vx_req_session_send_message_t { session_handle = _sessionHandle, message_body = message, application_stanza_body = applicationStanzaBody, language = language, application_stanza_namespace = applicationStanzaNamespace }; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); ar.SetComplete(); } catch (VivoxApiException e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); return(ar); }
public IAsyncResult Disconnect(AsyncCallback callback = null) { AssertSessionNotDeleted(); AsyncNoResult ar = new AsyncNoResult(callback); if (AudioState == ConnectionState.Connecting || AudioState == ConnectionState.Connected || TextState == ConnectionState.Connecting || TextState == ConnectionState.Connected) { var request = new vx_req_sessiongroup_remove_session_t { session_handle = _sessionHandle, sessiongroup_handle = GroupId }; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); _loginSession.ClearTransmittingChannel(Channel); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } // Don't set the media and text state since that needs to occur from // events or the client will not reflect what's happening on the server. }); if (AudioState != ConnectionState.Disconnected) { AudioState = ConnectionState.Disconnecting; } if (TextState != ConnectionState.Disconnected) { TextState = ConnectionState.Disconnecting; } if (ChannelState != ConnectionState.Disconnected) { ChannelState = ConnectionState.Disconnecting; } } return(ar); }
public IAsyncResult BeginLogin(Uri server, string accessToken, AsyncCallback callback) { if (string.IsNullOrEmpty(accessToken)) { throw new ArgumentNullException(nameof(accessToken)); } AssertLoggedOut(); AsyncNoResult result = new AsyncNoResult(callback); State = LoginState.LoggingIn; _client.BeginGetConnectorHandle(server, ar2 => { string connectorHandle; try { connectorHandle = _client.EndGetConnectorHandle(ar2); VivoxDebug.Instance.DebugMessage($"{GetType().Name}: connectorHandle={connectorHandle}", vx_log_level.log_debug); Login(accessToken, connectorHandle, result); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"BeginGetConnectorHandle failed: {e}"); State = LoginState.LoggedOut; result.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); return(result); }
public IAsyncResult BeginSendDirectedMessage(AccountId userId, string language, string message, string applicationStanzaNamespace, string applicationStanzaBody, AsyncCallback callback) { if (AccountId.IsNullOrEmpty(userId)) { throw new ArgumentNullException(nameof(userId)); } if (string.IsNullOrEmpty(message) && string.IsNullOrEmpty(applicationStanzaBody)) { throw new ArgumentNullException($"{nameof(message)} and {nameof(applicationStanzaBody)} cannot both be null"); } AssertLoggedIn(); AsyncNoResult ar = new AsyncNoResult(callback); var request = new vx_req_account_send_message_t { account_handle = _accountHandle, message_body = message, user_uri = userId.ToString(), language = language, application_stanza_namespace = applicationStanzaNamespace, application_stanza_body = applicationStanzaBody }; VxClient.Instance.BeginIssueRequest(request, result => { vx_resp_account_send_message_t response; try { response = VxClient.Instance.EndIssueRequest(result); _directedMessageResult = new DirectedMessageResult(response.request_id); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DirectedMessageResult))); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); return; } }); return(ar); }
public IAsyncResult BeginSetChannelTranscription(bool value, string accessToken, AsyncCallback callback) { AssertSessionNotDeleted(); AsyncNoResult ar = new AsyncNoResult(callback); // No need to issue the request if the current value is already what was passed in. if (_isSessionBeingTranscribed == value) { VivoxDebug.Instance.DebugMessage($"IsSessionBeingTranscribed is already {value.ToString()}. Returning.", vx_log_level.log_debug); ar.SetComplete(); return(ar); } var request = new vx_req_session_transcription_control_t { session_handle = this._sessionHandle, enable = value ? 1 : 0, access_token = accessToken }; VxClient.Instance.BeginIssueRequest(request, result => { try { var response = VxClient.Instance.EndIssueRequest(result); if (response.status_code == 0) { _isSessionBeingTranscribed = Convert.ToBoolean(request.enable); } } catch (Exception e) { VivoxDebug.Instance.DebugMessage($"BeginSetChannelTranscription() failed {e}", vx_log_level.log_error); ar.SetComplete(e); return; } ar.SetComplete(); }); return(ar); }
private void Login(string accessToken, string connectorHandle, AsyncNoResult ar, SubscriptionMode?mode = null) { vx_req_account_anonymous_login_t request = new vx_req_account_anonymous_login_t { account_handle = _accountHandle, connector_handle = connectorHandle, enable_buddies_and_presence = mode == null ? 0 : 1, acct_name = Key.AccountName, displayname = Key.DisplayName, languages = string.Join(",", Key.SpokenLanguages), access_token = accessToken, participant_property_frequency = (int)_participantPropertyFrequency }; if (mode != null) { request.buddy_management_mode = (vx_buddy_management_mode)mode.Value; } VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); State = LoginState.LoggedIn; ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); State = LoginState.LoggedOut; ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); }
public IAsyncResult BeginAddBlockedSubscription(AccountId userId, AsyncCallback callback) { AssertLoggedIn(); AsyncNoResult ar = new AsyncNoResult(callback); if (_blockedSubscriptions.Contains((userId))) { ar.SetCompletedSynchronously(); return(ar); } var request = new vx_req_account_create_block_rule_t { account_handle = _accountHandle, block_mask = userId.ToString(), presence_only = 0 }; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); _blockedSubscriptions.Add(userId); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); return(ar); }
public IAsyncResult SetIsMuteForAll(string accountHandle, bool setMuted, string accessToken, AsyncCallback callback) { if (string.IsNullOrEmpty(accessToken)) { throw new ArgumentNullException(nameof(accessToken)); } AsyncNoResult ar = new AsyncNoResult(callback); var request = new vx_req_channel_mute_user_t { account_handle = accountHandle, channel_uri = _parent.Key.ToString(), participant_uri = Account.ToString(), set_muted = setMuted ? 1 : 0, access_token = accessToken }; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); return(ar); }
public IAsyncResult BeginLogin( Uri server, string accessToken, SubscriptionMode subscriptionMode, IReadOnlyHashSet <AccountId> presenceSubscriptions, IReadOnlyHashSet <AccountId> blockedPresenceSubscriptions, IReadOnlyHashSet <AccountId> allowedPresenceSubscriptions, AsyncCallback callback) { if (string.IsNullOrEmpty(accessToken)) { throw new ArgumentNullException(nameof(accessToken)); } AssertLoggedOut(); AsyncNoResult result = new AsyncNoResult(callback); State = LoginState.LoggingIn; _client.BeginGetConnectorHandle(server, ar2 => { string connectorHandle; try { connectorHandle = _client.EndGetConnectorHandle(ar2); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"BeginGetConnectorHandle failed: {e}"); State = LoginState.LoggedOut; result.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } Debug.Write($"connectorHandle={connectorHandle}"); Login(accessToken, connectorHandle, result, subscriptionMode); }); return(result); }
public IAsyncResult BeginConnect(bool connectAudio, bool connectText, TransmitPolicy transmit, string accessToken, AsyncCallback callback) { AssertSessionNotDeleted(); if (string.IsNullOrEmpty(accessToken)) { throw new ArgumentNullException(nameof(accessToken)); } if (!connectAudio && !connectText) { throw new ArgumentException($"{GetType().Name}: connectAudio and connectText cannot both be false", nameof(connectAudio)); } if (AudioState != ConnectionState.Disconnected || TextState != ConnectionState.Disconnected) { throw new InvalidOperationException($"{GetType().Name}: Both AudioState and Text State must be disconnected"); } AsyncNoResult ar = new AsyncNoResult(callback); var request = new vx_req_sessiongroup_add_session_t { account_handle = _loginSession.AccountHandle, uri = Key.ToString(), session_handle = _sessionHandle, sessiongroup_handle = GroupId, connect_audio = connectAudio ? 1 : 0, connect_text = connectText ? 1 : 0, access_token = accessToken }; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); AudioState = ConnectionState.Disconnected; TextState = ConnectionState.Disconnected; ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); Debug.WriteLine(transmit); if (connectAudio) { switch (transmit) { case TransmitPolicy.No: { if (_loginSession.TransmittingSession == null) { SetNoSessionTransmitting(); } } break; case TransmitPolicy.Yes: { SetTransmitting(); } break; default: break; } AudioState = ConnectionState.Connecting; } if (connectText) { TextState = ConnectionState.Connecting; } return(ar); }
public IAsyncResult BeginAccountArchiveQuery(DateTime?timeStart, DateTime?timeEnd, string searchText, AccountId userId, ChannelId channel, uint max, string afterId, string beforeId, int firstMessageIndex, AsyncCallback callback) { AssertLoggedIn(); if (userId != null && channel != null) { throw new ArgumentException($"{GetType().Name}: Parameters {nameof(userId)} and {nameof(channel)} cannot be used at the same time"); } if (afterId != null && beforeId != null) { throw new ArgumentException($"{GetType().Name}: Parameters {nameof(afterId)} and {nameof(beforeId)} cannot be used at the same time"); } if (max > 50) { throw new ArgumentException($"{GetType().Name}: {nameof(max)} cannot be greater than 50"); } var ar = new AsyncNoResult(callback); var request = new vx_req_account_archive_query_t { account_handle = _accountHandle, max = max, after_id = afterId, before_id = beforeId, first_message_index = firstMessageIndex }; if (timeStart != null && timeStart != DateTime.MinValue) { request.time_start = timeStart?.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"); } if (timeEnd != null && timeEnd != DateTime.MaxValue) { request.time_end = timeEnd?.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"); } request.search_text = searchText; if (userId != null) { request.participant_uri = userId.ToString(); } else if (channel != null) { request.participant_uri = channel.ToString(); } VxClient.Instance.BeginIssueRequest(request, result => { vx_resp_account_archive_query_t response; try { response = VxClient.Instance.EndIssueRequest(result); _accountArchiveResult = new ArchiveQueryResult(response.query_id); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(AccountArchiveResult))); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); return(ar); }
public IAsyncResult BeginSessionArchiveQuery(DateTime?timeStart, DateTime?timeEnd, string searchText, AccountId userId, uint max, string afterId, string beforeId, int firstMessageIndex, AsyncCallback callback) { AssertSessionNotDeleted(); if (TextState != ConnectionState.Connected) { throw new InvalidOperationException($"{GetType().Name}: {nameof(TextState)} must equal ChannelState.Connected"); } if (afterId != null && beforeId != null) { throw new ArgumentException($"{GetType().Name}: Parameters {nameof(afterId)} and {nameof(beforeId)} cannot be used at the same time"); } if (max > 50) { throw new ArgumentException($"{GetType().Name}: {nameof(max)} cannot be greater than 50"); } var ar = new AsyncNoResult(callback); var request = new vx_req_session_archive_query_t { session_handle = _sessionHandle, max = max, after_id = afterId, before_id = beforeId, first_message_index = firstMessageIndex, search_text = searchText }; if (timeStart != null && timeStart != DateTime.MinValue) { request.time_start = (timeStart?.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")); } if (timeEnd != null && timeEnd != DateTime.MaxValue) { request.time_end = (timeEnd?.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")); } if (!AccountId.IsNullOrEmpty(userId)) { request.participant_uri = userId.ToString(); } VxClient.Instance.BeginIssueRequest(request, result => { vx_resp_session_archive_query_t response; try { response = VxClient.Instance.EndIssueRequest(result); _sessionArchiveResult = new ArchiveQueryResult(response.query_id); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SessionArchiveResult))); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); return(ar); }
public IAsyncResult BeginAddAllowedSubscription(AccountId userId, AsyncCallback callback) { AssertLoggedIn(); AsyncNoResult ar = new AsyncNoResult(callback); if (_allowedSubscriptions.Contains((userId))) { ar.SetCompletedSynchronously(); return(ar); } if (_incomingSubscriptionRequests.Contains(userId)) { var request = new vx_req_account_send_subscription_reply_t(); request.account_handle = _accountHandle; request.buddy_uri = userId.ToString(); request.rule_type = vx_rule_type.rule_allow; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); _incomingSubscriptionRequests.RemoveAll(userId); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); return; } }); return(ar); } else { var request = new vx_req_account_create_auto_accept_rule_t { account_handle = _accountHandle, auto_accept_mask = userId.ToString() }; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); _allowedSubscriptions.Add(userId); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); return(ar); } }
public IAsyncResult BeginSetTextConnected(bool value, AsyncCallback callback) { AssertSessionNotDeleted(); AsyncNoResult ar = new AsyncNoResult(callback); if (AlreadyDone(value, TextState)) { ar.CompletedSynchronously = true; ar.SetComplete(); } if (value) { var request = new vx_req_session_text_connect_t { session_handle = _sessionHandle }; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); TextState = ConnectionState.Connecting; return(ar); } else { var request = new vx_req_session_text_disconnect_t(); request.session_handle = _sessionHandle; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); TextState = ConnectionState.Disconnecting; return(ar); } }
public IAsyncResult BeginSetAudioConnected(bool value, bool switchTransmission, AsyncCallback callback) { AssertSessionNotDeleted(); AsyncNoResult ar = new AsyncNoResult(callback); if (value && switchTransmission) { _loginSession.SetTransmissionMode(TransmissionMode.Single, Key); } if (AlreadyDone(value, AudioState)) { ar.CompletedSynchronously = true; ar.SetComplete(); return(ar); } if (value) { var request = new vx_req_session_media_connect_t(); request.session_handle = _sessionHandle; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); AudioState = ConnectionState.Connecting; return(ar); } else { _loginSession.ClearTransmittingChannel(Channel); var request = new vx_req_session_media_disconnect_t(); request.session_handle = _sessionHandle; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); AudioState = ConnectionState.Disconnecting; return(ar); } }
public IAsyncResult BeginConnect(bool connectAudio, bool connectText, bool switchTransmission, string accessToken, AsyncCallback callback) { AssertSessionNotDeleted(); if (string.IsNullOrEmpty(accessToken)) { throw new ArgumentNullException(nameof(accessToken)); } if (!connectAudio && !connectText) { throw new ArgumentException($"{GetType().Name}: connectAudio and connectText cannot both be false", nameof(connectAudio)); } if (AudioState != ConnectionState.Disconnected || TextState != ConnectionState.Disconnected) { throw new InvalidOperationException($"{GetType().Name}: Both AudioState and Text State must be disconnected"); } AsyncNoResult ar = new AsyncNoResult(callback); var request = new vx_req_sessiongroup_add_session_t { account_handle = _loginSession.AccountHandle, uri = Key.ToString(), session_handle = _sessionHandle, sessiongroup_handle = GroupId, connect_audio = connectAudio ? 1 : 0, connect_text = connectText ? 1 : 0, access_token = accessToken }; VxClient.Instance.BeginIssueRequest(request, result => { try { VxClient.Instance.EndIssueRequest(result); ar.SetComplete(); } catch (Exception e) { VivoxDebug.Instance.VxExceptionMessage($"{request.GetType().Name} failed: {e}"); AudioState = ConnectionState.Disconnected; TextState = ConnectionState.Disconnected; ar.SetComplete(e); if (VivoxDebug.Instance.throwInternalExcepetions) { throw; } return; } }); if (connectAudio) { AudioState = ConnectionState.Connecting; } if (connectText) { TextState = ConnectionState.Connecting; } ChannelState = ConnectionState.Connecting; if (switchTransmission) { if (!connectAudio) { VivoxDebug.Instance.DebugMessage("Switching audio transmission exclusively to text-only channel -- this is allowed but unusual."); } _loginSession.SetTransmissionMode(TransmissionMode.Single, Key); } else { _loginSession.SetTransmission(); } return(ar); }