Asterisk - The Open Source Telephony Project GIT-master-f36a736
Data Structures | Macros | Enumerations | Functions | Variables
res_rtp_multicast.c File Reference

Multicast RTP Engine. More...

#include "asterisk.h"
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#include <math.h>
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/acl.h"
#include "asterisk/config.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/cli.h"
#include "asterisk/manager.h"
#include "asterisk/unaligned.h"
#include "asterisk/module.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/format_cache.h"
#include "asterisk/multicast_rtp.h"
#include "asterisk/app.h"
#include "asterisk/smoother.h"
Include dependency graph for res_rtp_multicast.c:

Go to the source code of this file.

Data Structures

struct  ast_multicast_rtp_options
 
struct  multicast_control_packet
 Structure for a Linksys control packet. More...
 
struct  multicast_rtp
 Structure for a multicast paging instance. More...
 

Macros

#define LINKSYS_MCAST_STARTCMD   6
 
#define LINKSYS_MCAST_STOPCMD   7
 
#define MAX_TIMESTAMP_SKEW   640
 

Enumerations

enum  { OPT_CODEC = (1 << 0) , OPT_LOOP = (1 << 1) , OPT_TTL = (1 << 2) , OPT_IF = (1 << 3) }
 
enum  {
  OPT_ARG_CODEC = 0 , OPT_ARG_LOOP , OPT_ARG_TTL , OPT_ARG_IF ,
  OPT_ARG_ARRAY_SIZE
}
 
enum  multicast_type { MULTICAST_TYPE_UNSPECIFIED = 0 , MULTICAST_TYPE_BASIC , MULTICAST_TYPE_LINKSYS }
 Type of paging to do. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
struct ast_multicast_rtp_optionsast_multicast_rtp_create_options (const char *type, const char *options)
 Create multicast RTP options. More...
 
void ast_multicast_rtp_free_options (struct ast_multicast_rtp_options *mcast_options)
 Free multicast RTP options. More...
 
struct ast_formatast_multicast_rtp_options_get_format (struct ast_multicast_rtp_options *mcast_options)
 Get format specified in multicast options. More...
 
static unsigned int calc_txstamp (struct multicast_rtp *rtp, struct timeval *delivery)
 
static int load_module (void)
 
static int multicast_rtp_activate (struct ast_rtp_instance *instance)
 Function called to indicate that audio is now going to flow. More...
 
static int multicast_rtp_destroy (struct ast_rtp_instance *instance)
 Function called to destroy a multicast instance. More...
 
static int multicast_rtp_new (struct ast_rtp_instance *instance, struct ast_sched_context *sched, struct ast_sockaddr *addr, void *data)
 Function called to create a new multicast instance. More...
 
static struct ast_framemulticast_rtp_read (struct ast_rtp_instance *instance, int rtcp)
 Function called to read from a multicast instance. More...
 
static int multicast_rtp_write (struct ast_rtp_instance *instance, struct ast_frame *frame)
 Function called to broadcast some audio on a multicast instance. More...
 
static int multicast_send_control_packet (struct ast_rtp_instance *instance, struct multicast_rtp *multicast, int command)
 Helper function which populates a control packet with useful information and sends it. More...
 
static int rtp_get_rate (struct ast_format *format)
 
static int rtp_raw_write (struct ast_rtp_instance *instance, struct ast_frame *frame, int codec)
 
static void set_if (int sock, const char *if_str)
 
static void set_loop (int sock, const char *loop_str)
 
static void set_ttl (int sock, const char *ttl_str)
 
static int set_type (struct multicast_rtp *multicast, const char *type)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Multicast RTP Engine" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_rtp_engine multicast_rtp_engine
 
static const struct ast_app_option multicast_rtp_options [128] = { [ 'c' ] = { .flag = OPT_CODEC , .arg_index = OPT_ARG_CODEC + 1 }, [ 'l' ] = { .flag = OPT_LOOP , .arg_index = OPT_ARG_LOOP + 1 }, [ 't' ] = { .flag = OPT_TTL , .arg_index = OPT_ARG_TTL + 1 }, [ 'i' ] = { .flag = OPT_IF , .arg_index = OPT_ARG_IF + 1 }, }
 

Detailed Description

