#include "asterisk.h"
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <alsa/asoundlib.h>
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/endian.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/poll-compat.h"

Go to the source code of this file.
Data Structures | |
| struct | chan_alsa_pvt |
Defines | |
| #define | ALSA_INDEV "default" |
| #define | ALSA_OUTDEV "default" |
| #define | ALSA_PCM_NEW_HW_PARAMS_API |
| #define | ALSA_PCM_NEW_SW_PARAMS_API |
| #define | BUFFER_FMT ((buffersize * 10) << 16) | (0x0006); |
| #define | DEBUG 0 |
| #define | DESIRED_RATE 8000 |
| #define | FRAME_SIZE 160 |
| #define | MAX_BUFFER_SIZE 100 |
| #define | MIN_SWITCH_TIME 600 |
| #define | PERIOD_FRAMES 80 |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static int | alsa_answer (struct ast_channel *c) |
| static int | alsa_call (struct ast_channel *c, const char *dest, int timeout) |
| static snd_pcm_t * | alsa_card_init (char *dev, snd_pcm_stream_t stream) |
| static int | alsa_digit (struct ast_channel *c, char digit, unsigned int duration) |
| static int | alsa_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
| static int | alsa_hangup (struct ast_channel *c) |
| static int | alsa_indicate (struct ast_channel *chan, int cond, const void *data, size_t datalen) |
| static struct ast_channel * | alsa_new (struct chan_alsa_pvt *p, int state, const char *linkedid) |
| static struct ast_frame * | alsa_read (struct ast_channel *chan) |
| static struct ast_channel * | alsa_request (const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause) |
| static int | alsa_text (struct ast_channel *c, const char *text) |
| static int | alsa_write (struct ast_channel *chan, struct ast_frame *f) |
| static char * | autoanswer_complete (const char *line, const char *word, int pos, int state) |
| static char * | console_answer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | console_autoanswer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | console_dial (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | console_hangup (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | console_mute (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | console_sendtext (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static void | grab_owner (void) |
| static int | load_module (void) |
| static int | soundcard_init (void) |
| static int | unload_module (void) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "ALSA Console Channel Driver" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } |
| static struct chan_alsa_pvt | alsa |
| static struct ast_channel_tech | alsa_tech |
| static ast_mutex_t | alsalock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static int | autoanswer = 1 |
| static struct ast_cli_entry | cli_alsa [] |
| static const char | config [] = "alsa.conf" |
| static char | context [AST_MAX_CONTEXT] = "default" |
| static struct ast_jb_conf | default_jbconf |
| static char | exten [AST_MAX_EXTENSION] = "s" |
| static snd_pcm_format_t | format = SND_PCM_FORMAT_S16_BE |
| static struct ast_jb_conf | global_jbconf |
| static int | hookstate = 0 |
| static char | indevname [50] = ALSA_INDEV |
| static char | language [MAX_LANGUAGE] = "" |
| static char | mohinterpret [MAX_MUSICCLASS] |
| static int | mute = 0 |
| static int | noaudiocapture = 0 |
| static char | outdevname [50] = ALSA_OUTDEV |
| static int | readdev = -1 |
| static int | silencesuppression = 0 |
| static int | silencethreshold = 1000 |
| static const char | tdesc [] = "ALSA Console Channel Driver" |
| static int | writedev = -1 |
Definition in file chan_alsa.c.
| #define ALSA_INDEV "default" |
Definition at line 74 of file chan_alsa.c.
| #define ALSA_OUTDEV "default" |
Definition at line 75 of file chan_alsa.c.
| #define ALSA_PCM_NEW_HW_PARAMS_API |
Definition at line 43 of file chan_alsa.c.
| #define ALSA_PCM_NEW_SW_PARAMS_API |
Definition at line 44 of file chan_alsa.c.
| #define BUFFER_FMT ((buffersize * 10) << 16) | (0x0006); |
Definition at line 85 of file chan_alsa.c.
| #define DEBUG 0 |
Definition at line 72 of file chan_alsa.c.
Referenced by ast_io_add(), ast_io_wait(), ast_sched_add_variable(), ast_sched_del(), ast_sched_runq(), ast_sched_wait(), ast_sched_when(), and io_grow().
| #define DESIRED_RATE 8000 |
| #define FRAME_SIZE 160 |
Definition at line 79 of file chan_alsa.c.
Referenced by alsa_read(), oss_read(), and soundcard_writeframe().
| #define MAX_BUFFER_SIZE 100 |
Definition at line 128 of file chan_alsa.c.
| #define MIN_SWITCH_TIME 600 |
Definition at line 88 of file chan_alsa.c.
| #define PERIOD_FRAMES 80 |
| static void __reg_module | ( | void | ) | [static] |
Definition at line 1026 of file chan_alsa.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1026 of file chan_alsa.c.
| static int alsa_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 352 of file chan_alsa.c.
References alsa, alsalock, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_UP, ast_verbose, and chan_alsa_pvt::icard.
00353 { 00354 ast_mutex_lock(&alsalock); 00355 ast_verbose(" << Console call has been answered >> \n"); 00356 ast_setstate(c, AST_STATE_UP); 00357 if (!noaudiocapture) { 00358 snd_pcm_prepare(alsa.icard); 00359 snd_pcm_start(alsa.icard); 00360 } 00361 ast_mutex_unlock(&alsalock); 00362 00363 return 0; 00364 }
| static int alsa_call | ( | struct ast_channel * | c, | |
| const char * | dest, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 316 of file chan_alsa.c.
References alsa, alsalock, ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_indicate(), ast_mutex_lock, ast_mutex_unlock, ast_queue_frame(), ast_verbose, grab_owner(), chan_alsa_pvt::icard, ast_frame_subclass::integer, chan_alsa_pvt::owner, and ast_frame::subclass.
00317 { 00318 struct ast_frame f = { AST_FRAME_CONTROL }; 00319 00320 ast_mutex_lock(&alsalock); 00321 ast_verbose(" << Call placed to '%s' on console >> \n", dest); 00322 if (autoanswer) { 00323 ast_verbose(" << Auto-answered >> \n"); 00324 if (mute) { 00325 ast_verbose( " << Muted >> \n" ); 00326 } 00327 grab_owner(); 00328 if (alsa.owner) { 00329 f.subclass.integer = AST_CONTROL_ANSWER; 00330 ast_queue_frame(alsa.owner, &f); 00331 ast_channel_unlock(alsa.owner); 00332 } 00333 } else { 00334 ast_verbose(" << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n"); 00335 grab_owner(); 00336 if (alsa.owner) { 00337 f.subclass.integer = AST_CONTROL_RINGING; 00338 ast_queue_frame(alsa.owner, &f); 00339 ast_channel_unlock(alsa.owner); 00340 ast_indicate(alsa.owner, AST_CONTROL_RINGING); 00341 } 00342 } 00343 if (!noaudiocapture) { 00344 snd_pcm_prepare(alsa.icard); 00345 snd_pcm_start(alsa.icard); 00346 } 00347 ast_mutex_unlock(&alsalock); 00348 00349 return 0; 00350 }
| static snd_pcm_t* alsa_card_init | ( | char * | dev, | |
| snd_pcm_stream_t | stream | |||
| ) | [static] |
Definition at line 164 of file chan_alsa.c.
References ast_debug, ast_log(), DESIRED_RATE, LOG_ERROR, LOG_WARNING, and PERIOD_FRAMES.
Referenced by soundcard_init().
00165 { 00166 int err; 00167 int direction; 00168 snd_pcm_t *handle = NULL; 00169 snd_pcm_hw_params_t *hwparams = NULL; 00170 snd_pcm_sw_params_t *swparams = NULL; 00171 struct pollfd pfd; 00172 snd_pcm_uframes_t period_size = PERIOD_FRAMES * 4; 00173 snd_pcm_uframes_t buffer_size = 0; 00174 unsigned int rate = DESIRED_RATE; 00175 snd_pcm_uframes_t start_threshold, stop_threshold; 00176 00177 err = snd_pcm_open(&handle, dev, stream, SND_PCM_NONBLOCK); 00178 if (err < 0) { 00179 ast_log(LOG_ERROR, "snd_pcm_open failed: %s\n", snd_strerror(err)); 00180 return NULL; 00181 } else { 00182 ast_debug(1, "Opening device %s in %s mode\n", dev, (stream == SND_PCM_STREAM_CAPTURE) ? "read" : "write"); 00183 } 00184 00185 hwparams = alloca(snd_pcm_hw_params_sizeof()); 00186 memset(hwparams, 0, snd_pcm_hw_params_sizeof()); 00187 snd_pcm_hw_params_any(handle, hwparams); 00188 00189 err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); 00190 if (err < 0) 00191 ast_log(LOG_ERROR, "set_access failed: %s\n", snd_strerror(err)); 00192 00193 err = snd_pcm_hw_params_set_format(handle, hwparams, format); 00194 if (err < 0) 00195 ast_log(LOG_ERROR, "set_format failed: %s\n", snd_strerror(err)); 00196 00197 err = snd_pcm_hw_params_set_channels(handle, hwparams, 1); 00198 if (err < 0) 00199 ast_log(LOG_ERROR, "set_channels failed: %s\n", snd_strerror(err)); 00200 00201 direction = 0; 00202 err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, &direction); 00203 if (rate != DESIRED_RATE) 00204 ast_log(LOG_WARNING, "Rate not correct, requested %d, got %d\n", DESIRED_RATE, rate); 00205 00206 direction = 0; 00207 err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, &direction); 00208 if (err < 0) 00209 ast_log(LOG_ERROR, "period_size(%ld frames) is bad: %s\n", period_size, snd_strerror(err)); 00210 else { 00211 ast_debug(1, "Period size is %d\n", err); 00212 } 00213 00214 buffer_size = 4096 * 2; /* period_size * 16; */ 00215 err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size); 00216 if (err < 0) 00217 ast_log(LOG_WARNING, "Problem setting buffer size of %ld: %s\n", buffer_size, snd_strerror(err)); 00218 else { 00219 ast_debug(1, "Buffer size is set to %d frames\n", err); 00220 } 00221 00222 err = snd_pcm_hw_params(handle, hwparams); 00223 if (err < 0) 00224 ast_log(LOG_ERROR, "Couldn't set the new hw params: %s\n", snd_strerror(err)); 00225 00226 swparams = alloca(snd_pcm_sw_params_sizeof()); 00227 memset(swparams, 0, snd_pcm_sw_params_sizeof()); 00228 snd_pcm_sw_params_current(handle, swparams); 00229 00230 if (stream == SND_PCM_STREAM_PLAYBACK) 00231 start_threshold = period_size; 00232 else 00233 start_threshold = 1; 00234 00235 err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold); 00236 if (err < 0) 00237 ast_log(LOG_ERROR, "start threshold: %s\n", snd_strerror(err)); 00238 00239 if (stream == SND_PCM_STREAM_PLAYBACK) 00240 stop_threshold = buffer_size; 00241 else 00242 stop_threshold = buffer_size; 00243 00244 err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold); 00245 if (err < 0) 00246 ast_log(LOG_ERROR, "stop threshold: %s\n", snd_strerror(err)); 00247 00248 err = snd_pcm_sw_params(handle, swparams); 00249 if (err < 0) 00250 ast_log(LOG_ERROR, "sw_params: %s\n", snd_strerror(err)); 00251 00252 err = snd_pcm_poll_descriptors_count(handle); 00253 if (err <= 0) 00254 ast_log(LOG_ERROR, "Unable to get a poll descriptors count, error is %s\n", snd_strerror(err)); 00255 if (err != 1) { 00256 ast_debug(1, "Can't handle more than one device\n"); 00257 } 00258 00259 snd_pcm_poll_descriptors(handle, &pfd, err); 00260 ast_debug(1, "Acquired fd %d from the poll descriptor\n", pfd.fd); 00261 00262 if (stream == SND_PCM_STREAM_CAPTURE) 00263 readdev = pfd.fd; 00264 else 00265 writedev = pfd.fd; 00266 00267 return handle; 00268 }
| static int alsa_digit | ( | struct ast_channel * | c, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Definition at line 290 of file chan_alsa.c.
References alsalock, ast_mutex_lock, ast_mutex_unlock, and ast_verbose.
00291 { 00292 ast_mutex_lock(&alsalock); 00293 ast_verbose(" << Console Received digit %c of duration %u ms >> \n", 00294 digit, duration); 00295 ast_mutex_unlock(&alsalock); 00296 00297 return 0; 00298 }
| static int alsa_fixup | ( | struct ast_channel * | oldchan, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
Definition at line 518 of file chan_alsa.c.
References alsalock, ast_mutex_lock, ast_mutex_unlock, chan_alsa_pvt::owner, and ast_channel::tech_pvt.
00519 { 00520 struct chan_alsa_pvt *p = newchan->tech_pvt; 00521 00522 ast_mutex_lock(&alsalock); 00523 p->owner = newchan; 00524 ast_mutex_unlock(&alsalock); 00525 00526 return 0; 00527 }
| static int alsa_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 366 of file chan_alsa.c.
References alsa, alsalock, ast_module_unref(), ast_mutex_lock, ast_mutex_unlock, ast_verbose, chan_alsa_pvt::icard, chan_alsa_pvt::owner, and ast_channel::tech_pvt.
00367 { 00368 ast_mutex_lock(&alsalock); 00369 c->tech_pvt = NULL; 00370 alsa.owner = NULL; 00371 ast_verbose(" << Hangup on console >> \n"); 00372 ast_module_unref(ast_module_info->self); 00373 hookstate = 0; 00374 if (!noaudiocapture) { 00375 snd_pcm_drop(alsa.icard); 00376 } 00377 ast_mutex_unlock(&alsalock); 00378 00379 return 0; 00380 }
| static int alsa_indicate | ( | struct ast_channel * | chan, | |
| int | cond, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 529 of file chan_alsa.c.
References alsalock, ast_channel_name(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_verbose, and LOG_WARNING.
00530 { 00531 int res = 0; 00532 00533 ast_mutex_lock(&alsalock); 00534 00535 switch (cond) { 00536 case AST_CONTROL_BUSY: 00537 case AST_CONTROL_CONGESTION: 00538 case AST_CONTROL_RINGING: 00539 case AST_CONTROL_INCOMPLETE: 00540 case -1: 00541 res = -1; /* Ask for inband indications */ 00542 break; 00543 case AST_CONTROL_PROGRESS: 00544 case AST_CONTROL_PROCEEDING: 00545 case AST_CONTROL_VIDUPDATE: 00546 case AST_CONTROL_SRCUPDATE: 00547 break; 00548 case AST_CONTROL_HOLD: 00549 ast_verbose(" << Console Has Been Placed on Hold >> \n"); 00550 ast_moh_start(chan, data, mohinterpret); 00551 break; 00552 case AST_CONTROL_UNHOLD: 00553 ast_verbose(" << Console Has Been Retrieved from Hold >> \n"); 00554 ast_moh_stop(chan); 00555 break; 00556 default: 00557 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, ast_channel_name(chan)); 00558 res = -1; 00559 } 00560 00561 ast_mutex_unlock(&alsalock); 00562 00563 return res; 00564 }
| static struct ast_channel* alsa_new | ( | struct chan_alsa_pvt * | p, | |
| int | state, | |||
| const char * | linkedid | |||
| ) | [static, read] |
Definition at line 566 of file chan_alsa.c.
References ast_channel_alloc, ast_channel_name(), ast_channel_set_fd(), ast_copy_string(), ast_format_cap_add(), ast_format_set(), AST_FORMAT_SLINEAR, ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), AST_STATE_DOWN, ast_strlen_zero(), ast_channel::context, chan_alsa_pvt::context, ast_channel::exten, chan_alsa_pvt::exten, global_jbconf, LOG_WARNING, ast_channel::nativeformats, chan_alsa_pvt::owner, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by alsa_request(), and console_dial().
00567 { 00568 struct ast_channel *tmp = NULL; 00569 00570 if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, linkedid, 0, "ALSA/%s", indevname))) 00571 return NULL; 00572 00573 tmp->tech = &alsa_tech; 00574 ast_channel_set_fd(tmp, 0, readdev); 00575 ast_format_set(&tmp->readformat, AST_FORMAT_SLINEAR, 0); 00576 ast_format_set(&tmp->writeformat, AST_FORMAT_SLINEAR, 0); 00577 ast_format_cap_add(tmp->nativeformats, &tmp->writeformat); 00578 00579 tmp->tech_pvt = p; 00580 if (!ast_strlen_zero(p->context)) 00581 ast_copy_string(tmp->context, p->context, sizeof(tmp->context)); 00582 if (!ast_strlen_zero(p->exten)) 00583 ast_copy_string(tmp->exten, p->exten, sizeof(tmp->exten)); 00584 if (!ast_strlen_zero(language)) 00585 ast_channel_language_set(tmp, language); 00586 p->owner = tmp; 00587 ast_module_ref(ast_module_info->self); 00588 ast_jb_configure(tmp, &global_jbconf); 00589 if (state != AST_STATE_DOWN) { 00590 if (ast_pbx_start(tmp)) { 00591 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); 00592 ast_hangup(tmp); 00593 tmp = NULL; 00594 } 00595 } 00596 00597 return tmp; 00598 }
| static struct ast_frame * alsa_read | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 434 of file chan_alsa.c.
References ast_channel::_state, alsa, alsalock, ast_format_set(), AST_FORMAT_SLINEAR, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_STATE_UP, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame_subclass::format, FRAME_SIZE, ast_frame::frametype, chan_alsa_pvt::icard, ast_frame_subclass::integer, LOG_ERROR, ast_frame::mallocd, ast_frame::offset, ast_frame::ptr, ast_frame::samples, ast_frame::src, and ast_frame::subclass.
00435 { 00436 static struct ast_frame f; 00437 static short __buf[FRAME_SIZE + AST_FRIENDLY_OFFSET / 2]; 00438 short *buf; 00439 static int readpos = 0; 00440 static int left = FRAME_SIZE; 00441 snd_pcm_state_t state; 00442 int r = 0; 00443 int off = 0; 00444 00445 ast_mutex_lock(&alsalock); 00446 f.frametype = AST_FRAME_NULL; 00447 f.subclass.integer = 0; 00448 f.samples = 0; 00449 f.datalen = 0; 00450 f.data.ptr = NULL; 00451 f.offset = 0; 00452 f.src = "Console"; 00453 f.mallocd = 0; 00454 f.delivery.tv_sec = 0; 00455 f.delivery.tv_usec = 0; 00456 00457 if (noaudiocapture) { 00458 /* Return null frame to asterisk*/ 00459 ast_mutex_unlock(&alsalock); 00460 return &f; 00461 } 00462 00463 state = snd_pcm_state(alsa.icard); 00464 if ((state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING)) { 00465 snd_pcm_prepare(alsa.icard); 00466 } 00467 00468 buf = __buf + AST_FRIENDLY_OFFSET / 2; 00469 00470 r = snd_pcm_readi(alsa.icard, buf + readpos, left); 00471 if (r == -EPIPE) { 00472 #if DEBUG 00473 ast_log(LOG_ERROR, "XRUN read\n"); 00474 #endif 00475 snd_pcm_prepare(alsa.icard); 00476 } else if (r == -ESTRPIPE) { 00477 ast_log(LOG_ERROR, "-ESTRPIPE\n"); 00478 snd_pcm_prepare(alsa.icard); 00479 } else if (r < 0) { 00480 ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r)); 00481 } else if (r >= 0) { 00482 off -= r; 00483 } 00484 /* Update positions */ 00485 readpos += r; 00486 left -= r; 00487 00488 if (readpos >= FRAME_SIZE) { 00489 /* A real frame */ 00490 readpos = 0; 00491 left = FRAME_SIZE; 00492 if (chan->_state != AST_STATE_UP) { 00493 /* Don't transmit unless it's up */ 00494 ast_mutex_unlock(&alsalock); 00495 return &f; 00496 } 00497 if (mute) { 00498 /* Don't transmit if muted */ 00499 ast_mutex_unlock(&alsalock); 00500 return &f; 00501 } 00502 00503 f.frametype = AST_FRAME_VOICE; 00504 ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR, 0); 00505 f.samples = FRAME_SIZE; 00506 f.datalen = FRAME_SIZE * 2; 00507 f.data.ptr = buf; 00508 f.offset = AST_FRIENDLY_OFFSET; 00509 f.src = "Console"; 00510 f.mallocd = 0; 00511 00512 } 00513 ast_mutex_unlock(&alsalock); 00514 00515 return &f; 00516 }
| static struct ast_channel * alsa_request | ( | const char * | type, | |
| struct ast_format_cap * | cap, | |||
| const struct ast_channel * | requestor, | |||
| const char * | data, | |||
| int * | cause | |||
| ) | [static, read] |
Definition at line 600 of file chan_alsa.c.
References alsa, alsa_new(), alsalock, AST_CAUSE_BUSY, ast_channel_linkedid(), ast_format_cap_iscompatible(), ast_format_set(), AST_FORMAT_SLINEAR, ast_getformatname_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_STATE_DOWN, LOG_NOTICE, LOG_WARNING, and chan_alsa_pvt::owner.
00601 { 00602 struct ast_format tmpfmt; 00603 char buf[256]; 00604 struct ast_channel *tmp = NULL; 00605 00606 ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0); 00607 00608 if (!(ast_format_cap_iscompatible(cap, &tmpfmt))) { 00609 ast_log(LOG_NOTICE, "Asked to get a channel of format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), cap)); 00610 return NULL; 00611 } 00612 00613 ast_mutex_lock(&alsalock); 00614 00615 if (alsa.owner) { 00616 ast_log(LOG_NOTICE, "Already have a call on the ALSA channel\n"); 00617 *cause = AST_CAUSE_BUSY; 00618 } else if (!(tmp = alsa_new(&alsa, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL))) { 00619 ast_log(LOG_WARNING, "Unable to create new ALSA channel\n"); 00620 } 00621 00622 ast_mutex_unlock(&alsalock); 00623 00624 return tmp; 00625 }
| static int alsa_text | ( | struct ast_channel * | c, | |
| const char * | text | |||
| ) | [static] |
Definition at line 300 of file chan_alsa.c.
References alsalock, ast_mutex_lock, ast_mutex_unlock, and ast_verbose.
00301 { 00302 ast_mutex_lock(&alsalock); 00303 ast_verbose(" << Console Received text %s >> \n", text); 00304 ast_mutex_unlock(&alsalock); 00305 00306 return 0; 00307 }
| static int alsa_write | ( | struct ast_channel * | chan, | |
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 382 of file chan_alsa.c.
References alsa, alsalock, ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_frame::data, ast_frame::datalen, len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, chan_alsa_pvt::ocard, and ast_frame::ptr.
00383 { 00384 static char sizbuf[8000]; 00385 static int sizpos = 0; 00386 int len = sizpos; 00387 int res = 0; 00388 /* size_t frames = 0; */ 00389 snd_pcm_state_t state; 00390 00391 ast_mutex_lock(&alsalock); 00392 00393 /* We have to digest the frame in 160-byte portions */ 00394 if (f->datalen > sizeof(sizbuf) - sizpos) { 00395 ast_log(LOG_WARNING, "Frame too large\n"); 00396 res = -1; 00397 } else { 00398 memcpy(sizbuf + sizpos, f->data.ptr, f->datalen); 00399 len += f->datalen; 00400 state = snd_pcm_state(alsa.ocard); 00401 if (state == SND_PCM_STATE_XRUN) 00402 snd_pcm_prepare(alsa.ocard); 00403 while ((res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2)) == -EAGAIN) { 00404 usleep(1); 00405 } 00406 if (res == -EPIPE) { 00407 #if DEBUG 00408 ast_debug(1, "XRUN write\n"); 00409 #endif 00410 snd_pcm_prepare(alsa.ocard); 00411 while ((res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2)) == -EAGAIN) { 00412 usleep(1); 00413 } 00414 if (res != len / 2) { 00415 ast_log(LOG_ERROR, "Write error: %s\n", snd_strerror(res)); 00416 res = -1; 00417 } else if (res < 0) { 00418 ast_log(LOG_ERROR, "Write error %s\n", snd_strerror(res)); 00419 res = -1; 00420 } 00421 } else { 00422 if (res == -ESTRPIPE) 00423 ast_log(LOG_ERROR, "You've got some big problems\n"); 00424 else if (res < 0) 00425 ast_log(LOG_NOTICE, "Error %d on write\n", res); 00426 } 00427 } 00428 ast_mutex_unlock(&alsalock); 00429 00430 return res >= 0 ? 0 : res; 00431 }
| static char* autoanswer_complete | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 627 of file chan_alsa.c.
References ast_strdup, ast_strlen_zero(), and MIN.
Referenced by console_autoanswer().
00628 { 00629 switch (state) { 00630 case 0: 00631 if (!ast_strlen_zero(word) && !strncasecmp(word, "on", MIN(strlen(word), 2))) 00632 return ast_strdup("on"); 00633 case 1: 00634 if (!ast_strlen_zero(word) && !strncasecmp(word, "off", MIN(strlen(word), 3))) 00635 return ast_strdup("off"); 00636 default: 00637 return NULL; 00638 } 00639 00640 return NULL; 00641 }
| static char* console_answer | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 679 of file chan_alsa.c.
References alsa, alsalock, ast_cli_args::argc, ast_channel_unlock, ast_cli(), AST_CONTROL_ANSWER, ast_mutex_lock, ast_mutex_unlock, ast_queue_control(), ast_verbose, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, grab_owner(), chan_alsa_pvt::icard, chan_alsa_pvt::owner, and ast_cli_entry::usage.
00680 { 00681 char *res = CLI_SUCCESS; 00682 00683 switch (cmd) { 00684 case CLI_INIT: 00685 e->command = "console answer"; 00686 e->usage = 00687 "Usage: console answer\n" 00688 " Answers an incoming call on the console (ALSA) channel.\n"; 00689 00690 return NULL; 00691 case CLI_GENERATE: 00692 return NULL; 00693 } 00694 00695 if (a->argc != 2) 00696 return CLI_SHOWUSAGE; 00697 00698 ast_mutex_lock(&alsalock); 00699 00700 if (!alsa.owner) { 00701 ast_cli(a->fd, "No one is calling us\n"); 00702 res = CLI_FAILURE; 00703 } else { 00704 if (mute) { 00705 ast_verbose( " << Muted >> \n" ); 00706 } 00707 hookstate = 1; 00708 grab_owner(); 00709 if (alsa.owner) { 00710 ast_queue_control(alsa.owner, AST_CONTROL_ANSWER); 00711 ast_channel_unlock(alsa.owner); 00712 } 00713 } 00714 00715 if (!noaudiocapture) { 00716 snd_pcm_prepare(alsa.icard); 00717 snd_pcm_start(alsa.icard); 00718 } 00719 00720 ast_mutex_unlock(&alsalock); 00721 00722 return res; 00723 }
| static char* console_autoanswer | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 643 of file chan_alsa.c.
References alsalock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, ast_mutex_unlock, autoanswer_complete(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
00644 { 00645 char *res = CLI_SUCCESS; 00646 00647 switch (cmd) { 00648 case CLI_INIT: 00649 e->command = "console autoanswer"; 00650 e->usage = 00651 "Usage: console autoanswer [on|off]\n" 00652 " Enables or disables autoanswer feature. If used without\n" 00653 " argument, displays the current on/off status of autoanswer.\n" 00654 " The default value of autoanswer is in 'alsa.conf'.\n"; 00655 return NULL; 00656 case CLI_GENERATE: 00657 return autoanswer_complete(a->line, a->word, a->pos, a->n); 00658 } 00659 00660 if ((a->argc != 2) && (a->argc != 3)) 00661 return CLI_SHOWUSAGE; 00662 00663 ast_mutex_lock(&alsalock); 00664 if (a->argc == 2) { 00665 ast_cli(a->fd, "Auto answer is %s.\n", autoanswer ? "on" : "off"); 00666 } else { 00667 if (!strcasecmp(a->argv[2], "on")) 00668 autoanswer = -1; 00669 else if (!strcasecmp(a->argv[2], "off")) 00670 autoanswer = 0; 00671 else 00672 res = CLI_SHOWUSAGE; 00673 } 00674 ast_mutex_unlock(&alsalock); 00675 00676 return res; 00677 }
| static char* console_dial | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 812 of file chan_alsa.c.
References alsa, alsa_new(), alsalock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_exists_extension(), AST_FRAME_DTMF, ast_mutex_lock, ast_mutex_unlock, ast_queue_frame(), AST_STATE_RINGING, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, chan_alsa_pvt::context, chan_alsa_pvt::exten, ast_cli_args::fd, ast_frame::frametype, chan_alsa_pvt::owner, strsep(), and ast_cli_entry::usage.
00813 { 00814 char tmp[256], *tmp2; 00815 char *mye, *myc; 00816 const char *d; 00817 char *res = CLI_SUCCESS; 00818 00819 switch (cmd) { 00820 case CLI_INIT: 00821 e->command = "console dial"; 00822 e->usage = 00823 "Usage: console dial [extension[@context]]\n" 00824 " Dials a given extension (and context if specified)\n"; 00825 return NULL; 00826 case CLI_GENERATE: 00827 return NULL; 00828 } 00829 00830 if ((a->argc != 2) && (a->argc != 3)) 00831 return CLI_SHOWUSAGE; 00832 00833 ast_mutex_lock(&alsalock); 00834 00835 if (alsa.owner) { 00836 if (a->argc == 3) { 00837 if (alsa.owner) { 00838 for (d = a->argv[2]; *d; d++) { 00839 struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = *d }; 00840 00841 ast_queue_frame(alsa.owner, &f); 00842 } 00843 } 00844 } else { 00845 ast_cli(a->fd, "You're already in a call. You can use this only to dial digits until you hangup\n"); 00846 res = CLI_FAILURE; 00847 } 00848 } else { 00849 mye = exten; 00850 myc = context; 00851 if (a->argc == 3) { 00852 char *stringp = NULL; 00853 00854 ast_copy_string(tmp, a->argv[2], sizeof(tmp)); 00855 stringp = tmp; 00856 strsep(&stringp, "@"); 00857 tmp2 = strsep(&stringp, "@"); 00858 if (!ast_strlen_zero(tmp)) 00859 mye = tmp; 00860 if (!ast_strlen_zero(tmp2)) 00861 myc = tmp2; 00862 } 00863 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) { 00864 ast_copy_string(alsa.exten, mye, sizeof(alsa.exten)); 00865 ast_copy_string(alsa.context, myc, sizeof(alsa.context)); 00866 hookstate = 1; 00867 alsa_new(&alsa, AST_STATE_RINGING, NULL); 00868 } else 00869 ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc); 00870 } 00871 00872 ast_mutex_unlock(&alsalock); 00873 00874 return res; 00875 }
| static char* console_hangup | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 774 of file chan_alsa.c.
References alsa, alsalock, ast_cli_args::argc, AST_CAUSE_NORMAL_CLEARING, ast_channel_unlock, ast_cli(), ast_mutex_lock, ast_mutex_unlock, ast_queue_hangup_with_cause(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, grab_owner(), chan_alsa_pvt::owner, and ast_cli_entry::usage.
00775 { 00776 char *res = CLI_SUCCESS; 00777 00778 switch (cmd) { 00779 case CLI_INIT: 00780 e->command = "console hangup"; 00781 e->usage = 00782 "Usage: console hangup\n" 00783 " Hangs up any call currently placed on the console.\n"; 00784 return NULL; 00785 case CLI_GENERATE: 00786 return NULL; 00787 } 00788 00789 00790 if (a->argc != 2) 00791 return CLI_SHOWUSAGE; 00792 00793 ast_mutex_lock(&alsalock); 00794 00795 if (!alsa.owner && !hookstate) { 00796 ast_cli(a->fd, "No call to hangup\n"); 00797 res = CLI_FAILURE; 00798 } else { 00799 hookstate = 0; 00800 grab_owner(); 00801 if (alsa.owner) { 00802 ast_queue_hangup_with_cause(alsa.owner, AST_CAUSE_NORMAL_CLEARING); 00803 ast_channel_unlock(alsa.owner); 00804 } 00805 } 00806 00807 ast_mutex_unlock(&alsalock); 00808 00809 return res; 00810 }
| static char* console_mute | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 877 of file chan_alsa.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
00878 { 00879 int toggle = 0; 00880 char *res = CLI_SUCCESS; 00881 00882 switch (cmd) { 00883 case CLI_INIT: 00884 e->command = "console {mute|unmute} [toggle]"; 00885 e->usage = 00886 "Usage: console {mute|unmute} [toggle]\n" 00887 " Mute/unmute the microphone.\n"; 00888 return NULL; 00889 case CLI_GENERATE: 00890 return NULL; 00891 } 00892 00893 00894 if (a->argc > 3) { 00895 return CLI_SHOWUSAGE; 00896 } 00897 00898 if (a->argc == 3) { 00899 if (strcasecmp(a->argv[2], "toggle")) 00900 return CLI_SHOWUSAGE; 00901 toggle = 1; 00902 } 00903 00904 if (a->argc < 2) { 00905 return CLI_SHOWUSAGE; 00906 } 00907 00908 if (!strcasecmp(a->argv[1], "mute")) { 00909 mute = toggle ? !mute : 1; 00910 } else if (!strcasecmp(a->argv[1], "unmute")) { 00911 mute = toggle ? !mute : 0; 00912 } else { 00913 return CLI_SHOWUSAGE; 00914 } 00915 00916 ast_cli(a->fd, "Console mic is %s\n", mute ? "off" : "on"); 00917 00918 return res; 00919 }
| static char* console_sendtext | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 725 of file chan_alsa.c.
References alsa, alsalock, ast_cli_args::argc, ast_cli_args::argv, ast_channel_unlock, ast_cli(), AST_CONTROL_ANSWER, AST_FRAME_TEXT, ast_mutex_lock, ast_mutex_unlock, ast_queue_control(), ast_queue_frame(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_frame::data, ast_frame::datalen, ast_cli_args::fd, grab_owner(), chan_alsa_pvt::owner, ast_frame::ptr, and ast_cli_entry::usage.
00726 { 00727 int tmparg = 3; 00728 char *res = CLI_SUCCESS; 00729 00730 switch (cmd) { 00731 case CLI_INIT: 00732 e->command = "console send text"; 00733 e->usage = 00734 "Usage: console send text <message>\n" 00735 " Sends a text message for display on the remote terminal.\n"; 00736 return NULL; 00737 case CLI_GENERATE: 00738 return NULL; 00739 } 00740 00741 if (a->argc < 3) 00742 return CLI_SHOWUSAGE; 00743 00744 ast_mutex_lock(&alsalock); 00745 00746 if (!alsa.owner) { 00747 ast_cli(a->fd, "No channel active\n"); 00748 res = CLI_FAILURE; 00749 } else { 00750 struct ast_frame f = { AST_FRAME_TEXT }; 00751 char text2send[256] = ""; 00752 00753 while (tmparg < a->argc) { 00754 strncat(text2send, a->argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1); 00755 strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1); 00756 } 00757 00758 text2send[strlen(text2send) - 1] = '\n'; 00759 f.data.ptr = text2send; 00760 f.datalen = strlen(text2send) + 1; 00761 grab_owner(); 00762 if (alsa.owner) { 00763 ast_queue_frame(alsa.owner, &f); 00764 ast_queue_control(alsa.owner, AST_CONTROL_ANSWER); 00765 ast_channel_unlock(alsa.owner); 00766 } 00767 } 00768 00769 ast_mutex_unlock(&alsalock); 00770 00771 return res; 00772 }
| static void grab_owner | ( | void | ) | [static] |
Definition at line 309 of file chan_alsa.c.
References alsa, alsalock, ast_channel_trylock, DEADLOCK_AVOIDANCE, and chan_alsa_pvt::owner.
Referenced by alsa_call(), console_answer(), console_hangup(), and console_sendtext().
00310 { 00311 while (alsa.owner && ast_channel_trylock(alsa.owner)) { 00312 DEADLOCK_AVOIDANCE(&alsalock); 00313 } 00314 }
| static int load_module | ( | void | ) | [static] |
Definition at line 930 of file chan_alsa.c.
References ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_format_cap_add(), ast_format_cap_alloc(), ast_format_set(), AST_FORMAT_SLINEAR, ast_jb_read_conf(), ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_true(), ast_variable_browse(), ast_verb, ast_channel_tech::capabilities, CONFIG_STATUS_FILEINVALID, global_jbconf, LOG_ERROR, ast_variable::name, ast_variable::next, soundcard_init(), and ast_variable::value.
00931 { 00932 struct ast_config *cfg; 00933 struct ast_variable *v; 00934 struct ast_flags config_flags = { 0 }; 00935 struct ast_format tmpfmt; 00936 00937 if (!(alsa_tech.capabilities = ast_format_cap_alloc())) { 00938 return AST_MODULE_LOAD_DECLINE; 00939 } 00940 ast_format_cap_add(alsa_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0)); 00941 00942 /* Copy the default jb config over global_jbconf */ 00943 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 00944 00945 strcpy(mohinterpret, "default"); 00946 00947 if (!(cfg = ast_config_load(config, config_flags))) { 00948 ast_log(LOG_ERROR, "Unable to read ALSA configuration file %s. Aborting.\n", config); 00949 return AST_MODULE_LOAD_DECLINE; 00950 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 00951 ast_log(LOG_ERROR, "%s is in an invalid format. Aborting.\n", config); 00952 return AST_MODULE_LOAD_DECLINE; 00953 } 00954 00955 v = ast_variable_browse(cfg, "general"); 00956 for (; v; v = v->next) { 00957 /* handle jb conf */ 00958 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) { 00959 continue; 00960 } 00961 00962 if (!strcasecmp(v->name, "autoanswer")) { 00963 autoanswer = ast_true(v->value); 00964 } else if (!strcasecmp(v->name, "mute")) { 00965 mute = ast_true(v->value); 00966 } else if (!strcasecmp(v->name, "noaudiocapture")) { 00967 noaudiocapture = ast_true(v->value); 00968 } else if (!strcasecmp(v->name, "silencesuppression")) { 00969 silencesuppression = ast_true(v->value); 00970 } else if (!strcasecmp(v->name, "silencethreshold")) { 00971 silencethreshold = atoi(v->value); 00972 } else if (!strcasecmp(v->name, "context")) { 00973 ast_copy_string(context, v->value, sizeof(context)); 00974 } else if (!strcasecmp(v->name, "language")) { 00975 ast_copy_string(language, v->value, sizeof(language)); 00976 } else if (!strcasecmp(v->name, "extension")) { 00977 ast_copy_string(exten, v->value, sizeof(exten)); 00978 } else if (!strcasecmp(v->name, "input_device")) { 00979 ast_copy_string(indevname, v->value, sizeof(indevname)); 00980 } else if (!strcasecmp(v->name, "output_device")) { 00981 ast_copy_string(outdevname, v->value, sizeof(outdevname)); 00982 } else if (!strcasecmp(v->name, "mohinterpret")) { 00983 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 00984 } 00985 } 00986 ast_config_destroy(cfg); 00987 00988 if (soundcard_init() < 0) { 00989 ast_verb(2, "No sound card detected -- console channel will be unavailable\n"); 00990 ast_verb(2, "Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n"); 00991 return AST_MODULE_LOAD_DECLINE; 00992 } 00993 00994 if (ast_channel_register(&alsa_tech)) { 00995 ast_log(LOG_ERROR, "Unable to register channel class 'Console'\n"); 00996 return AST_MODULE_LOAD_FAILURE; 00997 } 00998 00999 ast_cli_register_multiple(cli_alsa, ARRAY_LEN(cli_alsa)); 01000 01001 return AST_MODULE_LOAD_SUCCESS; 01002 }
| static int soundcard_init | ( | void | ) | [static] |
Definition at line 270 of file chan_alsa.c.
References alsa, alsa_card_init(), ast_log(), chan_alsa_pvt::icard, LOG_ERROR, and chan_alsa_pvt::ocard.
Referenced by load_module().
00271 { 00272 if (!noaudiocapture) { 00273 alsa.icard = alsa_card_init(indevname, SND_PCM_STREAM_CAPTURE); 00274 if (!alsa.icard) { 00275 ast_log(LOG_ERROR, "Problem opening alsa capture device\n"); 00276 return -1; 00277 } 00278 } 00279 00280 alsa.ocard = alsa_card_init(outdevname, SND_PCM_STREAM_PLAYBACK); 00281 00282 if (!alsa.ocard) { 00283 ast_log(LOG_ERROR, "Problem opening ALSA playback device\n"); 00284 return -1; 00285 } 00286 00287 return writedev; 00288 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 1004 of file chan_alsa.c.
References alsa, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_format_cap_destroy(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_channel_tech::capabilities, chan_alsa_pvt::icard, chan_alsa_pvt::ocard, and chan_alsa_pvt::owner.
01005 { 01006 ast_channel_unregister(&alsa_tech); 01007 ast_cli_unregister_multiple(cli_alsa, ARRAY_LEN(cli_alsa)); 01008 01009 if (alsa.icard) 01010 snd_pcm_close(alsa.icard); 01011 if (alsa.ocard) 01012 snd_pcm_close(alsa.ocard); 01013 if (alsa.owner) 01014 ast_softhangup(alsa.owner, AST_SOFTHANGUP_APPUNLOAD); 01015 if (alsa.owner) 01016 return -1; 01017 01018 alsa_tech.capabilities = ast_format_cap_destroy(alsa_tech.capabilities); 01019 return 0; 01020 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "ALSA Console Channel Driver" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } [static] |
Definition at line 1026 of file chan_alsa.c.
struct chan_alsa_pvt alsa [static] |
struct ast_channel_tech alsa_tech [static] |
Definition at line 149 of file chan_alsa.c.
ast_mutex_t alsalock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static] |
Definition at line 102 of file chan_alsa.c.
Referenced by alsa_answer(), alsa_call(), alsa_digit(), alsa_fixup(), alsa_hangup(), alsa_indicate(), alsa_read(), alsa_request(), alsa_text(), alsa_write(), console_answer(), console_autoanswer(), console_dial(), console_hangup(), console_sendtext(), and grab_owner().
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1026 of file chan_alsa.c.
int autoanswer = 1 [static] |
Definition at line 134 of file chan_alsa.c.
struct ast_cli_entry cli_alsa[] [static] |
Definition at line 921 of file chan_alsa.c.
const char config[] = "alsa.conf" [static] |
Definition at line 105 of file chan_alsa.c.
char context[AST_MAX_CONTEXT] = "default" [static] |
Definition at line 107 of file chan_alsa.c.
Referenced by acf_isexten_exec(), acf_vmcount_exec(), action_atxfer(), action_dialplan_exec(), action_extensionstate(), action_originate(), action_redirect(), add_peer_mailboxes(), aji_handle_pubsub_event(), aji_mwi_cb(), append_mailbox_mapping(), apply_outgoing(), ast_channel_by_exten_cb(), ast_compile_ael2(), ast_event_hash_mwi(), ast_get_enum(), build_device(), build_peer(), check_access(), check_peer_ok(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_include(), conf_run(), create_addr_from_peer(), disa_exec(), extenspy_exec(), extstate_read(), feature_attended_transfer(), feature_blind_transfer(), get_also_info(), get_cid_name(), get_destination(), handle_cli_dialplan_remove_extension(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), has_voicemail(), hint_read(), iax2_call(), iax2_transfer(), isexten_function_read(), jingle_load_config(), launch_ha_netscript(), load_config(), local_call(), local_devicestate(), log_exec(), lua_pbx_exec(), lua_register_hints(), lua_register_switches(), lua_sort_extensions(), mkintf(), notify_message(), orig_exten(), pickup_exec(), process_ast_dsp(), queue_mwi_event(), readexten_exec(), receive_message(), register_peer_exten(), reload_config(), retrydial_exec(), rpt_exec(), set_peer_defaults(), set_pvt_defaults(), sip_alloc(), sla_build_station(), sla_build_trunk(), socket_process(), store_config_core(), unistim_send_mwi_to_peer(), update_registry(), and wait_for_answer().
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 63 of file chan_alsa.c.
char exten[AST_MAX_EXTENSION] = "s" [static] |
Definition at line 109 of file chan_alsa.c.
Referenced by __analog_ss_thread(), action_atxfer(), action_dialplan_exec(), action_extensionstate(), action_originate(), action_redirect(), apply_outgoing(), ast_channel_by_exten_cb(), ast_compile_ael2(), ast_context_remove_extension_callerid2(), ast_ivr_menu_run_internal(), build_extension(), check_access(), check_user_full(), complete_dialplan_remove_extension(), complete_dpreply(), copy_plain_file(), create_queue_member(), destroy_station(), disa_exec(), extenspy_exec(), extstate_read(), feature_attended_transfer(), feature_blind_transfer(), get_cid_name(), get_destination(), get_rdnis(), gtalk_alloc(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_remove_extension(), handle_debug_dialplan(), handle_request_invite(), handle_show_dialplan(), hint_read(), initreqprep(), isexten_function_read(), leave_voicemail(), local_call(), local_devicestate(), lua_pbx_exec(), lua_sort_extensions(), manager_show_dialplan(), mgcp_ss(), new_iax(), orig_exten(), originate_exec(), osplookup_exec(), pickup_exec(), pp_each_extension_helper(), raise_exception(), readexten_exec(), register_verify(), rpt_exec(), set_config(), set_pvt_defaults(), sip_new(), sip_request_call(), sla_build_station(), socket_process(), store_config_core(), transmit_notify_with_mwi(), transmit_register(), user_destructor(), and waitstream_core().
snd_pcm_format_t format = SND_PCM_FORMAT_S16_BE [static] |
Definition at line 93 of file chan_alsa.c.
Referenced by acf_sprintf(), acf_strftime(), acf_strptime(), add_codec_to_answer(), append_cb(), ast_codec_choose(), ast_codec_pref_getsize(), ast_data_add_codecs(), ast_format_attr_reg_interface(), ast_format_attr_unreg_interface(), ast_format_cap_add_all(), ast_format_cap_add_all_by_type(), ast_getformatbyname(), ast_getformatname_multiple(), ast_getformatname_multiple_byid(), ast_monitor_stop(), ast_strftime_locale(), build_peer(), build_user(), check_header(), check_header_fmt(), complete_trans_path_choice(), copy_cb(), file_count_line(), file_read(), file_write(), find_best_byid_cb(), find_joint_cb(), handle_saydatetime(), handle_show_translation_path(), handle_show_translation_table(), hash_cb(), iax2_codec_choose(), load_module(), map_video_codec(), minivm_notify_exec(), multiple_by_id_cb(), multiple_by_type_cb(), process_sdp_a_audio(), sayunixtime_exec(), set_config(), show_codec_n(), show_codecs(), socket_process(), start_monitor_action(), and start_monitor_exec().
struct ast_jb_conf global_jbconf [static] |
Definition at line 70 of file chan_alsa.c.
Referenced by __oh323_rtp_create(), __oh323_update_info(), _build_general_config(), alsa_new(), config_load(), config_parse_variables(), console_new(), dahdi_new(), gtalk_load_config(), gtalk_new(), handle_skinny_show_settings(), jingle_load_config(), jingle_new(), load_config(), load_module(), mgcp_new(), misdn_cfg_init(), misdn_get_global_jbconf(), oss_new(), process_dahdi(), reload_config(), setup_dahdi_int(), sip_get_rtp_peer(), sip_new(), sip_show_settings(), skinny_new(), store_config(), store_config_core(), unistim_new(), and usbradio_new().
int hookstate = 0 [static] |
Definition at line 112 of file chan_alsa.c.
char indevname[50] = ALSA_INDEV [static] |
Definition at line 96 of file chan_alsa.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 108 of file chan_alsa.c.
Referenced by build_peer(), check_peer_ok(), create_addr_from_peer(), func_channel_write_real(), set_peer_defaults(), set_pvt_defaults(), store_config_core(), and tds_load_module().
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 110 of file chan_alsa.c.
Referenced by build_peer(), check_peer_ok(), create_addr_from_peer(), set_peer_defaults(), set_pvt_defaults(), sip_alloc(), and store_config_core().
int mute = 0 [static] |
Definition at line 135 of file chan_alsa.c.
Referenced by ast_console_toggle_mute(), ast_network_puts_mutable(), dahdi_read(), destroy_callback(), dtmf_detect(), func_mute_write(), initialize_mutehook(), manager_mutestream(), mf_detect(), mute_callback(), and tone_detect().
int noaudiocapture = 0 [static] |
Definition at line 136 of file chan_alsa.c.
char outdevname[50] = ALSA_OUTDEV [static] |
Definition at line 97 of file chan_alsa.c.
int readdev = -1 [static] |
Definition at line 131 of file chan_alsa.c.
int silencesuppression = 0 [static] |
Definition at line 99 of file chan_alsa.c.
int silencethreshold = 1000 [static] |
Definition at line 100 of file chan_alsa.c.
const char tdesc[] = "ALSA Console Channel Driver" [static] |
Definition at line 104 of file chan_alsa.c.
int writedev = -1 [static] |
Definition at line 132 of file chan_alsa.c.
1.5.6