Tue Aug 20 16:35:14 2013

Asterisk developer's documentation


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"

Go to the source code of this file.

Data Structures

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

Defines

#define LINKSYS_MCAST_STARTCMD   6
#define LINKSYS_MCAST_STOPCMD   7

Enumerations

enum  multicast_type { MULTICAST_TYPE_BASIC = 0, MULTICAST_TYPE_LINKSYS }
 

Type of paging to do.

More...

Functions

static void __reg_module (void)
static void __unreg_module (void)
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.
static int multicast_rtp_destroy (struct ast_rtp_instance *instance)
 Function called to destroy a multicast instance.
static int multicast_rtp_new (struct ast_rtp_instance *instance, struct sched_context *sched, struct ast_sockaddr *addr, void *data)
 Function called to create a new multicast instance.
static struct ast_framemulticast_rtp_read (struct ast_rtp_instance *instance, int rtcp)
 Function called to read from a multicast instance.
static int multicast_rtp_write (struct ast_rtp_instance *instance, struct ast_frame *frame)
 Function called to broadcast some audio on a multicast instance.
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.
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = 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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_rtp_engine multicast_rtp_engine

Detailed Description

Multicast RTP Engine.

Author:
Joshua Colp <jcolp@digium.com>
Andreas 'MacBrody' Brodmann <andreas.brodmann@gmail.com>

Definition in file res_rtp_multicast.c.


Define Documentation

#define LINKSYS_MCAST_STARTCMD   6

Command value used for Linksys paging to indicate we are starting

Definition at line 58 of file res_rtp_multicast.c.

Referenced by multicast_rtp_activate().

#define LINKSYS_MCAST_STOPCMD   7

Command value used for Linksys paging to indicate we are stopping

Definition at line 61 of file res_rtp_multicast.c.

Referenced by multicast_rtp_destroy().


Enumeration Type Documentation

Type of paging to do.

Enumerator:
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 64 of file res_rtp_multicast.c.

00064                     {
00065    /*! Simple multicast enabled client/receiver paging like Snom and Barix uses */
00066    MULTICAST_TYPE_BASIC = 0,
00067    /*! More advanced Linksys type paging which requires a start and stop packet */
00068    MULTICAST_TYPE_LINKSYS,
00069 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 282 of file res_rtp_multicast.c.

static void __unreg_module ( void   )  [static]

Definition at line 282 of file res_rtp_multicast.c.

static int load_module ( void   )  [static]

Definition at line 262 of file res_rtp_multicast.c.

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and ast_rtp_engine_register.

00263 {
00264    if (ast_rtp_engine_register(&multicast_rtp_engine)) {
00265       return AST_MODULE_LOAD_DECLINE;
00266    }
00267 
00268    return AST_MODULE_LOAD_SUCCESS;
00269 }

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 178 of file res_rtp_multicast.c.

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

00179 {
00180    struct multicast_rtp *multicast = ast_rtp_instance_get_data(instance);
00181 
00182    if (multicast->type != MULTICAST_TYPE_LINKSYS) {
00183       return 0;
00184    }
00185 
00186    return multicast_send_control_packet(instance, multicast, LINKSYS_MCAST_STARTCMD);
00187 }

static int multicast_rtp_destroy ( struct ast_rtp_instance instance  )  [static]

Function called to destroy a multicast instance.

Definition at line 190 of file res_rtp_multicast.c.

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

00191 {
00192    struct multicast_rtp *multicast = ast_rtp_instance_get_data(instance);
00193 
00194    if (multicast->type == MULTICAST_TYPE_LINKSYS) {
00195       multicast_send_control_packet(instance, multicast, LINKSYS_MCAST_STOPCMD);
00196    }
00197 
00198    close(multicast->socket);
00199 
00200    ast_free(multicast);
00201 
00202    return 0;
00203 }

static int multicast_rtp_new ( struct ast_rtp_instance instance,
struct sched_context sched,
struct ast_sockaddr addr,
void *  data 
) [static]

Function called to create a new multicast instance.

Definition at line 113 of file res_rtp_multicast.c.

References ast_calloc, ast_free, ast_random(), ast_rtp_instance_set_data(), MULTICAST_TYPE_BASIC, MULTICAST_TYPE_LINKSYS, multicast_rtp::socket, multicast_rtp::ssrc, multicast_rtp::type, and type.

00114 {
00115    struct multicast_rtp *multicast;
00116    const char *type = data;
00117 
00118    if (!(multicast = ast_calloc(1, sizeof(*multicast)))) {
00119       return -1;
00120    }
00121 
00122    if (!strcasecmp(type, "basic")) {
00123       multicast->type = MULTICAST_TYPE_BASIC;
00124    } else if (!strcasecmp(type, "linksys")) {
00125       multicast->type = MULTICAST_TYPE_LINKSYS;
00126    } else {
00127       ast_free(multicast);
00128       return -1;
00129    }
00130 
00131    if ((multicast->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00132       ast_free(multicast);
00133       return -1;
00134    }
00135 
00136    multicast->ssrc = ast_random();
00137 
00138    ast_rtp_instance_set_data(instance, multicast);
00139 
00140    return 0;
00141 }

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

Function called to read from a multicast instance.

Definition at line 257 of file res_rtp_multicast.c.

References ast_null_frame.

00258 {
00259    return &ast_null_frame;
00260 }

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 206 of file res_rtp_multicast.c.

References AST_FRAME_VOICE, ast_frdup(), ast_frfree, ast_log(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address(), ast_sendto(), ast_sockaddr_stringify(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, errno, f, ast_frame::frametype, LOG_ERROR, ast_frame::offset, ast_frame::ptr, put_unaligned_uint32(), multicast_rtp::seqno, multicast_rtp::socket, multicast_rtp::ssrc, ast_frame::subclass, and ast_frame::ts.

00207 {
00208    struct multicast_rtp *multicast = ast_rtp_instance_get_data(instance);
00209    struct ast_frame *f = frame;
00210    struct ast_sockaddr remote_address;
00211    int hdrlen = 12, res = 0, codec;
00212    unsigned char *rtpheader;
00213 
00214    /* We only accept audio, nothing else */
00215    if (frame->frametype != AST_FRAME_VOICE) {
00216       return 0;
00217    }
00218 
00219    /* Grab the actual payload number for when we create the RTP packet */
00220    if ((codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance), 1, frame->subclass.codec)) < 0) {
00221       return -1;
00222    }
00223 
00224    /* If we do not have space to construct an RTP header duplicate the frame so we get some */
00225    if (frame->offset < hdrlen) {
00226       f = ast_frdup(frame);
00227    }
00228 
00229    /* Construct an RTP header for our packet */
00230    rtpheader = (unsigned char *)(f->data.ptr - hdrlen);
00231    put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (multicast->seqno)));
00232    put_unaligned_uint32(rtpheader + 4, htonl(f->ts * 8));
00233    put_unaligned_uint32(rtpheader + 8, htonl(multicast->ssrc));
00234 
00235    /* Increment sequence number and wrap to 0 if it overflows 16 bits. */
00236    multicast->seqno = 0xFFFF & (multicast->seqno + 1);
00237 
00238    /* Finally send it out to the eager phones listening for us */
00239    ast_rtp_instance_get_remote_address(instance, &remote_address);
00240 
00241    if (ast_sendto(multicast->socket, (void *) rtpheader, f->datalen + hdrlen, 0, &remote_address) < 0) {
00242       ast_log(LOG_ERROR, "Multicast RTP Transmission error to %s: %s\n",
00243          ast_sockaddr_stringify(&remote_address),
00244          strerror(errno));
00245       res = -1;
00246    }
00247 
00248    /* If we were forced to duplicate the frame free the new one */
00249    if (frame != f) {
00250       ast_frfree(f);
00251    }
00252 
00253    return res;
00254 }

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 144 of file res_rtp_multicast.c.

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::ip, LOG_WARNING, multicast_control_packet::port, multicast_rtp::socket, and multicast_control_packet::unique_id.