Multicast RTP Engine.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om
Andreas 'MacBrody' Brodmann andre.nosp@m.as.b.nosp@m.rodma.nosp@m.nn@g.nosp@m.mail..nosp@m.com

Definition in file res_rtp_multicast.c.

Macro Definition Documentation

◆ LINKSYS_MCAST_STARTCMD

#define LINKSYS_MCAST_STARTCMD   6

Command value used for Linksys paging to indicate we are starting

Definition at line 60 of file res_rtp_multicast.c.

◆ LINKSYS_MCAST_STOPCMD

#define LINKSYS_MCAST_STOPCMD   7

Command value used for Linksys paging to indicate we are stopping

Definition at line 63 of file res_rtp_multicast.c.

◆ MAX_TIMESTAMP_SKEW

#define MAX_TIMESTAMP_SKEW   640

Definition at line 102 of file res_rtp_multicast.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
OPT_CODEC 
OPT_LOOP 
OPT_TTL 
OPT_IF 

Definition at line 104 of file res_rtp_multicast.c.

104 {
105 OPT_CODEC = (1 << 0),
106 OPT_LOOP = (1 << 1),
107 OPT_TTL = (1 << 2),
108 OPT_IF = (1 << 3),
109};
@ OPT_TTL
@ OPT_IF
@ OPT_CODEC
@ OPT_LOOP

◆ anonymous enum

anonymous enum
Enumerator
OPT_ARG_CODEC 
OPT_ARG_LOOP 
OPT_ARG_TTL 
OPT_ARG_IF 
OPT_ARG_ARRAY_SIZE 

Definition at line 111 of file res_rtp_multicast.c.

111 {
112 OPT_ARG_CODEC = 0,
117};
@ OPT_ARG_TTL
@ OPT_ARG_CODEC
@ OPT_ARG_IF
@ OPT_ARG_ARRAY_SIZE
@ OPT_ARG_LOOP

◆ multicast_type

Type of paging to do.

Enumerator
MULTICAST_TYPE_UNSPECIFIED 

Type has not been set yet

MULTICAST_TYPE_BASIC 

Simple multicast enabled client/receiver paging like Snom and Barix uses

MULTICAST_TYPE_LINKSYS 

More advanced Linksys type paging which requires a start and stop packet

Definition at line 66 of file res_rtp_multicast.c.

66 {
67 /*! Type has not been set yet */
69 /*! Simple multicast enabled client/receiver paging like Snom and Barix uses */
71 /*! More advanced Linksys type paging which requires a start and stop packet */
73};
@ MULTICAST_TYPE_BASIC
@ MULTICAST_TYPE_LINKSYS
@ MULTICAST_TYPE_UNSPECIFIED

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 567 of file res_rtp_multicast.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 567 of file res_rtp_multicast.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 567 of file res_rtp_multicast.c.

◆ ast_multicast_rtp_create_options()

struct ast_multicast_rtp_options * ast_multicast_rtp_create_options ( const char *  type,
const char *  options 
)

Create multicast RTP options.

These are passed to the multicast RTP engine on its creation.

Parameters
typeThe type of multicast RTP, either "basic" or "linksys"
optionsMiscellaneous options
Return values
NULLFailure
non-NULLsuccess

Definition at line 140 of file res_rtp_multicast.c.

142{
143 struct ast_multicast_rtp_options *mcast_options;
144 char *pos;
145
146 mcast_options = ast_calloc(1, sizeof(*mcast_options)
147 + strlen(type)
148 + strlen(S_OR(options, "")) + 2);
149 if (!mcast_options) {
150 return NULL;
151 }
152
153 pos = mcast_options->buf;
154
155 /* Safe */
156 strcpy(pos, type);
157 mcast_options->type = pos;
158 pos += strlen(type) + 1;
159
160 if (!ast_strlen_zero(options)) {
161 strcpy(pos, options); /* Safe */
162 }
163 mcast_options->options = pos;
164
166 mcast_options->opt_args, mcast_options->options)) {
167 ast_log(LOG_WARNING, "Error parsing multicast RTP options\n");
168 ast_multicast_rtp_free_options(mcast_options);
169 return NULL;
170 }
171
172 return mcast_options;
173}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
static const char type[]
Definition: chan_ooh323.c:109
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
#define LOG_WARNING
static const struct ast_app_option multicast_rtp_options[128]
void ast_multicast_rtp_free_options(struct ast_multicast_rtp_options *mcast_options)
Free multicast RTP options.
#define NULL
Definition: resample.c:96
#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
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
char * opt_args[OPT_ARG_ARRAY_SIZE]
static struct test_options options

