Sat Feb 11 06:34:40 2012

Asterisk developer's documentation


chan_nbs.c File Reference

Network broadcast sound support channel driver. More...

#include "asterisk.h"
#include <sys/socket.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <nbs.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"

Include dependency graph for chan_nbs.c:

Go to the source code of this file.

Data Structures

struct  nbs_pvt

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int load_module (void)
static struct nbs_pvtnbs_alloc (const char *data)
static int nbs_call (struct ast_channel *ast, const char *dest, int timeout)
static void nbs_destroy (struct nbs_pvt *p)
static int nbs_hangup (struct ast_channel *ast)
static struct ast_channelnbs_new (struct nbs_pvt *i, int state, const char *linkedid)
static struct ast_channelnbs_request (const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
static struct ast_framenbs_xread (struct ast_channel *ast)
static int nbs_xwrite (struct ast_channel *ast, struct ast_frame *frame)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Network Broadcast Sound Support" , .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, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static struct ast_module_infoast_module_info = &__mod_info
static char context [AST_MAX_EXTENSION] = "default"
static struct ast_channel_tech nbs_tech
static struct ast_format prefformat
static const char tdesc [] = "Network Broadcast Sound Driver"
static const char type [] = "NBS"


Detailed Description

Network broadcast sound support channel driver.

Author:
Mark Spencer <markster@digium.com>

Definition in file chan_nbs.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 296 of file chan_nbs.c.

static void __unreg_module ( void   )  [static]

Definition at line 296 of file chan_nbs.c.

static int load_module ( void   )  [static]

Definition at line 281 of file chan_nbs.c.

References ast_channel_register(), ast_format_cap_add(), ast_format_cap_alloc(), ast_format_set(), AST_FORMAT_SLINEAR, ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_channel_tech::capabilities, LOG_ERROR, and prefformat.

00282 {
00283    ast_format_set(&prefformat, AST_FORMAT_SLINEAR, 0);
00284    if (!(nbs_tech.capabilities = ast_format_cap_alloc())) {
00285       return AST_MODULE_LOAD_FAILURE;
00286    }
00287    ast_format_cap_add(nbs_tech.capabilities, &prefformat);
00288    /* Make sure we can register our channel type */
00289    if (ast_channel_register(&nbs_tech)) {
00290       ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
00291       return AST_MODULE_LOAD_DECLINE;
00292    }
00293    return AST_MODULE_LOAD_SUCCESS;
00294 }

static struct nbs_pvt* nbs_alloc ( const char *  data  )  [static, read]

Definition at line 120 of file chan_nbs.c.

References ast_calloc, ast_copy_string(), ast_free, ast_log(), ast_strlen_zero(), LOG_WARNING, nbs_pvt::nbs, and nbs_pvt::stream.

Referenced by nbs_request().

00121 {
00122    struct nbs_pvt *p;
00123    int flags = 0;
00124    char stream[256];
00125    char *opts;
00126 
00127    ast_copy_string(stream, data, sizeof(stream));
00128    if ((opts = strchr(stream, ':'))) {
00129       *opts = '\0';
00130       opts++;
00131    } else
00132       opts = "";
00133    p = ast_calloc(1, sizeof(*p));
00134    if (p) {
00135       if (!ast_strlen_zero(opts)) {
00136          if (strchr(opts, 'm'))
00137             flags |= NBS_FLAG_MUTE;
00138          if (strchr(opts, 'o'))
00139             flags |= NBS_FLAG_OVERSPEAK;
00140          if (strchr(opts, 'e'))
00141             flags |= NBS_FLAG_EMERGENCY;
00142          if (strchr(opts, 'O'))
00143             flags |= NBS_FLAG_OVERRIDE;
00144       } else
00145          flags = NBS_FLAG_OVERSPEAK;
00146       
00147       ast_copy_string(p->stream, stream, sizeof(p->stream));
00148       p->nbs = nbs_newstream("asterisk", stream, flags);
00149       if (!p->nbs) {
00150          ast_log(LOG_WARNING, "Unable to allocate new NBS stream '%s' with flags %d\n", stream, flags);
00151          ast_free(p);
00152          p = NULL;
00153       } else {
00154          /* Set for 8000 hz mono, 640 samples */
00155          nbs_setbitrate(p->nbs, 8000);
00156          nbs_setchannels(p->nbs, 1);
00157          nbs_setblocksize(p->nbs, 640);
00158          nbs_setblocking(p->nbs, 0);
00159       }
00160    }
00161    return p;
00162 }

static int nbs_call ( struct ast_channel ast,
const char *  dest,
int  timeout 
) [static]

Definition at line 86 of file chan_nbs.c.

References ast_channel::_state, ast_channel_name(), AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, ast_debug, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, LOG_WARNING, nbs_pvt::nbs, and ast_channel::tech_pvt.

00087 {
00088    struct nbs_pvt *p;
00089 
00090    p = ast->tech_pvt;
00091 
00092    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
00093       ast_log(LOG_WARNING, "nbs_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
00094       return -1;
00095    }
00096    /* When we call, it just works, really, there's no destination...  Just
00097       ring the phone and wait for someone to answer */
00098    ast_debug(1, "Calling %s on %s\n", dest, ast_channel_name(ast));
00099 
00100    /* If we can't connect, return congestion */
00101    if (nbs_connect(p->nbs)) {
00102       ast_log(LOG_WARNING, "NBS Connection failed on %s\n", ast_channel_name(ast));
00103       ast_queue_control(ast, AST_CONTROL_CONGESTION);
00104    } else {
00105       ast_setstate(ast, AST_STATE_RINGING);
00106       ast_queue_control(ast, AST_CONTROL_ANSWER);
00107    }
00108 
00109    return 0;
00110 }

static void nbs_destroy ( struct nbs_pvt p  )  [static]

Definition at line 112 of file chan_nbs.c.

References ast_free, ast_module_user_remove, nbs_pvt::nbs, and nbs_pvt::u.

Referenced by nbs_hangup(), and nbs_request().

00113 {
00114    if (p->nbs)
00115       nbs_delstream(p->nbs);
00116    ast_module_user_remove(p->u);
00117    ast_free(p);
00118 }

static int nbs_hangup ( struct ast_channel ast  )  [static]

Definition at line 164 of file chan_nbs.c.

References ast_channel_name(), ast_debug, ast_log(), ast_setstate(), AST_STATE_DOWN, LOG_WARNING, nbs_destroy(), and ast_channel::tech_pvt.

00165 {
00166    struct nbs_pvt *p;
00167    p = ast->tech_pvt;
00168    ast_debug(1, "nbs_hangup(%s)\n", ast_channel_name(ast));
00169    if (!ast->tech_pvt) {
00170       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
00171       return 0;
00172    }
00173    nbs_destroy(p);
00174    ast->tech_pvt = NULL;
00175    ast_setstate(ast, AST_STATE_DOWN);
00176    return 0;
00177 }

static struct ast_channel* nbs_new ( struct nbs_pvt i,
int  state,
const char *  linkedid 
) [static, read]

Definition at line 221 of file chan_nbs.c.

References ast_channel_alloc, ast_channel_name(), ast_channel_set_fd(), ast_copy_string(), ast_format_cap_add(), ast_format_copy(), ast_hangup(), ast_log(), ast_module_user_add, ast_pbx_start(), AST_STATE_DOWN, AST_STATE_RING, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::nativeformats, nbs_pvt::nbs, nbs_pvt::owner, prefformat, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, nbs_pvt::stream, ast_channel::tech, ast_channel::tech_pvt, nbs_pvt::u, and ast_channel::writeformat.

Referenced by nbs_request().

00222 {
00223    struct ast_channel *tmp;
00224    tmp = ast_channel_alloc(1, state, 0, 0, "", "s", context, linkedid, 0, "NBS/%s", i->stream);
00225    if (tmp) {
00226       tmp->tech = &nbs_tech;
00227       ast_channel_set_fd(tmp, 0, nbs_fd(i->nbs));
00228 
00229       ast_format_cap_add(tmp->nativeformats, &prefformat);
00230       ast_format_copy(&tmp->rawreadformat, &prefformat);
00231       ast_format_copy(&tmp->rawwriteformat, &prefformat);
00232       ast_format_copy(&tmp->writeformat, &prefformat);
00233       ast_format_copy(&tmp->readformat, &prefformat);
00234       if (state == AST_STATE_RING)
00235          tmp->rings = 1;
00236       tmp->tech_pvt = i;
00237       ast_copy_string(tmp->context, context, sizeof(tmp->context));
00238       ast_copy_string(tmp->exten, "s",  sizeof(tmp->exten));
00239       ast_channel_language_set(tmp, "");
00240       i->owner = tmp;
00241       i->u = ast_module_user_add(tmp);
00242       if (state != AST_STATE_DOWN) {
00243          if (ast_pbx_start(tmp)) {
00244             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
00245             ast_hangup(tmp);
00246          }
00247       }
00248    } else
00249       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
00250    return tmp;
00251 }

static struct ast_channel * nbs_request ( const char *  type,
struct ast_format_cap cap,
const struct ast_channel requestor,
const char *  data,
int *  cause 
) [static, read]

Definition at line 254 of file chan_nbs.c.

References ast_channel_linkedid(), ast_format_cap_iscompatible(), ast_getformatname_multiple(), ast_log(), AST_STATE_DOWN, LOG_NOTICE, nbs_alloc(), nbs_destroy(), nbs_new(), and prefformat.

00255 {
00256    struct nbs_pvt *p;
00257    struct ast_channel *tmp = NULL;
00258 
00259    if (!(ast_format_cap_iscompatible(cap, &prefformat))) {
00260       char tmp[256];
00261       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
00262       return NULL;
00263    }
00264    p = nbs_alloc(data);
00265    if (p) {
00266       tmp = nbs_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
00267       if (!tmp)
00268          nbs_destroy(p);
00269    }
00270    return tmp;
00271 }

static struct ast_frame * nbs_xread ( struct ast_channel ast  )  [static, read]

Definition at line 179 of file chan_nbs.c.

References ast_channel_name(), ast_debug, ast_frame::data, ast_frame::datalen, ast_frame::delivery, nbs_pvt::fr, ast_frame::mallocd, ast_frame::offset, ast_frame::ptr, ast_frame::samples, ast_frame::src, and ast_channel::tech_pvt.

00180 {
00181    struct nbs_pvt *p = ast->tech_pvt;
00182    
00183 
00184    /* Some nice norms */
00185    p->fr.datalen = 0;
00186    p->fr.samples = 0;
00187    p->fr.data.ptr =  NULL;
00188    p->fr.src = type;
00189    p->fr.offset = 0;
00190    p->fr.mallocd=0;
00191    p->fr.delivery.tv_sec = 0;
00192    p->fr.delivery.tv_usec = 0;
00193 
00194    ast_debug(1, "Returning null frame on %s\n", ast_channel_name(ast));
00195 
00196    return &p->fr;
00197 }

static int nbs_xwrite ( struct ast_channel ast,
struct ast_frame frame 
) [static]

Definition at line 199 of file chan_nbs.c.

References ast_channel::_state, AST_FORMAT_SLINEAR, AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_getformatname(), ast_log(), AST_STATE_UP, ast_frame::data, ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, ast_format::id, LOG_WARNING, nbs_pvt::nbs, ast_frame::ptr, ast_frame::subclass, and ast_channel::tech_pvt.

00200 {
00201    struct nbs_pvt *p = ast->tech_pvt;
00202    /* Write a frame of (presumably voice) data */
00203    if (frame->frametype != AST_FRAME_VOICE) {
00204       if (frame->frametype != AST_FRAME_IMAGE)
00205          ast_log(LOG_WARNING, "Don't know what to do with  frame type '%d'\n", frame->frametype);
00206       return 0;
00207    }
00208    if (frame->subclass.format.id != (AST_FORMAT_SLINEAR)) {
00209       ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(&frame->subclass.format));
00210       return 0;
00211    }
00212    if (ast->_state != AST_STATE_UP) {
00213       /* Don't try tos end audio on-hook */
00214       return 0;
00215    }
00216    if (nbs_write(p->nbs, frame->data.ptr, frame->datalen / 2) < 0) 
00217       return -1;
00218    return 0;
00219 }

static int unload_module ( void   )  [static]

Definition at line 273 of file chan_nbs.c.

References ast_channel_unregister(), ast_format_cap_destroy(), and ast_channel_tech::capabilities.

00274 {
00275    /* First, take us out of the channel loop */
00276    ast_channel_unregister(&nbs_tech);
00277    nbs_tech.capabilities = ast_format_cap_destroy(nbs_tech.capabilities);
00278    return 0;
00279 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Network Broadcast Sound Support" , .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, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 296 of file chan_nbs.c.

Definition at line 296 of file chan_nbs.c.

char context[AST_MAX_EXTENSION] = "default" [static]

Definition at line 56 of file chan_nbs.c.

struct ast_channel_tech nbs_tech [static]

Definition at line 76 of file chan_nbs.c.

struct ast_format prefformat [static]

Definition at line 54 of file chan_nbs.c.

const char tdesc[] = "Network Broadcast Sound Driver" [static]

Definition at line 51 of file chan_nbs.c.

const char type[] = "NBS" [static]


Generated on Sat Feb 11 06:34:40 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6