Open mrfarukturgut opened 4 years ago
When I added the following lines to the method onIncomingCall
in VSLEndpoint.m
, it is ringing on the caller side. However there is no ringing on your example project. Nothing happends. CallKitProviderDelegate
does not response to anything.
VSLCallManager *callManager = [VialerSIPLib sharedInstance].callManager;
VSLLogInfo(@"call: ** %@", [callManager callsForAccount:account]);
VSLCall *_call = [[VSLCall alloc] initInboundCallWithCallId:call_id account:account];
[callManager addCall:_call];
VSLCall *call = [callManager lastCallForAccount:account]; // TODO: safe to say that the last one is the right one?
@arjenfvellinga @smolskyaleksey @jeremynorman89 @ChrisKontosEU any interest to help, please?
About you addition of the 2 lines in the onIncomingCall
method:
VSLCall *_call = [[VSLCall alloc] initInboundCallWithCallId:call_id account:account];
[callManager addCall:_call];
We init and add the call in the func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith
method. See the changes Apple made regarding handling incoming push messages for incoming calls see https://forums.developer.apple.com/thread/117939
We are working on our own app to deal with these changes. There are changes to the library, but we didn't update the example app yet. So that could be the reason the incoming call is not working.
The simulator can not get incoming push notifications (I think), so therefor incoming calls won't work
I converted to 3.5.6 version and it works after some try. Can you please how do you get the call from didReceiveIncomingPushWith
and after init
it to the callManager
. Can you give some code sample? Lastly, is it possible to implement my own CallKit
delegation using the library?
This is our code
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
guard type == .voIP else { return }
// Extract the call information from the push notification payload.
if let phoneNumberString = payload.dictionaryPayload[PushedCall.MiddlewareAPNSPayloadKeyPhonenumber] as? String,
let uuidString = payload.dictionaryPayload[PushedCall.MiddlewareAPNSPayloadKeyUniqueKey] as? String {
// The uuid string in the payload is missing hyphens so fix that.
let callUUID = NSUUID.uuidFixer(uuidString: uuidString)! as UUID
// Configure the call information data structures.
let callUpdate = CXCallUpdate()
let phoneNumberHandle = CXHandle(type: .phoneNumber, value: phoneNumberString)
callUpdate.remoteHandle = phoneNumberHandle
callUpdate.localizedCallerName = phoneNumberString
if let callerId = payload.dictionaryPayload[PushedCall.MiddlewareAPNSPayloadKeyCallerId] as? String {
callUpdate.localizedCallerName = callerId
}
VialerLogDebug("Reporting a new call to CallKit provider with UUID: \(String(describing: callUUID.uuidString))")
appDelegate.callKitProviderDelegate.provider.reportNewIncomingCall(with: callUUID, update: callUpdate, completion: { (error) in
if error == nil { // The call is not blocked by DnD or blacklisted by the iPhone, so continue processing the call. At this stage account is not available - sip invite has not arrived yet.
if let newCall = VSLCall(inboundCallWith: callUUID, number: phoneNumberString, name:callUpdate.localizedCallerName ?? "") {
let callManager = VialerSIPLib.sharedInstance().callManager
callManager.add(newCall)
DispatchQueue.main.async {
self.middleware.handleReceivedAPSNPayload(payload.dictionaryPayload)
}
}
}
// Tell PushKit that the notification is handled.
completion()
})
}
}
So after this and some time the sip invite arrives in the onIncomingCall
method, and the call could be retrieved from the call manager (without your 2 added lines) .
Not sure what you mean with "is it possible to implement my own CallKit delegation using the library?"
Thanks for your answer. I will use it if I update the library to the current version. I made it work for version 3.5.6 with helps from @mudassirzulfiqar. So now, I can get calls and make outgoing calls.
But there is problem with the implemation of the CallKit
in the example project. It was working showing the native UI when there is a incoming call however when I answer it, it is switching to the UI which you have designed. I want to convert it to the native UI as well, for both incoming and outgoing calls. So I disabled the CallKitProviderDelegate.m
references in the example project and implemented them on my own from your obj-c
to swift
in the AppDelegate
. However right now when there is an incoming call, it shows the native UI but when I answer it -even though audio session is working- it just flashes the native UI
that has mute, audio output, audio session lenght, caller number etc and then goes back to the lastest page of the app. But sound is working.
I asked it because of this situtation.
I understand what you'te trying to achieve. sadly I can't help with that. We are aware that the example app is not up-to-date anymore, but unfortunately we currently have no time to spend time on it.
Good you have incoming calls working. Does that complies with the changes introduced with iOS 13 / Apple I linked earlier?
If you are saying whether I implemented the PKPushRegistry
or not, no I did not. Thanks for your help.
The simulator cannot get push notifications so do not expect incoming calls there. The example project as Arjen mentioned is currently outdated. Would be great if someone could pick it up and repair it with a pull request. After all this is an opensource project.
Yeah I did not know that the Simulator was not be able to get notifications and now learned the hard way :) After I finish the this project, if I have some free time I would help you to not just update the example project but also converting the lib to the swift.
@arjenfvellinga Hey, due to your answer regards to PushKit
; how are you managing to get info about the call itself and report it to the CallKit
. You have something called PushedCall
in your code and it is not included in the library. I am not able to examine the payloadDictionary
as it turned out that method is not working when CallKit
is not notified. As I can not notify the CallKit
this method not working and I can not learn what is what
@mrfarukturgut A colleague of mine will get back to you with an answer.
@arjenfvellinga Hey, due to your answer regards to
PushKit
; how are you managing to get info about the call itself and report it to theCallKit
. You have something calledPushedCall
in your code and it is not included in the library. I am not able to examine thepayloadDictionary
as it turned out that method is not working whenCallKit
is not notified. As I can not notify theCallKit
this method not working and I can not learn what is what
The payload contains information sent by your push server, in our case we are sending a call id and the name/number of the caller. This is the information that can be used to immediately launch the call kit, and then the actual sip call is tied based on the call id when it has been created.
With iOS 13 the main thing to be aware of is you must only send one push message per call. At least in our previous implementations we would send multiple push messages to make sure the phone got them, this will result in crashes in iOS 13.
hello arjenfvellinga, I tried the same thing for VOIP notification callback but I got error as PJSIP_ESESSIONTERMINATED as invited is terminated. please help up me to resolve this issue. Thank you
hello arjenfvellinga, I tried the same thing for VOIP notification callback but I got error as PJSIP_ESESSIONTERMINATED as invited is terminated. please help up me to resolve this issue. Thank you
We re-wrote our APNS handling code, you can see it here: https://github.com/VoIPGRID/vialer-ios/tree/master/Vialer/Push with PushKitManager being the entry point that is called by APNS when a notification is received.
hello arjenfvellinga, I tried the same thing for VOIP notification callback but I got error as PJSIP_ESESSIONTERMINATED as invited is terminated. please help up me to resolve this issue. Thank you
We re-wrote our APNS handling code, you can see it here: https://github.com/VoIPGRID/vialer-ios/tree/master/Vialer/Push with PushKitManager being the entry point that is called by APNS when a notification is received.
Hello jeremynorman89, Thank you for your reply. I stuck at one thing unique_key from VOIP push notification, what this key refer and how it will link to the opposite person initiated call.
For the reference will let you know clearly,
I want to initiate a call from A to B :
Case 1: Both Online when ever I open the apps, register or SIP clients to our server. And initiating a call using startCallToNumber method, at B side automatically incomingCall block is executing the request with callId and sipInvite.
Case 2: B is Offline From A side,I register my A client to backend server with SIP profile. When ever I initiate a call from A to B, sending A side VSLCall call UUID to server. And server will look after of B status , if B is offline will send one VOIP push notification to B. At the B side when ever I got VOIP notification register the SIP client to server once registration is done, creating a VSLCall object using client A created VSLCall UUID. When ever I answer the call getting error at _pjsua_call_answer2 method as (char [80]) statusmsg = "INVITE session already terminated (PJSIP_ESESSIONTERMINATED)"._
So, I got stuck what is the id we need to pass to link the call from A to B.As I observer new VoIPPushHandler its taking unique_key of VOIP payload to create call object.what is this value for unique_key?
Can you please help me to resolve this issue.
Thank you.
So, I got stuck what is the id we need to pass to link the call from A to B.As I observer new VoIPPushHandler its taking unique_key of VOIP payload to create call object.what is this value for unique_key?
Can you please help me to resolve this issue.
Thank you.
It's the Call-ID that we add hyphens to so it conforms to a UUID. However, I don't think it matters, any UUID should do. But you do need to make sure that the call is created when your push notification arrives, before you begin registering with SIP. As you can see onIncomingCall expects the call object to already be created:
Hello
So, I got stuck what is the id we need to pass to link the call from A to B.As I observer new VoIPPushHandler its taking unique_key of VOIP payload to create call object.what is this value for unique_key? Can you please help me to resolve this issue. Thank you.
It's the Call-ID that we add hyphens to so it conforms to a UUID. However, I don't think it matters, any UUID should do. But you do need to make sure that the call is created when your push notification arrives, before you begin registering with SIP. As you can see onIncomingCall expects the call object to already be created:
Thanks for the response,as I tried VSLCall *call = [callManager lastCallForAccount:account];
also got same error because CallKit is initiating the call, in the meanwhile I am registered the SIP account for getting invite its taking time. I tried reinviteActiveCallsForAccount
also to get existing invites to process it won't help.
Hi Team, Finally I did it, with dummy callUUID, and answer the call when user answered. But for milliseconds till the SIP Invite came, its blank call and updating the existing call with new VCLCall object.
Thank you
@jeremynorman89 @krishnastvSMSC
Hi guys, The only thing that I'm missing, is what happen if the user answer the call before this sip is registered? When it happens, I get the following error: Could not answer call PJSIP returned status: INVITE session already terminated (PJSIP_ESESSIONTERMINATED) Error answering call() error:Error Domain=VialerSIPLib.VSLCall Code=2 "Could not answer call" UserInfo={NSLocalizedDescription=Could not answer call, NSLocalizedFailureReason=PJSIP status code: 171140}
in such case, the call is not established, and the receiver see the call screen with "cancel/dial back" and the caller still hearing the ringing tone.
any ideas how to overcome this?
Best regards!
@shaydvir i got same problem : "INVITE session already terminated", did u solved this?
Hi @fukemy ,
I don't exactly remember how we nailed it, I think it was using asyncAfter() in order to register the call after the SIP is registered.
tks, let me try
File / Feature
Example Project
Expected behavior
The app should show incoming call page and ringtone should play.
Actual behavior
Nothing happens at UI. However it logs about an incoming call.
Stacktrace / Error message
Other info
Calling from the example project to another softphone application works like a charm. I have encountered another error about pjsip and fixed it by giving "useVideo" parameter of the endpoint true like this;
endpointConfiguration.disableVideoSupport = prefs.bool(forKey: "useVideo")
The error was about validating the SDP as follows;
Assertion failed: ((status=pjmedia_sdp_validate(l_sdp))==PJ_SUCCESS), function pjsip_inv_verify_request3, file ../src/pjsip-ua/sip_inv.c, line 1183.
Solution is from; https://www.spinics.net/lists/pjsip/msg18883.html
Another thing is I am trying to call the app which is running on a simulator. And they have different IPs.
Finally I changed the server IP to 255.255.255.255