Browse code

rtp_media_server: configurable event routes

for all action commands and corrected docs

Julien Chavanton authored on 25/02/2019 04:13:20
Showing 3 changed files
... ...
@@ -36,6 +36,10 @@ event_route[rms:bridged] {
36 36
 	xnotice("[rms:bridged] ...\n");
37 37
 }
38 38
 
39
+event_route[rms:answered] {
40
+	xnotice("[rms:answered] ...\n");
41
+}
42
+
39 43
 route {
40 44
 	if (t_precheck_trans()) {
41 45
 		t_check_trans();
... ...
@@ -54,7 +58,7 @@ route {
54 58
 			}
55 59
 			exit;
56 60
 		}
57
-		if (!rms_answer()) {
61
+		if (!rms_answer("rms:answered") {
58 62
 			t_reply("503", "server error");
59 63
 			xerr("rtp_media_server error!\n");
60 64
 			exit;
... ...
@@ -107,15 +107,15 @@ modparam("rtp_media_server", "log_file_name", "/var/log/rms/rms_ortp.log")
107 107
 	<title>Functions</title>
108 108
 
109 109
 	<section id="rtp_media_server.f.rms_answer">
110
-		<title><varname>rms_answer</varname> ()</title>
110
+		<title><varname>rms_answer</varname> (event_route)</title>
111 111
 		<para>
112
-		Create a session and a call leg and call the event_route[rms:start]
112
+		Create a session and a call leg and call the event_route
113 113
 		</para>
114 114
 		<para>
115 115
 		This function can be used from REQUEST_ROUTE, REPLY_ROUTE and FAILURE_ROUTE.
116 116
 		</para>
117 117
 		<example>
118
-		<title>usage example</title>
118
+		<title>rms_answer usage example</title>
119 119
 		<programlisting format="linespecific">
120 120
 ...
121 121
 event_route[rms:start] {
... ...
@@ -135,7 +135,7 @@ route {
135 135
 	}
136 136
 	t_check_trans();
137 137
 	if (is_method("INVITE") &amp;&amp; !has_totag()) {
138
-		if (!rms_answer()) {
138
+		if (!rms_answer("rms:start")) {
139 139
 			t_reply("503", "server error");
140 140
 		}
141 141
 	}
... ...
@@ -153,7 +153,7 @@ route {
153 153
 		This function can be used from EVENT_ROUTE.
154 154
 		</para>
155 155
 		<example>
156
-		<title>usage example</title>
156
+		<title>rms_hangup usage example</title>
157 157
 		<programlisting format="linespecific">
158 158
 ...
159 159
 	rms_hangup();
... ...
@@ -162,7 +162,7 @@ route {
162 162
 	</section>
163 163
 
164 164
 	<section id="rtp_media_server.f.rms_bridge">
165
-		<title><varname>rms_bridge</varname> ()</title>
165
+		<title><varname>rms_bridge</varname> (target URI, event_route)</title>
166 166
 		<para>
167 167
 		Bridge the incoming call, create a second call leg using a UAC
168 168
 		in a B2BUA manner, this is needed in case we want to un-bridge later, a feature not currently implemented
... ...
@@ -172,7 +172,7 @@ route {
172 172
 		This function can be used from REQUEST_ROUTE.
173 173
 		</para>
174 174
 		<example>
175
-		<title>usage example</title>
175
+		<title>rms_bridge usage example</title>
176 176
 		<programlisting format="linespecific">
177 177
 ...
178 178
 event_route[rms:bridged] {
... ...
@@ -209,7 +209,7 @@ route {
209 209
 		This function can be used from REQUEST_ROUTE, REPLY_ROUTE and FAILURE_ROUTE.
210 210
 		</para>
211 211
 		<example>
212
-		<title>usage example</title>
212
+		<title>rms_session_check usage example</title>
213 213
 		<programlisting format="linespecific">
214 214
 ...
215 215
 	if (rms_session_check()) {
... ...
@@ -235,7 +235,7 @@ route {
235 235
 		This function can be used from REQUEST_ROUTE, REPLY_ROUTE and FAILURE_ROUTE.
236 236
 		</para>
237 237
 		<example>
238
-		<title>usage example</title>
238
+		<title>rms_sip_request usage example</title>
239 239
 		<programlisting format="linespecific">
240 240
 ...
241 241
 	if (rms_session_check()) {
... ...
@@ -246,7 +246,7 @@ route {
246 246
 	</section>
247 247
 
248 248
 	<section id="rtp_media_server.f.rms_play">
249
-		<title><varname>rms_play</varname> ()</title>
249
+		<title><varname>rms_play</varname> (file, event_route)</title>
250 250
 		<para>
251 251
 		Play a wav file, a resampler is automaticaly configured to resample
252 252
 		and convert stereo to mono if needed.
... ...
@@ -257,7 +257,7 @@ route {
257 257
 		This function can be used from EVENT_ROUTE.
258 258
 		</para>
259 259
 		<example>
260
-		<title>usage example</title>
260
+		<title>rms_play usage example</title>
261 261
 		<programlisting format="linespecific">
262 262
 ...
263 263
 	rms_play("file.wav", "event_route_name");
... ...
@@ -30,28 +30,33 @@ static int child_init(int);
30 30
 str playback_fn = {0, 0};
31 31
 str log_fn = {0, 0};
32 32
 
33
+static char *rms_bridge_default_route = "rms:bridged";
34
+static char *rms_answer_default_route = "rms:start";
35
+
36
+
33 37
 static rms_t rms;
34 38
 
35 39
 static rms_session_info_t *rms_session_create_leg(rms_session_info_t *si);
36 40
 static int fixup_rms_action_play(void **param, int param_no);
37 41
 static int fixup_rms_bridge(void **param, int param_no);
42
+static int fixup_rms_answer(void **param, int param_no);
38 43
 static int rms_hangup_call(rms_session_info_t *si);
39 44
 static int rms_bridging_call(rms_session_info_t *si, rms_action_t *a);
40 45
 static int rms_bridged_call(rms_session_info_t *si, rms_action_t *a);
41 46
 
42
-static int rms_answer_f(struct sip_msg *);
47
+static int rms_answer_f(struct sip_msg *, char *);
43 48
 static int rms_sip_request_f(struct sip_msg *);
44 49
 static int rms_action_play_f(struct sip_msg *, str *, str *);
45 50
 static int rms_session_check_f(struct sip_msg *);
46 51
 static int rms_hangup_f(struct sip_msg *);
47
-static int rms_bridge_f(struct sip_msg *, char *, str *);
52
+static int rms_bridge_f(struct sip_msg *, char *, char *);
48 53
 
49 54
 static int rms_update_call_sdp(struct sip_msg *msg,
50 55
 		const rms_session_info_t *si, call_leg_media_t *m,
51 56
 		rms_sdp_info_t *sdp_info);
52 57
 
53 58
 static cmd_export_t cmds[] = {
54
-		{"rms_answer", (cmd_function)rms_answer_f, 0, 0, 0, EVENT_ROUTE},
59
+		{"rms_answer", (cmd_function)rms_answer_f, 1, fixup_rms_answer, 0, EVENT_ROUTE},
55 60
 		{"rms_sip_request", (cmd_function)rms_sip_request_f, 0, 0, 0,
56 61
 				EVENT_ROUTE},
57 62
 		{"rms_play", (cmd_function)rms_action_play_f, 2, fixup_rms_action_play,
... ...
@@ -132,9 +137,15 @@ static void run_action_route(rms_session_info_t *si, char *route)
132 137
 
133 138
 static int fixup_rms_bridge(void **param, int param_no)
134 139
 {
135
-	if(param_no == 1)
140
+	if(param_no == 1 || param_no == 2)
136 141
 		return fixup_spve_null(param, 1);
137
-	if(param_no == 2)
142
+	LM_ERR("invalid parameter count [%d]\n", param_no);
143
+	return -1;
144
+}
145
+
146
+static int fixup_rms_answer(void **param, int param_no)
147
+{
148
+	if(param_no == 1 || param_no == 2)
138 149
 		return fixup_spve_null(param, 1);
139 150
 	LM_ERR("invalid parameter count [%d]\n", param_no);
140 151
 	return -1;
... ...
@@ -142,9 +153,7 @@ static int fixup_rms_bridge(void **param, int param_no)
142 153
 
143 154
 static int fixup_rms_action_play(void **param, int param_no)
144 155
 {
145
-	if(param_no == 1)
146
-		return fixup_spve_null(param, 1);
147
-	if(param_no == 2)
156
+	if(param_no == 1 || param_no == 2 || param_no ==3)
148 157
 		return fixup_spve_null(param, 1);
149 158
 	LM_ERR("invalid parameter count [%d]\n", param_no);
150 159
 	return -1;
... ...
@@ -276,7 +285,7 @@ static rms_session_info_t *rms_session_action_check(rms_session_info_t *si)
276 285
 			create_call_leg_media(&si->media);
277 286
 			LM_INFO("session action RMS_START [%s]\n", si->callid.s);
278 287
 			rms_start_media(&si->media, a->param.s);
279
-			run_action_route(si, "rms:start");
288
+			run_action_route(si, a->route.s);
280 289
 			a->type = RMS_NONE;
281 290
 			return si;
282 291
 		}
... ...
@@ -399,6 +408,7 @@ static int rms_answer_call(
399 408
 			return 0;
400 409
 		}
401 410
 		LM_INFO("answered\n");
411
+		si->state = RMS_ST_CONNECTED;
402 412
 	} else {
403 413
 		LM_INFO("no request found\n");
404 414
 	}
... ...
@@ -786,32 +796,49 @@ static int rms_action_play_f(struct sip_msg *msg, str *playback_fn, str *route)
786 796
 	return 0;
787 797
 }
788 798
 
789
-static int rms_bridge_f(struct sip_msg *msg, char *_target, str *route)
799
+static int rms_bridge_f(struct sip_msg *msg, char *_target, char *_route)
790 800
 {
791 801
 	str target = {NULL, 0};
792
-	int status = rms_create_trans(msg);
793
-
794
-	if(get_str_fparam(&target, msg, (gparam_p)_target) != 0) {
795
-		LM_ERR("rms_bridge: missing target\n");
796
-		tmb.t_reply(msg, 404, "Not found");
797
-		return -1;
798
-	}
802
+	str route = {NULL, 0};
803
+	rms_session_info_t *si = rms_session_search(msg);
804
+	int status = 1;
799 805
 
800
-	LM_NOTICE("rms_bridge[%s][%d]\n", target.s, target.len);
801
-	if(status < 1)
802
-		return status;
803 806
 	if(!rms_check_msg(msg))
804 807
 		return -1;
805
-	rms_session_info_t *si = rms_session_search(msg);
806
-	if(si) { // bridge an existing session, another command/context ??
807
-		return 1;
808
+
809
+	if (si) {
810
+		if (si->state == RMS_ST_CONNECTED) {
811
+			LM_INFO("already connected, bridging\n");
812
+		} else {
813
+			LM_ERR("bridging an existing session that is not connected.\n");
814
+			return -1;
815
+		}
808 816
 	} else {
809
-		str to_tag;
817
+		status = rms_create_trans(msg);
818
+		if(status < 1)
819
+			return status;
810 820
 		// create a_leg session
811 821
 		si = rms_session_new(msg);
812 822
 		if(!si)
813 823
 			return -1;
824
+	}
814 825
 
826
+	if(get_str_fparam(&target, msg, (gparam_p)_target) != 0) {
827
+		if (si->state != RMS_ST_CONNECTED) {
828
+			LM_ERR("rms_bridge: missing target\n");
829
+			tmb.t_reply(msg, 404, "Not found");
830
+		}
831
+		return -1;
832
+	}
833
+	if(get_str_fparam(&route, msg, (gparam_p)_route) != 0) {
834
+		route.len = strlen(rms_bridge_default_route);
835
+		route.s = rms_bridge_default_route;
836
+	}
837
+
838
+	LM_NOTICE("rms_bridge[%s][%d]\n", target.s, target.len);
839
+
840
+	str to_tag;
841
+	{
815 842
 		parse_from(msg, si);
816 843
 		tmb.t_get_reply_totag(msg, &to_tag);
817 844
 		rms_str_dup(&si->local_tag, &to_tag, 1);
... ...
@@ -831,23 +858,29 @@ static int rms_bridge_f(struct sip_msg *msg, char *_target, str *route)
831 858
 		rms_sdp_prepare_new_body(sdp_info, si->media.pt->type);
832 859
 		LM_NOTICE("payload[%d]\n", si->media.pt->type);
833 860
 	}
834
-	tmb.t_reply(msg, 100, "Trying");
861
+
862
+
863
+
835 864
 	si->local_port = msg->rcv.dst_port;
836 865
 	rms_action_t *a = rms_action_new(RMS_BRIDGING);
837 866
 	if(!a)
838 867
 		return -1;
839 868
 	LM_NOTICE("remote target[%.*s]\n", target.len, target.s);
840
-	LM_NOTICE("remote route[%.*s]\n", route->len, route->s);
869
+	LM_NOTICE("remote route[%.*s]\n", route.len, route.s);
841 870
 	if(!rms_str_dup(&a->param, &target, 1)) {
842 871
 		goto error;
843 872
 	}
844 873
 
845
-	a->route.len = route->len;
846
-	a->route.s = route->s;
847
-	a->cell = tmb.t_gett();
848
-	if(tmb.t_suspend(msg, &a->tm_info.hash_index, &a->tm_info.label) < 0) {
849
-		LM_ERR("t_suspend() failed\n");
850
-		goto error;
874
+	a->route.len = route.len;
875
+	a->route.s = route.s;
876
+
877
+	if (si->state != RMS_ST_CONNECTED) { // a_leg: suspend transaction
878
+		a->cell = tmb.t_gett();
879
+		tmb.t_reply(msg, 100, "Trying");
880
+		if(tmb.t_suspend(msg, &a->tm_info.hash_index, &a->tm_info.label) < 0) {
881
+			LM_ERR("t_suspend() failed\n");
882
+			goto error;
883
+		}
851 884
 	}
852 885
 
853 886
 	LM_INFO("transaction request[%p]\n", a->cell->uas.request);
... ...
@@ -1028,13 +1061,20 @@ static int rms_sip_request_f(struct sip_msg *msg)
1028 1061
 	return 1;
1029 1062
 }
1030 1063
 
1031
-static int rms_answer_f(struct sip_msg *msg)
1064
+static int rms_answer_f(struct sip_msg *msg, char * _route)
1032 1065
 {
1033 1066
 	str to_tag;
1067
+	str route;
1068
+
1034 1069
 	int status = rms_create_trans(msg);
1035 1070
 	if(status < 1)
1036 1071
 		return status;
1037 1072
 
1073
+	if(get_str_fparam(&route, msg, (gparam_p)_route) != 0) {
1074
+		route.len = strlen(rms_answer_default_route);
1075
+		route.s = rms_answer_default_route;
1076
+	}
1077
+
1038 1078
 	if(rms_session_search(msg))
1039 1079
 		return -1;
1040 1080
 	rms_session_info_t *si = rms_session_new(msg);
... ...
@@ -1060,9 +1100,12 @@ static int rms_answer_f(struct sip_msg *msg)
1060 1100
 	}
1061 1101
 	LM_INFO("RTP session [%s:%d]<>[%s:%d]\n", si->media.local_ip.s,
1062 1102
 			si->media.local_port, si->media.remote_ip.s, si->media.remote_port);
1103
+
1063 1104
 	rms_action_t *a = rms_action_new(RMS_START);
1064 1105
 	if(!a)
1065 1106
 		return -1;
1107
+	a->route.len = route.len;
1108
+	a->route.s = route.s;
1066 1109
 	rms_action_add(si, a);
1067 1110
 	return 1;
1068 1111
 error: