Mon Jun 27 16:51:20 2011

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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 54 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 57 of file res_rtp_multicast.c.

Referenced by multicast_rtp_destroy().


Enumeration Type Documentation

enum multicast_type

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

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


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 275 of file res_rtp_multicast.c.

static void __unreg_module ( void   )  [static]

Definition at line 275 of file res_rtp_multicast.c.

static int load_module ( void   )  [static]

Definition at line 255 of file res_rtp_multicast.c.

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_rtp_engine_register, and multicast_rtp_engine.

00256 {
00257    if (ast_rtp_engine_register(&multicast_rtp_engine)) {
00258       return AST_MODULE_LOAD_DECLINE;
00259    }
00260 
00261    return AST_MODULE_LOAD_SUCCESS;
00262 }

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 174 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.

00175 {
00176    struct multicast_rtp *multicast = ast_rtp_instance_get_data(instance);
00177 
00178    if (multicast->type != MULTICAST_TYPE_LINKSYS) {
00179       return 0;
00180    }
00181 
00182    return multicast_send_control_packet(instance, multicast, LINKSYS_MCAST_STARTCMD);
00183 }

static int multicast_rtp_destroy ( struct ast_rtp_instance instance  )  [static]

Function called to destroy a multicast instance.

Definition at line 186 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.

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

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 109 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, and type.

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

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

References ast_null_frame.

00251 {
00252    return &ast_null_frame;
00253 }

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 202 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, errno, f, ast_frame::frametype, LOG_ERROR, ast_frame::offset, put_unaligned_uint32(), multicast_rtp::seqno, multicast_rtp::socket, multicast_rtp::ssrc, and ast_frame::subclass.

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

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 140 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().

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

static int unload_module ( void   )  [static]

Definition at line 264 of file res_rtp_multicast.c.

References ast_rtp_engine_unregister(), and multicast_rtp_engine.

00265 {
00266    ast_rtp_engine_unregister(&multicast_rtp_engine);
00267 
00268    return 0;
00269 }


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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, } [static]

Definition at line 275 of file res_rtp_multicast.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 275 of file res_rtp_multicast.c.

struct ast_rtp_engine multicast_rtp_engine [static]

Definition at line 99 of file res_rtp_multicast.c.

Referenced by load_module(), and unload_module().


Generated on Mon Jun 27 16:51:20 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7