mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-24 13:12:03 +00:00
Merge branch 'master' into v1.4.beta
This commit is contained in:
@@ -11,8 +11,10 @@
|
||||
<param name="record-file-prefix" value="$${recordings_dir}/"/>
|
||||
</record>
|
||||
|
||||
<!-- domain to use in from attribute of client messages -->
|
||||
<!-- XMPP server domain -->
|
||||
<domain name="$${rayo_domain_name}" shared-secret="ClueCon">
|
||||
<!-- use this instead if you want secure XMPP client to server connections. Put .crt and .key file in freeswitch/certs -->
|
||||
<!--domain name="$${rayo_domain_name}" shared-secret="ClueCon" cert="$${base_dir}/certs/$${rayo_domain_name}.crt" key="$${base_dir}/certs/$${rayo_domain_name}.key"-->
|
||||
|
||||
<!-- Listeners for new Rayo client connections -->
|
||||
<!--listen type="c2s" port="5222" address="$${local_ip_v4}" acl="rayo-clients"/-->
|
||||
|
||||
@@ -334,12 +334,15 @@
|
||||
<macro name="voicemail_say_phone_number">
|
||||
<input pattern="^000|^$|^[Aa]non|^[Pp]rivate" break_on_match="true">
|
||||
<match>
|
||||
<!-- add 'anonymous caller' sound here -->
|
||||
<action function="play-file" data="voicemail/vm-message_from.wav"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
<action function="play-file" data="ivr/ivr-anonymous_caller.wav"/>
|
||||
<action function="execute" data="sleep(500)"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="ivr/ivr-this_is_a_call_from.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-message_from.wav"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
<action function="execute" data="sleep(500)"/>
|
||||
|
||||
@@ -154,6 +154,12 @@ App.ShowSaysRoute = Ember.Route.extend({
|
||||
}
|
||||
});
|
||||
|
||||
App.ShowNatMapsRoute = Ember.Route.extend({
|
||||
setupController: function(controller) {
|
||||
App.showNatMapsController.load();
|
||||
}
|
||||
});
|
||||
|
||||
App.ShowChatsRoute = Ember.Route.extend({
|
||||
setupController: function(controller) {
|
||||
App.showChatsController.load();
|
||||
@@ -203,6 +209,7 @@ App.Router.map(function(){
|
||||
this.route("showAliases");
|
||||
this.route("showCompletes");
|
||||
this.route("showManagements");
|
||||
this.route("showNatMaps");
|
||||
this.route("showSays");
|
||||
this.route("showChats");
|
||||
this.route("showInterfaces");
|
||||
@@ -550,6 +557,23 @@ App.showManagementsController = Ember.ArrayController.create({
|
||||
}
|
||||
});
|
||||
|
||||
App.showNatMapsController = Ember.ArrayController.create({
|
||||
content: [],
|
||||
init: function(){
|
||||
},
|
||||
load: function() {
|
||||
var me = this;
|
||||
$.getJSON("/txtapi/show?nat_map%20as%20json", function(data){
|
||||
me.set('total', data.row_count);
|
||||
me.content.clear();
|
||||
if (data.row_count == 0) return;
|
||||
|
||||
me.pushObjects(data.rows);
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
App.showSaysController = Ember.ArrayController.create({
|
||||
content: [],
|
||||
init: function(){
|
||||
|
||||
@@ -357,6 +357,28 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-handlebars" data-template-name="showNatMaps">
|
||||
<h1>Nat Maps</h1>
|
||||
<div>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Port</th>
|
||||
<th>Protocol</th>
|
||||
<th>Protocol Number</th>
|
||||
<th>Sticky</th>
|
||||
</tr>
|
||||
{{#each App.showNatMapsController.content}}
|
||||
<tr>
|
||||
<td>{{ port }}</td>
|
||||
<td>{{ proto }}</td>
|
||||
<td>{{ proto_num }}</td>
|
||||
<td>{{ sticky }}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-handlebars" data-template-name="showSays">
|
||||
<h1>Say</h1>
|
||||
<div>
|
||||
@@ -492,7 +514,7 @@
|
||||
{{#linkTo "showCompletes"}} Complete {{/linkTo}} |
|
||||
{{#linkTo "showChats"}} Chat {{/linkTo}} |
|
||||
{{#linkTo "showManagements"}} Management {{/linkTo}} |
|
||||
Nat_map |
|
||||
{{#linkTo "showNatMaps"}} Nat Map {{/linkTo}} |
|
||||
{{#linkTo "showSays"}} Say {{/linkTo}} |
|
||||
{{#linkTo "showInterfaces"}} Interfaces {{/linkTo}} |
|
||||
{{#linkTo "showInterfaceTypes"}} InterfaceTypes {{/linkTo}} |
|
||||
|
||||
+1
-1
@@ -1201,7 +1201,7 @@ static void read_config(const char *dft_cfile, const char *cfile) {
|
||||
if (strcmp(cur_cat, cfg.category)) {
|
||||
esl_set_string(cur_cat, cfg.category);
|
||||
esl_set_string(profiles[pcount].name, cur_cat);
|
||||
esl_set_string(profiles[pcount].host, "localhost");
|
||||
esl_set_string(profiles[pcount].host, "127.0.0.1");
|
||||
esl_set_string(profiles[pcount].pass, "ClueCon");
|
||||
profiles[pcount].port = 8021;
|
||||
set_fn_keys(&profiles[pcount]);
|
||||
|
||||
@@ -21,15 +21,8 @@
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* Based on a single channel G.722 codec which is:
|
||||
*
|
||||
***** Copyright (c) CMU 1993 *****
|
||||
* Computer Science, Speech Group
|
||||
* Chengxiang Lu and Alex Hauptmann
|
||||
*/
|
||||
|
||||
|
||||
/*! \file */
|
||||
|
||||
#if !defined(_SPANDSP_PRIVATE_G722_H_)
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#if !defined(_SPANDSP_PRIVATE_T4_RX_H_)
|
||||
#define _SPANDSP_PRIVATE_T4_RX_H_
|
||||
|
||||
typedef int (*t4_image_put_handler_t)(void *user_data, const uint8_t buf[], size_t len);
|
||||
|
||||
/*!
|
||||
TIFF specific state information to go with T.4 compression or decompression handling.
|
||||
*/
|
||||
@@ -125,6 +127,9 @@ struct t4_rx_state_s
|
||||
t45_decode_state_t t45;
|
||||
#endif
|
||||
} decoder;
|
||||
|
||||
t4_image_put_handler_t image_put_handler;
|
||||
|
||||
int current_decoder;
|
||||
|
||||
uint8_t *pre_encoded_buf;
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#if !defined(_SPANDSP_PRIVATE_T4_TX_H_)
|
||||
#define _SPANDSP_PRIVATE_T4_TX_H_
|
||||
|
||||
typedef int (*t4_image_get_handler_t)(void *user_data, uint8_t buf[], size_t len);
|
||||
|
||||
/*!
|
||||
TIFF specific state information to go with T.4 compression or decompression handling.
|
||||
*/
|
||||
@@ -45,6 +47,17 @@ typedef struct
|
||||
/*! \brief The TIFF fill order setting for the current page. */
|
||||
uint16_t fill_order;
|
||||
|
||||
/*! \brief Width of the image in the file. */
|
||||
uint32_t image_width;
|
||||
/*! \brief Length of the image in the file. */
|
||||
uint32_t image_length;
|
||||
/*! \brief Column-to-column (X) resolution in pixels per metre of the image in the file. */
|
||||
int x_resolution;
|
||||
/*! \brief Row-to-row (Y) resolution in pixels per metre of the image in the file. */
|
||||
int y_resolution;
|
||||
/*! \brief Code for the combined X and Y resolution of the image in the file. */
|
||||
int resolution_code;
|
||||
|
||||
/*! \brief The number of pages in the current image file. */
|
||||
int pages_in_file;
|
||||
|
||||
@@ -56,18 +69,6 @@ typedef struct
|
||||
int image_buffer_size;
|
||||
/*! \brief Row counter for playing out the rows of the image. */
|
||||
int row;
|
||||
|
||||
/*! \brief Width of the image in the file. */
|
||||
uint32_t image_width;
|
||||
/*! \brief Length of the image in the file. */
|
||||
uint32_t image_length;
|
||||
/*! \brief Column-to-column (X) resolution in pixels per metre of the image in the file. */
|
||||
int image_x_resolution;
|
||||
/*! \brief Row-to-row (Y) resolution in pixels per metre of the image in the file. */
|
||||
int image_y_resolution;
|
||||
/*! \brief Code for the combined X and Y resolution of the image in the file. */
|
||||
int resolution_code;
|
||||
|
||||
/*! \brief Row counter used when the image is resized or dithered flat. */
|
||||
int raw_row;
|
||||
} t4_tx_tiff_state_t;
|
||||
@@ -162,23 +163,25 @@ struct t4_tx_state_s
|
||||
#endif
|
||||
} encoder;
|
||||
|
||||
image_translate_state_t translator;
|
||||
uint8_t *pack_buf;
|
||||
int pack_ptr;
|
||||
int pack_row;
|
||||
int pack_bit_mask;
|
||||
t4_image_get_handler_t image_get_handler;
|
||||
|
||||
int apply_lab;
|
||||
lab_params_t lab_params;
|
||||
uint8_t *colour_map;
|
||||
int colour_map_entries;
|
||||
|
||||
image_translate_state_t translator;
|
||||
uint8_t *pack_buf;
|
||||
int pack_ptr;
|
||||
int pack_row;
|
||||
int pack_bit_mask;
|
||||
|
||||
uint8_t *pre_encoded_buf;
|
||||
int pre_encoded_len;
|
||||
int pre_encoded_ptr;
|
||||
int pre_encoded_bit;
|
||||
|
||||
/* Supporting information, like resolutions, which the backend may want. */
|
||||
/*! \brief Supporting information, like resolutions, which the backend may want. */
|
||||
t4_tx_metadata_t metadata;
|
||||
|
||||
/*! \brief All TIFF file specific state information for the T.4 context. */
|
||||
|
||||
@@ -43,15 +43,15 @@ struct v18_state_s
|
||||
} queue;
|
||||
tone_gen_descriptor_t alert_tone_desc;
|
||||
tone_gen_state_t alert_tone_gen;
|
||||
fsk_tx_state_t fsktx;
|
||||
dtmf_tx_state_t dtmftx;
|
||||
async_tx_state_t asynctx;
|
||||
fsk_tx_state_t fsk_tx;
|
||||
dtmf_tx_state_t dtmf_tx;
|
||||
async_tx_state_t async_tx;
|
||||
int baudot_tx_shift;
|
||||
int tx_signal_on;
|
||||
uint8_t next_byte;
|
||||
|
||||
fsk_rx_state_t fskrx;
|
||||
dtmf_rx_state_t dtmfrx;
|
||||
fsk_rx_state_t fsk_rx;
|
||||
dtmf_rx_state_t dtmf_rx;
|
||||
int baudot_rx_shift;
|
||||
int consecutive_ones;
|
||||
uint8_t rx_msg[256 + 1];
|
||||
|
||||
+17
-22
@@ -434,7 +434,7 @@ static void disconnect(t30_state_t *s);
|
||||
static void decode_20digit_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int len);
|
||||
static void decode_url_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int len);
|
||||
static int decode_nsf_nss_nsc(t30_state_t *s, uint8_t *msg[], const uint8_t *pkt, int len);
|
||||
static int set_min_scan_time_code(t30_state_t *s);
|
||||
static void set_min_scan_time(t30_state_t *s);
|
||||
static int send_cfr_sequence(t30_state_t *s, int start);
|
||||
static void timer_t2_start(t30_state_t *s);
|
||||
static void timer_t2a_start(t30_state_t *s);
|
||||
@@ -1682,7 +1682,7 @@ static int build_dcs(t30_state_t *s)
|
||||
||
|
||||
((s->image_width == T4_WIDTH_1200_A4) && (s->x_resolution == T4_X_RESOLUTION_1200)))
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is A4 at %ddpi x %ddpi\n", s->x_resolution, s->y_resolution);
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is A4 at %ddpm x %ddpm\n", s->x_resolution, s->y_resolution);
|
||||
/* No width related bits need to be set. */
|
||||
}
|
||||
else if (((s->image_width == T4_WIDTH_200_B4) && (s->x_resolution == T4_X_RESOLUTION_200 || s->x_resolution == T4_X_RESOLUTION_R8))
|
||||
@@ -1697,7 +1697,7 @@ static int build_dcs(t30_state_t *s)
|
||||
{
|
||||
if ((s->mutual_image_sizes & T4_SUPPORT_WIDTH_255MM))
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is B4 at %ddpi x %ddpi\n", s->x_resolution, s->y_resolution);
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is B4 at %ddpm x %ddpm\n", s->x_resolution, s->y_resolution);
|
||||
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_255MM_WIDTH);
|
||||
}
|
||||
else
|
||||
@@ -1718,7 +1718,7 @@ static int build_dcs(t30_state_t *s)
|
||||
{
|
||||
if ((s->mutual_image_sizes & T4_SUPPORT_WIDTH_303MM))
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is A3 at %ddpi x %ddpi\n", s->x_resolution, s->y_resolution);
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is A3 at %ddpm x %ddpm\n", s->x_resolution, s->y_resolution);
|
||||
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_303MM_WIDTH);
|
||||
}
|
||||
else
|
||||
@@ -2392,8 +2392,6 @@ static int analyze_rx_dcs(t30_state_t *s, const uint8_t *msg, int len)
|
||||
|
||||
static int step_fallback_entry(t30_state_t *s)
|
||||
{
|
||||
int min_row_bits;
|
||||
|
||||
while (fallback_sequence[++s->current_fallback].which)
|
||||
{
|
||||
if ((fallback_sequence[s->current_fallback].which & s->current_permitted_modems))
|
||||
@@ -2404,8 +2402,7 @@ static int step_fallback_entry(t30_state_t *s)
|
||||
/* TODO: This only sets the minimum row time for future pages. It doesn't fix up the
|
||||
current page, though it is benign - fallback will only result in an excessive
|
||||
minimum. */
|
||||
min_row_bits = set_min_scan_time_code(s);
|
||||
t4_tx_set_min_bits_per_row(&s->t4.tx, min_row_bits);
|
||||
set_min_scan_time(s);
|
||||
/* We need to rebuild the DCS message we will send. */
|
||||
build_dcs(s);
|
||||
return s->current_fallback;
|
||||
@@ -2629,7 +2626,7 @@ static void disconnect(t30_state_t *s)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int set_min_scan_time_code(t30_state_t *s)
|
||||
static void set_min_scan_time(t30_state_t *s)
|
||||
{
|
||||
/* Translation between the codes for the minimum scan times the other end needs,
|
||||
and the codes for what we say will be used. We need 0 minimum. */
|
||||
@@ -2645,6 +2642,7 @@ static int set_min_scan_time_code(t30_state_t *s)
|
||||
20, 5, 10, 0, 40, 0, 0, 0
|
||||
};
|
||||
int min_bits_field;
|
||||
int min_row_bits;
|
||||
|
||||
/* Set the minimum scan time bits */
|
||||
if (s->error_correcting_mode)
|
||||
@@ -2654,6 +2652,7 @@ static int set_min_scan_time_code(t30_state_t *s)
|
||||
switch (s->y_resolution)
|
||||
{
|
||||
case T4_Y_RESOLUTION_SUPERFINE:
|
||||
case T4_Y_RESOLUTION_400:
|
||||
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_200_400_CAPABLE))
|
||||
{
|
||||
s->min_scan_time_code = translate_min_scan_time[(test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_MIN_SCAN_TIME_HALVES)) ? 2 : 1][min_bits_field];
|
||||
@@ -2662,6 +2661,7 @@ static int set_min_scan_time_code(t30_state_t *s)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Remote FAX does not support super-fine resolution. Squashing image.\n");
|
||||
/* Fall through */
|
||||
case T4_Y_RESOLUTION_FINE:
|
||||
case T4_Y_RESOLUTION_200:
|
||||
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_200_200_CAPABLE))
|
||||
{
|
||||
s->min_scan_time_code = translate_min_scan_time[1][min_bits_field];
|
||||
@@ -2671,19 +2671,21 @@ static int set_min_scan_time_code(t30_state_t *s)
|
||||
/* Fall through */
|
||||
default:
|
||||
case T4_Y_RESOLUTION_STANDARD:
|
||||
case T4_Y_RESOLUTION_100:
|
||||
s->min_scan_time_code = translate_min_scan_time[0][min_bits_field];
|
||||
break;
|
||||
}
|
||||
if (!s->error_correcting_mode && (s->iaf & T30_IAF_MODE_NO_FILL_BITS))
|
||||
return 0;
|
||||
return fallback_sequence[s->current_fallback].bit_rate*min_scan_times[s->min_scan_time_code]/1000;
|
||||
min_row_bits = 0;
|
||||
else
|
||||
min_row_bits = fallback_sequence[s->current_fallback].bit_rate*min_scan_times[s->min_scan_time_code]/1000;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Minimum bits per row will be %d\n", min_row_bits);
|
||||
t4_tx_set_min_bits_per_row(&s->t4.tx, min_row_bits);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int start_sending_document(t30_state_t *s)
|
||||
{
|
||||
int min_row_bits;
|
||||
|
||||
if (s->tx_file[0] == '\0')
|
||||
{
|
||||
/* There is nothing to send */
|
||||
@@ -2715,15 +2717,8 @@ static int start_sending_document(t30_state_t *s)
|
||||
s->x_resolution = t4_tx_get_x_resolution(&s->t4.tx);
|
||||
s->y_resolution = t4_tx_get_y_resolution(&s->t4.tx);
|
||||
s->image_width = t4_tx_get_image_width(&s->t4.tx);
|
||||
/* The minimum scan time to be used can't be evaluated until we know the Y resolution, and
|
||||
must be evaluated before the minimum scan row bits can be evaluated. */
|
||||
if ((min_row_bits = set_min_scan_time_code(s)) < 0)
|
||||
{
|
||||
terminate_operation_in_progress(s);
|
||||
return -1;
|
||||
}
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Minimum bits per row will be %d\n", min_row_bits);
|
||||
t4_tx_set_min_bits_per_row(&s->t4.tx, min_row_bits);
|
||||
/* The minimum scan time to be used can't be evaluated until we know the Y resolution. */
|
||||
set_min_scan_time(s);
|
||||
|
||||
if (s->error_correcting_mode)
|
||||
{
|
||||
|
||||
@@ -369,18 +369,18 @@ static int get_tiff_directory_info(t4_tx_state_t *s)
|
||||
t->fill_order = FILLORDER_LSB2MSB;
|
||||
|
||||
if (res_unit == RESUNIT_INCH)
|
||||
t->image_x_resolution = x_resolution*100.0f/CM_PER_INCH;
|
||||
t->x_resolution = x_resolution*100.0f/CM_PER_INCH;
|
||||
else
|
||||
t->image_x_resolution = x_resolution*100.0f;
|
||||
t->x_resolution = x_resolution*100.0f;
|
||||
/* Treat everything we can't match as R8. Most FAXes are this resolution anyway. */
|
||||
if ((best_x_entry = match_resolution(res_unit, x_resolution, x_res_table)) < 0)
|
||||
best_x_entry = 3;
|
||||
s->metadata.x_resolution = x_res_table[best_x_entry].code;
|
||||
|
||||
if (res_unit == RESUNIT_INCH)
|
||||
t->image_y_resolution = y_resolution*100.0f/CM_PER_INCH;
|
||||
t->y_resolution = y_resolution*100.0f/CM_PER_INCH;
|
||||
else
|
||||
t->image_y_resolution = y_resolution*100.0f;
|
||||
t->y_resolution = y_resolution*100.0f;
|
||||
if ((best_y_entry = match_resolution(res_unit, y_resolution, y_res_table)) < 0)
|
||||
best_y_entry = 0;
|
||||
s->metadata.y_resolution = y_res_table[best_y_entry].code;
|
||||
@@ -1354,8 +1354,8 @@ SPAN_DECLARE(void) t4_tx_get_transfer_statistics(t4_tx_state_t *s, t4_stats_t *t
|
||||
t->image_type = s->tiff.image_type;
|
||||
t->image_width = s->tiff.image_width;
|
||||
t->image_length = s->tiff.image_length;
|
||||
t->image_x_resolution = s->tiff.image_x_resolution;
|
||||
t->image_y_resolution = s->tiff.image_y_resolution;
|
||||
t->image_x_resolution = s->tiff.x_resolution;
|
||||
t->image_y_resolution = s->tiff.y_resolution;
|
||||
|
||||
t->x_resolution = s->metadata.x_resolution;
|
||||
t->y_resolution = s->metadata.y_resolution/s->row_squashing_ratio;
|
||||
|
||||
+30
-30
@@ -665,7 +665,7 @@ static void v18_dtmf_get(void *user_data)
|
||||
if ((ch = queue_read_byte(&s->queue.queue)) >= 0)
|
||||
{
|
||||
v = ascii_to_dtmf[ch & 0x7F];
|
||||
dtmf_tx_put(&s->dtmftx, v, strlen(v));
|
||||
dtmf_tx_put(&s->dtmf_tx, v, strlen(v));
|
||||
s->rx_suppression = ((300 + 100*strlen(v))*SAMPLE_RATE)/1000;
|
||||
}
|
||||
}
|
||||
@@ -809,12 +809,12 @@ SPAN_DECLARE_NONSTD(int) v18_tx(v18_state_t *s, int16_t *amp, int max_len)
|
||||
{
|
||||
case V18_MODE_DTMF:
|
||||
if (len < max_len)
|
||||
len += dtmf_tx(&s->dtmftx, amp, max_len - len);
|
||||
len += dtmf_tx(&s->dtmf_tx, amp, max_len - len);
|
||||
break;
|
||||
default:
|
||||
if (len < max_len)
|
||||
{
|
||||
if ((lenx = fsk_tx(&s->fsktx, amp + len, max_len - len)) <= 0)
|
||||
if ((lenx = fsk_tx(&s->fsk_tx, amp + len, max_len - len)) <= 0)
|
||||
s->tx_signal_on = FALSE;
|
||||
len += lenx;
|
||||
}
|
||||
@@ -841,10 +841,10 @@ SPAN_DECLARE_NONSTD(int) v18_rx(v18_state_t *s, const int16_t amp[], int len)
|
||||
s->in_progress -= len;
|
||||
if (s->in_progress <= 0)
|
||||
s->rx_msg_len = 0;
|
||||
dtmf_rx(&s->dtmfrx, amp, len);
|
||||
dtmf_rx(&s->dtmf_rx, amp, len);
|
||||
break;
|
||||
default:
|
||||
fsk_rx(&s->fskrx, amp, len);
|
||||
fsk_rx(&s->fsk_rx, amp, len);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@@ -867,10 +867,10 @@ SPAN_DECLARE_NONSTD(int) v18_rx_fillin(v18_state_t *s, int len)
|
||||
//s->in_progress -= len;
|
||||
//if (s->in_progress <= 0)
|
||||
// s->rx_msg_len = 0;
|
||||
dtmf_rx_fillin(&s->dtmfrx, len);
|
||||
dtmf_rx_fillin(&s->dtmf_rx, len);
|
||||
break;
|
||||
default:
|
||||
fsk_rx_fillin(&s->fskrx, len);
|
||||
fsk_rx_fillin(&s->fsk_rx, len);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@@ -973,56 +973,56 @@ SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
|
||||
{
|
||||
case V18_MODE_5BIT_45:
|
||||
s->repeat_shifts = mode & 0x100;
|
||||
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_WEITBRECHT], async_tx_get_bit, &s->asynctx);
|
||||
async_tx_init(&s->asynctx, 5, ASYNC_PARITY_NONE, 2, FALSE, v18_tdd_get_async_byte, s);
|
||||
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_WEITBRECHT], async_tx_get_bit, &s->async_tx);
|
||||
async_tx_init(&s->async_tx, 5, ASYNC_PARITY_NONE, 2, FALSE, v18_tdd_get_async_byte, s);
|
||||
/* Schedule an explicit shift at the start of baudot transmission */
|
||||
s->baudot_tx_shift = 2;
|
||||
/* TDD uses 5 bit data, no parity and 1.5 stop bits. We scan for the first stop bit, and
|
||||
ride over the fraction. */
|
||||
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_WEITBRECHT], FSK_FRAME_MODE_5N1_FRAMES, v18_tdd_put_async_byte, s);
|
||||
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_WEITBRECHT], FSK_FRAME_MODE_5N1_FRAMES, v18_tdd_put_async_byte, s);
|
||||
s->baudot_rx_shift = 0;
|
||||
s->next_byte = (uint8_t) 0xFF;
|
||||
break;
|
||||
case V18_MODE_5BIT_50:
|
||||
s->repeat_shifts = mode & 0x100;
|
||||
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_WEITBRECHT50], async_tx_get_bit, &s->asynctx);
|
||||
async_tx_init(&s->asynctx, 5, ASYNC_PARITY_NONE, 2, FALSE, v18_tdd_get_async_byte, s);
|
||||
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_WEITBRECHT50], async_tx_get_bit, &s->async_tx);
|
||||
async_tx_init(&s->async_tx, 5, ASYNC_PARITY_NONE, 2, FALSE, v18_tdd_get_async_byte, s);
|
||||
/* Schedule an explicit shift at the start of baudot transmission */
|
||||
s->baudot_tx_shift = 2;
|
||||
/* TDD uses 5 bit data, no parity and 1.5 stop bits. We scan for the first stop bit, and
|
||||
ride over the fraction. */
|
||||
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_WEITBRECHT50], FSK_FRAME_MODE_5N1_FRAMES, v18_tdd_put_async_byte, s);
|
||||
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_WEITBRECHT50], FSK_FRAME_MODE_5N1_FRAMES, v18_tdd_put_async_byte, s);
|
||||
s->baudot_rx_shift = 0;
|
||||
s->next_byte = (uint8_t) 0xFF;
|
||||
break;
|
||||
case V18_MODE_DTMF:
|
||||
dtmf_tx_init(&s->dtmftx, v18_dtmf_get, s);
|
||||
dtmf_rx_init(&s->dtmfrx, v18_dtmf_put, s);
|
||||
dtmf_tx_init(&s->dtmf_tx, v18_dtmf_get, s);
|
||||
dtmf_rx_init(&s->dtmf_rx, v18_dtmf_put, s);
|
||||
break;
|
||||
case V18_MODE_EDT:
|
||||
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_V21CH1_110], async_tx_get_bit, &s->asynctx);
|
||||
async_tx_init(&s->asynctx, 7, ASYNC_PARITY_EVEN, 2, FALSE, v18_edt_get_async_byte, s);
|
||||
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_V21CH1_110], FSK_FRAME_MODE_7E2_FRAMES, v18_edt_put_async_byte, s);
|
||||
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_V21CH1_110], async_tx_get_bit, &s->async_tx);
|
||||
async_tx_init(&s->async_tx, 7, ASYNC_PARITY_EVEN, 2, FALSE, v18_edt_get_async_byte, s);
|
||||
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_V21CH1_110], FSK_FRAME_MODE_7E2_FRAMES, v18_edt_put_async_byte, s);
|
||||
break;
|
||||
case V18_MODE_BELL103:
|
||||
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_BELL103CH1], async_tx_get_bit, &s->asynctx);
|
||||
async_tx_init(&s->asynctx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
|
||||
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_BELL103CH2], FSK_FRAME_MODE_7E1_FRAMES, v18_bell103_put_async_byte, s);
|
||||
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_BELL103CH1], async_tx_get_bit, &s->async_tx);
|
||||
async_tx_init(&s->async_tx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
|
||||
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_BELL103CH2], FSK_FRAME_MODE_7E1_FRAMES, v18_bell103_put_async_byte, s);
|
||||
break;
|
||||
case V18_MODE_V23VIDEOTEX:
|
||||
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_V23CH1], async_tx_get_bit, &s->asynctx);
|
||||
async_tx_init(&s->asynctx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
|
||||
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_V23CH2], FSK_FRAME_MODE_7E1_FRAMES, v18_videotex_put_async_byte, s);
|
||||
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_V23CH1], async_tx_get_bit, &s->async_tx);
|
||||
async_tx_init(&s->async_tx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
|
||||
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_V23CH2], FSK_FRAME_MODE_7E1_FRAMES, v18_videotex_put_async_byte, s);
|
||||
break;
|
||||
case V18_MODE_V21TEXTPHONE:
|
||||
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_V21CH1], async_tx_get_bit, &s->asynctx);
|
||||
async_tx_init(&s->asynctx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
|
||||
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_V21CH1], FSK_FRAME_MODE_7E1_FRAMES, v18_textphone_put_async_byte, s);
|
||||
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_V21CH1], async_tx_get_bit, &s->async_tx);
|
||||
async_tx_init(&s->async_tx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
|
||||
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_V21CH1], FSK_FRAME_MODE_7E1_FRAMES, v18_textphone_put_async_byte, s);
|
||||
break;
|
||||
case V18_MODE_V18TEXTPHONE:
|
||||
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_V21CH1], async_tx_get_bit, &s->asynctx);
|
||||
async_tx_init(&s->asynctx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
|
||||
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_V21CH1], FSK_FRAME_MODE_7E1_FRAMES, v18_textphone_put_async_byte, s);
|
||||
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_V21CH1], async_tx_get_bit, &s->async_tx);
|
||||
async_tx_init(&s->async_tx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
|
||||
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_V21CH1], FSK_FRAME_MODE_7E1_FRAMES, v18_textphone_put_async_byte, s);
|
||||
break;
|
||||
}
|
||||
s->nation = nation;
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
uint8_t buffer[256];
|
||||
|
||||
#define PATTERN 0x11111111
|
||||
#define PATTERN 0x1111111
|
||||
#define SEQUENCE_LENGTH 17
|
||||
|
||||
uint8_t left[] =
|
||||
@@ -111,7 +111,7 @@ int main(int argc, char *argv[])
|
||||
total_bits = 0;
|
||||
for (i = 0; i < SEQUENCE_LENGTH; i++)
|
||||
{
|
||||
bitstream_put(s, &w, PATTERN*i, i + 1);
|
||||
bitstream_put(s, &w, i*PATTERN, i + 1);
|
||||
total_bits += (i + 1);
|
||||
}
|
||||
bitstream_flush(s, &w);
|
||||
|
||||
@@ -490,6 +490,7 @@ int main(int argc, char *argv[])
|
||||
int noise_level;
|
||||
int code_to_look_up;
|
||||
int scan_line_time;
|
||||
int allowed_bilevel_resolutions;
|
||||
int colour_enabled;
|
||||
t38_stats_t t38_stats;
|
||||
t30_stats_t t30_stats;
|
||||
@@ -529,12 +530,16 @@ int main(int argc, char *argv[])
|
||||
scan_line_time = 0;
|
||||
decode_file_name = NULL;
|
||||
code_to_look_up = -1;
|
||||
allowed_bilevel_resolutions = 0;
|
||||
colour_enabled = FALSE;
|
||||
t38_transport = T38_TRANSPORT_UDPTL;
|
||||
while ((opt = getopt(argc, argv, "c:Cd:D:efFgH:i:Ilm:M:n:p:s:S:tT:u:v:z:")) != -1)
|
||||
while ((opt = getopt(argc, argv, "b:c:Cd:D:efFgH:i:Ilm:M:n:p:s:S:tT:u:v:z:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'b':
|
||||
allowed_bilevel_resolutions = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
code_to_look_up = atoi(optarg);
|
||||
break;
|
||||
@@ -850,41 +855,63 @@ int main(int argc, char *argv[])
|
||||
| T4_SUPPORT_LENGTH_US_LETTER
|
||||
| T4_SUPPORT_LENGTH_US_LEGAL
|
||||
| T4_SUPPORT_LENGTH_UNLIMITED);
|
||||
#if 1
|
||||
t30_set_supported_bilevel_resolutions(t30_state[i],
|
||||
T4_SUPPORT_RESOLUTION_R8_STANDARD
|
||||
| T4_SUPPORT_RESOLUTION_R8_FINE
|
||||
| T4_SUPPORT_RESOLUTION_R8_SUPERFINE
|
||||
| T4_SUPPORT_RESOLUTION_R16_SUPERFINE
|
||||
| T4_SUPPORT_RESOLUTION_200_100
|
||||
| T4_SUPPORT_RESOLUTION_200_200
|
||||
| T4_SUPPORT_RESOLUTION_200_400
|
||||
| T4_SUPPORT_RESOLUTION_300_300
|
||||
| T4_SUPPORT_RESOLUTION_300_600
|
||||
| T4_SUPPORT_RESOLUTION_400_400
|
||||
| T4_SUPPORT_RESOLUTION_400_800
|
||||
| T4_SUPPORT_RESOLUTION_600_600
|
||||
| T4_SUPPORT_RESOLUTION_600_1200
|
||||
| T4_SUPPORT_RESOLUTION_1200_1200);
|
||||
#elif 0
|
||||
t30_set_supported_bilevel_resolutions(t30_state[i],
|
||||
T4_SUPPORT_RESOLUTION_R8_STANDARD
|
||||
| T4_SUPPORT_RESOLUTION_R8_FINE
|
||||
| T4_SUPPORT_RESOLUTION_R8_SUPERFINE
|
||||
| T4_SUPPORT_RESOLUTION_R16_SUPERFINE);
|
||||
#else
|
||||
t30_set_supported_bilevel_resolutions(t30_state[i],
|
||||
T4_SUPPORT_RESOLUTION_200_100
|
||||
| T4_SUPPORT_RESOLUTION_200_200
|
||||
| T4_SUPPORT_RESOLUTION_200_400
|
||||
| T4_SUPPORT_RESOLUTION_300_300
|
||||
| T4_SUPPORT_RESOLUTION_300_600
|
||||
| T4_SUPPORT_RESOLUTION_400_400
|
||||
| T4_SUPPORT_RESOLUTION_400_800
|
||||
| T4_SUPPORT_RESOLUTION_600_600
|
||||
| T4_SUPPORT_RESOLUTION_600_1200
|
||||
| T4_SUPPORT_RESOLUTION_1200_1200);
|
||||
#endif
|
||||
switch (allowed_bilevel_resolutions)
|
||||
{
|
||||
case 0:
|
||||
/* Allow anything */
|
||||
t30_set_supported_bilevel_resolutions(t30_state[i],
|
||||
T4_SUPPORT_RESOLUTION_R8_STANDARD
|
||||
| T4_SUPPORT_RESOLUTION_R8_FINE
|
||||
| T4_SUPPORT_RESOLUTION_R8_SUPERFINE
|
||||
| T4_SUPPORT_RESOLUTION_R16_SUPERFINE
|
||||
| T4_SUPPORT_RESOLUTION_200_100
|
||||
| T4_SUPPORT_RESOLUTION_200_200
|
||||
| T4_SUPPORT_RESOLUTION_200_400
|
||||
| T4_SUPPORT_RESOLUTION_300_300
|
||||
| T4_SUPPORT_RESOLUTION_300_600
|
||||
| T4_SUPPORT_RESOLUTION_400_400
|
||||
| T4_SUPPORT_RESOLUTION_400_800
|
||||
| T4_SUPPORT_RESOLUTION_600_600
|
||||
| T4_SUPPORT_RESOLUTION_600_1200
|
||||
| T4_SUPPORT_RESOLUTION_1200_1200);
|
||||
break;
|
||||
case 1:
|
||||
/* Allow anything metric */
|
||||
t30_set_supported_bilevel_resolutions(t30_state[i],
|
||||
T4_SUPPORT_RESOLUTION_R8_STANDARD
|
||||
| T4_SUPPORT_RESOLUTION_R8_FINE
|
||||
| T4_SUPPORT_RESOLUTION_R8_SUPERFINE
|
||||
| T4_SUPPORT_RESOLUTION_R16_SUPERFINE);
|
||||
break;
|
||||
case 2:
|
||||
/* Allow anything inch based */
|
||||
t30_set_supported_bilevel_resolutions(t30_state[i],
|
||||
T4_SUPPORT_RESOLUTION_200_100
|
||||
| T4_SUPPORT_RESOLUTION_200_200
|
||||
| T4_SUPPORT_RESOLUTION_200_400
|
||||
| T4_SUPPORT_RESOLUTION_300_300
|
||||
| T4_SUPPORT_RESOLUTION_300_600
|
||||
| T4_SUPPORT_RESOLUTION_400_400
|
||||
| T4_SUPPORT_RESOLUTION_400_800
|
||||
| T4_SUPPORT_RESOLUTION_600_600
|
||||
| T4_SUPPORT_RESOLUTION_600_1200
|
||||
| T4_SUPPORT_RESOLUTION_1200_1200);
|
||||
break;
|
||||
case 3:
|
||||
/* Allow only restricted length resolution */
|
||||
t30_set_supported_bilevel_resolutions(t30_state[i],
|
||||
T4_SUPPORT_RESOLUTION_R8_STANDARD
|
||||
| T4_SUPPORT_RESOLUTION_R8_FINE
|
||||
| T4_SUPPORT_RESOLUTION_200_100
|
||||
| T4_SUPPORT_RESOLUTION_200_200);
|
||||
break;
|
||||
case 4:
|
||||
/* Allow only more restricted length resolution */
|
||||
t30_set_supported_bilevel_resolutions(t30_state[i],
|
||||
T4_SUPPORT_RESOLUTION_R8_STANDARD
|
||||
| T4_SUPPORT_RESOLUTION_200_100);
|
||||
break;
|
||||
}
|
||||
if (colour_enabled)
|
||||
{
|
||||
t30_set_supported_colour_resolutions(t30_state[i],
|
||||
|
||||
@@ -147,11 +147,15 @@ int main(int argc, char *argv[])
|
||||
uint16_t *map_b;
|
||||
uint16_t *map_z;
|
||||
uint32_t jpeg_table_len;
|
||||
#if 0
|
||||
logging_state_t *logging;
|
||||
#endif
|
||||
|
||||
printf("Demo of ITU/Lab library.\n");
|
||||
|
||||
#if 0
|
||||
logging = span_log_init(NULL, SPAN_LOG_FLOW, "T.42");
|
||||
#endif
|
||||
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
TIFF_FX_init();
|
||||
@@ -265,6 +269,7 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
outsize = 0;
|
||||
if (process_raw)
|
||||
{
|
||||
uint8_t *jpeg_table;
|
||||
|
||||
@@ -552,7 +552,6 @@ int read_compressed_image(meta_t *meta, uint8_t **buf)
|
||||
int read_decompressed_image(meta_t *meta, uint8_t **buf)
|
||||
{
|
||||
int bytes_per_row;
|
||||
tsize_t off;
|
||||
int x;
|
||||
int y;
|
||||
int xx;
|
||||
@@ -561,21 +560,23 @@ int read_decompressed_image(meta_t *meta, uint8_t **buf)
|
||||
int yyy;
|
||||
int i;
|
||||
int j;
|
||||
uint32_t w;
|
||||
uint32_t h;
|
||||
uint16_t samples_per_pixel;
|
||||
int result;
|
||||
int total_raw;
|
||||
int total_data;
|
||||
uint8_t *raw_buf;
|
||||
uint8_t *image_buf;
|
||||
uint8_t *jpeg_table;
|
||||
uint32_t jpeg_table_len;
|
||||
t85_decode_state_t t85;
|
||||
t43_decode_state_t t43;
|
||||
packer_t pack;
|
||||
logging_state_t *logging;
|
||||
logging_state_t logging2;
|
||||
#if 0
|
||||
uint8_t *jpeg_table;
|
||||
uint32_t jpeg_table_len;
|
||||
tsize_t off;
|
||||
uint32_t w;
|
||||
uint32_t h;
|
||||
#endif
|
||||
|
||||
image_buf = NULL;
|
||||
total_data = 0;
|
||||
@@ -652,8 +653,8 @@ total_data *= 8;
|
||||
if ((image_buf = malloc(total_data)) == NULL)
|
||||
printf("Failed to allocated image buffer\n");
|
||||
|
||||
jpeg_table_len = 0;
|
||||
#if 0
|
||||
jpeg_table_len = 0;
|
||||
if (TIFFGetField(meta->tif, TIFFTAG_JPEGTABLES, &jpeg_table_len, &jpeg_table))
|
||||
{
|
||||
total_image_len += (jpeg_table_len - 4);
|
||||
@@ -921,6 +922,7 @@ int main(int argc, char *argv[])
|
||||
set_lab_illuminant(&lab_param, 96.422f, 100.000f, 82.521f);
|
||||
set_lab_gamut(&lab_param, 0, 100, -85, 85, -75, 125, FALSE);
|
||||
|
||||
outptr = NULL;
|
||||
for (page_no = 0; ; page_no++)
|
||||
{
|
||||
if (read_file(&in_meta, page_no) < 0)
|
||||
|
||||
+70
-232
@@ -53,48 +53,6 @@ in ITU specifications T.4 and T.6.
|
||||
t4_tx_state_t *send_state;
|
||||
t4_rx_state_t *receive_state;
|
||||
|
||||
/* The following are some test cases from T.4 */
|
||||
#define FILL_70 " "
|
||||
#define FILL_80 " "
|
||||
#define FILL_100 " "
|
||||
#define FILL_670 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_70
|
||||
#define FILL_980 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_80
|
||||
|
||||
static const char t4_t6_test_patterns[][1728 + 1] =
|
||||
{
|
||||
"XXXXXX " FILL_980 " XXX XXX X " FILL_670 " XXXX",
|
||||
"XXXXXX " FILL_980 " XXX X " FILL_670 " XXXX",
|
||||
/* Line start should code to V(0). Line middle codes to VR(3) VL(2) V(0). Line end should code to V(0) V(0). */
|
||||
|
||||
" XXXX " FILL_980 " XXXXXXX " FILL_670 " XX ",
|
||||
"XXXXX " FILL_980 "XX XX " FILL_670 " XXXX",
|
||||
/* Line start should code to VL(1). Line middle codes to H(7,2). Line end should code to V(0) VR(2) */
|
||||
|
||||
"XXX " FILL_980 " XX XX XX XXX " FILL_670 " X ",
|
||||
" " FILL_980 " X XXX XXXX " FILL_670 " X XX",
|
||||
/* Line start should code to P. Line middle codes to P VL(1) V(0) H(3,4) P. Line end codes to V(0) VL(2) V(0). */
|
||||
|
||||
"XXXXX " FILL_980 " " FILL_670 " XXXX",
|
||||
" XXX " FILL_980 " " FILL_670 " XX ",
|
||||
/* Line start should code to VR(2). Line end codes to V(0) VL(2) V(0). */
|
||||
|
||||
" XX " FILL_980 " " FILL_670 " X XXX",
|
||||
"XXX X " FILL_980 " " FILL_670 " X ",
|
||||
/* Line start should code to H(0,3) VR(1). Line end codes to V(0) VR(3). */
|
||||
|
||||
" " FILL_980 " " FILL_670 " XX ",
|
||||
" " FILL_980 " " FILL_670 " ",
|
||||
/* Line end codes to P V(0) a'0. */
|
||||
|
||||
" " FILL_980 " " FILL_670 " XXXXXXXXXX",
|
||||
" " FILL_980 " " FILL_670 " XXXXXX XXXXXX",
|
||||
/* Line end codes to H(2,6). */
|
||||
|
||||
" " FILL_980 " " FILL_670 " XX XXXXX",
|
||||
" " FILL_980 " " FILL_670 " XX ",
|
||||
/* Line end codes to V(0) H(7,0). */
|
||||
};
|
||||
|
||||
int rows_written = 0;
|
||||
int rows_read = 0;
|
||||
|
||||
@@ -140,63 +98,7 @@ static void display_page_stats(t4_rx_state_t *s)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int row_read_handler(void *user_data, uint8_t buf[], size_t len)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
const char *s;
|
||||
|
||||
/* Send the test pattern. */
|
||||
if (rows_read >= 16)
|
||||
return 0;
|
||||
s = t4_t6_test_patterns[rows_read++];
|
||||
memset(buf, 0, len);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (*s++ != ' ')
|
||||
buf[i] |= (0x80 >> j);
|
||||
}
|
||||
}
|
||||
if (*s)
|
||||
printf("Oops - '%c' at end of row %d\n", *s, rows_read);
|
||||
return len;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int row_write_handler(void *user_data, const uint8_t buf[], size_t len)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
const char *s;
|
||||
uint8_t ref[8192];
|
||||
|
||||
/* Verify that what is received matches the test pattern. */
|
||||
if (len == 0)
|
||||
return 0;
|
||||
s = t4_t6_test_patterns[rows_written++];
|
||||
memset(ref, 0, len);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (*s++ != ' ')
|
||||
ref[i] |= (0x80 >> j);
|
||||
}
|
||||
}
|
||||
if (*s)
|
||||
printf("Oops - '%c' at end of row %d\n", *s, rows_written);
|
||||
if (memcmp(buf, ref, len))
|
||||
{
|
||||
printf("Test failed at row %d\n", rows_written);
|
||||
exit(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int detect_page_end(int bit, int page_ended)
|
||||
static int detect_non_ecm_page_end(int bit, int page_ended)
|
||||
{
|
||||
static int consecutive_eols;
|
||||
static int max_consecutive_eols;
|
||||
@@ -207,10 +109,10 @@ static int detect_page_end(int bit, int page_ended)
|
||||
static int expected_eols;
|
||||
static int end_marks;
|
||||
|
||||
/* Check the EOLs are added properly to the end of an image. We can't rely on the
|
||||
decoder giving the right answer, as a full set of EOLs is not needed for the
|
||||
decoder to work. */
|
||||
if (bit == -1000000)
|
||||
/* Check the EOLs are added properly to the end of a non-ECM image. We can't rely
|
||||
on the decoder giving the right answer, as a full set of EOLs is not needed for
|
||||
the decoder to work. */
|
||||
if (bit == -1)
|
||||
{
|
||||
/* Reset */
|
||||
consecutive_eols = 0;
|
||||
@@ -287,6 +189,9 @@ int main(int argc, char *argv[])
|
||||
T4_COMPRESSION_T6,
|
||||
T4_COMPRESSION_T85,
|
||||
T4_COMPRESSION_T85_L0,
|
||||
#if defined(SPANDSP_SUPPORT_T88x)
|
||||
T4_COMPRESSION_T88,
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T42x)
|
||||
T4_COMPRESSION_T42_T81,
|
||||
T4_COMPRESSION_SYCC_T81,
|
||||
@@ -294,7 +199,9 @@ int main(int argc, char *argv[])
|
||||
#if defined(SPANDSP_SUPPORT_T43x)
|
||||
T4_COMPRESSION_T43,
|
||||
#endif
|
||||
//T4_COMPRESSION_T45,
|
||||
#if defined(SPANDSP_SUPPORT_T45x)
|
||||
T4_COMPRESSION_T45,
|
||||
#endif
|
||||
-1
|
||||
};
|
||||
int sends;
|
||||
@@ -348,7 +255,10 @@ int main(int argc, char *argv[])
|
||||
case 'b':
|
||||
block_size = atoi(optarg);
|
||||
if (block_size > 1024)
|
||||
block_size = 1024;
|
||||
{
|
||||
printf("Block size too large. Must be 1024 or less\n");
|
||||
exit(2);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
if (strcmp(optarg, "T41D") == 0)
|
||||
@@ -371,6 +281,13 @@ int main(int argc, char *argv[])
|
||||
compression = T4_COMPRESSION_T85;
|
||||
compression_step = -1;
|
||||
}
|
||||
#if defined(SPANDSP_SUPPORT_T88)
|
||||
else if (strcmp(optarg, "T88") == 0)
|
||||
{
|
||||
compression = T4_COMPRESSION_T88;
|
||||
compression_step = -1;
|
||||
}
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
else if (strcmp(optarg, "T81") == 0)
|
||||
{
|
||||
@@ -385,6 +302,18 @@ int main(int argc, char *argv[])
|
||||
compression_step = -1;
|
||||
}
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T45)
|
||||
else if (strcmp(optarg, "T45") == 0)
|
||||
{
|
||||
compression = T4_COMPRESSION_T45;
|
||||
compression_step = -1;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
printf("Unrecognised compression.\n");
|
||||
exit(2);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
decode_file_name = optarg;
|
||||
@@ -533,130 +462,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 1
|
||||
printf("Testing image_function->compress->decompress->image_function\n");
|
||||
/* Send end gets image from a function */
|
||||
if ((send_state = t4_tx_init(NULL, NULL, -1, -1)) == NULL)
|
||||
{
|
||||
printf("Failed to init T.4 tx\n");
|
||||
exit(2);
|
||||
}
|
||||
span_log_set_level(t4_tx_get_logging_state(send_state), SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
|
||||
t4_tx_set_row_read_handler(send_state, row_read_handler, NULL);
|
||||
t4_tx_set_image_width(send_state, 1728);
|
||||
t4_tx_set_min_bits_per_row(send_state, min_row_bits);
|
||||
t4_tx_set_max_2d_rows_per_1d_row(send_state, 2);
|
||||
|
||||
/* Receive end puts TIFF to a function. */
|
||||
if ((receive_state = t4_rx_init(NULL, NULL, T4_COMPRESSION_T4_2D)) == NULL)
|
||||
{
|
||||
printf("Failed to init T.4 rx\n");
|
||||
exit(2);
|
||||
}
|
||||
span_log_set_level(t4_rx_get_logging_state(receive_state), SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
|
||||
t4_rx_set_row_write_handler(receive_state, row_write_handler, NULL);
|
||||
t4_rx_set_image_width(receive_state, t4_tx_get_image_width(send_state));
|
||||
t4_rx_set_x_resolution(receive_state, t4_tx_get_x_resolution(send_state));
|
||||
t4_rx_set_y_resolution(receive_state, t4_tx_get_y_resolution(send_state));
|
||||
|
||||
/* Now send and receive the test data with all compression modes. */
|
||||
/* If we are stepping around the compression schemes, reset to the start of the sequence. */
|
||||
if (compression_step > 0)
|
||||
compression_step = 0;
|
||||
for (;;)
|
||||
{
|
||||
end_marks = 0;
|
||||
if (compression_step >= 0)
|
||||
{
|
||||
compression = compression_sequence[compression_step++];
|
||||
if (compression < 0 || (block_size == 0 && compression_step >= 3))
|
||||
break;
|
||||
}
|
||||
t4_tx_set_tx_encoding(send_state, compression);
|
||||
t4_rx_set_rx_encoding(receive_state, compression);
|
||||
|
||||
rows_read = 0;
|
||||
rows_written = 0;
|
||||
if (t4_tx_start_page(send_state))
|
||||
break;
|
||||
if (t4_rx_start_page(receive_state))
|
||||
break;
|
||||
detect_page_end(-1000000, compression);
|
||||
page_ended = FALSE;
|
||||
switch (block_size)
|
||||
{
|
||||
case 0:
|
||||
while ((bit = t4_tx_get_bit(send_state)) >= 0)
|
||||
{
|
||||
/* Monitor whether the EOLs are there in the correct amount */
|
||||
if ((res = detect_page_end(bit, page_ended)))
|
||||
{
|
||||
printf("Incorrect EOLs - %d\n", res);
|
||||
tests_failed += (res - 1);
|
||||
break;
|
||||
}
|
||||
if (bit >= 0)
|
||||
{
|
||||
if (bit_error_rate)
|
||||
{
|
||||
if ((rand() % bit_error_rate) == 0)
|
||||
bit ^= 1;
|
||||
}
|
||||
end_of_page = t4_rx_put_bit(receive_state, bit);
|
||||
}
|
||||
}
|
||||
while (end_of_page != T4_DECODE_OK)
|
||||
{
|
||||
end_of_page = t4_rx_put_bit(receive_state, 0);
|
||||
if (++end_marks > 50)
|
||||
{
|
||||
printf("Receiver missed the end of page mark\n");
|
||||
tests_failed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Now throw junk at the receive context, to ensure stuff occuring
|
||||
after the end of page condition has no bad effect. */
|
||||
for (i = 0; i < 1000; i++)
|
||||
t4_rx_put_bit(receive_state, (rand() >> 10) & 1);
|
||||
break;
|
||||
default:
|
||||
/* Some decoders require a few extra bits before the recognise the end
|
||||
of an image, so be prepared to offer it a few. */
|
||||
do
|
||||
{
|
||||
len = t4_tx_get(send_state, block, block_size);
|
||||
if (len > 0)
|
||||
end_of_page = t4_rx_put(receive_state, block, len);
|
||||
}
|
||||
while (len > 0);
|
||||
while (end_of_page != T4_DECODE_OK)
|
||||
{
|
||||
block[0] = 0;
|
||||
end_of_page = t4_rx_put(receive_state, block, 1);
|
||||
if (++end_marks > 5)
|
||||
{
|
||||
printf("Receiver missed the end of page mark\n");
|
||||
tests_failed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
display_page_stats(receive_state);
|
||||
t4_tx_end_page(send_state);
|
||||
t4_rx_end_page(receive_state);
|
||||
if (rows_read != (15 + 1) || rows_written != (15 + 1))
|
||||
{
|
||||
printf("Test failed: %d rows read, %d rows written\n", rows_read, rows_written);
|
||||
exit(2);
|
||||
}
|
||||
if (compression_step < 0)
|
||||
break;
|
||||
}
|
||||
t4_tx_release(send_state);
|
||||
t4_rx_release(receive_state);
|
||||
#endif
|
||||
#if 1
|
||||
printf("Testing TIFF->compress->decompress->TIFF cycle\n");
|
||||
/* Send end gets TIFF from a file */
|
||||
@@ -713,6 +518,37 @@ int main(int argc, char *argv[])
|
||||
compression = compression_sequence[compression_step++];
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (t4_tx_set_tx_image_format(send_state,
|
||||
compression,
|
||||
T4_SUPPORT_WIDTH_215MM
|
||||
| T4_SUPPORT_LENGTH_US_LETTER
|
||||
| T4_SUPPORT_LENGTH_US_LEGAL
|
||||
| T4_SUPPORT_LENGTH_UNLIMITED,
|
||||
T4_RESOLUTION_R8_STANDARD
|
||||
| T4_RESOLUTION_R8_FINE
|
||||
| T4_RESOLUTION_R8_SUPERFINE
|
||||
| T4_RESOLUTION_R16_SUPERFINE
|
||||
| T4_RESOLUTION_200_100
|
||||
| T4_RESOLUTION_200_200
|
||||
| T4_RESOLUTION_200_400
|
||||
| T4_RESOLUTION_300_300
|
||||
| T4_RESOLUTION_300_600
|
||||
| T4_RESOLUTION_400_400
|
||||
| T4_RESOLUTION_400_800
|
||||
| T4_RESOLUTION_600_600
|
||||
| T4_RESOLUTION_600_1200
|
||||
| T4_RESOLUTION_1200_1200,
|
||||
T4_RESOLUTION_100_100
|
||||
| T4_RESOLUTION_200_200
|
||||
| T4_RESOLUTION_300_300
|
||||
| T4_RESOLUTION_400_400
|
||||
| T4_RESOLUTION_600_600
|
||||
| T4_RESOLUTION_1200_1200) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
t4_tx_set_tx_encoding(send_state, compression);
|
||||
t4_rx_set_rx_encoding(receive_state, compression);
|
||||
|
||||
@@ -723,15 +559,17 @@ int main(int argc, char *argv[])
|
||||
t4_rx_set_image_width(receive_state, t4_tx_get_image_width(send_state));
|
||||
}
|
||||
t4_rx_start_page(receive_state);
|
||||
detect_page_end(-1000000, compression);
|
||||
detect_non_ecm_page_end(-1, compression);
|
||||
page_ended = FALSE;
|
||||
switch (block_size)
|
||||
{
|
||||
case 0:
|
||||
/* Bit by bit operation. This is only appropriate for T.4 1D and 2D,
|
||||
which are used without ECM. */
|
||||
while ((bit = t4_tx_get_bit(send_state)) >= 0)
|
||||
{
|
||||
/* Monitor whether the EOLs are there in the correct amount */
|
||||
if ((res = detect_page_end(bit, page_ended)))
|
||||
if ((res = detect_non_ecm_page_end(bit, page_ended)))
|
||||
{
|
||||
printf("Incorrect EOLs - %d\n", res);
|
||||
tests_failed += (res - 1);
|
||||
@@ -767,7 +605,7 @@ int main(int argc, char *argv[])
|
||||
end_of_page = t4_rx_put(receive_state, block, len);
|
||||
}
|
||||
while (len > 0);
|
||||
/* Some decoders require a few extra bits before the recognise the end
|
||||
/* Some decoders require a few extra bits before they recognise the end
|
||||
of an image, so be prepared to offer it a few. */
|
||||
while (end_of_page != T4_DECODE_OK)
|
||||
{
|
||||
|
||||
@@ -54,8 +54,8 @@ static int test_vec_copyf(void)
|
||||
for (i = 0; i < 99; i++)
|
||||
{
|
||||
x[i] = i;
|
||||
za[i] = -1.0f;
|
||||
zb[i] = -1.0f;
|
||||
za[i] = -0.5f;
|
||||
zb[i] = -0.5f;
|
||||
}
|
||||
vec_copyf_dumb(za + 3, x + 1, 0);
|
||||
vec_copyf(zb + 3, x + 1, 0);
|
||||
@@ -114,8 +114,8 @@ static int test_vec_negatef(void)
|
||||
for (i = 0; i < 99; i++)
|
||||
{
|
||||
x[i] = i;
|
||||
za[i] = -1.0f;
|
||||
zb[i] = -1.0f;
|
||||
za[i] = -0.5f;
|
||||
zb[i] = -0.5f;
|
||||
}
|
||||
vec_negatef_dumb(za + 3, x + 1, 0);
|
||||
vec_negatef(zb + 3, x + 1, 0);
|
||||
@@ -143,6 +143,7 @@ static int test_vec_negatef(void)
|
||||
vec_negatef(zb + 3, x + 1, 29);
|
||||
for (i = 0; i < 99; i++)
|
||||
{
|
||||
printf("C %d %f %f %f\n", i, x[i], za[i], zb[i]);
|
||||
if (za[i] != zb[i])
|
||||
{
|
||||
printf("vec_negatef() - %d %f %f\n", i, za[i], zb[i]);
|
||||
|
||||
@@ -240,6 +240,7 @@ struct switch_runtime {
|
||||
uint32_t sps_total;
|
||||
int32_t sps;
|
||||
int32_t sps_last;
|
||||
int32_t sps_peak;
|
||||
switch_log_level_t hard_log_level;
|
||||
char *mailer_app;
|
||||
char *mailer_app_args;
|
||||
|
||||
@@ -1967,6 +1967,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_check_results(switch_asr_handle_
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_get_results(switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags);
|
||||
|
||||
/*!
|
||||
\brief Get result headers from an asr handle
|
||||
\param ah the handle to get results from
|
||||
\param headers a pointer to dynamically allocate an switch_event_t result to
|
||||
\param flags flags to influence behaviour
|
||||
\return SWITCH_STATUS_SUCCESS
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_get_result_headers(switch_asr_handle_t *ah, switch_event_t **headers, switch_asr_flag_t *flags);
|
||||
|
||||
/*!
|
||||
\brief Load a grammar to an asr handle
|
||||
\param ah the handle to load to
|
||||
|
||||
@@ -184,6 +184,18 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_and_detect_speech(switch_core_se
|
||||
switch_input_args_t *args);
|
||||
|
||||
|
||||
/*!
|
||||
\brief Initialize background Speech detection on a session, so that parameters can be set, and grammars loaded.
|
||||
After calling this function, it is possible to call switch_ivr_set_param_detect_speech() to set recognition parameters.
|
||||
Calling switch_ivr_detect_speech_load_grammar() starts the speech recognition.
|
||||
\param session the session to attach
|
||||
\param mod_name the module name of the ASR library
|
||||
\param dest the destination address
|
||||
\param ah an ASR handle to use (NULL to create one)
|
||||
\return SWITCH_STATUS_SUCCESS if all is well
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_init(switch_core_session_t *session, const char *mod_name,
|
||||
const char *dest, switch_asr_handle_t *ah);
|
||||
/*!
|
||||
\brief Engage background Speech detection on a session
|
||||
\param session the session to attach
|
||||
@@ -934,6 +946,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say_ip(switch_core_session_t *session
|
||||
switch_input_args_t *args);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *session, const char *data);
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_set_user_xml(switch_core_session_t *session, const char *prefix,
|
||||
const char *user, const char *domain, switch_xml_t x_user);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_sound_test(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(void) switch_process_import(switch_core_session_t *session, switch_channel_t *peer_channel, const char *varname, const char *prefix);
|
||||
SWITCH_DECLARE(switch_bool_t) switch_ivr_uuid_exists(const char *uuid);
|
||||
|
||||
@@ -377,6 +377,8 @@ struct switch_asr_interface {
|
||||
switch_status_t (*asr_check_results) (switch_asr_handle_t *ah, switch_asr_flag_t *flags);
|
||||
/*! function to read results from the ASR */
|
||||
switch_status_t (*asr_get_results) (switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags);
|
||||
/*! function to read result headers from the ASR */
|
||||
switch_status_t (*asr_get_result_headers) (switch_asr_handle_t *ah, switch_event_t **headers, switch_asr_flag_t *flags);
|
||||
/*! function to start ASR input timers */
|
||||
switch_status_t (*asr_start_input_timers) (switch_asr_handle_t *ah);
|
||||
void (*asr_text_param) (switch_asr_handle_t *ah, char *param, const char *val);
|
||||
|
||||
@@ -1887,7 +1887,8 @@ typedef enum {
|
||||
SCSC_DEBUG_SQL,
|
||||
SCSC_SQL,
|
||||
SCSC_API_EXPANSION,
|
||||
SCSC_RECOVER
|
||||
SCSC_RECOVER,
|
||||
SCSC_SPS_PEAK
|
||||
} switch_session_ctl_t;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -2012,7 +2012,7 @@ SWITCH_STANDARD_API(lan_addr_function)
|
||||
SWITCH_STANDARD_API(status_function)
|
||||
{
|
||||
switch_core_time_duration_t duration = { 0 };
|
||||
int sps = 0, last_sps = 0;
|
||||
int sps = 0, last_sps = 0, max_sps = 0;
|
||||
switch_bool_t html = SWITCH_FALSE; /* shortcut to format.html */
|
||||
char * nl = "\n"; /* shortcut to format.nl */
|
||||
stream_format format = { 0 };
|
||||
@@ -2058,7 +2058,8 @@ SWITCH_STANDARD_API(status_function)
|
||||
stream->write_function(stream, "%" SWITCH_SIZE_T_FMT " session(s) since startup%s", switch_core_session_id() - 1, nl);
|
||||
switch_core_session_ctl(SCSC_LAST_SPS, &last_sps);
|
||||
switch_core_session_ctl(SCSC_SPS, &sps);
|
||||
stream->write_function(stream, "%d session(s) - %d out of max %d per sec %s", switch_core_session_count(), last_sps, sps, nl);
|
||||
switch_core_session_ctl(SCSC_SPS_PEAK, &max_sps);
|
||||
stream->write_function(stream, "%d session(s) - %d out of max %d per sec peak %d %s", switch_core_session_count(), last_sps, sps, max_sps, nl);
|
||||
stream->write_function(stream, "%d session(s) max%s", switch_core_session_limit(0), nl);
|
||||
stream->write_function(stream, "min idle cpu %0.2f/%0.2f%s", switch_core_min_idle_cpu(-1.0), switch_core_idle_cpu(), nl);
|
||||
|
||||
@@ -2067,7 +2068,7 @@ SWITCH_STANDARD_API(status_function)
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define CTL_SYNTAX "[recover|send_sighup|hupall|pause [inbound|outbound]|resume [inbound|outbound]|shutdown [cancel|elegant|asap|now|restart]|sps|sync_clock|sync_clock_when_idle|reclaim_mem|max_sessions|min_dtmf_duration [num]|max_dtmf_duration [num]|default_dtmf_duration [num]|min_idle_cpu|loglevel [level]|debug_level [level]]"
|
||||
#define CTL_SYNTAX "[recover|send_sighup|hupall|pause [inbound|outbound]|resume [inbound|outbound]|shutdown [cancel|elegant|asap|now|restart]|sps|sps_peak_reset|sync_clock|sync_clock_when_idle|reclaim_mem|max_sessions|min_dtmf_duration [num]|max_dtmf_duration [num]|default_dtmf_duration [num]|min_idle_cpu|loglevel [level]|debug_level [level]]"
|
||||
SWITCH_STANDARD_API(ctl_function)
|
||||
{
|
||||
int argc;
|
||||
@@ -2289,6 +2290,10 @@ SWITCH_STANDARD_API(ctl_function)
|
||||
switch_core_session_ctl(SCSC_DEBUG_LEVEL, &arg);
|
||||
stream->write_function(stream, "+OK DEBUG level: %d\n", arg);
|
||||
|
||||
} else if (!strcasecmp(argv[0], "sps_peak_reset")) {
|
||||
arg = -1;
|
||||
switch_core_session_ctl(SCSC_SPS_PEAK, &arg);
|
||||
stream->write_function(stream, "+OK max sessions per second counter reset\n");
|
||||
} else if (!strcasecmp(argv[0], "last_sps")) {
|
||||
switch_core_session_ctl(SCSC_LAST_SPS, &arg);
|
||||
stream->write_function(stream, "+OK last sessions per second: %d\n", arg);
|
||||
|
||||
@@ -202,7 +202,8 @@ typedef enum {
|
||||
CFLAG_AUDIO_ALWAYS = (1 << 15),
|
||||
CFLAG_ENDCONF_FORCED = (1 << 16),
|
||||
CFLAG_RFC4579 = (1 << 17),
|
||||
CFLAG_FLOOR_CHANGE = (1 << 18)
|
||||
CFLAG_FLOOR_CHANGE = (1 << 18),
|
||||
CFLAG_VID_FLOOR_LOCK = (1 << 19)
|
||||
} conf_flag_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -1454,10 +1455,10 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe
|
||||
switch_channel_set_variable(channel, "conference_recording", conference->record_filename);
|
||||
switch_channel_set_variable(channel, CONFERENCE_UUID_VARIABLE, conference->uuid_str);
|
||||
|
||||
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_VIDEO)) {
|
||||
if (!switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)) {
|
||||
if (switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)) {
|
||||
switch_channel_set_flag(channel, CF_VIDEO_ECHO);
|
||||
} else {
|
||||
switch_channel_clear_flag(channel, CF_VIDEO_ECHO);
|
||||
}
|
||||
/* Tell the channel to request a fresh vid frame */
|
||||
@@ -1576,32 +1577,62 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe
|
||||
return status;
|
||||
}
|
||||
|
||||
static void conference_set_video_floor_holder(conference_obj_t *conference, conference_member_t *member)
|
||||
static void conference_set_video_floor_holder(conference_obj_t *conference, conference_member_t *member, switch_bool_t force)
|
||||
{
|
||||
switch_event_t *event;
|
||||
conference_member_t *old_member = NULL;
|
||||
int old_id = 0;
|
||||
|
||||
if (switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)) {
|
||||
if (!member) {
|
||||
switch_clear_flag(conference, CFLAG_VID_FLOOR_LOCK);
|
||||
}
|
||||
|
||||
if (switch_test_flag(conference, CFLAG_VIDEO_BRIDGE) || (!force && switch_test_flag(conference, CFLAG_VID_FLOOR_LOCK))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (conference->video_floor_holder) {
|
||||
if (conference->video_floor_holder == member) {
|
||||
return;
|
||||
} else {
|
||||
old_id = conference->video_floor_holder->id;
|
||||
switch_channel_clear_flag(conference->video_floor_holder->channel, CF_VIDEO_PASSIVE);
|
||||
switch_core_session_refresh_video(conference->video_floor_holder->session);
|
||||
} else {
|
||||
old_member = conference->video_floor_holder;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Dropping video floor %s\n",
|
||||
switch_channel_get_name(old_member->channel));
|
||||
}
|
||||
}
|
||||
|
||||
if ((conference->video_floor_holder = member)) {
|
||||
switch_channel_set_flag(member->channel, CF_VIDEO_PASSIVE);
|
||||
switch_core_session_refresh_video(conference->video_floor_holder->session);
|
||||
switch_set_flag(conference, CFLAG_FLOOR_CHANGE);
|
||||
|
||||
switch_mutex_lock(conference->mutex);
|
||||
if (!member) {
|
||||
conference_member_t *imember;
|
||||
|
||||
for (imember = conference->members; imember; imember = imember->next) {
|
||||
if (imember != conference->video_floor_holder && switch_channel_test_flag(imember->channel, CF_VIDEO)) {
|
||||
member = imember;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (old_id > -1 && test_eflag(conference, EFLAG_FLOOR_CHANGE)) {
|
||||
if (member) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Adding video floor %s\n",
|
||||
switch_channel_get_name(member->channel));
|
||||
switch_channel_set_flag(member->channel, CF_VIDEO_PASSIVE);
|
||||
switch_core_session_refresh_video(member->session);
|
||||
conference->video_floor_holder = member;
|
||||
} else {
|
||||
conference->video_floor_holder = NULL;
|
||||
}
|
||||
|
||||
if (old_member) {
|
||||
old_id = old_member->id;
|
||||
switch_channel_clear_flag(old_member->channel, CF_VIDEO_PASSIVE);
|
||||
}
|
||||
|
||||
switch_set_flag(conference, CFLAG_FLOOR_CHANGE);
|
||||
switch_mutex_unlock(conference->mutex);
|
||||
|
||||
if (test_eflag(conference, EFLAG_FLOOR_CHANGE)) {
|
||||
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT);
|
||||
conference_add_event_data(conference, event);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "video-floor-change");
|
||||
@@ -1623,29 +1654,44 @@ static void conference_set_video_floor_holder(conference_obj_t *conference, conf
|
||||
static void conference_set_floor_holder(conference_obj_t *conference, conference_member_t *member)
|
||||
{
|
||||
switch_event_t *event;
|
||||
conference_member_t *old_member = NULL;
|
||||
int old_id = 0;
|
||||
|
||||
if (!switch_test_flag(conference, CFLAG_VIDEO_BRIDGE) &&
|
||||
((conference->video_floor_holder && !member) || (member && switch_channel_test_flag(member->channel, CF_VIDEO)))) {
|
||||
conference_set_video_floor_holder(conference, member, SWITCH_FALSE);
|
||||
}
|
||||
|
||||
if (conference->floor_holder) {
|
||||
if (conference->floor_holder == member) {
|
||||
return;
|
||||
} else {
|
||||
old_id = conference->floor_holder->id;
|
||||
if (!conference->video_floor_holder && !switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)) {
|
||||
switch_channel_clear_flag(conference->floor_holder->channel, CF_VIDEO_PASSIVE);
|
||||
switch_core_session_refresh_video(conference->floor_holder->session);
|
||||
}
|
||||
old_member = conference->floor_holder;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Dropping floor %s\n",
|
||||
switch_channel_get_name(old_member->channel));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((conference->floor_holder = member)) {
|
||||
if (!conference->video_floor_holder && !switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)) {
|
||||
switch_channel_set_flag(member->channel, CF_VIDEO_PASSIVE);
|
||||
switch_core_session_refresh_video(conference->floor_holder->session);
|
||||
}
|
||||
switch_set_flag(conference, CFLAG_FLOOR_CHANGE);
|
||||
switch_mutex_lock(conference->mutex);
|
||||
if (member) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Adding floor %s\n",
|
||||
switch_channel_get_name(member->channel));
|
||||
|
||||
conference->floor_holder = member;
|
||||
} else {
|
||||
conference->floor_holder = NULL;
|
||||
}
|
||||
|
||||
if (old_id > -1 && test_eflag(conference, EFLAG_FLOOR_CHANGE)) {
|
||||
|
||||
if (old_member) {
|
||||
old_id = old_member->id;
|
||||
}
|
||||
|
||||
switch_set_flag(conference, CFLAG_FLOOR_CHANGE);
|
||||
switch_mutex_unlock(conference->mutex);
|
||||
|
||||
if (test_eflag(conference, EFLAG_FLOOR_CHANGE)) {
|
||||
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT);
|
||||
conference_add_event_data(conference, event);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "floor-change");
|
||||
@@ -1754,7 +1800,7 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe
|
||||
|
||||
|
||||
if (member == member->conference->video_floor_holder) {
|
||||
conference_set_video_floor_holder(member->conference, NULL);
|
||||
conference_set_video_floor_holder(member->conference, NULL, SWITCH_TRUE);
|
||||
}
|
||||
|
||||
member->conference = NULL;
|
||||
@@ -1770,11 +1816,6 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe
|
||||
}
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_VIDEO)) {
|
||||
switch_channel_set_flag(channel, CF_VIDEO_ECHO);
|
||||
switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE);
|
||||
}
|
||||
|
||||
conference_send_presence(conference);
|
||||
switch_channel_set_variable(channel, "conference_call_key", NULL);
|
||||
|
||||
@@ -1906,7 +1947,7 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr
|
||||
if (conference->video_floor_holder) {
|
||||
floor_holder = conference->video_floor_holder;
|
||||
} else {
|
||||
floor_holder = conference->floor_holder;
|
||||
floor_holder = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1915,7 +1956,7 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr
|
||||
goto do_continue;
|
||||
}
|
||||
|
||||
if (!switch_channel_test_flag(switch_core_session_get_channel(floor_holder->session), CF_VIDEO)) {
|
||||
if (!floor_holder->session || !floor_holder->channel || !switch_channel_test_flag(floor_holder->channel, CF_VIDEO)) {
|
||||
yield = 100000;
|
||||
goto do_continue;
|
||||
}
|
||||
@@ -2065,8 +2106,8 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
|
||||
if (switch_test_flag(imember, MFLAG_RUNNING) && imember->session) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(imember->session);
|
||||
|
||||
if ((!floor_holder || (imember->score_iir > SCORE_IIR_SPEAKING_MAX && (floor_holder->score_iir < SCORE_IIR_SPEAKING_MIN))) &&
|
||||
(!switch_test_flag(conference, CFLAG_VID_FLOOR) || switch_channel_test_flag(channel, CF_VIDEO))) {
|
||||
if ((!floor_holder || (imember->score_iir > SCORE_IIR_SPEAKING_MAX && (floor_holder->score_iir < SCORE_IIR_SPEAKING_MIN)))) {// &&
|
||||
//(!switch_test_flag(conference, CFLAG_VID_FLOOR) || switch_channel_test_flag(channel, CF_VIDEO))) {
|
||||
floor_holder = imember;
|
||||
}
|
||||
|
||||
@@ -5273,7 +5314,8 @@ static switch_status_t conf_api_sub_clear_vid_floor(conference_obj_t *conference
|
||||
}
|
||||
|
||||
switch_mutex_lock(conference->mutex);
|
||||
conference_set_video_floor_holder(conference, NULL);
|
||||
switch_clear_flag(conference, CFLAG_VID_FLOOR_LOCK);
|
||||
//conference_set_video_floor_holder(conference, NULL);
|
||||
switch_mutex_unlock(conference->mutex);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
@@ -5286,8 +5328,13 @@ static switch_status_t conf_api_sub_vid_floor(conference_member_t *member, switc
|
||||
if (member == NULL)
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
if (!switch_channel_test_flag(member->channel, CF_VIDEO)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Channel %s does not have video capability!\n", switch_channel_get_name(member->channel));
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_test_flag(member->conference, CFLAG_VIDEO_BRIDGE)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
||||
"conference %s is in video bridge mode, this functionality is not compatible\n", member->conference->name);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
@@ -5298,19 +5345,22 @@ static switch_status_t conf_api_sub_vid_floor(conference_member_t *member, switc
|
||||
force = 1;
|
||||
}
|
||||
|
||||
if (!force && member->conference->video_floor_holder == member) {
|
||||
conference_set_video_floor_holder(member->conference, NULL);
|
||||
if (member->conference->video_floor_holder == member && switch_test_flag(member->conference, CFLAG_VID_FLOOR_LOCK)) {
|
||||
switch_clear_flag(member->conference, CFLAG_VID_FLOOR_LOCK);
|
||||
|
||||
conference_set_floor_holder(member->conference, member);
|
||||
if (stream == NULL) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "conference %s OK floor none\n", member->conference->name);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "conference %s OK video floor auto\n", member->conference->name);
|
||||
} else {
|
||||
stream->write_function(stream, "OK floor none\n");
|
||||
}
|
||||
|
||||
} else if (force || member->conference->video_floor_holder == NULL) {
|
||||
conference_set_video_floor_holder(member->conference, member);
|
||||
switch_set_flag(member->conference, CFLAG_VID_FLOOR_LOCK);
|
||||
conference_set_video_floor_holder(member->conference, member, SWITCH_TRUE);
|
||||
if (test_eflag(member->conference, EFLAG_FLOOR_CHANGE)) {
|
||||
if (stream == NULL) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "conference %s OK floor %d %s\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "conference %s OK video floor %d %s\n",
|
||||
member->conference->name, member->id, switch_channel_get_name(member->channel));
|
||||
} else {
|
||||
stream->write_function(stream, "OK floor %u\n", member->id);
|
||||
@@ -7725,7 +7775,9 @@ SWITCH_STANDARD_APP(conference_function)
|
||||
}
|
||||
|
||||
while (!pin_valid && pin_retries && status == SWITCH_STATUS_SUCCESS) {
|
||||
int maxpin = strlen(dpin) > strlen(mdpin) ? strlen(dpin) : strlen(mdpin);
|
||||
size_t dpin_length = dpin ? strlen(dpin) : 0;
|
||||
size_t mdpin_length = mdpin ? strlen(mdpin) : 0;
|
||||
int maxpin = dpin_length > mdpin_length ? dpin_length : mdpin_length;
|
||||
switch_status_t pstatus = SWITCH_STATUS_FALSE;
|
||||
|
||||
/* be friendly */
|
||||
|
||||
@@ -445,6 +445,8 @@ SWITCH_STANDARD_APP(detect_speech_function)
|
||||
switch_ivr_detect_speech_disable_grammar(session, argv[1]);
|
||||
} else if (!strcasecmp(argv[0], "grammarsalloff")) {
|
||||
switch_ivr_detect_speech_disable_all_grammars(session);
|
||||
} else if (!strcasecmp(argv[0], "init")) {
|
||||
switch_ivr_detect_speech_init(session, argv[1], argv[2], NULL);
|
||||
} else if (!strcasecmp(argv[0], "pause")) {
|
||||
switch_ivr_pause_detect_speech(session);
|
||||
} else if (!strcasecmp(argv[0], "resume")) {
|
||||
|
||||
@@ -4069,6 +4069,8 @@ static switch_status_t load_config(int reload, int del_all)
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
|
||||
}
|
||||
} else if (!strcasecmp(var, "dbname") && !zstr(val)) {
|
||||
globals.dbname = switch_core_strdup(globals.pool, val);
|
||||
} else if (!strcasecmp(var, "allow-transcoding") && !zstr(val)) {
|
||||
globals.allow_transcoding = switch_true(val);
|
||||
} else if (!strcasecmp(var, "db-pre-trans-execute") && !zstr(val)) {
|
||||
|
||||
@@ -1002,6 +1002,7 @@ static switch_bool_t test_profile(char *lcr_profile)
|
||||
callback_t routes = { 0 };
|
||||
switch_memory_pool_t *pool = NULL;
|
||||
switch_event_t *event = NULL;
|
||||
switch_bool_t r;
|
||||
|
||||
switch_core_new_memory_pool(&pool);
|
||||
switch_event_create(&event, SWITCH_EVENT_MESSAGE);
|
||||
@@ -1016,8 +1017,11 @@ static switch_bool_t test_profile(char *lcr_profile)
|
||||
routes.lookup_number = "15555551212";
|
||||
routes.cid = "18005551212";
|
||||
lcr_destroy(routes.head);
|
||||
return (lcr_do_lookup(&routes) == SWITCH_STATUS_SUCCESS) ?
|
||||
SWITCH_TRUE : SWITCH_FALSE;
|
||||
|
||||
r = (lcr_do_lookup(&routes) == SWITCH_STATUS_SUCCESS) ? SWITCH_TRUE : SWITCH_FALSE;
|
||||
switch_event_destroy(&event);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static switch_status_t lcr_load_config()
|
||||
|
||||
@@ -1672,6 +1672,9 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
|
||||
char vm_cc[256] = "";
|
||||
char macro_buf[80] = "";
|
||||
|
||||
switch_xml_t xml_root, x_domain, x_param, x_params, x_user = NULL;
|
||||
switch_event_t *my_params = NULL;
|
||||
switch_bool_t vm_enabled = SWITCH_TRUE;
|
||||
|
||||
switch_snprintf(key_buf, sizeof(key_buf), "%s:%s", profile->prepend_key, profile->forward_key);
|
||||
TRY_CODE(vm_macro_get(session, VM_FORWARD_PREPEND_MACRO, key_buf, input, sizeof(input), 1, "", &term, profile->digit_timeout));
|
||||
@@ -1712,15 +1715,51 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
|
||||
cmd = switch_core_session_sprintf(session, "%s@%s@%s %s %s '%s'", vm_cc, cbt->domain, profile->name,
|
||||
new_file_path, cbt->cid_number, cbt->cid_name);
|
||||
|
||||
if (voicemail_inject(cmd, session) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Sent Carbon Copy to %s\n", vm_cc);
|
||||
TRY_CODE(switch_ivr_phrase_macro(session, VM_ACK_MACRO, "saved", NULL, NULL));
|
||||
cbt->move = VM_MOVE_SAME;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to Carbon Copy to %s\n", vm_cc);
|
||||
switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS);
|
||||
switch_assert(my_params);
|
||||
|
||||
if (switch_xml_locate_domain(cbt->domain, my_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to forward message - Cannot locate domain %s\n", cbt->domain);
|
||||
TRY_CODE(switch_ivr_phrase_macro(session, VM_INVALID_EXTENSION_MACRO, vm_cc, NULL, NULL));
|
||||
goto get_exten;
|
||||
} else if (switch_xml_locate_user_in_domain(vm_cc, x_domain, &x_user, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to forward message - Cannot locate user %s@%s\n", vm_cc, cbt->domain);
|
||||
TRY_CODE(switch_ivr_phrase_macro(session, VM_INVALID_EXTENSION_MACRO, vm_cc, NULL, NULL));
|
||||
goto get_exten;
|
||||
} else {
|
||||
x_params = switch_xml_child(x_user, "params");
|
||||
|
||||
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
|
||||
const char *var = switch_xml_attr_soft(x_param, "name");
|
||||
const char *val = switch_xml_attr_soft(x_param, "value");
|
||||
if (zstr(var) || zstr(val)) {
|
||||
continue; /* Ignore empty entires */
|
||||
}
|
||||
|
||||
if (!strcasecmp(var, "vm-enabled")) {
|
||||
vm_enabled = !switch_false(val);
|
||||
}
|
||||
}
|
||||
|
||||
if (!vm_enabled) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to forward message - Voicemail is disabled for user %s@%s\n", vm_cc, cbt->domain);
|
||||
TRY_CODE(switch_ivr_phrase_macro(session, VM_INVALID_EXTENSION_MACRO, vm_cc, NULL, NULL));
|
||||
goto get_exten;
|
||||
} else {
|
||||
if (voicemail_inject(cmd, session) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Forwarded message to %s\n", vm_cc);
|
||||
TRY_CODE(switch_ivr_phrase_macro(session, VM_ACK_MACRO, "saved", NULL, NULL));
|
||||
cbt->move = VM_MOVE_SAME;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to forward message to %s\n", vm_cc);
|
||||
TRY_CODE(switch_ivr_phrase_macro(session, VM_INVALID_EXTENSION_MACRO, vm_cc, NULL, NULL));
|
||||
goto get_exten;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch_xml_free(xml_root);
|
||||
switch_event_destroy(&my_params);
|
||||
} else if (!strcmp(input, profile->delete_file_key) || (!strcmp(input, profile->email_key) && !zstr(cbt->email))) {
|
||||
char *sql = switch_mprintf("update voicemail_msgs set flags='delete' where uuid='%s'", cbt->uuid);
|
||||
vm_execute_sql(profile, sql, profile->mutex);
|
||||
|
||||
@@ -450,6 +450,8 @@ struct recognizer_data {
|
||||
switch_hash_t *enabled_grammars;
|
||||
/** recognize result */
|
||||
char *result;
|
||||
/** recognize result headers */
|
||||
switch_event_t *result_headers;
|
||||
/** true, if voice has started */
|
||||
int start_of_input;
|
||||
/** true, if input timers have started */
|
||||
@@ -483,6 +485,7 @@ static switch_status_t recog_asr_resume(switch_asr_handle_t *ah);
|
||||
static switch_status_t recog_asr_pause(switch_asr_handle_t *ah);
|
||||
static switch_status_t recog_asr_check_results(switch_asr_handle_t *ah, switch_asr_flag_t *flags);
|
||||
static switch_status_t recog_asr_get_results(switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags);
|
||||
static switch_status_t recog_asr_get_result_headers(switch_asr_handle_t *ah, switch_event_t **headers, switch_asr_flag_t *flags);
|
||||
static switch_status_t recog_asr_start_input_timers(switch_asr_handle_t *ah);
|
||||
static void recog_asr_text_param(switch_asr_handle_t *ah, char *param, const char *val);
|
||||
static void recog_asr_numeric_param(switch_asr_handle_t *ah, char *param, int val);
|
||||
@@ -505,7 +508,9 @@ static switch_status_t recog_channel_check_results(speech_channel_t *schannel);
|
||||
static switch_status_t recog_channel_set_start_of_input(speech_channel_t *schannel);
|
||||
static switch_status_t recog_channel_start_input_timers(speech_channel_t *schannel);
|
||||
static switch_status_t recog_channel_set_results(speech_channel_t *schannel, const char *results);
|
||||
static switch_status_t recog_channel_set_result_headers(speech_channel_t *schannel, mrcp_recog_header_t *recog_hdr);
|
||||
static switch_status_t recog_channel_get_results(speech_channel_t *schannel, char **results);
|
||||
static switch_status_t recog_channel_get_result_headers(speech_channel_t *schannel, switch_event_t **result_headers);
|
||||
static switch_status_t recog_channel_set_params(speech_channel_t *schannel, mrcp_message_t *msg, mrcp_generic_header_t *gen_hdr,
|
||||
mrcp_recog_header_t *recog_hdr);
|
||||
static switch_status_t recog_channel_set_header(speech_channel_t *schannel, int id, char *val, mrcp_message_t *msg, mrcp_recog_header_t *recog_hdr);
|
||||
@@ -2156,9 +2161,9 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel)
|
||||
recognizer_data_t *r;
|
||||
char *start_input_timers;
|
||||
const char *mime_type;
|
||||
char *key;
|
||||
char *key = NULL;
|
||||
switch_size_t len;
|
||||
grammar_t *grammar;
|
||||
grammar_t *grammar = NULL;
|
||||
switch_size_t grammar_uri_count = 0;
|
||||
switch_size_t grammar_uri_list_len = 0;
|
||||
char *grammar_uri_list = NULL;
|
||||
@@ -2176,6 +2181,9 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel)
|
||||
}
|
||||
r = (recognizer_data_t *) schannel->data;
|
||||
r->result = NULL;
|
||||
if (r->result_headers) {
|
||||
switch_event_destroy(&r->result_headers);
|
||||
}
|
||||
r->start_of_input = 0;
|
||||
|
||||
/* input timers are started by default unless the start-input-timers=false param is set */
|
||||
@@ -2598,6 +2606,141 @@ static switch_status_t recog_channel_set_results(speech_channel_t *schannel, con
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a parameter from a ;-separated string
|
||||
*
|
||||
* @param str the input string to find data in
|
||||
* @param param the parameter to to look for
|
||||
* @return a pointer in the str if successful, or NULL.
|
||||
*/
|
||||
static char *find_parameter(const char *str, const char *param)
|
||||
{
|
||||
char *ptr = (char *) str;
|
||||
|
||||
while (ptr) {
|
||||
if (!strncasecmp(ptr, param, strlen(param)))
|
||||
return ptr;
|
||||
|
||||
if ((ptr = strchr(ptr, ';')))
|
||||
ptr++;
|
||||
|
||||
while (ptr && *ptr == ' ') {
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a parameter value from a ;-separated string
|
||||
*
|
||||
* @param str the input string to parse data from
|
||||
* @param param the parameter to to look for
|
||||
* @return a malloc'ed char* if successful, or NULL.
|
||||
*/
|
||||
static char *get_parameter_value(const char *str, const char *param)
|
||||
{
|
||||
const char *param_ptr;
|
||||
char *param_value = NULL;
|
||||
char *tmp;
|
||||
switch_size_t param_len;
|
||||
char *param_tmp;
|
||||
|
||||
if (zstr(str) || zstr(param)) return NULL;
|
||||
|
||||
/* Append "=" to the end of the string */
|
||||
param_tmp = switch_mprintf("%s=", param);
|
||||
if (!param_tmp) return NULL;
|
||||
param = param_tmp;
|
||||
|
||||
param_len = strlen(param);
|
||||
param_ptr = find_parameter(str, param);
|
||||
|
||||
if (zstr(param_ptr)) goto fail;
|
||||
|
||||
param_value = strdup(param_ptr + param_len);
|
||||
|
||||
if (zstr(param_value)) goto fail;
|
||||
|
||||
if ((tmp = strchr(param_value, ';'))) *tmp = '\0';
|
||||
|
||||
switch_safe_free(param_tmp);
|
||||
return param_value;
|
||||
|
||||
fail:
|
||||
switch_safe_free(param_tmp);
|
||||
switch_safe_free(param_value);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the recognition result headers
|
||||
*
|
||||
* @param schannel the channel whose results are set
|
||||
* @param recog_hdr the recognition headers
|
||||
* @return SWITCH_STATUS_SUCCESS if successful
|
||||
*/
|
||||
static switch_status_t recog_channel_set_result_headers(speech_channel_t *schannel, mrcp_recog_header_t *recog_hdr)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
recognizer_data_t *r;
|
||||
|
||||
switch_mutex_lock(schannel->mutex);
|
||||
|
||||
r = (recognizer_data_t *) schannel->data;
|
||||
|
||||
if (r->result_headers) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) result headers are already set\n", schannel->name);
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!recog_hdr) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) result headers are NULL\n", schannel->name);
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) ASR adding result headers\n", schannel->name);
|
||||
|
||||
if ((status = switch_event_create(&r->result_headers, SWITCH_EVENT_CLONE)) == SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
switch_event_add_header(r->result_headers, SWITCH_STACK_BOTTOM, "ASR-Completion-Cause", "%d", recog_hdr->completion_cause);
|
||||
|
||||
if (!zstr(recog_hdr->completion_reason.buf)) {
|
||||
switch_event_add_header_string(r->result_headers, SWITCH_STACK_BOTTOM, "ASR-Completion-Reason", recog_hdr->completion_reason.buf);
|
||||
}
|
||||
|
||||
if (!zstr(recog_hdr->waveform_uri.buf)) {
|
||||
char *tmp;
|
||||
|
||||
if ((tmp = strdup(recog_hdr->waveform_uri.buf))) {
|
||||
char *tmp2;
|
||||
if ((tmp2 = strchr(tmp, ';'))) *tmp2 = '\0';
|
||||
switch_event_add_header_string(r->result_headers, SWITCH_STACK_BOTTOM, "ASR-Waveform-URI", tmp);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
if ((tmp = get_parameter_value(recog_hdr->waveform_uri.buf, "size"))) {
|
||||
switch_event_add_header_string(r->result_headers, SWITCH_STACK_BOTTOM, "ASR-Waveform-Size", tmp);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
if ((tmp = get_parameter_value(recog_hdr->waveform_uri.buf, "duration"))) {
|
||||
switch_event_add_header_string(r->result_headers, SWITCH_STACK_BOTTOM, "ASR-Waveform-Duration", tmp);
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
switch_mutex_unlock(schannel->mutex);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the recognition results.
|
||||
*
|
||||
@@ -2627,6 +2770,29 @@ static switch_status_t recog_channel_get_results(speech_channel_t *schannel, cha
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the recognition result headers.
|
||||
*
|
||||
* @param schannel the channel to get results from
|
||||
* @param result_headers the recognition result headers. switch_event_destroy() the results when finished with them.
|
||||
* @return SWITCH_STATUS_SUCCESS will always be returned, since this is just optional data.
|
||||
*/
|
||||
static switch_status_t recog_channel_get_result_headers(speech_channel_t *schannel, switch_event_t **result_headers)
|
||||
{
|
||||
recognizer_data_t *r = (recognizer_data_t *) schannel->data;
|
||||
|
||||
switch_mutex_lock(schannel->mutex);
|
||||
|
||||
if (r->result_headers && result_headers) {
|
||||
*result_headers = r->result_headers;
|
||||
r->result_headers = NULL;
|
||||
}
|
||||
|
||||
switch_mutex_unlock(schannel->mutex);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parameters in a recognizer MRCP header
|
||||
*
|
||||
@@ -3207,6 +3373,9 @@ static switch_status_t recog_asr_close(switch_asr_handle_t *ah, switch_asr_flag_
|
||||
r->dtmf_generator_active = 0;
|
||||
mpf_dtmf_generator_destroy(r->dtmf_generator);
|
||||
}
|
||||
if (r->result_headers) {
|
||||
switch_event_destroy(&r->result_headers);
|
||||
}
|
||||
switch_mutex_unlock(schannel->mutex);
|
||||
speech_channel_destroy(schannel);
|
||||
}
|
||||
@@ -3326,6 +3495,19 @@ static switch_status_t recog_asr_get_results(switch_asr_handle_t *ah, char **xml
|
||||
return recog_channel_get_results(schannel, xmlstr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process asr_get_result_headers request from FreeSWITCH. Return the headers back
|
||||
* to FreeSWITCH. FreeSWITCH will switch_event_destroy() the headers.
|
||||
*
|
||||
* @param ah the FreeSWITCH speech recognition handle
|
||||
* @param flags other flags
|
||||
*/
|
||||
static switch_status_t recog_asr_get_result_headers(switch_asr_handle_t *ah, switch_event_t **headers, switch_asr_flag_t *flags)
|
||||
{
|
||||
speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
|
||||
return recog_channel_get_result_headers(schannel, headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send START-INPUT-TIMERS to executing recognition request
|
||||
* @param ah the handle to start timers on
|
||||
@@ -3473,6 +3655,7 @@ static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp
|
||||
recog_hdr->completion_cause);
|
||||
if (message->body.length > 0) {
|
||||
if (message->body.buf[message->body.length - 1] == '\0') {
|
||||
recog_channel_set_result_headers(schannel, recog_hdr);
|
||||
recog_channel_set_results(schannel, message->body.buf);
|
||||
} else {
|
||||
/* string is not null terminated */
|
||||
@@ -3481,11 +3664,13 @@ static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp
|
||||
"(%s) Recognition result is not null-terminated. Appending null terminator.\n", schannel->name);
|
||||
strncpy(result, message->body.buf, message->body.length);
|
||||
result[message->body.length] = '\0';
|
||||
recog_channel_set_result_headers(schannel, recog_hdr);
|
||||
recog_channel_set_results(schannel, result);
|
||||
}
|
||||
} else {
|
||||
char *completion_cause = switch_mprintf("Completion-Cause: %03d", recog_hdr->completion_cause);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) No result\n", schannel->name);
|
||||
recog_channel_set_result_headers(schannel, recog_hdr);
|
||||
recog_channel_set_results(schannel, completion_cause);
|
||||
switch_safe_free(completion_cause);
|
||||
}
|
||||
@@ -3584,6 +3769,7 @@ static switch_status_t recog_load(switch_loadable_module_interface_t *module_int
|
||||
asr_interface->asr_pause = recog_asr_pause;
|
||||
asr_interface->asr_check_results = recog_asr_check_results;
|
||||
asr_interface->asr_get_results = recog_asr_get_results;
|
||||
asr_interface->asr_get_result_headers = recog_asr_get_result_headers;
|
||||
asr_interface->asr_start_input_timers = recog_asr_start_input_timers;
|
||||
asr_interface->asr_text_param = recog_asr_text_param;
|
||||
asr_interface->asr_numeric_param = recog_asr_numeric_param;
|
||||
@@ -3620,7 +3806,7 @@ static switch_status_t recog_load(switch_loadable_module_interface_t *module_int
|
||||
switch_core_hash_insert(globals.recog.param_id_map, "N-Best-List-Length", unimrcp_param_id_create(RECOGNIZER_HEADER_N_BEST_LIST_LENGTH, pool));
|
||||
switch_core_hash_insert(globals.recog.param_id_map, "No-Input-Timeout", unimrcp_param_id_create(RECOGNIZER_HEADER_NO_INPUT_TIMEOUT, pool));
|
||||
switch_core_hash_insert(globals.recog.param_id_map, "Recognition-Timeout", unimrcp_param_id_create(RECOGNIZER_HEADER_RECOGNITION_TIMEOUT, pool));
|
||||
switch_core_hash_insert(globals.recog.param_id_map, "Waveform-Url", unimrcp_param_id_create(RECOGNIZER_HEADER_WAVEFORM_URI, pool));
|
||||
switch_core_hash_insert(globals.recog.param_id_map, "Waveform-Uri", unimrcp_param_id_create(RECOGNIZER_HEADER_WAVEFORM_URI, pool));
|
||||
switch_core_hash_insert(globals.recog.param_id_map, "Completion-Cause", unimrcp_param_id_create(RECOGNIZER_HEADER_COMPLETION_CAUSE, pool));
|
||||
switch_core_hash_insert(globals.recog.param_id_map, "Recognizer-Context-Block",
|
||||
unimrcp_param_id_create(RECOGNIZER_HEADER_RECOGNIZER_CONTEXT_BLOCK, pool));
|
||||
|
||||
@@ -888,7 +888,7 @@ void sofia_reg_auth_challenge(sofia_profile_t *profile, nua_handle_t *nh, sofia_
|
||||
auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization,
|
||||
sip_t const *sip,
|
||||
sofia_dispatch_event_t *de, const char *regstr, char *np, size_t nplen, char *ip, switch_event_t **v_event,
|
||||
long exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params, long *reg_count);
|
||||
long exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params, long *reg_count, switch_xml_t *user_xml);
|
||||
|
||||
|
||||
void sofia_reg_handle_sip_r_challenge(int status,
|
||||
@@ -935,7 +935,7 @@ void sofia_glue_do_xfer_invite(switch_core_session_t *session);
|
||||
uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
|
||||
sofia_dispatch_event_t *de,
|
||||
sofia_regtype_t regtype, char *key,
|
||||
uint32_t keylen, switch_event_t **v_event, const char *is_nat, sofia_private_t **sofia_private_p);
|
||||
uint32_t keylen, switch_event_t **v_event, const char *is_nat, sofia_private_t **sofia_private_p, switch_xml_t *user_xml);
|
||||
extern switch_endpoint_interface_t *sofia_endpoint_interface;
|
||||
void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip);
|
||||
switch_status_t sofia_on_hangup(switch_core_session_t *session);
|
||||
|
||||
@@ -1108,7 +1108,7 @@ static void our_sofia_event_callback(nua_event_t event,
|
||||
sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), NULL);
|
||||
auth_res = sofia_reg_parse_auth(profile, authorization, sip, de,
|
||||
(char *) sip->sip_request->rq_method_name, tech_pvt->key, strlen(tech_pvt->key), network_ip, NULL, 0,
|
||||
REG_INVITE, NULL, NULL, NULL);
|
||||
REG_INVITE, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if ((auth_res != AUTH_OK && auth_res != AUTH_RENEWED)) {
|
||||
@@ -2946,8 +2946,9 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
|
||||
sofia_gateway_t *gateway;
|
||||
char *pkey = switch_mprintf("%s::%s", profile->name, name);
|
||||
|
||||
if (zstr(name)) {
|
||||
name = "anonymous";
|
||||
if (zstr(name) || switch_regex_match(name, "^[\\w\\.\\-\\_]+$") != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring invalid name '%s'\n", name ? name : "NULL");
|
||||
goto skip;
|
||||
}
|
||||
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
@@ -5794,6 +5795,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||
switch_channel_get_name(channel), nua_callstate_name(ss_state), status);
|
||||
|
||||
if (r_sdp) {
|
||||
switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp);
|
||||
|
||||
if (!(profile->mndlb & SM_NDLB_ALLOW_NONDUP_SDP) || (!zstr(tech_pvt->mparams.remote_sdp_str) && !strcmp(tech_pvt->mparams.remote_sdp_str, r_sdp))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Duplicate SDP\n%s\n", r_sdp);
|
||||
@@ -5801,7 +5803,6 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp);
|
||||
tech_pvt->mparams.remote_sdp_str = switch_core_session_strdup(session, r_sdp);
|
||||
switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp);
|
||||
|
||||
if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
|
||||
switch_core_media_set_sdp_codec_string(session, r_sdp);
|
||||
@@ -7762,6 +7763,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
|
||||
char network_ip[80];
|
||||
char proxied_client_ip[80];
|
||||
switch_event_t *v_event = NULL;
|
||||
switch_xml_t x_user = NULL;
|
||||
uint32_t sess_count = switch_core_session_count();
|
||||
uint32_t sess_max = switch_core_session_limit(0);
|
||||
int is_auth = 0, calling_myself = 0;
|
||||
@@ -7999,10 +8001,13 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
|
||||
if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) {
|
||||
calling_myself++;
|
||||
} else {
|
||||
if (sofia_reg_handle_register(nua, profile, nh, sip, de, REG_INVITE, key, sizeof(key), &v_event, NULL, NULL)) {
|
||||
if (sofia_reg_handle_register(nua, profile, nh, sip, de, REG_INVITE, key, sizeof(key), &v_event, NULL, NULL, &x_user)) {
|
||||
if (v_event) {
|
||||
switch_event_destroy(&v_event);
|
||||
}
|
||||
if (x_user) {
|
||||
switch_xml_free(x_user);
|
||||
}
|
||||
|
||||
if (sip->sip_authorization || sip->sip_proxy_authorization) {
|
||||
goto fail;
|
||||
@@ -8085,15 +8090,6 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
|
||||
switch_channel_set_variable(channel, "sip_looped_call", "true");
|
||||
}
|
||||
|
||||
if (v_event) {
|
||||
switch_event_header_t *hp;
|
||||
|
||||
for (hp = v_event->headers; hp; hp = hp->next) {
|
||||
switch_channel_set_variable(channel, hp->name, hp->value);
|
||||
}
|
||||
switch_event_destroy(&v_event);
|
||||
}
|
||||
|
||||
if (sip->sip_from && sip->sip_from->a_url) {
|
||||
from_user = sip->sip_from->a_url->url_user;
|
||||
from_host = sip->sip_from->a_url->url_host;
|
||||
@@ -8840,6 +8836,24 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
|
||||
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
|
||||
}
|
||||
|
||||
if (x_user) {
|
||||
const char *user = NULL, *domain = NULL;
|
||||
|
||||
if (v_event) {
|
||||
user = switch_event_get_header(v_event, "username");
|
||||
domain = switch_event_get_header(v_event, "domain_name");
|
||||
}
|
||||
|
||||
switch_ivr_set_user_xml(session, NULL, user, domain, x_user);
|
||||
switch_xml_free(x_user);
|
||||
x_user = NULL;
|
||||
}
|
||||
|
||||
if (v_event) {
|
||||
switch_event_destroy(&v_event);
|
||||
}
|
||||
|
||||
|
||||
tech_pvt->sofia_private = sofia_private;
|
||||
tech_pvt->nh = nh;
|
||||
|
||||
|
||||
@@ -4475,8 +4475,8 @@ void sofia_presence_handle_sip_i_message(int status,
|
||||
sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), NULL);
|
||||
auth_res = sofia_reg_parse_auth(profile, authorization, sip, de,
|
||||
(char *) sip->sip_request->rq_method_name, key, keylen, network_ip, NULL, 0,
|
||||
REG_INVITE, NULL, NULL, NULL);
|
||||
} else if ( sofia_reg_handle_register(nua, profile, nh, sip, de, REG_INVITE, key, keylen, &v_event, NULL, NULL)) {
|
||||
REG_INVITE, NULL, NULL, NULL, NULL);
|
||||
} else if ( sofia_reg_handle_register(nua, profile, nh, sip, de, REG_INVITE, key, keylen, &v_event, NULL, NULL, NULL)) {
|
||||
if (v_event) {
|
||||
switch_event_destroy(&v_event);
|
||||
}
|
||||
|
||||
@@ -1121,7 +1121,7 @@ void sofia_reg_close_handles(sofia_profile_t *profile)
|
||||
|
||||
uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
|
||||
sofia_dispatch_event_t *de, sofia_regtype_t regtype, char *key,
|
||||
uint32_t keylen, switch_event_t **v_event, const char *is_nat, sofia_private_t **sofia_private_p)
|
||||
uint32_t keylen, switch_event_t **v_event, const char *is_nat, sofia_private_t **sofia_private_p, switch_xml_t *user_xml)
|
||||
{
|
||||
sip_to_t const *to = NULL;
|
||||
sip_from_t const *from = NULL;
|
||||
@@ -1135,6 +1135,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
const char *to_host = NULL;
|
||||
char *mwi_account = NULL;
|
||||
char *dup_mwi_account = NULL;
|
||||
char *display_m = NULL;
|
||||
char *mwi_user = NULL;
|
||||
char *mwi_host = NULL;
|
||||
char *var = NULL;
|
||||
@@ -1320,11 +1321,17 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
if (to) {
|
||||
display = to->a_display;
|
||||
if (zstr(display)) {
|
||||
display = "\"user\"";
|
||||
display = "\"\"";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (display && !strchr(display, '"')) {
|
||||
display_m = switch_mprintf("\"%q\"", display);
|
||||
display = display_m;
|
||||
}
|
||||
|
||||
|
||||
if (sip->sip_path) {
|
||||
path_val = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_path);
|
||||
path_encoded_len = (int)(strlen(path_val) * 3) + 1;
|
||||
@@ -1392,7 +1399,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
const char *username = "unknown";
|
||||
const char *realm = reg_host;
|
||||
if ((auth_res = sofia_reg_parse_auth(profile, authorization, sip, de, sip->sip_request->rq_method_name,
|
||||
key, keylen, network_ip, v_event, exptime, regtype, to_user, &auth_params, ®_count)) == AUTH_STALE) {
|
||||
key, keylen, network_ip, v_event, exptime, regtype, to_user, &auth_params, ®_count, user_xml)) == AUTH_STALE) {
|
||||
stale = 1;
|
||||
}
|
||||
|
||||
@@ -2023,6 +2030,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
|
||||
|
||||
end:
|
||||
switch_safe_free(display_m);
|
||||
switch_safe_free(dup_mwi_account);
|
||||
switch_safe_free(utmp);
|
||||
|
||||
@@ -2152,7 +2160,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
|
||||
is_nat = NULL;
|
||||
}
|
||||
|
||||
sofia_reg_handle_register(nua, profile, nh, sip, de, type, key, sizeof(key), &v_event, is_nat, sofia_private_p);
|
||||
sofia_reg_handle_register(nua, profile, nh, sip, de, type, key, sizeof(key), &v_event, is_nat, sofia_private_p, NULL);
|
||||
|
||||
if (v_event) {
|
||||
switch_event_destroy(&v_event);
|
||||
@@ -2459,7 +2467,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
|
||||
size_t nplen,
|
||||
char *ip,
|
||||
switch_event_t **v_event,
|
||||
long exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params, long *reg_count)
|
||||
long exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params, long *reg_count, switch_xml_t *user_xml)
|
||||
{
|
||||
int indexnum;
|
||||
const char *cur;
|
||||
@@ -2883,7 +2891,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
|
||||
|
||||
skip_auth:
|
||||
if (first && (ret == AUTH_OK || ret == AUTH_RENEWED)) {
|
||||
if (v_event) {
|
||||
if (!v_event) {
|
||||
switch_event_create_plain(v_event, SWITCH_EVENT_REQUEST_PARAMS);
|
||||
}
|
||||
|
||||
@@ -3015,7 +3023,11 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
|
||||
switch_event_destroy(¶ms);
|
||||
|
||||
if (user) {
|
||||
switch_xml_free(user);
|
||||
if (user_xml) {
|
||||
*user_xml = user;
|
||||
} else {
|
||||
switch_xml_free(user);
|
||||
}
|
||||
}
|
||||
|
||||
switch_safe_free(input);
|
||||
|
||||
@@ -11,8 +11,10 @@
|
||||
<param name="record-file-prefix" value="$${recordings_dir}/"/>
|
||||
</record>
|
||||
|
||||
<!-- domain to use in from attribute of client messages -->
|
||||
<!-- XMPP server domain -->
|
||||
<domain name="$${rayo_domain_name}" shared-secret="ClueCon">
|
||||
<!-- use this instead if you want secure XMPP client to server connections. Put .crt and .key file in freeswitch/certs -->
|
||||
<!--domain name="$${rayo_domain_name}" shared-secret="ClueCon" cert="$${base_dir}/certs/$${rayo_domain_name}.crt" key="$${base_dir}/certs/$${rayo_domain_name}.key"-->
|
||||
|
||||
<!-- Listeners for new Rayo client connections -->
|
||||
<!--listen type="c2s" port="5222" address="$${local_ip_v4}" acl="rayo-clients"/-->
|
||||
|
||||
@@ -39,8 +39,7 @@
|
||||
#define IKS_NS_XMPP_STANZAS "urn:ietf:params:xml:ns:xmpp-stanzas"
|
||||
#define IKS_NS_XMPP_STREAMS "http://etherx.jabber.org/streams"
|
||||
#define IKS_NS_XMPP_DIALBACK "jabber:server:dialback"
|
||||
#define IKS_NS_BIDI_FEATURE "urn:xmpp:features:bidi"
|
||||
#define IKS_NS_BIDI "urn:xmpp:bidi"
|
||||
#define IKS_NS_XMPP_TLS "urn:ietf:params:xml:ns:xmpp-tls"
|
||||
|
||||
struct xmpp_error {
|
||||
const char *name;
|
||||
|
||||
@@ -3079,6 +3079,8 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_
|
||||
switch_xml_t l;
|
||||
const char *shared_secret = switch_xml_attr_soft(domain, "shared-secret");
|
||||
const char *name = switch_xml_attr_soft(domain, "name");
|
||||
const char *cert = switch_xml_attr_soft(domain, "cert");
|
||||
const char *key = switch_xml_attr_soft(domain, "key");
|
||||
if (zstr(name)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing <domain name=\"... failed to configure rayo server\n");
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
@@ -3093,6 +3095,14 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_
|
||||
globals.xmpp_context = xmpp_stream_context_create(name, shared_secret, on_xmpp_stream_ready, on_xmpp_stream_recv, on_xmpp_stream_destroy);
|
||||
globals.server = rayo_server_create(name);
|
||||
|
||||
/* set up TLS */
|
||||
if (!zstr(cert)) {
|
||||
xmpp_stream_context_add_cert(globals.xmpp_context, cert);
|
||||
}
|
||||
if (!zstr(key)) {
|
||||
xmpp_stream_context_add_key(globals.xmpp_context, key);
|
||||
}
|
||||
|
||||
/* configure authorized users for this domain */
|
||||
l = switch_xml_child(domain, "users");
|
||||
if (l) {
|
||||
@@ -3719,14 +3729,14 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_rayo_shutdown)
|
||||
switch_event_unbind_callback(on_call_end_event);
|
||||
switch_event_unbind_callback(route_mixer_event);
|
||||
|
||||
switch_core_hash_destroy(&globals.command_handlers);
|
||||
switch_core_hash_destroy(&globals.event_handlers);
|
||||
switch_core_hash_destroy(&globals.clients_roster);
|
||||
switch_core_hash_destroy(&globals.actors);
|
||||
switch_core_hash_destroy(&globals.destroy_actors);
|
||||
switch_core_hash_destroy(&globals.actors_by_id);
|
||||
switch_core_hash_destroy(&globals.dial_gateways);
|
||||
switch_core_hash_destroy(&globals.cmd_aliases);
|
||||
switch_core_hash_destroy(&globals.command_handlers);
|
||||
switch_core_hash_destroy(&globals.event_handlers);
|
||||
switch_core_hash_destroy(&globals.clients_roster);
|
||||
switch_core_hash_destroy(&globals.actors);
|
||||
switch_core_hash_destroy(&globals.destroy_actors);
|
||||
switch_core_hash_destroy(&globals.actors_by_id);
|
||||
switch_core_hash_destroy(&globals.dial_gateways);
|
||||
switch_core_hash_destroy(&globals.cmd_aliases);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Module shutdown\n");
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <switch.h>
|
||||
#include <iksemel.h>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "xmpp_streams.h"
|
||||
#include "iks_helpers.h"
|
||||
#include "sasl.h"
|
||||
@@ -63,6 +65,10 @@ struct xmpp_stream_context {
|
||||
int shutdown;
|
||||
/** prevents context shutdown until all threads are finished */
|
||||
switch_thread_rwlock_t *shutdown_rwlock;
|
||||
/** path to cert PEM file */
|
||||
const char *cert_pem_file;
|
||||
/** path to key PEM file */
|
||||
const char *key_pem_file;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -71,8 +77,8 @@ struct xmpp_stream_context {
|
||||
enum xmpp_stream_state {
|
||||
/** new connection */
|
||||
XSS_CONNECT,
|
||||
/** bidirectional comms established */
|
||||
XSS_BIDI,
|
||||
/** encrypted comms established */
|
||||
XSS_SECURE,
|
||||
/** remote party authenticated */
|
||||
XSS_AUTHENTICATED,
|
||||
/** client resource bound */
|
||||
@@ -159,7 +165,7 @@ static const char *xmpp_stream_state_to_string(enum xmpp_stream_state state)
|
||||
{
|
||||
switch(state) {
|
||||
case XSS_CONNECT: return "CONNECT";
|
||||
case XSS_BIDI: return "BIDI";
|
||||
case XSS_SECURE: return "SECURE";
|
||||
case XSS_AUTHENTICATED: return "AUTHENTICATED";
|
||||
case XSS_RESOURCE_BOUND: return "RESOURCE_BOUND";
|
||||
case XSS_READY: return "READY";
|
||||
@@ -358,6 +364,31 @@ static void xmpp_send_client_header_auth(struct xmpp_stream *stream)
|
||||
free(header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send sasl + starttls reply to xmpp <stream>
|
||||
* @param stream the xmpp stream
|
||||
*/
|
||||
static void xmpp_send_client_header_tls(struct xmpp_stream *stream)
|
||||
{
|
||||
if (stream->context->key_pem_file && stream->context->cert_pem_file) {
|
||||
struct xmpp_stream_context *context = stream->context;
|
||||
char *header = switch_mprintf(
|
||||
"<stream:stream xmlns='"IKS_NS_CLIENT"' xmlns:db='"IKS_NS_XMPP_DIALBACK"'"
|
||||
" from='%s' id='%s' xml:lang='en' version='1.0'"
|
||||
" xmlns:stream='"IKS_NS_XMPP_STREAMS"'><stream:features>"
|
||||
"<starttls xmlns='"IKS_NS_XMPP_TLS"'><required/></starttls>"
|
||||
"<mechanisms xmlns='"IKS_NS_XMPP_SASL"'>"
|
||||
"<mechanism>PLAIN</mechanism>"
|
||||
"</mechanisms></stream:features>", context->domain, stream->id);
|
||||
iks_send_raw(stream->parser, header);
|
||||
free(header);
|
||||
} else {
|
||||
/* not set up for TLS, skip it */
|
||||
stream->state = XSS_SECURE;
|
||||
xmpp_send_client_header_auth(stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send sasl reply to xmpp <stream>
|
||||
* @param stream the xmpp stream
|
||||
@@ -370,12 +401,6 @@ static void xmpp_send_server_header_auth(struct xmpp_stream *stream)
|
||||
" from='%s' id='%s' xml:lang='en' version='1.0'"
|
||||
" xmlns:stream='"IKS_NS_XMPP_STREAMS"'>"
|
||||
"<stream:features>"
|
||||
#if 0
|
||||
"<bidi xmlns='"IKS_NS_BIDI_FEATURE"'/>"
|
||||
"<mechanisms xmlns='"IKS_NS_XMPP_SASL"'>"
|
||||
"<mechanism>PLAIN</mechanism>"
|
||||
"</mechanisms>"
|
||||
#endif
|
||||
"</stream:features>",
|
||||
context->domain, stream->id);
|
||||
iks_send_raw(stream->parser, header);
|
||||
@@ -417,6 +442,21 @@ static void xmpp_send_outbound_server_header(struct xmpp_stream *stream)
|
||||
free(header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle <starttls> message.
|
||||
* @param the xmpp stream
|
||||
* @param node the <starttls> packet
|
||||
*/
|
||||
static void on_stream_starttls(struct xmpp_stream *stream, iks *node)
|
||||
{
|
||||
/* wait for handshake to start */
|
||||
if (iks_proceed_tls(stream->parser, stream->context->cert_pem_file, stream->context->key_pem_file, 1) == IKS_OK) {
|
||||
stream->state = XSS_SECURE;
|
||||
} else {
|
||||
stream->state = XSS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle <auth> message. Only PLAIN supported.
|
||||
* @param stream the xmpp stream
|
||||
@@ -431,7 +471,7 @@ static void on_stream_auth(struct xmpp_stream *stream, iks *node)
|
||||
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, auth, state = %s\n", stream->jid, xmpp_stream_state_to_string(stream->state));
|
||||
|
||||
/* wrong state for authentication */
|
||||
if (stream->state != XSS_BIDI) {
|
||||
if (stream->state != XSS_SECURE) {
|
||||
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_WARNING, "%s, auth UNEXPECTED, state = %s\n", stream->jid, xmpp_stream_state_to_string(stream->state));
|
||||
/* on_auth unexpected error */
|
||||
stream->state = XSS_ERROR;
|
||||
@@ -486,38 +526,6 @@ static void on_stream_auth(struct xmpp_stream *stream, iks *node)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle <bidi> message.
|
||||
* @param stream the xmpp stream
|
||||
* @param node the <bidi> packet
|
||||
*/
|
||||
static void on_stream_bidi(struct xmpp_stream *stream, iks *node)
|
||||
{
|
||||
/* only allow bidi on s2s connections before auth */
|
||||
if (stream->s2s) {
|
||||
switch(stream->state) {
|
||||
case XSS_CONNECT:
|
||||
stream->state = XSS_BIDI;
|
||||
break;
|
||||
case XSS_BIDI:
|
||||
case XSS_AUTHENTICATED:
|
||||
case XSS_RESOURCE_BOUND:
|
||||
case XSS_READY:
|
||||
case XSS_SHUTDOWN:
|
||||
case XSS_ERROR:
|
||||
case XSS_DESTROY:
|
||||
/* error */
|
||||
stream->state = XSS_ERROR;
|
||||
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, bad state: %s\n", stream->jid, xmpp_stream_state_to_string(stream->state));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* error */
|
||||
stream->state = XSS_ERROR;
|
||||
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_INFO, "%s, bidi not allowed from client\n", stream->jid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle <iq><session> request
|
||||
* @param stream the xmpp stream
|
||||
@@ -606,7 +614,7 @@ static void on_stream_iq(struct xmpp_stream *stream, iks *iq)
|
||||
struct xmpp_stream_context *context = stream->context;
|
||||
switch(stream->state) {
|
||||
case XSS_CONNECT:
|
||||
case XSS_BIDI: {
|
||||
case XSS_SECURE: {
|
||||
iks *error = iks_new_error(iq, STANZA_ERROR_NOT_AUTHORIZED);
|
||||
xmpp_stream_stanza_send(stream, error);
|
||||
break;
|
||||
@@ -689,7 +697,9 @@ static void on_client_stream_start(struct xmpp_stream *stream, iks *node)
|
||||
|
||||
switch (stream->state) {
|
||||
case XSS_CONNECT:
|
||||
case XSS_BIDI:
|
||||
xmpp_send_client_header_tls(stream);
|
||||
break;
|
||||
case XSS_SECURE:
|
||||
xmpp_send_client_header_auth(stream);
|
||||
break;
|
||||
case XSS_AUTHENTICATED:
|
||||
@@ -960,7 +970,7 @@ static void on_outbound_server_stream_start(struct xmpp_stream *stream, iks *nod
|
||||
/* strange... I expect IKS_NODE_STOP, this is a workaround. */
|
||||
stream->state = XSS_DESTROY;
|
||||
break;
|
||||
case XSS_BIDI:
|
||||
case XSS_SECURE:
|
||||
case XSS_AUTHENTICATED:
|
||||
case XSS_RESOURCE_BOUND:
|
||||
case XSS_READY:
|
||||
@@ -1001,7 +1011,7 @@ static void on_inbound_server_stream_start(struct xmpp_stream *stream, iks *node
|
||||
case XSS_CONNECT:
|
||||
xmpp_send_server_header_auth(stream);
|
||||
break;
|
||||
case XSS_BIDI:
|
||||
case XSS_SECURE:
|
||||
break;
|
||||
case XSS_AUTHENTICATED: {
|
||||
/* all set */
|
||||
@@ -1075,8 +1085,8 @@ static int on_stream(void *user_data, int type, iks *node)
|
||||
on_stream_presence(stream, node);
|
||||
} else if (!strcmp("auth", name)) {
|
||||
on_stream_auth(stream, node);
|
||||
} else if (!strcmp("bidi", name)) {
|
||||
on_stream_bidi(stream, node);
|
||||
} else if (!strcmp("starttls", name)) {
|
||||
on_stream_starttls(stream, node);
|
||||
} else if (!strcmp("db:result", name)) {
|
||||
on_stream_dialback_result(stream, node);
|
||||
} else if (!strcmp("db:verify", name)) {
|
||||
@@ -1194,6 +1204,7 @@ static void *SWITCH_THREAD_FUNC xmpp_stream_thread(switch_thread_t *thread, void
|
||||
case IKS_OK:
|
||||
err_count = 0;
|
||||
break;
|
||||
case IKS_NET_TLSFAIL:
|
||||
case IKS_NET_RWERR:
|
||||
case IKS_NET_NOCONN:
|
||||
case IKS_NET_NOSOCK:
|
||||
@@ -1291,11 +1302,6 @@ static struct xmpp_stream *xmpp_stream_init(struct xmpp_stream_context *context,
|
||||
stream->incoming = incoming;
|
||||
switch_queue_create(&stream->msg_queue, MAX_QUEUE_LEN, pool);
|
||||
|
||||
if (!stream->s2s) {
|
||||
/* client is already bi-directional */
|
||||
stream->state = XSS_BIDI;
|
||||
}
|
||||
|
||||
/* set up XMPP stream parser */
|
||||
stream->parser = iks_stream_new(stream->s2s ? IKS_NS_SERVER : IKS_NS_CLIENT, stream, on_stream);
|
||||
|
||||
@@ -1829,6 +1835,23 @@ void *xmpp_stream_get_private(struct xmpp_stream *stream)
|
||||
return stream->user_private;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add PEM cert file to stream for new SSL connections
|
||||
*/
|
||||
void xmpp_stream_context_add_cert(struct xmpp_stream_context *context, const char *cert_pem_file)
|
||||
{
|
||||
context->cert_pem_file = switch_core_strdup(context->pool, cert_pem_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add PEM key file to stream for new SSL connections
|
||||
*/
|
||||
void xmpp_stream_context_add_key(struct xmpp_stream_context *context, const char *key_pem_file)
|
||||
{
|
||||
context->key_pem_file = switch_core_strdup(context->pool, key_pem_file);
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
|
||||
@@ -37,6 +37,8 @@ typedef void (* xmpp_stream_recv_callback)(struct xmpp_stream *stream, iks *stan
|
||||
typedef void (* xmpp_stream_destroy_callback)(struct xmpp_stream *stream);
|
||||
|
||||
extern struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy);
|
||||
extern void xmpp_stream_context_add_cert(struct xmpp_stream_context *context, const char *cert_pem_file);
|
||||
extern void xmpp_stream_context_add_key(struct xmpp_stream_context *context, const char *key_pem_file);
|
||||
extern void xmpp_stream_context_add_user(struct xmpp_stream_context *context, const char *user, const char *password);
|
||||
extern void xmpp_stream_context_dump(struct xmpp_stream_context *context, switch_stream_handle_t *stream);
|
||||
extern void xmpp_stream_context_destroy(struct xmpp_stream_context *context);
|
||||
|
||||
@@ -257,6 +257,10 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio
|
||||
switch_core_session_ctl(SCSC_SPS, &int_val);
|
||||
snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val);
|
||||
break;
|
||||
case SS_PEAK_SESSIONS_PER_SECOND:
|
||||
switch_core_session_ctl(SCSC_SPS_PEAK, &int_val);
|
||||
snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val);
|
||||
break;
|
||||
default:
|
||||
snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid);
|
||||
netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#define SS_CURRENT_CALLS 5
|
||||
#define SS_SESSIONS_PER_SECOND 6
|
||||
#define SS_MAX_SESSIONS_PER_SECOND 7
|
||||
#define SS_PEAK_SESSIONS_PER_SECOND 8
|
||||
|
||||
/* .1.3.6.1.4.1.27880.1.9 */
|
||||
#define CH_INDEX 1
|
||||
|
||||
@@ -4814,7 +4814,7 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_
|
||||
}
|
||||
|
||||
if (switch_event_create(&event, SWITCH_EVENT_DEVICE_STATE) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Device-State-Name", drec->device_id);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Device-ID", drec->device_id);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Last-Device-State", switch_channel_device_state2str(drec->last_state));
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Device-State", switch_channel_device_state2str(drec->state));
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Device-Call-State", switch_channel_callstate2str(callstate));
|
||||
|
||||
@@ -88,6 +88,7 @@ static void send_heartbeat(void)
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count());
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Max-Sessions", "%u", switch_core_session_limit(0));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-Max", "%u", runtime.sps_peak);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Idle-CPU", "%f", switch_core_idle_cpu());
|
||||
switch_event_fire(&event);
|
||||
@@ -2477,6 +2478,12 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *
|
||||
case SCSC_LAST_SPS:
|
||||
newintval = runtime.sps_last;
|
||||
break;
|
||||
case SCSC_SPS_PEAK:
|
||||
if (oldintval == -1) {
|
||||
runtime.sps_peak = 0;
|
||||
}
|
||||
newintval = runtime.sps_peak;
|
||||
break;
|
||||
case SCSC_MAX_DTMF_DURATION:
|
||||
newintval = switch_core_max_dtmf_duration(oldintval);
|
||||
break;
|
||||
|
||||
@@ -299,6 +299,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_get_results(switch_asr_handle_t
|
||||
return ah->asr_interface->asr_get_results(ah, xmlstr, flags);
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_get_result_headers(switch_asr_handle_t *ah, switch_event_t **headers, switch_asr_flag_t *flags)
|
||||
{
|
||||
switch_assert(ah != NULL);
|
||||
|
||||
if (ah->asr_interface->asr_get_result_headers) {
|
||||
return ah->asr_interface->asr_get_result_headers(ah, headers, flags);
|
||||
} else {
|
||||
/* Since this is not always implemented, return success if the function can't be called */
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_start_input_timers(switch_asr_handle_t *ah)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
@@ -3792,14 +3792,15 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread started\n", switch_channel_get_name(session->channel));
|
||||
switch_core_session_refresh_video(session);
|
||||
switch_channel_set_flag(channel, CF_VIDEO_ECHO);
|
||||
|
||||
while (switch_channel_up_nosig(channel)) {
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_VIDEO_PASSIVE)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread paused\n", switch_channel_get_name(session->channel));
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread paused. Echo is %s\n",
|
||||
switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
|
||||
switch_thread_cond_wait(mh->cond, mh->cond_mutex);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread resumed\n", switch_channel_get_name(session->channel));
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread resumed Echo is %s\n",
|
||||
switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
|
||||
switch_core_session_refresh_video(session);
|
||||
}
|
||||
|
||||
|
||||
@@ -2625,7 +2625,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_exec(switch_core_session_t *
|
||||
int scope = 0;
|
||||
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
|
||||
char *app_uuid = uuid_str;
|
||||
|
||||
|
||||
if ((app_uuid_var = switch_channel_get_variable(channel, "app_uuid"))) {
|
||||
app_uuid = (char *)app_uuid_var;
|
||||
switch_channel_set_variable(channel, "app_uuid", NULL);
|
||||
@@ -2727,8 +2727,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_exec(switch_core_session_t *
|
||||
msg.string_array_arg[1] = expanded;
|
||||
switch_core_session_receive_message(session, &msg);
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_VIDEO)) {
|
||||
switch_channel_set_flag(channel, CF_VIDEO_ECHO);
|
||||
switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE);
|
||||
switch_core_session_refresh_video(session);
|
||||
}
|
||||
|
||||
application_interface->application_function(session, expanded);
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_VIDEO)) {
|
||||
switch_channel_set_flag(channel, CF_VIDEO_ECHO);
|
||||
switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE);
|
||||
switch_core_session_refresh_video(session);
|
||||
}
|
||||
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE) == SWITCH_STATUS_SUCCESS) {
|
||||
const char *resp = switch_channel_get_variable(session->channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE);
|
||||
switch_channel_event_set_data(session->channel, event);
|
||||
|
||||
+47
-71
@@ -3190,36 +3190,18 @@ static const char *get_prefixed_str(char *buffer, size_t buffer_size, const char
|
||||
return buffer;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *session, const char *data)
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_set_user_xml(switch_core_session_t *session, const char *prefix,
|
||||
const char *user, const char *domain, switch_xml_t x_user)
|
||||
{
|
||||
switch_xml_t x_domain, xml = NULL, x_user, x_param, x_params, x_group = NULL;
|
||||
char *user, *number_alias, *domain;
|
||||
switch_xml_t x_params, x_param;
|
||||
char *number_alias;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
char *prefix_buffer = NULL, *prefix;
|
||||
char *prefix_buffer = NULL;
|
||||
size_t buffer_size = 0;
|
||||
size_t prefix_size = 0;
|
||||
if (zstr(data)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
user = switch_core_session_strdup(session, data);
|
||||
|
||||
if ((prefix = strchr(user, ' '))) {
|
||||
*prefix++ = 0;
|
||||
}
|
||||
|
||||
if (!(domain = strchr(user, '@'))) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
*domain++ = '\0';
|
||||
|
||||
if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, &x_group, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain);
|
||||
goto done;
|
||||
}
|
||||
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
@@ -3233,50 +3215,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *sessi
|
||||
switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "number_alias"), number_alias);
|
||||
}
|
||||
|
||||
if ((x_params = switch_xml_child(x_domain, "variables"))) {
|
||||
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
|
||||
const char *var = switch_xml_attr(x_param, "name");
|
||||
const char *val = switch_xml_attr(x_param, "value");
|
||||
|
||||
if (var && val) {
|
||||
switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((x_params = switch_xml_child(x_domain, "profile-variables"))) {
|
||||
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
|
||||
const char *var = switch_xml_attr(x_param, "name");
|
||||
const char *val = switch_xml_attr(x_param, "value");
|
||||
|
||||
if (var && val) {
|
||||
switch_channel_set_profile_var(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (x_group && (x_params = switch_xml_child(x_group, "variables"))) {
|
||||
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
|
||||
const char *var = switch_xml_attr(x_param, "name");
|
||||
const char *val = switch_xml_attr(x_param, "value");
|
||||
|
||||
if (var && val) {
|
||||
switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((x_params = switch_xml_child(x_group, "profile-variables"))) {
|
||||
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
|
||||
const char *var = switch_xml_attr(x_param, "name");
|
||||
const char *val = switch_xml_attr(x_param, "value");
|
||||
|
||||
if (var && val) {
|
||||
switch_channel_set_profile_var(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((x_params = switch_xml_child(x_user, "variables"))) {
|
||||
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
|
||||
const char *var = switch_xml_attr(x_param, "name");
|
||||
@@ -3299,17 +3237,55 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *sessi
|
||||
}
|
||||
}
|
||||
|
||||
switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "user_name"), user);
|
||||
switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "domain_name"), domain);
|
||||
if (user && domain) {
|
||||
switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "user_name"), user);
|
||||
switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "domain_name"), domain);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *session, const char *data)
|
||||
{
|
||||
switch_xml_t x_user;
|
||||
char *user, *domain;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
char *prefix;
|
||||
|
||||
if (zstr(data)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
user = switch_core_session_strdup(session, data);
|
||||
|
||||
if ((prefix = strchr(user, ' '))) {
|
||||
*prefix++ = 0;
|
||||
}
|
||||
|
||||
if (!(domain = strchr(user, '@'))) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
*domain++ = '\0';
|
||||
|
||||
|
||||
if (switch_xml_locate_user_merged("id", user, domain, NULL, &x_user, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain);
|
||||
goto done;
|
||||
}
|
||||
|
||||
status = switch_ivr_set_user_xml(session, prefix, user, domain, x_user);
|
||||
|
||||
goto done;
|
||||
|
||||
error:
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No user@domain specified.\n");
|
||||
|
||||
done:
|
||||
if (xml) {
|
||||
switch_xml_free(xml);
|
||||
|
||||
if (x_user) {
|
||||
switch_xml_free(x_user);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
+57
-27
@@ -3791,6 +3791,7 @@ static void *SWITCH_THREAD_FUNC speech_thread(switch_thread_t *thread, void *obj
|
||||
|
||||
while (switch_channel_up_nosig(channel) && !switch_test_flag(sth->ah, SWITCH_ASR_FLAG_CLOSED)) {
|
||||
char *xmlstr = NULL;
|
||||
switch_event_t *headers = NULL;
|
||||
|
||||
switch_thread_cond_wait(sth->cond, sth->mutex);
|
||||
|
||||
@@ -3804,6 +3805,9 @@ static void *SWITCH_THREAD_FUNC speech_thread(switch_thread_t *thread, void *obj
|
||||
|
||||
if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
|
||||
goto done;
|
||||
} else if (status == SWITCH_STATUS_SUCCESS) {
|
||||
/* Try to fetch extra information for this result, the return value doesn't really matter here - it's just optional data. */
|
||||
switch_core_asr_get_result_headers(sth->ah, &headers, &flags);
|
||||
}
|
||||
|
||||
if (status == SWITCH_STATUS_SUCCESS && switch_true(switch_channel_get_variable(channel, "asr_intercept_dtmf"))) {
|
||||
@@ -3853,6 +3857,11 @@ static void *SWITCH_THREAD_FUNC speech_thread(switch_thread_t *thread, void *obj
|
||||
if (switch_event_create(&event, SWITCH_EVENT_DETECTED_SPEECH) == SWITCH_STATUS_SUCCESS) {
|
||||
if (status == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Speech-Type", "detected-speech");
|
||||
|
||||
if (headers) {
|
||||
switch_event_merge(event, headers);
|
||||
}
|
||||
|
||||
switch_event_add_body(event, "%s", xmlstr);
|
||||
} else {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Speech-Type", "begin-speaking");
|
||||
@@ -3876,6 +3885,10 @@ static void *SWITCH_THREAD_FUNC speech_thread(switch_thread_t *thread, void *obj
|
||||
}
|
||||
|
||||
switch_safe_free(xmlstr);
|
||||
|
||||
if (headers) {
|
||||
switch_event_destroy(&headers);
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
@@ -4121,9 +4134,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_all_grammars(sw
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech(switch_core_session_t *session,
|
||||
const char *mod_name,
|
||||
const char *grammar, const char *name, const char *dest, switch_asr_handle_t *ah)
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_init(switch_core_session_t *session, const char *mod_name,
|
||||
const char *dest, switch_asr_handle_t *ah)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_status_t status;
|
||||
@@ -4133,9 +4145,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech(switch_core_session_t *
|
||||
const char *p;
|
||||
char key[512] = "";
|
||||
|
||||
switch_core_session_get_read_impl(session, &read_impl);
|
||||
|
||||
switch_snprintf(key, sizeof(key), "%s/%s/%s/%s", mod_name, grammar, name, dest);
|
||||
if (sth) {
|
||||
/* Already initialized */
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!ah) {
|
||||
if (!(ah = switch_core_session_alloc(session, sizeof(*ah)))) {
|
||||
@@ -4143,32 +4156,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech(switch_core_session_t *
|
||||
}
|
||||
}
|
||||
|
||||
if (sth) {
|
||||
if (switch_core_asr_load_grammar(sth->ah, grammar, name) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error loading Grammar\n");
|
||||
switch_ivr_stop_detect_speech(session);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if ((p = switch_channel_get_variable(channel, "fire_asr_events")) && switch_true(p)) {
|
||||
switch_set_flag(sth->ah, SWITCH_ASR_FLAG_FIRE_EVENTS);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
switch_core_session_get_read_impl(session, &read_impl);
|
||||
|
||||
if ((status = switch_core_asr_open(ah,
|
||||
mod_name,
|
||||
"L16",
|
||||
read_impl.actual_samples_per_second, dest, &flags,
|
||||
switch_core_session_get_pool(session))) == SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
if (switch_core_asr_load_grammar(ah, grammar, name) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error loading Grammar\n");
|
||||
switch_core_asr_close(ah, &flags);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
} else {
|
||||
switch_core_session_get_pool(session))) != SWITCH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -4181,6 +4175,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech(switch_core_session_t *
|
||||
switch_set_flag(ah, SWITCH_ASR_FLAG_FIRE_EVENTS);
|
||||
}
|
||||
|
||||
switch_snprintf(key, sizeof(key), "%s/%s/%s/%s", mod_name, NULL, NULL, dest);
|
||||
|
||||
if ((status = switch_core_media_bug_add(session, "detect_speech", key,
|
||||
speech_callback, sth, 0, SMBF_READ_STREAM | SMBF_NO_PAUSE, &sth->bug)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_core_asr_close(ah, &flags);
|
||||
@@ -4197,6 +4193,40 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech(switch_core_session_t *
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech(switch_core_session_t *session,
|
||||
const char *mod_name,
|
||||
const char *grammar, const char *name, const char *dest, switch_asr_handle_t *ah)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_status_t status;
|
||||
struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY);
|
||||
const char *p;
|
||||
|
||||
if (!sth) {
|
||||
/* No speech thread handle available yet, init speech detection first. */
|
||||
if ((status = switch_ivr_detect_speech_init(session, mod_name, dest, ah)) != SWITCH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Fetch the new speech thread handle */
|
||||
if (!(sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY))) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (switch_core_asr_load_grammar(sth->ah, grammar, name) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error loading Grammar\n");
|
||||
switch_ivr_stop_detect_speech(session);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if ((p = switch_channel_get_variable(channel, "fire_asr_events")) && switch_true(p)) {
|
||||
switch_set_flag(sth->ah, SWITCH_ASR_FLAG_FIRE_EVENTS);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
struct hangup_helper {
|
||||
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
|
||||
switch_bool_t bleg;
|
||||
|
||||
@@ -1676,6 +1676,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess
|
||||
*cause = SWITCH_CAUSE_NO_ANSWER;
|
||||
}
|
||||
|
||||
if (channel) {
|
||||
if (*cause == SWITCH_CAUSE_SUCCESS) {
|
||||
switch_channel_set_variable(channel, "originate_disposition", "success");
|
||||
} else {
|
||||
switch_channel_set_variable(channel, "originate_disposition", "failure");
|
||||
switch_channel_set_variable(channel, "hangup_cause", switch_channel_cause2str(*cause));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (var_event && var_event != ovars) {
|
||||
switch_event_destroy(&var_event);
|
||||
}
|
||||
|
||||
+47
-13
@@ -54,7 +54,7 @@
|
||||
#include <switch_version.h>
|
||||
#include <switch_ssl.h>
|
||||
|
||||
#define FIR_COUNTDOWN 100
|
||||
#define FIR_COUNTDOWN 50
|
||||
|
||||
#define READ_INC(rtp_session) switch_mutex_lock(rtp_session->read_mutex); rtp_session->reading++
|
||||
#define READ_DEC(rtp_session) switch_mutex_unlock(rtp_session->read_mutex); rtp_session->reading--
|
||||
@@ -270,6 +270,12 @@ typedef struct ts_normalize_s {
|
||||
uint32_t last_frame;
|
||||
uint32_t ts;
|
||||
uint32_t delta;
|
||||
uint32_t delta_ct;
|
||||
uint32_t delta_ttl;
|
||||
uint32_t delta_avg;
|
||||
uint32_t delta_delta;
|
||||
double delta_percent;
|
||||
uint8_t m;
|
||||
} ts_normalize_t;
|
||||
|
||||
struct switch_rtp {
|
||||
@@ -3349,6 +3355,10 @@ SWITCH_DECLARE(void) switch_rtp_break(switch_rtp_t *rtp_session)
|
||||
return;
|
||||
}
|
||||
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch_mutex_lock(rtp_session->flag_mutex);
|
||||
rtp_session->flags[SWITCH_RTP_FLAG_BREAK] = 1;
|
||||
|
||||
@@ -4247,15 +4257,6 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
if (*bytes && rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
||||
unsigned int diff = ts - rtp_session->last_read_ts;
|
||||
|
||||
if (abs(diff) > 10000) {
|
||||
switch_rtp_video_refresh(rtp_session);
|
||||
}
|
||||
}
|
||||
|
||||
if (ts) {
|
||||
rtp_session->last_read_ts = ts;
|
||||
}
|
||||
@@ -4645,7 +4646,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
||||
goto end;
|
||||
}
|
||||
// This is dumb
|
||||
switch_rtp_video_refresh(rtp_session);
|
||||
//switch_rtp_video_refresh(rtp_session);
|
||||
goto rtcp;
|
||||
}
|
||||
}
|
||||
@@ -4712,7 +4713,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
||||
}
|
||||
|
||||
has_rtcp = 0;
|
||||
|
||||
|
||||
} else if (rtp_session->rtcp_read_pollfd) {
|
||||
rtcp_poll_status = switch_poll(rtp_session->rtcp_read_pollfd, 1, &rtcp_fdr, 0);
|
||||
}
|
||||
@@ -5272,7 +5273,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
|
||||
}
|
||||
|
||||
if (rtp_session->fir_countdown) {
|
||||
if (--rtp_session->fir_countdown == 0) {
|
||||
rtp_session->fir_countdown--;
|
||||
|
||||
if (rtp_session->fir_countdown == FIR_COUNTDOWN / 2 || rtp_session->fir_countdown == 0) {
|
||||
send_fir(rtp_session);
|
||||
//send_pli(rtp_session);
|
||||
}
|
||||
@@ -5483,6 +5486,9 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
|
||||
|
||||
if (!rtp_session->ts_norm.last_ssrc || send_msg->header.ssrc != rtp_session->ts_norm.last_ssrc) {
|
||||
if (rtp_session->ts_norm.last_ssrc) {
|
||||
rtp_session->ts_norm.m = 1;
|
||||
rtp_session->ts_norm.delta_ct = 1;
|
||||
rtp_session->ts_norm.delta_ttl = 0;
|
||||
if (rtp_session->ts_norm.delta) {
|
||||
rtp_session->ts_norm.ts += rtp_session->ts_norm.delta;
|
||||
}
|
||||
@@ -5494,12 +5500,40 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
|
||||
|
||||
if (ntohl(send_msg->header.ts) != rtp_session->ts_norm.last_frame) {
|
||||
rtp_session->ts_norm.delta = ntohl(send_msg->header.ts) - rtp_session->ts_norm.last_frame;
|
||||
|
||||
if (rtp_session->ts_norm.delta > 0) {
|
||||
rtp_session->ts_norm.delta_ct++;
|
||||
if (rtp_session->ts_norm.delta_ct == 1000) {
|
||||
rtp_session->ts_norm.delta_ct = 1;
|
||||
rtp_session->ts_norm.delta_ttl = 0;
|
||||
}
|
||||
|
||||
rtp_session->ts_norm.delta_ttl += rtp_session->ts_norm.delta;
|
||||
rtp_session->ts_norm.delta_avg = rtp_session->ts_norm.delta_ttl / rtp_session->ts_norm.delta_ct;
|
||||
rtp_session->ts_norm.delta_delta = abs(rtp_session->ts_norm.delta_avg - rtp_session->ts_norm.delta);
|
||||
rtp_session->ts_norm.delta_percent = (double)((double)rtp_session->ts_norm.delta / (double)rtp_session->ts_norm.delta_avg) * 100.0f;
|
||||
|
||||
|
||||
if (rtp_session->ts_norm.delta_ct > 50 && rtp_session->ts_norm.delta_percent > 125.0) {
|
||||
//printf("%s diff %d %d (%.2f)\n", switch_core_session_get_name(rtp_session->session),
|
||||
//rtp_session->ts_norm.delta, rtp_session->ts_norm.delta_avg, rtp_session->ts_norm.delta_percent);
|
||||
switch_rtp_video_refresh(rtp_session);
|
||||
}
|
||||
}
|
||||
rtp_session->ts_norm.ts += rtp_session->ts_norm.delta;
|
||||
}
|
||||
|
||||
rtp_session->ts_norm.last_frame = ntohl(send_msg->header.ts);
|
||||
send_msg->header.ts = htonl(rtp_session->ts_norm.ts);
|
||||
|
||||
/* wait for a marked frame since we just switched streams */
|
||||
if (rtp_session->ts_norm.m) {
|
||||
if (send_msg->header.m) {
|
||||
rtp_session->ts_norm.m = 0;
|
||||
} else {
|
||||
send = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
send_msg->header.ssrc = htonl(rtp_session->ssrc);
|
||||
|
||||
@@ -1008,6 +1008,10 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
|
||||
}
|
||||
switch_mutex_lock(runtime.throttle_mutex);
|
||||
runtime.sps_last = runtime.sps_total - runtime.sps;
|
||||
|
||||
if (runtime.sps_last > runtime.sps_peak) {
|
||||
runtime.sps_peak = runtime.sps_last;
|
||||
}
|
||||
runtime.sps = runtime.sps_total;
|
||||
switch_mutex_unlock(runtime.throttle_mutex);
|
||||
tick = 0;
|
||||
|
||||
@@ -1919,8 +1919,10 @@ SWITCH_DECLARE(void) switch_xml_merge_user(switch_xml_t user, switch_xml_t domai
|
||||
|
||||
do_merge(user, group, "params", "param");
|
||||
do_merge(user, group, "variables", "variable");
|
||||
do_merge(user, group, "profile-variables", "variable");
|
||||
do_merge(user, domain, "params", "param");
|
||||
do_merge(user, domain, "variables", "variable");
|
||||
do_merge(user, domain, "profile-variables", "variable");
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(uint32_t) switch_xml_clear_user_cache(const char *key, const char *user_name, const char *domain_name)
|
||||
|
||||
Reference in New Issue
Block a user