Added registration code for incoming calls, add incoming call actions to the UI

This commit is contained in:
QuentinArguillere
2020-08-04 17:54:59 +02:00
parent 24e23aaf59
commit 4830d38167
3 changed files with 126 additions and 104 deletions

View File

@@ -84,11 +84,11 @@
children = (
6604165624D451F10064FC6C /* AppDelegate.swift */,
6604165824D451F10064FC6C /* SceneDelegate.swift */,
6604166A24D453240064FC6C /* CallExample.swift */,
6604165A24D451F10064FC6C /* ContentView.swift */,
6604165C24D451F40064FC6C /* Assets.xcassets */,
6604166124D451F40064FC6C /* LaunchScreen.storyboard */,
6604166424D451F40064FC6C /* Info.plist */,
6604166A24D453240064FC6C /* CallExample.swift */,
6604165E24D451F40064FC6C /* Preview Content */,
);
path = CallTutorial;

View File

@@ -29,18 +29,18 @@ class CallExampleContext : ObservableObject
@Published var videoEnabled : Bool = false
@Published var speakerEnabled : Bool = false
@Published var callRunning : Bool = false
@Published var isCallIncoming : Bool = false
@Published var dest : String = "sip:arguillq@sip.linphone.org"
var proxy_cfg: ProxyConfig!
let mRegistrationDelegate = LinphoneRegistrationDelegate()
@Published var id : String = "sip:peche5@sip.linphone.org"
@Published var passwd : String = "peche5"
@Published var loggedIn: Bool = false
init()
{
mCallStateTracer.tutorialContext = self
mRegistrationDelegate.tutorialContext = self
let factory = Factory.Instance // Instanciate
@@ -59,9 +59,35 @@ class CallExampleContext : ObservableObject
try? mCore.start()
mVideoDevices = mCore.videoDevicesList
registrationExample()
mCore.addDelegate(delegate: mCallStateTracer)
mCore.addDelegate(delegate: mRegistrationDelegate)
}
func registrationExample()
{
let factory = Factory.Instance
do {
let proxy_cfg = try mCore.createProxyConfig()
let address = try factory.createAddress(addr: id)
let info = try factory.createAuthInfo(username: address.username, userid: "", passwd: passwd, ha1: "", realm: "", domain: address.domain)
mCore.addAuthInfo(info: info)
try proxy_cfg.setIdentityaddress(newValue: address)
let server_addr = "sip:" + address.domain + ";transport=tls"
try proxy_cfg.setServeraddr(newValue: server_addr)
proxy_cfg.registerEnabled = true
try mCore.addProxyConfig(config: proxy_cfg)
if ( mCore.defaultProxyConfig == nil)
{
// IMPORTANT : default proxy config setting MUST be done AFTER adding the config to the core !
mCore.defaultProxyConfig = proxy_cfg
}
} catch {
print(error)
}
}
// Initiate a call
@@ -82,7 +108,6 @@ class CallExampleContext : ObservableObject
print("Could not place call to \(dest)\n")
} else {
print("Call to \(dest) is in progress...")
callRunning = true
}
}
else
@@ -96,18 +121,16 @@ class CallExampleContext : ObservableObject
}
// Terminate a call
func stopOutgoingCallExample()
func stopCall()
{
if (callRunning)
{
callRunning = false
if (mCall.state != Call.State.End){
// terminate the call
print("Terminating the call...\n")
do {
try mCall.terminate()
} catch {
callRunning = true
print(error)
}
}
@@ -138,67 +161,13 @@ class CallExampleContext : ObservableObject
}
}
/*
func acceptCall(incomingCall call : Call)
{
mCall = call
do {
try call.accept()
} catch {
print(error)
}
}
*/
func createProxyConfigAndRegister(identity sId : String, password sPwd : String, factoryUri fUri : String) -> ProxyConfig?
func acceptCall()
{
let factory = Factory.Instance
do {
let proxy_cfg = try mCore.createProxyConfig()
let address = try factory.createAddress(addr: sId)
let info = try factory.createAuthInfo(username: address.username, userid: "", passwd: sPwd, ha1: "", realm: "", domain: address.domain)
mCore.addAuthInfo(info: info)
try proxy_cfg.setIdentityaddress(newValue: address)
let server_addr = "sip:" + address.domain + ";transport=tls"
try proxy_cfg.setServeraddr(newValue: server_addr)
proxy_cfg.registerEnabled = true
proxy_cfg.conferenceFactoryUri = fUri
try mCore.addProxyConfig(config: proxy_cfg)
if ( mCore.defaultProxyConfig == nil)
{
// IMPORTANT : default proxy config setting MUST be done AFTER adding the config to the core !
mCore.defaultProxyConfig = proxy_cfg
}
return proxy_cfg
} catch {
print(error)
}
return nil
}
func registrationExample()
{
let factory = Factory.Instance
do {
let proxy_cfg = try mCore.createProxyConfig()
let address = try factory.createAddress(addr: id)
let info = try factory.createAuthInfo(username: address.username, userid: "", passwd: passwd, ha1: "", realm: "", domain: address.domain)
mCore.addAuthInfo(info: info)
try proxy_cfg.setIdentityaddress(newValue: address)
let server_addr = "sip:" + address.domain + ";transport=tls"
try proxy_cfg.setServeraddr(newValue: server_addr)
proxy_cfg.registerEnabled = true
try mCore.addProxyConfig(config: proxy_cfg)
if ( mCore.defaultProxyConfig == nil)
{
// IMPORTANT : default proxy config setting MUST be done AFTER adding the config to the core !
mCore.defaultProxyConfig = proxy_cfg
}
loggedIn = true
try mCall.accept()
callRunning = true
isCallIncoming = false
} catch {
print(error)
}
@@ -206,7 +175,18 @@ class CallExampleContext : ObservableObject
}
class LinphoneRegistrationDelegate: CoreDelegate {
var tutorialContext : CallExampleContext!
override func onRegistrationStateChanged(lc: Core, cfg: ProxyConfig, cstate: RegistrationState, message: String?) {
print("New registration state \(cstate) for user id \( String(describing: cfg.identityAddress?.asString()))\n")
if (cstate == .Ok)
{
tutorialContext.loggedIn = true
}
}
}
class LinphoneLoggingServiceManager: LoggingServiceDelegate {
@@ -221,38 +201,20 @@ class LinphoneLoggingServiceManager: LoggingServiceDelegate {
}
}
let mCallStateTracer = CallStateDelegate()
class CallStateDelegate: CoreDelegate {
var tutorialContext : CallExampleContext!
override func onCallStateChanged(lc: Core, call: Call, cstate: Call.State, message: String) {
print("CallTrace - \(cstate)")
/*
let traceFn = { print("CallTrace - \(cstate)") }
switch cstate
{
case .IncomingReceived:
tutorialContext.acceptCall(incomingCall: call)
case .IncomingEarlyMedia:
traceFn()
case .PushIncomingReceived:
traceFn()
case .OutgoingRinging:
print("CallTrace - It is now ringing remotely !\n")
case .OutgoingEarlyMedia:
print("CallTrace - Receiving some early media\n")
case .Connected:
print("CallTrace - We are connected !\n")
case .StreamsRunning:
print("CallTrace - Media streams established !\n")
case .End:
print("CallTrace - Call is terminated.\n")
case .Error:
print("CallTrace - Call failure !")
default:
print("CallTrace - Unhandled notification \(cstate)\n")
if (cstate == .IncomingReceived) {
tutorialContext.mCall = call
tutorialContext.isCallIncoming = true
} else if (cstate == .OutgoingRinging) {
tutorialContext.callRunning = true
} else if (cstate == .End) {
tutorialContext.callRunning = false
}
*/
}
}

