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