From 71a0ac7c319c61d7400bdca46bd1fbf20ea8d348 Mon Sep 17 00:00:00 2001
From: yanmorin <yanmorin>
Date: Wed, 9 Nov 2005 21:35:05 +0000
Subject: [PATCH] Add SIPINFO (dtmf) handling

---
 src/managerimpl.cpp | 12 +++++-
 src/sipvoiplink.cpp | 99 ++++++++++++++++++++++++++++++++++++++++-----
 src/sipvoiplink.h   |  8 +++-
 tools/install.sh    |  4 +-
 4 files changed, 107 insertions(+), 16 deletions(-)

diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index b6246dfa64..677b7dee41 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -565,6 +565,7 @@ ManagerImpl::sendDtmf (CALLID id, char code)
 
 /**
  * User action (main thread)
+ * Or sip event (dtmf body submit)
  */
 bool
 ManagerImpl::playDtmf(char code)
@@ -1597,10 +1598,19 @@ ManagerImpl::getConfigList(const std::string& sequenceId, const std::string& nam
     }
     returnValue = true;
   } else if (name=="ringtones") {
+    // add empty line
+    std::ostringstream str;
+    str << 1;
+    tk.push_back(str.str());
+    tk.push_back(""); // filepath
+    _gui->sendMessage("100", sequenceId, tk);
+
+    // share directory
     std::string path = std::string(PROGSHAREDIR) + DIR_SEPARATOR_STR + RINGDIR;
-    int nbFile = 0;
+    int nbFile = 1;
     returnValue = getDirListing(sequenceId, path, &nbFile);
 
+    // home directory
     path = std::string(HOMEDIR) + DIR_SEPARATOR_STR + "." + PROGDIR + DIR_SEPARATOR_STR + RINGDIR;
     getDirListing(sequenceId, path, &nbFile);
   } else if (name=="audiodevice") {
diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp
index 14bfc14ba6..a6697a813f 100644
--- a/src/sipvoiplink.cpp
+++ b/src/sipvoiplink.cpp
@@ -82,11 +82,11 @@ SipVoIPLink::init(void)
   _started = true;
 
   srand (time(NULL));
-  // second parameter, NULL is "::" for ipv6 and "0.0.0.0" for ipv4
+  // 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, NULL, DEFAULT_SIP_PORT, AF_INET, 0);
+  i = eXosip_listen_addr(IPPROTO_UDP, INADDR_ANY, DEFAULT_SIP_PORT, AF_INET, 0);
   if (i != 0) {
-    i = eXosip_listen_addr(IPPROTO_UDP, NULL, RANDOM_SIP_PORT, AF_INET, 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;
@@ -761,7 +761,7 @@ SipVoIPLink::getEvent (void)
     break;
 
   case EXOSIP_CALL_ACK: // 15
-    id = findCallId(event);
+    id = findCallId(event); 
     _debug("%10d: Receive ACK [cid = %d, did = %d]\n", id, event->cid, event->did);
     if (id != 0 ) {
       sipcall = getSipCall(id);
@@ -785,6 +785,7 @@ SipVoIPLink::getEvent (void)
     // The peer-user closed the phone call(we received BYE).
   case EXOSIP_CALL_CLOSED: // 25
     id = findCallId(event);
+    if (id==0) { id = findCallIdInitial(event); }
     _debug("%10d: Receive BYE [cid = %d, did = %d]\n", id, event->cid, event->did);	
     if (id != 0) {
       if (Manager::instance().callCanBeClosed(id)) {
@@ -880,9 +881,30 @@ SipVoIPLink::getEvent (void)
     break;
 
   case EXOSIP_CALL_MESSAGE_NEW: // 18
-    // TODO:
-    break;
+    if (0 == event->request) break;
+    if (MSG_IS_INFO(event->request)) {
+      _debug("Receive a call message request info\n");
+      osip_content_type_t* c_t = event->request->content_type;
+      if (c_t != 0 && c_t->type != 0 && c_t->subtype != 0 ) {
+        _debug("  Content Type of the message: %s/%s\n", c_t->type, c_t->subtype);
+        // application/dtmf-relay
+        if (strcmp(c_t->type, "application") == 0 && strcmp(c_t->subtype, "dtmf-relay") == 0) {
+          handleDtmfRelay(event);
+        }
+      }
+    }
 
+    osip_message_t *answerOKNewMessage;
+    eXosip_lock();
+    if ( 0 == eXosip_call_build_answer(event->tid, OK, &answerOKNewMessage)) {
+      _debug("< Sending 200 OK\n");
+      eXosip_call_send_answer(event->tid, OK, answerOKNewMessage);
+    } else {
+      _debug("Could not sent an OK message\n");
+    }
+    eXosip_unlock();
+    break;
+ 
   case EXOSIP_REGISTRATION_SUCCESS: // 1
     // Manager::instance().displayStatus(LOGGED_IN_STATUS);
     Manager::instance().registrationSucceed();
@@ -970,7 +992,7 @@ SipVoIPLink::getEvent (void)
       _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) {
+      if (c_t != 0 &&  c_t->type != 0 && c_t->subtype != 0 ) {
         _debug("  Content Type of the message: %s/%s\n", c_t->type, c_t->subtype);
 
         osip_body_t *body = NULL;
@@ -987,11 +1009,10 @@ SipVoIPLink::getEvent (void)
         }
       }
       osip_message_t *answerOK;
-      int tid = event->tid;
       eXosip_lock();
-      if ( 0 == eXosip_message_build_answer(tid, OK, &answerOK)) {
+      if ( 0 == eXosip_message_build_answer(event->tid, OK, &answerOK)) {
           _debug("< Sending 200 OK\n");
-          eXosip_message_send_answer(tid, OK, answerOK);
+          eXosip_message_send_answer(event->tid, OK, answerOK);
       }
       eXosip_unlock();
     }
@@ -1029,6 +1050,9 @@ SipVoIPLink::setLocalPort (int port)
 
 void
 SipVoIPLink::carryingDTMFdigits (CALLID id, char code) {
+  SipCall* sipcall = getSipCall(id);
+  if (sipcall == 0) { return; }
+
   int duration = Manager::instance().getConfigInt(SIGNALISATION, PULSE_LENGTH);
   osip_message_t *info;
   const int body_len = 1000;
@@ -1045,7 +1069,7 @@ SipVoIPLink::carryingDTMFdigits (CALLID id, char code) {
     osip_message_set_content_type (info, "application/dtmf-relay");
     osip_message_set_body (info, dtmf_body, strlen (dtmf_body));
     // Send info request
-    i = eXosip_call_send_request (getSipCall(id)->getDid(), info);
+    i = eXosip_call_send_request(sipcall->getDid(), info);
   }
   eXosip_unlock();
 	
@@ -1567,3 +1591,56 @@ SipVoIPLink::findCallIdInitial (eXosip_event_t *e)
   return 0;
 }
 
+/**
+ * Handle an INFO with application/dtmf-relay content-type
+ * @param event eXosip Event
+ */
+bool
+SipVoIPLink::handleDtmfRelay(eXosip_event_t* event) {
+  bool returnValue = false;
+  osip_body_t *body = NULL;
+  // Get the message body
+  if (0 == osip_message_get_body(event->request, 0, &body) && body->body != 0 )   {
+    _debug("  Text body: %s\n", body->body);
+    std::string dtmfBody(body->body);
+    unsigned int posStart = 0;
+    unsigned int posEnd = 0;
+    std::string signal;
+    std::string duration;
+    // search for signal=and duration=
+    posStart = dtmfBody.find("Signal=");
+    if (posStart != std::string::npos) {
+      posStart += strlen("Signal=");
+      posEnd = dtmfBody.find("\n", posStart);
+      if (posEnd == std::string::npos) {
+        posEnd = dtmfBody.length();
+      }
+      signal = dtmfBody.substr(posStart, posEnd-posStart+1);
+      _debug("Signal value: %s\n", signal.c_str());
+      
+      if (!signal.empty()) {
+        int id = findCallId(event);
+        if (id!=0 && id == Manager::instance().getCurrentCallId()) {
+          Manager::instance().playDtmf(signal[0]);
+        }
+      }
+/*
+ // we receive the duration, but we use our configuration...
+
+      posStart = dtmfBody.find("Duration=");
+      if (posStart != std::string::npos) {
+        posStart += strlen("Duration=");
+        posEnd = dtmfBody.find("\n", posStart);
+        if (posEnd == std::string::npos) {
+            posEnd = dtmfBody.length();
+        }
+        duration = dtmfBody.substr(posStart, posEnd-posStart+1);
+        _debug("Duration value: %s\n", duration.c_str());
+        returnValue = true;
+      }
+*/
+    }
+  }
+  return returnValue;
+}
+
diff --git a/src/sipvoiplink.h b/src/sipvoiplink.h
index ebfff7fea7..92d3bd0209 100644
--- a/src/sipvoiplink.h
+++ b/src/sipvoiplink.h
@@ -24,8 +24,7 @@
 #define __SIP_VOIP_LINK_H__
 
 #include <vector>
-#include <eXosip2/eXosip.h>  
-//#include <osipparser2/sdp_message.h>
+#include <eXosip2/eXosip.h>
 
 #include "voIPLink.h"
 #include "audio/audiortp.h"
@@ -202,6 +201,11 @@ private:
    */
   void endSipCalls();
 
+  /**
+   * Handle DTMF Relay INFO Request
+   */
+  bool handleDtmfRelay(eXosip_event_t* event);
+
 	///////////////////////////
 	// Private member variables
 	///////////////////////////
diff --git a/tools/install.sh b/tools/install.sh
index 4ec29679f4..e9e0254c2c 100755
--- a/tools/install.sh
+++ b/tools/install.sh
@@ -43,9 +43,9 @@ cmmi() {
 }
 
 
-cmmi $SFL_FILE_CCPP2 ''
-export CPPFLAGS="-I$SFL_PREFIX/include/cc++2"
+cmmi $SFL_FILE_CCPP2 '' '--without-libxml2'
 echo "Settings CPPFLAGS to $CPPFLAGS"
+export CPPFLAGS="-I$SFL_PREFIX/include/cc++2"
 cmmi $SFL_FILE_CCRTP ''
 cmmi $SFL_FILE_LIBOSIP2 ''
 cmmi $SFL_FILE_LIBEXOSIP2 '' --disable-josua
-- 
GitLab