Пример #1
0
static int load_module(void)
{
	int res = 0;
	int x, y, idx = 0;

	trans_size = ARRAY_LEN(id_list) * ARRAY_LEN(id_list);
	if (!(translators = ast_calloc(1, sizeof(struct ast_translator) * trans_size))) {
		return AST_MODULE_LOAD_FAILURE;
	}

	for (x = 0; x < ARRAY_LEN(id_list); x++) {
		for (y = 0; y < ARRAY_LEN(id_list); y++) {
			if (x == y) {
				continue;
			}
			translators[idx].newpvt = resamp_new;
			translators[idx].destroy = resamp_destroy;
			translators[idx].framein = resamp_framein;
			translators[idx].desc_size = 0;
			translators[idx].buffer_samples = (OUTBUF_SIZE / sizeof(int16_t));
			translators[idx].buf_size = OUTBUF_SIZE;
			ast_format_set(&translators[idx].src_format, id_list[x], 0);
			ast_format_set(&translators[idx].dst_format, id_list[y], 0);
			snprintf(translators[idx].name, sizeof(translators[idx].name), "slin %dkhz -> %dkhz",
				ast_format_rate(&translators[idx].src_format), ast_format_rate(&translators[idx].dst_format));
			res |= ast_register_translator(&translators[idx]);
			idx++;
		}

	}

	return AST_MODULE_LOAD_SUCCESS;
}
Пример #2
0
static int container_test2_no_locking_helper(struct ast_format_cap *cap, struct ast_test *test)
{
	int num = 0;
	struct ast_format tmpformat = { 0, };

	ast_format_cap_add(cap, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0));
	ast_format_cap_add(cap, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0));
	ast_format_cap_add(cap, ast_format_set(&tmpformat, AST_FORMAT_G722, 0));

	ast_format_cap_iter_start(cap);
	while (!ast_format_cap_iter_next(cap, &tmpformat)) {
		num++;
	}
	ast_format_cap_iter_end(cap);

	ast_format_cap_iter_start(cap);
	while (!ast_format_cap_iter_next(cap, &tmpformat)) {
		num++;
	}
	ast_format_cap_iter_end(cap);

	ast_format_cap_destroy(cap);
	ast_test_status_update(test, "%d items iterated over\n", num);
	return (num == 6) ? AST_TEST_PASS : AST_TEST_FAIL;

}
Пример #3
0
static int load_module(void)
{
	int res;

	ast_format_set(&lintoulaw.src_format, AST_FORMAT_SLINEAR, 0);
	ast_format_set(&lintoulaw.dst_format, AST_FORMAT_ULAW, 0);

	ast_format_set(&lintotestlaw.src_format, AST_FORMAT_SLINEAR, 0);
	ast_format_set(&lintotestlaw.dst_format, AST_FORMAT_TESTLAW, 0);

	ast_format_set(&ulawtolin.src_format, AST_FORMAT_ULAW, 0);
	ast_format_set(&ulawtolin.dst_format, AST_FORMAT_SLINEAR, 0);

	ast_format_set(&testlawtolin.src_format, AST_FORMAT_TESTLAW, 0);
	ast_format_set(&testlawtolin.dst_format, AST_FORMAT_SLINEAR, 0);

	res = ast_register_translator(&ulawtolin);
	if (!res) {
		res = ast_register_translator(&lintoulaw);
		res |= ast_register_translator(&lintotestlaw);
		res |= ast_register_translator(&testlawtolin);
	} else
		ast_unregister_translator(&ulawtolin);
	if (res)
		return AST_MODULE_LOAD_FAILURE;
	return AST_MODULE_LOAD_SUCCESS;
}
static int load_module(void)
{
	ast_format_set(&g719_f.format, AST_FORMAT_G719, 0);
	if (ast_format_def_register(&g719_f))
		return AST_MODULE_LOAD_DECLINE;
	return AST_MODULE_LOAD_SUCCESS;
}
static int load_module(void)
{
	ast_format_set(&wav49_f.format, AST_FORMAT_GSM, 0);
	if (ast_format_def_register(&wav49_f))
		return AST_MODULE_LOAD_FAILURE;
	return AST_MODULE_LOAD_SUCCESS;
}
Пример #6
0
static struct ast_channel *rec_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
{
	struct ast_channel *chan;
	struct ast_format format;
	const char *conf_name = data;

	chan = ast_channel_alloc(1, AST_STATE_UP, NULL, NULL, NULL, NULL, NULL, NULL, 0,
		"CBRec/conf-%s-uid-%d",
		conf_name, (int) ast_random());
	if (!chan) {
		return NULL;
	}
	if (ast_channel_add_bridge_role(chan, "recorder")) {
		ast_channel_release(chan);
		return NULL;
	}
	ast_format_set(&format, AST_FORMAT_SLINEAR, 0);
	ast_channel_tech_set(chan, conf_record_get_tech());
	ast_format_cap_add_all(ast_channel_nativeformats(chan));
	ast_format_copy(ast_channel_writeformat(chan), &format);
	ast_format_copy(ast_channel_rawwriteformat(chan), &format);
	ast_format_copy(ast_channel_readformat(chan), &format);
	ast_format_copy(ast_channel_rawreadformat(chan), &format);
	return chan;
}
static struct ast_frame *wav_read(struct ast_filestream *s, int *whennext)
{
	/* Send a frame from the file to the appropriate channel */
	struct wavg_desc *fs = (struct wavg_desc *)s->_private;

