[asterisk-dev] Zaptel resource temporarily unavailable

Anton anton.vazir at gmail.com
Tue Mar 14 04:14:06 MST 2006


Hi guys!

I'm trying to fix a glitch in the chan_ss7 which interacts with Zaptel hardware. 
The strange behaviour is that the channel cannot write() data to the zaptel fd from 
time to time and that is somehow in connection with used codecs. 

I'm getting the resouce unavailable and "Write buffer full on CIC=%d (wrote only %d of %d), audio lost.\n" upon receiving a 
error from write() of if(errno == EAGAIN || errno == EWOULDBLOCK)

Strange thing that when this is used with plain g711 communicaiton with ENDPOINT - there are no errors. 
But if remote endpoint is an Asterisk with g723/g729, or ASTERISK BOX itself uses g723/g729 - than I start receiving that "Resouce temporarily unavailable" error from write(). 
This behaviour makes audio glitchy. 

Can anyone point me what could be a potential reason of such a behaviour?

Below is a portion of the code, generating that error for your reference. As I uderstood zt_read() receives a 
stream in Zaptel kernel driver - But I can't guess anyway what could be a reason.

Would appreciate very much your help!

static int ss7_write(struct ast_channel * chan, struct ast_frame *frame) {
  struct ss7_chan *pvt = chan->tech_pvt;
  int res, sofar;

  ast_mutex_lock(&pvt->lock);

  if(frame->frametype != AST_FRAME_VOICE || frame->subclass != AST_FORMAT_ALAW) {
    ast_mutex_unlock(&pvt->lock);
    ast_log(LOG_WARNING, "Unexpected frame.\n");
    return -1;
  }

  if(pvt->sending_dtmf) {
    /* If we send audio while playing DTMF, the tone seems to be lost. */
    ast_mutex_unlock(&pvt->lock);
    return 0;
  }

  sofar = 0;
  while(sofar < frame->datalen) {
    res = write(pvt->zaptel_fd, (unsigned char *)frame->data + sofar, frame->datalen - sofar);
    if(res > 0) {
      sofar += res;
    } else if(res == 0) {
      ast_mutex_unlock(&pvt->lock);
      ast_log(LOG_WARNING, "EOF on zaptel device CIC=%d?!?\n", pvt->cic);
      return -1;
    } else {
      if(errno == EINTR) {
        /* Interrupted syscall, try again. */
      } else if(errno == EAGAIN || errno == EWOULDBLOCK) {
        ast_mutex_unlock(&pvt->lock);
        ast_log(LOG_NOTICE, "Write buffer full on CIC=%d (wrote only %d of %d), audio lost.\n",
                pvt->cic, sofar, frame->datalen);
        return 0;
      } else {
        ast_mutex_unlock(&pvt->lock);
        ast_log(LOG_WARNING, "Write error on CIC=%d: %s.\n", pvt->cic, strerror(errno));
        return -1;
      }
    }
  }

  ast_mutex_unlock(&pvt->lock);

  return 0;
}



More information about the asterisk-dev mailing list