static int pcm_write(struct ast_filestream *fs, struct ast_frame *f) { int res; if (f->frametype != AST_FRAME_VOICE) { ast_log(LOG_WARNING, "Asked to write non-voice frame!\n"); return -1; } if (ast_format_cmp(&f->subclass.format, &fs->fmt->format) == AST_FORMAT_CMP_NOT_EQUAL) { ast_log(LOG_WARNING, "Asked to write incompatible format frame (%s)!\n", ast_getformatname(&f->subclass.format)); return -1; } #ifdef REALTIME_WRITE if (s->fmt->format == AST_FORMAT_ALAW) { struct pcm_desc *pd = (struct pcm_desc *)fs->_private; struct stat stat_buf; unsigned long cur_time = get_time(); unsigned long fpos = ( cur_time - pd->start_time ) * 8; /* 8 bytes per msec */ /* Check if we have written to this position yet. If we have, then increment pos by one frame * for some degree of protection against receiving packets in the same clock tick. */ fstat(fileno(fs->f), &stat_buf ); if (stat_buf.st_size > fpos ) fpos += f->datalen; /* Incrementing with the size of this current frame */ if (stat_buf.st_size < fpos) { /* fill the gap with 0x55 rather than 0. */ char buf[1024]; unsigned long cur, to_write; cur = stat_buf.st_size; if (fseek(fs->f, cur, SEEK_SET) < 0) { ast_log( LOG_WARNING, "Cannot seek in file: %s\n", strerror(errno) ); return -1; } memset(buf, 0x55, 512); while (cur < fpos) { to_write = fpos - cur; if (to_write > sizeof(buf)) to_write = sizeof(buf); fwrite(buf, 1, to_write, fs->f); cur += to_write; } } if (fseek(s->f, fpos, SEEK_SET) < 0) { ast_log( LOG_WARNING, "Cannot seek in file: %s\n", strerror(errno) ); return -1; } } #endif /* REALTIME_WRITE */ if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) { ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno)); return -1; } return 0; }
static int find_exact_cb(void *obj, void *arg, int flag) { struct ast_format *format1 = (struct ast_format *) arg; struct ast_format *format2 = (struct ast_format *) obj; return (ast_format_cmp(format1, format2) == AST_FORMAT_CMP_EQUAL) ? CMP_MATCH : 0; }
/*! \brief Remove codec from pref list */ void ast_codec_pref_remove(struct ast_codec_pref *pref, struct ast_format *format) { struct ast_codec_pref oldorder; int x, y = 0; size_t f_len = 0; const const struct ast_format_list *f_list; if (!pref->order[0]) { return; } f_list = ast_format_list_get(&f_len); memcpy(&oldorder, pref, sizeof(oldorder)); memset(pref, 0, sizeof(*pref)); for (x = 0; x < f_len; x++) { if (!oldorder.order[x]) { break; } if (ast_format_cmp(&f_list[oldorder.order[x]-1].format, format) == AST_FORMAT_CMP_NOT_EQUAL) { pref->order[y] = oldorder.order[x]; ast_format_copy(&pref->formats[y], &oldorder.formats[x]); pref->framing[y++] = oldorder.framing[x]; } } ast_format_list_destroy(f_list); }
/*! \brief Append codec to list */ int ast_codec_pref_append(struct ast_codec_pref *pref, struct ast_format *format) { int x, newindex = 0; size_t f_len = 0; const struct ast_format_list *f_list = ast_format_list_get(&f_len); ast_codec_pref_remove(pref, format); for (x = 0; x < f_len; x++) { if (ast_format_cmp(&f_list[x].format, format) == AST_FORMAT_CMP_EQUAL) { newindex = x + 1; break; } } if (newindex) { for (x = 0; x < f_len; x++) { if (!pref->order[x]) { pref->order[x] = newindex; ast_format_copy(&pref->formats[x], format); break; } } } ast_format_list_destroy(f_list); return x; }
static int measurenoise(struct ast_channel *chan, int ms, char *who) { int res=0; int mssofar; int noise=0; int samples=0; int x; short *foo; struct timeval start; struct ast_frame *f; struct ast_format *rformat; rformat = ao2_bump(ast_channel_readformat(chan)); if (ast_set_read_format(chan, ast_format_slin)) { ast_log(LOG_NOTICE, "Unable to set to linear mode!\n"); ao2_cleanup(rformat); return -1; } start = ast_tvnow(); for(;;) { mssofar = ast_tvdiff_ms(ast_tvnow(), start); if (mssofar > ms) break; res = ast_waitfor(chan, ms - mssofar); if (res < 1) break; f = ast_read(chan); if (!f) { res = -1; break; } if ((f->frametype == AST_FRAME_VOICE) && (ast_format_cmp(f->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)) { foo = (short *)f->data.ptr; for (x=0;x<f->samples;x++) { noise += abs(foo[x]); samples++; } } ast_frfree(f); } if (rformat) { if (ast_set_read_format(chan, rformat)) { ast_log(LOG_NOTICE, "Unable to restore original format!\n"); ao2_ref(rformat, -1); return -1; } ao2_ref(rformat, -1); } if (res < 0) return res; if (!samples) { ast_log(LOG_NOTICE, "No samples were received from the other side!\n"); return -1; } ast_debug(1, "%s: Noise: %d, samples: %d, avg: %d\n", who, noise, samples, noise / samples); return (noise / samples); }
int ast_format_cache_is_slinear(struct ast_format *format) { if ((ast_format_cmp(format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) || (ast_format_cmp(format, ast_format_slin12) == AST_FORMAT_CMP_EQUAL) || (ast_format_cmp(format, ast_format_slin16) == AST_FORMAT_CMP_EQUAL) || (ast_format_cmp(format, ast_format_slin24) == AST_FORMAT_CMP_EQUAL) || (ast_format_cmp(format, ast_format_slin32) == AST_FORMAT_CMP_EQUAL) || (ast_format_cmp(format, ast_format_slin44) == AST_FORMAT_CMP_EQUAL) || (ast_format_cmp(format, ast_format_slin48) == AST_FORMAT_CMP_EQUAL) || (ast_format_cmp(format, ast_format_slin96) == AST_FORMAT_CMP_EQUAL) || (ast_format_cmp(format, ast_format_slin192) == AST_FORMAT_CMP_EQUAL)) { return 1; } return 0; }
/*! format exists within capabilities structure if it is identical to * another format, or if the format is a proper subset of another format. */ static int cmp_cb(void *obj, void *arg, int flags) { struct ast_format *format1 = arg; struct ast_format *format2 = obj; enum ast_format_cmp_res res = ast_format_cmp(format1, format2); return ((res == AST_FORMAT_CMP_EQUAL) || (res == AST_FORMAT_CMP_SUBSET)) ? CMP_MATCH | CMP_STOP : 0; }
/*! \brief Join function which actually adds the channel into the array to be monitored */ static int multiplexed_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel) { struct ast_channel *c0 = AST_LIST_FIRST(&bridge->channels)->chan, *c1 = AST_LIST_LAST(&bridge->channels)->chan; struct multiplexed_thread *multiplexed_thread = bridge->bridge_pvt; ast_debug(1, "Adding channel '%s' to multiplexed thread '%p' for monitoring\n", bridge_channel->chan->name, multiplexed_thread); multiplexed_add_or_remove(multiplexed_thread, bridge_channel->chan, 1); /* If the second channel has not yet joined do not make things compatible */ if (c0 == c1) { return 0; } if ((ast_format_cmp(&c0->writeformat, &c1->readformat) == AST_FORMAT_CMP_EQUAL) && (ast_format_cmp(&c0->readformat, &c1->writeformat) == AST_FORMAT_CMP_EQUAL) && (ast_format_cap_identical(c0->nativeformats, c1->nativeformats))) { return 0; } return ast_channel_make_compatible(c0, c1); }
int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel) { struct ast_format *tmpfmt = NULL; tmpfmt = convertH323CapToAsteriskCap(pChannel->chanCap->cap); if (tmpfmt) { if ((ast_format_cmp(tmpfmt, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) || (ast_format_cmp(tmpfmt, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL)) { ooh323_set_write_format(call, tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes); } else if (ast_format_cmp(tmpfmt, ast_format_g729) == AST_FORMAT_CMP_EQUAL) { ooh323_set_write_format(call, tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes*10); } else { ooh323_set_write_format(call, tmpfmt, 0); } }else{ ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n", call->callToken); return -1; } setup_rtp_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort); return 1; }
/*! \brief Prepend codec to list */ void ast_codec_pref_prepend(struct ast_codec_pref *pref, struct ast_format *format, int only_if_existing) { int x, newindex = 0; size_t f_len = 0; const struct ast_format_list *f_list = ast_format_list_get(&f_len); /* First step is to get the codecs "index number" */ for (x = 0; x < f_len; x++) { if (ast_format_cmp(&f_list[x].format, format) == AST_FORMAT_CMP_EQUAL) { newindex = x + 1; break; } } /* Done if its unknown */ if (!newindex) { ast_format_list_destroy(f_list); return; } /* Now find any existing occurrence, or the end */ for (x = 0; x < AST_CODEC_PREF_SIZE; x++) { if (!pref->order[x] || pref->order[x] == newindex) break; } /* If we failed to find any occurrence, set to the end */ if (x == AST_CODEC_PREF_SIZE) { --x; } if (only_if_existing && !pref->order[x]) { ast_format_list_destroy(f_list); return; } /* Move down to make space to insert - either all the way to the end, or as far as the existing location (which will be overwritten) */ for (; x > 0; x--) { pref->order[x] = pref->order[x - 1]; pref->framing[x] = pref->framing[x - 1]; ast_format_copy(&pref->formats[x], &pref->formats[x - 1]); } /* And insert the new entry */ pref->order[0] = newindex; pref->framing[0] = 0; /* ? */ ast_format_copy(&pref->formats[0], format); ast_format_list_destroy(f_list); }
const char* ast_getformatname(const struct ast_format *format) { int x; const char *ret = "unknown"; size_t f_len; const struct ast_format_list *f_list = ast_format_list_get(&f_len); for (x = 0; x < f_len; x++) { if (ast_format_cmp(&f_list[x].format, format) == AST_FORMAT_CMP_EQUAL) { ret = f_list[x].name; break; } } f_list = ast_format_list_destroy(f_list); return ret; }
/*! \brief Get packet size for codec */ struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, struct ast_format *format) { int x, idx = -1, framems = 0; struct ast_format_list fmt = { { 0, }, }; size_t f_len = 0; const struct ast_format_list *f_list = ast_format_list_get(&f_len); for (x = 0; x < f_len; x++) { if (ast_format_cmp(&f_list[x].format, format) == AST_FORMAT_CMP_EQUAL) { fmt = f_list[x]; idx = x; break; } } if (idx < 0) { ast_log(AST_LOG_WARNING, "Format %s unknown; unable to get preferred codec packet size\n", ast_getformatname(format)); ast_format_list_destroy(f_list); return fmt; } for (x = 0; x < f_len; x++) { if (pref->order[x] == (idx + 1)) { framems = pref->framing[x]; break; } } /* size validation */ if (!framems) framems = f_list[idx].def_ms; if (f_list[idx].inc_ms && framems % f_list[idx].inc_ms) /* avoid division by zero */ framems -= framems % f_list[idx].inc_ms; if (framems < f_list[idx].min_ms) framems = f_list[idx].min_ms; if (framems > f_list[idx].max_ms) framems = f_list[idx].max_ms; fmt.cur_ms = framems; ast_format_list_destroy(f_list); return fmt; }
/*! \brief Set packet size for codec */ int ast_codec_pref_setsize(struct ast_codec_pref *pref, struct ast_format *format, int framems) { int x, idx = -1; size_t f_len = 0; const struct ast_format_list *f_list = ast_format_list_get(&f_len); for (x = 0; x < f_len; x++) { if (ast_format_cmp(&f_list[x].format, format) == AST_FORMAT_CMP_EQUAL) { idx = x; break; } } if (idx < 0) { ast_format_list_destroy(f_list); return -1; } /* size validation */ if (!framems) framems = f_list[idx].def_ms; if (f_list[idx].inc_ms && framems % f_list[idx].inc_ms) /* avoid division by zero */ framems -= framems % f_list[idx].inc_ms; if (framems < f_list[idx].min_ms) framems = f_list[idx].min_ms; if (framems > f_list[idx].max_ms) framems = f_list[idx].max_ms; for (x = 0; x < f_len; x++) { if (pref->order[x] == (idx + 1)) { pref->framing[x] = framems; break; } } ast_format_list_destroy(f_list); return x; }
struct ast_format *ast_format_joint(const struct ast_format *format1, const struct ast_format *format2) { const struct ast_format_interface *interface; if (format1->codec != format2->codec) { return NULL; } /* If the two formats are the same structure OR if the codec is the same and no attributes * exist we can immediately return a format with reference count bumped up, since they are * the same. */ if ((ast_format_cmp(format1, format2) == AST_FORMAT_CMP_EQUAL && !format1->attribute_data && !format2->attribute_data)) { return ao2_bump((struct ast_format*)format1); } interface = format1->interface ? format1->interface : format2->interface; /* If there is attribute data on either there has to be an interface */ return interface->format_get_joint(format1, format2); }
static int transmit_audio(fax_session *s) { int res = -1; struct ast_format *original_read_fmt; struct ast_format *original_write_fmt = NULL; fax_state_t fax; t30_state_t *t30state; struct ast_frame *inf = NULL; int last_state = 0; struct timeval now, start, state_change; enum ast_t38_state t38_state; struct ast_control_t38_parameters t38_parameters = { .version = 0, .max_ifp = 800, .rate = AST_T38_RATE_14400, .rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, .fill_bit_removal = 1, /* * spandsp has API calls to support MMR and JBIG transcoding, but they aren't * implemented quite yet... so don't offer them to the remote endpoint * .transcoding_mmr = 1, * .transcoding_jbig = 1, */ }; /* if in called party mode, try to use T.38 */ if (s->caller_mode == FALSE) { /* check if we are already in T.38 mode (unlikely), or if we can request * a switch... if so, request it now and wait for the result, rather * than starting an audio FAX session that will have to be cancelled */ if ((t38_state = ast_channel_get_t38_state(s->chan)) == T38_STATE_NEGOTIATED) { return 1; } else if ((t38_state != T38_STATE_UNAVAILABLE) && (t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE, (ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) == 0))) { /* wait up to five seconds for negotiation to complete */ unsigned int timeout = 5000; int ms; ast_debug(1, "Negotiating T.38 for receive on %s\n", ast_channel_name(s->chan)); while (timeout > 0) { ms = ast_waitfor(s->chan, 1000); if (ms < 0) { ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", ast_channel_name(s->chan)); return -1; } if (!ms) { /* nothing happened */ if (timeout > 0) { timeout -= 1000; continue; } else { ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", ast_channel_name(s->chan)); break; } } if (!(inf = ast_read(s->chan))) { return -1; } if ((inf->frametype == AST_FRAME_CONTROL) && (inf->subclass.integer == AST_CONTROL_T38_PARAMETERS) && (inf->datalen == sizeof(t38_parameters))) { struct ast_control_t38_parameters *parameters = inf->data.ptr; switch (parameters->request_response) { case AST_T38_NEGOTIATED: ast_debug(1, "Negotiated T.38 for receive on %s\n", ast_channel_name(s->chan)); res = 1; break; case AST_T38_REFUSED: ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", ast_channel_name(s->chan)); break; default: ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", ast_channel_name(s->chan)); break; } ast_frfree(inf); if (res == 1) { return 1; } else { break; } } ast_frfree(inf); } } } #if SPANDSP_RELEASE_DATE >= 20080725 /* for spandsp shaphots 0.0.6 and higher */ t30state = &fax.t30; #else /* for spandsp release 0.0.5 */ t30state = &fax.t30_state; #endif original_read_fmt = ao2_bump(ast_channel_readformat(s->chan)); res = ast_set_read_format(s->chan, ast_format_slin); if (res < 0) { ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n"); goto done; } original_write_fmt = ao2_bump(ast_channel_writeformat(s->chan)); res = ast_set_write_format(s->chan, ast_format_slin); if (res < 0) { ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n"); goto done; } /* Initialize T30 terminal */ fax_init(&fax, s->caller_mode); /* Setup logging */ set_logging(&fax.logging); set_logging(&t30state->logging); /* Configure terminal */ set_local_info(t30state, s); set_file(t30state, s); set_ecm(t30state, TRUE); fax_set_transmit_on_idle(&fax, TRUE); t30_set_phase_e_handler(t30state, phase_e_handler, s); start = state_change = ast_tvnow(); ast_activate_generator(s->chan, &generator, &fax); while (!s->finished) { inf = NULL; if ((res = ast_waitfor(s->chan, 25)) < 0) { ast_debug(1, "Error waiting for a frame\n"); break; } /* Watchdog */ now = ast_tvnow(); if (ast_tvdiff_sec(now, start) > WATCHDOG_TOTAL_TIMEOUT || ast_tvdiff_sec(now, state_change) > WATCHDOG_STATE_TIMEOUT) { ast_log(LOG_WARNING, "It looks like we hung. Aborting.\n"); res = -1; break; } if (!res) { /* There was timeout waiting for a frame. Loop around and wait again */ continue; } /* There is a frame available. Get it */ res = 0; if (!(inf = ast_read(s->chan))) { ast_debug(1, "Channel hangup\n"); res = -1; break; } ast_debug(10, "frame %d/%s, len=%d\n", inf->frametype, ast_format_get_name(inf->subclass.format), inf->datalen); /* Check the frame type. Format also must be checked because there is a chance that a frame in old format was already queued before we set channel format to slinear so it will still be received by ast_read */ if (inf->frametype == AST_FRAME_VOICE && (ast_format_cmp(inf->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)) { if (fax_rx(&fax, inf->data.ptr, inf->samples) < 0) { /* I know fax_rx never returns errors. The check here is for good style only */ ast_log(LOG_WARNING, "fax_rx returned error\n"); res = -1; break; } if (last_state != t30state->state) { state_change = ast_tvnow(); last_state = t30state->state; } } else if ((inf->frametype == AST_FRAME_CONTROL) && (inf->subclass.integer == AST_CONTROL_T38_PARAMETERS)) { struct ast_control_t38_parameters *parameters = inf->data.ptr; if (parameters->request_response == AST_T38_NEGOTIATED) { /* T38 switchover completed */ s->t38parameters = *parameters; ast_debug(1, "T38 negotiated, finishing audio loop\n"); res = 1; break; } else if (parameters->request_response == AST_T38_REQUEST_NEGOTIATE) { t38_parameters.request_response = AST_T38_NEGOTIATED; ast_debug(1, "T38 request received, accepting\n"); /* Complete T38 switchover */ ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)); /* Do not break audio loop, wait until channel driver finally acks switchover * with AST_T38_NEGOTIATED */ } } ast_frfree(inf); inf = NULL; } ast_debug(1, "Loop finished, res=%d\n", res); if (inf) ast_frfree(inf); ast_deactivate_generator(s->chan); /* If we are switching to T38, remove phase E handler. Otherwise it will be executed by t30_terminate, display diagnostics and set status variables although no transmittion has taken place yet. */ if (res > 0) { t30_set_phase_e_handler(t30state, NULL, NULL); } t30_terminate(t30state); fax_release(&fax); done: if (original_write_fmt) { if (ast_set_write_format(s->chan, original_write_fmt) < 0) ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", ast_channel_name(s->chan)); ao2_ref(original_write_fmt, -1); } if (original_read_fmt) { if (ast_set_read_format(s->chan, original_read_fmt) < 0) ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", ast_channel_name(s->chan)); ao2_ref(original_read_fmt, -1); } return res; } static int transmit_t38(fax_session *s) { int res = 0; t38_terminal_state_t t38; struct ast_frame *inf = NULL; int last_state = 0; struct timeval now, start, state_change, last_frame; t30_state_t *t30state; t38_core_state_t *t38state; #if SPANDSP_RELEASE_DATE >= 20080725 /* for spandsp shaphots 0.0.6 and higher */ t30state = &t38.t30; t38state = &t38.t38_fe.t38; #else /* for spandsp releases 0.0.5 */ t30state = &t38.t30_state; t38state = &t38.t38; #endif /* Initialize terminal */ memset(&t38, 0, sizeof(t38)); if (t38_terminal_init(&t38, s->caller_mode, t38_tx_packet_handler, s->chan) == NULL) { ast_log(LOG_WARNING, "Unable to start T.38 termination.\n"); res = -1; goto disable_t38; } t38_set_max_datagram_size(t38state, s->t38parameters.max_ifp); if (s->t38parameters.fill_bit_removal) { t38_set_fill_bit_removal(t38state, TRUE); } if (s->t38parameters.transcoding_mmr) { t38_set_mmr_transcoding(t38state, TRUE); } if (s->t38parameters.transcoding_jbig) { t38_set_jbig_transcoding(t38state, TRUE); } /* Setup logging */ set_logging(&t38.logging); set_logging(&t30state->logging); set_logging(&t38state->logging); /* Configure terminal */ set_local_info(t30state, s); set_file(t30state, s); set_ecm(t30state, TRUE); t30_set_phase_e_handler(t30state, phase_e_handler, s); now = start = state_change = ast_tvnow(); while (!s->finished) { inf = NULL; if ((res = ast_waitfor(s->chan, 25)) < 0) { ast_debug(1, "Error waiting for a frame\n"); break; } last_frame = now; /* Watchdog */ now = ast_tvnow(); if (ast_tvdiff_sec(now, start) > WATCHDOG_TOTAL_TIMEOUT || ast_tvdiff_sec(now, state_change) > WATCHDOG_STATE_TIMEOUT) { ast_log(LOG_WARNING, "It looks like we hung. Aborting.\n"); res = -1; break; } t38_terminal_send_timeout(&t38, ast_tvdiff_us(now, last_frame) / (1000000 / 8000)); if (!res) { /* There was timeout waiting for a frame. Loop around and wait again */ continue; } /* There is a frame available. Get it */ res = 0; if (!(inf = ast_read(s->chan))) { ast_debug(1, "Channel hangup\n"); res = -1; break; } ast_debug(10, "frame %d/%d, len=%d\n", inf->frametype, inf->subclass.integer, inf->datalen); if (inf->frametype == AST_FRAME_MODEM && inf->subclass.integer == AST_MODEM_T38) { t38_core_rx_ifp_packet(t38state, inf->data.ptr, inf->datalen, inf->seqno); if (last_state != t30state->state) { state_change = ast_tvnow(); last_state = t30state->state; } } else if (inf->frametype == AST_FRAME_CONTROL && inf->subclass.integer == AST_CONTROL_T38_PARAMETERS) { struct ast_control_t38_parameters *parameters = inf->data.ptr; if (parameters->request_response == AST_T38_TERMINATED) { ast_debug(1, "T38 down, finishing\n"); break; } } ast_frfree(inf); inf = NULL; } ast_debug(1, "Loop finished, res=%d\n", res); if (inf) ast_frfree(inf); t30_terminate(t30state); t38_terminal_release(&t38); disable_t38: /* if we are not the caller, it's our job to shut down the T.38 * session when the FAX transmisson is complete. */ if ((s->caller_mode == FALSE) && (ast_channel_get_t38_state(s->chan) == T38_STATE_NEGOTIATED)) { struct ast_control_t38_parameters t38_parameters = { .request_response = AST_T38_REQUEST_TERMINATE, }; if (ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) == 0) { /* wait up to five seconds for negotiation to complete */ unsigned int timeout = 5000; int ms; ast_debug(1, "Shutting down T.38 on %s\n", ast_channel_name(s->chan)); while (timeout > 0) { ms = ast_waitfor(s->chan, 1000); if (ms < 0) { ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", ast_channel_name(s->chan)); return -1; } if (!ms) { /* nothing happened */ if (timeout > 0) { timeout -= 1000; continue; } else { ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 shutdown.\n", ast_channel_name(s->chan)); break; } } if (!(inf = ast_read(s->chan))) { return -1; } if ((inf->frametype == AST_FRAME_CONTROL) && (inf->subclass.integer == AST_CONTROL_T38_PARAMETERS) && (inf->datalen == sizeof(t38_parameters))) { struct ast_control_t38_parameters *parameters = inf->data.ptr; switch (parameters->request_response) { case AST_T38_TERMINATED: ast_debug(1, "Shut down T.38 on %s\n", ast_channel_name(s->chan)); break; case AST_T38_REFUSED: ast_log(LOG_WARNING, "channel '%s' refused to disable T.38\n", ast_channel_name(s->chan)); break; default: ast_log(LOG_ERROR, "channel '%s' failed to disable T.38\n", ast_channel_name(s->chan)); break; } ast_frfree(inf); break; } ast_frfree(inf); } } } return res; }
uint64_t ast_format_compatibility_format2bitfield(const struct ast_format *format) { if (ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_G723; } else if (ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_GSM; } else if (ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_ULAW; } else if (ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_ALAW; } else if (ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_G726_AAL2; } else if (ast_format_cmp(format, ast_format_adpcm) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_ADPCM; } else if (ast_format_cmp(format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_SLIN; } else if (ast_format_cmp(format, ast_format_lpc10) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_LPC10; } else if (ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_G729; } else if (ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_SPEEX; } else if (ast_format_cmp(format, ast_format_ilbc) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_ILBC; } else if (ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_G726; } else if (ast_format_cmp(format, ast_format_g722) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_G722; } else if (ast_format_cmp(format, ast_format_siren7) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_SIREN7; } else if (ast_format_cmp(format, ast_format_siren14) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_SIREN14; } else if (ast_format_cmp(format, ast_format_slin16) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_SLIN16; } else if (ast_format_cmp(format, ast_format_g719) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_G719; } else if (ast_format_cmp(format, ast_format_speex16) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_SPEEX16; } else if (ast_format_cmp(format, ast_format_opus) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_OPUS; } else if (ast_format_cmp(format, ast_format_testlaw) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_TESTLAW; } else if (ast_format_cmp(format, ast_format_h261) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_H261; } else if (ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_H263; } else if (ast_format_cmp(format, ast_format_h263p) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_H263P; } else if (ast_format_cmp(format, ast_format_h264) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_H264; } else if (ast_format_cmp(format, ast_format_mp4) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_MP4; } else if (ast_format_cmp(format, ast_format_vp8) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_VP8; } else if (ast_format_cmp(format, ast_format_jpeg) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_JPEG; } else if (ast_format_cmp(format, ast_format_png) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_PNG; } else if (ast_format_cmp(format, ast_format_t140_red) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_T140_RED; } else if (ast_format_cmp(format, ast_format_t140) == AST_FORMAT_CMP_EQUAL) { return AST_FORMAT_T140; } return 0; }
/*! * \brief This is the main function called by Asterisk Core whenever the App is invoked in the extension logic. * * \param chan Asterisk Channel * \param data Application data * * \retval 0 success * \retval -1 failure */ static int alarmreceiver_exec(struct ast_channel *chan, const char *data) { int res = 0; int no_checksum = 0; event_node_t *elp, *efree; char signalling_type[64] = ""; event_node_t *event_head = NULL; if ((ast_format_cmp(ast_channel_writeformat(chan), ast_format_ulaw) == AST_FORMAT_CMP_NOT_EQUAL) && (ast_format_cmp(ast_channel_writeformat(chan), ast_format_alaw) == AST_FORMAT_CMP_NOT_EQUAL)) { ast_verb(4, "AlarmReceiver: Setting write format to Mu-law\n"); if (ast_set_write_format(chan, ast_format_ulaw)) { ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",ast_channel_name(chan)); return -1; } } if ((ast_format_cmp(ast_channel_readformat(chan), ast_format_ulaw) == AST_FORMAT_CMP_NOT_EQUAL) && (ast_format_cmp(ast_channel_readformat(chan), ast_format_alaw) == AST_FORMAT_CMP_NOT_EQUAL)) { ast_verb(4, "AlarmReceiver: Setting read format to Mu-law\n"); if (ast_set_read_format(chan, ast_format_ulaw)) { ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",ast_channel_name(chan)); return -1; } } /* Set default values for this invocation of the application */ ast_copy_string(signalling_type, UNKNOWN_FORMAT, sizeof(signalling_type)); call_start_time = ast_tvnow(); /* Answer the channel if it is not already */ if (ast_channel_state(chan) != AST_STATE_UP) { ast_verb(4, "AlarmReceiver: Answering channel\n"); if (ast_answer(chan)) { return -1; } } /* Wait for the connection to settle post-answer */ ast_verb(4, "AlarmReceiver: Waiting for connection to stabilize\n"); if (ast_safe_sleep(chan, answait)) { return -1; } /* Attempt to receive the events */ receive_ademco_event(chan, &event_head, signalling_type, &no_checksum); /* Events queued by receiver, write them all out here if so configured */ if (!log_individual_events) { res = log_events(chan, signalling_type, event_head, no_checksum); } /* Do we exec a command line at the end? */ if ((!res) && (!ast_strlen_zero(event_app)) && (event_head)) { ast_debug(1,"Alarmreceiver: executing: %s\n", event_app); ast_safe_system(event_app); } /* Free up the data allocated in our linked list */ for (elp = event_head; (elp != NULL);) { efree = elp; elp = elp->next; ast_free(efree); } return 0; }
int ooh323c_set_capability (struct ast_format_cap *cap, int dtmf, int dtmfcodec) { int ret = 0, x; if (gH323Debug) { ast_verb(0, "\tAdding capabilities to H323 endpoint\n"); } for(x=0; x<ast_format_cap_count(cap); x++) { struct ast_format *format = ast_format_cap_get_format(cap, x); if(ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g711 ulaw capability to H323 endpoint\n"); } ret= ooH323EpAddG711Capability(OO_G711ULAW64K, gtxframes, grxframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g711 alaw capability to H323 endpoint\n"); } ret= ooH323EpAddG711Capability(OO_G711ALAW64K, gtxframes, grxframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g729A capability to H323 endpoint\n"); } ret = ooH323EpAddG729Capability(OO_G729A, 2, 24, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); if (gH323Debug) { ast_verb(0, "\tAdding g729 capability to H323 endpoint\n"); } ret |= ooH323EpAddG729Capability(OO_G729, 2, 24, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); if (gH323Debug) { ast_verb(0, "\tAdding g729b capability to H323 endpoint\n"); } ret |= ooH323EpAddG729Capability(OO_G729B, 2, 24, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g7231 capability to H323 endpoint\n"); } ret = ooH323EpAddG7231Capability(OO_G7231, 1, 1, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g726 capability to H323 endpoint\n"); } ret = ooH323EpAddG726Capability(OO_G726, gtxframes, grxframes, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g726aal2 capability to H323 endpoint\n"); } ret = ooH323EpAddG726Capability(OO_G726AAL2, gtxframes, grxframes, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding h263 capability to H323 endpoint\n"); } ret = ooH323EpAddH263VideoCapability(OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding gsm capability to H323 endpoint\n"); } ret = ooH323EpAddGSMCapability(OO_GSMFULLRATE, 4, FALSE, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding speex capability to H323 endpoint\n"); } ret = ooH323EpAddSpeexCapability(OO_SPEEX, 4, 4, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } ao2_ref(format, -1); } if(dtmf & H323_DTMF_CISCO) ret |= ooH323EpEnableDTMFCISCO(0); if(dtmf & H323_DTMF_RFC2833) ret |= ooH323EpEnableDTMFRFC2833(0); else if(dtmf & H323_DTMF_H245ALPHANUMERIC) ret |= ooH323EpEnableDTMFH245Alphanumeric(); else if(dtmf & H323_DTMF_H245SIGNAL) ret |= ooH323EpEnableDTMFH245Signal(); return ret; }
int ooh323c_set_capability_for_call (ooCallData *call, struct ast_format_cap *cap, int dtmf, int dtmfcodec, int t38support, int g729onlyA) { int ret = 0, x, txframes; if (gH323Debug) { ast_verb(0, "\tAdding capabilities to call(%s, %s)\n", call->callType, call->callToken); } if(dtmf & H323_DTMF_CISCO || 1) ret |= ooCallEnableDTMFCISCO(call,dtmfcodec); if(dtmf & H323_DTMF_RFC2833 || 1) ret |= ooCallEnableDTMFRFC2833(call,dtmfcodec); if(dtmf & H323_DTMF_H245ALPHANUMERIC || 1) ret |= ooCallEnableDTMFH245Alphanumeric(call); if(dtmf & H323_DTMF_H245SIGNAL || 1) ret |= ooCallEnableDTMFH245Signal(call); if (t38support) ooCapabilityAddT38Capability(call, OO_T38, OORXANDTX, &ooh323c_start_receive_datachannel, &ooh323c_start_transmit_datachannel, &ooh323c_stop_receive_datachannel, &ooh323c_stop_transmit_datachannel, 0); for(x=0; x<ast_format_cap_count(cap); x++) { struct ast_format *format = ast_format_cap_get_format(cap, x); if(ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g711 ulaw capability to call(%s, %s)\n", call->callType, call->callToken); } txframes = ast_format_cap_get_format_framing(cap, format); ret= ooCallAddG711Capability(call, OO_G711ULAW64K, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g711 alaw capability to call(%s, %s)\n", call->callType, call->callToken); } txframes = ast_format_cap_get_format_framing(cap, format); ret= ooCallAddG711Capability(call, OO_G711ALAW64K, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g726 capability to call (%s, %s)\n", call->callType, call->callToken); } txframes = ast_format_cap_get_format_framing(cap, format); ret = ooCallAddG726Capability(call, OO_G726, txframes, grxframes, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g726aal2 capability to call (%s, %s)\n", call->callType, call->callToken); } txframes = ast_format_cap_get_format_framing(cap, format); ret = ooCallAddG726Capability(call, OO_G726AAL2, txframes, grxframes, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) { txframes = (ast_format_cap_get_format_framing(cap, format))/10; if (gH323Debug) { ast_verb(0, "\tAdding g729A capability to call(%s, %s)\n", call->callType, call->callToken); } ret= ooCallAddG729Capability(call, OO_G729A, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); if (g729onlyA) continue; if (gH323Debug) { ast_verb(0, "\tAdding g729 capability to call(%s, %s)\n", call->callType, call->callToken); } ret|= ooCallAddG729Capability(call, OO_G729, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); if (gH323Debug) { ast_verb(0, "\tAdding g729B capability to call(%s, %s)\n", call->callType, call->callToken); } ret|= ooCallAddG729Capability(call, OO_G729B, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding g7231 capability to call (%s, %s)\n", call->callType, call->callToken); } ret = ooCallAddG7231Capability(call, OO_G7231, 1, 1, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding h263 capability to call (%s, %s)\n", call->callType, call->callToken); } ret = ooCallAddH263VideoCapability(call, OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding gsm capability to call(%s, %s)\n", call->callType, call->callToken); } ret = ooCallAddGSMCapability(call, OO_GSMFULLRATE, 4, FALSE, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } if(ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL) { if (gH323Debug) { ast_verb(0, "\tAdding Speex capability to call(%s, %s)\n", call->callType, call->callToken); } ret = ooCallAddSpeexCapability(call, OO_SPEEX, 4, 4, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, &ooh323c_stop_transmit_channel); } ao2_ref(format, -1); } return ret; }