diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp index d666f14760a6aa91f9eff35978f723915a7b5f1f..f748bc4149e5396e59594044109c6e5144bcee3f 100644 --- a/src/audio/audiortp.cpp +++ b/src/audio/audiortp.cpp @@ -288,6 +288,7 @@ AudioRtpRTX::sendSessionFromMic (unsigned char* data_to_send, int16* data_from_m // encode divise by two // Send encoded audio sample over the network if (compSize > RTP_FRAMES2SEND) { _debug("%d should be %d\n", compSize, _nbFrames);} + //fprintf(stderr, "S"); if (!_sym) { _sessionSend->putData(timestamp, data_to_send, compSize); } else { @@ -382,6 +383,7 @@ AudioRtpRTX::receiveSessionForSpkr (int16* data_for_speakers_stereo, int16* data // If the current call is the call which is answered // Set decoded data to sound device // expandedSize is in mono/bytes, since we double in stereo, we send two time more + //fprintf(stderr, "R"); audiolayer->putMain(data_for_speakers_stereo, toPut * sizeof(int16)); //Manager::instance().getAudioDriver()->startStream(); diff --git a/src/audio/ringbuffer.cpp b/src/audio/ringbuffer.cpp index fe8f49b9b11357e28cf2737e722f01faa2fc8f9b..eb1d54b6766171596decc93f32dc20032235829c 100644 --- a/src/audio/ringbuffer.cpp +++ b/src/audio/ringbuffer.cpp @@ -79,7 +79,7 @@ RingBuffer::Put(void* buffer, int toCopy, unsigned short volume) { copied = 0; pos = mEnd; - + //fprintf(stderr, "P"); while(toCopy) { block = toCopy; if (block > (mBufferSize - pos)) // from current pos. to end of buffer @@ -130,7 +130,7 @@ RingBuffer::Get(void *buffer, int toCopy, unsigned short volume) { dest = (samplePtr) buffer; copied = 0; - //fprintf(stderr, "get start... "); + //fprintf(stderr, "G"); while(toCopy) { block = toCopy; if (block > (mBufferSize - mStart)) diff --git a/src/gui/server/guiserverimpl.h b/src/gui/server/guiserverimpl.h index d8585870fd07bb1bab5beca24779c45d09a2101a..f237a3f3d0b19ccb9728796f4497795acad7077b 100644 --- a/src/gui/server/guiserverimpl.h +++ b/src/gui/server/guiserverimpl.h @@ -57,21 +57,17 @@ public: void sendRegistrationState(bool state); void setup(); - void sendMessage(const std::string& code, const std::string& seqId, TokenList& -arg); - void sendCallMessage(const std::string& code, - const std::string& sequenceId, - CALLID id, - TokenList arg); + void sendMessage(const std::string& code, const std::string& seqId, + TokenList& arg); + void sendCallMessage(const std::string& code, const std::string& sequenceId, + CALLID id, TokenList arg); void callFailure(CALLID id); bool getEvents(const std::string& sequenceId); bool sendGetEventsEnd(); - bool outgoingCall (const std::string& seq, - const std::string& account, - const std::string& callid, - const std::string& to); + bool outgoingCall (const std::string& seq, const std::string& account, + const std::string& callid, const std::string& to); bool answerCall(const std::string& callId); bool refuseCall(const std::string& callId); bool holdCall(const std::string& callId); @@ -100,6 +96,7 @@ private: std::string getCallIdFromId(CALLID id); CALLID getIdFromCallId(const std::string& callId); + /** * This callMap is necessary because * ManagerImpl use callid-int diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index b78e62a8017d342e8db31dc7a95f6329a6882eb0..77c451d8cffd28f43faf6196eadb404052d2fb89 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -1131,32 +1131,32 @@ ManagerImpl::notificationIncomingCall (void) { /** * Multi Thread */ -void -ManagerImpl::getStunInfo (StunAddress4& stunSvrAddr) +bool +ManagerImpl::getStunInfo (StunAddress4& stunSvrAddr, int port) { StunAddress4 mappedAddr; struct in_addr in; char* addr; - char to[16]; - bzero (to, 16); - - int fd3, fd4; - bool ok = stunOpenSocketPair(stunSvrAddr, - &mappedAddr, - &fd3, - &fd4); + + //int fd3, fd4; + // bool ok = stunOpenSocketPair(stunSvrAddr, &mappedAddr, &fd3, &fd4, port); + int fd1 = stunOpenSocket(stunSvrAddr, &mappedAddr, port); + bool ok = (fd1 == -1 || fd1 == INVALID_SOCKET) ? false : true; if (ok) { - closesocket(fd3); - closesocket(fd4); + closesocket(fd1); + //closesocket(fd3); + //closesocket(fd4); _firewallPort = mappedAddr.port; // Convert ipv4 address to host byte ordering in.s_addr = ntohl (mappedAddr.addr); addr = inet_ntoa(in); _firewallAddr = std::string(addr); _debug("STUN Firewall: [%s:%d]\n", _firewallAddr.data(), _firewallPort); + return true; } else { _debug("Opening a stun socket pair failed\n"); } + return false; } bool diff --git a/src/managerimpl.h b/src/managerimpl.h index 1a78aa73112c0768ec7df8b02e4b293574daabe2..f70e429b6b093a2d743df5e53c1785b06dcf2cba 100644 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -210,11 +210,13 @@ public: */ void notificationIncomingCall (void); - /* - * Get information about firewall - * @param stunSvrAddr: stun server - */ - void getStunInfo (StunAddress4& stunSvrAddr); + /* + * Get information about firewall + * @param stunSvrAddr: stun server + * @param port port number to open to test the connection + * @return true if the connection is successful + */ + bool getStunInfo(StunAddress4& stunSvrAddr, int port); bool useStun (void); /* diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp index 6d1af281dd0341dd47bdf9ff3c717b20f2529864..ca05212e3121a1372ce30e89f040b11f5a209401 100644 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -76,6 +76,14 @@ SipVoIPLink::checkNetwork (void) return getSipLocalIp(); } + +/** + * Steps: + * 1. Init eXosip + * 2. Try to listen two times on a port + * if we use stun, we check if we can use 5060, before connecting to eXosip... + * if we can't we check on a random port + */ bool SipVoIPLink::init(void) { @@ -86,39 +94,54 @@ SipVoIPLink::init(void) _started = true; srand (time(NULL)); - // second parameter, NULL is "::" for ipv6 and "0.0.0.0" for ipv4, we can put INADDR_ANY int i; - i = eXosip_listen_addr(IPPROTO_UDP, INADDR_ANY, DEFAULT_SIP_PORT, AF_INET, 0); - if (i != 0) { - i = eXosip_listen_addr(IPPROTO_UDP, INADDR_ANY, RANDOM_SIP_PORT, AF_INET, 0); - if (i != 0) { - _debug("Could not initialize transport layer\n"); - return false; - } else { - _debug("VoIP Link listen on random port %d\n", RANDOM_SIP_PORT); - } - } else { - _debug("VoIP Link listen on port %d\n", DEFAULT_SIP_PORT); - } - - // Set user agent - std::string tmp = std::string(PROGNAME_GLOBAL) + "/" + std::string(SFLPHONED_VERSION); - eXosip_set_user_agent(tmp.data()); + // check networking capabilities if ( !checkNetwork() ) { return false; } + // if we useStun and we failed to receive something on port 5060, we try a random port // If use STUN server, firewall address setup - if (Manager::instance().useStun()) { - if (behindNat() != 1) { - return false; + bool useStun = Manager::instance().useStun(); + int port = DEFAULT_SIP_PORT; + + int nbTry = 2; // number of times to try to start SIP listener + int iTry = 1; // try number.. + + do { + if (useStun && !behindNat(port)) { + port = RANDOM_SIP_PORT; + if (!behindNat(port)) { + return false; // hoho we can't use the random sip port too... + } } + + // second parameter, NULL is "::" for ipv6 and "0.0.0.0" for ipv4, we can put INADDR_ANY + i = eXosip_listen_addr(IPPROTO_UDP, INADDR_ANY, port, AF_INET, 0); + if (i != 0) { + _debug("SIP ERROR: [%d/%d] could not initialize SIP listener on port %d\n", iTry, nbTry, port); + port = RANDOM_SIP_PORT; + } + } while ( i != 0 && iTry < nbTry ); + + if ( i != 0 ) { // we didn't succeeded + _debug("SIP FAILURE: SIP failed to listen on port %d\n", port); + return false; + } + _debug("SIP Init: listening on port %d\n", port); + + if (useStun) { // This method is used to replace contact address with the public address of your NAT + // it should be call after eXosip_listen_addr eXosip_masquerade_contact((Manager::instance().getFirewallAddress()).data(), Manager::instance().getFirewallPort()); } - _debug("SIP VoIP Link: listen to SIP Events\n"); + // Set user agent + std::string tmp = std::string(PROGNAME_GLOBAL) + "/" + std::string(SFLPHONED_VERSION); + eXosip_set_user_agent(tmp.data()); + + _debug("SIP Init: starting loop thread (SIP events)\n"); _evThread->start(); return true; } @@ -652,10 +675,7 @@ SipVoIPLink::getEvent (void) CALLID id = 0; int returnValue = EXOSIP_ERROR_NO; - _debug("#############################################\n" - " SipEvent #%03d %s\n" - " #############################################\n", - event->type, event->textinfo); + _debug("SIP Event: #%03d %s\n", event->type, event->textinfo); switch (event->type) { // IP-Phone user receives a new call @@ -668,7 +688,7 @@ SipVoIPLink::getEvent (void) setLocalPort(RANDOM_LOCAL_PORT); } else { // If there is a firewall - if (behindNat() != 0) { + if (behindNat(DEFAULT_LOCAL_PORT) != 0) { setLocalPort(Manager::instance().getFirewallPort()); } else { returnValue = EXOSIP_ERROR_STD; @@ -1281,8 +1301,8 @@ SipVoIPLink::sdp_off_hold_call (sdp_message_t * sdp) return 0; } -int -SipVoIPLink::behindNat (void) +bool +SipVoIPLink::behindNat(int port) { StunAddress4 stunSvrAddr; stunSvrAddr.addr = 0; @@ -1299,9 +1319,7 @@ SipVoIPLink::behindNat (void) // Firewall address //_debug("STUN server: %s\n", svr.data()); - Manager::instance().getStunInfo(stunSvrAddr); - - return 1; + return Manager::instance().getStunInfo(stunSvrAddr, port); } /** @@ -1413,17 +1431,18 @@ SipVoIPLink::startCall(CALLID id, const std::string& from, const std::string& to _debug(" Setting local port to random: %d\n",_localPort); } else { // If use Stun server - if (behindNat() != 0) { + if (behindNat(_localPort)) { + setLocalIpAddress(Manager::instance().getFirewallAddress()); setLocalPort(Manager::instance().getFirewallPort()); - _debug(" Setting local port to firewall port: %d\n", _localPort); + _debug(" Setting local port to firewall port: %d\n", _localPort); } else { return -1; } } // Set local audio port for sipcall(id) - sipcall->setLocalAudioPort(_localPort); sipcall->setLocalIp(getLocalIpAddress()); + sipcall->setLocalAudioPort(_localPort); eXosip_lock(); int i = eXosip_call_build_initial_invite (&invite, (char*)to.data(), diff --git a/src/sipvoiplink.h b/src/sipvoiplink.h index 2339a2f112676b6a572ae5c603be2ae09b50e364..392209dbab16f6552aae536acd485296a30a9a18 100644 --- a/src/sipvoiplink.h +++ b/src/sipvoiplink.h @@ -132,10 +132,11 @@ private: * If you are behind a NAT, you have to use STUN server, specified in * STUN configuration(you can change this one by default) to give you an * public IP address and assign a port number. + * @param port : on which port we want to listen to * - * Return 0 if an error occured and 1 if no error. + * Return false if an error occured and true if no error. */ - int behindNat (void); + bool behindNat(int port); /* * Return -1 if an error occured and 0 if no error