freetdm: Add initial testing support for unrestricted digital calls using G722 codec
This commit is contained in:
parent
b073d1a396
commit
e544e4cff1
|
@ -294,10 +294,7 @@ static void cycle_foreground(ftdm_channel_t *ftdmchan, int flash, const char *bc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session, ftdm_channel_t *ftdmchan, ftdm_caller_data_t *caller_data)
|
||||||
|
|
||||||
|
|
||||||
static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session, ftdm_channel_t *ftdmchan)
|
|
||||||
{
|
{
|
||||||
const char *dname = NULL;
|
const char *dname = NULL;
|
||||||
uint32_t interval = 0, srate = 8000;
|
uint32_t interval = 0, srate = 8000;
|
||||||
|
@ -321,6 +318,14 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
|
||||||
return SWITCH_STATUS_GENERR;
|
return SWITCH_STATUS_GENERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Initializing digital call.\n");
|
||||||
|
/* temporary hack, this will be configurable */
|
||||||
|
dname = "G722";
|
||||||
|
srate = 16000;
|
||||||
|
goto init_codecs;
|
||||||
|
}
|
||||||
|
|
||||||
if (FTDM_SUCCESS != ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CODEC, &codec)) {
|
if (FTDM_SUCCESS != ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CODEC, &codec)) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel codec.\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel codec.\n");
|
||||||
return SWITCH_STATUS_GENERR;
|
return SWITCH_STATUS_GENERR;
|
||||||
|
@ -349,6 +354,7 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_codecs:
|
||||||
|
|
||||||
if (switch_core_codec_init(&tech_pvt->read_codec,
|
if (switch_core_codec_init(&tech_pvt->read_codec,
|
||||||
dname,
|
dname,
|
||||||
|
@ -1093,7 +1099,7 @@ static ftdm_status_t on_channel_found(ftdm_channel_t *fchan, ftdm_caller_data_t
|
||||||
span_id = ftdm_channel_get_span_id(fchan);
|
span_id = ftdm_channel_get_span_id(fchan);
|
||||||
chan_id = ftdm_channel_get_id(fchan);
|
chan_id = ftdm_channel_get_id(fchan);
|
||||||
|
|
||||||
tech_init(hdata->tech_pvt, hdata->new_session, fchan);
|
tech_init(hdata->tech_pvt, hdata->new_session, fchan, caller_data);
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", span_id, chan_id, caller_data->dnis.digits);
|
snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", span_id, chan_id, caller_data->dnis.digits);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name);
|
||||||
|
@ -1542,7 +1548,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
|
||||||
tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t));
|
tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t));
|
||||||
assert(tech_pvt != NULL);
|
assert(tech_pvt != NULL);
|
||||||
channel = switch_core_session_get_channel(session);
|
channel = switch_core_session_get_channel(session);
|
||||||
if (tech_init(tech_pvt, session, sigmsg->channel) != SWITCH_STATUS_SUCCESS) {
|
if (tech_init(tech_pvt, session, sigmsg->channel, channel_caller_data) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n");
|
||||||
switch_core_session_destroy(&session);
|
switch_core_session_destroy(&session);
|
||||||
return FTDM_FAIL;
|
return FTDM_FAIL;
|
||||||
|
|
|
@ -508,13 +508,16 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_caller_data(ftdm_channel_t *ftdmchan,
|
||||||
{
|
{
|
||||||
ftdm_status_t err = FTDM_SUCCESS;
|
ftdm_status_t err = FTDM_SUCCESS;
|
||||||
if (!ftdmchan) {
|
if (!ftdmchan) {
|
||||||
ftdm_log(FTDM_LOG_CRIT, "Error: trying to set caller data, but no ftdmchan!\n");
|
ftdm_log(FTDM_LOG_CRIT, "trying to set caller data, but no ftdmchan!\n");
|
||||||
return FTDM_FAIL;
|
return FTDM_FAIL;
|
||||||
}
|
}
|
||||||
if ((err = ftdm_set_caller_data(ftdmchan->span, caller_data)) != FTDM_SUCCESS) {
|
if ((err = ftdm_set_caller_data(ftdmchan->span, caller_data)) != FTDM_SUCCESS) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
ftdmchan->caller_data = *caller_data;
|
ftdmchan->caller_data = *caller_data;
|
||||||
|
if (ftdmchan->caller_data.bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) {
|
||||||
|
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA);
|
||||||
|
}
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2628,6 +2631,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
||||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
|
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
|
||||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_ANSWERED);
|
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_ANSWERED);
|
||||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_USER_HANGUP);
|
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_USER_HANGUP);
|
||||||
|
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA);
|
||||||
ftdm_mutex_lock(ftdmchan->pre_buffer_mutex);
|
ftdm_mutex_lock(ftdmchan->pre_buffer_mutex);
|
||||||
ftdm_buffer_destroy(&ftdmchan->pre_buffer);
|
ftdm_buffer_destroy(&ftdmchan->pre_buffer);
|
||||||
ftdmchan->pre_buffer_size = 0;
|
ftdmchan->pre_buffer_size = 0;
|
||||||
|
@ -3780,6 +3784,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data
|
||||||
|
|
||||||
handle_tone_generation(ftdmchan);
|
handle_tone_generation(ftdmchan);
|
||||||
|
|
||||||
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) {
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) {
|
||||||
if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) {
|
if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) {
|
||||||
codec_func = fio_ulaw2slin;
|
codec_func = fio_ulaw2slin;
|
||||||
|
@ -3994,6 +4002,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat
|
||||||
status = FTDM_FAIL;
|
status = FTDM_FAIL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA)) {
|
||||||
|
goto do_write;
|
||||||
|
}
|
||||||
|
|
||||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) {
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) {
|
||||||
if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) {
|
if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) {
|
||||||
|
@ -4025,6 +4037,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_write:
|
||||||
|
|
||||||
if (ftdmchan->span->sig_write) {
|
if (ftdmchan->span->sig_write) {
|
||||||
status = ftdmchan->span->sig_write(ftdmchan, data, *datalen);
|
status = ftdmchan->span->sig_write(ftdmchan, data, *datalen);
|
||||||
if (status == FTDM_BREAK) {
|
if (status == FTDM_BREAK) {
|
||||||
|
@ -5374,10 +5388,12 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
||||||
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED);
|
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED);
|
||||||
ftdm_call_set_call_id(sigmsg->channel, &sigmsg->channel->caller_data);
|
ftdm_call_set_call_id(sigmsg->channel, &sigmsg->channel->caller_data);
|
||||||
/* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was
|
/* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was
|
||||||
* doing it during SIGEVENT_START, but now that flags are private they can't, wonder if
|
* doing it during SIGEVENT_START, but now that flags are private they can't, wonder if
|
||||||
* is needed at all?
|
* is needed at all? */
|
||||||
* */
|
|
||||||
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD);
|
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD);
|
||||||
|
if (sigmsg->channel->caller_data.bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) {
|
||||||
|
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_DIGITAL_MEDIA);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -249,6 +249,8 @@ typedef enum {
|
||||||
#define FTDM_CHANNEL_IND_ACK_PENDING (1ULL << 34)
|
#define FTDM_CHANNEL_IND_ACK_PENDING (1ULL << 34)
|
||||||
/*!< There is someone blocking in the channel waiting for state completion */
|
/*!< There is someone blocking in the channel waiting for state completion */
|
||||||
#define FTDM_CHANNEL_BLOCKING (1ULL << 35)
|
#define FTDM_CHANNEL_BLOCKING (1ULL << 35)
|
||||||
|
/*!< Media is digital */
|
||||||
|
#define FTDM_CHANNEL_DIGITAL_MEDIA (1ULL << 36)
|
||||||
|
|
||||||
#include "ftdm_state.h"
|
#include "ftdm_state.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue