1 /*
2  * Copyright 2008-2014 Arsen Chaloyan
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * $Id: mpf_suite.c 2214 2014-11-06 03:05:51Z achaloyan@gmail.com $
17  */
18 
19 #include <apr_thread_cond.h>
20 #include "apt_test_suite.h"
21 #include "apt_pool.h"
22 #include "apt_consumer_task.h"
23 #include "apt_dir_layout.h"
24 #include "apt_log.h"
25 #include "mpf_engine.h"
26 #include "mpf_rtp_termination_factory.h"
27 #include "mpf_file_termination_factory.h"
28 #include "mpf_audio_file_descriptor.h"
29 #include "mpf_rtp_descriptor.h"
30 #include "mpf_codec_manager.h"
31 
32 typedef struct mpf_suite_session_t mpf_suite_session_t;
33 typedef struct mpf_suite_agent_t mpf_suite_agent_t;
34 
35 /** Test suite session */
36 struct mpf_suite_session_t {
37 	/** Pool to allocate memory from */
38 	apr_pool_t        *pool;
39 
40 	/** Media context associated with the session */
41 	mpf_context_t     *context;
42 	/** The first termination in the context */
43 	mpf_termination_t *file_termination;
44 	/** The second termination in the context */
45 	mpf_termination_t *rtp_termination;
46 };
47 
48 /** Test suite agent */
49 struct mpf_suite_agent_t {
50 	/** Directory layout */
51 	apt_dir_layout_t          *dir_layout;
52 	/** The main task of the test agent, which sends messages to MPF engine and
53 	 * processes responses and events sent back from MPF engine */
54 	apt_consumer_task_t       *consumer_task;
55 	/** MPF engine */
56 	mpf_engine_t              *engine;
57 	/** RTP termination factory */
58 	mpf_termination_factory_t *rtp_termination_factory;
59 	/** File termination factory */
60 	mpf_termination_factory_t *file_termination_factory;
61 	/* Configuration of RTP termination factory */
62 	mpf_rtp_config_t          *rtp_config;
63 	/* RTP stream settings */
64 	mpf_rtp_settings_t        *rtp_settings;
65 
66 	/** RTP receiver -> File */
67 	mpf_suite_session_t       *rx_session;
68 	/** File -> RTP transmitter */
69 	mpf_suite_session_t       *tx_session;
70 
71 	/** Wait object, which is signalled to indicate shutdown */
72 	apr_thread_cond_t         *wait_object;
73 	/** Mutex of the wait object */
74 	apr_thread_mutex_t        *wait_object_mutex;
75 };
76 
77 static apt_bool_t mpf_test_run(apt_test_suite_t *suite, int argc, const char * const *argv);
78 
79 static void mpf_suite_on_start_complete(apt_task_t *task);
80 static void mpf_suite_on_terminate_complete(apt_task_t *task);
81 static apt_bool_t mpf_suite_task_msg_process(apt_task_t *task, apt_task_msg_t *msg);
82 
83 static mpf_audio_file_descriptor_t* mpf_file_reader_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session);
84 static mpf_audio_file_descriptor_t* mpf_file_writer_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session);
85 static mpf_rtp_stream_descriptor_t* mpf_rtp_rx_local_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session);
86 static mpf_rtp_stream_descriptor_t* mpf_rtp_rx_remote_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session);
87 static mpf_rtp_stream_descriptor_t* mpf_rtp_tx_local_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session);
88 static mpf_rtp_stream_descriptor_t* mpf_rtp_tx_remote_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session);
89 
90 
91 /** Create MPF test suite */
mpf_suite_create(apr_pool_t * pool)92 apt_test_suite_t* mpf_suite_create(apr_pool_t *pool)
93 {
94 	apt_test_suite_t *suite = apt_test_suite_create(pool,"mpf",NULL,mpf_test_run);
95 	return suite;
96 }
97 
98 /** Run MPF test suite */
mpf_test_run(apt_test_suite_t * suite,int argc,const char * const * argv)99 static apt_bool_t mpf_test_run(apt_test_suite_t *suite, int argc, const char * const *argv)
100 {
101 	mpf_suite_agent_t *agent;
102 	mpf_codec_manager_t *codec_manager;
103 	mpf_rtp_config_t *rtp_config;
104 	mpf_rtp_settings_t *rtp_settings;
105 	mpf_engine_t *engine;
106 
107 	apt_task_t *task;
108 	apt_task_vtable_t *vtable;
109 	apt_task_msg_pool_t *msg_pool;
110 
111 	agent = apr_palloc(suite->pool,sizeof(mpf_suite_agent_t));
112 
113 	agent->dir_layout = apt_default_dir_layout_create(NULL,suite->pool);
114 	engine = mpf_engine_create("MPF-Engine",suite->pool);
115 	if(!engine) {
116 		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create MPF Engine");
117 		return FALSE;
118 	}
119 
120 	codec_manager = mpf_engine_codec_manager_create(suite->pool);
121 	if(!codec_manager) {
122 		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Codec Manager");
123 		return FALSE;
124 	}
125 
126 	mpf_engine_codec_manager_register(engine,codec_manager);
127 	agent->engine = engine;
128 
129 	rtp_config = mpf_rtp_config_alloc(suite->pool);
130 	apt_string_set(&rtp_config->ip,"127.0.0.1");
131 	rtp_config->rtp_port_min = 5000;
132 	rtp_config->rtp_port_max = 6000;
133 
134 	agent->rtp_config = rtp_config;
135 
136 	rtp_settings = mpf_rtp_settings_alloc(suite->pool);
137 	rtp_settings->ptime = 20;
138 	rtp_settings->jb_config.adaptive = 1;
139 	rtp_settings->jb_config.time_skew_detection = 1;
140 	rtp_settings->jb_config.min_playout_delay = 0;
141 	rtp_settings->jb_config.initial_playout_delay = 50;
142 	rtp_settings->jb_config.max_playout_delay = 800;
143 	mpf_codec_manager_codec_list_load(codec_manager,&rtp_settings->codec_list,"PCMU",suite->pool);
144 
145 	agent->rtp_settings = rtp_settings;
146 
147 	agent->rtp_termination_factory = mpf_rtp_termination_factory_create(rtp_config,suite->pool);
148 	agent->file_termination_factory = mpf_file_termination_factory_create(suite->pool);
149 
150 	agent->rx_session = NULL;
151 	agent->tx_session = NULL;
152 
153 	msg_pool = apt_task_msg_pool_create_dynamic(sizeof(mpf_message_t),suite->pool);
154 
155 	apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create Consumer Task");
156 	agent->consumer_task = apt_consumer_task_create(agent,msg_pool,suite->pool);
157 	if(!agent->consumer_task) {
158 		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Consumer Task");
159 		return FALSE;
160 	}
161 	task = apt_consumer_task_base_get(agent->consumer_task);
162 	apt_task_name_set(task,"MPF-Tester");
163 	vtable = apt_task_vtable_get(task);
164 	if(vtable) {
165 		vtable->process_msg = mpf_suite_task_msg_process;
166 		vtable->on_start_complete = mpf_suite_on_start_complete;
167 		vtable->on_terminate_complete = mpf_suite_on_terminate_complete;
168 	}
169 
170 	apt_task_add(task,mpf_task_get(engine));
171 
172 	apr_thread_mutex_create(&agent->wait_object_mutex,APR_THREAD_MUTEX_UNNESTED,suite->pool);
173 	apr_thread_cond_create(&agent->wait_object,suite->pool);
174 
175 	if(apt_task_start(task) == FALSE) {
176 		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Start Task");
177 		apt_task_destroy(task);
178 		return FALSE;
179 	}
180 
181 	apr_thread_mutex_lock(agent->wait_object_mutex);
182 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Wait for Task to Complete");
183 	apr_thread_cond_wait(agent->wait_object,agent->wait_object_mutex);
184 	apr_thread_mutex_unlock(agent->wait_object_mutex);
185 
186 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Terminate Task [wait till complete]");
187 	apt_task_terminate(task,TRUE);
188 	apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy Task");
189 	apt_task_destroy(task);
190 
191 	apr_thread_cond_destroy(agent->wait_object);
192 	apr_thread_mutex_destroy(agent->wait_object_mutex);
193 	return TRUE;
194 }
195 
mpf_suite_rx_session_create(const mpf_suite_agent_t * agent)196 static mpf_suite_session_t* mpf_suite_rx_session_create(const mpf_suite_agent_t *agent)
197 {
198 	mpf_task_msg_t *task_msg = NULL;
199 	void *descriptor;
200 	apr_pool_t *pool;
201 	mpf_suite_session_t *session;
202 
203 	pool = apt_pool_create();
204 	session = apr_palloc(pool,sizeof(mpf_suite_session_t));
205 	session->pool = pool;
206 	session->context = NULL;
207 	session->file_termination = NULL;
208 	session->rtp_termination = NULL;
209 
210 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create MPF Context [Rx]");
211 	session->context = mpf_engine_context_create(agent->engine,NULL,session,2,pool);
212 
213 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create Termination [RTP Rx]");
214 	session->rtp_termination = mpf_termination_create(agent->rtp_termination_factory,session,session->pool);
215 
216 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Add Termination [RTP Rx]");
217 	descriptor = mpf_rtp_rx_local_descriptor_create(agent,session);
218 	mpf_engine_termination_message_add(
219 			agent->engine,
220 			MPF_ADD_TERMINATION,session->context,session->rtp_termination,descriptor,
221 			&task_msg);
222 
223 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create Termination [File Writer]");
224 	session->file_termination = mpf_termination_create(agent->file_termination_factory,session,session->pool);
225 
226 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Add Termination [File Writer]");
227 	descriptor = mpf_file_writer_descriptor_create(agent,session);
228 	mpf_engine_termination_message_add(
229 			agent->engine,
230 			MPF_ADD_TERMINATION,session->context,session->file_termination,descriptor,
231 			&task_msg);
232 
233 	mpf_engine_message_send(agent->engine,&task_msg);
234 	return session;
235 }
236 
mpf_suite_tx_session_create(const mpf_suite_agent_t * agent)237 static mpf_suite_session_t* mpf_suite_tx_session_create(const mpf_suite_agent_t *agent)
238 {
239 	mpf_task_msg_t *task_msg = NULL;
240 	void *descriptor;
241 	apr_pool_t *pool;
242 	mpf_suite_session_t *session;
243 
244 	pool = apt_pool_create();
245 	session = apr_palloc(pool,sizeof(mpf_suite_session_t));
246 	session->pool = pool;
247 	session->context = NULL;
248 	session->file_termination = NULL;
249 	session->rtp_termination = NULL;
250 
251 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create MPF Context [Tx]");
252 	session->context = mpf_engine_context_create(agent->engine,NULL,session,2,pool);
253 
254 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create Termination [File Reader]");
255 	session->file_termination = mpf_termination_create(agent->file_termination_factory,session,session->pool);
256 
257 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Add Termination [File Reader]");
258 	descriptor = mpf_file_reader_descriptor_create(agent,session);
259 	mpf_engine_termination_message_add(
260 			agent->engine,
261 			MPF_ADD_TERMINATION,session->context,session->file_termination,descriptor,
262 			&task_msg);
263 
264 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create Termination [RTP Tx]");
265 	session->rtp_termination = mpf_termination_create(agent->rtp_termination_factory,session,session->pool);
266 
267 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Add Termination [RTP Tx]");
268 	descriptor = mpf_rtp_tx_local_descriptor_create(agent,session);
269 	mpf_engine_termination_message_add(
270 			agent->engine,
271 			MPF_ADD_TERMINATION,session->context,session->rtp_termination,descriptor,
272 			&task_msg);
273 
274 	mpf_engine_message_send(agent->engine,&task_msg);
275 	return session;
276 }
277 
mpf_suite_session_destroy(mpf_suite_agent_t * agent,mpf_suite_session_t * session)278 static void mpf_suite_session_destroy(mpf_suite_agent_t *agent, mpf_suite_session_t* session)
279 {
280 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Destroy MPF Context");
281 	mpf_engine_context_destroy(session->context);
282 	session->context = NULL;
283 
284 	if(agent->rx_session == session) {
285 		agent->rx_session = NULL;
286 	}
287 	else if(agent->tx_session == session) {
288 		agent->tx_session = NULL;
289 	}
290 
291 	apr_pool_destroy(session->pool);
292 
293 	if(!agent->tx_session && !agent->rx_session) {
294 		apr_thread_mutex_lock(agent->wait_object_mutex);
295 		apr_thread_cond_signal(agent->wait_object);
296 		apr_thread_mutex_unlock(agent->wait_object_mutex);
297 	}
298 }
299 
300 /** Start execution of MPF test suite scenario  */
mpf_suite_on_start_complete(apt_task_t * task)301 static void mpf_suite_on_start_complete(apt_task_t *task)
302 {
303 	apt_consumer_task_t *consumer_task;
304 	mpf_suite_agent_t *agent;
305 
306 	consumer_task = apt_task_object_get(task);
307 	agent = apt_consumer_task_object_get(consumer_task);
308 
309 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"On MPF Suite Start");
310 
311 	agent->rx_session = mpf_suite_rx_session_create(agent);
312 	agent->tx_session = mpf_suite_tx_session_create(agent);
313 }
314 
315 /** Execution of MPF test suite scenario is terminated  */
mpf_suite_on_terminate_complete(apt_task_t * task)316 static void mpf_suite_on_terminate_complete(apt_task_t *task)
317 {
318 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"On MPF Suite Terminate");
319 }
320 
321 /** Process MPF response  */
mpf_suite_response_process(mpf_suite_agent_t * agent,const mpf_message_t * mpf_message)322 static apt_bool_t mpf_suite_response_process(mpf_suite_agent_t *agent, const mpf_message_t *mpf_message)
323 {
324 	mpf_task_msg_t *task_msg = NULL;
325 	apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process MPF Response");
326 	if(mpf_message->command_id == MPF_ADD_TERMINATION) {
327 		apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Add Termination");
328 		if(mpf_message->termination) {
329 			mpf_suite_session_t *session;
330 			session = mpf_termination_object_get(mpf_message->termination);
331 			if(session->rtp_termination == mpf_message->termination) {
332 				mpf_rtp_stream_descriptor_t *descriptor = NULL;
333 				if(session == agent->rx_session) {
334 					descriptor = mpf_rtp_rx_remote_descriptor_create(agent,session);
335 				}
336 				if(session == agent->tx_session) {
337 					descriptor = mpf_rtp_tx_remote_descriptor_create(agent,session);
338 				}
339 
340 				if(descriptor) {
341 					mpf_engine_termination_message_add(
342 						agent->engine,
343 						MPF_MODIFY_TERMINATION,session->context,session->rtp_termination,descriptor,
344 						&task_msg);
345 				}
346 
347 				mpf_engine_assoc_message_add(
348 						agent->engine,
349 						MPF_ADD_ASSOCIATION,session->context,session->file_termination,session->rtp_termination,
350 						&task_msg);
351 
352 				mpf_engine_topology_message_add(
353 						agent->engine,
354 						MPF_APPLY_TOPOLOGY,session->context,
355 						&task_msg);
356 			}
357 		}
358 	}
359 	else if(mpf_message->command_id == MPF_SUBTRACT_TERMINATION) {
360 		apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Subtract Termination");
361 		if(mpf_message->termination) {
362 			mpf_suite_session_t *session;
363 			session = mpf_termination_object_get(mpf_message->termination);
364 			if(session->file_termination == mpf_message->termination) {
365 				session->file_termination = NULL;
366 			}
367 			else if(session->rtp_termination == mpf_message->termination) {
368 				session->rtp_termination = NULL;
369 			}
370 			mpf_termination_destroy(mpf_message->termination);
371 
372 			if(!session->file_termination && !session->rtp_termination) {
373 				mpf_suite_session_destroy(agent,session);
374 			}
375 		}
376 	}
377 	return mpf_engine_message_send(agent->engine,&task_msg);
378 }
379 
380 /** Process MPF event  */
mpf_suite_event_process(mpf_suite_agent_t * agent,const mpf_message_t * mpf_message)381 static apt_bool_t mpf_suite_event_process(mpf_suite_agent_t *agent, const mpf_message_t *mpf_message)
382 {
383 	mpf_task_msg_t *task_msg = NULL;
384 	mpf_suite_session_t *session;
385 	apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process MPF Event");
386 	if(mpf_message->termination) {
387 		session = mpf_termination_object_get(mpf_message->termination);
388 		/* first destroy existing topology */
389 		mpf_engine_topology_message_add(
390 					agent->engine,
391 					MPF_DESTROY_TOPOLOGY,session->context,
392 					&task_msg);
393 
394 		if(session->file_termination) {
395 			apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Subtract Termination [File]");
396 			mpf_engine_termination_message_add(
397 				agent->engine,
398 				MPF_SUBTRACT_TERMINATION,session->context,session->file_termination,NULL,
399 				&task_msg);
400 		}
401 		if(session->rtp_termination) {
402 			apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Subtract Termination [RTP]");
403 			mpf_engine_termination_message_add(
404 				agent->engine,
405 				MPF_SUBTRACT_TERMINATION,session->context,session->rtp_termination,NULL,
406 				&task_msg);
407 		}
408 	}
409 	return mpf_engine_message_send(agent->engine,&task_msg);
410 }
411 
412 /** Process task messages */
mpf_suite_task_msg_process(apt_task_t * task,apt_task_msg_t * msg)413 static apt_bool_t mpf_suite_task_msg_process(apt_task_t *task, apt_task_msg_t *msg)
414 {
415 	apr_size_t i;
416 	const mpf_message_t *mpf_message;
417 	apt_consumer_task_t *consumer_task = apt_task_object_get(task);
418 	mpf_suite_agent_t *agent = apt_consumer_task_object_get(consumer_task);
419 	const mpf_message_container_t *container = (const mpf_message_container_t*) msg->data;
420 	for(i=0; i<container->count; i++) {
421 		mpf_message = &container->messages[i];
422 		if(mpf_message->message_type == MPF_MESSAGE_TYPE_RESPONSE) {
423 			mpf_suite_response_process(agent,mpf_message);
424 		}
425 		else {
426 			mpf_suite_event_process(agent,mpf_message);
427 		}
428 	}
429 	return TRUE;
430 }
431 
432 /** Create file reader descriptor */
mpf_file_reader_descriptor_create(const mpf_suite_agent_t * agent,const mpf_suite_session_t * session)433 static mpf_audio_file_descriptor_t* mpf_file_reader_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session)
434 {
435 	const char *file_path = apt_datadir_filepath_get(agent->dir_layout,"demo-8kHz.pcm",session->pool);
436 	mpf_audio_file_descriptor_t *descriptor = apr_palloc(session->pool,sizeof(mpf_audio_file_descriptor_t));
437 	descriptor->mask = FILE_READER;
438 	descriptor->read_handle = NULL;
439 	descriptor->write_handle = NULL;
440 	descriptor->codec_descriptor = mpf_codec_lpcm_descriptor_create(8000,1,session->pool);
441 	if(file_path) {
442 		apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Open File [%s] for Reading",file_path);
443 		descriptor->read_handle = fopen(file_path,"rb");
444 		if(!descriptor->read_handle) {
445 			apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open File [%s]",file_path);
446 		}
447 	}
448 	return descriptor;
449 }
450 
451 /** Create file writer descriptor */
mpf_file_writer_descriptor_create(const mpf_suite_agent_t * agent,const mpf_suite_session_t * session)452 static mpf_audio_file_descriptor_t* mpf_file_writer_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session)
453 {
454 	const char *file_path = apt_vardir_filepath_get(agent->dir_layout,"output-8kHz.pcm",session->pool);
455 	mpf_audio_file_descriptor_t *descriptor = apr_palloc(session->pool,sizeof(mpf_audio_file_descriptor_t));
456 	descriptor->mask = FILE_WRITER;
457 	descriptor->max_write_size = 500000; /* ~500Kb */
458 	descriptor->write_handle = NULL;
459 	descriptor->read_handle = NULL;
460 	descriptor->codec_descriptor = mpf_codec_lpcm_descriptor_create(8000,1,session->pool);
461 	if(file_path) {
462 		apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Open File [%s] for Writing",file_path);
463 		descriptor->write_handle = fopen(file_path,"wb");
464 		if(!descriptor->write_handle) {
465 			apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open File [%s] for Writing",file_path);
466 		}
467 	}
468 	return descriptor;
469 }
470 
471 /** Create RTP rx local descriptor */
mpf_rtp_rx_local_descriptor_create(const mpf_suite_agent_t * agent,const mpf_suite_session_t * session)472 static mpf_rtp_stream_descriptor_t* mpf_rtp_rx_local_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session)
473 {
474 	mpf_rtp_media_descriptor_t *media_descriptor;
475 	mpf_rtp_stream_descriptor_t *stream_descriptor;
476 
477 	media_descriptor = apr_palloc(session->pool,sizeof(mpf_rtp_media_descriptor_t));
478 	mpf_rtp_media_descriptor_init(media_descriptor);
479 	media_descriptor->state = MPF_MEDIA_ENABLED;
480 	media_descriptor->direction = STREAM_DIRECTION_RECEIVE;
481 	apt_string_set(&media_descriptor->ip,"127.0.0.1");
482 	media_descriptor->port = 5000;
483 
484 	stream_descriptor = apr_palloc(session->pool,sizeof(mpf_rtp_stream_descriptor_t));
485 	mpf_rtp_stream_descriptor_init(stream_descriptor);
486 	stream_descriptor->local = media_descriptor;
487 	stream_descriptor->settings = agent->rtp_settings;
488 	return stream_descriptor;
489 }
490 
491 /** Create RTP rx remote descriptor */
mpf_rtp_rx_remote_descriptor_create(const mpf_suite_agent_t * agent,const mpf_suite_session_t * session)492 static mpf_rtp_stream_descriptor_t* mpf_rtp_rx_remote_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session)
493 {
494 	mpf_codec_list_t *codec_list;
495 	mpf_codec_descriptor_t *codec_descriptor;
496 	mpf_rtp_media_descriptor_t *media_descriptor;
497 	mpf_rtp_stream_descriptor_t *stream_descriptor;
498 
499 	media_descriptor = apr_palloc(session->pool,sizeof(mpf_rtp_media_descriptor_t));
500 	mpf_rtp_media_descriptor_init(media_descriptor);
501 	media_descriptor->state = MPF_MEDIA_ENABLED;
502 	media_descriptor->direction = STREAM_DIRECTION_SEND;
503 	apt_string_set(&media_descriptor->ip,"127.0.0.1");
504 	media_descriptor->port = 5002;
505 	codec_list = &media_descriptor->codec_list;
506 	mpf_codec_list_init(codec_list,1,session->pool);
507 	codec_descriptor = mpf_codec_list_add(codec_list);
508 	if(codec_descriptor) {
509 		codec_descriptor->payload_type = 0;
510 		apt_string_set(&codec_descriptor->name,"PCMU");
511 		codec_descriptor->sampling_rate = 8000;
512 		codec_descriptor->channel_count = 1;
513 	}
514 
515 	stream_descriptor = apr_palloc(session->pool,sizeof(mpf_rtp_stream_descriptor_t));
516 	mpf_rtp_stream_descriptor_init(stream_descriptor);
517 	stream_descriptor->remote = media_descriptor;
518 	stream_descriptor->settings = agent->rtp_settings;
519 	return stream_descriptor;
520 }
521 
522 /** Create RTP tx local descriptor */
mpf_rtp_tx_local_descriptor_create(const mpf_suite_agent_t * agent,const mpf_suite_session_t * session)523 static mpf_rtp_stream_descriptor_t* mpf_rtp_tx_local_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session)
524 {
525 	mpf_rtp_media_descriptor_t *media_descriptor;
526 	mpf_rtp_stream_descriptor_t *stream_descriptor;
527 
528 	media_descriptor = apr_palloc(session->pool,sizeof(mpf_rtp_media_descriptor_t));
529 	mpf_rtp_media_descriptor_init(media_descriptor);
530 	media_descriptor->state = MPF_MEDIA_ENABLED;
531 	media_descriptor->direction = STREAM_DIRECTION_SEND;
532 	apt_string_set(&media_descriptor->ip,"127.0.0.1");
533 	media_descriptor->port = 5002;
534 
535 	stream_descriptor = apr_palloc(session->pool,sizeof(mpf_rtp_stream_descriptor_t));
536 	mpf_rtp_stream_descriptor_init(stream_descriptor);
537 	stream_descriptor->local = media_descriptor;
538 	stream_descriptor->settings = agent->rtp_settings;
539 	return stream_descriptor;
540 }
541 
542 /** Create RTP tx remote descriptor */
mpf_rtp_tx_remote_descriptor_create(const mpf_suite_agent_t * agent,const mpf_suite_session_t * session)543 static mpf_rtp_stream_descriptor_t* mpf_rtp_tx_remote_descriptor_create(const mpf_suite_agent_t *agent, const mpf_suite_session_t *session)
544 {
545 	mpf_codec_list_t *codec_list;
546 	mpf_codec_descriptor_t *codec_descriptor;
547 	mpf_rtp_media_descriptor_t *media_descriptor;
548 	mpf_rtp_stream_descriptor_t *stream_descriptor;
549 
550 	media_descriptor = apr_palloc(session->pool,sizeof(mpf_rtp_media_descriptor_t));
551 	mpf_rtp_media_descriptor_init(media_descriptor);
552 	media_descriptor->state = MPF_MEDIA_ENABLED;
553 	media_descriptor->direction = STREAM_DIRECTION_RECEIVE;
554 	apt_string_set(&media_descriptor->ip,"127.0.0.1");
555 	media_descriptor->port = 5000;
556 	codec_list = &media_descriptor->codec_list;
557 	mpf_codec_list_init(codec_list,1,session->pool);
558 	codec_descriptor = mpf_codec_list_add(codec_list);
559 	if(codec_descriptor) {
560 		codec_descriptor->payload_type = 0;
561 		apt_string_set(&codec_descriptor->name,"PCMU");
562 		codec_descriptor->sampling_rate = 8000;
563 		codec_descriptor->channel_count = 1;
564 	}
565 
566 	stream_descriptor = apr_palloc(session->pool,sizeof(mpf_rtp_stream_descriptor_t));
567 	mpf_rtp_stream_descriptor_init(stream_descriptor);
568 	stream_descriptor->remote = media_descriptor;
569 	stream_descriptor->settings = agent->rtp_settings;
570 	return stream_descriptor;
571 }
572