References ast_app_parse_options(), ast_calloc, ast_log, ast_multicast_rtp_free_options(), ast_strlen_zero(), ast_multicast_rtp_options::buf, LOG_WARNING, multicast_rtp_options, NULL, ast_multicast_rtp_options::opt_args, ast_multicast_rtp_options::options, options, ast_multicast_rtp_options::opts, S_OR, type, and ast_multicast_rtp_options::type.

Referenced by multicast_rtp_request().

◆ ast_multicast_rtp_free_options()

void ast_multicast_rtp_free_options ( struct ast_multicast_rtp_options mcast_options)

Free multicast RTP options.

This function is NULL-tolerant

Parameters
mcast_optionsOptions to free

Definition at line 175 of file res_rtp_multicast.c.

176{
177 ast_free(mcast_options);
178}
#define ast_free(a)
Definition: astmm.h:180

References ast_free.

Referenced by ast_multicast_rtp_create_options(), and multicast_rtp_request().

◆ ast_multicast_rtp_options_get_format()

struct ast_format * ast_multicast_rtp_options_get_format ( struct ast_multicast_rtp_options mcast_options)

Get format specified in multicast options.

Multicast options allow for a format to be selected. This function accesses the selected format and creates an ast_format structure for it.

Parameters
mcast_optionsThe options where a codec was specified
Return values
NULLNo format specified in the options
non-NULLThe format to use for communication

Definition at line 180 of file res_rtp_multicast.c.

181{
182 if (ast_test_flag(&mcast_options->opts, OPT_CODEC)
183 && !ast_strlen_zero(mcast_options->opt_args[OPT_ARG_CODEC])) {
184 return ast_format_cache_get(mcast_options->opt_args[OPT_ARG_CODEC]);
185 }
186
187 return NULL;
188}
#define ast_format_cache_get(name)
Retrieve a named format from the cache.
Definition: format_cache.h:278
#define ast_test_flag(p, flag)
Definition: utils.h:63

References ast_format_cache_get, ast_strlen_zero(), ast_test_flag, NULL, OPT_ARG_CODEC, ast_multicast_rtp_options::opt_args, OPT_CODEC, and ast_multicast_rtp_options::opts.

Referenced by multicast_rtp_request().

◆ calc_txstamp()

static unsigned int calc_txstamp ( struct multicast_rtp rtp,
struct timeval *  delivery 
)
static

Definition at line 328 of file res_rtp_multicast.c.

329{
330 struct timeval t;
331 long ms;
332
333 if (ast_tvzero(rtp->txcore)) {
334 rtp->txcore = ast_tvnow();
335 rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
336 }
337
338 t = (delivery && !ast_tvzero(*delivery)) ? *delivery : ast_tvnow();
339 if ((ms = ast_tvdiff_ms(t, rtp->txcore)) < 0) {
340 ms = 0;
341 }
342 rtp->txcore = t;
343
344 return (unsigned int) ms;
345}
struct timeval txcore
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and multicast_rtp::txcore.

Referenced by rtp_raw_write().

◆ load_module()

static int load_module ( void  )
static

Definition at line 546 of file res_rtp_multicast.c.

547{
550 }
551
553}
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ast_rtp_engine multicast_rtp_engine
#define ast_rtp_engine_register(engine)
Definition: rtp_engine.h:852

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_rtp_engine_register, and multicast_rtp_engine.

◆ multicast_rtp_activate()

static int multicast_rtp_activate ( struct ast_rtp_instance instance)
static

Function called to indicate that audio is now going to flow.

Definition at line 382 of file res_rtp_multicast.c.

383{
384 struct multicast_rtp *multicast = ast_rtp_instance_get_data(instance);
385
386 if (multicast->type != MULTICAST_TYPE_LINKSYS) {
387 return 0;
388 }
389
390 return multicast_send_control_packet(instance, multicast, LINKSYS_MCAST_STARTCMD);
391}
static int multicast_send_control_packet(struct ast_rtp_instance *instance, struct multicast_rtp *multicast, int command)
Helper function which populates a control packet with useful information and sends it.
#define LINKSYS_MCAST_STARTCMD
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:585
Structure for a multicast paging instance.
enum multicast_type type

