7d695472 |
--
-- This DSM app
-- o plays early media from a file in the DB
-- o sends a HTTP request to a web server
-- o SUBSCRIBEs to registration state
-- o if registration becomes active (at least one active contact), it sends back "300 Multiple Choices"
-- o otherwise (timeout) it sends back "480 Not found"
-- Parameters (P-App-Param):
-- audio_id - indicating audio file in DB
-- expiration - subscription expiration/waiting time (default: 60)
-- caller - caller passed to notification web app
-- callee - callee passed to notification web app
-- domain - domain passed to notification web app
--
-- Example: P-App-Param: audio_id=rbt;expiration=30;caller=+43111111111;callee=+432222222222;domain=sip.sipwise.com
--
-- Example DB:
-- CREATE TABLE `audio_files` (
-- `id` varchar(20) DEFAULT NULL,
-- `data` mediumblob
-- ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
import(mod_utils);
import(mod_dlg);
import(mod_subscription);
import(mod_xml);
import(mod_mysql);
import(mod_curl);
initial state START;
|
4f11cb95 |
transition "SIP dialog error" START - exception; test(#type=="dlg") / {
log(1, "Error in accepting call:");
logParams(1);
set($connect_session=0);
stop(false);
} -> END;
|
7d695472 |
transition "DB exception" START - exception / {
log(1, "Error in initializing mobile push:");
logAll(1);
dlg.reply(500, "Server Internal Error");
stop(false);
} -> END;
transition "invite" START - invite / {
if test($config.enable_rbt=="yes") {
if test($audio_id != "") {
mysql.connect();
throwOnError();
-- play waiting file from DB
if test($config.play_looped=="yes") {
mysql.playDBAudioLooped(SELECT data FROM provisioning.audio_files WHERE id="$audio_id", rbt.wav);
} else {
mysql.playDBAudio(SELECT data FROM provisioning.audio_files WHERE id="$audio_id", rbt.wav);
}
throwOnError();
mysql.disconnect();
}
}
-- send 183 with early media
dlg.acceptInvite(183, "Progress");
|
4f11cb95 |
throwOnError();
|
7d695472 |
-- no default 200 OK
set($connect_session=0);
-- start RTP processing
connectMedia();
|
07c7f0a4 |
-- no need to process incoming RTP (also no RTP timeout needed)
|
4f362b3c |
disableReceiving();
|
07c7f0a4 |
|
7d695472 |
-- create subscription to reg event
set($r.domain=@domain);
set($r.user=@user);
set($r.from_user=$config.subscription_user);
set($r.pwd=$config.subscription_pwd);
set($r.event="reg");
if test($config.proxy != "") {
set($r.proxy=$config.proxy);
}
if test($config.use_subscription_id == "yes") {
utils.getNewId(r.id);
}
if test($expiration != "") {
set($r.expires=$expiration);
} else {
set($r.expires=60);
}
subscription.create(r);
if test($r.handle == "") {
log(1, "Subscription creation failed!");
logVars(1);
dlg.reply(500, "Server Internal Error");
stop(false);
throw(subscription);
}
-- send HTTP request
|
a15b0bf2 |
set($curl.timeout=15);
|
7d695472 |
if test($config.use_post=="yes") {
curl.postDiscardResult($config.push_server_url, $caller;$callee;$domain)
} else {
curl.getForm($config.push_server_url, $caller;$callee;$domain)
}
-- set Timer on our side, too (server subscription timing could be broken...)
setTimer(1, $r.expires);
} -> WAITING;
state WAITING;
|
07c7f0a4 |
transition "RTP timeout - ignore" WAITING - rtpTimeout / set(#processed=true) -> WAITING;
|
7d695472 |
transition "subscription failed" WAITING - subscription(#status=="failed") / {
log(1, "Subscription failed:");
logParams(1);
logVars(1);
dlg.reply(500, "Server Internal Error");
stop(false);
} -> END;
function evaluateRegNotifyBody() {
xml.parseSIPMsgBody("SipSubscriptionBody", "substatus");
-- namespaces to be used:
set($substatus.ns="a=urn:ietf:params:xml:ns:reginfo")
-- look for an active contact
xml.evalXPath("/a:reginfo/a:registration/a:contact[@state='active']", "substatus");
xml.XPathResultCount($active_contacts="substatus.xpath");
};
function releaseRegEvalObjects() {
freeObject("substatus");
freeObject("substatus.xpath");
};
function replyWith300() {
|
dc9c524b |
if test($has_replied!="yes") {
set($dlg.reply.hdrs="Contact: ");
append($dlg.reply.hdrs, @local_uri);
append($dlg.reply.hdrs, $config.extra_3xx_uri_append);
dlg.reply(300, "Multiple Choices");
set($has_replied="yes");
}
stop(false);
};
function replyWith480() {
if test($has_replied!="yes") {
dlg.reply(480, "Not found");
set($has_replied="yes");
}
|
7d695472 |
stop(false);
};
transition "NOTIFY received, with body" WAITING - subscription(#status!="terminated"); test(#has_body=="true") / {
evaluateRegNotifyBody();
if test($active_contacts != 0) {
replyWith300();
subscription.remove($r.handle);
}
releaseRegEvalObjects();
} -> WAITING;
transition "NOTIFY received, no body" WAITING - subscription(#status!="terminated") / {
log(3, "subscription active");
logParams(3);
} -> WAITING;
transition "NOTIFY received, terminated (but with body)" WAITING - subscription(#status=="terminated"); test(#has_body=="true") / {
evaluateRegNotifyBody();
if test($active_contacts != 0) {
replyWith300();
} else {
|
dc9c524b |
replyWith480();
|
7d695472 |
}
releaseRegEvalObjects();
} -> END;
transition "NOTIFY received, subscription terminated" WAITING - subscription(#status=="terminated") / {
|
dc9c524b |
replyWith480();
|
7d695472 |
} -> END;
transition "timer hit" WAITING - timer(#id==1) / {
subscription.remove($r.handle);
|
dc9c524b |
replyWith480();
|
7d695472 |
} -> END;
|
50ad6bba |
transition "CANCEL received" WAITING - hangup / {
subscription.remove($r.handle);
|
102dad80 |
dlg.reply(487, "Request Terminated");
|
50ad6bba |
stop(false);
} -> END;
|
7d695472 |
state END;
|