mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-23 20:51:58 +00:00
Merge branch 'master' into v1.4.beta
This commit is contained in:
@@ -1 +1 @@
|
||||
Wed Jun 26 12:43:51 EDT 2013
|
||||
Thu Jun 27 14:04:11 CDT 2013
|
||||
|
||||
@@ -432,26 +432,43 @@ int tport_ws_init_secondary(tport_t *self, int socket, int accepted,
|
||||
int one = 1;
|
||||
tport_ws_primary_t *wspri = (tport_ws_primary_t *)self->tp_pri;
|
||||
tport_ws_t *wstp = (tport_ws_t *)self;
|
||||
char *buffer, *wbuffer;
|
||||
|
||||
self->tp_has_connection = 1;
|
||||
|
||||
if (setsockopt(socket, SOL_TCP, TCP_NODELAY, (void *)&one, sizeof one) == -1)
|
||||
return *return_reason = "TCP_NODELAY", -1;
|
||||
return *return_reason = "TCP_NODELAY", -1;
|
||||
|
||||
#if defined(SO_KEEPALIVE)
|
||||
setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, (void *)&one, sizeof one);
|
||||
#endif
|
||||
one = 30;
|
||||
#if defined(TCP_KEEPIDLE)
|
||||
setsockopt(socket, SOL_TCP, TCP_KEEPIDLE, (void *)&one, sizeof one);
|
||||
#endif
|
||||
#if defined(TCP_KEEPINTVL)
|
||||
setsockopt(socket, SOL_TCP, TCP_KEEPINTVL, (void *)&one, sizeof one);
|
||||
#endif
|
||||
|
||||
|
||||
if (!accepted)
|
||||
tport_ws_setsndbuf(socket, 64 * 1024);
|
||||
|
||||
if ( wspri->ws_secure ) wstp->ws_secure = 1;
|
||||
|
||||
|
||||
memset(&wstp->ws, 0, sizeof(wstp->ws));
|
||||
if (ws_init(&wstp->ws, socket, 65336, wstp->ws_secure ? wspri->ssl_ctx : NULL, 0) < 0) {
|
||||
|
||||
buffer = (char *) su_alloc((su_home_t *)self, 65536);
|
||||
wbuffer = (char *) su_alloc((su_home_t *)self, 65536);
|
||||
|
||||
if (ws_init(&wstp->ws, socket, buffer, wbuffer, 65336, wstp->ws_secure ? wspri->ssl_ctx : NULL, 0) < 0) {
|
||||
return *return_reason = "WS_INIT", -1;
|
||||
}
|
||||
|
||||
wstp->ws_initialized = 1;
|
||||
self->tp_pre_framed = 1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -352,7 +352,7 @@ issize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes)
|
||||
return r;
|
||||
}
|
||||
|
||||
int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, SSL_CTX *ssl_ctx, int close_sock)
|
||||
int ws_init(wsh_t *wsh, ws_socket_t sock, char *buffer, char *wbuffer, size_t buflen, SSL_CTX *ssl_ctx, int close_sock)
|
||||
{
|
||||
memset(wsh, 0, sizeof(*wsh));
|
||||
wsh->sock = sock;
|
||||
@@ -372,14 +372,26 @@ int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, SSL_CTX *ssl_ctx, int c
|
||||
wsh->buflen = buflen;
|
||||
wsh->secure = ssl_ctx ? 1 : 0;
|
||||
|
||||
if (!wsh->buffer) {
|
||||
if (buffer) {
|
||||
wsh->buffer = buffer;
|
||||
} else if (!wsh->buffer) {
|
||||
wsh->buffer = malloc(wsh->buflen);
|
||||
assert(wsh->buffer);
|
||||
wsh->free_buffer = 1;
|
||||
}
|
||||
|
||||
if (wbuffer) {
|
||||
wsh->wbuffer = wbuffer;
|
||||
} else if (!wsh->wbuffer) {
|
||||
wsh->wbuffer = malloc(wsh->buflen);
|
||||
assert(wsh->wbuffer);
|
||||
wsh->free_wbuffer = 1;
|
||||
}
|
||||
|
||||
if (wsh->secure) {
|
||||
int code;
|
||||
|
||||
int sanity = 500;
|
||||
|
||||
wsh->ssl = SSL_new(ssl_ctx);
|
||||
assert(wsh->ssl);
|
||||
|
||||
@@ -387,8 +399,32 @@ int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, SSL_CTX *ssl_ctx, int c
|
||||
|
||||
do {
|
||||
code = SSL_accept(wsh->ssl);
|
||||
} while (code == -1 && SSL_get_error(wsh->ssl, code) == SSL_ERROR_WANT_READ);
|
||||
|
||||
if (code == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (code == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (code < 0) {
|
||||
if (code == -1 && SSL_get_error(wsh->ssl, code) != SSL_ERROR_WANT_READ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#ifndef _MSC_VER
|
||||
usleep(10000);
|
||||
#else
|
||||
Sleep(10);
|
||||
#endif
|
||||
|
||||
} while (--sanity > 0);
|
||||
|
||||
if (!sanity) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
while (!wsh->down && !wsh->handshake) {
|
||||
@@ -429,12 +465,12 @@ void ws_destroy(wsh_t *wsh)
|
||||
wsh->ssl = NULL;
|
||||
}
|
||||
|
||||
if (wsh->buffer) {
|
||||
if (wsh->free_buffer && wsh->buffer) {
|
||||
free(wsh->buffer);
|
||||
wsh->buffer = NULL;
|
||||
}
|
||||
|
||||
if (wsh->wbuffer) {
|
||||
if (wsh->free_wbuffer && wsh->wbuffer) {
|
||||
free(wsh->wbuffer);
|
||||
wsh->wbuffer = NULL;
|
||||
}
|
||||
@@ -628,13 +664,6 @@ issize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!wsh->wbuffer) {
|
||||
wsh->wbuffer = malloc(wsh->buflen);
|
||||
assert(wsh->wbuffer);
|
||||
}
|
||||
|
||||
|
||||
memcpy(wsh->wbuffer + wsh->wdatalen, data, bytes);
|
||||
|
||||
wsh->wdatalen += bytes;
|
||||
|
||||
@@ -71,8 +71,9 @@ typedef struct wsh_s {
|
||||
int handshake;
|
||||
uint8_t down;
|
||||
int secure;
|
||||
unsigned close_sock:1;
|
||||
unsigned :0;
|
||||
uint8_t free_buffer;
|
||||
uint8_t free_wbuffer;
|
||||
uint8_t close_sock;
|
||||
} wsh_t;
|
||||
|
||||
issize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc);
|
||||
@@ -83,7 +84,7 @@ issize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes);
|
||||
issize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes);
|
||||
issize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data);
|
||||
issize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes);
|
||||
int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, SSL_CTX *ssl_ctx, int close_sock);
|
||||
int ws_init(wsh_t *wsh, ws_socket_t sock, char *buffer, char *wbuffer, size_t buflen, SSL_CTX *ssl_ctx, int close_sock);
|
||||
issize_t ws_close(wsh_t *wsh, int16_t reason);
|
||||
void ws_destroy(wsh_t *wsh);
|
||||
void init_ssl(void);
|
||||
|
||||
@@ -142,6 +142,27 @@ typedef struct {
|
||||
} switch_stun_ip_t;
|
||||
|
||||
|
||||
#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
|
||||
|
||||
typedef struct {
|
||||
unsigned padding:21;
|
||||
unsigned code:3;
|
||||
unsigned number:8;
|
||||
char reason[764];
|
||||
} switch_stun_error_code_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef struct {
|
||||
unsigned number:8;
|
||||
unsigned code:3;
|
||||
unsigned padding:21;
|
||||
char reason[764];
|
||||
} switch_stun_error_code_t;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\brief Writes random characters into a buffer
|
||||
\param buf the buffer
|
||||
|
||||
@@ -7354,7 +7354,7 @@ SWITCH_STANDARD_APP(conference_function)
|
||||
char *bridgeto = NULL;
|
||||
char *profile_name = NULL;
|
||||
switch_xml_t cxml = NULL, cfg = NULL, profiles = NULL;
|
||||
const char *flags_str;
|
||||
const char *flags_str, *v_flags_str;
|
||||
member_flag_t mflags = 0;
|
||||
switch_core_session_message_t msg = { 0 };
|
||||
uint8_t rl = 0, isbr = 0;
|
||||
@@ -7406,8 +7406,14 @@ SWITCH_STANDARD_APP(conference_function)
|
||||
if ((p = strchr(flags_str, '}'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
} else {
|
||||
flags_str = switch_channel_get_variable(channel, "conference_member_flags");
|
||||
}
|
||||
|
||||
if ((v_flags_str = switch_channel_get_variable(channel, "conference_member_flags"))) {
|
||||
if (zstr(flags_str)) {
|
||||
flags_str = v_flags_str;
|
||||
} else {
|
||||
flags_str = switch_core_session_sprintf(session, "%s|%s", flags_str, v_flags_str);
|
||||
}
|
||||
}
|
||||
|
||||
/* is this a bridging conference ? */
|
||||
|
||||
@@ -230,6 +230,19 @@ action : Change url to submit to.
|
||||
temp-action : Change url to submit to. just for the next loop.
|
||||
|
||||
|
||||
<answer is-conference>
|
||||
: Answer the call
|
||||
|
||||
ATTRS:
|
||||
is-conference : true|false (set the conference flag for RFC4579 stuff.
|
||||
|
||||
|
||||
<preAnswer>
|
||||
: Establish media on the call without answering.
|
||||
|
||||
<ringReady>
|
||||
: Indicate ringing to an unaswered channel.
|
||||
|
||||
|
||||
<hangup cause action>
|
||||
: Hangup the call
|
||||
|
||||
@@ -877,6 +877,26 @@ static switch_status_t parse_hangup(const char *tag_name, client_t *client, swit
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
static switch_status_t parse_answer(const char *tag_name, client_t *client, switch_xml_t tag, const char *body)
|
||||
{
|
||||
|
||||
if (!strcasecmp(tag_name, "answer")) {
|
||||
const char *conf = switch_xml_attr(tag, "is-conference");
|
||||
|
||||
if (conf && switch_true(conf)) {
|
||||
switch_channel_set_flag(client->channel, CF_CONFERENCE);
|
||||
}
|
||||
|
||||
switch_channel_answer(client->channel);
|
||||
} else if (!strcasecmp(tag_name, "preAnswer")) {
|
||||
switch_channel_pre_answer(client->channel);
|
||||
} else if (!strcasecmp(tag_name, "ringReady")) {
|
||||
switch_channel_ring_ready(client->channel);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
static switch_status_t parse_record_call(const char *tag_name, client_t *client, switch_xml_t tag, const char *body)
|
||||
{
|
||||
const char *limit_ = switch_xml_attr(tag, "limit");
|
||||
@@ -2997,6 +3017,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_httapi_load)
|
||||
bind_parser("sms", parse_sms);
|
||||
bind_parser("dial", parse_dial);
|
||||
bind_parser("pause", parse_playback);
|
||||
bind_parser("answer", parse_answer);
|
||||
bind_parser("preAnswer", parse_answer);
|
||||
bind_parser("ringReady", parse_answer);
|
||||
bind_parser("hangup", parse_hangup);
|
||||
bind_parser("record", parse_record);
|
||||
bind_parser("recordCall", parse_record_call);
|
||||
|
||||
@@ -1596,7 +1596,7 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
|
||||
|
||||
args.input_callback = cancel_on_dtmf;
|
||||
|
||||
switch_snprintf(key_buf, sizeof(key_buf), "%s:%s:%s:%s:%s:%s%s%s", profile->listen_file_key, profile->save_file_key,
|
||||
switch_snprintf(key_buf, sizeof(key_buf), "%s:%s:%s:%s:%s:%s%s%s", profile->repeat_msg_key, profile->save_file_key,
|
||||
profile->delete_file_key, profile->email_key, profile->callback_key,
|
||||
profile->forward_key, cbt->email ? ":" : "", cbt->email ? cbt->email : "");
|
||||
|
||||
|
||||
@@ -1051,27 +1051,40 @@ switch_status_t channel_receive_message(switch_core_session_t *session, switch_c
|
||||
private_t *tech_pvt = switch_core_session_get_private(session);
|
||||
|
||||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
|
||||
return channel_answer_channel(session);
|
||||
|
||||
case SWITCH_MESSAGE_INDICATE_DISPLAY:
|
||||
skinny_session_send_call_info_all(session);
|
||||
break;
|
||||
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_EARLY_MEDIA)) {
|
||||
/* early media */
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
|
||||
return channel_answer_channel(session);
|
||||
|
||||
case SWITCH_MESSAGE_INDICATE_DISPLAY:
|
||||
skinny_session_send_call_info_all(session);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_EARLY_MEDIA)) {
|
||||
/* early media */
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
|
||||
return channel_answer_channel(session);
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
default:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case SWITCH_MESSAGE_INDICATE_BRIDGE:
|
||||
if (switch_rtp_ready(tech_pvt->rtp_session)) {
|
||||
rtp_flush_read_buffer(tech_pvt->rtp_session, SWITCH_RTP_FLUSH_STICK);
|
||||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_UNBRIDGE:
|
||||
if (switch_rtp_ready(tech_pvt->rtp_session)) {
|
||||
rtp_flush_read_buffer(tech_pvt->rtp_session, SWITCH_RTP_FLUSH_UNSTICK);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
|
||||
@@ -1982,10 +1995,10 @@ static switch_status_t load_skinny_config(void)
|
||||
|
||||
|
||||
if ((dbh = skinny_get_db_handle(profile))) {
|
||||
switch_cache_db_test_reactive(dbh, "DELETE FROM skinny_devices", "DROP TABLE skinny_devices", devices_sql);
|
||||
switch_cache_db_test_reactive(dbh, "DELETE FROM skinny_lines", "DROP TABLE skinny_lines", lines_sql);
|
||||
switch_cache_db_test_reactive(dbh, "DELETE FROM skinny_buttons", "DROP TABLE skinny_buttons", buttons_sql);
|
||||
switch_cache_db_test_reactive(dbh, "DELETE FROM skinny_active_lines", "DROP TABLE skinny_active_lines", active_lines_sql);
|
||||
switch_cache_db_test_reactive(dbh, "select count(*) from skinny_devices", NULL, devices_sql);
|
||||
switch_cache_db_test_reactive(dbh, "select count(*) from skinny_lines", NULL, lines_sql);
|
||||
switch_cache_db_test_reactive(dbh, "select count(*) from skinny_buttons", NULL, buttons_sql);
|
||||
switch_cache_db_test_reactive(dbh, "select count(*) from skinny_active_lines", NULL, active_lines_sql);
|
||||
switch_cache_db_release_db_handle(&dbh);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,8 @@ uint32_t soft_key_template_default_textids[] = {
|
||||
SKINNY_TEXTID_IDIVERT
|
||||
};
|
||||
|
||||
#define TEXT_ID_LEN 20
|
||||
|
||||
uint32_t soft_key_template_default_events[] = {
|
||||
SOFTKEY_REDIAL,
|
||||
SOFTKEY_NEWCALL,
|
||||
@@ -984,9 +986,9 @@ switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *r
|
||||
request->data.reg.device_name, request->data.reg.instance, &listener2);
|
||||
if (listener2) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
||||
"Device %s:%d is already registred on another listener.\n",
|
||||
"Device %s:%d is already registered on another listener.\n",
|
||||
request->data.reg.device_name, request->data.reg.instance);
|
||||
send_register_reject(listener, "Device is already registred on another listener");
|
||||
send_register_reject(listener, "Device is already registered on another listener");
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto end;
|
||||
}
|
||||
@@ -1732,6 +1734,10 @@ switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *liste
|
||||
struct in_addr addr;
|
||||
switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0};
|
||||
|
||||
flags[SWITCH_RTP_FLAG_DATAWAIT]++;
|
||||
flags[SWITCH_RTP_FLAG_AUTOADJ]++;
|
||||
flags[SWITCH_RTP_FLAG_RAW_WRITE]++;
|
||||
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
channel = switch_core_session_get_channel(session);
|
||||
|
||||
@@ -1955,7 +1961,7 @@ switch_status_t skinny_handle_unregister(listener_t *listener, skinny_message_t
|
||||
|
||||
switch_status_t skinny_handle_soft_key_template_request(listener_t *listener, skinny_message_t *request)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
skinny_message_t *message;
|
||||
|
||||
switch_assert(listener->profile);
|
||||
@@ -1970,7 +1976,7 @@ switch_status_t skinny_handle_soft_key_template_request(listener_t *listener, sk
|
||||
message->data.soft_key_template.total_soft_key_count = 21;
|
||||
|
||||
memset(message->data.soft_key_template.soft_key, 0, sizeof(message->data.soft_key_template));
|
||||
for (i=0; i<sizeof(soft_key_template_default_textids); i++) {
|
||||
for (i=0; i< TEXT_ID_LEN; i++) {
|
||||
char *label = skinny_textid2raw(soft_key_template_default_textids[i]);
|
||||
strcpy(message->data.soft_key_template.soft_key[i].soft_key_label, skinny_textid2raw(soft_key_template_default_textids[i]));
|
||||
switch_safe_free(label);
|
||||
|
||||
@@ -3674,6 +3674,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_rayo_load)
|
||||
"<![CDATA[<grammar mode=\"dtmf\"><rule id=\"digits\" scope=\"public\"><item repeat=\"4\"><one-of><item>0</item><item>1</item><item>2</item><item>3</item><item>4</item><item>5</item><item>6</item><item>7</item><item>8</item><item>9</item></one-of></item></rule></grammar>]]>"
|
||||
"</grammar></input>"
|
||||
"</prompt>");
|
||||
rayo_add_cmd_alias("input", "<input xmlns=\""RAYO_INPUT_NS"\" mode=\"dtmf\" initial-timeout=\"5000\" inter-digit-timeout=\"3000\">"
|
||||
"<grammar content-type=\"application/srgs+xml\">"
|
||||
"<![CDATA[<grammar mode=\"dtmf\"><rule id=\"digits\" scope=\"public\"><item><one-of><item>0</item><item>1</item><item>2</item><item>3</item><item>4</item><item>5</item><item>6</item><item>7</item><item>8</item><item>9</item><item>*</item><item>#</item></one-of></item></rule></grammar>]]>"
|
||||
"</grammar></input>");
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -363,6 +363,37 @@ iks *nlsml_normalize(const char *result)
|
||||
return result_xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if digit is a DTMF
|
||||
*/
|
||||
static int isdtmf(const char digit)
|
||||
{
|
||||
switch(digit) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '*':
|
||||
case '#':
|
||||
case 'a':
|
||||
case 'A':
|
||||
case 'b':
|
||||
case 'B':
|
||||
case 'c':
|
||||
case 'C':
|
||||
case 'd':
|
||||
case 'D':
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an NLSML result for digit match
|
||||
* @param digits the matching digits
|
||||
@@ -387,7 +418,7 @@ iks *nlsml_create_dtmf_match(const char *digits)
|
||||
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
for (i = 0; i < num_digits; i++) {
|
||||
if (isdigit(digits[i])) {
|
||||
if (isdtmf(digits[i])) {
|
||||
if (first) {
|
||||
stream.write_function(&stream, "%c", digits[i]);
|
||||
first = 0;
|
||||
|
||||
@@ -430,6 +430,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_add(switch_core_session_t
|
||||
|
||||
if (punt) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+24
-22
@@ -227,7 +227,6 @@ typedef struct {
|
||||
uint8_t ready;
|
||||
uint8_t rready;
|
||||
int missed_count;
|
||||
int flips;
|
||||
char last_sent_id[12];
|
||||
} switch_rtp_ice_t;
|
||||
|
||||
@@ -784,27 +783,6 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (packet->header.type == SWITCH_STUN_BINDING_ERROR_RESPONSE) {
|
||||
if ((ice->type & ICE_VANILLA)) {
|
||||
if (ice->flips < 4) {
|
||||
if ((ice->type & ICE_CONTROLLED)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Changing role to CONTROLLING\n");
|
||||
ice->type &= ~ICE_CONTROLLED;
|
||||
ice->flips++;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Changing role to CONTROLLED\n");
|
||||
ice->type |= ICE_CONTROLLED;
|
||||
ice->flips++;
|
||||
}
|
||||
packet->header.type = SWITCH_STUN_BINDING_RESPONSE;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
ice->flips = 0;
|
||||
}
|
||||
|
||||
end_buf = buf + ((sizeof(buf) > packet->header.length) ? packet->header.length : sizeof(buf));
|
||||
|
||||
rtp_session->last_stun = switch_micro_time_now();
|
||||
@@ -813,6 +791,30 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
|
||||
|
||||
do {
|
||||
switch (attr->type) {
|
||||
case SWITCH_STUN_ATTR_ERROR_CODE:
|
||||
{
|
||||
switch_stun_error_code_t *err = (switch_stun_error_code_t *) attr->value;
|
||||
uint32_t code = (err->code * 100) + err->number;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "%s got stun binding response %u %s\n",
|
||||
switch_core_session_get_name(rtp_session->session),
|
||||
code,
|
||||
err->reason
|
||||
);
|
||||
|
||||
if ((ice->type & ICE_VANILLA) && code == 487) {
|
||||
if ((ice->type & ICE_CONTROLLED)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Changing role to CONTROLLING\n");
|
||||
ice->type &= ~ICE_CONTROLLED;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Changing role to CONTROLLED\n");
|
||||
ice->type |= ICE_CONTROLLED;
|
||||
}
|
||||
packet->header.type = SWITCH_STUN_BINDING_RESPONSE;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case SWITCH_STUN_ATTR_MAPPED_ADDRESS:
|
||||
if (attr->type) {
|
||||
char ip[16];
|
||||
|
||||
+6
-1
@@ -257,11 +257,16 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_parse(uint8_t *buf, ui
|
||||
*val = ntohl(*val); /* should we do this here? */
|
||||
}
|
||||
break;
|
||||
case SWITCH_STUN_ATTR_ERROR_CODE: /* ErrorCode */
|
||||
{
|
||||
uint32_t *u = (uint32_t *) attr->value;
|
||||
*u = htonl(*u);
|
||||
}
|
||||
break;
|
||||
|
||||
case SWITCH_STUN_ATTR_USERNAME: /* ByteString, multiple of 4 bytes */
|
||||
case SWITCH_STUN_ATTR_PASSWORD: /* ByteString, multiple of 4 bytes */
|
||||
case SWITCH_STUN_ATTR_DATA: /* ByteString */
|
||||
case SWITCH_STUN_ATTR_ERROR_CODE: /* ErrorCode */
|
||||
case SWITCH_STUN_ATTR_TRANSPORT_PREFERENCES: /* TransportPrefs */
|
||||
/*
|
||||
* No length checking here, since we already checked against the padded length
|
||||
|
||||
Reference in New Issue
Block a user