References ast_rtp_instance_get_data(), LINKSYS_MCAST_STARTCMD, multicast_send_control_packet(), MULTICAST_TYPE_LINKSYS, and multicast_rtp::type.

◆ multicast_rtp_destroy()

static int multicast_rtp_destroy ( struct ast_rtp_instance instance)
static

Function called to destroy a multicast instance.

Definition at line 394 of file res_rtp_multicast.c.

395{
396 struct multicast_rtp *multicast = ast_rtp_instance_get_data(instance);
397
398 if (multicast->type == MULTICAST_TYPE_LINKSYS) {
400 }
401
402 if (multicast->smoother) {
403 ast_smoother_free(multicast->smoother);
404 }
405
406 close(multicast->socket);
407
408 ast_free(multicast);
409
410 return 0;
411}
#define LINKSYS_MCAST_STOPCMD
void ast_smoother_free(struct ast_smoother *s)
Definition: smoother.c:220
struct ast_smoother * smoother

References ast_free, ast_rtp_instance_get_data(), ast_smoother_free(), LINKSYS_MCAST_STOPCMD, multicast_send_control_packet(), MULTICAST_TYPE_LINKSYS, multicast_rtp::smoother, multicast_rtp::socket, and multicast_rtp::type.

◆ multicast_rtp_new()

static int multicast_rtp_new ( struct ast_rtp_instance instance,
struct ast_sched_context sched,
struct ast_sockaddr addr,
void *  data 
)
static

Function called to create a new multicast instance.

Definition at line 284 of file res_rtp_multicast.c.

