From a11aeb9c81176ce56ff73de502da9a8c31718a04 Mon Sep 17 00:00:00 2001
From: yanmorin <yanmorin>
Date: Tue, 1 Nov 2005 19:10:52 +0000
Subject: [PATCH] Partially implement text message reception Corrected double
 config problem Corrected some problem with incoming call

---
 src/call.cpp                    |  14 +----
 src/call.h                      |   2 -
 src/gui/server/argtokenizer.cpp |  15 +++--
 src/managerimpl.cpp             |  20 ++++---
 src/managerimpl.h               |   3 +-
 src/sipcall.cpp                 |  13 ++---
 src/sipvoiplink.cpp             | 100 ++++++++++++++++++++++----------
 src/sipvoiplink.h               |   2 +-
 src/voIPLink.h                  |   2 +-
 9 files changed, 103 insertions(+), 68 deletions(-)

diff --git a/src/call.cpp b/src/call.cpp
index b316c760f0..09419400b2 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -25,7 +25,8 @@
 
 Call::Call (CALLID id, CallType type, VoIPLink* voiplink)
 {
- 	initConstructor();
+	_state = NotExist;
+	_type = Null;
 	_id = id; 
 	_type = type;
 	_voIPLink = voiplink;
@@ -268,14 +269,3 @@ Call::refuse  (void)
 	int i = _voIPLink->refuse(_id);
 	return i;
 }
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Private functions
-///////////////////////////////////////////////////////////////////////////////
-void
-Call::initConstructor(void)
-{
-	_state = NotExist;
-	_type = Null;
-}
diff --git a/src/call.h b/src/call.h
index 6dffa6f04d..0baa2b22ff 100644
--- a/src/call.h
+++ b/src/call.h
@@ -107,8 +107,6 @@ public:
   bool getFlagNotAnswered() const { return _flagNotAnswered; }
 
 private:
-	void initConstructor (void);
-	
 	VoIPLink		*_voIPLink;	
 	CALLID 		  	 _id;
 	enum CallState 	 _state;
diff --git a/src/gui/server/argtokenizer.cpp b/src/gui/server/argtokenizer.cpp
index 036374e6d1..0391645f30 100644
--- a/src/gui/server/argtokenizer.cpp
+++ b/src/gui/server/argtokenizer.cpp
@@ -17,6 +17,7 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include "argtokenizer.h"
+#include <ios>
 #include <iostream>
 #include <sstream>
 #include <cc++/url.h>
