Thu Sep 7 01:03:18 2017

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"

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, const char *linkedid)
static struct ast_channelnbs_request (const char *type, format_t format, const struct ast_channel *requestor, 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 format_t prefformat = AST_FORMAT_SLINEAR
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

AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"Network Broadcast Sound Support"   
)
static int load_module ( void   )  [static]

Definition at line 283 of file chan_nbs.c.

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

00284 {
00285    /* Make sure we can register our channel type */
00286    if (ast_channel_register(&nbs_tech)) {
00287       ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
00288       return -1;
00289    }
00290    return 0;
00291 }

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

Definition at line 121 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().

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

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

Definition at line 87 of file chan_nbs.c.

References ast_channel::_state, 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.

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

static void nbs_destroy ( struct nbs_pvt p  )  [static]

Definition at line 113 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().

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

static int nbs_hangup ( struct ast_channel ast  )  [static]

Definition at line 165 of file chan_nbs.c.

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

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

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

Definition at line 223 of file chan_nbs.c.

References ast_channel_alloc, ast_channel_set_fd(), 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, 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().

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

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

Definition at line 255 of file chan_nbs.c.

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

00256 {
00257    format_t oldformat;
00258    struct nbs_pvt *p;
00259    struct ast_channel *tmp = NULL;
00260    
00261    oldformat = format;
00262    format &= (AST_FORMAT_SLINEAR);
00263    if (!format) {
00264       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname(oldformat));
00265       return NULL;
00266    }
00267    p = nbs_alloc(data);
00268    if (p) {
00269       tmp = nbs_new(p, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
00270       if (!tmp)
00271          nbs_destroy(p);
00272    }
00273    return tmp;
00274 }

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

Definition at line 180 of file chan_nbs.c.

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

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

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

Definition at line 200 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_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, nbs_pvt::nbs, ast_frame::ptr, ast_frame::subclass, and ast_channel::tech_pvt.

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

static int unload_module ( void   )  [static]

Definition at line 276 of file chan_nbs.c.

References ast_channel_unregister().

00277 {
00278    /* First, take us out of the channel loop */
00279    ast_channel_unregister(&nbs_tech);
00280    return 0;
00281 }


Variable Documentation

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.

format_t prefformat = AST_FORMAT_SLINEAR [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 7 Sep 2017 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1