Merge branch 'master' into FS-4558
This commit is contained in:
commit
bf4bb0028e
|
@ -590,7 +590,7 @@
|
|||
<prompt phrase="...is already on the blacklist." filename="ivr-is_already_on_the_blacklist.wav"/>
|
||||
<prompt phrase="For other options, press..." filename="ivr-for_other_options.wav"/>
|
||||
<!-- The following phrases still need to be recorded -->
|
||||
<prompt phrase="" filename=""/>
|
||||
<prompt phrase="Thank you." filename="ivr-thank_you.wav"/>
|
||||
<prompt phrase="" filename=""/>
|
||||
|
||||
</ivr>
|
||||
|
|
|
@ -201,7 +201,7 @@ int lpwrap_start_timer(struct lpwrap_pri *spri, struct lpwrap_timer *timer, cons
|
|||
ftdm_mutex_lock(spri->timer_mutex);
|
||||
|
||||
for (prev = &spri->timer_list, cur = spri->timer_list; cur; prev = &(*prev)->next, cur = cur->next) {
|
||||
if (cur->timeout < timer->timeout) {
|
||||
if (cur->timeout > timer->timeout) {
|
||||
*prev = timer;
|
||||
timer->next = cur;
|
||||
break;
|
||||
|
@ -238,6 +238,10 @@ int lpwrap_stop_timer(struct lpwrap_pri *spri, struct lpwrap_timer *timer)
|
|||
|
||||
ftdm_mutex_unlock(spri->timer_mutex);
|
||||
|
||||
if (!cur) {
|
||||
ftdm_log_chan(spri->dchan, FTDM_LOG_WARNING, "-- Timer %p not found in list\n", timer);
|
||||
}
|
||||
|
||||
timer->next = NULL;
|
||||
timer->timeout = 0;
|
||||
timer->callback = NULL;
|
||||
|
|
|
@ -1689,6 +1689,16 @@ static int restart_modem(t31_state_t *s, int new_modem)
|
|||
}
|
||||
s->at_state.transmit = TRUE;
|
||||
break;
|
||||
case FAX_MODEM_V21_RX:
|
||||
if (s->t38_mode)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
t31_v21_rx(s);
|
||||
fax_modems_set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &t->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
|
||||
}
|
||||
break;
|
||||
case FAX_MODEM_V21_TX:
|
||||
if (s->t38_mode)
|
||||
{
|
||||
|
@ -1712,15 +1722,16 @@ static int restart_modem(t31_state_t *s, int new_modem)
|
|||
s->dled = FALSE;
|
||||
s->at_state.transmit = TRUE;
|
||||
break;
|
||||
case FAX_MODEM_V21_RX:
|
||||
if (s->t38_mode)
|
||||
{
|
||||
}
|
||||
else
|
||||
case FAX_MODEM_V17_RX:
|
||||
case FAX_MODEM_V27TER_RX:
|
||||
case FAX_MODEM_V29_RX:
|
||||
if (!s->t38_mode)
|
||||
{
|
||||
fax_modems_start_fast_modem(t, s->modem, s->bit_rate, s->short_train, use_hdlc);
|
||||
/* Allow for +FCERROR/+FRH:3 */
|
||||
t31_v21_rx(s);
|
||||
fax_modems_set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &t->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
|
||||
}
|
||||
s->at_state.transmit = FALSE;
|
||||
break;
|
||||
case FAX_MODEM_V17_TX:
|
||||
if (s->t38_mode)
|
||||
|
@ -1755,17 +1766,6 @@ static int restart_modem(t31_state_t *s, int new_modem)
|
|||
s->tx.data_started = FALSE;
|
||||
s->at_state.transmit = TRUE;
|
||||
break;
|
||||
case FAX_MODEM_V17_RX:
|
||||
case FAX_MODEM_V27TER_RX:
|
||||
case FAX_MODEM_V29_RX:
|
||||
if (!s->t38_mode)
|
||||
{
|
||||
fax_modems_start_fast_modem(t, s->modem, s->bit_rate, s->short_train, use_hdlc);
|
||||
/* Allow for +FCERROR/+FRH:3 */
|
||||
t31_v21_rx(s);
|
||||
}
|
||||
s->at_state.transmit = FALSE;
|
||||
break;
|
||||
case FAX_MODEM_V27TER_TX:
|
||||
if (s->t38_mode)
|
||||
{
|
||||
|
|
|
@ -172,7 +172,7 @@ static int set_tiff_directory_info(t4_rx_state_t *s)
|
|||
}
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
TIFFSetField(t->tiff_file, TIFFTAG_PROFILETYPE, PROFILETYPE_G3_FAX);
|
||||
TIFFSetField(t->tiff_file, TIFFTAG_FAXPROFILE, FAXPROFILE_S);
|
||||
TIFFSetField(t->tiff_file, TIFFTAG_FAXPROFILE, FAXPROFILE_F);
|
||||
TIFFSetField(t->tiff_file, TIFFTAG_CODINGMETHODS, CODINGMETHODS_T4_1D | CODINGMETHODS_T4_2D | CODINGMETHODS_T6);
|
||||
TIFFSetField(t->tiff_file, TIFFTAG_VERSIONYEAR, "1998");
|
||||
/* TIFFSetField(t->tiff_file, TIFFTAG_MODENUMBER, 0); */
|
||||
|
@ -304,10 +304,14 @@ static int write_tiff_image(t4_rx_state_t *s)
|
|||
return -1;
|
||||
/* Set up the TIFF directory info... */
|
||||
set_tiff_directory_info(s);
|
||||
/* ...and then write the image... */
|
||||
/* ...Put the directory in the file before the image data, to get them in the order specified
|
||||
for TIFF/F files... */
|
||||
if (!TIFFCheckpointDirectory(t->tiff_file))
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to checkpoint directory for page %d.\n", t->file, s->current_page);
|
||||
/* ...and write out the image... */
|
||||
if (TIFFWriteEncodedStrip(t->tiff_file, 0, t->image_buffer, t->image_size) < 0)
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", t->file);
|
||||
/* ...then the directory entry, and libtiff is happy. */
|
||||
/* ...then finalise the directory entry, and libtiff is happy. */
|
||||
if (!TIFFWriteDirectory(t->tiff_file))
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to write directory for page %d.\n", t->file, s->current_page);
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
|
@ -316,7 +320,7 @@ static int write_tiff_image(t4_rx_state_t *s)
|
|||
if (!TIFFCreateCustomDirectory(t->tiff_file, &tiff_fx_field_array))
|
||||
{
|
||||
TIFFSetField(t->tiff_file, TIFFTAG_FAXPROFILE, PROFILETYPE_G3_FAX);
|
||||
TIFFSetField(t->tiff_file, TIFFTAG_PROFILETYPE, FAXPROFILE_S);
|
||||
TIFFSetField(t->tiff_file, TIFFTAG_PROFILETYPE, FAXPROFILE_F);
|
||||
TIFFSetField(t->tiff_file, TIFFTAG_VERSIONYEAR, "1998");
|
||||
|
||||
offset = 0;
|
||||
|
|
|
@ -623,6 +623,10 @@ int main(int argc, char *argv[])
|
|||
tm->tm_sec);
|
||||
TIFFSetField(tiff_file, TIFFTAG_DATETIME, buf);
|
||||
image_length = sequence[i].length;
|
||||
TIFFSetField(tiff_file, TIFFTAG_PAGENUMBER, 0, 1);
|
||||
TIFFSetField(tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_CLEAN);
|
||||
TIFFSetField(tiff_file, TIFFTAG_IMAGELENGTH, image_length);
|
||||
TIFFCheckpointDirectory(tiff_file);
|
||||
|
||||
/* Write the image first.... */
|
||||
switch (sequence[i].type)
|
||||
|
@ -662,8 +666,6 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
/* ....then the directory entry, and libtiff is happy. */
|
||||
TIFFSetField(tiff_file, TIFFTAG_IMAGELENGTH, image_length);
|
||||
TIFFSetField(tiff_file, TIFFTAG_PAGENUMBER, 0, 1);
|
||||
TIFFSetField(tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_CLEAN);
|
||||
|
||||
TIFFWriteDirectory(tiff_file);
|
||||
}
|
||||
|
|
|
@ -137,6 +137,7 @@ int main(int argc, char *argv[])
|
|||
TIFFSetField(tiff_file, TIFFTAG_PAGENUMBER, 0, 1);
|
||||
TIFFSetField(tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_CLEAN);
|
||||
TIFFSetField(tiff_file, TIFFTAG_IMAGEWIDTH, image_width);
|
||||
TIFFCheckpointDirectory(tiff_file);
|
||||
|
||||
/* Write the image first.... */
|
||||
for (row = 0; row < image_length; row++)
|
||||
|
|
|
@ -367,6 +367,7 @@ int main(int argc, char *argv[])
|
|||
TIFFSetField(tiff_file, TIFFTAG_PAGENUMBER, 0, 1);
|
||||
TIFFSetField(tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_CLEAN);
|
||||
TIFFSetField(tiff_file, TIFFTAG_IMAGEWIDTH, sequence[i].width);
|
||||
TIFFCheckpointDirectory(tiff_file);
|
||||
|
||||
/* Write the image first.... */
|
||||
for (row = 0; row < sequence[i].length; row++)
|
||||
|
|
|
@ -103,6 +103,7 @@ int main(int argc, char *argv[])
|
|||
TIFFSetField(tiff_file, TIFFTAG_IMAGEWIDTH, IMAGE_WIDTH);
|
||||
TIFFSetField(tiff_file, TIFFTAG_IMAGELENGTH, IMAGE_LENGTH);
|
||||
TIFFSetField(tiff_file, TIFFTAG_PAGENUMBER, 0, 1);
|
||||
TIFFCheckpointDirectory(tiff_file);
|
||||
|
||||
image_size = IMAGE_WIDTH*ROWS_PER_STRIPE/8;
|
||||
memset(image_buffer, 0x18, image_size);
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "spandsp.h"
|
||||
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
//#include <tif_dir.h>
|
||||
#include <tif_dir.h>
|
||||
#endif
|
||||
|
||||
//#define IN_FILE_NAME "../test-data/itu/t24/F21_200.TIF"
|
||||
|
@ -156,7 +156,9 @@ int main(int argc, char *argv[])
|
|||
|
||||
logging = span_log_init(NULL, SPAN_LOG_FLOW, "T.42");
|
||||
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
TIFF_FX_init();
|
||||
#endif
|
||||
|
||||
set_lab_illuminant(&lab_param, 0.9638f, 1.0f, 0.8245f);
|
||||
set_lab_gamut(&lab_param, 0, 100, -85, 85, -75, 125, FALSE);
|
||||
|
@ -189,7 +191,7 @@ int main(int argc, char *argv[])
|
|||
YCbCrSubsampleHoriz = 0;
|
||||
YCbCrSubsampleVert = 0;
|
||||
TIFFGetField(tif, TIFFTAG_YCBCRSUBSAMPLING, &YCbCrSubsampleHoriz, &YCbCrSubsampleVert);
|
||||
planar_config = 0;
|
||||
planar_config = PLANARCONFIG_CONTIG;
|
||||
TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planar_config);
|
||||
off = 0;
|
||||
|
||||
|
|
|
@ -642,6 +642,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_api_on(switch_channel_t *channel,
|
|||
SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_queued_extension(switch_channel_t *channel);
|
||||
SWITCH_DECLARE(void) switch_channel_transfer_to_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension);
|
||||
SWITCH_DECLARE(const char *) switch_channel_get_partner_uuid(switch_channel_t *channel);
|
||||
SWITCH_DECLARE(switch_hold_record_t *) switch_channel_get_hold_record(switch_channel_t *channel);
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,16 @@ struct switch_app_log {
|
|||
struct switch_app_log *next;
|
||||
};
|
||||
|
||||
|
||||
typedef struct switch_hold_record_s {
|
||||
switch_time_t on;
|
||||
switch_time_t off;
|
||||
char *uuid;
|
||||
struct switch_hold_record_s *next;
|
||||
} switch_hold_record_t;
|
||||
|
||||
|
||||
|
||||
#define MESSAGE_STAMP_FFL(_m) _m->_file = __FILE__; _m->_func = __SWITCH_FUNC__; _m->_line = __LINE__
|
||||
|
||||
#define MESSAGE_STRING_ARG_MAX 10
|
||||
|
|
|
@ -906,6 +906,7 @@ typedef enum {
|
|||
SWITCH_MESSAGE_INDICATE_AUDIO_DATA,
|
||||
SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE,
|
||||
SWITCH_MESSAGE_INDICATE_STUN_ERROR,
|
||||
SWITCH_MESSAGE_INDICATE_MEDIA_RENEG,
|
||||
SWITCH_MESSAGE_INVALID
|
||||
} switch_core_session_message_types_t;
|
||||
|
||||
|
|
|
@ -2739,6 +2739,49 @@ SWITCH_STANDARD_API(uuid_media_function)
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define MEDIA_RENEG_SYNTAX "<uuid>[ <codec_string>]"
|
||||
SWITCH_STANDARD_API(uuid_media_neg_function)
|
||||
{
|
||||
char *mycmd = NULL, *argv[2] = { 0 };
|
||||
int argc = 0;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
if (!zstr(cmd) && (mycmd = strdup(cmd))) {
|
||||
argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
}
|
||||
|
||||
if (zstr(cmd) || argc < 1 || zstr(argv[0])) {
|
||||
stream->write_function(stream, "-USAGE: %s\n", MEDIA_RENEG_SYNTAX);
|
||||
} else {
|
||||
switch_core_session_message_t msg = { 0 };
|
||||
switch_core_session_t *lsession = NULL;
|
||||
char *uuid = argv[0];
|
||||
|
||||
msg.message_id = SWITCH_MESSAGE_INDICATE_MEDIA_RENEG;
|
||||
msg.string_arg = argv[1];
|
||||
msg.from = __FILE__;
|
||||
|
||||
if (*uuid == '+') {
|
||||
msg.numeric_arg++;
|
||||
uuid++;
|
||||
}
|
||||
|
||||
if ((lsession = switch_core_session_locate(uuid))) {
|
||||
status = switch_core_session_receive_message(lsession, &msg);
|
||||
switch_core_session_rwunlock(lsession);
|
||||
}
|
||||
}
|
||||
|
||||
if (status == SWITCH_STATUS_SUCCESS) {
|
||||
stream->write_function(stream, "+OK Success\n");
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR Operation Failed\n");
|
||||
}
|
||||
|
||||
switch_safe_free(mycmd);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(uuid_early_ok_function)
|
||||
{
|
||||
char *uuid = (char *) cmd;
|
||||
|
@ -5690,6 +5733,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
|||
SWITCH_ADD_API(commands_api_interface, "uuid_limit_release", "Release limit resource", uuid_limit_release_function, LIMIT_RELEASE_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_loglevel", "set loglevel on session", uuid_loglevel, UUID_LOGLEVEL_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_media", "media", uuid_media_function, MEDIA_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_media_reneg", "media negotiation", uuid_media_neg_function, MEDIA_RENEG_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_park", "Park Channel", park_function, PARK_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_phone_event", "Send and event to the phone", uuid_phone_event_function, PHONE_EVENT_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_pre_answer", "pre_answer", uuid_pre_answer_function, "<uuid>");
|
||||
|
@ -5841,6 +5885,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
|||
switch_console_set_complete("add uuid_media ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_media off ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_park ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_media_reneg ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_phone_event ::console::list_uuid talk");
|
||||
switch_console_set_complete("add uuid_phone_event ::console::list_uuid hold");
|
||||
switch_console_set_complete("add uuid_preprocess ::console::list_uuid");
|
||||
|
|
|
@ -1547,6 +1547,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
|||
case SWITCH_MESSAGE_INDICATE_RECOVERY_REFRESH:
|
||||
case SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC:
|
||||
break;
|
||||
|
||||
case SWITCH_MESSAGE_INDICATE_PROXY_MEDIA:
|
||||
{
|
||||
if (switch_rtp_ready(tech_pvt->rtp_session)) {
|
||||
|
@ -1849,6 +1850,43 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
|||
}
|
||||
|
||||
switch (msg->message_id) {
|
||||
|
||||
case SWITCH_MESSAGE_INDICATE_MEDIA_RENEG:
|
||||
{
|
||||
switch_core_session_t *nsession;
|
||||
|
||||
if (msg->string_arg) {
|
||||
switch_channel_set_variable(channel, "absolute_codec_string", NULL);
|
||||
if (*msg->string_arg == '=') {
|
||||
switch_channel_set_variable(channel, "codec_string", msg->string_arg);
|
||||
} else {
|
||||
switch_channel_set_variable_printf(channel, "codec_string", "=%s%s%s,%s",
|
||||
tech_pvt->video_rm_encoding ? tech_pvt->video_rm_encoding : "",
|
||||
tech_pvt->video_rm_encoding ? "," : "",
|
||||
tech_pvt->rm_encoding, msg->string_arg);
|
||||
}
|
||||
|
||||
|
||||
tech_pvt->num_codecs = 0;
|
||||
tech_pvt->rm_encoding = NULL;
|
||||
tech_pvt->video_rm_encoding = NULL;
|
||||
sofia_clear_flag_locked(tech_pvt, TFLAG_VIDEO);
|
||||
sofia_glue_tech_prepare_codecs(tech_pvt);
|
||||
sofia_glue_check_video_codecs(tech_pvt);
|
||||
sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 1);
|
||||
sofia_set_pflag(tech_pvt->profile, PFLAG_RENEG_ON_REINVITE);
|
||||
}
|
||||
|
||||
sofia_glue_do_invite(session);
|
||||
|
||||
if (msg->numeric_arg && switch_core_session_get_partner(session, &nsession) == SWITCH_STATUS_SUCCESS) {
|
||||
msg->numeric_arg = 0;
|
||||
switch_core_session_receive_message(nsession, msg);
|
||||
switch_core_session_rwunlock(nsession);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ:
|
||||
{
|
||||
const char *pl = "<media_control><vc_primitive><to_encoder><picture_fast_update/></to_encoder></vc_primitive></media_control>";
|
||||
|
|
|
@ -1209,11 +1209,13 @@ static void our_sofia_event_callback(nua_event_t event,
|
|||
sofia_handle_sip_i_options(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
|
||||
break;
|
||||
case nua_i_invite:
|
||||
if (session && sofia_private->is_call > 1) {
|
||||
sofia_handle_sip_i_reinvite(session, nua, profile, nh, sofia_private, sip, de, tags);
|
||||
} else {
|
||||
sofia_private->is_call++;
|
||||
sofia_handle_sip_i_invite(session, nua, profile, nh, sofia_private, sip, de, tags);
|
||||
if (session && sofia_private) {
|
||||
if (sofia_private->is_call > 1) {
|
||||
sofia_handle_sip_i_reinvite(session, nua, profile, nh, sofia_private, sip, de, tags);
|
||||
} else {
|
||||
sofia_private->is_call++;
|
||||
sofia_handle_sip_i_invite(session, nua, profile, nh, sofia_private, sip, de, tags);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case nua_i_publish:
|
||||
|
@ -1688,6 +1690,14 @@ static void sofia_queue_message(sofia_dispatch_event_t *de)
|
|||
switch_queue_push(mod_sofia_globals.msg_queue, de);
|
||||
}
|
||||
|
||||
static void set_call_id(private_object_t *tech_pvt, sip_t const *sip)
|
||||
{
|
||||
if (!tech_pvt->call_id && tech_pvt->session && tech_pvt->channel && sip && sip->sip_call_id && sip->sip_call_id->i_id) {
|
||||
tech_pvt->call_id = switch_core_session_strdup(tech_pvt->session, sip->sip_call_id->i_id);
|
||||
switch_channel_set_variable(tech_pvt->channel, "sip_call_id", tech_pvt->call_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sofia_event_callback(nua_event_t event,
|
||||
int status,
|
||||
|
@ -1707,16 +1717,22 @@ void sofia_event_callback(nua_event_t event,
|
|||
|
||||
if ((session = switch_core_session_locate(sofia_private->uuid))) {
|
||||
private_object_t *tech_pvt = switch_core_session_get_private(session);
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "detaching session %s\n", sofia_private->uuid);
|
||||
|
||||
tech_pvt->sofia_private = NULL;
|
||||
tech_pvt->nh = NULL;
|
||||
sofia_set_flag(tech_pvt, TFLAG_BYE);
|
||||
switch_mutex_lock(profile->flag_mutex);
|
||||
switch_core_hash_insert(profile->chat_hash, tech_pvt->call_id, strdup(switch_core_session_get_uuid(session)));
|
||||
switch_mutex_unlock(profile->flag_mutex);
|
||||
switch_core_session_rwunlock(session);
|
||||
set_call_id(tech_pvt, sip);
|
||||
|
||||
if (!zstr(tech_pvt->call_id)) {
|
||||
tech_pvt->sofia_private = NULL;
|
||||
tech_pvt->nh = NULL;
|
||||
sofia_set_flag(tech_pvt, TFLAG_BYE);
|
||||
switch_mutex_lock(profile->flag_mutex);
|
||||
switch_core_hash_insert(profile->chat_hash, tech_pvt->call_id, strdup(switch_core_session_get_uuid(session)));
|
||||
switch_mutex_unlock(profile->flag_mutex);
|
||||
switch_core_session_rwunlock(session);
|
||||
} else {
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
}
|
||||
}
|
||||
}
|
||||
goto end;
|
||||
|
@ -1802,9 +1818,25 @@ void sofia_event_callback(nua_event_t event,
|
|||
} else {
|
||||
free(uuid);
|
||||
uuid = NULL;
|
||||
sip = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!sip || !sip->sip_call_id || zstr(sip->sip_call_id->i_id)) {
|
||||
nua_respond(nh, 503, "INVALID INVITE", TAG_END());
|
||||
nua_destroy_event(de->event);
|
||||
su_free(nh->nh_home, de);
|
||||
|
||||
switch_mutex_lock(profile->flag_mutex);
|
||||
profile->queued_events--;
|
||||
switch_mutex_unlock(profile->flag_mutex);
|
||||
|
||||
nua_handle_unref(nh);
|
||||
nua_stack_unref(nua);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (sofia_test_pflag(profile, PFLAG_CALLID_AS_UUID)) {
|
||||
session = switch_core_session_request_uuid(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL, sip->sip_call_id->i_id);
|
||||
|
@ -1827,13 +1859,8 @@ void sofia_event_callback(nua_event_t event,
|
|||
}
|
||||
|
||||
sofia_glue_attach_private(session, profile, tech_pvt, channel_name);
|
||||
|
||||
if (!tech_pvt->call_id && sip->sip_call_id && sip->sip_call_id->i_id) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
tech_pvt->call_id = switch_core_session_strdup(session, sip->sip_call_id->i_id);
|
||||
switch_channel_set_variable(channel, "sip_call_id", tech_pvt->call_id);
|
||||
}
|
||||
|
||||
set_call_id(tech_pvt, sip);
|
||||
} else {
|
||||
nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
|
||||
nua_destroy_event(de->event);
|
||||
|
|
|
@ -833,12 +833,14 @@ void sofia_glue_tech_prepare_codecs(private_object_t *tech_pvt)
|
|||
|
||||
if (!(codec_string = switch_channel_get_variable(tech_pvt->channel, "codec_string"))) {
|
||||
codec_string = sofia_glue_get_codec_string(tech_pvt);
|
||||
if (codec_string && *codec_string == '=') {
|
||||
codec_string++;
|
||||
goto ready;
|
||||
}
|
||||
}
|
||||
|
||||
if (codec_string && *codec_string == '=') {
|
||||
codec_string++;
|
||||
goto ready;
|
||||
}
|
||||
|
||||
|
||||
if ((ocodec = switch_channel_get_variable(tech_pvt->channel, SWITCH_ORIGINATOR_CODEC_VARIABLE))) {
|
||||
if (!codec_string || sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_TRANSCODING)) {
|
||||
codec_string = ocodec;
|
||||
|
@ -871,6 +873,7 @@ void sofia_glue_check_video_codecs(private_object_t *tech_pvt)
|
|||
int i;
|
||||
tech_pvt->video_count = 0;
|
||||
for (i = 0; i < tech_pvt->num_codecs; i++) {
|
||||
|
||||
if (tech_pvt->codecs[i]->codec_type == SWITCH_CODEC_TYPE_VIDEO) {
|
||||
tech_pvt->video_count++;
|
||||
}
|
||||
|
@ -5135,6 +5138,8 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
|
|||
|
||||
if (mimp) {
|
||||
char tmp[50];
|
||||
const char *mirror = switch_channel_get_variable(tech_pvt->channel, "sip_mirror_remote_audio_codec_payload");
|
||||
|
||||
tech_pvt->rm_encoding = switch_core_session_strdup(session, (char *) map->rm_encoding);
|
||||
tech_pvt->iananame = switch_core_session_strdup(session, (char *) mimp->iananame);
|
||||
tech_pvt->pt = (switch_payload_t) map->rm_pt;
|
||||
|
@ -5152,7 +5157,9 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
|
|||
switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
|
||||
tech_pvt->audio_recv_pt = (switch_payload_t)map->rm_pt;
|
||||
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
|
||||
if (!switch_true(mirror) &&
|
||||
switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND &&
|
||||
(!sofia_test_flag(tech_pvt, TFLAG_REINVITE) || sofia_test_pflag(tech_pvt->profile, PFLAG_RENEG_ON_REINVITE))) {
|
||||
sofia_glue_get_offered_pt(tech_pvt, mimp, &tech_pvt->audio_recv_pt);
|
||||
}
|
||||
|
||||
|
@ -5275,6 +5282,8 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
|
|||
if (mimp) {
|
||||
if ((tech_pvt->video_rm_encoding = switch_core_session_strdup(session, (char *) rm_encoding))) {
|
||||
char tmp[50];
|
||||
const char *mirror = switch_channel_get_variable(tech_pvt->channel, "sip_mirror_remote_video_codec_payload");
|
||||
|
||||
tech_pvt->video_pt = (switch_payload_t) map->rm_pt;
|
||||
tech_pvt->video_rm_rate = map->rm_rate;
|
||||
tech_pvt->video_codec_ms = mimp->microseconds_per_packet / 1000;
|
||||
|
@ -5292,7 +5301,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
|
|||
|
||||
tech_pvt->video_recv_pt = (switch_payload_t)map->rm_pt;
|
||||
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
if (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
sofia_glue_get_offered_pt(tech_pvt, mimp, &tech_pvt->video_recv_pt);
|
||||
}
|
||||
|
||||
|
|
|
@ -139,16 +139,13 @@ namespace FreeSWITCH.Native
|
|||
// The delegate needs to be stored so it doesn't get GC'd, so we can't just return GetFunctionPointerForDelegate right away.
|
||||
|
||||
/// <summary>Wraps a nice handler into a delegate suitable for reverse P/Invoke. This only currently works well for hangup/reporting handlers.</summary>
|
||||
public static switch_state_handler_t_delegate CreateStateHandlerDelegate(Action<ManagedSession> handler) {
|
||||
public static switch_state_handler_t_delegate CreateStateHandlerDelegate(ManagedSession sess, Action<ManagedSession> handler)
|
||||
{
|
||||
// We create a ManagedSession on top of the session so callbacks can use it "nicely"
|
||||
// Then we sort of dispose it.
|
||||
switch_state_handler_t_delegate del = ptr => {
|
||||
using (var sess = new ManagedSession(new SWIGTYPE_p_switch_core_session(ptr, false))) {
|
||||
handler(sess);
|
||||
sess.SetAutoHangup(false);
|
||||
sess.destroy();
|
||||
return switch_status_t.SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
};
|
||||
return del;
|
||||
}
|
||||
|
@ -187,7 +184,7 @@ namespace FreeSWITCH.Native
|
|||
var bleg = new ManagedSession();
|
||||
|
||||
bleg.originate_ondestroy_delegate = bleg.originate_ondestroy_method;
|
||||
bleg.originate_onhangup_delegate = CreateStateHandlerDelegate(sess_b => {
|
||||
bleg.originate_onhangup_delegate = CreateStateHandlerDelegate(bleg, sess_b => {
|
||||
if (onHangup != null) {
|
||||
onHangup(sess_b);
|
||||
}
|
||||
|
|
|
@ -155,8 +155,13 @@ struct switch_channel {
|
|||
switch_event_t *app_list;
|
||||
switch_event_t *api_list;
|
||||
switch_event_t *var_list;
|
||||
switch_hold_record_t *hold_record;
|
||||
};
|
||||
|
||||
SWITCH_DECLARE(switch_hold_record_t *) switch_channel_get_hold_record(switch_channel_t *channel)
|
||||
{
|
||||
return channel->hold_record;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(const char *) switch_channel_cause2str(switch_call_cause_t cause)
|
||||
{
|
||||
|
@ -1611,9 +1616,24 @@ SWITCH_DECLARE(void) switch_channel_set_flag_value(switch_channel_t *channel, sw
|
|||
switch_mutex_unlock(channel->flag_mutex);
|
||||
|
||||
if (HELD) {
|
||||
switch_hold_record_t *hr;
|
||||
const char *brto = switch_channel_get_partner_uuid(channel);
|
||||
|
||||
switch_channel_set_callstate(channel, CCS_HELD);
|
||||
switch_mutex_lock(channel->profile_mutex);
|
||||
channel->caller_profile->times->last_hold = switch_time_now();
|
||||
|
||||
hr = switch_core_session_alloc(channel->session, sizeof(*hr));
|
||||
hr->on = switch_time_now();
|
||||
if (brto) {
|
||||
hr->uuid = switch_core_session_strdup(channel->session, brto);
|
||||
}
|
||||
|
||||
if (channel->hold_record) {
|
||||
hr->next = channel->hold_record;
|
||||
}
|
||||
channel->hold_record = hr;
|
||||
|
||||
switch_mutex_unlock(channel->profile_mutex);
|
||||
}
|
||||
|
||||
|
@ -1763,6 +1783,11 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch
|
|||
if (channel->caller_profile->times->last_hold) {
|
||||
channel->caller_profile->times->hold_accum += (switch_time_now() - channel->caller_profile->times->last_hold);
|
||||
}
|
||||
|
||||
if (channel->hold_record) {
|
||||
channel->hold_record->off = switch_time_now();
|
||||
}
|
||||
|
||||
switch_mutex_unlock(channel->profile_mutex);
|
||||
}
|
||||
|
||||
|
@ -2905,6 +2930,12 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_hangup(switch_chan
|
|||
switch_event_t *event;
|
||||
const char *var;
|
||||
|
||||
switch_mutex_lock(channel->profile_mutex);
|
||||
if (channel->hold_record && !channel->hold_record->off) {
|
||||
channel->hold_record->off = switch_time_now();
|
||||
}
|
||||
switch_mutex_unlock(channel->profile_mutex);
|
||||
|
||||
switch_mutex_lock(channel->state_mutex);
|
||||
last_state = channel->state;
|
||||
channel->state = CS_HANGUP;
|
||||
|
|
|
@ -631,8 +631,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se
|
|||
}
|
||||
}
|
||||
|
||||
if (!inner || switch_channel_test_flag(channel, CF_STOP_BROADCAST)) {
|
||||
switch_channel_clear_flag(channel, CF_BROADCAST);
|
||||
if (!inner) {
|
||||
switch_channel_clear_flag(channel, CF_BROADCAST);
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_STOP_BROADCAST)) {
|
||||
switch_channel_clear_flag(channel, CF_BROADCAST);
|
||||
switch_channel_set_flag(channel, CF_BREAK);
|
||||
}
|
||||
|
||||
|
@ -2191,11 +2195,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_
|
|||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_caller_profile_t *caller_profile;
|
||||
switch_xml_t variables, cdr, x_main_cp, x_caller_profile, x_caller_extension, x_times, time_tag,
|
||||
x_application, x_callflow, x_inner_extension, x_apps, x_o, x_channel_data, x_field;
|
||||
x_application, x_callflow, x_inner_extension, x_apps, x_o, x_channel_data, x_field, xhr, x_hold;
|
||||
switch_app_log_t *app_log;
|
||||
char tmp[512], *f;
|
||||
int cdr_off = 0, v_off = 0, cd_off = 0;
|
||||
|
||||
switch_hold_record_t *hold_record = switch_channel_get_hold_record(channel), *hr;
|
||||
|
||||
if (*xml_cdr) {
|
||||
cdr = *xml_cdr;
|
||||
} else {
|
||||
|
@ -2262,6 +2267,36 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_
|
|||
}
|
||||
}
|
||||
|
||||
if (hold_record) {
|
||||
int cf_off = 0;
|
||||
|
||||
if (!(xhr = switch_xml_add_child_d(cdr, "hold-record", cdr_off++))) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (hr = hold_record; hr; hr = hr->next) {
|
||||
char *t = tmp;
|
||||
if (!(x_hold = switch_xml_add_child_d(xhr, "hold", cf_off++))) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, hr->on);
|
||||
switch_xml_set_attr_d(x_hold, "on", t);
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, hr->off);
|
||||
switch_xml_set_attr_d(x_hold, "off", t);
|
||||
|
||||
if (hr->uuid) {
|
||||
switch_xml_set_attr_d(x_hold, "bridged-to", hr->uuid);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
caller_profile = switch_channel_get_caller_profile(channel);
|
||||
|
||||
|
|
|
@ -311,9 +311,18 @@ static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachin
|
|||
|
||||
for(bp = dmachine->realm->binding_list; bp; bp = bp->next) {
|
||||
if (bp->is_regex) {
|
||||
switch_status_t r_status = switch_regex_match(dmachine->digits, bp->digits);
|
||||
pmatches = 1;
|
||||
pmatches++;
|
||||
} else {
|
||||
if (!strncmp(dmachine->digits, bp->digits, strlen(dmachine->digits))) {
|
||||
pmatches++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(bp = dmachine->realm->binding_list; bp; bp = bp->next) {
|
||||
if (bp->is_regex) {
|
||||
switch_status_t r_status = switch_regex_match(dmachine->digits, bp->digits);
|
||||
|
||||
if (r_status == SWITCH_STATUS_SUCCESS) {
|
||||
if (is_timeout || (bp == dmachine->realm->binding_list && !bp->next)) {
|
||||
best = DM_MATCH_EXACT;
|
||||
|
@ -325,11 +334,7 @@ static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachin
|
|||
} else {
|
||||
int pmatch = !strncmp(dmachine->digits, bp->digits, strlen(dmachine->digits));
|
||||
|
||||
if (pmatch) {
|
||||
pmatches++;
|
||||
}
|
||||
|
||||
if (!exact_bp && pmatch && !strcmp(bp->digits, dmachine->digits)) {
|
||||
if (!exact_bp && pmatch && (pmatches == 1 || is_timeout) && !strcmp(bp->digits, dmachine->digits)) {
|
||||
best = DM_MATCH_EXACT;
|
||||
exact_bp = bp;
|
||||
if (dmachine->cur_digit_len == dmachine->max_digit_len) break;
|
||||
|
|
Loading…
Reference in New Issue