	s->fr.frametype = AST_FRAME_VOICE;
	ast_format_set(&s->fr.subclass.format, AST_FORMAT_GSM, 0);
	s->fr.offset = AST_FRIENDLY_OFFSET;
	s->fr.samples = GSM_SAMPLES;
	s->fr.mallocd = 0;
	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, GSM_FRAME_SIZE);
	if (fs->secondhalf) {
		/* Just return a frame based on the second GSM frame */
		s->fr.data.ptr = (char *)s->fr.data.ptr + GSM_FRAME_SIZE;
		s->fr.offset += GSM_FRAME_SIZE;
	} else {
		/* read and convert */
		unsigned char msdata[MSGSM_FRAME_SIZE];
		int res;
		
		if ((res = fread(msdata, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) {
			if (res && (res != 1))
				ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
			return NULL;
		}
		/* Convert from MS format to two real GSM frames */
		conv65(msdata, s->fr.data.ptr);
	}
	fs->secondhalf = !fs->secondhalf;
	*whennext = GSM_SAMPLES;
	return &s->fr;
}
Пример #8
0
static int fax_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
{
	fax_state_t *fax = (fax_state_t*) data;
	uint8_t buffer[AST_FRIENDLY_OFFSET + MAX_SAMPLES * sizeof(uint16_t)];
	int16_t *buf = (int16_t *) (buffer + AST_FRIENDLY_OFFSET);
    
	struct ast_frame outf = {
		.frametype = AST_FRAME_VOICE,
		.src = __FUNCTION__,
	};
	ast_format_set(&outf.subclass.format, AST_FORMAT_SLINEAR, 0);

	if (samples > MAX_SAMPLES) {
		ast_log(LOG_WARNING, "Only generating %d samples, where %d requested\n", MAX_SAMPLES, samples);
		samples = MAX_SAMPLES;
	}
	
	if ((len = fax_tx(fax, buf, samples)) > 0) {
		outf.samples = len;
		AST_FRAME_SET_BUFFER(&outf, buffer, AST_FRIENDLY_OFFSET, len * sizeof(int16_t));

		if (ast_write(chan, &outf) < 0) {
			ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", ast_channel_name(chan), strerror(errno));
			return -1;
		}
	}

	return 0;
}
Пример #9
0
static int load_module(void)
{
	int res;

	ast_format_set(&gsmtolin.src_format, AST_FORMAT_GSM, 0);
	ast_format_set(&gsmtolin.dst_format, AST_FORMAT_SLINEAR, 0);

	ast_format_set(&lintogsm.src_format, AST_FORMAT_SLINEAR, 0);
	ast_format_set(&lintogsm.dst_format, AST_FORMAT_GSM, 0);

	res = ast_register_translator(&gsmtolin);
	if (!res) 
		res=ast_register_translator(&lintogsm);
	else
		ast_unregister_translator(&gsmtolin);
	if (res) 
		return AST_MODULE_LOAD_FAILURE;
	return AST_MODULE_LOAD_SUCCESS;
}
Пример #10
0
/*
* Send a single tone burst for a specifed duration and frequency.
* Returns 0 if successful
*/
static int send_tone_burst(struct ast_channel *chan, float freq, int duration, int tldn)
{
	int res = 0;
	int i = 0;
	int x = 0;
	struct ast_frame *f, wf;
	
	struct {
		unsigned char offset[AST_FRIENDLY_OFFSET];
		unsigned char buf[640];
	} tone_block;

	for (;;) {

		if (ast_waitfor(chan, -1) < 0) {
			res = -1;
			break;
		}

		f = ast_read(chan);
		if (!f) {
			res = -1;
			break;
		}

		if (f->frametype == AST_FRAME_VOICE) {
			wf.frametype = AST_FRAME_VOICE;
			ast_format_set(&wf.subclass.format, AST_FORMAT_ULAW, 0);
			wf.offset = AST_FRIENDLY_OFFSET;
			wf.mallocd = 0;
			wf.data.ptr = tone_block.buf;
			wf.datalen = f->datalen;
			wf.samples = wf.datalen;
			
			make_tone_burst(tone_block.buf, freq, (float) tldn, wf.datalen, &x);

			i += wf.datalen / 8;
			if (i > duration) {
				ast_frfree(f);
				break;
			}
			if (ast_write(chan, &wf)) {
				ast_verb(4, "AlarmReceiver: Failed to write frame on %s\n", ast_channel_name(chan));
				ast_log(LOG_WARNING, "AlarmReceiver Failed to write frame on %s\n",ast_channel_name(chan));
				res = -1;
				ast_frfree(f);
				break;
			}
		}

		ast_frfree(f);
	}
	return res;
}
static int load_module(void)
{
	int i;

	/* XXX better init ? */
	for (i = 0; i < ARRAY_LEN(ulaw_silence); i++)
		ulaw_silence[i] = AST_LIN2MU(0);
	for (i = 0; i < ARRAY_LEN(alaw_silence); i++)
		alaw_silence[i] = AST_LIN2A(0);

	ast_format_set(&pcm_f.format, AST_FORMAT_ULAW, 0);
	ast_format_set(&alaw_f.format, AST_FORMAT_ALAW, 0);
	ast_format_set(&au_f.format, AST_FORMAT_ULAW, 0);
	ast_format_set(&g722_f.format, AST_FORMAT_G722, 0);
	if ( ast_format_def_register(&pcm_f)
		|| ast_format_def_register(&alaw_f)
		|| ast_format_def_register(&au_f)
		|| ast_format_def_register(&g722_f) )
		return AST_MODULE_LOAD_FAILURE;
	return AST_MODULE_LOAD_SUCCESS;
}
Пример #12
0
/** \brief Load module */
static int load_module(void)
{
	ast_log(LOG_NOTICE, "Load Res-Speech-UniMRCP module\n");

	if(uni_engine_load() == FALSE) {
		return AST_MODULE_LOAD_FAILURE;
	}

	if(mrcp_client_start(uni_engine.client) != TRUE) {
		ast_log(LOG_ERROR, "Failed to start MRCP client\n");
		uni_engine_unload();
		return AST_MODULE_LOAD_FAILURE;
	}

#if AST_VERSION_AT_LEAST(10,0,0)

#if AST_VERSION_AT_LEAST(13,0,0)
	ast_engine.formats = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
#elif AST_VERSION_AT_LEAST(12,0,0)
	ast_engine.formats = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK);
#else /* <= 11 */
	ast_engine.formats = ast_format_cap_alloc_nolock();
#endif
	if(!ast_engine.formats) {
		ast_log(LOG_ERROR, "Failed to alloc media format capabilities\n");
		uni_engine_unload();
		return AST_MODULE_LOAD_FAILURE;
	}
#if AST_VERSION_AT_LEAST(13,0,0)
	ast_format_cap_append(ast_engine.formats, ast_format_slin, 0);
#else
	struct ast_format format;
	ast_format_set(&format, AST_FORMAT_SLINEAR, 0);
	ast_format_cap_add(ast_engine.formats, &format);
#endif

#else /* <= 1.8 */
	ast_engine.formats = AST_FORMAT_SLINEAR;
#endif

	if(ast_speech_register(&ast_engine)) {
		ast_log(LOG_ERROR, "Failed to register module\n");
		mrcp_client_shutdown(uni_engine.client);
		uni_engine_unload();
		return AST_MODULE_LOAD_FAILURE;
	}

	return AST_MODULE_LOAD_SUCCESS;
}
Пример #13
0
static int load_module(void)
{
	int res;
	int x;

	ast_format_set(&alawtoulaw.src_format, AST_FORMAT_ALAW, 0);
	ast_format_set(&alawtoulaw.dst_format, AST_FORMAT_ULAW, 0);

	ast_format_set(&ulawtoalaw.src_format, AST_FORMAT_ULAW, 0);
	ast_format_set(&ulawtoalaw.dst_format, AST_FORMAT_ALAW, 0);

	for (x=0;x<256;x++) {
		mu2a[x] = AST_LIN2A(AST_MULAW(x));
		a2mu[x] = AST_LIN2MU(AST_ALAW(x));
	}
	res = ast_register_translator(&alawtoulaw);
	if (!res)
		res = ast_register_translator(&ulawtoalaw);
	else
		ast_unregister_translator(&alawtoulaw);
	if (res)
		return AST_MODULE_LOAD_FAILURE;
	return AST_MODULE_LOAD_SUCCESS;
}
Пример #14
0
static int load_module(void)
{
	int i;
	ast_format_set(&slin_f.format, AST_FORMAT_SLINEAR, 0);
	ast_format_set(&slin12_f.format, AST_FORMAT_SLINEAR12, 0);
	ast_format_set(&slin16_f.format, AST_FORMAT_SLINEAR16, 0);
	ast_format_set(&slin24_f.format, AST_FORMAT_SLINEAR24, 0);
	ast_format_set(&slin32_f.format, AST_FORMAT_SLINEAR32, 0);
	ast_format_set(&slin44_f.format, AST_FORMAT_SLINEAR44, 0);
	ast_format_set(&slin48_f.format, AST_FORMAT_SLINEAR48, 0);
	ast_format_set(&slin96_f.format, AST_FORMAT_SLINEAR96, 0);
	ast_format_set(&slin192_f.format, AST_FORMAT_SLINEAR192, 0);

	for (i = 0; i < ARRAY_LEN(slin_list); i++) {
		if (ast_format_def_register(slin_list[i])) {
			return AST_MODULE_LOAD_FAILURE;
		}
	}

	return AST_MODULE_LOAD_SUCCESS;
}
static struct ast_frame *gsm_read(struct ast_filestream *s, int *whennext)
{
	int res;

