Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IOS VoIP integration, special sockets and timeout handlers for keepalive #53

Open
lukeweber opened this issue Dec 17, 2012 · 7 comments

Comments

@lukeweber
Copy link
Owner

IOS recommends a few things for VoIP, specifically special sockets and timeout handlers.

http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/AdvancedAppTricks/AdvancedAppTricks.html#//apple_ref/doc/uid/TP40007072-CH7-SW12

There are several requirements for implementing a VoIP app:

  • Add the UIBackgroundModes key to your app’s Info.plist file. Set the value of this key to an array that includes the voip string.
  • Configure one of the app’s sockets for VoIP usage.
  • Before moving to the background, call the setKeepAliveTimeout:handler: method to install a handler to be executed periodically. Your app can use this handler to maintain its service connection.
  • Configure your audio session to handle transitions to and from active use.
  • To ensure a better user experience on iPhone, use the Core Telephony framework to adjust your behavior in relation to cell-based phone calls; see Core Telephony Framework Reference.
  • To ensure good performance for your VoIP app, use the System Configuration framework to detect network changes and allow your app to sleep as much as possible.

Socket that would need to change to the IPhone recommended version is used here:
./third_party/libjingle/talk/xmpp/xmppengineimpl.cc

In terms of timeouts, we would need a handler that wakes up and calls the white space keepalive method located in clientsignalingthread.cc.

@lukeweber
Copy link
Owner Author

A bit more about specifics, we use TxmppSocket in xmppclient for our xmpp conneciton. When creating the thread, we may simple be able to pass macsocketserver to the thread() method in voiceclient.cc.

@https://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/UsingSocketsandSocketStreams.html "Note: POSIX networking does not activate the cellular radio on iOS. For this reason, the POSIX networking API is generally discouraged in iOS."

We can't use posix it seems, shit, looks pretty tangled, but maybe not.

It seems we should need to do something like this:
http://stackoverflow.com/questions/12057151/voip-socket-on-ios-no-notifications-received

MacAsyncSocket uses CFSocket, which is a c bsd socket. I assume we would need to create a new socket, IOSAsyncSocket that uses the correct interfaces, but will have to confirm further. Otherwise if we can reuse MacAsyncSocket then we would have to reuse CFSocket with CFSocketNativeHandle CFSocketGetNative (CFSocketRef s) to plug into the code from the stackoverflow example above and use the read/write streams from the example. Don't think/am not sure that would work, as I think CFSocket is an underlying POSIX socket that won't work well on IOS.

Current code flow of using posix sockets:
............... Based on current thread get socket server and create a socket.

