Sat Aug 6 00:39:47 2011

Asterisk developer's documentation


chan_nbs.c File Reference

Network broadcast sound support channel driver. More...

#include "asterisk.h"
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.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/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"

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 (void *data)
static int nbs_call (struct ast_channel *ast, 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)
static struct ast_channelnbs_request (const char *type, int format, void *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_DEFAULT | AST_MODFLAG_BUILDSUM, .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, }
static const struct ast_module_infoast_module_info = &__mod_info
static char context [AST_MAX_EXTENSION] = "default"
static struct ast_channel_tech nbs_tech
static int prefformat = AST_FORMAT_SLINEAR
static const char tdesc [] = "Network Broadcast Sound Driver"
static 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 302 of file chan_nbs.c.

static void __unreg_module ( void   )  [static]

Definition at line 302 of file chan_nbs.c.

static int load_module ( void   )  [static]

Definition at line 292 of file chan_nbs.c.

References ast_channel_register(), ast_log(), LOG_ERROR, and nbs_tech.

00293 {
00294    /* Make sure we can register our channel type */
00295    if (ast_channel_register(&nbs_tech)) {
00296       ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
00297       return -1;
00298    }
00299    return 0;
00300 }

static struct nbs_pvt* nbs_alloc ( void *  data  )  [static]

Definition at line 128 of file chan_nbs.c.

References ast_copy_string(), ast_log(), ast_strlen_zero(), free, LOG_WARNING, malloc, and nbs_pvt::stream.

Referenced by nbs_request().

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

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

Definition at line 93 of file chan_nbs.c.

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

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

static void nbs_destroy ( struct nbs_pvt p  )  [static]

Definition at line 120 of file chan_nbs.c.

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

Referenced by nbs_hangup(), and nbs_request().

00121 {
00122    if (p->nbs)
00123       nbs_delstream(p->nbs);
00124    ast_module_user_remove(p->u);
00125    free(p);
00126 }

static int nbs_hangup ( struct ast_channel ast  )  [static]

Definition at line 173 of file chan_nbs.c.

References ast_log(), ast_setstate(), AST_STATE_DOWN, LOG_DEBUG, LOG_WARNING, ast_channel::name, nbs_destroy(), option_debug, and ast_channel::tech_pvt.

00174 {
00175    struct nbs_pvt *p;
00176    p = ast->tech_pvt;
00177    if (option_debug)
00178       ast_log(LOG_DEBUG, "nbs_hangup(%s)\n", ast->name);
00179    if (!ast->tech_pvt) {
00180       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
00181       return 0;
00182    }
00183    nbs_destroy(p);
00184    ast->tech_pvt = NULL;
00185    ast_setstate(ast, AST_STATE_DOWN);
00186    return 0;
00187 }

static struct ast_channel* nbs_new ( struct nbs_pvt i,
int  state 
) [static]

Definition at line 232 of file chan_nbs.c.

References ast_channel_alloc(), ast_copy_string(), ast_hangup(), ast_log(), ast_module_user_add, ast_pbx_start(), AST_STATE_DOWN, AST_STATE_RING, ast_string_field_set, ast_channel::context, ast_channel::exten, ast_channel::fds, language, LOG_WARNING, ast_channel::nativeformats, nbs_pvt::nbs, nbs_tech, nbs_pvt::owner, 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().

00233 {
00234    struct ast_channel *tmp;
00235    tmp = ast_channel_alloc(1, state, 0, 0, "", "s", context, 0, "NBS/%s", i->stream);
00236    if (tmp) {
00237       tmp->tech = &nbs_tech;
00238       tmp->fds[0] = nbs_fd(i->nbs);
00239       tmp->nativeformats = prefformat;
00240       tmp->rawreadformat = prefformat;
00241       tmp->rawwriteformat = prefformat;
00242       tmp->writeformat = prefformat;
00243       tmp->readformat = prefformat;
00244       if (state == AST_STATE_RING)
00245          tmp->rings = 1;
00246       tmp->tech_pvt = i;
00247       ast_copy_string(tmp->context, context, sizeof(tmp->context));
00248       ast_copy_string(tmp->exten, "s",  sizeof(tmp->exten));
00249       ast_string_field_set(tmp, language, "");
00250       i->owner = tmp;
00251       i->u = ast_module_user_add(tmp);
00252       if (state != AST_STATE_DOWN) {
00253          if (ast_pbx_start(tmp)) {
00254             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
00255             ast_hangup(tmp);
00256          }
00257       }
00258    } else
00259       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
00260    return tmp;
00261 }

static struct ast_channel * nbs_request ( const char *  type,
int  format,
void *  data,
int *  cause 
) [static]

Definition at line 264 of file chan_nbs.c.

References AST_FORMAT_SLINEAR, ast_log(), AST_STATE_DOWN, LOG_NOTICE, nbs_alloc(), nbs_destroy(), and nbs_new().

00265 {
00266    int oldformat;
00267    struct nbs_pvt *p;
00268    struct ast_channel *tmp = NULL;
00269    
00270    oldformat = format;
00271    format &= (AST_FORMAT_SLINEAR);
00272    if (!format) {
00273       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
00274       return NULL;
00275    }
00276    p = nbs_alloc(data);
00277    if (p) {
00278       tmp = nbs_new(p, AST_STATE_DOWN);
00279       if (!tmp)
00280          nbs_destroy(p);
00281    }
00282    return tmp;
00283 }

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

Definition at line 189 of file chan_nbs.c.

References ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, nbs_pvt::fr, LOG_DEBUG, ast_frame::mallocd, ast_channel::name, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_channel::tech_pvt.

00190 {
00191    struct nbs_pvt *p = ast->tech_pvt;
00192    
00193 
00194    /* Some nice norms */
00195    p->fr.datalen = 0;
00196    p->fr.samples = 0;
00197    p->fr.data =  NULL;
00198    p->fr.src = type;
00199    p->fr.offset = 0;
00200    p->fr.mallocd=0;
00201    p->fr.delivery.tv_sec = 0;
00202    p->fr.delivery.tv_usec = 0;
00203 
00204    ast_log(LOG_DEBUG, "Returning null frame on %s\n", ast->name);
00205 
00206    return &p->fr;
00207 }

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

Definition at line 209 of file chan_nbs.c.

References ast_channel::_state, AST_FORMAT_SLINEAR, AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log(), AST_STATE_UP, ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, nbs_pvt::nbs, ast_frame::subclass, and ast_channel::tech_pvt.

00210 {
00211    struct nbs_pvt *p = ast->tech_pvt;
00212    /* Write a frame of (presumably voice) data */
00213    if (frame->frametype != AST_FRAME_VOICE) {
00214       if (frame->frametype != AST_FRAME_IMAGE)
00215          ast_log(LOG_WARNING, "Don't know what to do with  frame type '%d'\n", frame->frametype);
00216       return 0;
00217    }
00218    if (!(frame->subclass &
00219       (AST_FORMAT_SLINEAR))) {
00220       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
00221       return 0;
00222    }
00223    if (ast->_state != AST_STATE_UP) {
00224       /* Don't try tos end audio on-hook */
00225       return 0;
00226    }
00227    if (nbs_write(p->nbs, frame->data, frame->datalen / 2) < 0) 
00228       return -1;
00229    return 0;
00230 }

static int unload_module ( void   )  [static]

Definition at line 285 of file chan_nbs.c.

References ast_channel_unregister(), and nbs_tech.

00286 {
00287    /* First, take us out of the channel loop */
00288    ast_channel_unregister(&nbs_tech);
00289    return 0;
00290 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 302 of file chan_nbs.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 302 of file chan_nbs.c.

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

Definition at line 62 of file chan_nbs.c.

struct ast_channel_tech nbs_tech [static]

Definition at line 82 of file chan_nbs.c.

Referenced by load_module(), nbs_new(), and unload_module().

int prefformat = AST_FORMAT_SLINEAR [static]

Definition at line 60 of file chan_nbs.c.

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

Definition at line 57 of file chan_nbs.c.

char type[] = "NBS" [static]

Definition at line 63 of file chan_nbs.c.


Generated on Sat Aug 6 00:39:47 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7