	s->fr.frametype = AST_FRAME_VOICE;
	ast_format_set(&s->fr.subclass.format, AST_FORMAT_GSM, 0);
	AST_FRAME_SET_BUFFER(&(s->fr), s->buf, AST_FRIENDLY_OFFSET, GSM_FRAME_SIZE)
	s->fr.mallocd = 0;
	if ((res = fread(s->fr.data.ptr, 1, GSM_FRAME_SIZE, s->f)) != GSM_FRAME_SIZE) {
		if (res)
			ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
		return NULL;
	}
	*whennext = s->fr.samples = GSM_SAMPLES;
	return &s->fr;
}
Пример #16
0
static struct ast_frame *ilbc_read(struct ast_filestream *s, int *whennext)
{
	int res;
	/* Send a frame from the file to the appropriate channel */
	s->fr.frametype = AST_FRAME_VOICE;
	ast_format_set(&s->fr.subclass.format, AST_FORMAT_ILBC, 0);
	s->fr.mallocd = 0;
	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, ILBC_BUF_SIZE);
	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
		if (res)
			ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
		return NULL;
	}
	*whennext = s->fr.samples = ILBC_SAMPLES;
	return &s->fr;
}
Пример #17
0
/*! \brief Called when we want to place a call somewhere, but not actually call it... yet */
static struct ast_channel *bridge_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
	struct bridge_pvt *p = NULL;
	struct ast_format slin;

	/* Try to allocate memory for our very minimal pvt structure */
	if (!(p = ao2_alloc(sizeof(*p), NULL))) {
		return NULL;
	}

	/* Try to grab two Asterisk channels to use as input and output channels */
	if (!(p->input = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-input", p))) {
		ao2_ref(p, -1);
		return NULL;
	}
	if (!(p->output = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-output", p))) {
		p->input = ast_channel_release(p->input);
		ao2_ref(p, -1);
		return NULL;
	}

	/* Setup parameters on both new channels */
	p->input->tech = p->output->tech = &bridge_tech;

	ao2_ref(p, 2);
	p->input->tech_pvt = p->output->tech_pvt = p;

	ast_format_set(&slin, AST_FORMAT_SLINEAR, 0);

	ast_format_cap_add(p->input->nativeformats, &slin);
	ast_format_cap_add(p->output->nativeformats, &slin);
	ast_format_copy(&p->input->readformat, &slin);
	ast_format_copy(&p->output->readformat, &slin);
	ast_format_copy(&p->input->rawreadformat, &slin);
	ast_format_copy(&p->output->rawreadformat, &slin);
	ast_format_copy(&p->input->writeformat, &slin);
	ast_format_copy(&p->output->writeformat, &slin);
	ast_format_copy(&p->input->rawwriteformat, &slin);
	ast_format_copy(&p->output->rawwriteformat, &slin);

	ast_answer(p->output);
	ast_answer(p->input);

	/* remove the reference from the alloc. The channels now own the pvt. */
	ao2_ref(p, -1);
	return p->input;
}
Пример #18
0
static struct ast_frame *mp3_read(struct ast_filestream *s, int *whennext)
{

	struct mp3_private *p = s->_private;
	int delay =0;
	int save=0;

	/* Send a frame from the file to the appropriate channel */

	if(mp3_queue(s))
		return NULL;

	if(p->dbuflen) {
		for(p->buflen=0; p->buflen < MP3_BUFLEN && p->buflen < p->dbuflen; p->buflen++) {
			s->buf[p->buflen + AST_FRIENDLY_OFFSET] = p->dbuf[p->buflen+p->dbufoffset];
			p->sbufoffset++;
		}
		p->dbufoffset += p->buflen;
		p->dbuflen -= p->buflen;

		if(p->buflen < MP3_BUFLEN) {
			if(mp3_queue(s))
				return NULL;

			for(save = p->buflen; p->buflen < MP3_BUFLEN; p->buflen++) {
				s->buf[p->buflen + AST_FRIENDLY_OFFSET] = p->dbuf[(p->buflen-save)+p->dbufoffset];
				p->sbufoffset++;
			}
			p->dbufoffset += (MP3_BUFLEN - save);
			p->dbuflen -= (MP3_BUFLEN - save);

		} 

	}
	
	p->offset += p->buflen;
	delay = p->buflen/2;
	s->fr.frametype = AST_FRAME_VOICE;
	ast_format_set(&s->fr.subclass.format, AST_FORMAT_SLINEAR, 0);
	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, p->buflen);
	s->fr.mallocd = 0;
	s->fr.samples = delay;
	*whennext = delay;
	return &s->fr;
}
Пример #19
0
static struct ast_frame *generic_read(struct ast_filestream *s, int *whennext, unsigned int buf_size, enum ast_format_id id)
{
	int res;
	/* Send a frame from the file to the appropriate channel */

