فهرست منبع

rtp_media_server: support for multiple actions

Julien Chavanton 6 سال پیش
والد
کامیت
2a76fdd433

+ 1 - 1
src/modules/rtp_media_server/config_example/kamailio.cfg

@@ -24,7 +24,7 @@ listen=udp:147.75.39.121:5090
 
 
 event_route[rms:start] {
 event_route[rms:start] {
 	xnotice("[rms:start] play ...\n");
 	xnotice("[rms:start] play ...\n");
-	rms_play("./voice_file/Bach_10s_8000.wav", "rms:after_play");
+	rms_play("./voice_files/OSR_us_000_0010_8k.wav", "rms:after_play");
 };
 };
 
 
 event_route[rms:after_play] {
 event_route[rms:after_play] {

+ 12 - 0
src/modules/rtp_media_server/doc/rtp_media_server_admin.xml

@@ -103,6 +103,9 @@ modparam("rtp_media_server", "log_file_name", "/var/log/rms/rms_ortp.log")
 		Create a session and a call leg and call the event_route[rms:start]
 		Create a session and a call leg and call the event_route[rms:start]
 		config example
 		config example
 		</para>
 		</para>
+		<para>
+		This function can be used from REQUEST_ROUTE, REPLY_ROUTE and FAILURE_ROUTE.
+		</para>
 		<example>
 		<example>
 		<title>usage example</title>
 		<title>usage example</title>
 		<programlisting format="linespecific">
 		<programlisting format="linespecific">
@@ -142,6 +145,9 @@ route {
 		<para>
 		<para>
 		Send a BYE, delete the RTP session and the media ressources.
 		Send a BYE, delete the RTP session and the media ressources.
 		</para>
 		</para>
+		<para>
+		This function can be used from EVENT_ROUTE.
+		</para>
 		<example>
 		<example>
 		<title>usage example</title>
 		<title>usage example</title>
 		<programlisting format="linespecific">
 		<programlisting format="linespecific">
@@ -162,6 +168,9 @@ route {
 		If the SIP session is not found "481 Call/Transaction Does Not Exist"
 		If the SIP session is not found "481 Call/Transaction Does Not Exist"
 		is returned.
 		is returned.
 		</para>
 		</para>
+		<para>
+		This function can be used from REQUEST_ROUTE, REPLY_ROUTE and FAILURE_ROUTE.
+		</para>
 		<example>
 		<example>
 		<title>usage example</title>
 		<title>usage example</title>
 		<programlisting format="linespecific">
 		<programlisting format="linespecific">
@@ -181,6 +190,9 @@ route {
 		</para><para>
 		</para><para>
 		The second parameter is the event route that will be called when the file was played.
 		The second parameter is the event route that will be called when the file was played.
 		</para>
 		</para>
+		<para>
+		This function can be used from EVENT_ROUTE.
+		</para>
 		<example>
 		<example>
 		<title>usage example</title>
 		<title>usage example</title>
 		<programlisting format="linespecific">
 		<programlisting format="linespecific">

+ 7 - 0
src/modules/rtp_media_server/install_bc.sh

@@ -43,3 +43,10 @@ make install
 cd ..
 cd ..
 
 
 ldconfig
 ldconfig
+
+# download sample voice file
+mkdir -p voice_files
+cd voice_files
+wget http://www.voiptroubleshooter.com/open_speech/american/OSR_us_000_0010_8k.wav
+cd ..
+

+ 14 - 7
src/modules/rtp_media_server/rms_media.c

@@ -41,7 +41,6 @@ typedef struct shared_global_vars
 	gen_lock_t lock;
 	gen_lock_t lock;
 } shared_global_vars_t;
 } shared_global_vars_t;
 
 
-static shared_global_vars_t *vars;
 
 
 MSFilterDesc *rms_ms_filter_descs[] = {&ms_alaw_dec_desc, &ms_alaw_enc_desc,
 MSFilterDesc *rms_ms_filter_descs[] = {&ms_alaw_dec_desc, &ms_alaw_enc_desc,
 		&ms_ulaw_dec_desc, &ms_ulaw_enc_desc, &ms_rtp_send_desc,
 		&ms_ulaw_dec_desc, &ms_ulaw_enc_desc, &ms_rtp_send_desc,
@@ -75,7 +74,6 @@ int rms_media_init()
 	ortp_memory_functions.free_fun = ptr_shm_free;
 	ortp_memory_functions.free_fun = ptr_shm_free;
 	ortp_set_memory_functions(&ortp_memory_functions);
 	ortp_set_memory_functions(&ortp_memory_functions);
 	ortp_init();
 	ortp_init();
-	vars = shm_malloc(sizeof(shared_global_vars_t));
 	return 1;
 	return 1;
 }
 }
 
 
@@ -155,8 +153,8 @@ static void rms_player_eof(
 		void *user_data, MSFilter *f, unsigned int event, void *event_data)
 		void *user_data, MSFilter *f, unsigned int event, void *event_data)
 {
 {
 	if(event == MS_FILE_PLAYER_EOF) {
 	if(event == MS_FILE_PLAYER_EOF) {
-		rms_session_info_t *si = (rms_session_info_t *)user_data;
-		si->action = RMS_DONE;
+		rms_action_t *a = (rms_action_t *)user_data;
+		a->type = RMS_DONE;
 	}
 	}
 	MS_UNUSED(f), MS_UNUSED(event_data);
 	MS_UNUSED(f), MS_UNUSED(event_data);
 }
 }
@@ -203,13 +201,22 @@ int rms_stop_bridge(call_leg_media_t *m1, call_leg_media_t *m2)
 	return 1;
 	return 1;
 }
 }
 
 