285{
286 struct multicast_rtp *multicast;
287 struct ast_multicast_rtp_options *mcast_options = data;
288
289 if (!(multicast = ast_calloc(1, sizeof(*multicast)))) {
290 return -1;
291 }
292
293 if (set_type(multicast, mcast_options->type)) {
294 ast_free(multicast);
295 return -1;
296 }
297
298 if ((multicast->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
299 ast_free(multicast);
300 return -1;
301 }
302
303 if (ast_test_flag(&mcast_options->opts, OPT_LOOP)) {
304 set_loop(multicast->socket, mcast_options->opt_args[OPT_ARG_LOOP]);
305 }
306
307 if (ast_test_flag(&mcast_options->opts, OPT_TTL)) {
308 set_ttl(multicast->socket, mcast_options->opt_args[OPT_ARG_TTL]);
309 }
310
311 if (ast_test_flag(&mcast_options->opts, OPT_IF)) {
312 set_if(multicast->socket, mcast_options->opt_args[OPT_ARG_IF]);
313 }
314
315 multicast->ssrc = ast_random();
316
317 ast_rtp_instance_set_data(instance, multicast);
318
319 return 0;
320}
static void set_ttl(int sock, const char *ttl_str)
static int set_type(struct multicast_rtp *multicast, const char *type)
static void set_if(int sock, const char *if_str)
static void set_loop(int sock, const char *loop_str)
void ast_rtp_instance_set_data(struct ast_rtp_instance *instance, void *data)
Set the data portion of an RTP instance.
Definition: rtp_engine.c:580
unsigned int ssrc
long int ast_random(void)
Definition: utils.c:2312

References ast_calloc, ast_free, ast_random(), ast_rtp_instance_set_data(), ast_test_flag, OPT_ARG_IF, OPT_ARG_LOOP, OPT_ARG_TTL, ast_multicast_rtp_options::opt_args, OPT_IF, OPT_LOOP, OPT_TTL, ast_multicast_rtp_options::opts, set_if(), set_loop(), set_ttl(), set_type(), multicast_rtp::socket, multicast_rtp::ssrc, and ast_multicast_rtp_options::type.

◆ multicast_rtp_read()

static struct ast_frame * multicast_rtp_read ( struct ast_rtp_instance instance,
int  rtcp 
)
static

Function called to read from a multicast instance.

Definition at line 541 of file res_rtp_multicast.c.

542{
543 return &ast_null_frame;
544}
struct ast_frame ast_null_frame
Definition: main/frame.c:79

References ast_null_frame.

◆ multicast_rtp_write()

static int multicast_rtp_write ( struct ast_rtp_instance instance,
struct ast_frame frame 
)
static

Function called to broadcast some audio on a multicast instance.

Definition at line 469 of file res_rtp_multicast.c.

470{
471 struct multicast_rtp *multicast = ast_rtp_instance_get_data(instance);
472 struct ast_format *format;
473 struct ast_frame *f;
474 int codec;
475
476 /* We only accept audio, nothing else */
477 if (frame->frametype != AST_FRAME_VOICE) {
478 return 0;
479 }
480
481 /* Grab the actual payload number for when we create the RTP packet */
483 1, frame->subclass.format, 0);
484 if (codec < 0) {
485 return -1;
486 }
487
488 format = frame->subclass.format;
489 if (!multicast->smoother && ast_format_can_be_smoothed(format)) {
490 unsigned int smoother_flags = ast_format_get_smoother_flags(format);
491 unsigned int framing_ms = ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(instance));
492
493 if (!framing_ms && (smoother_flags & AST_SMOOTHER_FLAG_FORCED)) {
494 framing_ms = ast_format_get_default_ms(format);
495 }
496
497 if (framing_ms) {
498 multicast->smoother = ast_smoother_new((framing_ms * ast_format_get_minimum_bytes(format)) / ast_format_get_minimum_ms(format));
499 if (!multicast->smoother) {
500 ast_log(LOG_WARNING, "Unable to create smoother: format %s ms: %u len %u\n",
501 ast_format_get_name(format), framing_ms, ast_format_get_minimum_bytes(format));
502 return -1;
503 }
504 ast_smoother_set_flags(multicast->smoother, smoother_flags);
505 }
506 }
507
508 if (multicast->smoother) {
510 ast_smoother_feed_be(multicast->smoother, frame);
511 } else {
512 ast_smoother_feed(multicast->smoother, frame);
513 }
514
515 while ((f = ast_smoother_read(multicast->smoother)) && f->data.ptr) {
516 rtp_raw_write(instance, f, codec);
517 }
518 } else {
519 int hdrlen = 12;
520
521 /* If we do not have space to construct an RTP header duplicate the frame so we get some */
522 if (frame->offset < hdrlen) {
523 f = ast_frdup(frame);
524 } else {
525 f = frame;
526 }
527
528 if (f->data.ptr) {
529 rtp_raw_write(instance, f, codec);
530 }
531
532 if (f != frame) {
533 ast_frfree(f);
534 }
535 }
536
537 return 0;
538}
int ast_format_get_smoother_flags(const struct ast_format *format)
Get smoother flags for this format.
Definition: format.c:349
int ast_format_can_be_smoothed(const struct ast_format *format)
Get whether or not the format can be smoothed.
Definition: format.c:344
unsigned int ast_format_get_minimum_bytes(const struct ast_format *format)
Get the minimum number of bytes expected in a frame for this format.
Definition: format.c:374
unsigned int ast_format_get_minimum_ms(const struct ast_format *format)
Get the minimum amount of media carried in this format.
Definition: format.c:364
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
unsigned int ast_format_get_default_ms(const struct ast_format *format)
Get the default framing size (in milliseconds) for a format.
Definition: format.c:359
#define ast_frdup(fr)
Copies a frame.
#define ast_frfree(fr)
@ AST_FRAME_VOICE
static int rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame *frame, int codec)
int ast_rtp_codecs_payload_code_tx(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code)
Retrieve a tx mapped payload type based on whether it is an Asterisk format and the code.
Definition: rtp_engine.c:2146
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:749
unsigned int ast_rtp_codecs_get_framing(struct ast_rtp_codecs *codecs)
Get the framing used for a set of codecs.
Definition: rtp_engine.c:1682
void ast_smoother_set_flags(struct ast_smoother *smoother, int flags)
Definition: smoother.c:123
#define ast_smoother_feed_be(s, f)
Definition: smoother.h:80
int ast_smoother_test_flag(struct ast_smoother *s, int flag)
Definition: smoother.c:128
#define AST_SMOOTHER_FLAG_FORCED
Definition: smoother.h:36
struct ast_frame * ast_smoother_read(struct ast_smoother *s)
Definition: smoother.c:169
#define ast_smoother_feed(s, f)
Definition: smoother.h:75
struct ast_smoother * ast_smoother_new(int bytes)
Definition: smoother.c:108
#define AST_SMOOTHER_FLAG_BE
Definition: smoother.h:35
Definition of a media format.
Definition: format.c:43
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
enum ast_frame_type frametype

