From 5d25a52244b37596c81165d7bd522b253e0d057d Mon Sep 17 00:00:00 2001
From: yanmorin <yanmorin>
Date: Tue, 27 Sep 2005 17:36:41 +0000
Subject: [PATCH] Voice Message notification

---
 src/call.h                         |  4 +-
 src/gui/guiframework.cpp           | 10 ++++
 src/gui/guiframework.h             |  1 +
 src/gui/server/guiserverimpl.cpp   | 22 ++++++--
 src/gui/server/guiserverimpl.h     | 29 +++++-----
 src/gui/server/responsemessage.cpp | 22 ++++++++
 src/gui/server/responsemessage.h   |  3 ++
 src/managerimpl.cpp                | 22 ++++++--
 src/managerimpl.h                  |  2 +
 src/sipvoiplink.cpp                | 85 ++++++++++++++++--------------
 10 files changed, 135 insertions(+), 65 deletions(-)

diff --git a/src/call.h b/src/call.h
index de2f0e7791..c65a9bfbce 100644
--- a/src/call.h
+++ b/src/call.h
@@ -72,7 +72,7 @@ public:
 	void setCallerIdName (const std::string& callerId_name);
 	std::string getCallerIdNumber (void);
 	void setCallerIdNumber (const std::string& callerId_number);
-	
+ 	
 	// Handle state
 	enum CallState getState (void);
 	void setState (enum CallState state);
@@ -114,7 +114,7 @@ private:
 	enum CallType 	 _type;
 	std::string 			 _callerIdName;
 	std::string 			 _callerIdNumber;
-	std::string 			 _status;
+  std::string        _status;
 };
 
 #endif // __CALL_H__
diff --git a/src/gui/guiframework.cpp b/src/gui/guiframework.cpp
index 809d820779..b5baba0aa8 100644
--- a/src/gui/guiframework.cpp
+++ b/src/gui/guiframework.cpp
@@ -28,6 +28,16 @@ GuiFramework::GuiFramework ()
 
 GuiFramework::~GuiFramework (void) {}
 
+/**
+ * This function is only to not redeclare it in old qt-gui code
+ * Since isn't not virtual
+ */
+int
+GuiFramework::incomingCall(short id, const std::string& accountId, const std::string& from) 
+{
+  return incomingCall(id);
+} 
+
 int 
 GuiFramework::outgoingCall (const string& to)
 {
diff --git a/src/gui/guiframework.h b/src/gui/guiframework.h
index cbbb5d99a9..ac110eacb6 100644
--- a/src/gui/guiframework.h
+++ b/src/gui/guiframework.h
@@ -32,6 +32,7 @@ public:
 
 	/* Parent class to child class */
 	virtual int incomingCall (short id) = 0;
+	virtual int incomingCall (short id, const std::string& accountId, const std::string& from);
 	virtual void peerAnsweredCall (short id) = 0;
 	virtual int peerRingingCall (short id) = 0;
 	virtual int peerHungupCall (short id) = 0;
diff --git a/src/gui/server/guiserverimpl.cpp b/src/gui/server/guiserverimpl.cpp
index 20545889cb..e51100e1f2 100644
--- a/src/gui/server/guiserverimpl.cpp
+++ b/src/gui/server/guiserverimpl.cpp
@@ -211,19 +211,29 @@ GUIServerImpl::version()
 }
 
 
-
 int 
 GUIServerImpl::incomingCall (short id) 
 {
-  std::ostringstream responseMessage, callId;
+  _debug("ERROR: GUIServerImpl::incomingCall(%d) should not be call\n",id);
+  return 0;
+}
+
+int 
+GUIServerImpl::incomingCall (short id, const std::string& accountId, const std::string& from) 
+{
+  TokenList arg;
+  std::ostringstream callId;
   callId << "s" << id;
-  responseMessage << "acc1 " << callId.str() << " call";
+  arg.push_back(accountId);
+  arg.push_back(callId.str());
+  arg.push_back(from);
+  arg.push_back("call");
 
   SubCall subcall("seq0", callId.str());
 
   insertSubCall(id, subcall);
 
-  _requestManager.sendResponse(ResponseMessage("001", "seq0", responseMessage.str()));
+  _requestManager.sendResponse(ResponseMessage("001", "seq0", arg));
 
   return 0;
 }
@@ -259,7 +269,7 @@ GUIServerImpl::peerHungupCall (short id)
     std::ostringstream responseMessage;
     responseMessage << iter->second.callId() << " hangup";
 
-    _requestManager.sendResponse(ResponseMessage("250", "seq0", responseMessage.str()));
+    _requestManager.sendResponse(ResponseMessage("002", "seq0", responseMessage.str()));
     
     // remove this call...
     _callMap.erase(id);
@@ -324,9 +334,11 @@ GUIServerImpl::setup (void)
 void  
 GUIServerImpl::startVoiceMessageNotification (void) 
 {
+  _requestManager.sendResponse(ResponseMessage("020", "seq0", "voice message"));
 }
 
 void  
 GUIServerImpl::stopVoiceMessageNotification (void) 
 {
+  _requestManager.sendResponse(ResponseMessage("021", "seq0", "no voice message"));
 }
diff --git a/src/gui/server/guiserverimpl.h b/src/gui/server/guiserverimpl.h
index 839c2be0c6..8ece35def1 100644
--- a/src/gui/server/guiserverimpl.h
+++ b/src/gui/server/guiserverimpl.h
@@ -44,19 +44,22 @@ public:
   short getIdFromCallId(const std::string& callId);
 
   // Reimplementation of virtual functions
-	virtual int incomingCall (short id);
-	virtual void peerAnsweredCall (short id);
-	virtual int peerRingingCall (short id);
-	virtual int peerHungupCall (short id);
-	virtual void displayTextMessage (short id, const std::string& message);
-	virtual void displayErrorText (short id, const std::string& message);
-	virtual void displayError (const std::string& error);
-	virtual void displayStatus (const std::string& status);
-	virtual void displayContext (short id);
-	virtual std::string getRingtoneFile (void);
-	virtual void setup (void);
-	virtual void startVoiceMessageNotification (void);
-	virtual void stopVoiceMessageNotification (void);  
+  // TODO: remove incomingCall with one parameter
+	int incomingCall (short id);
+  int incomingCall(short id, const std::string& accountId, const std::string& from);
+
+	void peerAnsweredCall (short id);
+	int peerRingingCall (short id);
+	int peerHungupCall (short id);
+	void displayTextMessage (short id, const std::string& message);
+	void displayErrorText (short id, const std::string& message);
+	void displayError (const std::string& error);
+	void displayStatus (const std::string& status);
+	void displayContext (short id);
+	std::string getRingtoneFile (void);
+	void setup (void);
+	void startVoiceMessageNotification (void);
+	void stopVoiceMessageNotification (void);  
 
   bool outgoingCall (const std::string& seq, 
     const std::string& callid, 
diff --git a/src/gui/server/responsemessage.cpp b/src/gui/server/responsemessage.cpp
index 46dc17d4c8..6e735c8c59 100644
--- a/src/gui/server/responsemessage.cpp
+++ b/src/gui/server/responsemessage.cpp
@@ -30,6 +30,28 @@ ResponseMessage::ResponseMessage(const std::string& code,
 {
 }
 
+/*
+ * Construct a message with a list of argument
+ * and a space separator between each argument
+ */
+ResponseMessage::ResponseMessage(const std::string& code,
+      const std::string& seq,
+      TokenList& arg) : _code(code), _seq(seq)
+{
+  TokenList::iterator iter=arg.begin();
+  if (iter!=arg.end()) {
+    _message = *iter;
+    iter++;
+  }
+  // add space between each
+  while(iter!=arg.end()) {
+    _message.append(" ");
+    // TODO: encode string here
+    _message.append(*iter);
+    iter++;
+  }
+}
+
 
 ResponseMessage::~ResponseMessage()
 {
diff --git a/src/gui/server/responsemessage.h b/src/gui/server/responsemessage.h
index 2a2522ea9a..906b8df415 100644
--- a/src/gui/server/responsemessage.h
+++ b/src/gui/server/responsemessage.h
@@ -20,6 +20,8 @@
 #define __RESPONSEMESSAGE_H__
 
 #include <string>
+#include "argtokenizer.h" // for TokenList declare
+
 /**
 Response Message stock a message from a request when it is executed.
 @author Yan Morin
@@ -32,6 +34,7 @@ public:
     // build a constructor with a TokenList
     // so that they will be encoded..
     ResponseMessage(const std::string& code,const std::string& seq, const std::string& message);
+    ResponseMessage(const std::string& code,const std::string& seq, TokenList& arg);
     ~ResponseMessage();
 
     std::string sequenceId() const { return _seq; }
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index 342cb6e2b5..5e4787d6cc 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -65,8 +65,9 @@ ManagerImpl::ManagerImpl (void)
   // Init private variables 
   _error = new Error();
   _tone = new ToneGenerator();	
-  
+  _hasZeroconf = false;
 #ifdef USE_ZEROCONF
+  _hasZeroconf = true;
   _DNSService = new DNSService();
 #endif
 
@@ -562,16 +563,27 @@ ManagerImpl::sendDtmf (short id, char code)
 int 
 ManagerImpl::incomingCall (short id)
 {
-	Call* call;
-	call = getCall(id);
+	Call* call = getCall(id);
 	if (call == NULL)
 		return -1;
+
 	call->setType(Incoming);
 	call->setStatus(string(RINGING_STATUS));
 	call->setState(Progressing);
 	ringtone(true);
 	//displayStatus(RINGING_STATUS);
-	return _gui->incomingCall(id);
+
+  // TODO: Account not yet implemented
+  std::string accountId = "acc1";
+  std::string from = call->getCallerIdName();
+  std::string number = call->getCallerIdNumber();
+  if ( number.length() ) {
+    from.append(" <");
+    from.append(number);
+    from.append(">");
+  }
+
+  return _gui->incomingCall(id, accountId, from);
 }
 
 void 
@@ -687,7 +699,7 @@ ManagerImpl::displayStatus (const string& status)
 void
 ManagerImpl::startVoiceMessageNotification (void)
 {
-	_gui->startVoiceMessageNotification();
+  _gui->startVoiceMessageNotification();
 }
 
 void
diff --git a/src/managerimpl.h b/src/managerimpl.h
index d369c10404..4321043d05 100644
--- a/src/managerimpl.h
+++ b/src/managerimpl.h
@@ -354,6 +354,8 @@ private:
 
   // look if zeroconf scanning should run or not
   int _useZeroconf;
+  // tell if we have zeroconf d'enable
+  int _hasZeroconf;
 
 #ifdef USE_ZEROCONF
   // DNSService contain every zeroconf services
diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp
index 2d2e812765..d10f7c240c 100644
--- a/src/sipvoiplink.cpp
+++ b/src/sipvoiplink.cpp
@@ -562,12 +562,12 @@ SipVoIPLink::getEvent (void)
     } else {
       // If there is a firewall
       if (behindNat() != 0) {
-	setLocalPort(Manager::instance().getFirewallPort());
+        setLocalPort(Manager::instance().getFirewallPort());
       } else {
-	return -1;
-      }	
+        return -1;
+      }
     }
-			
+
     // Generate id
     id = Manager::instance().generateNewCallId();
     Manager::instance().pushBackNewCall(id, Incoming);
@@ -584,31 +584,38 @@ SipVoIPLink::getEvent (void)
 
       osip_from_to_str (event->request->from, &tmp);
       if (tmp != NULL) {
-	snprintf (getSipCall(id)->getRemoteUri(), 256, "%s", tmp);
-	osip_free (tmp);
+        snprintf (getSipCall(id)->getRemoteUri(), 256, "%s", tmp);
+        osip_free (tmp);
       }
     }
     osip_from_parse(from, getSipCall(id)->getRemoteUri());
     name = osip_from_get_displayname(from);
-    Manager::instance().displayTextMessage(id, name);
-    if (Manager::instance().getCall(id) != NULL) {
-      Manager::instance().getCall(id)->setCallerIdName(name);
+
+    //Don't need this display text message now that we send the name
+    //inside the Manager to the gui
+    //Manager::instance().displayTextMessage(id, name);
+    Call *call = Manager::instance().getCall(id);
+    if ( call != NULL) {
+      call->setCallerIdName(name);
+      osip_uri_t* url = osip_from_get_url(from);
+      if ( url != NULL ) {
+        call->setCallerIdNumber(url->username);
+      }
     } else {
+      osip_from_free(from);
       return -1;
     }
     _debug("From: %s\n", name);
     osip_from_free(from);
-			
+
     // Associate an audio port with a call
     getSipCall(id)->setLocalAudioPort(_localPort);
 
-			
     getSipCall(id)->newIncomingCall(event);
     if (Manager::instance().incomingCall(id) < 0) {
       Manager::instance().displayErrorText(id, "Incoming call failed");
       return -1;
     }
-	
     break;
 
   case EXOSIP_CALL_REINVITE:
@@ -621,22 +628,22 @@ SipVoIPLink::getEvent (void)
     if (id == 0) {
       id = findCallIdInitial(event);
     }
-    SipCall *call = getSipCall(id);
-    if ( call ) {
+    SipCall *sipcall = getSipCall(id);
+    if ( sipcall ) {
       _debug("Call is answered [id = %d, cid = %d, did = %d], localport=%d\n", 
-	   id, event->cid, event->did,call->getLocalAudioPort());
+	   id, event->cid, event->did,sipcall->getLocalAudioPort());
     }
  
     // Answer
     if (id > 0 && !Manager::instance().getCall(id)->isOnHold()
                && !Manager::instance().getCall(id)->isOffHold()) {
-      call->setStandBy(false);
-      if (call->answeredCall(event) != -1) {
-        call->answeredCall_without_hold(event);
+      sipcall->setStandBy(false);
+      if (sipcall->answeredCall(event) != -1) {
+        sipcall->answeredCall_without_hold(event);
         Manager::instance().peerAnsweredCall(id);
 
         // Outgoing call is answered, start the sound channel.
-        if (_audiortp.createNewSession (call) < 0) {
+        if (_audiortp.createNewSession (sipcall) < 0) {
           _debug("FATAL: Unable to start sound (%s:%d)\n", 
           __FILE__, __LINE__);
           exit(1);
@@ -645,7 +652,7 @@ SipVoIPLink::getEvent (void)
     } else {
       // Answer to on/off hold to send ACK
       if (id > 0) {
-        call->answeredCall(event);
+        sipcall->answeredCall(event);
         _debug("-----------------------\n");
       }
     }
@@ -697,10 +704,8 @@ SipVoIPLink::getEvent (void)
     }	
     break;
   case EXOSIP_CALL_RELEASED:
-    id = findCallIdInitial(event);
-    _debug("Id Released: %d\n", id);
-    //TODO: find the id...
-    //Manager::instance().displayErrorText(0, "getEvent:CallReleased");
+    //id = findCallIdInitial(event);
+    //_debug("Id Released: %d\n", id);
 
     break;
   case EXOSIP_CALL_REQUESTFAILURE:
@@ -771,7 +776,7 @@ SipVoIPLink::getEvent (void)
     break;
 
   case EXOSIP_REGISTRATION_FAILURE: // 2
-    Manager::instance().displayError("getEvent : Registration Failure\n");
+    Manager::instance().displayError("getEvent : Registration Failure");
     break;
 
   case EXOSIP_MESSAGE_NEW:
@@ -779,25 +784,25 @@ SipVoIPLink::getEvent (void)
 				
     if (event->request != NULL && MSG_IS_OPTIONS(event->request)) {
       for (k = 0; k < _sipcallVector.size(); k++) {
-	if (_sipcallVector.at(k)->getCid() == event->cid) { 
-	  break;
-	}
+        if (_sipcallVector.at(k)->getCid() == event->cid) { 
+          break;
+        }
       }
 			
       // TODO: Que faire si rien trouve??
       eXosip_lock();
       if (k == _sipcallVector.size()) {
-	/* answer 200 ok */
-	eXosip_options_send_answer (event->tid, OK, NULL);
+        /* answer 200 ok */
+        eXosip_options_send_answer (event->tid, OK, NULL);
       } else if (_sipcallVector.at(k)->getCid() == event->cid) {
-	/* already answered! */
+        /* already answered! */
       } else {
-	/* answer 486 ok */
-	eXosip_options_send_answer (event->tid, BUSY_HERE, NULL);
+        /* answer 486 ok */
+      	eXosip_options_send_answer (event->tid, BUSY_HERE, NULL);
       }
       eXosip_unlock();
     } 
-			
+
     // Voice message 
     else if (event->request != NULL && MSG_IS_NOTIFY(event->request)){
       int ii;
@@ -813,29 +818,29 @@ SipVoIPLink::getEvent (void)
         _debug("Cannot get body\n");
         return -1;
       }
-				
+
       // Analyse message body
       str = new string(body->body);
       pos = str->find (VOICE_MSG);
-				
+
       if (pos == string::npos) {
 	     // If the string is not found
        delete str;
 	     return -1;
       } 
-				
+
       pos_slash = str->find ("/");
       nb_msg = str->substr(pos + LENGTH_VOICE_MSG, 
-			   pos_slash - (pos + LENGTH_VOICE_MSG));
+      pos_slash - (pos + LENGTH_VOICE_MSG));
 
       // Set the number of voice-message
       setMsgVoicemail(atoi(nb_msg.data()));
 
       if (getMsgVoicemail() != 0) {
-	// If there is at least one voice-message, start notification
+        // If there is at least one voice-message, start notification
         Manager::instance().startVoiceMessageNotification();
       } else {
-	// Stop notification when there is 0 voice message
+        // Stop notification when there is 0 voice message
         Manager::instance().stopVoiceMessageNotification();
       }
       delete str;
-- 
GitLab