Merge branch 'master' into v1.4.beta

This commit is contained in:
Ken Rice
2013-06-28 10:34:34 -05:00
16 changed files with 246 additions and 74 deletions
+1 -1
View File
@@ -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;
}
+42 -13
View File
@@ -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;
+4 -3
View File
@@ -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);
+21
View File
@@ -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 : "");
+35 -22
View File
@@ -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);
}
+10 -4
View File
@@ -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;
}
+32 -1
View File
@@ -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;
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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