lukeweber / webrtc-jingle-client

Webrtc audio + jingle protocol brought to IOS and Android.
https://groups.google.com/forum/?fromgroups#!forum/webrtc-jingle
BSD 3-Clause "New" or "Revised" License
336 stars 136 forks source link

iOS voiceclient example. How to make a call to another voiceclient app #91

Closed alexledovskiy closed 11 years ago

alexledovskiy commented 11 years ago

Hi Everyone. Maybe somebody could guide me through and help me to move forward. Any help will do. Appreciate any suggestions and tips and help. The goal is to make a voice call from iOS device to iOS device using webrtc-jingle-client and Ejabberd server.

What I've got:

The problem:

callingVoiceClient::Call
ClientSignalingThread::Call
ClientSignalingThread::OnMessage: MSG_CALL
ClientSignalingThread::CallS
Calling friend 'bob@dummyname.local'
ClientSignalingThread::OnCallCreate
ClientSignalingThread::OnSessionCreate
WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel 1
Created channel for audio
Transport::ConnectChannels_w: No local description has been set. Will generate one.
Jingle:Channel[audio|1|__]: NULL DTLS identity supplied. Not doing DTLS
Jingle:Channel[audio|1|__]: NULL DTLS identity supplied. Not doing DTLS
Session:1758606884 Old state:STATE_INIT New state:STATE_SENTINITIATE Type:urn:xmpp:jingle:apps:rtp:1 Transport:http://www.google.com/transport/p2p
Setting local voice description
Add send ssrc: 433074798
Setting receive voice codecs:
ISAC/16000/1 (103)
CN/16000/1 (105)
telephone-event/8000/1 (126)
Changing voice state, recv=0 send=0
ClientSignalingThread::OnSessionState STATE_SENTINITIATE - sent initiate, waiting for Accept or Reject
ClientSignalingThread::OnMessage: MSG_CALL_STATE
SEND >>>>>>>>>>>>>>>> : Mon Apr 29 02:49:59 2013
   <iq to="bob@dummyname.local" type="set" id="15">
     <jingle xmlns="urn:xmpp:jingle:1" action="session-initiate" sid="1758606884" initiator="alex@dummyname.local/voice">
       <content name="audio" creator="initiator">
         <description xmlns="urn:xmpp:jingle:apps:rtp:1" media="audio" ssrc="433074798">
           <payload-type id="103" name="ISAC" clockrate="16000"/>
           <payload-type id="105" name="CN" clockrate="16000"/>
           <payload-type id="126" name="telephone-event" clockrate="8000"/>
           <rtcp-mux/>
         </description>
         <transport xmlns="http://www.google.com/transport/p2p"/>
       </content>
     </jingle>
     <session xmlns="http://www.google.com/session" type="initiate" id="1758606884" initiator="alex@dummyname.local">
       <description xmlns="http://www.google.com/session/phone">
         <payload-type xmlns="http://www.google.com/session/phone" id="103" name="ISAC" clockrate="16000"/>
         <payload-type xmlns="http://www.google.com/session/phone" id="105" name="CN" clockrate="16000"/>
         <payload-type xmlns="http://www.google.com/session/phone" id="126" name="telephone-event" clockrate="8000"/>
         <src-id xmlns="http://www.google.com/session/phone">
           433074798
         </src-id>
       </description>
     </session>
   </iq>
