Asterisk - The Open Source Telephony Project  18.5.0
chan_rtp.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2009 - 2014, Digium, Inc.
5  *
6  * Joshua Colp <[email protected]>
7  * Andreas 'MacBrody' Brodmann <[email protected]>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19 
20 /*! \file
21  *
22  * \author Joshua Colp <[email protected]>
23  * \author Andreas 'MacBrody' Broadmann <[email protected]>
24  *
25  * \brief RTP (Multicast and Unicast) Media Channel
26  *
27  * \ingroup channel_drivers
28  */
29 
30 /*** MODULEINFO
31  <depend>res_rtp_multicast</depend>
32  <support_level>core</support_level>
33  ***/
34 
35 #include "asterisk.h"
36 
37 #include "asterisk/channel.h"
38 #include "asterisk/module.h"
39 #include "asterisk/pbx.h"
40 #include "asterisk/acl.h"
41 #include "asterisk/app.h"
42 #include "asterisk/rtp_engine.h"
43 #include "asterisk/causes.h"
44 #include "asterisk/format_cache.h"
45 #include "asterisk/multicast_rtp.h"
46 #include "asterisk/dns_core.h"
47 
48 /* Forward declarations */
49 static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
50 static struct ast_channel *unicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
51 static int rtp_call(struct ast_channel *ast, const char *dest, int timeout);
52 static int rtp_hangup(struct ast_channel *ast);
53 static struct ast_frame *rtp_read(struct ast_channel *ast);
54 static int rtp_write(struct ast_channel *ast, struct ast_frame *f);
55 
56 /* Multicast channel driver declaration */
58  .type = "MulticastRTP",
59  .description = "Multicast RTP Paging Channel Driver",
60  .requester = multicast_rtp_request,
61  .call = rtp_call,
62  .hangup = rtp_hangup,
63  .read = rtp_read,
64  .write = rtp_write,
65 };
66 
67 /* Unicast channel driver declaration */
69  .type = "UnicastRTP",
70  .description = "Unicast RTP Media Channel Driver",
71  .requester = unicast_rtp_request,
72  .call = rtp_call,
73  .hangup = rtp_hangup,
74  .read = rtp_read,
75  .write = rtp_write,
76 };
77 
78 /*! \brief Function called when we should read a frame from the channel */
79 static struct ast_frame *rtp_read(struct ast_channel *ast)
80 {
81  struct ast_rtp_instance *instance = ast_channel_tech_pvt(ast);
82  int fdno = ast_channel_fdno(ast);
83 
84  switch (fdno) {
85  case 0:
86  return ast_rtp_instance_read(instance, 0);
87  default:
88  return &ast_null_frame;
89  }
90 }
91 
92 /*! \brief Function called when we should write a frame to the channel */
93 static int rtp_write(struct ast_channel *ast, struct ast_frame *f)
94 {
95  struct ast_rtp_instance *instance = ast_channel_tech_pvt(ast);
96 
97  return ast_rtp_instance_write(instance, f);
98 }
99 
100 /*! \brief Function called when we should actually call the destination */
101 static int rtp_call(struct ast_channel *ast, const char *dest, int timeout)
102 {
103  struct ast_rtp_instance *instance = ast_channel_tech_pvt(ast);
104 
106 
107  return ast_rtp_instance_activate(instance);
108 }
109 
110 /*! \brief Function called when we should hang the channel up */
111 static int rtp_hangup(struct ast_channel *ast)
112 {
113  struct ast_rtp_instance *instance = ast_channel_tech_pvt(ast);
114 
115  ast_rtp_instance_destroy(instance);
116 
118 
119  return 0;
120 }
121 
123 {
124  struct ast_format *fmt = ast_format_cap_get_format(cap, 0);
125 
126  if (ast_format_cap_count(cap) == 1 && fmt == ast_format_slin) {
127  /*
128  * Because we have no SDP, we must use one of the static RTP payload
129  * assignments. Signed linear @ 8kHz does not map, so if that is our
130  * only capability, we force μ-law instead.
131  */
132  fmt = ast_format_ulaw;
133  }
134 
135  return fmt;
136 }
137 
138 /*! \brief Function called when we should prepare to call the multicast destination */
139 static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
140 {
141  char *parse;
142  struct ast_rtp_instance *instance;
143  struct ast_sockaddr control_address;
144  struct ast_sockaddr destination_address;
145  struct ast_channel *chan;
146  struct ast_format_cap *caps = NULL;
147  struct ast_format *fmt = NULL;
149  AST_APP_ARG(type);
150  AST_APP_ARG(destination);
151  AST_APP_ARG(control);
153  );
154  struct ast_multicast_rtp_options *mcast_options = NULL;
155 
156  if (ast_strlen_zero(data)) {
157  ast_log(LOG_ERROR, "A multicast type and destination must be given to the 'MulticastRTP' channel\n");
158  goto failure;
159  }
160  parse = ast_strdupa(data);
161  AST_NONSTANDARD_APP_ARGS(args, parse, '/');
162 
163  if (ast_strlen_zero(args.type)) {
164  ast_log(LOG_ERROR, "Type is required for the 'MulticastRTP' channel\n");
165  goto failure;
166  }
167 
168  if (ast_strlen_zero(args.destination)) {
169  ast_log(LOG_ERROR, "Destination is required for the 'MulticastRTP' channel\n");
170  goto failure;
171  }
172  if (!ast_sockaddr_parse(&destination_address, args.destination, PARSE_PORT_REQUIRE)) {
173  ast_log(LOG_ERROR, "Destination address '%s' could not be parsed\n",
174  args.destination);
175  goto failure;
176  }
177 
178  ast_sockaddr_setnull(&control_address);
179  if (!ast_strlen_zero(args.control)
180  && !ast_sockaddr_parse(&control_address, args.control, PARSE_PORT_REQUIRE)) {
181  ast_log(LOG_ERROR, "Control address '%s' could not be parsed\n", args.control);
182  goto failure;
183  }
184 
185  mcast_options = ast_multicast_rtp_create_options(args.type, args.options);
186  if (!mcast_options) {
187  goto failure;
188  }
189 
190  fmt = ast_multicast_rtp_options_get_format(mcast_options);
191  if (!fmt) {
192  fmt = derive_format_from_cap(cap);
193  }
194  if (!fmt) {
195  ast_log(LOG_ERROR, "No codec available for sending RTP to '%s'\n",
196  args.destination);
197  goto failure;
198  }
199 
201  if (!caps) {
202  goto failure;
203  }
204 
205  instance = ast_rtp_instance_new("multicast", NULL, &control_address, mcast_options);
206  if (!instance) {
208  "Could not create '%s' multicast RTP instance for sending media to '%s'\n",
209  args.type, args.destination);
210  goto failure;
211  }
212 
213  chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", assignedids,
214  requestor, 0, "MulticastRTP/%p", instance);
215  if (!chan) {
216  ast_rtp_instance_destroy(instance);
217  goto failure;
218  }
220  ast_rtp_instance_set_remote_address(instance, &destination_address);
221 
222  ast_channel_tech_set(chan, &multicast_rtp_tech);
223 
224  ast_format_cap_append(caps, fmt, 0);
225  ast_channel_nativeformats_set(chan, caps);
226  ast_channel_set_writeformat(chan, fmt);
228  ast_channel_set_readformat(chan, fmt);
230 
231  ast_channel_tech_pvt_set(chan, instance);
232 
233  ast_channel_unlock(chan);
234 
235  ao2_ref(fmt, -1);
236  ao2_ref(caps, -1);
237  ast_multicast_rtp_free_options(mcast_options);
238 
239  return chan;
240 
241 failure:
242  ao2_cleanup(fmt);
243  ao2_cleanup(caps);
244  ast_multicast_rtp_free_options(mcast_options);
245  *cause = AST_CAUSE_FAILURE;
246  return NULL;
247 }
248 
249 enum {
250  OPT_RTP_CODEC = (1 << 0),
251  OPT_RTP_ENGINE = (1 << 1),
252 };
253 
254 enum {
257  /* note: this entry _MUST_ be the last one in the enum */
259 };
260 
262  /*! Set the codec to be used for unicast RTP */
264  /*! Set the RTP engine to use for unicast RTP */
267 
268 /*! \brief Function called when we should prepare to call the unicast destination */
269 static struct ast_channel *unicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
270 {
271  char *parse;
272  struct ast_rtp_instance *instance;
273  struct ast_sockaddr address;
274  struct ast_sockaddr local_address;
275  struct ast_channel *chan;
276  struct ast_format_cap *caps = NULL;
277  struct ast_format *fmt = NULL;
278  const char *engine_name;
280  AST_APP_ARG(destination);
282  );
283  struct ast_flags opts = { 0, };
284  char *opt_args[OPT_ARG_ARRAY_SIZE];
285 
286  if (ast_strlen_zero(data)) {
287  ast_log(LOG_ERROR, "Destination is required for the 'UnicastRTP' channel\n");
288  goto failure;
289  }
290  parse = ast_strdupa(data);
291  AST_NONSTANDARD_APP_ARGS(args, parse, '/');
292 
293  if (ast_strlen_zero(args.destination)) {
294  ast_log(LOG_ERROR, "Destination is required for the 'UnicastRTP' channel\n");
295  goto failure;
296  }
297 
298  if (!ast_sockaddr_parse(&address, args.destination, PARSE_PORT_REQUIRE)) {
299  int rc;
300  char *host;
301  char *port;
302 
303  rc = ast_sockaddr_split_hostport(args.destination, &host, &port, PARSE_PORT_REQUIRE);
304  if (!rc) {
305  ast_log(LOG_ERROR, "Unable to parse destination '%s' into host and port\n", args.destination);
306  goto failure;
307  }
308 
309  rc = ast_dns_resolve_ipv6_and_ipv4(&address, host, port);
310  if (rc != 0) {
311  ast_log(LOG_ERROR, "Unable to resolve host '%s'\n", host);
312  goto failure;
313  }
314  }
315 
316  if (!ast_strlen_zero(args.options)
317  && ast_app_parse_options(unicast_rtp_options, &opts, opt_args,
318  ast_strdupa(args.options))) {
319  ast_log(LOG_ERROR, "'UnicastRTP' channel options '%s' parse error\n",
320  args.options);
321  goto failure;
322  }
323 
324  if (ast_test_flag(&opts, OPT_RTP_CODEC)
325  && !ast_strlen_zero(opt_args[OPT_ARG_RTP_CODEC])) {
326  fmt = ast_format_cache_get(opt_args[OPT_ARG_RTP_CODEC]);
327  if (!fmt) {
328  ast_log(LOG_ERROR, "Codec '%s' not found for sending RTP to '%s'\n",
329  opt_args[OPT_ARG_RTP_CODEC], args.destination);
330  goto failure;
331  }
332  } else {
333  fmt = derive_format_from_cap(cap);
334  if (!fmt) {
335  ast_log(LOG_ERROR, "No codec available for sending RTP to '%s'\n",
336  args.destination);
337  goto failure;
338  }
339  }
340 
342  if (!caps) {
343  goto failure;
344  }
345 
346  engine_name = S_COR(ast_test_flag(&opts, OPT_RTP_ENGINE),
347  opt_args[OPT_ARG_RTP_ENGINE], "asterisk");
348 
349  ast_sockaddr_copy(&local_address, &address);
350  if (ast_ouraddrfor(&address, &local_address)) {
351  ast_log(LOG_ERROR, "Could not get our address for sending media to '%s'\n",
352  args.destination);
353  goto failure;
354  }
355  instance = ast_rtp_instance_new(engine_name, NULL, &local_address, NULL);
356  if (!instance) {
358  "Could not create %s RTP instance for sending media to '%s'\n",
359  S_OR(engine_name, "default"), args.destination);
360  goto failure;
361  }
362 
363  chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", assignedids,
364  requestor, 0, "UnicastRTP/%s-%p", args.destination, instance);
365  if (!chan) {
366  ast_rtp_instance_destroy(instance);
367  goto failure;
368  }
370  ast_rtp_instance_set_remote_address(instance, &address);
371  ast_channel_set_fd(chan, 0, ast_rtp_instance_fd(instance, 0));
372 
373  ast_channel_tech_set(chan, &unicast_rtp_tech);
374 
375  ast_format_cap_append(caps, fmt, 0);
376  ast_channel_nativeformats_set(chan, caps);
377  ast_channel_set_writeformat(chan, fmt);
379  ast_channel_set_readformat(chan, fmt);
381 
382  ast_channel_tech_pvt_set(chan, instance);
383 
384  pbx_builtin_setvar_helper(chan, "UNICASTRTP_LOCAL_ADDRESS",
385  ast_sockaddr_stringify_addr(&local_address));
386  ast_rtp_instance_get_local_address(instance, &local_address);
387  pbx_builtin_setvar_helper(chan, "UNICASTRTP_LOCAL_PORT",
388  ast_sockaddr_stringify_port(&local_address));
389 
390  ast_channel_unlock(chan);
391 
392  ao2_ref(fmt, -1);
393  ao2_ref(caps, -1);
394 
395  return chan;
396 
397 failure:
398  ao2_cleanup(fmt);
399  ao2_cleanup(caps);
400  *cause = AST_CAUSE_FAILURE;
401  return NULL;
402 }
403 
404 /*! \brief Function called when our module is unloaded */
405 static int unload_module(void)
406 {
407  ast_channel_unregister(&multicast_rtp_tech);
408  ao2_cleanup(multicast_rtp_tech.capabilities);
409  multicast_rtp_tech.capabilities = NULL;
410 
411  ast_channel_unregister(&unicast_rtp_tech);
412  ao2_cleanup(unicast_rtp_tech.capabilities);
413  unicast_rtp_tech.capabilities = NULL;
414 
415  return 0;
416 }
417 
418 /*! \brief Function called when our module is loaded */
419 static int load_module(void)
420 {
421  if (!(multicast_rtp_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
423  }
425  if (ast_channel_register(&multicast_rtp_tech)) {
426  ast_log(LOG_ERROR, "Unable to register channel class 'MulticastRTP'\n");
427  unload_module();
429  }
430 
432  unload_module();
434  }
436  if (ast_channel_register(&unicast_rtp_tech)) {
437  ast_log(LOG_ERROR, "Unable to register channel class 'UnicastRTP'\n");
438  unload_module();
440  }
441 
443 }
444 
446  .support_level = AST_MODULE_SUPPORT_CORE,
447  .load = load_module,
448  .unload = unload_module,
449  .load_pri = AST_MODPRI_CHANNEL_DRIVER,
450  .requires = "res_rtp_multicast",
451 );
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
static const char type[]
Definition: chan_ooh323.c:109
int ast_rtp_instance_activate(struct ast_rtp_instance *instance)
Indicate to the RTP engine that packets are now expected to be sent/received on the RTP instance...
Definition: rtp_engine.c:2647
Main Channel structure associated with a channel.
const char *const type
Definition: channel.h:630
static struct ast_format * derive_format_from_cap(struct ast_format_cap *cap)
Definition: chan_rtp.c:122
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_channel_tech multicast_rtp_tech
Definition: chan_rtp.c:57
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
void ast_rtp_instance_set_channel_id(struct ast_rtp_instance *instance, const char *uniqueid)
Set the channel that owns this RTP instance.
Definition: rtp_engine.c:553
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define BEGIN_OPTIONS
static int rtp_hangup(struct ast_channel *ast)
Function called when we should hang the channel up.
Definition: chan_rtp.c:111
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
static int timeout
Definition: cdr_mysql.c:86
static int unload_module(void)
Function called when our module is unloaded.
Definition: chan_rtp.c:405
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:568
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:605
int ast_dns_resolve_ipv6_and_ipv4(struct ast_sockaddr *address, const char *host, const char *port)
Synchronously resolves host to an AAAA or A record.
Definition: dns_core.c:369
Definition of a media format.
Definition: format.c:43
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
struct ast_format * ast_multicast_rtp_options_get_format(struct ast_multicast_rtp_options *mcast_options)
Get format specified in multicast options.
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
const char * args
#define NULL
Definition: resample.c:96
const char * data
Socket address structure.
Definition: netsock2.h:97
#define ast_format_cache_get(name)
Definition: format_cache.h:286
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:140
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:362
struct ast_multicast_rtp_options * ast_multicast_rtp_create_options(const char *type, const char *options)
Create multicast RTP options.
int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
Get our local IP address when contacting a remote host.
Definition: acl.c:1005
#define ast_log
Definition: astobj2.c:42
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
static char host[256]
Definition: muted.c:77
int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags)
Splits a string into its host and port components.
Definition: netsock2.c:164
General Asterisk PBX channel definitions.
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
Access Control of various sorts.
static int rtp_call(struct ast_channel *ast, const char *dest, int timeout)
Function called when we should actually call the destination.
Definition: chan_rtp.c:101
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static const struct ast_app_option unicast_rtp_options[128]
Definition: chan_rtp.c:266
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
static int rtp_write(struct ast_channel *ast, struct ast_frame *f)
Function called when we should write a frame to the channel.
Definition: chan_rtp.c:93
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:2906
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:629
Core PBX routines and definitions.
int ast_channel_fdno(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define AST_CAUSE_FAILURE
Definition: causes.h:149
#define LOG_ERROR
Definition: logger.h:285
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1080
static int load_module(void)
Function called when our module is loaded.
Definition: chan_rtp.c:419
struct ast_format_cap * capabilities
Definition: channel.h:633
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2192
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ast_frame * rtp_read(struct ast_channel *ast)
Function called when we should read a frame from the channel.
Definition: chan_rtp.c:79
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:643
Structure used to handle boolean flags.
Definition: utils.h:199
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_frame ast_null_frame
Definition: main/frame.c:79
static struct ast_channel_tech unicast_rtp_tech
Definition: chan_rtp.c:68
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_multicast_rtp_free_options(struct ast_multicast_rtp_options *mcast_options)
Free multicast RTP options.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define END_OPTIONS
static struct ast_channel * unicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
Function called when we should prepare to call the unicast destination.
Definition: chan_rtp.c:269
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
static struct test_options options
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
struct ast_rtp_instance * ast_rtp_instance_new(const char *engine_name, struct ast_sched_context *sched, const struct ast_sockaddr *sa, void *data)
Create a new RTP instance.
Definition: rtp_engine.c:465
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Pluggable RTP Architecture.
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1259
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
Asterisk module definitions.
static struct ast_channel * multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
Function called when we should prepare to call the multicast destination.
Definition: chan_rtp.c:139
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
Core DNS API.
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:578
Media Format Cache API.
#define AST_APP_ARG(name)
Define an application argument.