You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sems/apps/mwi/mwi.cpp

131 lines
3.5 KiB

/*
Copyright (C) Anton Zagorskiy amberovsky@gmail.com
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";
AmMimeBody sms_body;
sms_body.addPart("application/simple-message-summary");
sms_body.setPayload(body.c_str(),body.length());
AmSipDialog tmp_d(NULL);
tmp_d.setLocalParty(string("<sip:mwi-publisher@") + presence_server + ">");
tmp_d.setRemoteParty("sip:" + user + "@" + domain);
tmp_d.setRouteSet("sip:" + presence_server);
tmp_d.setRemoteUri("sip:" + user + "@" + domain);
tmp_d.setCallid(AmSession::getNewId() + "@" + presence_server);
tmp_d.setLocalTag(AmSession::getNewId());
tmp_d.sendRequest(SIP_METH_NOTIFY, &sms_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);
};