Transport: audio, allocating candidates
ClientSignalingThread::OnRequestSignaling
Transport: audio, allocating candidates
ClientSignalingThread::OnRequestSignaling
LOGT AllocationSequence::OnMessage
Jingle:Net[en0:192.168.1.0/24]: Allocation Phase=Udp (Step=0)
LOGT AllocationSequence::OnMessage - PHASE_UDP
Jingle:Port[:1:0:local:Net[en0:192.168.1.0/24]]: Port created
Adding allocated port for audio
Jingle:Port[audio:1:0:local:Net[en0:192.168.1.0/24]]: Added port to allocator
Sorting available connections:
Jingle:Port[:1:0:local:Net[en0:192.168.1.0/24]]: Port created
Adding allocated port for audio
Jingle:Port[audio:1:0:stun:Net[en0:192.168.1.0/24]]: Added port to allocator
LOGT AllocationSequence::EnableProtocol
LOGT AllocationSequence::EnableProtocol - PROTO_UDP
LOGT AllocationSequence::Start
Sorting available connections:
LOGT AllocationSequence::OnMessage
Jingle:Net[en0:192.168.1.0/24]: Allocation Phase=Relay (Step=1)
LOGT AllocationSequence::OnMessage - PHASE_RELAY
AllocationSequence: Relay ports disabled, skipping.
LOGT AllocationSequence::OnMessage
Jingle:Net[en0:192.168.1.0/24]: Allocation Phase=Tcp (Step=2)
LOGT AllocationSequence::OnMessage - PHASE_TCP
Jingle:Port[:1:0:local:Net[en0:192.168.1.0/24]]: Port created
Adding allocated port for audio
Jingle:Port[audio:1:0:local:Net[en0:192.168.1.0/24]]: Added port to allocator
Preparing TCP address, current state: 2
Sorting available connections:
LOGT AllocationSequence::EnableProtocol
LOGT AllocationSequence::EnableProtocol - PROTO_TCP
ClientSignalingThread::OnSessionError ERROR_ACK_TIME - no ack response to signaling, client not available
ClientSignalingThread::OnMessage: MSG_CALL_ERROR
Session:1259542186 Old state:STATE_SENTINITIATE New state:STATE_SENTTERMINATE Type:urn:xmpp:jingle:apps:rtp:1 Transport:http://www.google.com/transport/p2p
ClientSignalingThread::OnSessionState STATE_SENTTERMINATE - sent terminate (any time / either side)
SEND >>>>>>>>>>>>>>>> : Mon Apr 29 02:50:01 2013
   <iq to="bob@dummyname.local/voice" type="set" id="16">
     <jingle xmlns="urn:xmpp:jingle:1" action="session-terminate" sid="1259542186">
       <reason>
         <general-error/>
       </reason>
ClientSignalingThread::OnMessage: MSG_CALL_STATE
     </jingle>
     <session xmlns="http://www.google.com/session" type="terminate" id="1259542186" initiator="alex@dummyname.local/voice">
       <general-error/>
     </session>
   </iq>
WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel 0
Destroyed channel
Warning(call.cc:727): Speaker monitor for session 1259542186 already stopped.
Session:1259542186 Old state:STATE_SENTTERMINATE New state:STATE_DEINIT Type:urn:xmpp:jingle:apps:rtp:1 Transport:http://www.google.com/transport/p2p
ClientSignalingThread::OnSessionState STATE_DEINIT - session is being destroyed
ClientSignalingThread::OnCallDestroy
ClientSignalingThread::OnMessage: MSG_CALL_STATE
LOGT AllocationSequence::OnMessage
Jingle:Net[en0:192.168.1.0/24]: Allocation Phase=SslTcp (Step=3)
LOGT AllocationSequence::OnMessage - PHASE_SSLTCP
LOGT AllocationSequence::EnableProtocol
LOGT AllocationSequence::EnableProtocol - PROTO_SSLTCP
All candidates gathered for audio:1:0
Transport: audio, component 1 allocation complete
Transport: audio allocation complete
Candidate gathering is complete.

After debugging for a little while I found this line in clientsignalingthread.cc line 713:

      if (presence->available() == buzz::XMPP_PRESENCE_AVAILABLE
              && presence->jid().BareEquals(callto_jid)) {
          found_jid = presence->jid();
          found = true;
          break;
      }

presence->jid().BareEquals(callto_jid) is false And it seems it can not find the callto_jid online or something.

RECV <<<<<<<<<<<<<<<< : Mon Apr 29 02:57:46 2013
   <iq from='alex@dummyname.local' to='alex@dummyname.local/voice' id='4' type='result'>
     <query xmlns='jabber:iq:roster'>
       <item subscription='from' jid='bob@dummyname.local'/>
     </query>
   </iq>
   <iq from='dummyname.local' to='alex@dummyname.local/voice' id='984888815' type='get'>
     <query xmlns='http://jabber.org/protocol/disco#info' node='http://github.com/lukeweber/webrtc-jingle#1.0-SNAPSHOT'/>
   </iq>
   <presence from='alex@dummyname.local/voice' to='alex@dummyname.local/voice' xml:lang='*'>
     <status/>
     <priority>
       0
     </priority>
     <c xmlns='http://jabber.org/protocol/caps' node='http://github.com/lukeweber/webrtc-jingle' ver='1.0-SNAPSHOT' ext='voice-v1'/>
     <x xmlns='jabber:x:delay' stamp='20130429T09:57:46'/>
   </presence>
   <iq from='alex@dummyname.local' to='alex@dummyname.local/voice' type='error' xml:lang='*' id='7'>
     <ping xmlns='urn:xmpp:ping'/>
     <error code='503' type='cancel'>
       <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
   <iq from='dummyname.local' to='alex@dummyname.local/voice' id='2400779902' type='get'>
     <query xmlns='http://jabber.org/protocol/disco#info' node='http://github.com/lukeweber/webrtc-jingle#voice-v1'/>
   </iq>
