Index: chan_alsa.c =================================================================== --- chan_alsa.c (revision 219786) +++ chan_alsa.c (working copy) @@ -268,12 +268,12 @@ alsa.icard = alsa_card_init(indevname, SND_PCM_STREAM_CAPTURE); alsa.ocard = alsa_card_init(outdevname, SND_PCM_STREAM_PLAYBACK); - if (!alsa.icard || !alsa.ocard) { + if (!alsa.icard && !alsa.ocard) { ast_log(LOG_ERROR, "Problem opening ALSA I/O devices\n"); return -1; } - return readdev; + return 0; } static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration) @@ -326,8 +326,10 @@ ast_indicate(alsa.owner, AST_CONTROL_RINGING); } } - snd_pcm_prepare(alsa.icard); - snd_pcm_start(alsa.icard); + if (alsa.icard) { + snd_pcm_prepare(alsa.icard); + snd_pcm_start(alsa.icard); + } ast_mutex_unlock(&alsalock); return 0; @@ -338,8 +340,10 @@ ast_mutex_lock(&alsalock); ast_verbose(" << Console call has been answered >> \n"); ast_setstate(c, AST_STATE_UP); - snd_pcm_prepare(alsa.icard); - snd_pcm_start(alsa.icard); + if (alsa.icard) { + snd_pcm_prepare(alsa.icard); + snd_pcm_start(alsa.icard); + } ast_mutex_unlock(&alsalock); return 0; @@ -353,7 +357,9 @@ ast_verbose(" << Hangup on console >> \n"); ast_module_unref(ast_module_info->self); hookstate = 0; - snd_pcm_drop(alsa.icard); + if (alsa.icard) { + snd_pcm_drop(alsa.icard); + } ast_mutex_unlock(&alsalock); return 0; @@ -375,7 +381,7 @@ if (f->datalen > sizeof(sizbuf) - sizpos) { ast_log(LOG_WARNING, "Frame too large\n"); res = -1; - } else { + } else if (alsa.ocard) { memcpy(sizbuf + sizpos, f->data.ptr, f->datalen); len += f->datalen; pos = 0; @@ -436,50 +442,51 @@ f.delivery.tv_sec = 0; f.delivery.tv_usec = 0; - state = snd_pcm_state(alsa.icard); - if ((state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING)) { - snd_pcm_prepare(alsa.icard); - } - - buf = __buf + AST_FRIENDLY_OFFSET / 2; - - r = snd_pcm_readi(alsa.icard, buf + readpos, left); - if (r == -EPIPE) { + if (alsa.icard) { + state = snd_pcm_state(alsa.icard); + if ((state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING)) { + snd_pcm_prepare(alsa.icard); + } + + buf = __buf + AST_FRIENDLY_OFFSET / 2; + + r = snd_pcm_readi(alsa.icard, buf + readpos, left); + if (r == -EPIPE) { #if DEBUG - ast_log(LOG_ERROR, "XRUN read\n"); + ast_log(LOG_ERROR, "XRUN read\n"); #endif - snd_pcm_prepare(alsa.icard); - } else if (r == -ESTRPIPE) { - ast_log(LOG_ERROR, "-ESTRPIPE\n"); - snd_pcm_prepare(alsa.icard); - } else if (r < 0) { - ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r)); - } else if (r >= 0) { - off -= r; - } - /* Update positions */ - readpos += r; - left -= r; - - if (readpos >= FRAME_SIZE) { - /* A real frame */ - readpos = 0; - left = FRAME_SIZE; - if (chan->_state != AST_STATE_UP) { - /* Don't transmit unless it's up */ - ast_mutex_unlock(&alsalock); - return &f; - } - f.frametype = AST_FRAME_VOICE; - f.subclass = AST_FORMAT_SLINEAR; - f.samples = FRAME_SIZE; - f.datalen = FRAME_SIZE * 2; - f.data.ptr = buf; - f.offset = AST_FRIENDLY_OFFSET; - f.src = "Console"; - f.mallocd = 0; - - } + snd_pcm_prepare(alsa.icard); + } else if (r == -ESTRPIPE) { + ast_log(LOG_ERROR, "-ESTRPIPE\n"); + snd_pcm_prepare(alsa.icard); + } else if (r < 0) { + ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r)); + } else if (r >= 0) { + off -= r; + } + /* Update positions */ + readpos += r; + left -= r; + + if (readpos >= FRAME_SIZE) { + /* A real frame */ + readpos = 0; + left = FRAME_SIZE; + if (chan->_state != AST_STATE_UP) { + /* Don't transmit unless it's up */ + ast_mutex_unlock(&alsalock); + return &f; + } + f.frametype = AST_FRAME_VOICE; + f.subclass = AST_FORMAT_SLINEAR; + f.samples = FRAME_SIZE; + f.datalen = FRAME_SIZE * 2; + f.data.ptr = buf; + f.offset = AST_FRIENDLY_OFFSET; + f.src = "Console"; + f.mallocd = 0; + } + } ast_mutex_unlock(&alsalock); return &f; @@ -676,8 +683,10 @@ } } - snd_pcm_prepare(alsa.icard); - snd_pcm_start(alsa.icard); + if (alsa.icard) { + snd_pcm_prepare(alsa.icard); + snd_pcm_start(alsa.icard); + } ast_mutex_unlock(&alsalock);