Hello,

I'm attaching a patch which implement Pager functionality (sending SMS using SIP/SMS gateway)

The patch is against branch wengophone-2.1

The patch does not touch the GUI stuff only libs/imwrapper and libs/sipwrapper.... it does not modify
existing functionality.

I'd like somebody to look at it and confirm/infirm that i can commit




Thanks
Vadim




Index: imwrapper/include/imwrapper/IMWrapperFactory.h
===================================================================
--- imwrapper/include/imwrapper/IMWrapperFactory.h	(revision 10772)
+++ imwrapper/include/imwrapper/IMWrapperFactory.h	(working copy)
@@ -28,7 +28,8 @@
 class IMConnect;
 class IMPresence;
 class IMContactList;
-
+class IMPager;
+    
 /**
  * Factories for the Instant Messaging wrapper component.
  *
@@ -103,7 +104,16 @@
 	 * @return the new IMContactList instance.
 	 */
 	virtual IMContactList * createIMContactList(IMAccount & account) = 0;
+
+
+	/**
+	 * Instantiates a IMPager implementation.
+	 *
+	 * @return the new IMPager instance.
+	 */
+	virtual IMPager * createIMPager(const std::string &smsServer) = 0;
 
+
 	/** 
 	 * Tells the wrapper to remove all class associated with the given IMAccount. 
 	 * TODO: this is a workaround until the refactoring from CoIpManager branch. 
Index: imwrapper/include/imwrapper/IMPager.h
===================================================================
--- imwrapper/include/imwrapper/IMPager.h	(revision 0)
+++ imwrapper/include/imwrapper/IMPager.h	(revision 0)
@@ -0,0 +1,97 @@
+/*
+ * WengoPhone, a voice over Internet phone
+ * Copyright (C) 2004-2006  Wengo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef OWIMPAGER_H
+#define OWIMPAGER_H
+
+
+#include <util/Event.h>
+#include <util/Interface.h>
+#include <util/Trackable.h>
+
+#include <string>
+#include <list>
+
+
+/**
+ * Wrapper for sending Pager mode Instant Messages
+ *
+ * @author Vadim Lebedev
+ */
+class IMPager : Interface, public Trackable {
+public:
+
+	/**
+	 * Emitted when a new Page Mode message arrives.
+	 *
+	 * @param  from  SIP originator
+     * @param  ctt   content type
+	 * @param  message message content
+	 */
+	Event<void (const std::string & from, const std::string & ctt,  const std::string & message )> sipMessageEvent;
+
+	/**
+	 * Emitted when a new SMS Mode message arrives.
+	 *
+     * @param  ctt   content type
+	 * @param  message message content
+	 */
+	Event<void (const std::string & ctt,  const std::string & message )> smsMessageEvent;
+
+	/**
+	 * Emitted when a new SMS Mode message arrives.
+	 *
+     * @param  ctt   content type
+	 * @param  message message content
+	 */
+	Event<void (const std::string & ctt,  const std::string & message )> smsDeliveredEvent;
+
+
+    /**
+     * Send SIP MESSAGE request
+     *
+     * @param to destination URI
+     * @param ctt content type
+     * @param message message text
+     */
+    virtual void sendSipMessage(const std::string &to, const std::string &ctt, const std::string & message) = 0;
+    
+
+   /**
+     * Send SMS  MESSAGE using SIP-SMS server
+     *
+     * @param tos list of SMS destinations URIs
+     * @param subj message subject
+     * @param ctt content type
+     * @param message message text
+     * @param msgid  generated message id (can be used to match delivery notifications)
+     */
+    virtual void sendSmsMessage(const std::list<std::string> & tos, const std::string &subj, 
+        const std::string &ctt, const std::string & message, std::string &msgid) = 0;
+    
+
+
+	IMPager(const std::string &smsServerUri) : smsServer(smsServerUri) { }
+    
+protected:
+    std::string smsServer; 
+};
+
+
+#endif	//OWIMPAGER
Index: imwrapper/src/multiim/multiim/MultiIMFactory.h
===================================================================
--- imwrapper/src/multiim/multiim/MultiIMFactory.h	(revision 10772)
+++ imwrapper/src/multiim/multiim/MultiIMFactory.h	(working copy)
@@ -47,6 +47,8 @@
 	virtual IMContactList * createIMContactList(IMAccount & account);
 
 	virtual void removeIMAccount(IMAccount imAccount);
