I have a problem with call transfer using pjsua2 api. Actually I don't understand how this should be implemented for call transfer (REFER method).
My issue is on the transferee: when the transferee receives the REFER message, after sending NOTIFY to the transferor it creates the call to the transfer target: But the same Call class instance is used for both calls (the lookup method changes the id to match the searched id), while pjsua has 2 different call ids for the old and new calls.
Therefore, when the transferee receives the BYE from the transferor, it deletes the Call instance which is used for both calls, whereas pjsua still keeps a reference to the new call with the target transfer, which ends with a program exception.
I implemented the onCallTransferRequest() callback in the transferee but I don't see what to do here (pjsua doesn't do anything in its similar callback...)
My question is: how should I process this kind of transfer using pjsua2?
Thanks for your help and merry Christmas.
Thibault
Unfortunately I am not expert in C++. If I may, I can explain you how to blind transfer an active SIP call generally in PJSUA2.
First of all you have to create CallOpParam-object with default call settings. Then, you have to call your current Call-object and transfer method on it. As I know, blind transfer method should take two (2) parameters, destination as a String and CallOpParam. You should specify destination as: sip:username#domain. Last thing you have to do is set a status code to your CallOpParam, it should be PJSIP_SC_DECLINE, and hang up your active Call.
After all that B and C partner should be able to talk.
Related
I know how to send data to DriverKit and get back some values, that is application calling IOConnectCallStructMethod() and driver fill the OSData in structureOutput from application.
In my Application it is using IOConnectCallAsyncScalarMethod() and the kext using sendAsyncResult64() to let the app know events coming in. However the method sendAsyncResult64() is not available in DriverKit.
I saw AsyncCompletion looks like solution but no idea to implement it. Anyone know how to do?
Appreciate if any suggestion!
IOUserClient::AsyncCompletion is indeed the replacement for sendAsyncResult64().
To call it successfully, you need to retain the OSAction object supplied in the completion field of the IOUserClientMethodArguments supplied in your ExternalMethod dispatch function. Then, when you are ready to send an asynchronous result, call
userclient->AsyncCompletion(saved_osaction, result, async_arguments, num_async_arguments);
Don't forget to release the OSAction object once you no longer need it. The array of async arguments will be passed to the handler function in the user space application, same as with a kext calling sendAsyncResult64().
Note that you can't asynchronously fill "small" structureOutput fields (4096 bytes or less) as these must be returned in the ExternalMethod handler. Only if the buffer is large enough to be passed via structureOutputDescriptor can you retain that descriptor and fill it with data after the initial ExternalMethod returns. This is no different than for kexts, however.
I've been trying to implement a call centre type system using Taskrouter using this guide as a base:
https://www.twilio.com/docs/tutorials/walkthrough/dynamic-call-center/ruby/rails
Project location is Australia, if that affects call details.
This system dials multiple numbers (workers), and I have run into an issue where phones will continue to ring even after the call has been accepted or cancelled.
ie. If Taskrouter calls Workers A and B, and A picks up first they are connected to the customer, but B will continue to ring. If B then picks up the phone they are greeted by a hangup tone. Ringing can continue for at least minutes until B picks up (I haven't checked if it ever times out).
Similar occurs if no one picks up and the call simply times out and is redirected to voicemail. As you can imagine, an endlessly ringing phone is pretty annoying, especially when there's no one on the other end.
I was able to replicate this issue using the above guide without modification (other than the minimum changes to set it up locally). Note that it doesn't dial workers simultaneously, rather it dials the first in line for a few seconds before moving to the next.
My interpretation of what is occurring is that Taskrouter is dialling workers, but not updating them when dialling should end, and simply moving on to the next stage of the workflow. It does update Worker status, so it knows if they've timed out for instance, but that doesn't update the actual call.
I have looked for any solutions to this and havent found much about it except the following:
How to make Twilio stop dialing numbers when hangup() is fired?
https://www.twilio.com/docs/api/rest/change-call-state
These don't specifically apply to Taskrouter, but suggest that a call that needs to be ended can be updated and completed.
I am not too sure if I can implement this however, as it seems to be using the same CallSid for all calls being dialled within a Workflow, makes it hard/impossible to seperate each call, and would end the active call as well.
It also just seems wrong that Taskrouter wouldn't be doing this automatically, so I wanted to ask about this before I tinker too much and break things.
Has anyone run into this issue before, or is able/unable to replicate it using the tutorial code?
When testing I've noticed the problem much more on landline numbers, which may only be because mobiles have their own timeout/redirects. VOIPs seem to immediately answer calls, so they behave a bit differently.
Any help/suggestions appreciated, thanks!
Current suggestion to work around this is to not issue the dequeue instruction immediately, but rather issue a Call instruction on the REST API when the Worker wishes to accept the Inbound Call.
This will create an Outbound Call to bridge the two calls together and thus won’t have many outbound calls for the same inbound caller at once.
Your implementation will depend on the behavior that you want to achieve:
Do you want to simul-dial both Workers?
Do you want to send
the task to both Workers and whoever clicks to Accept the Task first
will have the call routed to them?
If it's #2, this is a scenario where you're saying that the Worker should accept the Reservation (reservation.accepted) before issuing the Call.
If it's #1, you can either issue a Call Instruction or Dequeue Instruction. The key being that you provide a DequeueStatusCallbackUrl or CallStatusCallbackUrl to receive call progress events. Once one of the outbound calls is connected, you will need to complete the other associated call. So you will have to unfortunately track which outbound calls are tied to which Reservation, by using AssignmentCallbacks or EventCallbacks, to make that determination within your app.
I have a cakephp application. I have used webrtc for the video chat between peer groups and used XHR for the peer connection.
Problem: I want to pass a message to the callee about the call so
that callee can receive the call.
After searching on the Internet I come up with the some solutions:
Refresh the page say ( after 5 seconds) and check whether call
has initiated, If initiated show popup ( Initiation can be checked
though Database).
Make Ajax request to check whether the call has initiated, If initiated show popup ( Initiation can be checked though Database).
I came up with the event listeners in the cakephp. But I am not sure whether it will be feasible to show the pop up message to the callee only, not to all the user.
1st and 2nd are not efficient, 3rd is efficient but I am not sure about this. Is there any other ways to do this. If third is possible, explain us
Socket programming is perfect use case for your problem. It's kinda similar to your 3rd approach.
A very high level flow will be
Register caller & callee to the server-socket, by some identifier (say name)
Caller sends the "calling" signal with callee's name.
Server-socket identifies callee by the name
Sends the call signal to callee
P.S. Socket is a 2-way communication
Cakephp has socket features. http://book.cakephp.org/2.0/en/core-utility-libraries/httpsocket.html
You can also check this out.
https://github.com/thabung/phpSocketExample
I've been reading the MSDN documentation for IcmpSendEcho2 and it raises more questions than it answers.
I'm familiar with asynchronous callbacks from other Win32 APIs such as ReadFileEx... I provide a buffer which I guarantee will be reserved for the driver's use until the operation completes with any result other than IO_PENDING, I get my callback in case of either success or failure (and call GetCompletionStatus to find out which). Timeouts are my responsibility and I can call CancelIo to abort processing, but the buffer is still reserved until the driver cancels the operation and calls my completion routine with a status of CANCELLED. And there's an OVERLAPPED structure which uniquely identifies the request through all of this.
IcmpSendEcho2 doesn't use an OVERLAPPED context structure for asynchronous requests. And the documentation is unclear excessively minimalist about what happens if the ping times out or fails (failure would be lack of a network connection, a missing ARP entry for local peers, ICMP destination unreachable response from an intervening router for remote peers, etc).
Does anyone know whether the callback occurs on timeout and/or failure? And especially, if no response comes, can I reuse the buffer for another call to IcmpSendEcho2 or is it forever reserved in case a reply comes in late?
I'm wanting to use this function from a Win32 service, which means I have to get the error-handling cases right and I can't just leak buffers (or if the API does leak buffers, I have to use a helper process so I have a way to abandon requests).
There's also an ugly incompatibility in the way the callback is made. It looks like the first parameter is consistent between the two signatures, so I should be able to use the newer PIO_APC_ROUTINE as long as I only use the second parameter if an OS version check returns Vista or newer? Although MSDN says "don't do a Windows version check", it seems like I need to, because the set of versions with the new argument aren't the same as the set of versions where the function exists in iphlpapi.dll.
Pointers to additional documentation or working code which uses this function and an APC would be much appreciated.
Please also let me know if this is completely the wrong approach -- i.e. if either using raw sockets or some combination of IcmpCreateFile+WriteFileEx+ReadFileEx would be more robust.
I use IcmpSendEcho2 with an event, not a callback, but I think the flow is the same in both cases. IcmpSendEcho2 uses NtDeviceIoControlFile internally. It detects some ICMP-related errors early on and returns them as error codes in the 12xx range. If (and only if) IcmpSendEcho2 returns ERROR_IO_PENDING, it will eventually call the callback and/or set the event, regardless of whether the ping succeeds, fails or times out. Any buffers you pass in must be preserved until then, but can be reused afterwards.
As for the version check, you can avoid it at a slight cost by using an event with RegisterWaitForSingleObject instead of an APC callback.
I have a situation similar to this:
Objective-C: How to use memory managment properly for asynchronous methods
I have an object that asynchronously downloads & parses an xml doc. It then has a delegate method that transfers the data it retrieved to the caller.
My 2 questions are:
When do I release the data retrieving object? The link I posted above gives 2 answers, one says release in the delegate and one says release immediately, which is correct (or which is better if both answers are correct)
My second question is, what is the best way to transfer the retrieved data to the caller? At the moment I have
self.imagesDataSource = [articleImagesParserObject.returnedArray copy];
I used copy because, as far as I understand, that makes the mutable array immutable. Is that correct?
I'm going to pick you up on a couple of things.. It might start the ball rolling :)
You say
It then has a delegate method that
transfers the data it retrieved to the
caller
-- EDIT --
You mean that you send a message to the NSURLConnection's delegate. Yes, it is just semantics, but it is clearer.
You say
The link I posted above gives 2
answers, one says release in the
delegate and one says release
immediately
The post you link to says that if you launch your secondary thread with NSThread +detachNewThreadSelector:toTarget:withObject: the thread will retain your object, so if you have finished with it, you can release it, as is normal practise. You are not doing this.
The second suggested method is to supply a method to callback when your background operation has completed. As you are using NSURLConnection and it already provides you with callback hooks, and in fact you are using them to return your downloaded data, this seems like the way to go.
Copying a mutable array does give you an immutable copy, which you own - so it should be self.imagesDataSource = [[articleImagesParserObject.returnedArray copy] autorelease] unless imagesDataSource doesn't retain - which would be irregular.