Browse code

mobile-push: b/f: reply 487 to INVITE on CANCEL

Stefan Sayer authored on 19/04/2012 10:11:33
Showing 1 changed files
... ...
@@ -196,6 +196,7 @@ transition "timer hit" WAITING - timer(#id==1) / {
196 196
 
197 197
 transition "CANCEL received" WAITING - hangup / {
198 198
   subscription.remove($r.handle);
199
+  dlg.reply(487, "Request Terminated");
199 200
   stop(false);
200 201
 } -> END;
201 202
 
Browse code

mobile_push: set a curl http timeout (15s)

this will also set CURLOPT_NOSIGNAL, which may prevent weird and rare
libcurl related crashes ("longjmp causes uninitialized stack frame")

Stefan Sayer authored on 18/04/2012 13:49:05
Showing 1 changed files
... ...
@@ -101,6 +101,7 @@ transition "invite" START - invite / {
101 101
   }
102 102
 
103 103
   -- send HTTP request
104
+  set($curl.timeout=15);
104 105
   if test($config.use_post=="yes") {
105 106
     curl.postDiscardResult($config.push_server_url, $caller;$callee;$domain)
106 107
   } else {
Browse code

mobile-push: b/f: reply only once with FR to INVITE

Stefan Sayer authored on 18/04/2012 11:25:49
Showing 1 changed files
... ...
@@ -139,10 +139,21 @@ function releaseRegEvalObjects() {
139 139
 };
140 140
 
141 141
 function replyWith300() {
142
-  set($dlg.reply.hdrs="Contact: ");
143
-  append($dlg.reply.hdrs, @local_uri);
144
-  append($dlg.reply.hdrs, $config.extra_3xx_uri_append);
145
-  dlg.reply(300, "Multiple Choices");
142
+  if test($has_replied!="yes") {
143
+    set($dlg.reply.hdrs="Contact: ");
144
+    append($dlg.reply.hdrs, @local_uri);
145
+    append($dlg.reply.hdrs, $config.extra_3xx_uri_append);
146
+    dlg.reply(300, "Multiple Choices");
147
+    set($has_replied="yes");
148
+  }
149
+  stop(false);
150
+};
151
+
152
+function replyWith480() {
153
+  if test($has_replied!="yes") {
154
+    dlg.reply(480, "Not found");
155
+    set($has_replied="yes");
156
+  }
146 157
   stop(false);
147 158
 };
148 159
 
... ...
@@ -152,7 +163,6 @@ transition "NOTIFY received, with body" WAITING - subscription(#status!="termina
152 163
   if test($active_contacts != 0) {
153 164
     replyWith300();
154 165
     subscription.remove($r.handle);
155
-    stop(false);
156 166
   }
157 167
 
158 168
   releaseRegEvalObjects();
... ...
@@ -169,21 +179,18 @@ transition "NOTIFY received, terminated (but with body)" WAITING - subscription(
169 179
   if test($active_contacts != 0) {
170 180
     replyWith300();
171 181
   } else {
172
-    dlg.reply(480, "Not found");
182
+    replyWith480();
173 183
   }
174 184
   releaseRegEvalObjects();
175
-  stop(false);
176 185
 } -> END;
177 186
 
178 187
 transition "NOTIFY received, subscription terminated" WAITING - subscription(#status=="terminated") / {
179
-  dlg.reply(480, "Not found");
180
-  stop(false);
188
+  replyWith480();
181 189
 } -> END;
182 190
 
183 191
 transition "timer hit" WAITING - timer(#id==1) / {
184 192
   subscription.remove($r.handle);
185
-  dlg.reply(480, "Not found");
186
-  stop(false);
193
+  replyWith480();
187 194
 } -> END;
188 195
 
189 196
 transition "CANCEL received" WAITING - hangup / {
Browse code

mobile_push: updated to enableReceiving method (in-line with master)

Stefan Sayer authored on 18/04/2012 09:11:53
Showing 1 changed files
... ...
@@ -70,7 +70,7 @@ transition "invite" START - invite / {
70 70
   connectMedia();
71 71
 
72 72
   -- no need to process incoming RTP (also no RTP timeout needed)
73
-  pauseReceiving();
73
+  disableReceiving();
74 74
 
75 75
   -- create subscription to reg event
76 76
   set($r.domain=@domain);
Browse code

mobile_push: b/f: stopping DSM already when registration there

(no need to wait until subscription is terminated, subscription handling is in core anyway)

Stefan Sayer authored on 17/04/2012 17:35:23
Showing 1 changed files
... ...
@@ -152,6 +152,7 @@ transition "NOTIFY received, with body" WAITING - subscription(#status!="termina
152 152
   if test($active_contacts != 0) {
153 153
     replyWith300();
154 154
     subscription.remove($r.handle);
155
+    stop(false);
155 156
   }
156 157
 
157 158
   releaseRegEvalObjects();
... ...
@@ -169,9 +170,9 @@ transition "NOTIFY received, terminated (but with body)" WAITING - subscription(
169 170
     replyWith300();
170 171
   } else {
171 172
     dlg.reply(480, "Not found");
172
-    stop(false);
173 173
   }
174 174
   releaseRegEvalObjects();
175
+  stop(false);
175 176
 } -> END;
176 177
 
177 178
 transition "NOTIFY received, subscription terminated" WAITING - subscription(#status=="terminated") / {
Browse code

mobile_push: handle CANCEL properly

Stefan Sayer authored on 17/04/2012 17:22:06
Showing 1 changed files
... ...
@@ -185,4 +185,9 @@ transition "timer hit" WAITING - timer(#id==1) / {
185 185
   stop(false);
186 186
 } -> END;
187 187
 
188
+transition "CANCEL received" WAITING - hangup / {
189
+  subscription.remove($r.handle);
190
+  stop(false);
191
+} -> END;
192
+
188 193
 state END;
189 194
\ No newline at end of file
Browse code

mobile_push: ignore incoming RTP

Stefan Sayer authored on 17/04/2012 14:43:52
Showing 1 changed files
... ...
@@ -69,6 +69,9 @@ transition "invite" START - invite / {
69 69
   -- start RTP processing 
70 70
   connectMedia();
71 71
 
72
+  -- no need to process incoming RTP (also no RTP timeout needed)
73
+  pauseReceiving();
74
+
72 75
   -- create subscription to reg event
73 76
   set($r.domain=@domain);
74 77
   set($r.user=@user);
... ...
@@ -111,6 +114,8 @@ transition "invite" START - invite / {
111 114
 
112 115
 state WAITING;
113 116
 
117
+transition "RTP timeout - ignore" WAITING - rtpTimeout / set(#processed=true) -> WAITING;
118
+
114 119
 transition "subscription failed" WAITING - subscription(#status=="failed") / {
115 120
   log(1, "Subscription failed:");
116 121
   logParams(1);
Browse code

mobile_push: handle dlg errors gracefully

Stefan Sayer authored on 17/04/2012 14:21:36
Showing 1 changed files
... ...
@@ -30,6 +30,13 @@ import(mod_curl);
30 30
 
31 31
 initial state START;
32 32
 
33
+transition "SIP dialog error" START - exception; test(#type=="dlg") / {
34
+  log(1, "Error in accepting call:");
35
+  logParams(1);
36
+  set($connect_session=0);
37
+  stop(false);
38
+} -> END;
39
+
33 40
 transition "DB exception" START - exception / {
34 41
   log(1, "Error in initializing mobile push:");
35 42
   logAll(1);
... ...
@@ -55,6 +62,7 @@ transition "invite" START - invite / {
55 62
 
56 63
   -- send 183 with early media
57 64
   dlg.acceptInvite(183, "Progress");
65
+  throwOnError();
58 66
   -- no default 200 OK
59 67
   set($connect_session=0);
60 68
 
Browse code

mobile-push DSM app

--
-- 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;

Stefan Sayer authored on 16/04/2012 13:48:12
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,175 @@
1
+--
2
+-- This DSM app 
3
+--   o plays early media from a file in the DB
4
+--   o sends a HTTP request to a web server
5
+--   o SUBSCRIBEs to registration state 
6
+--   o if registration becomes active (at least one active contact), it sends back "300 Multiple Choices"
7
+--   o otherwise (timeout) it sends back "480 Not found"
8
+
9
+-- Parameters (P-App-Param):
10
+--    audio_id   - indicating audio file in DB
11
+--    expiration - subscription expiration/waiting time (default: 60)
12
+--    caller     - caller passed to notification web app
13
+--    callee     - callee passed to notification web app
14
+--    domain     - domain passed to notification web app
15
+--
16
+--  Example: P-App-Param: audio_id=rbt;expiration=30;caller=+43111111111;callee=+432222222222;domain=sip.sipwise.com
17
+-- 
18
+-- Example DB: 
19
+--  CREATE TABLE `audio_files` (
20
+--    `id` varchar(20) DEFAULT NULL,
21
+--    `data` mediumblob
22
+--  ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
23
+
24
+import(mod_utils);
25
+import(mod_dlg);
26
+import(mod_subscription);
27
+import(mod_xml);
28
+import(mod_mysql);
29
+import(mod_curl);
30
+
31
+initial state START;
32
+
33
+transition "DB exception" START - exception / {
34
+  log(1, "Error in initializing mobile push:");
35
+  logAll(1);
36
+  dlg.reply(500, "Server Internal Error");
37
+  stop(false);
38
+} -> END;
39
+
40
+transition "invite" START - invite / {
41
+  if test($config.enable_rbt=="yes") {
42
+    if test($audio_id != "") {
43
+      mysql.connect();
44
+      throwOnError();
45
+      -- play waiting file from DB
46
+      if test($config.play_looped=="yes") {
47
+        mysql.playDBAudioLooped(SELECT data FROM provisioning.audio_files WHERE id="$audio_id", rbt.wav);
48
+      } else {
49
+        mysql.playDBAudio(SELECT data FROM provisioning.audio_files WHERE id="$audio_id", rbt.wav);
50
+      }
51
+      throwOnError();
52
+      mysql.disconnect();
53
+    }
54
+  }
55
+
56
+  -- send 183 with early media
57
+  dlg.acceptInvite(183, "Progress");
58
+  -- no default 200 OK
59
+  set($connect_session=0);
60
+
61
+  -- start RTP processing 
62
+  connectMedia();
63
+
64
+  -- create subscription to reg event
65
+  set($r.domain=@domain);
66
+  set($r.user=@user);
67
+  set($r.from_user=$config.subscription_user);
68
+  set($r.pwd=$config.subscription_pwd);
69
+  set($r.event="reg");
70
+  if test($config.proxy != "") {
71
+    set($r.proxy=$config.proxy);
72
+  }
73
+  if test($config.use_subscription_id == "yes") {
74
+    utils.getNewId(r.id);
75
+  }
76
+  if test($expiration != "") {
77
+    set($r.expires=$expiration);
78
+  } else {
79
+    set($r.expires=60);
80
+  }
81
+
82
+  subscription.create(r);
83
+
84
+  if test($r.handle == "") {
85
+    log(1, "Subscription creation failed!");
86
+    logVars(1);
87
+    dlg.reply(500, "Server Internal Error");
88
+    stop(false);
89
+    throw(subscription);
90
+  }
91
+
92
+  -- send HTTP request
93
+  if test($config.use_post=="yes") {
94
+    curl.postDiscardResult($config.push_server_url, $caller;$callee;$domain)
95
+  } else {
96
+    curl.getForm($config.push_server_url, $caller;$callee;$domain)
97
+  }
98
+
99
+  -- set Timer on our side, too (server subscription timing could be broken...)
100
+  setTimer(1, $r.expires);
101
+
102
+} -> WAITING;
103
+
104
+state WAITING;
105
+
106
+transition "subscription failed" WAITING - subscription(#status=="failed") / {
107
+  log(1, "Subscription failed:");
108
+  logParams(1);
109
+  logVars(1); 
110
+  dlg.reply(500, "Server Internal Error");
111
+  stop(false);
112
+} -> END;
113
+
114
+function evaluateRegNotifyBody() {
115
+  xml.parseSIPMsgBody("SipSubscriptionBody", "substatus");
116
+  -- namespaces to be used:
117
+  set($substatus.ns="a=urn:ietf:params:xml:ns:reginfo")
118
+  -- look for an active contact
119
+  xml.evalXPath("/a:reginfo/a:registration/a:contact[@state='active']", "substatus");
120
+  xml.XPathResultCount($active_contacts="substatus.xpath");
121
+};
122
+
123
+function releaseRegEvalObjects() {
124
+  freeObject("substatus");
125
+  freeObject("substatus.xpath");
126
+};
127
+
128
+function replyWith300() {
129
+  set($dlg.reply.hdrs="Contact: ");
130
+  append($dlg.reply.hdrs, @local_uri);
131
+  append($dlg.reply.hdrs, $config.extra_3xx_uri_append);
132
+  dlg.reply(300, "Multiple Choices");
133
+  stop(false);
134
+};
135
+
136
+transition "NOTIFY received, with body" WAITING - subscription(#status!="terminated"); test(#has_body=="true") / {
137
+  evaluateRegNotifyBody();
138
+
139
+  if test($active_contacts != 0) {
140
+    replyWith300();
141
+    subscription.remove($r.handle);
142
+  }
143
+
144
+  releaseRegEvalObjects();
145
+} -> WAITING;
146
+
147
+transition "NOTIFY received, no body" WAITING - subscription(#status!="terminated")  / {
148
+  log(3, "subscription active");
149
+  logParams(3);
150
+} -> WAITING;
151
+
152
+transition "NOTIFY received, terminated (but with body)" WAITING - subscription(#status=="terminated"); test(#has_body=="true") / {
153
+  evaluateRegNotifyBody();
154
+
155
+  if test($active_contacts != 0) {
156
+    replyWith300();
157
+  } else {
158
+    dlg.reply(480, "Not found");
159
+    stop(false);
160
+  }
161
+  releaseRegEvalObjects();
162
+} -> END;
163
+
164
+transition "NOTIFY received, subscription terminated" WAITING - subscription(#status=="terminated") / {
165
+  dlg.reply(480, "Not found");
166
+  stop(false);
167
+} -> END;
168
+
169
+transition "timer hit" WAITING - timer(#id==1) / {
170
+  subscription.remove($r.handle);
171
+  dlg.reply(480, "Not found");
172
+  stop(false);
173
+} -> END;
174
+
175
+state END;
0 176
\ No newline at end of file