void LinphoneMainLoop() { LOG.Debug("Main loop started"); bool isRunning = true; bool dequeCommand; while (isRunning) { regulator.WaitOne(30); // fire each 30 msec dequeCommand = true; try { if (commandQueue.Count > 0) { LinphoneCommand command; lock(commandQueue) { command = commandQueue.Peek(); } if (command != null) { switch (command.Command) { case LinphoneCommandType.TerminateCall: var terminateCmd = command as TerminateCallCommand; if (terminateCmd != null) LinphoneAPI.linphone_core_terminate_call(LinphoneCore, terminateCmd.CallPtr); break; case LinphoneCommandType.TerminateAllCalls: LinphoneAPI.linphone_core_terminate_all_calls(linphoneCore); break; case LinphoneCommandType.AcceptCall: var acceptCmd = command as AcceptCallCommand; if (acceptCmd != null) LinphoneAPI.linphone_core_accept_call_with_params(linphoneCore, acceptCmd.CallPtr, acceptCmd.CallParamsPtr); break; case LinphoneCommandType.DeclineCall: var declineCmd = command as DeclineCallCommand; if (declineCmd != null) LinphoneAPI.linphone_core_decline_call(linphoneCore, declineCmd.CallPtr, declineCmd.Reason); break; case LinphoneCommandType.CreateCall: { var createCmd = command as CreateCallCommand; if (createCmd != null) { // enable rtt LinphoneAPI.linphone_call_params_enable_realtime_text(createCmd.CallParamsPtr, createCmd.EnableRtt); MuteCall(createCmd.MuteMicrophone); MuteSpeaker(createCmd.MuteSpeaker); IntPtr callPtr = LinphoneAPI.linphone_core_invite_with_params(linphoneCore, createCmd.Callee, createCmd.CallParamsPtr); if (callPtr == IntPtr.Zero) { if (ErrorEvent != null) ErrorEvent(null, "Cannot create call to " + createCmd.Callee); } if (createCmd.CallParamsPtr != IntPtr.Zero) LinphoneAPI.linphone_call_params_destroy(createCmd.CallParamsPtr); } } break; case LinphoneCommandType.StopLinphone: isRunning = false; break; case LinphoneCommandType.PauseCall: var pauseCmd = command as PauseCallCommand; if (pauseCmd != null) { dequeCommand = LinphoneAPI.linphone_call_media_in_progress(pauseCmd.CallPtr) == 0; if (dequeCommand) LinphoneAPI.linphone_core_pause_call(linphoneCore, pauseCmd.CallPtr); } break; case LinphoneCommandType.ResumeCall: var resumeCmd = command as ResumeCallCommand; if (resumeCmd != null) { dequeCommand = LinphoneAPI.linphone_call_media_in_progress(resumeCmd.CallPtr) == 0; if (dequeCommand) LinphoneAPI.linphone_core_resume_call(linphoneCore, resumeCmd.CallPtr); } break; case LinphoneCommandType.MuteCall: var muteCmd = command as MuteCallCommand; if (muteCmd != null) { IntPtr callPtr = LinphoneAPI.linphone_core_get_current_call(linphoneCore); dequeCommand = callPtr == IntPtr.Zero; if (callPtr != IntPtr.Zero) dequeCommand = LinphoneAPI.linphone_call_media_in_progress(callPtr) == 0; if (dequeCommand) LinphoneAPI.linphone_core_enable_mic(linphoneCore, muteCmd.MuteOn); } break; case LinphoneCommandType.SendChatMessage: { var msgCmd = command as SendChatMessageCommand; if (msgCmd != null) { IntPtr callbacks = LinphoneAPI.linphone_chat_message_get_callbacks(msgCmd.CallPtr); LinphoneAPI.linphone_chat_message_cbs_set_msg_state_changed(callbacks, Marshal.GetFunctionPointerForDelegate(message_status_changed)); LinphoneAPI.linphone_chat_room_send_chat_message(msgCmd.ChatPtr, msgCmd.CallPtr); LinphoneAPI.linphone_chat_message_unref(msgCmd.CallPtr); } break; } case LinphoneCommandType.ToggleCamera: { var msgCmd = command as ToggleCameraCommand; if (msgCmd != null) { IntPtr callPtr = LinphoneAPI.linphone_core_get_current_call(linphoneCore); if (msgCmd.CallPtr == callPtr) { LinphoneAPI.linphone_call_enable_camera(callPtr, msgCmd.EnableCamera); } } break; } } } if (dequeCommand) { lock (commandQueue) { commandQueue.Dequeue(); } } } LinphoneAPI.linphone_core_iterate(linphoneCore); // roll } catch (Exception ex) { LOG.Debug("************ Linphone Main loop exception: " + ex.Message); } } LinphoneAPI.linphone_core_iterate(linphoneCore); // roll if (vtablePtr != IntPtr.Zero) { Marshal.FreeHGlobal(vtablePtr); vtablePtr = IntPtr.Zero; } if (t_configPtr != IntPtr.Zero) { Marshal.FreeHGlobal(t_configPtr); t_configPtr = IntPtr.Zero; } if (_cardDavStatsPtr != IntPtr.Zero) { Marshal.FreeHGlobal(_cardDavStatsPtr); _cardDavStatsPtr = IntPtr.Zero; } //Marshal.FreeHGlobal(linphoneCore); LinphoneAPI.linphone_core_destroy(linphoneCore); registration_state_changed = null; call_state_changed = null; notify_received = null; info_received = null; network_reachable = null; message_received = null; message_status_changed = null; call_log_updated = null; carddav_new_contact = null; carddav_removed_contact = null; carddav_updated_contact = null; carddav_sync_done = null; carddav_auth = IntPtr.Zero; linphoneCore = proxy_cfg = auth_info = t_configPtr = IntPtr.Zero; call_stats_updated = null; coreLoop = null; _isStarting = false; _isStarted = false; _isStopping = false; _isStopped = true; LOG.Debug("Main loop exited"); if (ServiceStopped != null) ServiceStopped(this, EventArgs.Empty); }
public bool Start(bool enableLogs) { if (IsStarting) return false; if (IsStarted) return true; linphone_log_received = new LinphoneLogFuncCB(OnLinphoneLog); try { if (enableLogs) { #if !USE_LINPHONE_LOGGING LinphoneAPI.linphone_core_enable_logs(IntPtr.Zero); LinphoneAPI.linphone_core_set_log_level_mask(OrtpLogLevel.ORTP_DEBUG); #else LinphoneAPI.linphone_core_enable_logs_with_cb(Marshal.GetFunctionPointerForDelegate(linphone_log_received)); #endif } else LinphoneAPI.linphone_core_disable_logs(); } catch (Exception ex) { LOG.Debug(ex.ToString()); } registration_state_changed = new LinphoneCoreRegistrationStateChangedCb(OnRegistrationChanged); call_state_changed = new LinphoneCoreCallStateChangedCb(OnCallStateChanged); global_state_changed = new LinphoneCoreGlobalStateChangedCb(OnGlobalStateChanged); notify_received = new LinphoneCoreNotifyReceivedCb(OnNotifyEventReceived); call_stats_updated = new LinphoneCoreCallStatsUpdatedCb(OnCallStatsUpdated); is_composing_received = new LinphoneCoreIsComposingReceivedCb(OnIsComposingReceived); message_received = new LinphoneCoreMessageReceivedCb(OnMessageReceived); message_status_changed = new LinphoneChatMessageCbsMsgStateChangedCb(OnMessageStatusChanged); call_log_updated = new LinphoneCoreCallLogUpdatedCb(OnCallLogUpdated); info_received = new LinphoneCoreInfoReceivedCb(OnInfoEventReceived); network_reachable = new LinphoneCoreNetworkReachableCb(OnNetworkReachable); // cardDAV stuff carddav_new_contact = new LinphoneFriendListContactCreatedCb(OnCardDAVContactCreated); carddav_removed_contact = new LinphoneFriendListContactDeletedCb(OnCardDAVContactRemoved); carddav_updated_contact = new LinphoneFriendListContactUpdatedCb(OnCardDAVContactUpdated); carddav_sync_done = new LinphoneFriendListSyncStateChangedCb(OnCardDAVSyncChanged); vtable = new LinphoneCoreVTable() { global_state_changed = Marshal.GetFunctionPointerForDelegate(global_state_changed), registration_state_changed = Marshal.GetFunctionPointerForDelegate(registration_state_changed), call_state_changed = Marshal.GetFunctionPointerForDelegate(call_state_changed), notify_presence_received = IntPtr.Zero, new_subscription_requested = IntPtr.Zero, auth_info_requested = IntPtr.Zero, call_log_updated = Marshal.GetFunctionPointerForDelegate(call_log_updated), message_received = Marshal.GetFunctionPointerForDelegate(message_received), is_composing_received = Marshal.GetFunctionPointerForDelegate(is_composing_received), dtmf_received = IntPtr.Zero, refer_received = IntPtr.Zero, call_encryption_changed = IntPtr.Zero, transfer_state_changed = IntPtr.Zero, buddy_info_updated = IntPtr.Zero, call_stats_updated = Marshal.GetFunctionPointerForDelegate(call_stats_updated), info_received = Marshal.GetFunctionPointerForDelegate(info_received), network_reachable = Marshal.GetFunctionPointerForDelegate(network_reachable), subscription_state_changed = IntPtr.Zero, notify_received = Marshal.GetFunctionPointerForDelegate(notify_received), publish_state_changed = IntPtr.Zero, configuring_status = IntPtr.Zero, display_status = IntPtr.Zero, display_message = IntPtr.Zero, display_warning = IntPtr.Zero, display_url = IntPtr.Zero, show = IntPtr.Zero, text_received = IntPtr.Zero, }; vtablePtr = Marshal.AllocHGlobal(Marshal.SizeOf(vtable)); Marshal.StructureToPtr(vtable, vtablePtr, false); string configPath = manager.BuildStoragePath("linphonerc.cfg"); linphoneCore = LinphoneAPI.linphone_core_new(vtablePtr, configPath, null, IntPtr.Zero); if (linphoneCore != IntPtr.Zero) { LinphoneAPI.libmsopenh264_init(LinphoneAPI.linphone_core_get_ms_factory(linphoneCore)); // Liz E. - this is set in the account settings now //LinphoneAPI.linphone_core_set_video_preset(linphoneCore, "high-fps"); LinphoneAPI.linphone_core_enable_video_capture(linphoneCore, true); LinphoneAPI.linphone_core_enable_video_display(linphoneCore, true); LinphoneAPI.linphone_core_enable_video_preview(linphoneCore, false); LinphoneAPI.linphone_core_set_native_preview_window_id(linphoneCore, -1); LinphoneAPI.linphone_core_set_upload_bandwidth(linphoneCore, 1500); LinphoneAPI.linphone_core_set_download_bandwidth(linphoneCore, 1500); string codeBase = Assembly.GetExecutingAssembly().CodeBase; UriBuilder uri = new UriBuilder(codeBase); string path = Uri.UnescapeDataString(uri.Path); string directory = String.Empty; if (!string.IsNullOrEmpty(path)) { directory = Path.GetDirectoryName(path); } if (!string.IsNullOrEmpty(directory )) { var rootCAPath = Path.Combine(directory, "rootca.pem"); LinphoneAPI.linphone_core_set_root_ca(linphoneCore, rootCAPath); var noVideoImagePath = Path.Combine(directory, "images"); noVideoImagePath = Path.Combine(noVideoImagePath, "camera_disabled.jpg"); LinphoneAPI.ms_static_image_set_default_image(noVideoImagePath); } LinphoneAPI.linphone_core_verify_server_cn(linphoneCore, true); LinphoneAPI.linphone_core_verify_server_certificates(linphoneCore, true); // load installed codecs LoadAudioCodecs(); LoadVideoCodecs(); IntPtr defProxyCfg = LinphoneAPI.linphone_core_get_default_proxy_config(linphoneCore); if (defProxyCfg != IntPtr.Zero) { proxy_cfg = defProxyCfg; LinphoneAPI.linphone_proxy_config_edit(proxy_cfg); LinphoneAPI.linphone_proxy_config_enable_register(proxy_cfg, false); LinphoneAPI.linphone_proxy_config_done(proxy_cfg); } ClearProxyInformation(); IntPtr coreConfig = LinphoneAPI.linphone_core_get_config(linphoneCore); if (coreConfig != IntPtr.Zero) { LinphoneAPI.lp_config_set_int(coreConfig, "sip", "tcp_tls_keepalive", 1); LinphoneAPI.lp_config_set_int(coreConfig, "sip", "keepalive_period", 90000); LinphoneAPI.lp_config_set_int(coreConfig, "sip", "auto_net_state_mon", 1); // enable linphone network monitoring // store contacts as vcard LinphoneAPI.lp_config_set_int(coreConfig, "misc", "store_friends", 1); // VATRP-2130, prevent SIP spam LinphoneAPI.lp_config_set_int(coreConfig, "sip", "sip_random_port", 1); // force to set random ports } LinphoneAPI.linphone_core_enable_keep_alive(linphoneCore, false); coreLoop = new Thread(LinphoneMainLoop) {IsBackground = true}; coreLoop.Start(); _isStarting = false; _isStopping = false; _isStopped = false; _isStarted = true; } if (ServiceStarted != null) ServiceStarted(this, EventArgs.Empty); return _isStarted; }