142 lines
5.5 KiB
Swift
142 lines
5.5 KiB
Swift
//
|
|
// CallExample.swift
|
|
// CallTutorial
|
|
//
|
|
// Created by QuentinArguillere on 31/07/2020.
|
|
// Copyright © 2020 BelledonneCommunications. All rights reserved.
|
|
//
|
|
|
|
import linphonesw
|
|
import AVFoundation
|
|
|
|
class CallKitExampleContext : ObservableObject
|
|
{
|
|
var mCore: Core!
|
|
@Published var coreVersion: String = Core.getVersion
|
|
|
|
var mAccount: Account?
|
|
var mCoreDelegate : CoreDelegate!
|
|
@Published var username : String = "user"
|
|
@Published var passwd : String = "pwd"
|
|
@Published var domain : String = "sip.example.org"
|
|
@Published var loggedIn: Bool = false
|
|
@Published var transportType : String = "TLS"
|
|
|
|
@Published var callMsg : String = ""
|
|
@Published var isCallIncoming : Bool = false
|
|
@Published var isCallRunning : Bool = false
|
|
@Published var remoteAddress : String = "Nobody yet"
|
|
@Published var isSpeakerEnabled : Bool = false
|
|
@Published var isMicrophoneEnabled : Bool = false
|
|
|
|
/*------------ Callkit tutorial related variables ---------------*/
|
|
let incomingCallName = "Incoming call example"
|
|
var mCall : Call?
|
|
var mProviderDelegate : CallKitProviderDelegate!
|
|
var mCallAlreadyStopped : Bool = false;
|
|
|
|
init()
|
|
{
|
|
LoggingService.Instance.logLevel = LogLevel.Debug
|
|
|
|
let factory = Factory.Instance
|
|
// IMPORTANT : In this tutorial, we require the use of a core configuration file.
|
|
// This way, once the registration is done, and until it is cleared, it will return to the LoggedIn state on launch.
|
|
// This allows us to have a functional call when the app was closed and is started by a VOIP push notification (incoming call
|
|
// We also need to enable "Push Notitifications" and "Background Mode - Voice Over IP"
|
|
let configDir = factory.getConfigDir(context: nil)
|
|
try? mCore = factory.createCore(configPath: "\(configDir)/MyConfig", factoryConfigPath: "", systemContext: nil)
|
|
mProviderDelegate = CallKitProviderDelegate(context: self)
|
|
// enabling push notifications management in the core
|
|
mCore.callkitEnabled = true
|
|
mCore.pushNotificationEnabled = true
|
|
try? mCore.start()
|
|
|
|
mCoreDelegate = CoreDelegateStub( onCallStateChanged: { (core: Core, call: Call, state: Call.State, message: String) in
|
|
self.callMsg = message
|
|
|
|
if (state == .PushIncomingReceived){
|
|
// We're being called by someone (and app is in background)
|
|
self.mCall = call
|
|
self.isCallIncoming = true
|
|
self.mProviderDelegate.incomingCall()
|
|
} else if (state == .IncomingReceived) {
|
|
// If app is in foreground, it's likely that we will receive the SIP invite before the Push notification
|
|
if (!self.isCallIncoming) {
|
|
self.mCall = call
|
|
self.isCallIncoming = true
|
|
self.mProviderDelegate.incomingCall()
|
|
}
|
|
self.remoteAddress = call.remoteAddress!.asStringUriOnly()
|
|
} else if (state == .Connected) {
|
|
self.isCallIncoming = false
|
|
self.isCallRunning = true
|
|
} else if (state == .Released || state == .End || state == .Error) {
|
|
// Call has been terminated by any side
|
|
|
|
// Report to CallKit that the call is over, if the terminate action was initiated by other end of the call
|
|
if (self.isCallRunning) {
|
|
self.mProviderDelegate.stopCall()
|
|
}
|
|
self.remoteAddress = "Nobody yet"
|
|
}
|
|
}, onAccountRegistrationStateChanged: { (core: Core, account: Account, state: RegistrationState, message: String) in
|
|
NSLog("New registration state is \(state) for user id \( String(describing: account.params?.identityAddress?.asString()))\n")
|
|
if (state == .Ok) {
|
|
self.loggedIn = true
|
|
// Since core has "Push Enabled", the reception and setting of the push notification token is done automatically
|
|
// It should have been set and used when we log in, you can check here or in the liblinphone logs
|
|
NSLog("Account registered Push voip token: \(account.params?.pushNotificationConfig?.voipToken)")
|
|
} else if (state == .Cleared) {
|
|
self.loggedIn = false
|
|
}
|
|
})
|
|
mCore.addDelegate(delegate: mCoreDelegate)
|
|
}
|
|
|
|
func login() {
|
|
|
|
do {
|
|
var transport : TransportType
|
|
if (transportType == "TLS") { transport = TransportType.Tls }
|
|
else if (transportType == "TCP") { transport = TransportType.Tcp }
|
|
else { transport = TransportType.Udp }
|
|
|
|
let authInfo = try Factory.Instance.createAuthInfo(username: username, userid: "", passwd: passwd, ha1: "", realm: "", domain: domain)
|
|
let accountParams = try mCore.createAccountParams()
|
|
let identity = try Factory.Instance.createAddress(addr: String("sip:" + username + "@" + domain))
|
|
try! accountParams.setIdentityaddress(newValue: identity)
|
|
let address = try Factory.Instance.createAddress(addr: String("sip:" + domain))
|
|
try address.setTransport(newValue: transport)
|
|
try accountParams.setServeraddress(newValue: address)
|
|
accountParams.registerEnabled = true
|
|
// Enable push notifications on this account
|
|
accountParams.pushNotificationAllowed = true
|
|
// We're in a sandbox application, so we must set the provider to "apns.dev" since it will be "apns" by default, which is used only for production apps
|
|
accountParams.pushNotificationConfig?.provider = "apns.dev"
|
|
mAccount = try mCore.createAccount(params: accountParams)
|
|
mCore.addAuthInfo(info: authInfo)
|
|
try mCore.addAccount(account: mAccount!)
|
|
mCore.defaultAccount = mAccount
|
|
|
|
} catch { NSLog(error.localizedDescription) }
|
|
}
|
|
|
|
func unregister()
|
|
{
|
|
if let account = mCore.defaultAccount {
|
|
let params = account.params
|
|
let clonedParams = params?.clone()
|
|
clonedParams?.registerEnabled = false
|
|
account.params = clonedParams
|
|
}
|
|
}
|
|
func delete() {
|
|
if let account = mCore.defaultAccount {
|
|
mCore.removeAccount(account: account)
|
|
mCore.clearAccounts()
|
|
mCore.clearAllAuthInfo()
|
|
}
|
|
}
|
|
}
|