Exemplo n.º 1
0
SWITCH_DECLARE(switch_status_t) switch_core_session_send_dtmf_string(switch_core_session_t *session, const char *dtmf_string)
{
	char *p;
	switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0) };
	int sent = 0, dur;
	char *string;
	int i, argc;
	char *argv[256];
	int dur_total = 0;

	switch_assert(session != NULL);


	if (switch_channel_down(session->channel)) {
		return SWITCH_STATUS_FALSE;
	}

	if (zstr(dtmf_string)) {
		return SWITCH_STATUS_FALSE;
	}

	if (strlen(dtmf_string) > 99) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Attempt to send very large dtmf string ignored!\n");
		return SWITCH_STATUS_FALSE;
	}

	string = switch_core_session_strdup(session, dtmf_string);
	argc = switch_separate_string(string, '+', argv, (sizeof(argv) / sizeof(argv[0])));

	if (argc) {
		switch_channel_pre_answer(session->channel);
	}

	for (i = 0; i < argc; i++) {
		dtmf.duration = switch_core_default_dtmf_duration(0);
		dur = switch_core_default_dtmf_duration(0) / 8;
		if ((p = strchr(argv[i], '@'))) {
			*p++ = '\0';
			if ((dur = atoi(p)) > 50) {
				dtmf.duration = dur * 8;
			}
		}


		if (dtmf.duration > switch_core_max_dtmf_duration(0)) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n",
							  switch_channel_get_name(session->channel), dtmf.digit, dtmf.duration);
			dtmf.duration = switch_core_max_dtmf_duration(0);
		} else if (dtmf.duration < switch_core_min_dtmf_duration(0)) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n",
							  switch_channel_get_name(session->channel), dtmf.digit, dtmf.duration);
			dtmf.duration = switch_core_min_dtmf_duration(0);
		} else if (!dtmf.duration) {
			dtmf.duration = switch_core_default_dtmf_duration(0);
		}

		for (p = argv[i]; p && *p; p++) {
			if (is_dtmf(*p)) {
				dtmf.digit = *p;
				if (switch_core_session_send_dtmf(session, &dtmf) == SWITCH_STATUS_SUCCESS) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s send dtmf\ndigit=%c ms=%u samples=%u\n",
									  switch_channel_get_name(session->channel), dtmf.digit, dur, dtmf.duration);
					sent++;
					dur_total += dtmf.duration + 2000;	/* account for 250ms pause */
				}
			}
		}

		if (dur_total) {
			char tmp[32] = "";
			switch_snprintf(tmp, sizeof(tmp), "%d", dur_total / 8);
			switch_channel_set_variable(session->channel, "last_dtmf_duration", tmp);
		}

	}
	return sent ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
}
Exemplo n.º 2
0
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
{
    ftdm_wait_flag_t wflags = FTDM_READ;
    ftdm_status_t status;
    ctdm_private_t *tech_pvt;
    const char *name;
    switch_channel_t *channel;
    int chunk;
    uint32_t span_id, chan_id;
    ftdm_size_t len;
    char dtmf[128] = "";
    
    channel = switch_core_session_get_channel(session);
	assert(channel != NULL);
	
	tech_pvt = switch_core_session_get_private(session);
	assert(tech_pvt != NULL);
    
	name = switch_channel_get_name(channel);

top:
    wflags = FTDM_READ;
    chunk = ftdm_channel_get_io_interval(tech_pvt->ftdm_channel) * 2;
    status = ftdm_channel_wait(tech_pvt->ftdm_channel, &wflags, chunk);
    
    
	span_id = ftdm_channel_get_span_id(tech_pvt->ftdm_channel);
	chan_id = ftdm_channel_get_id(tech_pvt->ftdm_channel);

    if (status == FTDM_FAIL) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
        goto fail;
    }

    if (status == FTDM_TIMEOUT) {
        goto top;
    }

    if (!(wflags & FTDM_READ)) {
        goto top;
    }

    len = tech_pvt->read_frame.buflen;
    if (ftdm_channel_read(tech_pvt->ftdm_channel, tech_pvt->read_frame.data, &len) != FTDM_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
    }

    *frame = &tech_pvt->read_frame;
    tech_pvt->read_frame.datalen = (uint32_t)len;
    tech_pvt->read_frame.samples = tech_pvt->read_frame.datalen;
    tech_pvt->read_frame.codec = &tech_pvt->read_codec;

    if (ftdm_channel_get_codec(tech_pvt->ftdm_channel) == FTDM_CODEC_SLIN) {
        tech_pvt->read_frame.samples /= 2;
    }

    while (ftdm_channel_dequeue_dtmf(tech_pvt->ftdm_channel, dtmf, sizeof(dtmf))) {
        switch_dtmf_t _dtmf = { 0, switch_core_default_dtmf_duration(0) };
        char *p;
        for (p = dtmf; p && *p; p++) {
            if (is_dtmf(*p)) {
                _dtmf.digit = *p;
                ftdm_log(FTDM_LOG_DEBUG, "Queuing DTMF [%c] in channel %s device %d:%d\n", *p, name, span_id, chan_id);
                switch_channel_queue_dtmf(channel, &_dtmf);
            }
        }
    }

    return SWITCH_STATUS_SUCCESS;

fail:
    return SWITCH_STATUS_GENERR;
}