RosterHandler::IncomingPresenceChanged()
SEND >>>>>>>>>>>>>>>> : Mon Apr 29 02:57:46 2013
   <iq type="error" to="dummyname.local" id="984888815">
     <query xmlns="http://jabber.org/protocol/disco#info" node="http://github.com/lukeweber/webrtc-jingle#1.0-SNAPSHOT"/>
     <error code="501" type="cancel">
       <feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
     </error>
   </iq>
   <iq type="error" to="dummyname.local" id="2400779902">
     <query xmlns="http://jabber.org/protocol/disco#info" node="http://github.com/lukeweber/webrtc-jingle#voice-v1"/>
     <error code="501" type="cancel">
       <feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
     </error>
   </iq>

Please if anybody knows anything help me.

lukeweber commented 11 years ago

I recommend you start with gmail, as it's a good working example to use as a basis to start things.

First in the initial iq, you're sending session, and jingle iq's in one stanza. This is not rfc compliant and will fail on most xmpp servers as an iq can usually only contain one child in a request I believe. This in libjingle is known as hybrid mode and is sometimes even required with this lib to talk to gmail, but on ejabberd, the cause of many issues.

Also notice in login, the flag, isGtalk in login. If you're using your own server, set this to false.

void VoiceClientDelegate::Login(){
    stun_config_.stun = "stun.l.google.com:19302";
    voiceClient_->Login("username@gmail.com","password",
                        &stun_config_, "talk.google.com", 5222, true, 0, true/*isGtalk*/);

As well(ping module not enabled on server):

<ping xmlns='urn:xmpp:ping'/>
     <error code='503' type='cancel'>
       <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>

http://jabber.org/protocol/disco#info as well not enabled I assume.

Another thing to mention is that @hailg is nearly done with a port which would use xmppframework for your connection and libjingle would just attach to that, which is more familiar to most iOS guys.

https://github.com/hailg/webrtc-jingle-client/commits/master

alexledovskiy commented 11 years ago

Thank you @lukeweber.

Gmail works for me just fine. I did try it like that with my account and I am able to receive calls on gtalk client.

void VoiceClientDelegate::Login(){
    stun_config_.stun = "stun.l.google.com:19302";
    voiceClient_->Login("myusername@gmail.com","password",
                        &stun_config_, "talk.google.com", 5222, true, 0, true/*isGtalk*/);

And I assume it's server side issue but since I don't have much of experience with xmpp yet. It must be misconfiguration or difference in gmail server and Ejabberd.

Thank you for the urn:xmpp:ping hint. I'll look in to it and will try to enable it. Also thx for @hailg link. I saw it earlier but didn't want to use it due to my plans to use libjingle on other platforms and I want to keep it in C++. But I'll try his port and maybe it'll sole my problem.

Anyway, thank you for this @lukeweber! Appreciate your help. Will defiantly keep this thread updated as I move forward.

If anybody else know any info on how correctly configure the server side or the client, or which server to use please let me know. I already spent a week on trying to figure things out. I am sure I am pretty close since Gtalk is working fine.

chathudan commented 11 years ago

This is perfectly working with ejabberd , I installed ejabberd on Windows, this helped me https://git.process-one.net/ejabberd/mainline/blobs/raw/v2.1.11/doc/guide.html#htoc16

Thank you lukeweber

alexledovskiy commented 11 years ago

Thanks Chathura I'll try to follow the docs. I have a Mac though but it should be the same. Were you able to make a voice call locally from one client to another? If yes could you please give me your ejubberd cfg file please.

chathudan commented 11 years ago

Which linux version you are using debian,ubuntu, redhat ?

alexledovskiy commented 11 years ago

For now I just setting it up on my mac. And two iOS clients through the local network try to communicate with each other.