void TXmppSocket::CreateCricketSocket(int family) {
talk_base::Thread* pth = talk_base::Thread::Current();
if (family == AF_UNSPEC) {
family = AF_INET;
}
talk_base::AsyncSocket* socket = pth->socketserver()->CreateAsyncSocket(

............... Based on socket server that's passed in, construct message queue

libjingle/talk/base/thread.cc ->
Thread::Thread(SocketServer* ss)
: MessageQueue(ss), ...

....... if no socket server, create the default PhysicalSocketServer()

MessageQueue::MessageQueue(SocketServer* ss)
: ss_(ss), fStop_(false), fPeekKeep_(false), active_(false),
dmsgq_next_num_(0) {
if (!ss_) {
// Currently, MessageQueue holds a socket server, and is the base class for
// Thread. It seems like it makes more sense for Thread to hold the socket
// server, and provide it to the MessageQueue, since the Thread controls
// the I/O model, and MQ is agnostic to those details. Anyway, this causes
// messagequeue_unittest to depend on network libraries... yuck.
default_ss_.reset(new PhysicalSocketServer());
ss_ = default_ss_.get();
}
ss_->SetMessageQueue(this);
}

......

// Creates the underlying OS socket (same as the "socket" function).
virtual bool Create(int family, int type) {
Close();
s_ = ::socket(family, type, 0);
udp_ = (SOCK_DGRAM == type);
UpdateLastError();
if (udp_)
enabled_events_ = DE_READ | DE_WRITE;
return s_ != INVALID_SOCKET;
}

@seankovacs
Copy link

Trying to work on this (backgrounding on iOS), but having some difficulties switching to the MacCFSocketServer. I got it working in the libjingle call client example, but can't seem to get it going here. I switched the pss_ var from Physical to MacCF, though it's getting an assertion failure.

@seankovacs
Copy link

This is the exact error I get: Error(common.cc:67): /Users/seankovacs/Documents/webrtcjingleproject/trunk/third_party/libjingle/talk/base/macsocketserver.cc(146): ASSERT FAILED: CFRunLoopGetCurrent() == run_loop_ @ Wait

@lukeweber
Copy link
Owner Author

I worked on this a bit but lost track of my unwprking patch. I think in the
end what I was trying was to pass the native posix socket back to a
cfsocket and then try to manipulate that. Anyhow hailg was working on an
xmpp framework branch. I've updated his patch to trunk and its in the
branch ios-xmppframework. It has a different deps file so make sure you
just manually download the xmppframework that's referenced in deps. The
advantage of this is that webrtcjingle uses the iOS socket provided by
xmppframework. Branch didn't seem to be working for me but was for hailg
and didn't have time yet to debug why I couldn't make a call.

If you want to mess around with it you'll also need to uncomment the
constant XMPP_FRAMEWORK in libjingle.gyp in third_party/libjingle as well.
On May 2, 2013 4:01 PM, "Sean Kovacs" notifications@github.com wrote:

This is the exact error I get: Error(common.cc:67):
/Users/seankovacs/Documents/webrtcjingleproject/trunk/third_party/libjingle/talk/base/macsocketserver.cc(146):
ASSERT FAILED: CFRunLoopGetCurrent() == run_loop_ @ Wait


Reply to this email directly or view it on GitHubhttps://github.com//issues/53#issuecomment-17339477
.

@hailg
Copy link
Contributor

hailg commented May 3, 2013

Hi guy, you may want to try my work at:
https://mega.co.nz/#!v1JwlCIT!BVNtzzCb3HAyi91mHyY-0FCvjNZcIjnlOA2tLT4C3zE
Hoping Luke can debug why it cannot run on his side and merge the code to
the current branch.

On Fri, May 3, 2013 at 4:00 AM, Luke Weber notifications@github.com wrote:

I worked on this a bit but lost track of my unwprking patch. I think in
the
end what I was trying was to pass the native posix socket back to a
cfsocket and then try to manipulate that. Anyhow hailg was working on an
xmpp framework branch. I've updated his patch to trunk and its in the
branch ios-xmppframework. It has a different deps file so make sure you
just manually download the xmppframework that's referenced in deps. The
advantage of this is that webrtcjingle uses the iOS socket provided by
xmppframework. Branch didn't seem to be working for me but was for hailg
and didn't have time yet to debug why I couldn't make a call.

If you want to mess around with it you'll also need to uncomment the
constant XMPP_FRAMEWORK in libjingle.gyp in third_party/libjingle as well.
On May 2, 2013 4:01 PM, "Sean Kovacs" notifications@github.com wrote:

This is the exact error I get: Error(common.cc:67):

/Users/seankovacs/Documents/webrtcjingleproject/trunk/third_party/libjingle/talk/base/macsocketserver.cc(146):

ASSERT FAILED: CFRunLoopGetCurrent() == run_loop_ @ Wait


Reply to this email directly or view it on GitHub<
https://github.com/lukeweber/webrtc-jingle-client/issues/53#issuecomment-17339477>

.


Reply to this email directly or view it on GitHubhttps://github.com//issues/53#issuecomment-17364407
.

@seankovacs
Copy link

Yeah I was able to get the voip in the background thing working. Just this occasional ssl write error. I'll try hailg's version using the ios xmppframework and see if that helps.

@lukeweber
Copy link
Owner Author

Do you mind sharing, others might find the code useful?

What are your thoughts on xmppframework vs just using libjingle?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants