Sat Apr 12 07:12:38 2008

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"

Include dependency graph for chan_nbs.c:

Go to the source code of this file.

Data Structures

struct  nbs_pvt

Functions

 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Network Broadcast Sound Support")
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 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

AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"Network Broadcast Sound Support"   
)

static int load_module ( void   )  [static]

Definition at line 292 of file chan_nbs.c.

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

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, read]

Definition at line 128 of file chan_nbs.c.

References ast_log(), ast_strlen_zero(), free, LOG_WARNING, malloc, nbs_pvt::nbs, 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, 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, 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, read]

Definition at line 232 of file chan_nbs.c.

References ast_channel_alloc(), 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_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, read]

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, read]

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

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


Variable Documentation

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.

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 Apr 12 07:12:38 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.5