	s->fr.frametype = AST_FRAME_VOICE;
	ast_format_set(&s->fr.subclass.format, id, 0);
	s->fr.mallocd = 0;
	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, buf_size);
	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
		if (res)
			ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
		return NULL;
	}
	*whennext = s->fr.samples = res/2;
	s->fr.datalen = res;
	return &s->fr;
}
Пример #20
0
static int spy_generate(struct ast_channel *chan, void *data, int len, int samples)
{
	struct chanspy_translation_helper *csth = data;
	struct ast_frame *f, *cur;
	struct ast_format format_slin;

	ast_format_set(&format_slin, AST_FORMAT_SLINEAR, 0);

	ast_audiohook_lock(&csth->spy_audiohook);
	if (csth->spy_audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
		/* Channel is already gone more than likely */
		ast_audiohook_unlock(&csth->spy_audiohook);
		return -1;
	}

	if (ast_test_flag(&csth->flags, OPTION_READONLY)) {
		/* Option 'o' was set, so don't mix channel audio */
		f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_READ, &format_slin);
	} else {
		f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, &format_slin);
	}

	ast_audiohook_unlock(&csth->spy_audiohook);

	if (!f)
		return 0;

	for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
		if (ast_write(chan, cur)) {
			ast_frfree(f);
			return -1;
		}

		if (csth->fd) {
			if (write(csth->fd, cur->data.ptr, cur->datalen) < 0) {
				ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
			}
		}
	}

	ast_frfree(f);

	return 0;
}
Пример #21
0
/*!
 * \brief Read a frame full of audio data from the filestream.
 * \param fs The filestream.
 * \param whennext Number of sample times to schedule the next call.
 * \return A pointer to a frame containing audio data or NULL ifthere is no more audio data.
 */