+
+    virtual IMPager * createIMPager(const std::string &smsServer);
 
 private:
 
Index: imwrapper/src/multiim/MultiIMFactory.cpp
===================================================================
--- imwrapper/src/multiim/MultiIMFactory.cpp	(revision 10772)
+++ imwrapper/src/multiim/MultiIMFactory.cpp	(working copy)
@@ -56,11 +56,11 @@
 	} else {
 		return _gaimIMFactory.createIMChat(account);
 	}
-}
-
+}
+
 IMPresence * MultiIMFactory::createIMPresence(IMAccount & account) {
 	if ((account.getProtocol() == EnumIMProtocol::IMProtocolSIPSIMPLE)
-		|| (account.getProtocol() == EnumIMProtocol::IMProtocolSIP)
+		|| (account.getProtocol() == EnumIMProtocol::IMProtocolSIP)	
 		|| (account.getProtocol() == EnumIMProtocol::IMProtocolWengo)) {
 		return _phApiFactory.createIMPresence(account);
 	} else {
@@ -68,6 +68,11 @@
 	}
 }
 
+
+IMPager * MultiIMFactory::createIMPager(const std::string &smsServer) {
+		return _phApiFactory.createIMPager(smsServer);
+}
+
 IMContactList * MultiIMFactory::createIMContactList(IMAccount & account) {
 	if ((account.getProtocol() == EnumIMProtocol::IMProtocolSIPSIMPLE)
 		|| (account.getProtocol() == EnumIMProtocol::IMProtocolSIP)
@@ -76,8 +81,10 @@
 	} else {
 		return _gaimIMFactory.createIMContactList(account);
 	}
-}
+}
+
 