References ast_format_can_be_smoothed(), ast_format_get_default_ms(), ast_format_get_minimum_bytes(), ast_format_get_minimum_ms(), ast_format_get_name(), ast_format_get_smoother_flags(), AST_FRAME_VOICE, ast_frdup, ast_frfree, ast_log, ast_rtp_codecs_get_framing(), ast_rtp_codecs_payload_code_tx(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_data(), ast_smoother_feed, ast_smoother_feed_be, AST_SMOOTHER_FLAG_BE, AST_SMOOTHER_FLAG_FORCED, ast_smoother_new(), ast_smoother_read(), ast_smoother_set_flags(), ast_smoother_test_flag(), ast_frame::data, ast_frame_subclass::format, ast_frame::frametype, LOG_WARNING, ast_frame::offset, ast_frame::ptr, rtp_raw_write(), multicast_rtp::smoother, and ast_frame::subclass.

◆ multicast_send_control_packet()

static int multicast_send_control_packet ( struct ast_rtp_instance instance,
struct multicast_rtp multicast,
int  command 
)
static

Helper function which populates a control packet with useful information and sends it.

Definition at line 348 of file res_rtp_multicast.c.

349{
350 struct multicast_control_packet control_packet = { .unique_id = htonl((u_long)time(NULL)),
351 .command = htonl(command),
352 };
353 struct ast_sockaddr control_address, remote_address;
354
355 ast_rtp_instance_get_local_address(instance, &control_address);
356 ast_rtp_instance_get_remote_address(instance, &remote_address);
357
358 /* Ensure the user of us have given us both the control address and destination address */
359 if (ast_sockaddr_isnull(&control_address) ||
360 ast_sockaddr_isnull(&remote_address)) {
361 return -1;
362 }
363
364 /* The protocol only supports IPv4. */
365 if (ast_sockaddr_is_ipv6(&remote_address)) {
366 ast_log(LOG_WARNING, "Cannot send control packet for IPv6 "
367 "remote address.\n");
368 return -1;
369 }
370
371 control_packet.ip = htonl(ast_sockaddr_ipv4(&remote_address));
372 control_packet.port = htonl(ast_sockaddr_port(&remote_address));
373
374 /* Based on a recommendation by Brian West who did the FreeSWITCH implementation we send control packets twice */
375 ast_sendto(multicast->socket, &control_packet, sizeof(control_packet), 0, &control_address);
376 ast_sendto(multicast->socket, &control_packet, sizeof(control_packet), 0, &control_address);
377
378 return 0;
379}
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
uint32_t ast_sockaddr_ipv4(const struct ast_sockaddr *addr)
Get an IPv4 address of an ast_sockaddr.
Definition: netsock2.c:491
ssize_t ast_sendto(int sockfd, const void *buf, size_t len, int flags, const struct ast_sockaddr *dest_addr)
Wrapper around sendto(2) that uses ast_sockaddr.
Definition: netsock2.c:614
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition: netsock2.h:127
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1250
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
Socket address structure.
Definition: netsock2.h:97
Structure for a Linksys control packet.

References ast_log, ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address, ast_sendto(), ast_sockaddr_ipv4(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, multicast_control_packet::command, multicast_control_packet::ip, LOG_WARNING, NULL, multicast_control_packet::port, multicast_rtp::socket, and multicast_control_packet::unique_id.

Referenced by multicast_rtp_activate(), and multicast_rtp_destroy().

◆ rtp_get_rate()

static int rtp_get_rate ( struct ast_format format)
static

Definition at line 322 of file res_rtp_multicast.c.

323{
325 8000 : ast_format_get_sample_rate(format);
326}
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition: format.h:36
struct ast_format * ast_format_g722
Built-in cached g722 format.
Definition: format_cache.c:106

References ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_g722, and ast_format_get_sample_rate().

Referenced by rtp_raw_write().

◆ rtp_raw_write()

static int rtp_raw_write ( struct ast_rtp_instance instance,
struct ast_frame frame,
int  codec 
)
static

Definition at line 413 of file res_rtp_multicast.c.

414{
415 struct multicast_rtp *multicast = ast_rtp_instance_get_data(instance);
416 unsigned int ms = calc_txstamp(multicast, &frame->delivery);
417 unsigned char *rtpheader;
418 struct ast_sockaddr remote_address = { {0,} };
419 int rate = rtp_get_rate(frame->subclass.format) / 1000;
420 int hdrlen = 12, mark = 0;
421
423 frame->samples /= 2;
424 }
425
427 multicast->lastts = frame->ts * rate;
428 } else {
429 /* Try to predict what our timestamp should be */
430 int pred = multicast->lastts + frame->samples;
431
432 /* Calculate last TS */
433 multicast->lastts = multicast->lastts + ms * rate;
434 if (ast_tvzero(frame->delivery)) {
435 int delta = abs((int) multicast->lastts - pred);
436 if (delta < MAX_TIMESTAMP_SKEW) {
437 multicast->lastts = pred;
438 } else {
439 ast_debug(3, "Difference is %d, ms is %u\n", delta, ms);
440 mark = 1;
441 }
442 }
443 }
444
445 /* Construct an RTP header for our packet */
446 rtpheader = (unsigned char *)(frame->data.ptr - hdrlen);
447
448 put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (multicast->seqno) | (mark << 23)));
449 put_unaligned_uint32(rtpheader + 4, htonl(multicast->lastts));
450 put_unaligned_uint32(rtpheader + 8, htonl(multicast->ssrc));
451
452 /* Increment sequence number and wrap to 0 if it overflows 16 bits. */
453 multicast->seqno = 0xFFFF & (multicast->seqno + 1);
454
455 /* Finally send it out to the eager phones listening for us */
456 ast_rtp_instance_get_remote_address(instance, &remote_address);
457
458 if (ast_sendto(multicast->socket, (void *) rtpheader, frame->datalen + hdrlen, 0, &remote_address) < 0) {
459 ast_log(LOG_ERROR, "Multicast RTP Transmission error to %s: %s\n",
460 ast_sockaddr_stringify(&remote_address),
461 strerror(errno));
462 return -1;
463 }
464
465 return 0;
466}
#define abs(x)
Definition: f2c.h:195
@ AST_FRFLAG_HAS_TIMING_INFO
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
int errno
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
#define MAX_TIMESTAMP_SKEW
static unsigned int calc_txstamp(struct multicast_rtp *rtp, struct timeval *delivery)
static int rtp_get_rate(struct ast_format *format)
struct timeval delivery
unsigned int lastts
static void put_unaligned_uint32(void *p, unsigned int datum)
Definition: unaligned.h:58