static struct ast_frame *ogg_vorbis_read(struct ast_filestream *fs,
					 int *whennext)
{
	struct ogg_vorbis_desc *desc = (struct ogg_vorbis_desc *) fs->_private;
	int current_bitstream = -10;
	char *out_buf;
	long bytes_read;

	if (desc->writing) {
		ast_log(LOG_WARNING, "Reading is not supported on OGG/Vorbis on write files.\n");
		return NULL;
	}

	/* initialize frame */
	fs->fr.frametype = AST_FRAME_VOICE;
	ast_format_set(&fs->fr.subclass.format, AST_FORMAT_SLINEAR, 0);
	fs->fr.mallocd = 0;
	AST_FRAME_SET_BUFFER(&fs->fr, fs->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
	out_buf = (char *) (fs->fr.data.ptr);	/* SLIN data buffer */

	/* read samples from OV interface */
	bytes_read = ov_read(
		&desc->ov_f,
		out_buf,						/* Buffer to write data */
		BUF_SIZE,						/* Size of buffer */
		(__BYTE_ORDER == __BIG_ENDIAN),	/* Endianes (0 for little) */
		2,								/* 1 = 8bit, 2 = 16bit */
		1,								/* 0 = unsigned, 1 = signed */
		&current_bitstream				/* Returns the current bitstream section */
	);

	/* check returned data */
	if (bytes_read <= 0) {
		/* End of stream */
		return NULL;
	}

	/* Return decoded bytes */
	fs->fr.datalen = bytes_read;
	fs->fr.samples = bytes_read / 2;
	*whennext = fs->fr.samples;
	return &fs->fr;
}
Пример #22
0
static struct ast_frame *h263_read(struct ast_filestream *s, int *whennext)
{
	int res;
	uint32_t mark;
	unsigned short len;
	unsigned int ts;
	struct h263_desc *fs = (struct h263_desc *)s->_private;

	/* Send a frame from the file to the appropriate channel */
	if ((res = fread(&len, 1, sizeof(len), s->f)) < 1)
		return NULL;
	len = ntohs(len);
	mark = (len & 0x8000) ? 1 : 0;
	len &= 0x7fff;
	if (len > BUF_SIZE) {
		ast_log(LOG_WARNING, "Length %d is too long\n", len);
		return NULL;
	}
	s->fr.frametype = AST_FRAME_VIDEO;
	ast_format_set(&s->fr.subclass.format, AST_FORMAT_H263, 0);
	s->fr.mallocd = 0;
	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, len);
	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
		if (res)
			ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
		return NULL;
	}
	s->fr.samples = fs->lastts;	/* XXX what ? */
	s->fr.datalen = len;
	if (mark) {
		ast_format_set_video_mark(&s->fr.subclass.format);
	}
	s->fr.delivery.tv_sec = 0;
	s->fr.delivery.tv_usec = 0;
	if ((res = fread(&ts, 1, sizeof(ts), s->f)) == sizeof(ts)) {
		fs->lastts = ntohl(ts);
		*whennext = fs->lastts * 4/45;
	} else
		*whennext = 0;
	return &s->fr;
}
Пример #23
0
static int milliwatt_generate(struct ast_channel *chan, void *data, int len, int samples)
{
	unsigned char buf[AST_FRIENDLY_OFFSET + 640];
	const int maxsamples = ARRAY_LEN(buf) - (AST_FRIENDLY_OFFSET / sizeof(buf[0]));
	int i, *indexp = (int *) data;
	struct ast_frame wf = {
		.frametype = AST_FRAME_VOICE,
		.offset = AST_FRIENDLY_OFFSET,
		.src = __FUNCTION__,
	};
	ast_format_set(&wf.subclass.format, AST_FORMAT_ULAW, 0);
	wf.data.ptr = buf + AST_FRIENDLY_OFFSET;

	/* Instead of len, use samples, because channel.c generator_force
	* generate(chan, tmp, 0, 160) ignores len. In any case, len is
	* a multiple of samples, given by number of samples times bytes per
	* sample. In the case of ulaw, len = samples. for signed linear
	* len = 2 * samples */
	if (samples > maxsamples) {
		ast_log(LOG_WARNING, "Only doing %d samples (%d requested)\n", maxsamples, samples);
		samples = maxsamples;
	}

	len = samples * sizeof (buf[0]);
	wf.datalen = len;
	wf.samples = samples;

	/* create a buffer containing the digital milliwatt pattern */
	for (i = 0; i < len; i++) {
		buf[AST_FRIENDLY_OFFSET + i] = digital_milliwatt[(*indexp)++];
		*indexp &= 7;
	}

	if (ast_write(chan,&wf) < 0) {
		ast_log(LOG_WARNING,"Failed to write frame to '%s': %s\n",ast_channel_name(chan),strerror(errno));
		return -1;
	}

	return 0;
}
Пример #24
0
static struct ast_frame *g723_read(struct ast_filestream *s, int *whennext)
{
	unsigned short size;
	int res;
	int delay;
	/* Read the delay for the next packet, and schedule again if necessary */
	/* XXX is this ignored ? */
	if (fread(&delay, 1, 4, s->f) == 4) 
		delay = ntohl(delay);
	else
		delay = -1;
	if (fread(&size, 1, 2, s->f) != 2) {
		/* Out of data, or the file is no longer valid.  In any case
		   go ahead and stop the stream */
		return NULL;
	}
	/* Looks like we have a frame to read from here */
	size = ntohs(size);
	if (size > G723_MAX_SIZE) {
		ast_log(LOG_WARNING, "Size %d is invalid\n", size);
		/* The file is apparently no longer any good, as we
		   shouldn't ever get frames even close to this 
		   size.  */
		return NULL;
	}
	/* Read the data into the buffer */
	s->fr.frametype = AST_FRAME_VOICE;
	ast_format_set(&s->fr.subclass.format, AST_FORMAT_G723_1, 0);
	s->fr.mallocd = 0;
	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, size);
	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != size) {
		ast_log(LOG_WARNING, "Short read (%d of %d bytes) (%s)!\n", res, size, strerror(errno));
		return NULL;
	}
	*whennext = s->fr.samples = 240;
	return &s->fr;
}
Пример #25
0
static int nv_detectfax_exec(struct ast_channel *chan, const char *data)
{
	int res = 0;
	char tmp[256] = "\0";
	char *p = NULL;
	char *waitstr = NULL;
	char *options = NULL;
	char *silstr = NULL;
	char *minstr = NULL;
	char *maxstr = NULL;
	struct ast_frame *fr = NULL;
	struct ast_frame *fr2 = NULL;
	int notsilent = 0;
	struct timeval start = {0, 0}, end = {0, 0};
	int waitdur = 4;
	int sildur = 1000;
	int mindur = 100;
	int maxdur = -1;
	int skipanswer = 0;
	int noextneeded = 0;
	int ignoredtmf = 0;
	int ignorefax = 0;
	int ignoretalk = 0;
	int x = 0;
	struct ast_format* origrformat = NULL;
	int features = 0;
	time_t timeout = 0;
	struct ast_dsp *dsp = NULL;
	
	struct ast_format_cap *cap;
	struct ast_format linearFormat;
	
	/* linear format capabilities */
	ast_format_set(&linearFormat, AST_FORMAT_SLINEAR, 0);
	cap = ast_format_cap_alloc_nolock();
	ast_format_cap_add(cap, &linearFormat);
	/* done */
	
	pbx_builtin_setvar_helper(chan, "FAX_DETECTED", "");
	pbx_builtin_setvar_helper(chan, "FAXEXTEN", "");
	pbx_builtin_setvar_helper(chan, "DTMF_DETECTED", "");
	pbx_builtin_setvar_helper(chan, "TALK_DETECTED", "");
	
	if (data || !ast_strlen_zero(data)) {
		strncpy(tmp, data, sizeof(tmp)-1);
	}	
	
	p = tmp;
	
	waitstr = strsep(&p, ",");
	options = strsep(&p, ",");
	silstr = strsep(&p, ",");
	minstr = strsep(&p, ",");	
	maxstr = strsep(&p, ",");	
	
	if (waitstr) {
		if ((sscanf(waitstr, "%d", &x) == 1) && (x > 0))
			waitdur = x;
	}
	
	if (options) {
		if (strchr(options, 'n'))
			skipanswer = 1;
		if (strchr(options, 'x'))
			noextneeded = 1;
		if (strchr(options, 'd'))
			ignoredtmf = 1;
		if (strchr(options, 'f'))
			ignorefax = 1;
		if (strchr(options, 't'))
			ignoretalk = 1;
	}
	
	if (silstr) {
		if ((sscanf(silstr, "%d", &x) == 1) && (x > 0))
			sildur = x;
	}
	
	if (minstr) {
		if ((sscanf(minstr, "%d", &x) == 1) && (x > 0))
			mindur = x;
	}
	
	if (maxstr) {
		if ((sscanf(maxstr, "%d", &x) == 1) && (x > 0))
			maxdur = x;
	}
	
	ast_log(LOG_DEBUG, "Preparing detect of fax (waitdur=%dms, sildur=%dms, mindur=%dms, maxdur=%dms)\n", 
						waitdur, sildur, mindur, maxdur);
						
	//	LOCAL_USER_ADD(u);
// 	if (chan->_state != AST_STATE_UP && !skipanswer) {
	if (ast_channel_state(chan) != AST_STATE_UP && !skipanswer) {
		/* Otherwise answer unless we're supposed to send this while on-hook */
		res = ast_answer(chan);
	}
	if (!res) {
// 		origrformat = chan->readformat;
		origrformat = ast_channel_readformat(chan);
		
// 		if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR))) 
		if ((res = ast_set_read_format_from_cap(chan, cap)) ){
			ast_log(LOG_WARNING, "Unable to set read format to linear!\n");
		}
	}
	if (!(dsp = ast_dsp_new())) {
		ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
		res = -1;
	}
	
	if (dsp) {	
		if (!ignoretalk)
			; /* features |= DSP_FEATURE_SILENCE_SUPPRESS; */
		if (!ignorefax)
			features |= DSP_FEATURE_FAX_DETECT;
		//if (!ignoredtmf)
			features |= DSP_FEATURE_DIGIT_DETECT;
			
		ast_dsp_set_threshold(dsp, 256); 
		ast_dsp_set_features(dsp, features | DSP_DIGITMODE_RELAXDTMF);
		ast_dsp_set_digitmode(dsp, DSP_DIGITMODE_DTMF);
	}

	if (!res) {
		if (waitdur > 0)
			timeout = time(NULL) + (time_t)waitdur;

		while(ast_waitfor(chan, -1) > -1) {
			if (waitdur > 0 && time(NULL) > timeout) {
				res = 0;
				break;
			}

			fr = ast_read(chan);
			if (!fr) {
				ast_log(LOG_DEBUG, "Got hangup\n");
				res = -1;
				break;
			}

			fr2 = ast_dsp_process(chan, dsp, fr);
			if (!fr2) {
				ast_log(LOG_WARNING, "Bad DSP received (what happened?)\n");
				fr2 = fr;
			} 

			if (fr2->frametype == AST_FRAME_DTMF) {
				if (fr2->subclass.integer == 'f' && !ignorefax) {
					/* Fax tone -- Handle and return NULL */
					ast_log(LOG_DEBUG, "Fax detected on %s\n", ast_channel_name(chan));
					ast_log(LOG_DEBUG, "Fax detected on %s\n", ast_channel_name(chan));
					if (strcmp(ast_channel_exten(chan), "fax")) {
						ast_log(LOG_NOTICE, "Redirecting %s to fax extension\n", ast_channel_name(chan));
						pbx_builtin_setvar_helper(chan, "FAX_DETECTED", "1");
						pbx_builtin_setvar_helper(chan,"FAXEXTEN",ast_channel_exten(chan));								
						if (ast_exists_extension(chan, ast_channel_context(chan), "fax", 1, ast_channel_caller(chan)->id.number.str)) {
							/* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
// 							strncpy(ast_channel_exten(chan), "fax", sizeof(ast_channel_exten(chan))-1);
// 							chan->priority = 0;
							ast_channel_exten_set(chan, "fax");
							ast_channel_priority_set(chan, 0);
						} else
							ast_log(LOG_WARNING, "Fax detected, but no fax extension\n");
					} else
						ast_log(LOG_WARNING, "Already in a fax extension, not redirecting\n");

					res = 0;
					ast_frfree(fr);
					break;
				} else if (!ignoredtmf) {
					ast_log(LOG_DEBUG, "DTMF detected on %s\n", ast_channel_name(chan));
					char t[2];
					t[0] = fr2->subclass.integer;
					t[1] = '\0';
					if (noextneeded || ast_canmatch_extension(chan, ast_channel_context(chan), t, 1, ast_channel_caller(chan)->id.number.str)) {
						pbx_builtin_setvar_helper(chan, "DTMF_DETECTED", "1");
						/* They entered a valid extension, or might be anyhow */
						if (noextneeded) {
							ast_log(LOG_NOTICE, "DTMF received (not matching to exten)\n");
							res = 0;
						} else {
							ast_log(LOG_NOTICE, "DTMF received (matching to exten)\n");
							res = fr2->subclass.integer;
						}
						ast_frfree(fr);
						break;
					} else
						ast_log(LOG_DEBUG, "Valid extension requested and DTMF did not match\n");
				}
// 			} else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR) && !ignoretalk) {
			} else if ((fr->frametype == AST_FRAME_VOICE) && ( ast_format_cap_iscompatible(cap, &fr->subclass.format)) && !ignoretalk) {
				int totalsilence;
				int ms;
				res = ast_dsp_silence(dsp, fr, &totalsilence);
				if (res && (totalsilence > sildur)) {
					/* We've been quiet a little while */
					if (notsilent) {
						/* We had heard some talking */
						gettimeofday(&end, NULL);
						ms = (end.tv_sec - start.tv_sec) * 1000;
						ms += (end.tv_usec - start.tv_usec) / 1000;
						ms -= sildur;
						if (ms < 0)
							ms = 0;
						if ((ms > mindur) && ((maxdur < 0) || (ms < maxdur))) {
							char ms_str[10];
							ast_log(LOG_DEBUG, "Found qualified token of %d ms\n", ms);
							ast_log(LOG_NOTICE, "Redirecting %s to talk extension\n", ast_channel_name(chan));

							/* Save detected talk time (in milliseconds) */ 
							sprintf(ms_str, "%d", ms);	
							pbx_builtin_setvar_helper(chan, "TALK_DETECTED", ms_str);

							if (ast_exists_extension(chan, ast_channel_context(chan), "talk", 1, ast_channel_caller(chan)->id.number.str)) {
// 								strncpy(ast_channel_exten(chan), "talk", sizeof(ast_channel_exten(chan)) - 1);
// 								chan->priority = 0;
								ast_channel_exten_set(chan, "talk");
								ast_channel_priority_set(chan, 0);
							} else
								ast_log(LOG_WARNING, "Talk detected, but no talk extension\n");
							res = 0;
							ast_frfree(fr);
							break;
						} else
							ast_log(LOG_DEBUG, "Found unqualified token of %d ms\n", ms);
						notsilent = 0;
					}
				} else {
					if (!notsilent) {
						/* Heard some audio, mark the begining of the token */
						gettimeofday(&start, NULL);
						ast_log(LOG_DEBUG, "Start of voice token!\n");
						notsilent = 1;
					}
				}						
			}
			ast_frfree(fr);
		}
	} else
		ast_log(LOG_WARNING, "Could not answer channel '%s'\n", ast_channel_name(chan));
	
	if (res > -1) {
		if (origrformat && ast_set_read_format(chan, origrformat)) {
			ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n", 
				ast_channel_name(chan), ast_getformatname(origrformat));
		}
	}
	
	if (dsp)
		ast_dsp_free(dsp);
	
	//	LOCAL_USER_REMOVE(u);
	ast_format_cap_destroy(cap);
	return res;
}
Пример #26
0
static int NBScat_exec(struct ast_channel *chan, const char *data)
{
	int res=0;
	int fds[2];
	int ms = -1;
	int pid = -1;
	struct ast_format owriteformat;
	struct timeval next;
	struct ast_frame *f;
	struct myframe {
		struct ast_frame f;
		char offset[AST_FRIENDLY_OFFSET];
		short frdata[160];
	} myf;

	ast_format_clear(&owriteformat);
	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) {
		ast_log(LOG_WARNING, "Unable to create socketpair\n");
		return -1;
	}
	
	ast_stopstream(chan);

	ast_format_copy(&owriteformat, &chan->writeformat);
	res = ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
	if (res < 0) {
		ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
		return -1;
	}
	
	res = NBScatplay(fds[1]);
	/* Wait 1000 ms first */
	next = ast_tvnow();
	next.tv_sec += 1;
	if (res >= 0) {
		pid = res;
		/* Order is important -- there's almost always going to be mp3...  we want to prioritize the
		   user */
		for (;;) {
			ms = ast_tvdiff_ms(next, ast_tvnow());
			if (ms <= 0) {
				res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata));
				if (res > 0) {
					myf.f.frametype = AST_FRAME_VOICE;
					ast_format_set(&myf.f.subclass.format, AST_FORMAT_SLINEAR, 0);
					myf.f.datalen = res;
					myf.f.samples = res / 2;
					myf.f.mallocd = 0;
					myf.f.offset = AST_FRIENDLY_OFFSET;
					myf.f.src = __PRETTY_FUNCTION__;
					myf.f.delivery.tv_sec = 0;
					myf.f.delivery.tv_usec = 0;
					myf.f.data.ptr = myf.frdata;
					if (ast_write(chan, &myf.f) < 0) {
						res = -1;
						break;
					}
				} else {
					ast_debug(1, "No more mp3\n");
					res = 0;
					break;
				}
				next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000));
			} else {
				ms = ast_waitfor(chan, ms);
				if (ms < 0) {
					ast_debug(1, "Hangup detected\n");
					res = -1;
					break;
				}
				if (ms) {
					f = ast_read(chan);
					if (!f) {
						ast_debug(1, "Null frame == hangup() detected\n");
						res = -1;
						break;
					}
					if (f->frametype == AST_FRAME_DTMF) {
						ast_debug(1, "User pressed a key\n");
						ast_frfree(f);
						res = 0;
						break;
					}
					ast_frfree(f);
				} 
			}
		}
	}
	close(fds[0]);
	close(fds[1]);
	
	if (pid > -1)
		kill(pid, SIGKILL);
	if (!res && owriteformat.id)
		ast_set_write_format(chan, &owriteformat);

	return res;
}
Пример #27
0
static int adsi_careful_send(struct ast_channel *chan, unsigned char *buf, int len, int *remain)
{
	/* Sends carefully on a full duplex channel by using reading for
	   timing */
	struct ast_frame *inf, outf;
	int amt;

	/* Zero out our outgoing frame */
	memset(&outf, 0, sizeof(outf));

	if (remain && *remain) {
		amt = len;

		/* Send remainder if provided */
		if (amt > *remain) {
			amt = *remain;
		} else {
			*remain = *remain - amt;
		}
		outf.frametype = AST_FRAME_VOICE;
		ast_format_set(&outf.subclass.format, AST_FORMAT_ULAW, 0);
		outf.data.ptr = buf;
		outf.datalen = amt;
		outf.samples = amt;
		if (ast_write(chan, &outf)) {
			ast_log(LOG_WARNING, "Failed to carefully write frame\n");
			return -1;
		}
		/* Update pointers and lengths */
		buf += amt;
		len -= amt;
	}

	while (len) {
		amt = len;
		/* If we don't get anything at all back in a second, forget
		   about it */
		if (ast_waitfor(chan, 1000) < 1) {
			return -1;
		}
		/* Detect hangup */
		if (!(inf = ast_read(chan))) {
			return -1;
		}

		/* Drop any frames that are not voice */
		if (inf->frametype != AST_FRAME_VOICE) {
			ast_frfree(inf);
			continue;
		}

		if (inf->subclass.format.id != AST_FORMAT_ULAW) {
			ast_log(LOG_WARNING, "Channel not in ulaw?\n");
			ast_frfree(inf);
			return -1;
		}
		/* Send no more than they sent us */
		if (amt > inf->datalen) {
			amt = inf->datalen;
		} else if (remain) {
			*remain = inf->datalen - amt;
		}
		outf.frametype = AST_FRAME_VOICE;
		ast_format_set(&outf.subclass.format, AST_FORMAT_ULAW, 0);
		outf.data.ptr = buf;
		outf.datalen = amt;
		outf.samples = amt;
		if (ast_write(chan, &outf)) {
			ast_log(LOG_WARNING, "Failed to carefully write frame\n");
			ast_frfree(inf);
			return -1;
		}
		/* Update pointers and lengths */
		buf += amt;
		len -= amt;
		ast_frfree(inf);
	}
	return 0;
}
Пример #28
0
static int load_module(void)
{
	int res = 0;

	if (parse_config(0))
		return AST_MODULE_LOAD_DECLINE;


	ast_format_set(&speextolin.src_format, AST_FORMAT_SPEEX, 0);
	ast_format_set(&speextolin.dst_format, AST_FORMAT_SLINEAR, 0);

	ast_format_set(&lintospeex.src_format, AST_FORMAT_SLINEAR, 0);
	ast_format_set(&lintospeex.dst_format, AST_FORMAT_SPEEX, 0);

	ast_format_set(&speexwbtolin16.src_format, AST_FORMAT_SPEEX16, 0);
	ast_format_set(&speexwbtolin16.dst_format, AST_FORMAT_SLINEAR16, 0);

	ast_format_set(&lin16tospeexwb.src_format, AST_FORMAT_SLINEAR16, 0);
	ast_format_set(&lin16tospeexwb.dst_format, AST_FORMAT_SPEEX16, 0);

	ast_format_set(&speexuwbtolin32.src_format, AST_FORMAT_SPEEX32, 0);
	ast_format_set(&speexuwbtolin32.dst_format, AST_FORMAT_SLINEAR32, 0);

	ast_format_set(&lin32tospeexuwb.src_format, AST_FORMAT_SLINEAR32, 0);
	ast_format_set(&lin32tospeexuwb.dst_format, AST_FORMAT_SPEEX32, 0);

	res |= ast_register_translator(&speextolin);
	res |= ast_register_translator(&lintospeex);
	res |= ast_register_translator(&speexwbtolin16);
	res |= ast_register_translator(&lin16tospeexwb);
	res |= ast_register_translator(&speexuwbtolin32);
	res |= ast_register_translator(&lin32tospeexuwb);


	return res;
}
Пример #29
0
static int __adsi_transmit_messages(struct ast_channel *chan, unsigned char **msg, int *msglen, int *msgtype)
{
	/* msglen must be no more than 256 bits, each */
	unsigned char buf[24000 * 5];
	int pos = 0, res, x, start = 0, retries = 0, waittime, rem = 0, def;
	char ack[3];
	struct ast_frame *f;

	if (ast_channel_adsicpe(chan) == AST_ADSI_UNAVAILABLE) {
		/* Don't bother if we know they don't support ADSI */
		errno = ENOSYS;
		return -1;
	}

	while (retries < maxretries) {
		struct ast_format tmpfmt;
		if (!(ast_channel_adsicpe(chan) & ADSI_FLAG_DATAMODE)) {
			/* Generate CAS (no SAS) */
			ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0);
			ast_gen_cas(buf, 0, 680, &tmpfmt);

			/* Send CAS */
			if (adsi_careful_send(chan, buf, 680, NULL)) {
				ast_log(LOG_WARNING, "Unable to send CAS\n");
			}

			/* Wait For DTMF result */
			waittime = 500;
			for (;;) {
				if (((res = ast_waitfor(chan, waittime)) < 1)) {
					/* Didn't get back DTMF A in time */
					ast_debug(1, "No ADSI CPE detected (%d)\n", res);
					if (!ast_channel_adsicpe(chan)) {
						ast_channel_adsicpe_set(chan, AST_ADSI_UNAVAILABLE);
					}
					errno = ENOSYS;
					return -1;
				}
				waittime = res;
				if (!(f = ast_read(chan))) {
					ast_debug(1, "Hangup in ADSI\n");
					return -1;
				}
				if (f->frametype == AST_FRAME_DTMF) {
					if (f->subclass.integer == 'A') {
						/* Okay, this is an ADSI CPE.  Note this for future reference, too */
						if (!ast_channel_adsicpe(chan)) {
							ast_channel_adsicpe_set(chan, AST_ADSI_AVAILABLE);
						}
						break;
					} else {
						if (f->subclass.integer == 'D') {
							ast_debug(1, "Off-hook capable CPE only, not ADSI\n");
						} else {
							ast_log(LOG_WARNING, "Unknown ADSI response '%c'\n", f->subclass.integer);
						}
						if (!ast_channel_adsicpe(chan)) {
							ast_channel_adsicpe_set(chan, AST_ADSI_UNAVAILABLE);
						}
						errno =	ENOSYS;
						ast_frfree(f);
						return -1;
					}
				}
				ast_frfree(f);
			}

			ast_debug(1, "ADSI Compatible CPE Detected\n");
		} else {
			ast_debug(1, "Already in data mode\n");
		}

		x = 0;
		pos = 0;
#if 1
		def= ast_channel_defer_dtmf(chan);
#endif
		while ((x < 6) && msg[x]) {
			if ((res = adsi_generate(buf + pos, msgtype[x], msg[x], msglen[x], x+1 - start, (x == 5) || !msg[x+1], ast_format_set(&tmpfmt, AST_FORMAT_ULAW,0))) < 0) {
				ast_log(LOG_WARNING, "Failed to generate ADSI message %d on channel %s\n", x + 1, ast_channel_name(chan));
				return -1;
			}
			ast_debug(1, "Message %d, of %d input bytes, %d output bytes\n", x + 1, msglen[x], res);
			pos += res;
			x++;
		}


		rem = 0;
		res = adsi_careful_send(chan, buf, pos, &rem);
		if (!def) {
			ast_channel_undefer_dtmf(chan);
		}
		if (res) {
			return -1;
		}

		ast_debug(1, "Sent total spill of %d bytes\n", pos);

		memset(ack, 0, sizeof(ack));
		/* Get real result and check for hangup */
		if ((res = ast_readstring(chan, ack, 2, 1000, 1000, "")) < 0) {
			return -1;
		}
		if (ack[0] == 'D') {
			ast_debug(1, "Acked up to message %d\n", atoi(ack + 1)); start += atoi(ack + 1);
			if (start >= x) {
				break;
			} else {
				retries++;
				ast_debug(1, "Retransmitting (%d), from %d\n", retries, start + 1);
			}
		} else {
			retries++;
			ast_log(LOG_WARNING, "Unexpected response to ack: %s (retry %d)\n", ack, retries);
		}
	}
	if (retries >= maxretries) {
		ast_log(LOG_WARNING, "Maximum ADSI Retries (%d) exceeded\n", maxretries);
		errno = ETIMEDOUT;
		return -1;
	}
	return 0;
}
Пример #30
0
struct ast_format *ast_format_from_old_bitfield(struct ast_format *dst, uint64_t src)
{
	switch (src) {
	/*! G.723.1 compression */
	case (1ULL << 0):
		return ast_format_set(dst, AST_FORMAT_G723_1, 0);
	/*! GSM compression */
	case (1ULL << 1):
		return ast_format_set(dst, AST_FORMAT_GSM, 0);
	/*! Raw mu-law data (G.711) */
	case (1ULL << 2):
		return ast_format_set(dst, AST_FORMAT_ULAW, 0);
	/*! Raw A-law data (G.711) */
	case (1ULL << 3):
		return ast_format_set(dst, AST_FORMAT_ALAW, 0);
	/*! ADPCM (G.726, 32kbps, AAL2 codeword packing) */
	case (1ULL << 4):
		return ast_format_set(dst, AST_FORMAT_G726_AAL2, 0);
	/*! ADPCM (IMA) */
	case (1ULL << 5):
		return ast_format_set(dst, AST_FORMAT_ADPCM, 0);
	/*! Raw 16-bit Signed Linear (8000 Hz) PCM */
	case (1ULL << 6):
		return ast_format_set(dst, AST_FORMAT_SLINEAR, 0);
	/*! LPC10, 180 samples/frame */
	case (1ULL << 7):
		return ast_format_set(dst, AST_FORMAT_LPC10, 0);
	/*! G.729A audio */
	case (1ULL << 8):
		return ast_format_set(dst, AST_FORMAT_G729A, 0);
	/*! SpeeX Free Compression */
	case (1ULL << 9):
		return ast_format_set(dst, AST_FORMAT_SPEEX, 0);
	/*! iLBC Free Compression */
	case (1ULL << 10):
		return ast_format_set(dst, AST_FORMAT_ILBC, 0);
	/*! ADPCM (G.726, 32kbps, RFC3551 codeword packing) */
	case (1ULL << 11):
		return ast_format_set(dst, AST_FORMAT_G726, 0);
	/*! G.722 */
	case (1ULL << 12):
		return ast_format_set(dst, AST_FORMAT_G722, 0);
	/*! G.722.1 (also known as Siren7, 32kbps assumed) */
	case (1ULL << 13):
		return ast_format_set(dst, AST_FORMAT_SIREN7, 0);
	/*! G.722.1 Annex C (also known as Siren14, 48kbps assumed) */
	case (1ULL << 14):
		return ast_format_set(dst, AST_FORMAT_SIREN14, 0);
	/*! Raw 16-bit Signed Linear (16000 Hz) PCM */
	case (1ULL << 15):
		return ast_format_set(dst, AST_FORMAT_SLINEAR16, 0);
	/*! G.719 (64 kbps assumed) */
	case (1ULL << 32):
		return ast_format_set(dst, AST_FORMAT_G719, 0);
	/*! SpeeX Wideband (16kHz) Free Compression */
	case (1ULL << 33):
		return ast_format_set(dst, AST_FORMAT_SPEEX16, 0);
	/*! Raw mu-law data (G.711) */
	case (1ULL << 47):
		return ast_format_set(dst, AST_FORMAT_TESTLAW, 0);

	/*! H.261 Video */
	case (1ULL << 18):
		return ast_format_set(dst, AST_FORMAT_H261, 0);
	/*! H.263 Video */
	case (1ULL << 19):
		return ast_format_set(dst, AST_FORMAT_H263, 0);
	/*! H.263+ Video */
	case (1ULL << 20):
		return ast_format_set(dst, AST_FORMAT_H263_PLUS, 0);
	/*! H.264 Video */
	case (1ULL << 21):
		return ast_format_set(dst, AST_FORMAT_H264, 0);
	/*! MPEG4 Video */
	case (1ULL << 22):
		return ast_format_set(dst, AST_FORMAT_MP4_VIDEO, 0);

	/*! JPEG Images */
	case (1ULL << 16):
		return ast_format_set(dst, AST_FORMAT_JPEG, 0);
	/*! PNG Images */
	case (1ULL << 17):
		return ast_format_set(dst, AST_FORMAT_PNG, 0);

	/*! T.140 RED Text format RFC 4103 */
	case (1ULL << 26):
		return ast_format_set(dst, AST_FORMAT_T140RED, 0);
	/*! T.140 Text format - ITU T.140, RFC 4103 */
	case (1ULL << 27):
		return ast_format_set(dst, AST_FORMAT_T140, 0);
	}
	ast_format_clear(dst);
	return NULL;
}