@@ -30,11 +31,15 @@ ArgTokenizer::tokenize(const std::string& str) {
   TokenList args;
   while(s.good()) {
     s >> output;
-    char *tmp = new char[output.length()+1];
-    strcpy(tmp, output.c_str());
-    ost::urlDecode(tmp, NULL);
-    args.push_back(tmp);
-    delete[] tmp; tmp = NULL;
+    // if we have a string that end with an space
+    // failbit is set
+    if ( ! ( s.rdstate() & std::ios_base::failbit) ) {
+      char *tmp = new char[output.length()+1];
+      strcpy(tmp, output.c_str());
+      ost::urlDecode(tmp, NULL);
+      args.push_back(tmp);
+      delete[] tmp; tmp = NULL;
+    }
   }
   return args;
 }
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index 7dd8f5f2bb..10264dc3a8 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -232,7 +232,7 @@ ManagerImpl::deleteCall (CALLID id)
   while(iter!=_callVector.end()) {
     Call *call = *iter;
     if (call != NULL && call->getId() == id) {
-      if (call->getFlagNotAnswered() && call->isIncomingType()) {
+      if (call->getFlagNotAnswered() && call->isIncomingType() && call->getState() != Call::NotExist) {
         decWaitingCall();
       }
       delete (*iter); *iter = NULL; 
@@ -454,23 +454,27 @@ ManagerImpl::saveConfig (void)
 /**
  * Main Thread
  */
-void 
+bool
 ManagerImpl::initRegisterVoIPLink() 
 {
+  int returnValue = true;
   _debug("Initiate VoIP Link Registration\n");
   if (_hasTriedToRegister == false) {
-   _voIPLinkVector.at(DFT_VOIP_LINK)->init(); // we call here, because it's long...
-   if (_voIPLinkVector.at(DFT_VOIP_LINK)->checkNetwork()) {
-      // If network is available
-  
+    if ( _voIPLinkVector.at(DFT_VOIP_LINK)->init() ) { 
+      // we call here, because it's long...
+      // If network is available and exosip is start..
       if (getConfigInt(SIGNALISATION, AUTO_REGISTER) && _exist == 1) {
         registerVoIPLink();
+        _hasTriedToRegister = true;
       }
+    } else {
+      returnValue = false;
     }
-    _hasTriedToRegister = true;
   }
+  return returnValue;
 }
 
+
 /**
  * Initialize action (main thread)
  * Note that Registration is only send if STUN is not activated
@@ -661,7 +665,7 @@ ManagerImpl::callCanBeAnswered(CALLID id) {
   bool returnValue = false;
   ost::MutexLock m(_mutex);
   Call* call = getCall(id);
-  if (call != NULL && ( call->getFlagNotAnswered() || 
+  if (id == _currentCallId && call != NULL && ( call->getFlagNotAnswered() || 
        (call->getState()!=Call::OnHold && call->getState()!=Call::OffHold) )) {
     returnValue = true;
   }
diff --git a/src/managerimpl.h b/src/managerimpl.h
index a79a8c4a49..cf885e066a 100644
--- a/src/managerimpl.h
+++ b/src/managerimpl.h
@@ -379,8 +379,9 @@ private:
   int			_firewallPort;
   std::string		_firewallAddr;
 
+  // return false if exosip or the network checking failed
+  bool initRegisterVoIPLink();
   // true if we tried to register Once
-  void initRegisterVoIPLink();
   bool    _hasTriedToRegister;
   // Register state
   REGISTRATION_STATE _registerState;
diff --git a/src/sipcall.cpp b/src/sipcall.cpp
index 1842ab7837..fca71b522e 100644
--- a/src/sipcall.cpp
+++ b/src/sipcall.cpp
@@ -204,12 +204,11 @@ SipCall::newIncomingCall (eXosip_event_t *event) {
     eXosip_unlock();
   }
   if (remote_sdp == NULL) {
-    _debug("SipCall::newIncomingCall: No remote SDP in INVITE request. Sending 400 BAD REQUEST\n");
-    // Send 400 BAD REQUEST
+    _debug("< Sending 400 Bad Request (no SDP)\n");
     eXosip_lock();
     eXosip_call_send_answer (_tid, 400, NULL);
     eXosip_unlock();
-    return 0;
+    return -1;
   }
   /* TODO: else build an offer */
 
@@ -234,7 +233,7 @@ SipCall::newIncomingCall (eXosip_event_t *event) {
     eXosip_call_send_answer (_tid, 415, NULL);
     eXosip_unlock();
     sdp_message_free (remote_sdp);
-    return 0;
+    return -1;
   }
   _remote_sdp_audio_port = atoi(remote_med->m_port);
   _debug("  Remote Audio Port: %d\n", _remote_sdp_audio_port);
@@ -262,7 +261,7 @@ SipCall::newIncomingCall (eXosip_event_t *event) {
     eXosip_call_send_answer (_tid, 415, NULL);
     eXosip_unlock();
     sdp_message_free (remote_sdp);
-    return 0;
+    return -1;
   }
 
   osip_message_t *answer = 0;
@@ -272,8 +271,8 @@ SipCall::newIncomingCall (eXosip_event_t *event) {
     if ( 0 != sdp_complete_message(remote_sdp, answer)) {
       osip_message_free(answer);
       // Send 415 Unsupported media type
-      eXosip_call_send_answer (_tid, 415, NULL);
       _debug("< Sending Answer 415\n");
+      eXosip_call_send_answer (_tid, 415, NULL);
     } else {
 
       sdp_message_t *local_sdp = eXosip_get_sdp_info(answer);
@@ -365,7 +364,7 @@ SipCall::newReinviteCall (eXosip_event_t *event) {
     eXosip_unlock();
   }
   if (remote_sdp == NULL) {
-    _debug("SipCall::newIncomingCall: No remote SDP in REINVITE request. Sending 400 BAD REQUEST\n");
+    _debug("< Sending 400 Bad Request (no sdp)\n");
     // Send 400 BAD REQUEST
     eXosip_lock();
     eXosip_call_send_answer (_tid, 400, NULL);
diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp
index 45643a385d..0471f0344c 100644
--- a/src/sipvoiplink.cpp
+++ b/src/sipvoiplink.cpp
@@ -72,51 +72,49 @@ SipVoIPLink::checkNetwork (void)
   return getSipLocalIp();
 }
 
-int
+bool
 SipVoIPLink::init(void)
 {
-  std::string tmp;
-  tmp = std::string(PROGNAME) + "/" + std::string(SFLPHONED_VERSION);
-	
   if (0 != eXosip_init()) {
     _debug("Could not initialize eXosip\n");
-    exit (0);
+    return false;
   }
   _started = true;
 
   srand (time(NULL));
-  //should be NULL or INADDR_ANY for the second parameter?
+  // second parameter, NULL is "::" for ipv6 and "0.0.0.0" for ipv4
   int i;
   i = eXosip_listen_addr(IPPROTO_UDP, NULL, DEFAULT_SIP_PORT, AF_INET, 0);
   if (i != 0) {
     i = eXosip_listen_addr(IPPROTO_UDP, NULL, RANDOM_SIP_PORT, AF_INET, 0);
     if (i != 0) {
       _debug("Could not initialize transport layer\n");
-      return -1;
+      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) + "/" + std::string(SFLPHONED_VERSION);
+  eXosip_set_user_agent(tmp.data());
+
   // If use STUN server, firewall address setup
   if (Manager::instance().useStun()) {
-    eXosip_set_user_agent(tmp.data());
     if (behindNat() != 1) {
-      return 0;
+      return false;
     }
-    // This method is used to replace contact address with the public address of your NAT.
+    // This method is used to replace contact address with the public address of your NAT
     eXosip_masquerade_contact((Manager::instance().getFirewallAddress()).data(), Manager::instance().getFirewallPort());
-		
-  } else {
-    // Set user agent
-    eXosip_set_user_agent(tmp.data());
   }
 
-  checkNetwork();
+  if ( !checkNetwork() ) {
+    return false;
+  }
   _debug("SIP VoIP Link: listen to SIP Events\n");
   _evThread->start();
-  return 1;
+  return true;
 }
 
 /**
@@ -291,16 +289,19 @@ SipVoIPLink::outgoingInvite (CALLID id, const std::string& to_url)
   ManagerImpl& manager = Manager::instance();
   // Form the From header field basis on configuration panel
   std::string host = manager.getConfigString(SIGNALISATION, HOST_PART);
-  if ( host.empty() ) {
-    host = getLocalIpAddress();
+  std::string hostFrom = host;
+  if ( hostFrom.empty() ) {
+    hostFrom = getLocalIpAddress();
   }
-  from = fromHeader(manager.getConfigString(SIGNALISATION, USER_PART), host);
+  from = fromHeader(manager.getConfigString(SIGNALISATION, USER_PART), hostFrom);
 	
   to = toHeader(to_url);
 
   if (to.find("@") == std::string::npos and 
       manager.getConfigInt(SIGNALISATION, AUTO_REGISTER)) {
-    to = to + "@" + manager.getConfigString(SIGNALISATION, HOST_PART);
+    if(!host.empty()) {
+      to = to + "@" + manager.getConfigString(SIGNALISATION, HOST_PART);
+    }
   }
 		
   _debug("From: %s\n", from.data());
@@ -553,12 +554,13 @@ SipVoIPLink::offhold (CALLID id)
   }
 
   // Send request
+  _debug("< Send off hold request\n");
   eXosip_lock ();
   i = eXosip_call_send_request (did, invite);
   eXosip_unlock ();
-  
+
   // Enable audio
-  _debug("Stopping AudioRTP\n");
+  _debug("Starting AudioRTP\n");
   if (_audiortp.createNewSession (getSipCall(id)) < 0) {
     _debug("FATAL: Unable to start sound (%s:%d)\n", __FILE__, __LINE__);
     i = -1;
@@ -659,9 +661,15 @@ SipVoIPLink::getEvent (void)
     _debug("  Local listening port: %d\n", _localPort);
     _debug("  Local listening IP: %s\n", getLocalIpAddress().c_str());
 
-    sipcall->newIncomingCall(event);
-    if (Manager::instance().incomingCall(id, sipcall->getName(), sipcall->getNumber()) < 0) {
-      Manager::instance().displayErrorText(id, "  Incoming Call Failed");
+    if (sipcall->newIncomingCall(event) == 0 ) {
+      if (Manager::instance().incomingCall(id, sipcall->getName(), sipcall->getNumber()) == -1) {
+        Manager::instance().displayError("  Incoming Call Failed");
+        deleteSipCall(id);
+      }
+    } else {
+      Manager::instance().peerHungupCall(id);
+      deleteSipCall(id);
+      Manager::instance().displayError("  Incoming Call Failed");
     }
     break;
 
@@ -872,9 +880,13 @@ SipVoIPLink::getEvent (void)
     break;
 
   case EXOSIP_MESSAGE_NEW: //27
+
+    if ( event->request == NULL) {
+      break; // do nothing
+    }
     unsigned int k;
 				
-    if (event->request != NULL && MSG_IS_OPTIONS(event->request)) {
+    if (MSG_IS_OPTIONS(event->request)) {
       for (k = 0; k < _sipcallVector.size(); k++) {
         if (_sipcallVector.at(k)->getCid() == event->cid) { 
           break;
@@ -896,15 +908,13 @@ SipVoIPLink::getEvent (void)
     } 
 
     // Voice message 
-    else if (event->request != NULL && MSG_IS_NOTIFY(event->request)){
+    else if (MSG_IS_NOTIFY(event->request)){
       _debug("> NOTIFY Voice message\n");
       int ii;
       unsigned int pos;
       unsigned int pos_slash;
-      
-      std::string nb_msg;
-      osip_body_t *body = NULL;
 
+      osip_body_t *body = NULL;
       // Get the message body
       ii = osip_message_get_body(event->request, 0, &body);
       if (ii != 0) {
@@ -928,7 +938,7 @@ SipVoIPLink::getEvent (void)
       } 
 
       pos_slash = str.find ("/");
-      nb_msg = str.substr(pos + LENGTH_VOICE_MSG, 
+      std::string nb_msg = str.substr(pos + LENGTH_VOICE_MSG, 
       pos_slash - (pos + LENGTH_VOICE_MSG));
 
       // Set the number of voice-message
@@ -941,6 +951,34 @@ SipVoIPLink::getEvent (void)
         // Stop notification when there is 0 voice message
         Manager::instance().stopVoiceMessageNotification();
       }
+    // http://www.jdrosen.net/papers/draft-ietf-simple-im-session-00.txt
+    } else if (MSG_IS_MESSAGE(event->request)) {
+      _debug("> MESSAGE received\n");
+      // osip_content_type_t* osip_message::content_type
+      osip_content_type_t* c_t = event->request->content_type;
+      if (c_t != 0) {
+        _debug("  Content Type of the message: %s/%s\n", c_t->type, c_t->subtype);
+
+        osip_body_t *body = NULL;
+        // Get the message body
+        if (0 == osip_message_get_body(event->request, 0, &body)) {
+          _debug("  Body length: %d\n", body->length);
+          if (body->body!=0 && 
+              strcmp(c_t->type,"text") == 0 && 
+              strcmp(c_t->subtype,"plain") == 0
+            ) {
+            _debug("  Text body: %s\n", body->body);
+          }
+        }
+      }
+      osip_message_t *answerOK;
+      int tid = event->tid;
+      eXosip_lock();
+      if ( 0 == eXosip_message_build_answer(tid, OK, &answerOK)) {
+          _debug("< Sending 200 OK\n");
+          eXosip_message_send_answer(tid, OK, answerOK);
+      }
+      eXosip_unlock();
     }
     break;
 
diff --git a/src/sipvoiplink.h b/src/sipvoiplink.h
index 8aa704519d..ebfff7fea7 100644
--- a/src/sipvoiplink.h
+++ b/src/sipvoiplink.h
@@ -72,7 +72,7 @@ public:
   SipVoIPLink();
   virtual ~SipVoIPLink();
 	
-	virtual int init (void);
+	virtual bool init (void);
 	virtual bool checkNetwork (void);
 	virtual void terminate (void);
 	virtual int setRegister (void);
diff --git a/src/voIPLink.h b/src/voIPLink.h
index 6621669515..aa53a2cdd0 100644
--- a/src/voIPLink.h
+++ b/src/voIPLink.h
@@ -39,7 +39,7 @@ public:
 
 	// Pure virtual functions
 	virtual int getEvent (void) = 0;
-	virtual int init (void) = 0;
+	virtual bool init (void) = 0;
 	virtual bool checkNetwork (void) = 0;
 	virtual void terminate (void) = 0;
 	virtual void newOutgoingCall (CALLID id) = 0;
-- 
GitLab