View File

@@ -12,18 +12,73 @@ struct ContentView: View {
@ObservedObject var tutorialContext = CallExampleContext()
func getCallButtonText() -> String
{
if (tutorialContext.isCallIncoming) {
return "Answer"
}
else if (tutorialContext.callRunning) {
return "Update Call"
}
else {
return "Call"
}
}
func callStateString() -> String
{
if (tutorialContext.isCallIncoming) {
return "Incoming call"
}
else if (tutorialContext.callRunning) {
return "Call running"
}
else {
return "No Call"
}
}
var body: some View {
VStack(alignment: .leading) {
Group {
HStack {
Text("Identity :")
.font(.subheadline)
TextField("", text : $tutorialContext.id)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
HStack {
Text("Password :")
.font(.subheadline)
TextField("", text : $tutorialContext.passwd)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
HStack {
Button(action: tutorialContext.registrationExample)
{
Text("Login")
.font(.largeTitle)
.foregroundColor(Color.white)
.frame(width: 90.0, height: 42.0)
.background(Color.gray)
}
Text("Login State : ")
.font(.footnote)
Text(tutorialContext.loggedIn ? "Looged in" : "Unregistered")
.font(.footnote)
.foregroundColor(tutorialContext.loggedIn ? Color.green : Color.black)
}
}
VStack(spacing: 0.0) {
Text("Call Settings")
.font(.largeTitle)
.padding(.top, 5)
HStack {
Text("Call destination :")
TextField("", text : $tutorialContext.dest)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
.padding(.top)
.padding(.top, 5)
}
VStack(alignment: .leading) {
Toggle(isOn: $tutorialContext.audioEnabled) {
@@ -56,15 +111,22 @@ struct ContentView: View {
Spacer()
VStack {
HStack {
Button(action: tutorialContext.outgoingCallExample)
Button(action: {
if (self.tutorialContext.isCallIncoming) {
self.tutorialContext.acceptCall()
}
else {
self.tutorialContext.outgoingCallExample()
}
})
{
Text(tutorialContext.callRunning ? "Update Call" : "Call")
Text(getCallButtonText())
.font(.largeTitle)
.foregroundColor(Color.white)
.frame(width: 180.0, height: 42.0)
.background(Color.green)
}
Button(action: tutorialContext.stopOutgoingCallExample) {
Button(action: tutorialContext.stopCall) {
Text("Stop Call")
.font(.largeTitle)
.foregroundColor(Color.white)
@@ -73,11 +135,9 @@ struct ContentView: View {
}
}
HStack {
Text("Call State : ")
Text(callStateString())
.font(.footnote)
Text(tutorialContext.callRunning ? "Ongoing" : "Stopped")
.font(.footnote)
.foregroundColor(tutorialContext.callRunning ? Color.green : Color.black)
.foregroundColor(tutorialContext.callRunning || tutorialContext.isCallIncoming ? Color.green : Color.black)
}
.padding(.top)
}