Referenced by multicast_rtp_activate(), and multicast_rtp_destroy().

00145 {
00146    struct multicast_control_packet control_packet = { .unique_id = htonl((u_long)time(NULL)),
00147                         .command = htonl(command),
00148    };
00149    struct ast_sockaddr control_address, remote_address;
00150 
00151    ast_rtp_instance_get_local_address(instance, &control_address);
00152    ast_rtp_instance_get_remote_address(instance, &remote_address);
00153 
00154    /* Ensure the user of us have given us both the control address and destination address */
00155    if (ast_sockaddr_isnull(&control_address) ||
00156        ast_sockaddr_isnull(&remote_address)) {
00157       return -1;
00158    }
00159 
00160    /* The protocol only supports IPv4. */
00161    if (ast_sockaddr_is_ipv6(&remote_address)) {
00162       ast_log(LOG_WARNING, "Cannot send control packet for IPv6 "
00163          "remote address.\n");
00164       return -1;
00165    }
00166 
00167    control_packet.ip = htonl(ast_sockaddr_ipv4(&remote_address));
00168    control_packet.port = htonl(ast_sockaddr_port(&remote_address));
00169 
00170    /* Based on a recommendation by Brian West who did the FreeSWITCH implementation we send control packets twice */
00171    ast_sendto(multicast->socket, &control_packet, sizeof(control_packet), 0, &control_address);
00172    ast_sendto(multicast->socket, &control_packet, sizeof(control_packet), 0, &control_address);
00173 
00174    return 0;
00175 }

static int unload_module ( void   )  [static]

Definition at line 271 of file res_rtp_multicast.c.

References ast_rtp_engine_unregister().

00272 {
00273    ast_rtp_engine_unregister(&multicast_rtp_engine);
00274 
00275    return 0;
00276 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = 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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, } [static]

Definition at line 282 of file res_rtp_multicast.c.

Definition at line 282 of file res_rtp_multicast.c.

Definition at line 103 of file res_rtp_multicast.c.


Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1