-int rms_playfile(call_leg_media_t *m, char *file_name)
+
+int rms_get_dtmf(call_leg_media_t *m, char dtmf) {
+//	static void tone_detected_cb(void *data, MSFilter *f, unsigned int event_id, MSToneDetectorEvent *ev) {
+//			MS_UNUSED(data), MS_UNUSED(f), MS_UNUSED(event_id), MS_UNUSED(ev);
+//				ms_tester_tone_detected = TRUE;
+//	}
+	return 1;
+}
+
+int rms_playfile(call_leg_media_t *m, rms_action_t *a)
 {
 {
 	int file_sample_rate = 8000;
 	int file_sample_rate = 8000;
 	if(!m->ms_player)
 	if(!m->ms_player)
 		return 0;
 		return 0;
-	ms_filter_add_notify_callback(m->ms_player, rms_player_eof, m->si, TRUE);
-	ms_filter_call_method(m->ms_player, MS_FILE_PLAYER_OPEN, (void *)file_name);
+	ms_filter_add_notify_callback(m->ms_player, rms_player_eof, a, TRUE);
+	ms_filter_call_method(m->ms_player, MS_FILE_PLAYER_OPEN, (void *)a->param.s);
 	ms_filter_call_method(m->ms_player, MS_FILE_PLAYER_START, NULL);
 	ms_filter_call_method(m->ms_player, MS_FILE_PLAYER_START, NULL);
 	ms_filter_call_method(m->ms_player, MS_FILTER_GET_SAMPLE_RATE, &file_sample_rate);
 	ms_filter_call_method(m->ms_player, MS_FILTER_GET_SAMPLE_RATE, &file_sample_rate);
 	ms_filter_call_method(m->ms_resampler, MS_FILTER_SET_SAMPLE_RATE, &file_sample_rate);
 	ms_filter_call_method(m->ms_resampler, MS_FILTER_SET_SAMPLE_RATE, &file_sample_rate);

+ 2 - 1
src/modules/rtp_media_server/rms_media.h

@@ -35,6 +35,7 @@
 #include <ortp/port.h>
 #include <ortp/port.h>
 
 
 struct rms_session_info;
 struct rms_session_info;
+typedef struct rms_action rms_action_t;
 
 
 typedef struct call_leg_media
 typedef struct call_leg_media
 {
 {
@@ -68,7 +69,7 @@ void rms_media_destroy();
 MSFactory *rms_get_factory();
 MSFactory *rms_get_factory();
 
 
 int rms_stop_media(call_leg_media_t *m);
 int rms_stop_media(call_leg_media_t *m);
-int rms_playfile(call_leg_media_t *m, char *file_name);
+int rms_playfile(call_leg_media_t *m, rms_action_t *a);
 int rms_start_media(call_leg_media_t *m, char *file_name);
 int rms_start_media(call_leg_media_t *m, char *file_name);
 int rms_bridge(call_leg_media_t *m1, call_leg_media_t *m2);
 int rms_bridge(call_leg_media_t *m1, call_leg_media_t *m2);
 int rms_stop_bridge(call_leg_media_t *m1, call_leg_media_t *m2);
 int rms_stop_bridge(call_leg_media_t *m1, call_leg_media_t *m2);

+ 133 - 61
src/modules/rtp_media_server/rtp_media_server.c

@@ -47,13 +47,15 @@ static int rms_hangup_f(struct sip_msg *);
 static int rms_sessions_dump_f(struct sip_msg *, char *, char *);
 static int rms_sessions_dump_f(struct sip_msg *, char *, char *);
 
 
 static cmd_export_t cmds[] = {
 static cmd_export_t cmds[] = {
-		{"rms_answer", (cmd_function)rms_answer_f, 0, 0, 0, ANY_ROUTE},
+		{"rms_answer", (cmd_function)rms_answer_f, 0, 0, 0, EVENT_ROUTE},
 		{"rms_play", (cmd_function)rms_action_play_f, 2, fixup_rms_action_play, 0,
 		{"rms_play", (cmd_function)rms_action_play_f, 2, fixup_rms_action_play, 0,
 				ANY_ROUTE},
 				ANY_ROUTE},
 		{"rms_sdp_offer", (cmd_function)rms_sdp_offer_f, 0, 0, 0, ANY_ROUTE},
 		{"rms_sdp_offer", (cmd_function)rms_sdp_offer_f, 0, 0, 0, ANY_ROUTE},
-		{"rms_sdp_answer", (cmd_function)rms_sdp_answer_f, 0, 0, 0, ANY_ROUTE},
-		{"rms_media_stop", (cmd_function)rms_media_stop_f, 0, 0, 0, ANY_ROUTE},
-		{"rms_hangup", (cmd_function)rms_hangup_f, 0, 0, 0, ANY_ROUTE},
+		{"rms_sdp_answer", (cmd_function)rms_sdp_answer_f, 0, 0, 0, REQUEST_ROUTE
+				| FAILURE_ROUTE | ONREPLY_ROUTE},
+		{"rms_media_stop", (cmd_function)rms_media_stop_f, 0, 0, 0, REQUEST_ROUTE
+				| FAILURE_ROUTE | ONREPLY_ROUTE},
+		{"rms_hangup", (cmd_function)rms_hangup_f, 0, 0, 0, EVENT_ROUTE},
 		{"rms_sessions_dump", (cmd_function)rms_sessions_dump_f, 0, 0, 0,
 		{"rms_sessions_dump", (cmd_function)rms_sessions_dump_f, 0, 0, 0,
 				ANY_ROUTE},
 				ANY_ROUTE},
 		{0, 0, 0, 0, 0, 0}};
 		{0, 0, 0, 0, 0, 0}};
@@ -161,6 +163,53 @@ void rms_signal_handler(int signum)
 	LM_INFO("signal received [%d]\n", signum);
 	LM_INFO("signal received [%d]\n", signum);
 }
 }
 
 
+static rms_session_info_t* rms_session_action_check(rms_session_info_t *si)
+{
+	rms_action_t *a;
+	clist_foreach(&si->action, a, next)
+	{
+		if(a->type == RMS_HANGUP) {
+			LM_INFO("session action RMS_HANGUP [%s]\n", si->callid.s);
+			rms_hangup_call(si);
+			a->type = RMS_STOP;
+			return si;
+		} else if(a->type == RMS_STOP) {
+			LM_INFO("session action RMS_STOP [%s][%p|%p]\n", si->callid.s, si, si->prev);
+			rms_stop_media(&si->caller_media);
+			rms_session_info_t *tmp = si->prev;
+			clist_rm(si, next, prev);
+			rms_session_free(si);
+			si = tmp;
+			return si;
+		} else if(a->type == RMS_PLAY) {
+			LM_INFO("session action RMS_PLAY [%s]\n", si->callid.s);
+			rms_playfile(&si->caller_media, a);
+			a->type = RMS_NONE;
+		} else if(a->type == RMS_DONE) {
+			LM_INFO("session action RMS_DONE [%s][%s]\n", si->callid.s,
+					a->route.s);
+			if(a->route.s) {
+				run_action_route(si, a->route.s);
+				rms_action_t *tmp = a->prev;
+				clist_rm(a, next, prev);
+				shm_free(a);
+				a = tmp;
+			} else {
+				a->type = RMS_HANGUP;
+			}
+			return si;
+		} else if(a->type == RMS_START) {
+			create_call_leg_media(&si->caller_media);
+			LM_INFO("session action RMS_START [%s]\n", si->callid.s);
+			rms_start_media(&si->caller_media, a->param.s);
+			run_action_route(si, "rms:start");
+			a->type = RMS_NONE;
+			return si;
+		}
+	}
+	return si;
+}
+
 /**
 /**
  * Most interaction with the session and media streams that are controlled 
  * Most interaction with the session and media streams that are controlled 
  * in this function this is safer in the event where a library is using non shared memory
  * in this function this is safer in the event where a library is using non shared memory
@@ -173,36 +222,7 @@ static void rms_session_manage_loop()
 		rms_session_info_t *si;
 		rms_session_info_t *si;
 		clist_foreach(rms_session_list, si, next)
 		clist_foreach(rms_session_list, si, next)
 		{
 		{
-			if(si->action == RMS_HANGUP) {
-				LM_INFO("session action RMS_HANGUP [%s]\n", si->callid.s);
-				rms_hangup_call(si);
-				si->action = RMS_STOP;
-			} else if(si->action == RMS_STOP) {
-				LM_INFO("session action RMS_STOP [%s]\n", si->callid.s);
-				rms_stop_media(&si->caller_media);
-				rms_session_info_t *tmp = si->prev;
-				clist_rm(si, next, prev);
-				rms_session_free(si);
-				si = tmp;
-			} else if(si->action == RMS_PLAY) {
-				LM_INFO("session action RMS_PLAY [%s]\n", si->callid.s);
-				rms_playfile(&si->caller_media, si->action_param.s);
-				si->action = RMS_NONE;
-			} else if(si->action == RMS_DONE) {
-				LM_INFO("session action RMS_DONE [%s][%s]\n", si->callid.s,
-						si->action_route.s);
-				if(si->action_route.s) {
-					run_action_route(si, si->action_route.s);
-				} else {
-					si->action = RMS_HANGUP;
-				}
-			} else if(si->action == RMS_START) {
-				create_call_leg_media(&si->caller_media);
-				LM_INFO("session action RMS_START [%s]\n", si->callid.s);
-				rms_start_media(&si->caller_media, si->action_param.s);
-				si->action = RMS_NONE;
-				run_action_route(si, "rms:start");
-			}
+			si = rms_session_action_check(si);
 		}
 		}
 		unlock(&session_list_mutex);
 		unlock(&session_list_mutex);
 		usleep(2000);
 		usleep(2000);
@@ -362,20 +382,6 @@ static int rms_answer_call(struct sip_msg *msg, rms_session_info_t *si)
 	return 1;
 	return 1;
 }
 }
 
 
-static rms_session_info_t *rms_session_search(char *callid, int len)
-{
-	// lock(&session_list_mutex);
-	rms_session_info_t *si;
-	clist_foreach(rms_session_list, si, next)
-	{
-		if(strncmp(callid, si->callid.s, len) == 0) {
-			unlock(&session_list_mutex);
-			return si;
-		}
-	}
-	// unlock(&session_list_mutex);
-	return NULL;
-}
 
 
 static int rms_hangup_call(rms_session_info_t *si)
 static int rms_hangup_call(rms_session_info_t *si)
 {
 {
@@ -421,8 +427,20 @@ static int rms_check_msg(struct sip_msg *msg)
 	return 1;
 	return 1;
 }
 }
 
 
+static void rms_action_free(rms_session_info_t *si)
+{
+	rms_action_t *a, *tmp;
+	clist_foreach(&si->action, a, next) {
+		tmp = a;
+		a = a->prev;
+		clist_rm(tmp, next, prev);
+		shm_free(tmp);
+	}
+}
+
 static int rms_session_free(rms_session_info_t *si)
 static int rms_session_free(rms_session_info_t *si)
 {
 {
+	rms_action_free(si);
 	rms_sdp_info_free(&si->sdp_info_offer);
 	rms_sdp_info_free(&si->sdp_info_offer);
 	rms_sdp_info_free(&si->sdp_info_answer);
 	rms_sdp_info_free(&si->sdp_info_answer);
 	if(si->caller_media.pt) {
 	if(si->caller_media.pt) {
@@ -458,6 +476,14 @@ static int rms_session_free(rms_session_info_t *si)
 	return 1;
 	return 1;
 }
 }
 
 
+rms_action_t *rms_action_new(rms_action_type_t t) {
+	rms_action_t *a = shm_malloc(sizeof(rms_action_t));
+	if (!a) return NULL;
+	memset(a, 0, sizeof(rms_action_t));
+	a->type = t;
+	return a;
+}
+
 rms_session_info_t *rms_session_new(struct sip_msg *msg)
 rms_session_info_t *rms_session_new(struct sip_msg *msg)
 {
 {
 	struct hdr_field *hdr = NULL;
 	struct hdr_field *hdr = NULL;
@@ -502,7 +528,7 @@ rms_session_info_t *rms_session_new(struct sip_msg *msg)
 		tmb.t_reply(msg, 488, "incompatible media format");
 		tmb.t_reply(msg, 488, "incompatible media format");
 		goto error;
 		goto error;
 	}
 	}
-
+	clist_init(&si->action, next, prev);
 	return si;
 	return si;
 error:
 error:
 	rms_session_free(si);
 	rms_session_free(si);
@@ -552,6 +578,16 @@ static int rms_create_trans(struct sip_msg *msg) {
 	return 1;
 	return 1;
 }
 }
 
 
+static void rms_action_add(rms_session_info_t *si, rms_action_t *a) {
+	clist_append(&si->action, a, next, prev);
+}
+
+static void rms_action_add_sync(rms_session_info_t *si, rms_action_t *a) {
+	lock(&session_list_mutex);
+	rms_action_add(si, a);
+	unlock(&session_list_mutex);
+}
+
 static void rms_session_add(rms_session_info_t *si) {
 static void rms_session_add(rms_session_info_t *si) {
 	lock(&session_list_mutex);
 	lock(&session_list_mutex);
 	clist_append(rms_session_list, si, next, prev);
 	clist_append(rms_session_list, si, next, prev);
@@ -564,6 +600,26 @@ static void rms_session_rm(rms_session_info_t *si) {
 	unlock(&session_list_mutex);
 	unlock(&session_list_mutex);
 }
 }
 
 
+static rms_session_info_t *rms_session_search(char *callid, int len)
+{
+	rms_session_info_t *si;
+	clist_foreach(rms_session_list, si, next)
+	{
+		if(strncmp(callid, si->callid.s, len) == 0) {
+			return si;
+		}
+	}
+	return NULL;
+}
+
+static rms_session_info_t *rms_session_search_sync(char *callid, int len)
+{
+	lock(&session_list_mutex);
+	rms_session_info_t *si = rms_session_search(callid, len);
+	unlock(&session_list_mutex);
+	return si;
+}
+
 static int rms_sdp_offer_f(struct sip_msg *msg, char *param1, char *param2)
 static int rms_sdp_offer_f(struct sip_msg *msg, char *param1, char *param2)
 {
 {
 	int status = rms_create_trans(msg);
 	int status = rms_create_trans(msg);
@@ -595,7 +651,7 @@ static int rms_sdp_answer_f(struct sip_msg *msg, char *param1, char *param2)
 		LM_INFO("no callid ?\n");
 		LM_INFO("no callid ?\n");
 		return -1;
 		return -1;
 	}
 	}
-	si = rms_session_search(msg->callid->body.s, msg->callid->body.len);
+	si = rms_session_search_sync(msg->callid->body.s, msg->callid->body.len);
 	if(!si) {
 	if(!si) {
 		LM_INFO("session not found ci[%.*s]\n", msg->callid->body.len,
 		LM_INFO("session not found ci[%.*s]\n", msg->callid->body.len,
 				msg->callid->body.s);
 				msg->callid->body.s);
@@ -642,7 +698,7 @@ static int rms_media_stop_f(struct sip_msg *msg, char *param1, char *param2)
 		LM_ERR("no callid\n");
 		LM_ERR("no callid\n");
 		return -1;
 		return -1;
 	}
 	}
-	si = rms_session_search(msg->callid->body.s, msg->callid->body.len);
+	si = rms_session_search_sync(msg->callid->body.s, msg->callid->body.len);
 	if(!si) {
 	if(!si) {
 		LM_INFO("session not found ci[%.*s]\n", msg->callid->body.len,
 		LM_INFO("session not found ci[%.*s]\n", msg->callid->body.len,
 				msg->callid->body.s);
 				msg->callid->body.s);
@@ -651,13 +707,24 @@ static int rms_media_stop_f(struct sip_msg *msg, char *param1, char *param2)
 		}
 		}
 		return 0;
 		return 0;
 	}
 	}
-	si->action = RMS_STOP;
+	rms_action_t *a = rms_action_new(RMS_STOP);
+	if(!a) return -1;
+	rms_action_add_sync(si, a);
 	if(!tmb.t_reply(msg, 200, "OK")) {
 	if(!tmb.t_reply(msg, 200, "OK")) {
 		return -1;
 		return -1;
 	}
 	}
 	return 0;
 	return 0;
 }
 }
 
 
+//static int rms_action_dtmf_f(struct sip_msg *msg, char dtmf, str *route)
+//	rms_session_info_t *si =
+//			rms_session_search(msg->callid->body.s, msg->callid->body.len);
+//	if(!si)
+//		return -1;
+//	rms_playfile();
+//	return 0;
+//}
+
 static int rms_action_play_f(struct sip_msg *msg, str *playback_fn, str *route)
 static int rms_action_play_f(struct sip_msg *msg, str *playback_fn, str *route)
 {
 {
 	rms_session_info_t *si =
 	rms_session_info_t *si =
@@ -667,11 +734,14 @@ static int rms_action_play_f(struct sip_msg *msg, str *playback_fn, str *route)
 	LM_INFO("RTP session [%s:%d]<>[%s:%d]\n", si->caller_media.local_ip.s,
 	LM_INFO("RTP session [%s:%d]<>[%s:%d]\n", si->caller_media.local_ip.s,
 			si->caller_media.local_port, si->caller_media.remote_ip.s,
 			si->caller_media.local_port, si->caller_media.remote_ip.s,
 			si->caller_media.remote_port);
 			si->caller_media.remote_port);
-	si->action = RMS_PLAY;
-	si->action_param.len = playback_fn->len;
-	si->action_param.s = playback_fn->s;
-	si->action_route.len = route->len;
-	si->action_route.s = route->s;
+
+	rms_action_t *a = rms_action_new(RMS_PLAY);
+	if(!a) return -1;
+	a->param.len = playback_fn->len;
+	a->param.s = playback_fn->s;
+	a->route.len = route->len;
+	a->route.s = route->s;
+	rms_action_add(si, a);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -681,12 +751,12 @@ static int rms_hangup_f(struct sip_msg *msg)
 			rms_session_search(msg->callid->body.s, msg->callid->body.len);
 			rms_session_search(msg->callid->body.s, msg->callid->body.len);
 	if(!si)
 	if(!si)
 		return -1;
 		return -1;
-	si->action = RMS_HANGUP;
+	rms_action_t *a = rms_action_new(RMS_HANGUP);
+	if(!a) return -1;
+	rms_action_add(si, a);
 	return 0;
 	return 0;
 }
 }
 
 
-
-
 static int rms_answer_f(struct sip_msg *msg)
 static int rms_answer_f(struct sip_msg *msg)
 {
 {
 	int status = rms_create_trans(msg);
 	int status = rms_create_trans(msg);
@@ -707,7 +777,9 @@ static int rms_answer_f(struct sip_msg *msg)
 	LM_INFO("RTP session [%s:%d]<>[%s:%d]\n", si->caller_media.local_ip.s,
 	LM_INFO("RTP session [%s:%d]<>[%s:%d]\n", si->caller_media.local_ip.s,
 			si->caller_media.local_port, si->caller_media.remote_ip.s,
 			si->caller_media.local_port, si->caller_media.remote_ip.s,
 			si->caller_media.remote_port);
 			si->caller_media.remote_port);
-	si->action = RMS_START;
+	rms_action_t *a = rms_action_new(RMS_START);
+	if(!a) return -1;
+	rms_action_add(si, a);
 	return 1;
 	return 1;
 error:
 error:
 	rms_session_rm(si);
 	rms_session_rm(si);

+ 11 - 3
src/modules/rtp_media_server/rtp_media_server.h

@@ -58,13 +58,23 @@ typedef struct ms_res
 	RtpProfile *rtp_profile;
 	RtpProfile *rtp_profile;
 } ms_res_t;
 } ms_res_t;
 
 
-typedef enum rms_action {
+typedef enum rms_action_type
+{
 	RMS_NONE,
 	RMS_NONE,
 	RMS_START,
 	RMS_START,
 	RMS_STOP,
 	RMS_STOP,
 	RMS_HANGUP,
 	RMS_HANGUP,
 	RMS_PLAY,
 	RMS_PLAY,
 	RMS_DONE,
 	RMS_DONE,
+} rms_action_type_t;
+
+typedef struct rms_action
+{
+	struct rms_action *next;
+	struct rms_action *prev;
+	str param;
+	str route;
+	rms_action_type_t type;
 } rms_action_t;
 } rms_action_t;
 
 
 typedef struct rms_session_info
 typedef struct rms_session_info
@@ -85,8 +95,6 @@ typedef struct rms_session_info
 	call_leg_media_t caller_media;
 	call_leg_media_t caller_media;
 	call_leg_media_t callee_media;
 	call_leg_media_t callee_media;
 	rms_action_t action;
 	rms_action_t action;
-	str action_param;
-	str action_route;
 } rms_session_info_t;
 } rms_session_info_t;
 
 
 #endif
 #endif

BIN
src/modules/rtp_media_server/voice_file/Bach_10s_8000.wav