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 | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | load_module (void) |
static struct nbs_pvt * | nbs_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_channel * | nbs_new (struct nbs_pvt *i, int state) |
static struct ast_channel * | nbs_request (const char *type, int format, void *data, int *cause) |
static struct ast_frame * | nbs_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 __MODULE_INFO_SECTION | __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Network Broadcast Sound Support" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } |
static struct ast_module_info * | ast_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" |
Network broadcast sound support channel driver.
Definition in file chan_nbs.c.
static void __reg_module | ( | void | ) | [static] |
Definition at line 292 of file chan_nbs.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 292 of file chan_nbs.c.
static int load_module | ( | void | ) | [static] |
Definition at line 282 of file chan_nbs.c.
References ast_channel_register(), ast_log(), and LOG_ERROR.
{ /* Make sure we can register our channel type */ if (ast_channel_register(&nbs_tech)) { ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); return -1; } return 0; }
static struct nbs_pvt* nbs_alloc | ( | void * | 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().
{ struct nbs_pvt *p; int flags = 0; char stream[256]; char *opts; ast_copy_string(stream, data, sizeof(stream)); if ((opts = strchr(stream, ':'))) { *opts = '\0'; opts++; } else opts = ""; p = ast_calloc(1, sizeof(*p)); if (p) { if (!ast_strlen_zero(opts)) { if (strchr(opts, 'm')) flags |= NBS_FLAG_MUTE; if (strchr(opts, 'o')) flags |= NBS_FLAG_OVERSPEAK; if (strchr(opts, 'e')) flags |= NBS_FLAG_EMERGENCY; if (strchr(opts, 'O')) flags |= NBS_FLAG_OVERRIDE; } else flags = NBS_FLAG_OVERSPEAK; ast_copy_string(p->stream, stream, sizeof(p->stream)); p->nbs = nbs_newstream("asterisk", stream, flags); if (!p->nbs) { ast_log(LOG_WARNING, "Unable to allocate new NBS stream '%s' with flags %d\n", stream, flags); ast_free(p); p = NULL; } else { /* Set for 8000 hz mono, 640 samples */ nbs_setbitrate(p->nbs, 8000); nbs_setchannels(p->nbs, 1); nbs_setblocksize(p->nbs, 640); nbs_setblocking(p->nbs, 0); } } return p; }
static int nbs_call | ( | struct ast_channel * | ast, |
char * | dest, | ||
int | timeout | ||
) | [static] |
Definition at line 86 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, ast_channel::name, nbs_pvt::nbs, and ast_channel::tech_pvt.
{ struct nbs_pvt *p; p = ast->tech_pvt; if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { ast_log(LOG_WARNING, "nbs_call called on %s, neither down nor reserved\n", ast->name); return -1; } /* When we call, it just works, really, there's no destination... Just ring the phone and wait for someone to answer */ ast_debug(1, "Calling %s on %s\n", dest, ast->name); /* If we can't connect, return congestion */ if (nbs_connect(p->nbs)) { ast_log(LOG_WARNING, "NBS Connection failed on %s\n", ast->name); ast_queue_control(ast, AST_CONTROL_CONGESTION); } else { ast_setstate(ast, AST_STATE_RINGING); ast_queue_control(ast, AST_CONTROL_ANSWER); } return 0; }
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().
{ if (p->nbs) nbs_delstream(p->nbs); ast_module_user_remove(p->u); ast_free(p); }
static int nbs_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 164 of file chan_nbs.c.
References ast_debug, ast_log(), ast_setstate(), AST_STATE_DOWN, LOG_WARNING, ast_channel::name, nbs_destroy(), and ast_channel::tech_pvt.
{ struct nbs_pvt *p; p = ast->tech_pvt; ast_debug(1, "nbs_hangup(%s)\n", ast->name); if (!ast->tech_pvt) { ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); return 0; } nbs_destroy(p); ast->tech_pvt = NULL; ast_setstate(ast, AST_STATE_DOWN); return 0; }
static struct ast_channel* nbs_new | ( | struct nbs_pvt * | i, |
int | state | ||
) | [static, read] |
Definition at line 222 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::name, ast_channel::nativeformats, nbs_pvt::nbs, nbs_tech, 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().
{ struct ast_channel *tmp; tmp = ast_channel_alloc(1, state, 0, 0, "", "s", context, 0, "NBS/%s", i->stream); if (tmp) { tmp->tech = &nbs_tech; ast_channel_set_fd(tmp, 0, nbs_fd(i->nbs)); tmp->nativeformats = prefformat; tmp->rawreadformat = prefformat; tmp->rawwriteformat = prefformat; tmp->writeformat = prefformat; tmp->readformat = prefformat; if (state == AST_STATE_RING) tmp->rings = 1; tmp->tech_pvt = i; ast_copy_string(tmp->context, context, sizeof(tmp->context)); ast_copy_string(tmp->exten, "s", sizeof(tmp->exten)); ast_string_field_set(tmp, language, ""); i->owner = tmp; i->u = ast_module_user_add(tmp); if (state != AST_STATE_DOWN) { if (ast_pbx_start(tmp)) { ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); ast_hangup(tmp); } } } else ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); return tmp; }
static struct ast_channel * nbs_request | ( | const char * | type, |
int | format, | ||
void * | data, | ||
int * | cause | ||
) | [static, read] |
Definition at line 254 of file chan_nbs.c.
References AST_FORMAT_SLINEAR, ast_log(), AST_STATE_DOWN, format, LOG_NOTICE, nbs_alloc(), nbs_destroy(), and nbs_new().
{ int oldformat; struct nbs_pvt *p; struct ast_channel *tmp = NULL; oldformat = format; format &= (AST_FORMAT_SLINEAR); if (!format) { ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat); return NULL; } p = nbs_alloc(data); if (p) { tmp = nbs_new(p, AST_STATE_DOWN); if (!tmp) nbs_destroy(p); } return tmp; }
static struct ast_frame * nbs_xread | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 179 of file chan_nbs.c.
References ast_debug, ast_frame::data, ast_frame::datalen, ast_frame::delivery, nbs_pvt::fr, ast_frame::mallocd, ast_channel::name, ast_frame::offset, ast_frame::ptr, ast_frame::samples, ast_frame::src, ast_channel::tech_pvt, and type.
{ struct nbs_pvt *p = ast->tech_pvt; /* Some nice norms */ p->fr.datalen = 0; p->fr.samples = 0; p->fr.data.ptr = NULL; p->fr.src = type; p->fr.offset = 0; p->fr.mallocd=0; p->fr.delivery.tv_sec = 0; p->fr.delivery.tv_usec = 0; ast_debug(1, "Returning null frame on %s\n", ast->name); return &p->fr; }
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_log(), AST_STATE_UP, 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.
{ struct nbs_pvt *p = ast->tech_pvt; /* Write a frame of (presumably voice) data */ if (frame->frametype != AST_FRAME_VOICE) { if (frame->frametype != AST_FRAME_IMAGE) ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); return 0; } if (!(frame->subclass & (AST_FORMAT_SLINEAR))) { ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass); return 0; } if (ast->_state != AST_STATE_UP) { /* Don't try tos end audio on-hook */ return 0; } if (nbs_write(p->nbs, frame->data.ptr, frame->datalen / 2) < 0) return -1; return 0; }
static int unload_module | ( | void | ) | [static] |
Definition at line 275 of file chan_nbs.c.
References ast_channel_unregister().
{ /* First, take us out of the channel loop */ ast_channel_unregister(&nbs_tech); return 0; }
struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Network Broadcast Sound Support" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static] |
Definition at line 292 of file chan_nbs.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 292 of file chan_nbs.c.
char context[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 55 of file chan_nbs.c.
struct ast_channel_tech nbs_tech [static] |
Definition at line 75 of file chan_nbs.c.
Referenced by nbs_new().
int prefformat = AST_FORMAT_SLINEAR [static] |
Definition at line 53 of file chan_nbs.c.
Referenced by nbs_new().
const char tdesc[] = "Network Broadcast Sound Driver" [static] |
Definition at line 50 of file chan_nbs.c.
char type[] = "NBS" [static] |
Definition at line 56 of file chan_nbs.c.
Referenced by nbs_xread().