References abs, ast_debug, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_g722, AST_FRFLAG_HAS_TIMING_INFO, ast_log, ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_sendto(), ast_sockaddr_stringify(), ast_test_flag, ast_tvzero(), calc_txstamp(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, errno, ast_frame_subclass::format, multicast_rtp::lastts, LOG_ERROR, MAX_TIMESTAMP_SKEW, ast_frame::ptr, put_unaligned_uint32(), rtp_get_rate(), ast_frame::samples, multicast_rtp::seqno, multicast_rtp::socket, multicast_rtp::ssrc, ast_frame::subclass, and ast_frame::ts.

Referenced by multicast_rtp_write().

◆ set_if()

static void set_if ( int  sock,
const char *  if_str 
)
static

Definition at line 263 of file res_rtp_multicast.c.

264{
265 struct in_addr iface;
266
267 if (ast_strlen_zero(if_str)) {
268 return;
269 }
270
271 ast_debug(3, "Setting multicast if to %s\n", if_str);
272
273 if (!inet_aton(if_str, &iface)) {
274 ast_log(LOG_WARNING, "Cannot parse if option '%s'\n", if_str);
275 }
276
277 if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &iface, sizeof(iface)) < 0) {
278 ast_log(LOG_WARNING, "Could not set multicast if to '%s': %s\n",
279 if_str, strerror(errno));
280 }
281}
int inet_aton(const char *cp, struct in_addr *pin)

