EXPORT_DEF int at_wait (int fd, int* ms) { int exception, outfd; outfd = ast_waitfor_n_fd (&fd, 1, ms, &exception); if (outfd < 0) { outfd = 0; } return outfd; }
static struct ast_frame *bestdata_read(struct ast_modem_pvt *p) { char result[256]; short *b; struct ast_frame *f=NULL; int res; int x; if (p->ministate == STATE_COMMAND) { /* Read the first two bytes, first, in case it's a control message */ fread(result, 1, 2, p->f); if (result[0] == CHAR_DLE) { return bestdata_handle_escape(p, result[1]); } else { if (p->ringt) /* if ring timeout specified */ { x = fileno(p->f); res = ast_waitfor_n_fd(&x, 1, &p->ringt, NULL); if (res < 0) { return NULL; } } if ((result[0] == '\n') || (result[0] == '\r')) return bestdata_handle_escape(p, 0); /* Read the rest of the line */ fgets(result + 2, sizeof(result) - 2, p->f); ast_modem_trim(result); if (!strcasecmp(result, "OK")) { /* If we're in immediate mode, reply now */ if (p->mode == MODEM_MODE_IMMEDIATE) return bestdata_handle_escape(p, '@'); } else if (!strcasecmp(result, "BUSY")) { /* Same as a busy signal */ return bestdata_handle_escape(p, 'b'); } else if (!strcasecmp(result, "RING")) { return bestdata_handle_escape(p, 'R'); } else if (!strcasecmp(result, "NO DIALTONE")) { /* There's no dialtone, so the line isn't working */ ast_log(LOG_WARNING, "Device '%s' lacking dialtone\n", p->dev); return NULL; } ast_log(LOG_DEBUG, "Modem said '%s'\n", result); return bestdata_handle_escape(p, 0); } } else { /* if playing, start recording instead */ if (p->ministate == STATE_VOICEPLAY) { if (bestdata_startrec(p)) return NULL; } /* We have to be more efficient in voice mode */ b = (short *)(p->obuf + p->obuflen); while (p->obuflen/2 < 240) { /* Read ahead the full amount */ res = fread(result, 1, 240 - p->obuflen/2, p->f); if (res < 1) { /* If there's nothing there, just continue on */ if (errno == EAGAIN) return bestdata_handle_escape(p, 0); ast_log(LOG_WARNING, "Read failed: %s\n", strerror(errno)); } for (x=0;x<res;x++) { /* Process all the bytes that we've read */ if (result[x] == CHAR_DLE) { /* We assume there is no more than one signal frame among our data. */ if (f) ast_log(LOG_WARNING, "Warning: Dropped a signal frame\n"); /* if not a DLE in the data */ if (result[++x] != CHAR_DLE) { /* If bestdata_handle_escape says NULL, say it now, doesn't matter what else is there, the connection is dead. */ f = bestdata_handle_escape(p, result[x]); if (p->dtmfrx) continue; return(f); } } /* Generate a 16-bit signed linear value from our unsigned 8-bit value */ *(b++) = (((short)result[x]) - 127) * 0xff; p->obuflen += 2; } if (f) break; } /* If we have a control frame, return it now */ if (f) return f; /* If we get here, we have a complete voice frame */ p->fr.frametype = AST_FRAME_VOICE; p->fr.subclass = AST_FORMAT_SLINEAR; p->fr.samples = 240; p->fr.data = p->obuf; p->fr.datalen = p->obuflen; p->fr.mallocd = 0; p->fr.delivery.tv_sec = 0; p->fr.delivery.tv_usec = 0; p->fr.offset = AST_FRIENDLY_OFFSET; p->fr.src = __FUNCTION__; if (option_debug) ast_log(LOG_DEBUG, "bestdata_read(voice frame)\n"); p->obuflen = 0; return &p->fr; } return NULL; }