+
 void MultiIMFactory::removeIMAccount(IMAccount imAccount) { 
 	if ((imAccount.getProtocol() == EnumIMProtocol::IMProtocolSIPSIMPLE)
 		|| (imAccount.getProtocol() == EnumIMProtocol::IMProtocolSIP)
Index: imwrapper/src/gaim/GaimIMFactory.h
===================================================================
--- imwrapper/src/gaim/GaimIMFactory.h	(revision 10772)
+++ imwrapper/src/gaim/GaimIMFactory.h	(working copy)
@@ -58,7 +58,9 @@
 	virtual IMPresence *createIMPresence(IMAccount & account);
 
 	virtual IMContactList *createIMContactList(IMAccount & account);
-
+
+    virtual IMPager * createIMPager(const std::string &smsServer) { return 0; }
+    
 	virtual void removeIMAccount(IMAccount imAccount);
 
 	static bool equals(const IMAccount & imAccount,
Index: sipwrapper/src/phapi/PhApiFactory.h
===================================================================
--- sipwrapper/src/phapi/PhApiFactory.h	(revision 10772)
+++ sipwrapper/src/phapi/PhApiFactory.h	(working copy)
@@ -50,6 +50,8 @@
 	virtual IMChat * createIMChat(IMAccount & account);
 
 	virtual IMPresence * createIMPresence(IMAccount & account);
+
+    virtual IMPager * createIMPager(const std::string &smsServer);
 
 	virtual IMContactList * createIMContactList(IMAccount & account);
 
Index: sipwrapper/src/phapi/PhApiCallbacks.cpp
===================================================================
--- sipwrapper/src/phapi/PhApiCallbacks.cpp	(revision 10772)
+++ sipwrapper/src/phapi/PhApiCallbacks.cpp	(working copy)
@@ -544,7 +544,16 @@
 	if (info->szSubContentType) {
 		subtype = info->szSubContentType;
 	}
-
+
+    std::string ctt = ctype;
+    ctt += "/";
+    ctt += subtype;
+
+    if (info->event == MESSAGE_NEW)  {
+    	std::string to = p->parseFromHeader(std::string(info->szLocalIdentity));
+        p->sipMessageEvent(*p, to, from, ctt, content);
+    }
+    
 	//Getting buddy icon
 	if ((info->event == MESSAGE_NEW) && (ctype == "buddyicon")) {
 		if (!subtype.empty()) {
@@ -555,7 +564,7 @@
 
 	// Is there already an IMChatSession with this contact?
 	IMChatSession *imChatSession = p->getIMChatSession(from);
-
+
 	//Drop typingstate packet if there is no chat session created
 	if (!imChatSession && (ctype == "typingstate" || (ctype == "application" && subtype == "im-iscomposing+xml"))) {
 		return;
@@ -605,7 +614,7 @@
 		} else {
 			// once a message is received, typing is inferred off
 			p->typingStateChangedEvent(*p, *imChatSession, from, IMChat::TypingStateNotTyping);
-			p->messageReceivedEvent(*p, *imChatSession, from, content);
+			p->messageReceivedEvent(*p, *imChatSession, from, content);
 		}
 
 		break;
Index: sipwrapper/src/phapi/PhApiWrapper.cpp
===================================================================
--- sipwrapper/src/phapi/PhApiWrapper.cpp	(revision 10772)
+++ sipwrapper/src/phapi/PhApiWrapper.cpp	(working copy)
@@ -927,3 +927,12 @@
 
 	return result;
 }
+
+
+
+void PhApiWrapper::sendMessage(const std::string & to, const std::string & ctt, const std::string & message)
+{
+    int mid;
+    
+    owplMessageSend(_wengoVline, to.c_str(), ctt.c_str(), message.c_str(), &mid);
+}
Index: sipwrapper/src/phapi/PhApiIMPager.cpp
===================================================================
--- sipwrapper/src/phapi/PhApiIMPager.cpp	(revision 0)
+++ sipwrapper/src/phapi/PhApiIMPager.cpp	(revision 0)
@@ -0,0 +1,178 @@
+/*
+ * WengoPhone, a voice over Internet phone
+ * Copyright (C) 2007  MBDSYS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <algorithm>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+#include <ctype.h>
+#include <time.h>
+#include <sstream>
+
+#include "PhApiIMPager.h"
+#include "PhApiWrapper.h"
+
+
+PhApiIMPager::PhApiIMPager(const std::string & smsServer, PhApiWrapper & phApiWrapper)
+	: IMPager(smsServer),
+	_phApiWrapper(phApiWrapper) {
+
+
+	_phApiWrapper.sipMessageEvent += 
+        boost::bind(&PhApiIMPager::msgReceivedEventHandler, this, _1, _2, _3, _4, _5);
+
+
+    myself = phApiWrapper._wengoSipAddress;        
+}
+
+
+
+static std::string tolowercase(const std::string &data)
+{
+    std::string cp = data;
+
+    std::transform(data.begin(), data.end(), cp.begin(), boost::bind(&tolower, _1));
+    return cp;
+    
+}
+
+// extract payload type from the message
+static std::string getHeaderValue(const char *hdrname, const std::string & data, bool lcvalue = true)
+{
+    static std::string nullstr;
+    std::string hdr = tolowercase(hdrname);
+    
+    std::string lcdata = tolowercase(data);
+    std::string::size_type cttPos;
+    
+    cttPos = lcdata.find("content-type:", 0);
+    if (cttPos == lcdata.npos)
+        return nullstr;
+
+    cttPos += hdr.size();
+    std::string::size_type lineEnd = lcdata.find('\r', cttPos);
+    if (lineEnd == lcdata.npos)
+        lineEnd = lcdata.length();
+    
+    cttPos = lcdata.find_first_not_of(" ", cttPos);
+    
+    std::string cttVal(lcvalue ? lcdata :  data, cttPos, lineEnd - cttPos);
+    
+    return cttVal;
+}
+
+static std::string getPayloadType(const std::string data)
+{
+    return getHeaderValue("Content-Type:", data, true);
+}
+
+void PhApiIMPager::msgReceivedEventHandler(PhApiWrapper & sender, const std::string & to,
+    const std::string & from, const std::string & ctt, const std::string & message) {       
+
+    if (message.empty())
+        return;
+
+    std::string lctt = tolowercase(ctt);
+    if (lctt != "message/cpim") {
+        sipMessageEvent(from, ctt, message);
+        return;
+    }
+    
+    std::string payloadType = getPayloadType(message);
+        
+    if (payloadType == "text/html") 
+        smsMessageEvent(payloadType, message);
+    else if (payloadType == "message/imdn+xml")            
+     smsDeliveredEvent(payloadType, message);
+    else {
+            // FIXME:  LOG something
+    }
+           
+            
+}
+
+
+
+void PhApiIMPager::sendSipMessage(const std::string &to, const std::string &ctt, const std::string & message) {
+
+	if (!message.empty()) {
+		_phApiWrapper.sendMessage(to, ctt, message);
+	}
+}
+
+
+static std::string maketmstamp()
+{
+  struct tm tmbuf;
+  time_t  now;
+  char  tmstr[64];
+
+
+  now = time(0);
+  tmbuf = *localtime(&now);
+
+  strftime(tmstr, 64, "%d-%b-%Y %I:%M:%S %P", &tmbuf);
+
+  return tmstr;
+ 
+}
+
+
+void PhApiIMPager::sendSmsMessage(const std::list<std::string> & tos, const std::string &subj, 
+    const std::string &ctt, const std::string & message, std::string &msgid) {
+
+
+    if (!message.empty()) 
+        return;
+
+    msgid = "this is msgid";
+    
+    std::string msg; 
+    struct builder {
+        std::string &target;
+        
+        void add(const char *hdr, const std::string &v) { target += hdr; target += v; target += "\r\n"; }
+        void add(const char *hdr, const char* v) { target += hdr; target += v; target += "\r\n"; }
+        builder(std::string &t) : target(t) {}
+    };
+    builder bh(msg);
+    std::ostringstream os;
+
+    
+    
+    bh.add("From: ", myself);
+    for( std::list<std::string>::const_iterator it = tos.begin(); it != tos.end(); it++)
+        bh.add("To: ", *it);
+    
+    bh.add("DateTime: ", maketmstamp());
+    bh.add("Subject: ", subj);
+    bh.add("Expires: ", "3600");
+    bh.add("imdn.Message-ID: ", msgid);
+    bh.add("imdn.Disposition-Notification: ", "");
+    bh.add("Content-Type: ", ctt);
+    os << message.length();    
+    bh.add("Content-Length: ", os.str());
+    msg += message;
+    
+    sendSipMessage(this->smsServer, "message/cpim", msg);
+    
+ 	
+}
+
+
Index: sipwrapper/src/phapi/PhApiWrapper.h
===================================================================
--- sipwrapper/src/phapi/PhApiWrapper.h	(revision 10772)
+++ sipwrapper/src/phapi/PhApiWrapper.h	(working copy)
@@ -53,7 +53,9 @@
  * @author Mathieu Stute
  * @author Julien Bossart
  */
-class PhApiWrapper : public SipWrapper {
+class PhApiWrapper : public SipWrapper {
+    friend class PhApiIMChat;
+    friend class PhApiIMPager;
 public:
 
 	Event<void (PhApiWrapper & sender, IMChatSession & imChatSession)> newIMChatSessionCreatedEvent;
@@ -82,6 +84,15 @@
 
 	Event<void (PhApiWrapper & sender, const std::string & contactId, const std::string filename)> contactIconChangedEvent;
 
+    Event<void (PhApiWrapper & sender, const std::string & to, 	
+        const std::string & from, const std::string & ctt, const std::string & message)> sipMessageEvent;
+
+    Event<void (PhApiWrapper & sender, const std::string & to, 	
+        const std::string & from, const std::string & ctt, const std::string & body)>  sipNotifyEvent;
+
+
+
+public:
 
 	/** Value when phApi returns an error message. */
 	static const int PhApiResultNoError = 0;
@@ -213,6 +224,9 @@
 	void removeContact(IMChatSession & chatSession, const std::string & contactId);
 
 	/** @} */
+
+
+	void sendMessage(const std::string & to, const std::string & ctt, const std::string & message);
 
 	/**
 	 * @name IMPresence Implementation
Index: sipwrapper/src/phapi/PhApiIMPager.h
===================================================================
--- sipwrapper/src/phapi/PhApiIMPager.h	(revision 0)
+++ sipwrapper/src/phapi/PhApiIMPager.h	(revision 0)
@@ -0,0 +1,76 @@
+/*
+ * WengoPhone, a voice over Internet phone
+ * Copyright (C) 2007  MBDSYS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef PHAPIIMPAGER_H
+#define PHAPIIMPAGER_H
+
+
+#include <imwrapper/IMPager.h>
+
+/**
+ * PhApi IM Pager.
+ *
+ * @ingroup model
+ * @author Vadim Lebedev
+ */
+class PhApiIMPager : public IMPager {
+	friend class PhApiFactory;
+	friend class PhApiWrapper;
+	friend class PhApiCallbacks;
+public:
+
+    /**
+     * Send SIP MESSAGE request
+     *
+     * @param to destination URI
+     * @param ctt content type
+     * @param message message text
+     */
+    virtual void sendSipMessage(const std::string &to, const std::string &ctt, const std::string & message);
+    
+
+   /**
+     * Send SMS  MESSAGE using SIP-SMS server
+     *
+     * @param tos list of SMS destinations URIs
+     * @param subj message subject
+     * @param ctt content type
+     * @param message message text
+     * @param msgid  generated message id (can be used to match delivery notifications)
+     */
+    virtual void sendSmsMessage(const std::list<std::string> & tos, const std::string &subj, 
+        const std::string &ctt, const std::string & message, std::string &msgid);    
+
+
+
+protected:
+
+	PhApiIMPager(const std::string & smsServer, PhApiWrapper & phApiWrapper);
+
+
+    void msgReceivedEventHandler(PhApiWrapper & sender, const std::string & to,
+        const std::string & from, const std::string & ctt, const std::string & message);
+
+
+
+	PhApiWrapper & _phApiWrapper;
+    std::string myself;
+};
+
+#endif	//PHAPIIMPAGER_H
Index: sipwrapper/src/phapi/PhApiFactory.cpp
===================================================================
--- sipwrapper/src/phapi/PhApiFactory.cpp	(revision 10772)
+++ sipwrapper/src/phapi/PhApiFactory.cpp	(working copy)
@@ -22,7 +22,8 @@
 #include "PhApiWrapper.h"
 #include "PhApiIMConnect.h"
 #include "PhApiIMChat.h"
-#include "PhApiIMPresence.h"
+#include "PhApiIMPresence.h"
+#include "PhApiIMPager.h"
 
 PhApiFactory::PhApiFactory() {
 	_phApiWrapperInstance = PhApiWrapper::getInstance();
@@ -48,8 +49,14 @@
 
 IMPresence * PhApiFactory::createIMPresence(IMAccount & account) {
 	return new PhApiIMPresence(account, *_phApiWrapperInstance);
-}
+}
+
+
+IMPager * PhApiFactory::createIMPager(const std::string &smsServer) {
+	return new PhApiIMPager(smsServer, *_phApiWrapperInstance);
+}
 
+
 IMContactList * PhApiFactory::createIMContactList(IMAccount & account) {
 	return NULL;
 }
Index: sipwrapper/src/phapi/CMakeLists.txt
===================================================================
--- sipwrapper/src/phapi/CMakeLists.txt	(revision 10772)
+++ sipwrapper/src/phapi/CMakeLists.txt	(working copy)
@@ -34,6 +34,7 @@
 	PhApiSFPCallbacks.cpp
 	PhApiSFPWrapper.cpp
 	PhApiSFPEvent.cpp
+    PhApiIMPager.cpp
 )
 
 if (PHAPI_VIDEO_SUPPORT)
_______________________________________________
Wengophone-devel mailing list
Wengophone-devel@lists.openwengo.com
http://dev.openwengo.com/mailman/listinfo/wengophone-devel

Reply via email to