References ast_debug, ast_log, ast_strlen_zero(), errno, inet_aton(), and LOG_WARNING.

Referenced by multicast_rtp_new().

◆ set_loop()

static void set_loop ( int  sock,
const char *  loop_str 
)
static

Definition at line 242 of file res_rtp_multicast.c.

243{
244 unsigned char loop;
245
246 if (ast_strlen_zero(loop_str)) {
247 return;
248 }
249
250 ast_debug(3, "Setting multicast loop to %s\n", loop_str);
251
252 if (sscanf(loop_str, "%30hhu", &loop) < 1) {
253 ast_log(LOG_WARNING, "Invalid multicast loop option '%s'\n", loop_str);
254 return;
255 }
256
257 if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) {
258 ast_log(LOG_WARNING, "Could not set multicast loop to '%s': %s\n",
259 loop_str, strerror(errno));
260 }
261}

References ast_debug, ast_log, ast_strlen_zero(), errno, and LOG_WARNING.

Referenced by multicast_rtp_new().

◆ set_ttl()

static void set_ttl ( int  sock,
const char *  ttl_str 
)
static

Definition at line 221 of file res_rtp_multicast.c.

222{
223 int ttl;
224
225 if (ast_strlen_zero(ttl_str)) {
226 return;
227 }
228
229 ast_debug(3, "Setting multicast TTL to %s\n", ttl_str);
230
231 if (sscanf(ttl_str, "%30d", &ttl) < 1) {
232 ast_log(LOG_WARNING, "Invalid multicast ttl option '%s'\n", ttl_str);
233 return;
234 }
235
236 if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) {
237 ast_log(LOG_WARNING, "Could not set multicast ttl to '%s': %s\n",
238 ttl_str, strerror(errno));
239 }
240}

References ast_debug, ast_log, ast_strlen_zero(), errno, and LOG_WARNING.

Referenced by multicast_rtp_new().

◆ set_type()

static int set_type ( struct multicast_rtp multicast,
const char *  type 
)
static

Definition at line 207 of file res_rtp_multicast.c.

208{
209 if (!strcasecmp(type, "basic")) {
210 multicast->type = MULTICAST_TYPE_BASIC;
211 } else if (!strcasecmp(type, "linksys")) {
212 multicast->type = MULTICAST_TYPE_LINKSYS;
213 } else {
214 ast_log(LOG_WARNING, "Unrecognized multicast type '%s' specified.\n", type);
215 return -1;
216 }
217
218 return 0;
219}

References ast_log, LOG_WARNING, MULTICAST_TYPE_BASIC, MULTICAST_TYPE_LINKSYS, type, and multicast_rtp::type.

Referenced by multicast_rtp_new().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 555 of file res_rtp_multicast.c.

556{
558
559 return 0;
560}
int ast_rtp_engine_unregister(struct ast_rtp_engine *engine)
Unregister an RTP engine.
Definition: rtp_engine.c:364

References ast_rtp_engine_unregister(), and multicast_rtp_engine.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Multicast RTP Engine" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
static

Definition at line 567 of file res_rtp_multicast.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 567 of file res_rtp_multicast.c.

◆ multicast_rtp_engine

struct ast_rtp_engine multicast_rtp_engine
static

Definition at line 198 of file res_rtp_multicast.c.

Referenced by load_module(), and unload_module().

◆ multicast_rtp_options

const struct ast_app_option multicast_rtp_options[128] = { [ 'c' ] = { .flag = OPT_CODEC , .arg_index = OPT_ARG_CODEC + 1 }, [ 'l' ] = { .flag = OPT_LOOP , .arg_index = OPT_ARG_LOOP + 1 }, [ 't' ] = { .flag = OPT_TTL , .arg_index = OPT_ARG_TTL + 1 }, [ 'i' ] = { .flag = OPT_IF , .arg_index = OPT_ARG_IF + 1 }, }
static

Set the codec to be used for multicast RTP

Set whether multicast RTP is looped back to the sender

Set the hop count for multicast RTP

Set the interface from which multicast RTP is sent

Definition at line 128 of file res_rtp_multicast.c.

Referenced by ast_multicast_rtp_create_options().