Asterisk - The Open Source Telephony Project  21.4.1
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 <jcolp@digium.com>
7  * Andreas 'MacBrody' Brodmann <andreas.brodmann@gmail.com>
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 <jcolp@digium.com>
23  * \author Andreas 'MacBrody' Brodmann <andreas.brodmann@gmail.com>
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 */
57 static struct ast_channel_tech multicast_rtp_tech = {
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 */
68 static struct ast_channel_tech unicast_rtp_tech = {
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 
117  ast_channel_tech_pvt_set(ast, NULL);
118 
119  return 0;
120 }
121 
122 static struct ast_format *derive_format_from_cap(struct ast_format_cap *cap)
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  ao2_ref(fmt, -1);
133  fmt = ao2_bump(ast_format_ulaw);
134  }
135 
136  return fmt;
137 }
138 
139 /*! \brief Function called when we should prepare to call the multicast destination */
140 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)
141 {
142  char *parse;
143  struct ast_rtp_instance *instance;
144  struct ast_sockaddr control_address;
145  struct ast_sockaddr destination_address;
146  struct ast_channel *chan;
147  struct ast_format_cap *caps = NULL;
148  struct ast_format *fmt = NULL;
150  AST_APP_ARG(type);
151  AST_APP_ARG(destination);
152  AST_APP_ARG(control);
153  AST_APP_ARG(options);
154  );
155  struct ast_multicast_rtp_options *mcast_options = NULL;
156 
157  if (ast_strlen_zero(data)) {
158  ast_log(LOG_ERROR, "A multicast type and destination must be given to the 'MulticastRTP' channel\n");
159  goto failure;
160  }
161  parse = ast_strdupa(data);
162  AST_NONSTANDARD_APP_ARGS(args, parse, '/');
163 
164  if (ast_strlen_zero(args.type)) {
165  ast_log(LOG_ERROR, "Type is required for the 'MulticastRTP' channel\n");
166  goto failure;
167  }
168 
169  if (ast_strlen_zero(args.destination)) {
170  ast_log(LOG_ERROR, "Destination is required for the 'MulticastRTP' channel\n");
171  goto failure;
172  }
173  if (!ast_sockaddr_parse(&destination_address, args.destination, PARSE_PORT_REQUIRE)) {
174  ast_log(LOG_ERROR, "Destination address '%s' could not be parsed\n",
175  args.destination);
176  goto failure;
177  }
178 
179  ast_sockaddr_setnull(&control_address);
180  if (!ast_strlen_zero(args.control)
181  && !ast_sockaddr_parse(&control_address, args.control, PARSE_PORT_REQUIRE)) {
182  ast_log(LOG_ERROR, "Control address '%s' could not be parsed\n", args.control);
183  goto failure;
184  }
185 
186  mcast_options = ast_multicast_rtp_create_options(args.type, args.options);
187  if (!mcast_options) {
188  goto failure;
189  }
190 
191  fmt = ast_multicast_rtp_options_get_format(mcast_options);
192  if (!fmt) {
193  fmt = derive_format_from_cap(cap);
194  }
195  if (!fmt) {
196  ast_log(LOG_ERROR, "No codec available for sending RTP to '%s'\n",
197  args.destination);
198  goto failure;
199  }
200 
202  if (!caps) {
203  goto failure;
204  }
205 
206  instance = ast_rtp_instance_new("multicast", NULL, &control_address, mcast_options);
207  if (!instance) {
208  ast_log(LOG_ERROR,
209  "Could not create '%s' multicast RTP instance for sending media to '%s'\n",
210  args.type, args.destination);
211  goto failure;
212  }
213 
214  chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", assignedids,
215  requestor, 0, "MulticastRTP/%s-%p", args.destination, instance);
216  if (!chan) {
217  ast_rtp_instance_destroy(instance);
218  goto failure;
219  }
220  ast_rtp_instance_set_channel_id(instance, ast_channel_uniqueid(chan));
221  ast_rtp_instance_set_remote_address(instance, &destination_address);
222 
223  ast_channel_tech_set(chan, &multicast_rtp_tech);
224 
225  ast_format_cap_append(caps, fmt, 0);
226  ast_channel_nativeformats_set(chan, caps);
227  ast_channel_set_writeformat(chan, fmt);
228  ast_channel_set_rawwriteformat(chan, fmt);
229  ast_channel_set_readformat(chan, fmt);
230  ast_channel_set_rawreadformat(chan, fmt);
231 
232  ast_channel_tech_pvt_set(chan, instance);
233 
234  ast_channel_unlock(chan);
235 
236  ao2_ref(fmt, -1);
237  ao2_ref(caps, -1);
238  ast_multicast_rtp_free_options(mcast_options);
239 
240  return chan;
241 
242 failure:
243  ao2_cleanup(fmt);
244  ao2_cleanup(caps);
245  ast_multicast_rtp_free_options(mcast_options);
246  *cause = AST_CAUSE_FAILURE;
247  return NULL;
248 }
249 
250 enum {
251  OPT_RTP_CODEC = (1 << 0),
252  OPT_RTP_ENGINE = (1 << 1),
253  OPT_RTP_GLUE = (1 << 2),
254 };
255 
256 enum {
257  OPT_ARG_RTP_CODEC,
258  OPT_ARG_RTP_ENGINE,
259  /* note: this entry _MUST_ be the last one in the enum */
260  OPT_ARG_ARRAY_SIZE
261 };
262 
263 AST_APP_OPTIONS(unicast_rtp_options, BEGIN_OPTIONS
264  /*! Set the codec to be used for unicast RTP */
265  AST_APP_OPTION_ARG('c', OPT_RTP_CODEC, OPT_ARG_RTP_CODEC),
266  /*! Set the RTP engine to use for unicast RTP */
267  AST_APP_OPTION_ARG('e', OPT_RTP_ENGINE, OPT_ARG_RTP_ENGINE),
268  /*! Provide RTP glue for the channel */
269  AST_APP_OPTION('g', OPT_RTP_GLUE),
270 END_OPTIONS );
271 
272 static const struct ast_datastore_info chan_rtp_datastore_info = {
273  .type = "CHAN_RTP_GLUE",
274 };
275 
276 /*! \brief Function called when we should prepare to call the unicast destination */
277 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)
278 {
279  char *parse;
280  struct ast_rtp_instance *instance;
281  struct ast_sockaddr address;
282  struct ast_sockaddr local_address;
283  struct ast_channel *chan;
284  struct ast_format_cap *caps = NULL;
285  struct ast_format *fmt = NULL;
286  const char *engine_name;
288  AST_APP_ARG(destination);
289  AST_APP_ARG(options);
290  );
291  struct ast_flags opts = { 0, };
292  char *opt_args[OPT_ARG_ARRAY_SIZE];
293 
294  if (ast_strlen_zero(data)) {
295  ast_log(LOG_ERROR, "Destination is required for the 'UnicastRTP' channel\n");
296  goto failure;
297  }
298  parse = ast_strdupa(data);
299  AST_NONSTANDARD_APP_ARGS(args, parse, '/');
300 
301  if (ast_strlen_zero(args.destination)) {
302  ast_log(LOG_ERROR, "Destination is required for the 'UnicastRTP' channel\n");
303  goto failure;
304  }
305 
306  if (!ast_sockaddr_parse(&address, args.destination, PARSE_PORT_REQUIRE)) {
307  int rc;
308  char *host;
309  char *port;
310 
311  rc = ast_sockaddr_split_hostport(args.destination, &host, &port, PARSE_PORT_REQUIRE);
312  if (!rc) {
313  ast_log(LOG_ERROR, "Unable to parse destination '%s' into host and port\n", args.destination);
314  goto failure;
315  }
316 
317  rc = ast_dns_resolve_ipv6_and_ipv4(&address, host, port);
318  if (rc != 0) {
319  ast_log(LOG_ERROR, "Unable to resolve host '%s'\n", host);
320  goto failure;
321  }
322  }
323 
324  if (!ast_strlen_zero(args.options)
325  && ast_app_parse_options(unicast_rtp_options, &opts, opt_args,
326  ast_strdupa(args.options))) {
327  ast_log(LOG_ERROR, "'UnicastRTP' channel options '%s' parse error\n",
328  args.options);
329  goto failure;
330  }
331 
332  if (ast_test_flag(&opts, OPT_RTP_CODEC)
333  && !ast_strlen_zero(opt_args[OPT_ARG_RTP_CODEC])) {
334  fmt = ast_format_cache_get(opt_args[OPT_ARG_RTP_CODEC]);
335  if (!fmt) {
336  ast_log(LOG_ERROR, "Codec '%s' not found for sending RTP to '%s'\n",
337  opt_args[OPT_ARG_RTP_CODEC], args.destination);
338  goto failure;
339  }
340  } else {
341  fmt = derive_format_from_cap(cap);
342  if (!fmt) {
343  ast_log(LOG_ERROR, "No codec available for sending RTP to '%s'\n",
344  args.destination);
345  goto failure;
346  }
347  }
348 
350  if (!caps) {
351  goto failure;
352  }
353 
354  engine_name = S_COR(ast_test_flag(&opts, OPT_RTP_ENGINE),
355  opt_args[OPT_ARG_RTP_ENGINE], "asterisk");
356 
357  ast_sockaddr_copy(&local_address, &address);
358  if (ast_ouraddrfor(&address, &local_address)) {
359  ast_log(LOG_ERROR, "Could not get our address for sending media to '%s'\n",
360  args.destination);
361  goto failure;
362  }
363  instance = ast_rtp_instance_new(engine_name, NULL, &local_address, NULL);
364  if (!instance) {
365  ast_log(LOG_ERROR,
366  "Could not create %s RTP instance for sending media to '%s'\n",
367  S_OR(engine_name, "default"), args.destination);
368  goto failure;
369  }
370 
371  chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", assignedids,
372  requestor, 0, "UnicastRTP/%s-%p", args.destination, instance);
373  if (!chan) {
374  ast_rtp_instance_destroy(instance);
375  goto failure;
376  }
377  ast_rtp_instance_set_channel_id(instance, ast_channel_uniqueid(chan));
378  ast_rtp_instance_set_remote_address(instance, &address);
379  ast_channel_set_fd(chan, 0, ast_rtp_instance_fd(instance, 0));
380 
381  ast_channel_tech_set(chan, &unicast_rtp_tech);
382 
383  if (ast_test_flag(&opts, OPT_RTP_GLUE)) {
384  struct ast_datastore *datastore;
385  if ((datastore = ast_datastore_alloc(&chan_rtp_datastore_info, NULL))) {
386  ast_channel_datastore_add(chan, datastore);
387  }
388  }
389 
390  ast_format_cap_append(caps, fmt, 0);
391  ast_channel_nativeformats_set(chan, caps);
392  ast_channel_set_writeformat(chan, fmt);
393  ast_channel_set_rawwriteformat(chan, fmt);
394  ast_channel_set_readformat(chan, fmt);
395  ast_channel_set_rawreadformat(chan, fmt);
396 
397  ast_channel_tech_pvt_set(chan, instance);
398 
399  ast_rtp_instance_get_local_address(instance, &local_address);
400  pbx_builtin_setvar_helper(chan, "UNICASTRTP_LOCAL_ADDRESS",
401  ast_sockaddr_stringify_addr(&local_address));
402  pbx_builtin_setvar_helper(chan, "UNICASTRTP_LOCAL_PORT",
403  ast_sockaddr_stringify_port(&local_address));
404 
405  ast_channel_unlock(chan);
406 
407  ao2_ref(fmt, -1);
408  ao2_ref(caps, -1);
409 
410  return chan;
411 
412 failure:
413  ao2_cleanup(fmt);
414  ao2_cleanup(caps);
415  *cause = AST_CAUSE_FAILURE;
416  return NULL;
417 }
418 
419 /*! \brief Function called by RTP engine to get peer capabilities */
420 static void chan_rtp_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
421 {
422  SCOPE_ENTER(1, "%s Native formats %s\n", ast_channel_name(chan),
423  ast_str_tmp(AST_FORMAT_CAP_NAMES_LEN, ast_format_cap_get_names(ast_channel_nativeformats(chan), &STR_TMP)));
424  ast_format_cap_append_from_cap(result, ast_channel_nativeformats(chan), AST_MEDIA_TYPE_UNKNOWN);
425  SCOPE_EXIT_RTN();
426 }
427 
428 /*! \brief Function called by RTP engine to change where the remote party should send media.
429  *
430  * chan_rtp is not able to actually update the peer, so this function has no effect.
431  * */
432 static int chan_rtp_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, const struct ast_format_cap *cap, int nat_active)
433 {
434  return -1;
435 }
436 
437 /*! \brief Function called by RTP engine to get local audio RTP peer */
438 static enum ast_rtp_glue_result chan_rtp_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
439 {
441 }
442 
443 /*! \brief Function called by RTP engine to get local audio RTP peer */
444 static enum ast_rtp_glue_result chan_rtp_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
445 {
446  struct ast_rtp_instance *rtp_instance = ast_channel_tech_pvt(chan);
447  struct ast_datastore *datastore;
448 
449  if (!rtp_instance) {
451  }
452 
453  if ((datastore = ast_channel_datastore_find(chan, &chan_rtp_datastore_info, NULL))) {
454  ao2_ref(datastore, -1);
455 
456  *instance = rtp_instance;
457  ao2_ref(*instance, +1);
458 
460  }
461 
463 }
464 
465 /*! \brief Local glue for interacting with the RTP engine core */
467  .type = "UnicastRTP",
468  .get_rtp_info = chan_rtp_get_rtp_peer,
469  .get_vrtp_info = chan_rtp_get_vrtp_peer,
470  .get_codec = chan_rtp_get_codec,
471  .update_peer = chan_rtp_set_rtp_peer,
472 };
473 
474 /*! \brief Function called when our module is unloaded */
475 static int unload_module(void)
476 {
477  ast_channel_unregister(&multicast_rtp_tech);
478  ao2_cleanup(multicast_rtp_tech.capabilities);
479  multicast_rtp_tech.capabilities = NULL;
480 
481  ast_channel_unregister(&unicast_rtp_tech);
482  ao2_cleanup(unicast_rtp_tech.capabilities);
483  unicast_rtp_tech.capabilities = NULL;
484 
485  ast_rtp_glue_unregister(&unicast_rtp_glue);
486 
487  return 0;
488 }
489 
490 /*! \brief Function called when our module is loaded */
491 static int load_module(void)
492 {
493  if (!(multicast_rtp_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
495  }
496 
497  ast_rtp_glue_register(&unicast_rtp_glue);
498 
499  ast_format_cap_append_by_type(multicast_rtp_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
500  if (ast_channel_register(&multicast_rtp_tech)) {
501  ast_log(LOG_ERROR, "Unable to register channel class 'MulticastRTP'\n");
502  unload_module();
504  }
505 
507  unload_module();
509  }
510  ast_format_cap_append_by_type(unicast_rtp_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
511  if (ast_channel_register(&unicast_rtp_tech)) {
512  ast_log(LOG_ERROR, "Unable to register channel class 'UnicastRTP'\n");
513  unload_module();
515  }
516 
518 }
519 
520 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "RTP Media Channel",
521  .support_level = AST_MODULE_SUPPORT_CORE,
522  .load = load_module,
523  .unload = unload_module,
524  .load_pri = AST_MODPRI_CHANNEL_DRIVER,
525  .requires = "res_rtp_multicast",
526 );
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:286
const char * type
Definition: datastore.h:32
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:2795
struct ast_multicast_rtp_options * ast_multicast_rtp_create_options(const char *type, const char *options)
Create multicast RTP options.
Main Channel structure associated with a channel.
Asterisk main include file. File version handling, generic pbx functions.
static enum ast_rtp_glue_result chan_rtp_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
Function called by RTP engine to get local audio RTP peer.
Definition: chan_rtp.c:444
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:575
static enum ast_rtp_glue_result chan_rtp_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
Function called by RTP engine to get local audio RTP peer.
Definition: chan_rtp.c:438
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
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:167
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
static int unload_module(void)
Function called when our module is unloaded.
Definition: chan_rtp.c:475
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:590
static int chan_rtp_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, const struct ast_format_cap *cap, int nat_active)
Function called by RTP engine to change where the remote party should send media. ...
Definition: chan_rtp.c:432
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:604
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
Structure for a data store type.
Definition: datastore.h:31
Definition of a media format.
Definition: format.c:43
void ast_multicast_rtp_free_options(struct ast_multicast_rtp_options *mcast_options)
Free multicast RTP options.
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
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
Structure for a data store object.
Definition: datastore.h:64
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
const char * data
Socket address structure.
Definition: netsock2.h:97
const char * type
Definition: rtp_engine.h:775
#define ast_format_cache_get(name)
Retrieve a named format from the cache.
Definition: format_cache.h:278
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:138
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
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:358
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
Definition: strings.h:1189
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:1004
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.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
Access Control of various sorts.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
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 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:87
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
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
ast_rtp_glue_result
Definition: rtp_engine.h:161
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
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:3066
static struct ast_rtp_glue unicast_rtp_glue
Local glue for interacting with the RTP engine core.
Definition: chan_rtp.c:466
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:628
Core PBX routines and definitions.
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 'nonstandard' 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:1133
static int load_module(void)
Function called when our module is loaded.
Definition: chan_rtp.c:491
struct ast_format * ast_multicast_rtp_options_get_format(struct ast_multicast_rtp_options *mcast_options)
Get format specified in multicast options.
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:734
struct ast_format_cap * capabilities
Definition: channel.h:632
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:2316
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:665
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:2426
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 void chan_rtp_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
Function called by RTP engine to get peer capabilities.
Definition: chan_rtp.c:420
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition: rtp_engine.c:408
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:277
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
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
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
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:487
#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:1258
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:140
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application'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:600
Media Format Cache API.
#define AST_APP_ARG(name)
Define an application argument.