Module: sems
Branch: master
Commit: 96b1e816e4ccf9f588f790525f331245c0653a3c
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=96b1e816e4ccf9f588f790525f331245c0653a3c

Author: Raphael Coeffic <[email protected]>
Committer: Raphael Coeffic <[email protected]>
Date:   Mon Sep 27 17:29:59 2010 +0200

adds MWI support through PUBLISH

The mwi plug-in uses the event notification from the msg_storage plug-in and 
sends PUBLISH requests to a presence server.
Thanks to Anton Zagorskiy for this contribution.

---

 apps/mwi/CMakeLists.txt |    7 +++
 apps/mwi/Makefile       |    7 +++
 apps/mwi/etc/mwi.conf   |    2 +
 apps/mwi/mwi.cpp        |  126 +++++++++++++++++++++++++++++++++++++++++++++++
 apps/mwi/mwi.h          |   41 +++++++++++++++
 5 files changed, 183 insertions(+), 0 deletions(-)

diff --git a/apps/mwi/CMakeLists.txt b/apps/mwi/CMakeLists.txt
new file mode 100644
index 0000000..80dd6a2
--- /dev/null
+++ b/apps/mwi/CMakeLists.txt
@@ -0,0 +1,7 @@
+set (mwi_SRCS
+mwi.cpp
+)
+
+SET(sems_module_name mwi)
+INCLUDE(${CMAKE_SOURCE_DIR}/cmake/module.rules.txt)
+INCLUDE(${CMAKE_SOURCE_DIR}/cmake/config.rules.txt)
diff --git a/apps/mwi/Makefile b/apps/mwi/Makefile
new file mode 100644
index 0000000..cec8b8d
--- /dev/null
+++ b/apps/mwi/Makefile
@@ -0,0 +1,7 @@
+plug_in_name = mwi
+
+module_ldflags =
+module_cflags  = -DMOD_NAME=\"$(plug_in_name)\"
+
+COREPATH ?=../../core
+include $(COREPATH)/plug-in/Makefile.app_module
diff --git a/apps/mwi/etc/mwi.conf b/apps/mwi/etc/mwi.conf
new file mode 100644
index 0000000..13fcce6
--- /dev/null
+++ b/apps/mwi/etc/mwi.conf
@@ -0,0 +1,2 @@
+# Presence Server:
+presence_server=127.0.0.1
\ No newline at end of file
diff --git a/apps/mwi/mwi.cpp b/apps/mwi/mwi.cpp
new file mode 100644
index 0000000..8597234
--- /dev/null
+++ b/apps/mwi/mwi.cpp
@@ -0,0 +1,126 @@
+/*
+  Copyright (C) Anton Zagorskiy [email protected]
+  Oyster-Telecom Laboratory
+        
+  Published under BSD License
+*/
+            
+#include "AmPlugIn.h"
+#include "AmSession.h"
+#include "AmConfigReader.h"
+#include "AmUtils.h"
+#include "log.h"
+#include "mwi.h"
+#include <string>
+
+MWI* MWI::_instance = 0;
+AmDynInvoke* MWI::MessageStorage = 0;
+
+EXPORT_PLUGIN_CLASS_FACTORY(MWI, MOD_NAME);
+
+MWI::MWI(const string& name)
+  : AmDynInvokeFactory(name) { 
+  _instance = this; 
+};
+
+MWI::~MWI() { };
+
+
+int MWI::onLoad()
+{
+  AmDynInvokeFactory* ms_fact = 
+    AmPlugIn::instance()->getFactory4Di("msg_storage");
+
+  if(!ms_fact || !(MessageStorage = ms_fact->getInstance())) {
+    ERROR("could not load msg_storage. Load a msg_storage implementation 
module.\n");
+    return -1;
+  };
+
+  // register the publish method as event sink for msg_storage events
+  AmArg es_args,ret;
+  es_args.push(this);
+  es_args.push("publish");
+  MessageStorage->invoke("events_subscribe",es_args,ret);
+  
+  AmConfigReader cfg;
+  if(cfg.loadFile(AmConfig::ModConfigPath + "mwi.conf")) {
+    ERROR("can not load configuration file\n");
+    return -1;
+  };
+  
+  presence_server = cfg.getParameter("presence_server");
+  if (presence_server.length())
+    DBG("set presence server '%s'\n", presence_server.c_str());
+  else {
+    ERROR("parameter 'presence_server' did not found in the configuration 
file\n");
+    return -1;
+  }                
+  
+  DBG("MWI module loaded.\n");
+  return 0;
+};
+
+
+void MWI::publish(const string& user, const string& domain)
+{
+  int new_msgs = 0;
+  int all_msgs = 0;
+  string headers, body;
+                                            
+  AmArg di_args, ret;
+  di_args.push(domain.c_str());
+  di_args.push(user.c_str());
+    
+  MessageStorage->invoke("userdir_open",di_args,ret);
+    
+  if (!ret.size() || !isArgInt(ret.get(0))) {
+    ERROR("userdir_open for user '%s' domain '%s' returned no (valid) 
result.\n", user.c_str(), domain.c_str());
+    return;
+  };
+    
+  all_msgs = ret.get(1).size();
+  for (size_t i = 0; i < ret.get(1).size(); i++) {
+    AmArg& elem = ret.get(1).get(i);
+    
+    if (elem.get(2).asInt()) // skip empty messages
+      new_msgs += elem.get(1).asInt();
+    else
+      all_msgs--;
+  };
+                                                  
+  DBG("Found %d new and %d old messages\n", new_msgs, all_msgs - new_msgs);
+  string vm_buf = int2str(new_msgs) + "/" + int2str(all_msgs - new_msgs);
+
+  headers = "Event: message-summary\r\n";
+  headers += "Subscription-State: active\r\n";
+    
+  if (new_msgs > 0)
+    body = "Messages-Waiting: yes\r\n";
+  else
+    body = "Messages-Waiting: no\r\n";
+
+  body += "Message-Account: sip:" + user + "@" + domain + "\r\n";
+  body += "Voice-Message: " + vm_buf + " (" + vm_buf + ")\r\n";
+    
+  AmSipDialog tmp_d(NULL);
+  tmp_d.local_party = string("<sip:mwi-publisher@") + presence_server + ">";
+  tmp_d.remote_party = domain.c_str();
+  tmp_d.route = "sip:" + presence_server;
+  tmp_d.remote_uri = "sip:" + user + "@" + domain;
+  tmp_d.callid = AmSession::getNewId() + "@" + presence_server;
+  tmp_d.local_tag = AmSession::getNewId();
+  tmp_d.sendRequest("PUBLISH", "application/simple-message-summary", body, 
headers);              
+};
+
+void MWI::invoke(const string& method, const AmArg& args, AmArg& ret)
+{
+  if (method == "publish") {
+    string user, domain;
+    user = args.get(1).asCStr();
+    domain = args.get(0).asCStr();
+    publish(user, domain);
+    ret.push(0);
+  }
+  else
+    throw AmDynInvoke::NotImplemented(method); 
+};
diff --git a/apps/mwi/mwi.h b/apps/mwi/mwi.h
new file mode 100644
index 0000000..c1d7f1d
--- /dev/null
+++ b/apps/mwi/mwi.h
@@ -0,0 +1,41 @@
+/*
+    Copyright (C) Anton Zagorskiy [email protected]
+    Oyster-Telecom Laboratory
+    
+    Published under BSD License
+*/
+
+#ifndef _MWI_H
+#define _MWI_H
+
+#include "AmApi.h"
+#include <string>
+
+class MWI : public AmDynInvokeFactory, public AmDynInvoke
+{
+private:
+    static MWI* _instance;
+    static AmDynInvoke* MessageStorage;
+    
+    string presence_server;
+    
+    typedef struct
+    {
+       unsigned int new_msgs;
+       unsigned int saved_msgs;
+    } msg_info_struct;
+    
+    void getMsgInfo (const string& name, const string& domain, 
msg_info_struct& msg_info);
+    void publish (const string& name, const string& domain);
+
+public:
+    MWI(const string& name);
+    ~MWI();
+
+    AmDynInvoke* getInstance(){ return _instance; }
+
+    int onLoad();
+    void invoke(const string& method, const AmArg& args, AmArg& ret);
+};
+
+#endif

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to