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_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, const char *linkedid) |
static struct ast_channel * | nbs_request (const char *type, format_t format, const struct ast_channel *requestor, 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 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" |
Network broadcast sound support channel driver.
Definition in file chan_nbs.c.
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 }
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] |
Definition at line 57 of file chan_nbs.c.
Referenced by __ast_data_add_structure(), __ast_data_search_cmp_structure(), _build_port_config(), _fill_defaults(), _free_port_cfg(), aji_handle_presence(), ast_call_forward(), ast_format_str_reduce(), ast_writestream(), check_header(), find_agent_callbacks(), find_subscription_type(), g723_len(), get_sdp_line(), h264_decap(), misdn_cfg_get(), misdn_cfg_get_config_string(), msg_timestamp(), multicast_rtp_new(), originate_exec(), osp_check_destination(), osp_lookup(), osp_next(), osplookup_exec(), ospnext_exec(), parse_connect(), parse_facility(), parse_information(), parse_notify(), parse_setup(), process_sdp(), require_curl(), require_odbc(), sip_acf_channel_read(), sla_load_config(), subscription_type2str(), and yyparse().