#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <alsa/asoundlib.h>
#include "asterisk.h"
#include "asterisk/frame.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/options.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 "busy.h"
#include "ringtone.h"
#include "ring10.h"
#include "answer.h"
Go to the source code of this file.
Data Structures | |
struct | chan_alsa_pvt |
struct | sound |
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(a, b) ((a) < (b) ? (a) : (b)) |
#define | MIN_SWITCH_TIME 600 |
#define | PERIOD_FRAMES 80 |
Functions | |
int | alsa_answer (struct ast_channel *c) |
int | alsa_call (struct ast_channel *c, char *dest, int timeout) |
snd_pcm_t * | alsa_card_init (char *dev, snd_pcm_stream_t stream) |
int | alsa_digit (struct ast_channel *c, char digit) |
int | alsa_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
int | alsa_hangup (struct ast_channel *c) |
int | alsa_indicate (struct ast_channel *chan, int cond) |
ast_channel * | alsa_new (struct chan_alsa_pvt *p, int state) |
ast_frame * | alsa_read (struct ast_channel *chan) |
ast_channel * | alsa_request (const char *type, int format, void *data, int *cause) |
int | alsa_text (struct ast_channel *c, const char *text) |
int | alsa_write (struct ast_channel *chan, struct ast_frame *f) |
void | answer_sound (void) |
AST_MUTEX_DEFINE_STATIC (alsalock) | |
AST_MUTEX_DEFINE_STATIC (usecnt_lock) | |
char * | autoanswer_complete (char *line, char *word, int pos, int state) |
int | console_answer (int fd, int argc, char *argv[]) |
int | console_autoanswer (int fd, int argc, char *argv[]) |
int | console_dial (int fd, int argc, char *argv[]) |
int | console_hangup (int fd, int argc, char *argv[]) |
int | console_sendtext (int fd, int argc, char *argv[]) |
char * | description () |
Provides a description of the module. | |
void | grab_owner (void) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module () |
Initialize the module. | |
int | send_sound (void) |
void * | sound_thread (void *unused) |
int | soundcard_init (void) |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
int | usecount () |
Provides a usecount. | |
Variables | |
chan_alsa_pvt | alsa |
const struct ast_channel_tech | alsa_tech |
char | answer_usage [] |
int | autoanswer = 1 |
char | autoanswer_usage [] |
const char | config [] = "alsa.conf" |
char | context [AST_MAX_CONTEXT] = "default" |
int | cursound = -1 |
const char | desc [] = "ALSA Console Channel Driver" |
char | dial_usage [] |
char | exten [AST_MAX_EXTENSION] = "s" |
snd_pcm_format_t | format = SND_PCM_FORMAT_S16_LE |
char | hangup_usage [] |
int | hookstate = 0 |
char | indevname [50] = ALSA_INDEV |
char | language [MAX_LANGUAGE] = "" |
ast_cli_entry | myclis [] |
int | nosound = 0 |
int | offset = 0 |
char | outdevname [50] = ALSA_OUTDEV |
int | readdev = -1 |
int | sampsent = 0 |
char | sendtext_usage [] |
short | silence [FRAME_SIZE] = {0, } |
int | silencelen = 0 |
int | silencesuppression = 0 |
int | silencethreshold = 1000 |
int | sndcmd [2] |
sound | sounds [] |
pthread_t | sthread |
const char | tdesc [] = "ALSA Console Channel Driver" |
const char | type [] = "Console" |
int | usecnt |
int | writedev = -1 |
Definition in file chan_alsa.c.
|
Definition at line 69 of file chan_alsa.c. |
|
Definition at line 70 of file chan_alsa.c. |
|
Definition at line 38 of file chan_alsa.c. |
|
Definition at line 39 of file chan_alsa.c. |
|
Definition at line 80 of file chan_alsa.c. |
|
Definition at line 67 of file chan_alsa.c. |
|
Definition at line 71 of file chan_alsa.c. Referenced by alsa_card_init(). |
|
Definition at line 74 of file chan_alsa.c. Referenced by alsa_read(), oss_read(), oss_write(), send_sound(), sound_thread(), and soundcard_writeframe(). |
|
Definition at line 158 of file chan_alsa.c. Referenced by soundcard_writeframe(). |
|
Referenced by autoanswer_complete(). |
|
Definition at line 83 of file chan_alsa.c. |
|
Definition at line 75 of file chan_alsa.c. Referenced by alsa_card_init(). |
|
Definition at line 560 of file chan_alsa.c. References alsa, answer_sound(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, ast_verbose(), cursound, and chan_alsa_pvt::icard. 00561 { 00562 ast_mutex_lock(&alsalock); 00563 ast_verbose( " << Console call has been answered >> \n"); 00564 answer_sound(); 00565 ast_setstate(c, AST_STATE_UP); 00566 cursound = -1; 00567 snd_pcm_prepare(alsa.icard); 00568 snd_pcm_start(alsa.icard); 00569 ast_mutex_unlock(&alsalock); 00570 return 0; 00571 }
|
|
Definition at line 521 of file chan_alsa.c. References alsa, AST_FRAME_CONTROL, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), ast_verbose(), grab_owner(), chan_alsa_pvt::icard, ast_channel::lock, chan_alsa_pvt::owner, sndcmd, and ast_frame::subclass. 00522 { 00523 int res = 3; 00524 struct ast_frame f = { AST_FRAME_CONTROL }; 00525 ast_mutex_lock(&alsalock); 00526 ast_verbose( " << Call placed to '%s' on console >> \n", dest); 00527 if (autoanswer) { 00528 ast_verbose( " << Auto-answered >> \n" ); 00529 grab_owner(); 00530 if (alsa.owner) { 00531 f.subclass = AST_CONTROL_ANSWER; 00532 ast_queue_frame(alsa.owner, &f); 00533 ast_mutex_unlock(&alsa.owner->lock); 00534 } 00535 } else { 00536 ast_verbose( " << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n"); 00537 grab_owner(); 00538 if (alsa.owner) { 00539 f.subclass = AST_CONTROL_RINGING; 00540 ast_queue_frame(alsa.owner, &f); 00541 ast_mutex_unlock(&alsa.owner->lock); 00542 } 00543 write(sndcmd[1], &res, sizeof(res)); 00544 } 00545 snd_pcm_prepare(alsa.icard); 00546 snd_pcm_start(alsa.icard); 00547 ast_mutex_unlock(&alsalock); 00548 return 0; 00549 }
|
|
Definition at line 333 of file chan_alsa.c. References ast_log(), DESIRED_RATE, pollfd::fd, format, LOG_DEBUG, LOG_ERROR, LOG_WARNING, PERIOD_FRAMES, readdev, silencethreshold, and writedev. Referenced by soundcard_init(). 00334 { 00335 int err; 00336 int direction; 00337 snd_pcm_t *handle = NULL; 00338 snd_pcm_hw_params_t *hwparams = NULL; 00339 snd_pcm_sw_params_t *swparams = NULL; 00340 struct pollfd pfd; 00341 snd_pcm_uframes_t period_size = PERIOD_FRAMES * 4; 00342 /* int period_bytes = 0; */ 00343 snd_pcm_uframes_t buffer_size = 0; 00344 00345 unsigned int rate = DESIRED_RATE; 00346 #if 0 00347 unsigned int per_min = 1; 00348 #endif 00349 /* unsigned int per_max = 8; */ 00350 snd_pcm_uframes_t start_threshold, stop_threshold; 00351 00352 err = snd_pcm_open(&handle, dev, stream, O_NONBLOCK); 00353 if (err < 0) { 00354 ast_log(LOG_ERROR, "snd_pcm_open failed: %s\n", snd_strerror(err)); 00355 return NULL; 00356 } else { 00357 ast_log(LOG_DEBUG, "Opening device %s in %s mode\n", dev, (stream == SND_PCM_STREAM_CAPTURE) ? "read" : "write"); 00358 } 00359 00360 snd_pcm_hw_params_alloca(&hwparams); 00361 snd_pcm_hw_params_any(handle, hwparams); 00362 00363 err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); 00364 if (err < 0) { 00365 ast_log(LOG_ERROR, "set_access failed: %s\n", snd_strerror(err)); 00366 } 00367 00368 err = snd_pcm_hw_params_set_format(handle, hwparams, format); 00369 if (err < 0) { 00370 ast_log(LOG_ERROR, "set_format failed: %s\n", snd_strerror(err)); 00371 } 00372 00373 err = snd_pcm_hw_params_set_channels(handle, hwparams, 1); 00374 if (err < 0) { 00375 ast_log(LOG_ERROR, "set_channels failed: %s\n", snd_strerror(err)); 00376 } 00377 00378 direction = 0; 00379 err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, &direction); 00380 if (rate != DESIRED_RATE) { 00381 ast_log(LOG_WARNING, "Rate not correct, requested %d, got %d\n", DESIRED_RATE, rate); 00382 } 00383 00384 direction = 0; 00385 err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, &direction); 00386 if (err < 0) { 00387 ast_log(LOG_ERROR, "period_size(%ld frames) is bad: %s\n", period_size, snd_strerror(err)); 00388 } else { 00389 ast_log(LOG_DEBUG, "Period size is %d\n", err); 00390 } 00391 00392 buffer_size = 4096 * 2; /* period_size * 16; */ 00393 err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size); 00394 if (err < 0) { 00395 ast_log(LOG_WARNING, "Problem setting buffer size of %ld: %s\n", buffer_size, snd_strerror(err)); 00396 } else { 00397 ast_log(LOG_DEBUG, "Buffer size is set to %d frames\n", err); 00398 } 00399 00400 #if 0 00401 direction = 0; 00402 err = snd_pcm_hw_params_set_periods_min(handle, hwparams, &per_min, &direction); 00403 if (err < 0) { 00404 ast_log(LOG_ERROR, "periods_min: %s\n", snd_strerror(err)); 00405 } 00406 00407 err = snd_pcm_hw_params_set_periods_max(handle, hwparams, &per_max, 0); 00408 if (err < 0) { 00409 ast_log(LOG_ERROR, "periods_max: %s\n", snd_strerror(err)); 00410 } 00411 #endif 00412 00413 err = snd_pcm_hw_params(handle, hwparams); 00414 if (err < 0) { 00415 ast_log(LOG_ERROR, "Couldn't set the new hw params: %s\n", snd_strerror(err)); 00416 } 00417 00418 snd_pcm_sw_params_alloca(&swparams); 00419 snd_pcm_sw_params_current(handle, swparams); 00420 00421 #if 1 00422 if (stream == SND_PCM_STREAM_PLAYBACK) { 00423 start_threshold = period_size; 00424 } else { 00425 start_threshold = 1; 00426 } 00427 00428 err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold); 00429 if (err < 0) { 00430 ast_log(LOG_ERROR, "start threshold: %s\n", snd_strerror(err)); 00431 } 00432 #endif 00433 00434 #if 1 00435 if (stream == SND_PCM_STREAM_PLAYBACK) { 00436 stop_threshold = buffer_size; 00437 } else { 00438 stop_threshold = buffer_size; 00439 } 00440 err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold); 00441 if (err < 0) { 00442 ast_log(LOG_ERROR, "stop threshold: %s\n", snd_strerror(err)); 00443 } 00444 #endif 00445 #if 0 00446 err = snd_pcm_sw_params_set_xfer_align(handle, swparams, PERIOD_FRAMES); 00447 if (err < 0) { 00448 ast_log(LOG_ERROR, "Unable to set xfer alignment: %s\n", snd_strerror(err)); 00449 } 00450 #endif 00451 00452 #if 0 00453 err = snd_pcm_sw_params_set_silence_threshold(handle, swparams, silencethreshold); 00454 if (err < 0) { 00455 ast_log(LOG_ERROR, "Unable to set silence threshold: %s\n", snd_strerror(err)); 00456 } 00457 #endif 00458 err = snd_pcm_sw_params(handle, swparams); 00459 if (err < 0) { 00460 ast_log(LOG_ERROR, "sw_params: %s\n", snd_strerror(err)); 00461 } 00462 00463 err = snd_pcm_poll_descriptors_count(handle); 00464 if (err <= 0) { 00465 ast_log(LOG_ERROR, "Unable to get a poll descriptors count, error is %s\n", snd_strerror(err)); 00466 } 00467 00468 if (err != 1) { 00469 ast_log(LOG_DEBUG, "Can't handle more than one device\n"); 00470 } 00471 00472 snd_pcm_poll_descriptors(handle, &pfd, err); 00473 ast_log(LOG_DEBUG, "Acquired fd %d from the poll descriptor\n", pfd.fd); 00474 00475 if (stream == SND_PCM_STREAM_CAPTURE) 00476 readdev = pfd.fd; 00477 else 00478 writedev = pfd.fd; 00479 00480 return handle; 00481 }
|
|
Definition at line 496 of file chan_alsa.c. References ast_mutex_lock(), ast_mutex_unlock(), and ast_verbose(). 00497 { 00498 ast_mutex_lock(&alsalock); 00499 ast_verbose( " << Console Received digit %c >> \n", digit); 00500 ast_mutex_unlock(&alsalock); 00501 return 0; 00502 }
|
|
Definition at line 739 of file chan_alsa.c. References ast_mutex_lock(), ast_mutex_unlock(), chan_alsa_pvt::owner, and ast_channel::tech_pvt. 00740 { 00741 struct chan_alsa_pvt *p = newchan->tech_pvt; 00742 ast_mutex_lock(&alsalock); 00743 p->owner = newchan; 00744 ast_mutex_unlock(&alsalock); 00745 return 0; 00746 }
|
|
Definition at line 573 of file chan_alsa.c. References alsa, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), cursound, hookstate, chan_alsa_pvt::icard, chan_alsa_pvt::owner, sndcmd, ast_channel::tech_pvt, and usecnt. 00574 { 00575 int res; 00576 ast_mutex_lock(&alsalock); 00577 cursound = -1; 00578 c->tech_pvt = NULL; 00579 alsa.owner = NULL; 00580 ast_verbose( " << Hangup on console >> \n"); 00581 ast_mutex_lock(&usecnt_lock); 00582 usecnt--; 00583 ast_mutex_unlock(&usecnt_lock); 00584 if (hookstate) { 00585 if (autoanswer) { 00586 hookstate = 0; 00587 } else { 00588 /* Congestion noise */ 00589 res = 2; 00590 write(sndcmd[1], &res, sizeof(res)); 00591 hookstate = 0; 00592 } 00593 } 00594 snd_pcm_drop(alsa.icard); 00595 ast_mutex_unlock(&alsalock); 00596 return 0; 00597 }
|
|
Definition at line 748 of file chan_alsa.c. References AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_RINGING, AST_CONTROL_VIDUPDATE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, ast_channel::name, and sndcmd. 00749 { 00750 int res = 0; 00751 ast_mutex_lock(&alsalock); 00752 switch(cond) { 00753 case AST_CONTROL_BUSY: 00754 res = 1; 00755 break; 00756 case AST_CONTROL_CONGESTION: 00757 res = 2; 00758 break; 00759 case AST_CONTROL_RINGING: 00760 res = 0; 00761 break; 00762 case -1: 00763 res = -1; 00764 break; 00765 case AST_CONTROL_VIDUPDATE: 00766 res = -1; 00767 break; 00768 default: 00769 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, chan->name); 00770 res = -1; 00771 } 00772 if (res > -1) { 00773 write(sndcmd[1], &res, sizeof(res)); 00774 } 00775 ast_mutex_unlock(&alsalock); 00776 return res; 00777 }
|
|
Definition at line 779 of file chan_alsa.c. References ast_channel_alloc(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_setstate(), ast_strlen_zero(), ast_update_use_count(), ast_channel::context, chan_alsa_pvt::context, ast_channel::exten, chan_alsa_pvt::exten, ast_channel::fds, indevname, ast_channel::language, language, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, chan_alsa_pvt::owner, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt, and ast_channel::writeformat. Referenced by alsa_request(), and console_dial(). 00780 { 00781 struct ast_channel *tmp; 00782 tmp = ast_channel_alloc(1); 00783 if (tmp) { 00784 tmp->tech = &alsa_tech; 00785 snprintf(tmp->name, sizeof(tmp->name), "ALSA/%s", indevname); 00786 tmp->type = type; 00787 tmp->fds[0] = readdev; 00788 tmp->nativeformats = AST_FORMAT_SLINEAR; 00789 tmp->readformat = AST_FORMAT_SLINEAR; 00790 tmp->writeformat = AST_FORMAT_SLINEAR; 00791 tmp->tech_pvt = p; 00792 if (!ast_strlen_zero(p->context)) 00793 ast_copy_string(tmp->context, p->context, sizeof(tmp->context)); 00794 if (!ast_strlen_zero(p->exten)) 00795 ast_copy_string(tmp->exten, p->exten, sizeof(tmp->exten)); 00796 if (!ast_strlen_zero(language)) 00797 ast_copy_string(tmp->language, language, sizeof(tmp->language)); 00798 p->owner = tmp; 00799 ast_setstate(tmp, state); 00800 ast_mutex_lock(&usecnt_lock); 00801 usecnt++; 00802 ast_mutex_unlock(&usecnt_lock); 00803 ast_update_use_count(); 00804 if (state != AST_STATE_DOWN) { 00805 if (ast_pbx_start(tmp)) { 00806 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 00807 ast_hangup(tmp); 00808 tmp = NULL; 00809 } 00810 } 00811 } 00812 return tmp; 00813 }
|
|
Definition at line 663 of file chan_alsa.c. References ast_channel::_state, alsa, AST_FRIENDLY_OFFSET, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, FRAME_SIZE, ast_frame::frametype, chan_alsa_pvt::icard, LOG_ERROR, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass. 00664 { 00665 static struct ast_frame f; 00666 static short __buf[FRAME_SIZE + AST_FRIENDLY_OFFSET/2]; 00667 short *buf; 00668 static int readpos = 0; 00669 static int left = FRAME_SIZE; 00670 snd_pcm_state_t state; 00671 int r = 0; 00672 int off = 0; 00673 00674 ast_mutex_lock(&alsalock); 00675 /* Acknowledge any pending cmd */ 00676 f.frametype = AST_FRAME_NULL; 00677 f.subclass = 0; 00678 f.samples = 0; 00679 f.datalen = 0; 00680 f.data = NULL; 00681 f.offset = 0; 00682 f.src = type; 00683 f.mallocd = 0; 00684 f.delivery.tv_sec = 0; 00685 f.delivery.tv_usec = 0; 00686 00687 state = snd_pcm_state(alsa.icard); 00688 if ((state != SND_PCM_STATE_PREPARED) && 00689 (state != SND_PCM_STATE_RUNNING)) { 00690 snd_pcm_prepare(alsa.icard); 00691 } 00692 00693 buf = __buf + AST_FRIENDLY_OFFSET/2; 00694 00695 r = snd_pcm_readi(alsa.icard, buf + readpos, left); 00696 if (r == -EPIPE) { 00697 #if DEBUG 00698 ast_log(LOG_ERROR, "XRUN read\n"); 00699 #endif 00700 snd_pcm_prepare(alsa.icard); 00701 } else if (r == -ESTRPIPE) { 00702 ast_log(LOG_ERROR, "-ESTRPIPE\n"); 00703 snd_pcm_prepare(alsa.icard); 00704 } else if (r < 0) { 00705 ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r)); 00706 } else if (r >= 0) { 00707 off -= r; 00708 } 00709 /* Update positions */ 00710 readpos += r; 00711 left -= r; 00712 00713 if (readpos >= FRAME_SIZE) { 00714 /* A real frame */ 00715 readpos = 0; 00716 left = FRAME_SIZE; 00717 if (chan->_state != AST_STATE_UP) { 00718 /* Don't transmit unless it's up */ 00719 ast_mutex_unlock(&alsalock); 00720 return &f; 00721 } 00722 f.frametype = AST_FRAME_VOICE; 00723 f.subclass = AST_FORMAT_SLINEAR; 00724 f.samples = FRAME_SIZE; 00725 f.datalen = FRAME_SIZE * 2; 00726 f.data = buf; 00727 f.offset = AST_FRIENDLY_OFFSET; 00728 f.src = type; 00729 f.mallocd = 0; 00730 #ifdef ALSA_MONITOR 00731 alsa_monitor_read((char *)buf, FRAME_SIZE * 2); 00732 #endif 00733 00734 } 00735 ast_mutex_unlock(&alsalock); 00736 return &f; 00737 }
|
|
Definition at line 815 of file chan_alsa.c. References alsa, alsa_new(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, format, LOG_NOTICE, LOG_WARNING, and chan_alsa_pvt::owner. 00816 { 00817 int oldformat = format; 00818 struct ast_channel *tmp=NULL; 00819 format &= AST_FORMAT_SLINEAR; 00820 if (!format) { 00821 ast_log(LOG_NOTICE, "Asked to get a channel of format '%d'\n", oldformat); 00822 return NULL; 00823 } 00824 ast_mutex_lock(&alsalock); 00825 if (alsa.owner) { 00826 ast_log(LOG_NOTICE, "Already have a call on the ALSA channel\n"); 00827 *cause = AST_CAUSE_BUSY; 00828 } else { 00829 tmp= alsa_new(&alsa, AST_STATE_DOWN); 00830 if (!tmp) { 00831 ast_log(LOG_WARNING, "Unable to create new ALSA channel\n"); 00832 } 00833 } 00834 ast_mutex_unlock(&alsalock); 00835 return tmp; 00836 }
|
|
Definition at line 504 of file chan_alsa.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), and text. 00505 { 00506 ast_mutex_lock(&alsalock); 00507 ast_verbose( " << Console Received text %s >> \n", text); 00508 ast_mutex_unlock(&alsalock); 00509 return 0; 00510 }
|
|
Definition at line 599 of file chan_alsa.c. References alsa, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), cursound, ast_frame::data, ast_frame::datalen, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, and chan_alsa_pvt::ocard. 00600 { 00601 static char sizbuf[8000]; 00602 static int sizpos = 0; 00603 int len = sizpos; 00604 int pos; 00605 int res = 0; 00606 /* size_t frames = 0; */ 00607 snd_pcm_state_t state; 00608 /* Immediately return if no sound is enabled */ 00609 if (nosound) 00610 return 0; 00611 ast_mutex_lock(&alsalock); 00612 /* Stop any currently playing sound */ 00613 if (cursound != -1) { 00614 snd_pcm_drop(alsa.ocard); 00615 snd_pcm_prepare(alsa.ocard); 00616 cursound = -1; 00617 } 00618 00619 00620 /* We have to digest the frame in 160-byte portions */ 00621 if (f->datalen > sizeof(sizbuf) - sizpos) { 00622 ast_log(LOG_WARNING, "Frame too large\n"); 00623 res = -1; 00624 } else { 00625 memcpy(sizbuf + sizpos, f->data, f->datalen); 00626 len += f->datalen; 00627 pos = 0; 00628 #ifdef ALSA_MONITOR 00629 alsa_monitor_write(sizbuf, len); 00630 #endif 00631 state = snd_pcm_state(alsa.ocard); 00632 if (state == SND_PCM_STATE_XRUN) { 00633 snd_pcm_prepare(alsa.ocard); 00634 } 00635 res = snd_pcm_writei(alsa.ocard, sizbuf, len/2); 00636 if (res == -EPIPE) { 00637 #if DEBUG 00638 ast_log(LOG_DEBUG, "XRUN write\n"); 00639 #endif 00640 snd_pcm_prepare(alsa.ocard); 00641 res = snd_pcm_writei(alsa.ocard, sizbuf, len/2); 00642 if (res != len/2) { 00643 ast_log(LOG_ERROR, "Write error: %s\n", snd_strerror(res)); 00644 res = -1; 00645 } else if (res < 0) { 00646 ast_log(LOG_ERROR, "Write error %s\n", snd_strerror(res)); 00647 res = -1; 00648 } 00649 } else { 00650 if (res == -ESTRPIPE) { 00651 ast_log(LOG_ERROR, "You've got some big problems\n"); 00652 } else if (res < 0) 00653 ast_log(LOG_NOTICE, "Error %d on write\n", res); 00654 } 00655 } 00656 ast_mutex_unlock(&alsalock); 00657 if (res > 0) 00658 res = 0; 00659 return res; 00660 }
|
|
Definition at line 551 of file chan_alsa.c. References nosound, and sndcmd. Referenced by alsa_answer(), console_answer(), and oss_answer(). 00552 { 00553 int res; 00554 nosound = 1; 00555 res = 4; 00556 write(sndcmd[1], &res, sizeof(res)); 00557 00558 }
|
|
|
|
|
|
Definition at line 858 of file chan_alsa.c. References ast_strlen_zero(), MIN, and strdup. 00859 { 00860 #ifndef MIN 00861 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 00862 #endif 00863 switch(state) { 00864 case 0: 00865 if (!ast_strlen_zero(word) && !strncasecmp(word, "on", MIN(strlen(word), 2))) 00866 return strdup("on"); 00867 case 1: 00868 if (!ast_strlen_zero(word) && !strncasecmp(word, "off", MIN(strlen(word), 3))) 00869 return strdup("off"); 00870 default: 00871 return NULL; 00872 } 00873 return NULL; 00874 }
|
|
Definition at line 882 of file chan_alsa.c. References alsa, answer_sound(), ast_cli(), AST_CONTROL_ANSWER, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), cursound, grab_owner(), hookstate, chan_alsa_pvt::icard, ast_channel::lock, and chan_alsa_pvt::owner. 00883 { 00884 int res = RESULT_SUCCESS; 00885 if (argc != 1) 00886 return RESULT_SHOWUSAGE; 00887 ast_mutex_lock(&alsalock); 00888 if (!alsa.owner) { 00889 ast_cli(fd, "No one is calling us\n"); 00890 res = RESULT_FAILURE; 00891 } else { 00892 hookstate = 1; 00893 cursound = -1; 00894 grab_owner(); 00895 if (alsa.owner) { 00896 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; 00897 ast_queue_frame(alsa.owner, &f); 00898 ast_mutex_unlock(&alsa.owner->lock); 00899 } 00900 answer_sound(); 00901 } 00902 snd_pcm_prepare(alsa.icard); 00903 snd_pcm_start(alsa.icard); 00904 ast_mutex_unlock(&alsalock); 00905 return RESULT_SUCCESS; 00906 }
|
|
Definition at line 838 of file chan_alsa.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), and autoanswer. 00839 { 00840 int res = RESULT_SUCCESS;; 00841 if ((argc != 1) && (argc != 2)) 00842 return RESULT_SHOWUSAGE; 00843 ast_mutex_lock(&alsalock); 00844 if (argc == 1) { 00845 ast_cli(fd, "Auto answer is %s.\n", autoanswer ? "on" : "off"); 00846 } else { 00847 if (!strcasecmp(argv[1], "on")) 00848 autoanswer = -1; 00849 else if (!strcasecmp(argv[1], "off")) 00850 autoanswer = 0; 00851 else 00852 res = RESULT_SHOWUSAGE; 00853 } 00854 ast_mutex_unlock(&alsalock); 00855 return res; 00856 }
|
|
Definition at line 979 of file chan_alsa.c. References alsa, alsa_new(), ast_cli(), ast_exists_extension(), AST_FRAME_DTMF, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), AST_STATE_RINGING, ast_strlen_zero(), chan_alsa_pvt::context, chan_alsa_pvt::exten, grab_owner(), hookstate, ast_channel::lock, chan_alsa_pvt::owner, strsep(), and ast_frame::subclass. 00980 { 00981 char tmp[256], *tmp2; 00982 char *mye, *myc; 00983 char *d; 00984 int res = RESULT_SUCCESS; 00985 if ((argc != 1) && (argc != 2)) 00986 return RESULT_SHOWUSAGE; 00987 ast_mutex_lock(&alsalock); 00988 if (alsa.owner) { 00989 if (argc == 2) { 00990 d = argv[1]; 00991 grab_owner(); 00992 if (alsa.owner) { 00993 struct ast_frame f = { AST_FRAME_DTMF }; 00994 while(*d) { 00995 f.subclass = *d; 00996 ast_queue_frame(alsa.owner, &f); 00997 d++; 00998 } 00999 ast_mutex_unlock(&alsa.owner->lock); 01000 } 01001 } else { 01002 ast_cli(fd, "You're already in a call. You can use this only to dial digits until you hangup\n"); 01003 res = RESULT_FAILURE; 01004 } 01005 } else { 01006 mye = exten; 01007 myc = context; 01008 if (argc == 2) { 01009 char *stringp=NULL; 01010 strncpy(tmp, argv[1], sizeof(tmp)-1); 01011 stringp=tmp; 01012 strsep(&stringp, "@"); 01013 tmp2 = strsep(&stringp, "@"); 01014 if (!ast_strlen_zero(tmp)) 01015 mye = tmp; 01016 if (!ast_strlen_zero(tmp2)) 01017 myc = tmp2; 01018 } 01019 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) { 01020 strncpy(alsa.exten, mye, sizeof(alsa.exten)-1); 01021 strncpy(alsa.context, myc, sizeof(alsa.context)-1); 01022 hookstate = 1; 01023 alsa_new(&alsa, AST_STATE_RINGING); 01024 } else 01025 ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc); 01026 } 01027 ast_mutex_unlock(&alsalock); 01028 return res; 01029 }
|
|
Definition at line 952 of file chan_alsa.c. References alsa, ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), cursound, grab_owner(), hookstate, ast_channel::lock, and chan_alsa_pvt::owner. 00953 { 00954 int res = RESULT_SUCCESS; 00955 if (argc != 1) 00956 return RESULT_SHOWUSAGE; 00957 cursound = -1; 00958 ast_mutex_lock(&alsalock); 00959 if (!alsa.owner && !hookstate) { 00960 ast_cli(fd, "No call to hangup up\n"); 00961 res = RESULT_FAILURE; 00962 } else { 00963 hookstate = 0; 00964 grab_owner(); 00965 if (alsa.owner) { 00966 ast_queue_hangup(alsa.owner); 00967 ast_mutex_unlock(&alsa.owner->lock); 00968 } 00969 } 00970 ast_mutex_unlock(&alsalock); 00971 return res; 00972 }
|
|
Definition at line 912 of file chan_alsa.c. References alsa, ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, grab_owner(), ast_channel::lock, chan_alsa_pvt::owner, and ast_frame::subclass. 00913 { 00914 int tmparg = 2; 00915 int res = RESULT_SUCCESS; 00916 if (argc < 2) 00917 return RESULT_SHOWUSAGE; 00918 ast_mutex_lock(&alsalock); 00919 if (!alsa.owner) { 00920 ast_cli(fd, "No one is calling us\n"); 00921 res = RESULT_FAILURE; 00922 } else { 00923 struct ast_frame f = { AST_FRAME_TEXT, 0 }; 00924 char text2send[256] = ""; 00925 text2send[0] = '\0'; 00926 while(tmparg < argc) { 00927 strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1); 00928 strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1); 00929 } 00930 text2send[strlen(text2send) - 1] = '\n'; 00931 f.data = text2send; 00932 f.datalen = strlen(text2send) + 1; 00933 grab_owner(); 00934 if (alsa.owner) { 00935 ast_queue_frame(alsa.owner, &f); 00936 f.frametype = AST_FRAME_CONTROL; 00937 f.subclass = AST_CONTROL_ANSWER; 00938 f.data = NULL; 00939 f.datalen = 0; 00940 ast_queue_frame(alsa.owner, &f); 00941 ast_mutex_unlock(&alsa.owner->lock); 00942 } 00943 } 00944 ast_mutex_unlock(&alsalock); 00945 return res; 00946 }
|
|
Provides a description of the module.
Definition at line 1127 of file chan_alsa.c. 01128 { 01129 return (char *) desc; 01130 }
|
|
Definition at line 512 of file chan_alsa.c. References alsa, ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_channel::lock, and chan_alsa_pvt::owner. Referenced by alsa_call(), console_answer(), console_dial(), console_hangup(), and console_sendtext(). 00513 { 00514 while(alsa.owner && ast_mutex_trylock(&alsa.owner->lock)) { 00515 ast_mutex_unlock(&alsalock); 00516 usleep(1); 00517 ast_mutex_lock(&alsalock); 00518 } 00519 }
|
|
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 1137 of file chan_alsa.c. 01138 {
01139 return ASTERISK_GPL_KEY;
01140 }
|
|
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 1044 of file chan_alsa.c. References alsa_tech, ast_channel_register(), ast_cli_register(), ast_config_destroy(), ast_config_load(), ast_log(), ast_pthread_create, ast_true(), ast_variable_browse(), ast_verbose(), autoanswer, cfg, config, context, exten, indevname, language, LOG_ERROR, myclis, ast_variable::name, ast_variable::next, option_verbose, outdevname, silencesuppression, silencethreshold, sndcmd, sound_thread(), soundcard_init(), sthread, type, ast_variable::value, and VERBOSE_PREFIX_2. 01045 { 01046 int res; 01047 int x; 01048 struct ast_config *cfg; 01049 struct ast_variable *v; 01050 if ((cfg = ast_config_load(config))) { 01051 v = ast_variable_browse(cfg, "general"); 01052 while(v) { 01053 if (!strcasecmp(v->name, "autoanswer")) 01054 autoanswer = ast_true(v->value); 01055 else if (!strcasecmp(v->name, "silencesuppression")) 01056 silencesuppression = ast_true(v->value); 01057 else if (!strcasecmp(v->name, "silencethreshold")) 01058 silencethreshold = atoi(v->value); 01059 else if (!strcasecmp(v->name, "context")) 01060 strncpy(context, v->value, sizeof(context)-1); 01061 else if (!strcasecmp(v->name, "language")) 01062 strncpy(language, v->value, sizeof(language)-1); 01063 else if (!strcasecmp(v->name, "extension")) 01064 strncpy(exten, v->value, sizeof(exten)-1); 01065 else if (!strcasecmp(v->name, "input_device")) 01066 strncpy(indevname, v->value, sizeof(indevname)-1); 01067 else if (!strcasecmp(v->name, "output_device")) 01068 strncpy(outdevname, v->value, sizeof(outdevname)-1); 01069 v=v->next; 01070 } 01071 ast_config_destroy(cfg); 01072 } 01073 res = pipe(sndcmd); 01074 if (res) { 01075 ast_log(LOG_ERROR, "Unable to create pipe\n"); 01076 return -1; 01077 } 01078 res = soundcard_init(); 01079 if (res < 0) { 01080 if (option_verbose > 1) { 01081 ast_verbose(VERBOSE_PREFIX_2 "No sound card detected -- console channel will be unavailable\n"); 01082 ast_verbose(VERBOSE_PREFIX_2 "Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n"); 01083 } 01084 return 0; 01085 } 01086 01087 res = ast_channel_register(&alsa_tech); 01088 if (res < 0) { 01089 ast_log(LOG_ERROR, "Unable to register channel class '%s'\n", type); 01090 return -1; 01091 } 01092 for (x=0;x<sizeof(myclis)/sizeof(struct ast_cli_entry); x++) 01093 ast_cli_register(myclis + x); 01094 ast_pthread_create(&sthread, NULL, sound_thread, NULL); 01095 #ifdef ALSA_MONITOR 01096 if (alsa_monitor_start()) { 01097 ast_log(LOG_ERROR, "Problem starting Monitoring\n"); 01098 } 01099 #endif 01100 return 0; 01101 }
|
|
Definition at line 200 of file chan_alsa.c. References alsa, cursound, sound::datalen, nosound, chan_alsa_pvt::ocard, offset, sound::repeat, sound::samplen, sampsent, sound::silencelen, silencelen, and sounds. Referenced by sound_thread(). 00201 { 00202 short myframe[FRAME_SIZE]; 00203 int total = FRAME_SIZE; 00204 short *frame = NULL; 00205 int amt=0; 00206 int res; 00207 int myoff; 00208 snd_pcm_state_t state; 00209 00210 if (cursound > -1) { 00211 res = total; 00212 if (sampsent < sounds[cursound].samplen) { 00213 myoff=0; 00214 while(total) { 00215 amt = total; 00216 if (amt > (sounds[cursound].datalen - offset)) 00217 amt = sounds[cursound].datalen - offset; 00218 memcpy(myframe + myoff, sounds[cursound].data + offset, amt * 2); 00219 total -= amt; 00220 offset += amt; 00221 sampsent += amt; 00222 myoff += amt; 00223 if (offset >= sounds[cursound].datalen) 00224 offset = 0; 00225 } 00226 /* Set it up for silence */ 00227 if (sampsent >= sounds[cursound].samplen) 00228 silencelen = sounds[cursound].silencelen; 00229 frame = myframe; 00230 } else { 00231 if (silencelen > 0) { 00232 frame = silence; 00233 silencelen -= res; 00234 } else { 00235 if (sounds[cursound].repeat) { 00236 /* Start over */ 00237 sampsent = 0; 00238 offset = 0; 00239 } else { 00240 cursound = -1; 00241 nosound = 0; 00242 } 00243 return 0; 00244 } 00245 } 00246 00247 if (res == 0 || !frame) { 00248 return 0; 00249 } 00250 #ifdef ALSA_MONITOR 00251 alsa_monitor_write((char *)frame, res * 2); 00252 #endif 00253 state = snd_pcm_state(alsa.ocard); 00254 if (state == SND_PCM_STATE_XRUN) { 00255 snd_pcm_prepare(alsa.ocard); 00256 } 00257 res = snd_pcm_writei(alsa.ocard, frame, res); 00258 if (res > 0) 00259 return 0; 00260 return 0; 00261 } 00262 return 0; 00263 }
|
|
Definition at line 265 of file chan_alsa.c. References alsa, ast_log(), ast_select(), cursound, FRAME_SIZE, chan_alsa_pvt::icard, LOG_ERROR, LOG_WARNING, chan_alsa_pvt::ocard, offset, chan_alsa_pvt::owner, ast_channel_tech::read, readdev, sampsent, send_sound(), silencelen, sndcmd, and writedev. Referenced by load_module(). 00266 { 00267 fd_set rfds; 00268 fd_set wfds; 00269 int max; 00270 int res; 00271 for(;;) { 00272 FD_ZERO(&rfds); 00273 FD_ZERO(&wfds); 00274 max = sndcmd[0]; 00275 FD_SET(sndcmd[0], &rfds); 00276 if (cursound > -1) { 00277 FD_SET(writedev, &wfds); 00278 if (writedev > max) 00279 max = writedev; 00280 } 00281 #ifdef ALSA_MONITOR 00282 if (!alsa.owner) { 00283 FD_SET(readdev, &rfds); 00284 if (readdev > max) 00285 max = readdev; 00286 } 00287 #endif 00288 res = ast_select(max + 1, &rfds, &wfds, NULL, NULL); 00289 if (res < 1) { 00290 ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno)); 00291 continue; 00292 } 00293 #ifdef ALSA_MONITOR 00294 if (FD_ISSET(readdev, &rfds)) { 00295 /* Keep the pipe going with read audio */ 00296 snd_pcm_state_t state; 00297 short buf[FRAME_SIZE]; 00298 int r; 00299 00300 state = snd_pcm_state(alsa.ocard); 00301 if (state == SND_PCM_STATE_XRUN) { 00302 snd_pcm_prepare(alsa.ocard); 00303 } 00304 r = snd_pcm_readi(alsa.icard, buf, FRAME_SIZE); 00305 if (r == -EPIPE) { 00306 #if DEBUG 00307 ast_log(LOG_ERROR, "XRUN read\n"); 00308 #endif 00309 snd_pcm_prepare(alsa.icard); 00310 } else if (r == -ESTRPIPE) { 00311 ast_log(LOG_ERROR, "-ESTRPIPE\n"); 00312 snd_pcm_prepare(alsa.icard); 00313 } else if (r < 0) { 00314 ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r)); 00315 } else 00316 alsa_monitor_read((char *)buf, r * 2); 00317 } 00318 #endif 00319 if (FD_ISSET(sndcmd[0], &rfds)) { 00320 read(sndcmd[0], &cursound, sizeof(cursound)); 00321 silencelen = 0; 00322 offset = 0; 00323 sampsent = 0; 00324 } 00325 if (FD_ISSET(writedev, &wfds)) 00326 if (send_sound()) 00327 ast_log(LOG_WARNING, "Failed to write sound\n"); 00328 } 00329 /* Never reached */ 00330 return NULL; 00331 }
|
|
Definition at line 483 of file chan_alsa.c. References alsa, alsa_card_init(), ast_log(), chan_alsa_pvt::icard, indevname, LOG_ERROR, chan_alsa_pvt::ocard, and outdevname. Referenced by load_module(). 00484 { 00485 alsa.icard = alsa_card_init(indevname, SND_PCM_STREAM_CAPTURE); 00486 alsa.ocard = alsa_card_init(outdevname, SND_PCM_STREAM_PLAYBACK); 00487 00488 if (!alsa.icard || !alsa.ocard) { 00489 ast_log(LOG_ERROR, "Problem opening alsa I/O devices\n"); 00490 return -1; 00491 } 00492 00493 return readdev; 00494 }
|
|
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 1105 of file chan_alsa.c. References alsa, alsa_tech, ast_channel_unregister(), ast_cli_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, chan_alsa_pvt::icard, myclis, chan_alsa_pvt::ocard, chan_alsa_pvt::owner, and sndcmd. 01106 { 01107 int x; 01108 01109 ast_channel_unregister(&alsa_tech); 01110 for (x=0;x<sizeof(myclis)/sizeof(struct ast_cli_entry); x++) 01111 ast_cli_unregister(myclis + x); 01112 if (alsa.icard) 01113 snd_pcm_close(alsa.icard); 01114 if (alsa.ocard) 01115 snd_pcm_close(alsa.ocard); 01116 if (sndcmd[0] > 0) { 01117 close(sndcmd[0]); 01118 close(sndcmd[1]); 01119 } 01120 if (alsa.owner) 01121 ast_softhangup(alsa.owner, AST_SOFTHANGUP_APPUNLOAD); 01122 if (alsa.owner) 01123 return -1; 01124 return 0; 01125 }
|
|
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 1132 of file chan_alsa.c. 01133 {
01134 return usecnt;
01135 }
|
|
|
Definition at line 184 of file chan_alsa.c. Referenced by load_module(), and unload_module(). |
|
Initial value: "Usage: answer\n" " Answers an incoming call on the console (ALSA) channel.\n" Definition at line 948 of file chan_alsa.c. |
|
Definition at line 164 of file chan_alsa.c. Referenced by console_autoanswer(), and load_module(). |
|
Initial value: "Usage: autoanswer [on|off]\n" " Enables or disables autoanswer feature. If used without\n" " argument, displays the current on/off status of autoanswer.\n" " The default value of autoanswer is in 'alsa.conf'.\n" Definition at line 876 of file chan_alsa.c. |
|
Definition at line 109 of file chan_alsa.c. Referenced by load_module(). |
|
Definition at line 111 of file chan_alsa.c. Referenced by load_module(). |
|
Definition at line 166 of file chan_alsa.c. Referenced by alsa_answer(), alsa_hangup(), alsa_write(), console_answer(), console_hangup(), send_sound(), and sound_thread(). |
|
Definition at line 107 of file chan_alsa.c. |
|
Initial value: "Usage: dial [extension[@context]]\n" " Dials a given extension (and context if specified)\n" Definition at line 1031 of file chan_alsa.c. |
|
Definition at line 113 of file chan_alsa.c. Referenced by load_module(). |
|
Definition at line 86 of file chan_alsa.c. Referenced by alsa_card_init(), and alsa_request(). |
|
Initial value: "Usage: hangup\n" " Hangs up any call currently placed on the console.\n" Definition at line 974 of file chan_alsa.c. |
|
Definition at line 115 of file chan_alsa.c. Referenced by alsa_hangup(), console_answer(), console_dial(), and console_hangup(). |
|
Definition at line 92 of file chan_alsa.c. Referenced by alsa_new(), load_module(), and soundcard_init(). |
|
Definition at line 112 of file chan_alsa.c. Referenced by alsa_new(), and load_module(). |
|
Definition at line 1036 of file chan_alsa.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 170 of file chan_alsa.c. Referenced by answer_sound(), and send_sound(). |
|
Definition at line 169 of file chan_alsa.c. Referenced by send_sound(), and sound_thread(). |
|
Definition at line 93 of file chan_alsa.c. Referenced by load_module(), and soundcard_init(). |
|
Definition at line 161 of file chan_alsa.c. Referenced by alsa_card_init(), and sound_thread(). |
|
Definition at line 167 of file chan_alsa.c. Referenced by send_sound(), and sound_thread(). |
|
Initial value: "Usage: send text <message>\n" " Sends a text message for display on the remote terminal.\n" Definition at line 908 of file chan_alsa.c. |
|
Definition at line 117 of file chan_alsa.c. |
|
Definition at line 168 of file chan_alsa.c. Referenced by send_sound(), and sound_thread(). |
|
Definition at line 100 of file chan_alsa.c. Referenced by load_module(). |
|
Definition at line 101 of file chan_alsa.c. Referenced by alsa_card_init(), and load_module(). |
|
Definition at line 137 of file chan_alsa.c. Referenced by alsa_call(), alsa_hangup(), alsa_indicate(), answer_sound(), load_module(), sound_thread(), and unload_module(). |
|
Definition at line 128 of file chan_alsa.c. Referenced by send_sound(). |
|
Definition at line 156 of file chan_alsa.c. Referenced by load_module(). |
|
Definition at line 108 of file chan_alsa.c. |
|
Definition at line 106 of file chan_alsa.c. |
|
Definition at line 99 of file chan_alsa.c. Referenced by alsa_hangup(), and alsa_new(). |
|
Definition at line 162 of file chan_alsa.c. Referenced by alsa_card_init(), and sound_thread(). |