#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.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 | |
int | __unload_module (void) |
AST_MUTEX_DEFINE_STATIC (usecnt_lock) | |
char * | description () |
Provides a description of the module. | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module () |
Initialize the module. | |
nbs_pvt * | nbs_alloc (void *data) |
int | nbs_call (struct ast_channel *ast, char *dest, int timeout) |
void | nbs_destroy (struct nbs_pvt *p) |
int | nbs_hangup (struct ast_channel *ast) |
ast_channel * | nbs_new (struct nbs_pvt *i, int state) |
ast_channel * | nbs_request (const char *type, int format, void *data, int *cause) |
ast_frame * | nbs_xread (struct ast_channel *ast) |
int | nbs_xwrite (struct ast_channel *ast, struct ast_frame *frame) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount () |
Provides a usecount. | |
Variables | |
char | context [AST_MAX_EXTENSION] = "default" |
const char | desc [] = "Network Broadcast Sound Support" |
const struct ast_channel_tech | nbs_tech |
int | prefformat = AST_FORMAT_SLINEAR |
const char | tdesc [] = "Network Broadcast Sound Driver" |
const char | type [] = "NBS" |
int | usecnt = 0 |
Definition in file chan_nbs.c.
|
Definition at line 289 of file chan_nbs.c. References ast_channel_unregister(), and nbs_tech. 00290 { 00291 /* First, take us out of the channel loop */ 00292 ast_channel_unregister(&nbs_tech); 00293 return 0; 00294 }
|
|
|
|
Provides a description of the module.
Definition at line 317 of file chan_nbs.c. 00318 { 00319 return (char *) desc; 00320 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 322 of file chan_nbs.c. 00323 {
00324 return ASTERISK_GPL_KEY;
00325 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 301 of file chan_nbs.c. References __unload_module(), ast_channel_register(), ast_log(), LOG_ERROR, nbs_tech, and type. 00302 { 00303 /* Make sure we can register our channel type */ 00304 if (ast_channel_register(&nbs_tech)) { 00305 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 00306 __unload_module(); 00307 return -1; 00308 } 00309 return 0; 00310 }
|
|
Definition at line 127 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(). 00128 { 00129 struct nbs_pvt *p; 00130 int flags = 0; 00131 char stream[256] = ""; 00132 char *opts; 00133 strncpy(stream, data, sizeof(stream) - 1); 00134 if ((opts = strchr(stream, ':'))) { 00135 *opts = '\0'; 00136 opts++; 00137 } else 00138 opts = ""; 00139 p = malloc(sizeof(struct nbs_pvt)); 00140 if (p) { 00141 memset(p, 0, sizeof(struct nbs_pvt)); 00142 if (!ast_strlen_zero(opts)) { 00143 if (strchr(opts, 'm')) 00144 flags |= NBS_FLAG_MUTE; 00145 if (strchr(opts, 'o')) 00146 flags |= NBS_FLAG_OVERSPEAK; 00147 if (strchr(opts, 'e')) 00148 flags |= NBS_FLAG_EMERGENCY; 00149 if (strchr(opts, 'O')) 00150 flags |= NBS_FLAG_OVERRIDE; 00151 } else 00152 flags = NBS_FLAG_OVERSPEAK; 00153 00154 strncpy(p->stream, stream, sizeof(p->stream) - 1); 00155 p->nbs = nbs_newstream("asterisk", stream, flags); 00156 if (!p->nbs) { 00157 ast_log(LOG_WARNING, "Unable to allocate new NBS stream '%s' with flags %d\n", stream, flags); 00158 free(p); 00159 p = NULL; 00160 } else { 00161 /* Set for 8000 hz mono, 640 samples */ 00162 nbs_setbitrate(p->nbs, 8000); 00163 nbs_setchannels(p->nbs, 1); 00164 nbs_setblocksize(p->nbs, 640); 00165 nbs_setblocking(p->nbs, 0); 00166 } 00167 } 00168 return p; 00169 }
|
|
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_RINGING, LOG_DEBUG, LOG_WARNING, ast_channel::name, nbs_pvt::nbs, 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 }
|
|
Definition at line 120 of file chan_nbs.c. References free, and nbs_pvt::nbs. Referenced by nbs_hangup(), and nbs_request().
|
|
Definition at line 171 of file chan_nbs.c. References ast_log(), ast_setstate(), AST_STATE_DOWN, LOG_DEBUG, LOG_WARNING, ast_channel::name, nbs_destroy(), and ast_channel::tech_pvt. 00172 { 00173 struct nbs_pvt *p; 00174 p = ast->tech_pvt; 00175 if (option_debug) 00176 ast_log(LOG_DEBUG, "nbs_hangup(%s)\n", ast->name); 00177 if (!ast->tech_pvt) { 00178 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 00179 return 0; 00180 } 00181 nbs_destroy(p); 00182 ast->tech_pvt = NULL; 00183 ast_setstate(ast, AST_STATE_DOWN); 00184 return 0; 00185 }
|
|
Definition at line 230 of file chan_nbs.c. References ast_channel_alloc(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_setstate(), ast_update_use_count(), context, ast_channel::context, ast_channel::exten, ast_channel::fds, ast_channel::language, LOG_WARNING, ast_channel::name, 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, ast_channel::type, usecnt, and ast_channel::writeformat. Referenced by nbs_request(). 00231 { 00232 struct ast_channel *tmp; 00233 tmp = ast_channel_alloc(1); 00234 if (tmp) { 00235 tmp->tech = &nbs_tech; 00236 snprintf(tmp->name, sizeof(tmp->name), "NBS/%s", i->stream); 00237 tmp->type = type; 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 ast_setstate(tmp, state); 00245 if (state == AST_STATE_RING) 00246 tmp->rings = 1; 00247 tmp->tech_pvt = i; 00248 strncpy(tmp->context, context, sizeof(tmp->context)-1); 00249 strncpy(tmp->exten, "s", sizeof(tmp->exten) - 1); 00250 tmp->language[0] = '\0'; 00251 i->owner = tmp; 00252 ast_mutex_lock(&usecnt_lock); 00253 usecnt++; 00254 ast_mutex_unlock(&usecnt_lock); 00255 ast_update_use_count(); 00256 if (state != AST_STATE_DOWN) { 00257 if (ast_pbx_start(tmp)) { 00258 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 00259 ast_hangup(tmp); 00260 } 00261 } 00262 } else 00263 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 00264 return tmp; 00265 }
|
|
Definition at line 268 of file chan_nbs.c. References ast_log(), AST_STATE_DOWN, LOG_NOTICE, nbs_alloc(), nbs_destroy(), and nbs_new(). 00269 { 00270 int oldformat; 00271 struct nbs_pvt *p; 00272 struct ast_channel *tmp = NULL; 00273 00274 oldformat = format; 00275 format &= (AST_FORMAT_SLINEAR); 00276 if (!format) { 00277 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat); 00278 return NULL; 00279 } 00280 p = nbs_alloc(data); 00281 if (p) { 00282 tmp = nbs_new(p, AST_STATE_DOWN); 00283 if (!tmp) 00284 nbs_destroy(p); 00285 } 00286 return tmp; 00287 }
|
|
Definition at line 187 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. 00188 { 00189 struct nbs_pvt *p = ast->tech_pvt; 00190 00191 00192 /* Some nice norms */ 00193 p->fr.datalen = 0; 00194 p->fr.samples = 0; 00195 p->fr.data = NULL; 00196 p->fr.src = type; 00197 p->fr.offset = 0; 00198 p->fr.mallocd=0; 00199 p->fr.delivery.tv_sec = 0; 00200 p->fr.delivery.tv_usec = 0; 00201 00202 ast_log(LOG_DEBUG, "Returning null frame on %s\n", ast->name); 00203 00204 return &p->fr; 00205 }
|
|
Definition at line 207 of file chan_nbs.c. References ast_channel::_state, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, nbs_pvt::nbs, ast_frame::subclass, and ast_channel::tech_pvt. 00208 { 00209 struct nbs_pvt *p = ast->tech_pvt; 00210 /* Write a frame of (presumably voice) data */ 00211 if (frame->frametype != AST_FRAME_VOICE) { 00212 if (frame->frametype != AST_FRAME_IMAGE) 00213 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 00214 return 0; 00215 } 00216 if (!(frame->subclass & 00217 (AST_FORMAT_SLINEAR))) { 00218 ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass); 00219 return 0; 00220 } 00221 if (ast->_state != AST_STATE_UP) { 00222 /* Don't try tos end audio on-hook */ 00223 return 0; 00224 } 00225 if (nbs_write(p->nbs, frame->data, frame->datalen / 2) < 0) 00226 return -1; 00227 return 0; 00228 }
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 296 of file chan_nbs.c. References __unload_module(). 00297 { 00298 return __unload_module(); 00299 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 312 of file chan_nbs.c. 00313 {
00314 return usecnt;
00315 }
|
|
Definition at line 64 of file chan_nbs.c. Referenced by nbs_new(). |
|
Definition at line 53 of file chan_nbs.c. |
|
Definition at line 82 of file chan_nbs.c. Referenced by __unload_module(), and load_module(). |
|
Definition at line 60 of file chan_nbs.c. |
|
Definition at line 55 of file chan_nbs.c. |
|
Definition at line 54 of file chan_nbs.c. |
|
Definition at line 57 of file chan_nbs.c. Referenced by nbs_new(). |