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;
}
Example #2
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;
}
Example #3
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);
}
Example #4
0
/*! \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;
}
Example #5
0
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;
}
Example #7
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;
}
Example #8
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);
}
Example #9
0
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);
}
Example #11
0
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;
}
Example #13
0
/*! \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;
}
Example #14
0
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);
}
Example #15
0
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;
}
Example #17
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;
}
Example #18
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;
}
Example #19
0
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;
}