Merge branch 'master' of ssh://git.freeswitch.org:222/freeswitch

This commit is contained in:
Giovanni Maruzzelli committed 2011-08-06 03:30:20 -05:00
commit 38cfa1ff31
14 files changed
+263 -55

No files matched your search

@@ -38,6 +38,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_valet_parking_load);
*/
SWITCH_MODULE_DEFINITION(mod_valet_parking, mod_valet_parking_load, NULL, NULL);
typedef struct {
char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
time_t timeout;
} valet_token_t;
typedef struct {
switch_hash_t *hash;
switch_mutex_t *mutex;
@@ -80,22 +85,65 @@ static switch_status_t valet_on_dtmf(switch_core_session_t *session, void *input
return SWITCH_STATUS_SUCCESS;
}
static void check_timeouts(void)
{
switch_hash_index_t *hi;
const void *var;
void *val;
time_t now;
valet_lot_t *lot;
now = switch_epoch_time_now(NULL);
switch_mutex_lock(globals.mutex);
for (hi = switch_hash_first(NULL, globals.hash); hi; hi = switch_hash_next(hi)) {
switch_hash_index_t *i_hi;
const void *i_var;
void *i_val;
char *i_ext;
valet_token_t *token;
switch_hash_this(hi, &var, NULL, &val);
lot = (valet_lot_t *) val;
switch_mutex_lock(lot->mutex);
top:
for (i_hi = switch_hash_first(NULL, lot->hash); i_hi; i_hi = switch_hash_next(i_hi)) {
switch_hash_this(i_hi, &i_var, NULL, &i_val);
i_ext = (char *) i_var;
token = (valet_token_t *) i_val;
if (token->timeout > 0 && token->timeout < now) {
switch_core_hash_delete(lot->hash, i_ext);
switch_safe_free(token);
goto top;
}
}
switch_mutex_unlock(lot->mutex);
}
switch_mutex_unlock(globals.mutex);
}
static int next_id(valet_lot_t *lot, int min, int max, int in)
{
int i, r = 0, m;
int i, r = 0;
char buf[128] = "";
valet_token_t *token;
if (!min)
if (!min) {
min = 1;
}
switch_mutex_lock(globals.mutex);
for (i = min; (i < max || max == 0); i++) {
switch_snprintf(buf, sizeof(buf), "%d", i);
m = !!switch_core_hash_find(lot->hash, buf);
if ((in && !m) || (!in && m)) {
token = (valet_token_t *) switch_core_hash_find(lot->hash, buf);
if ((in && !token) || (!in && token && !token->timeout)) {
r = i;
break;
}
@@ -116,12 +164,14 @@ SWITCH_STANDARD_APP(valet_parking_function)
char dtmf_buf[128] = "";
int is_auto = 0, play_announce = 1;
const char *var;
valet_token_t *token;
if ((var = switch_channel_get_variable(channel, "valet_announce_slot"))) {
play_announce = switch_true(var);
}
check_timeouts();
if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))
&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 2) {
char *lot_name = argv[0];
@@ -220,9 +270,23 @@ SWITCH_STANDARD_APP(valet_parking_function)
}
switch_mutex_lock(lot->mutex);
if ((uuid = switch_core_hash_find(lot->hash, ext))) {
if ((token = (valet_token_t *) switch_core_hash_find(lot->hash, ext))) {
switch_core_session_t *b_session;
if ((b_session = switch_core_session_locate(uuid))) {
if (token->timeout) {
const char *var = switch_channel_get_variable(channel, "valet_ticket");
if (!strcmp(var, token->uuid)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Valet ticket %s accepted.\n", var);
switch_channel_set_variable(channel, "valet_ticket", NULL);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid token %s\n", token->uuid);
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return;
}
}
if (token && (b_session = switch_core_session_locate(token->uuid))) {
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VALET_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Lot-Name", lot_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Extension", ext);
@@ -231,14 +295,17 @@ SWITCH_STANDARD_APP(valet_parking_function)
switch_channel_event_set_data(switch_core_session_get_channel(b_session), event);
switch_event_fire(&event);
switch_core_session_rwunlock(b_session);
switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), uuid);
token->timeout = 0;
switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), token->uuid);
switch_mutex_unlock(lot->mutex);
return;
}
}
}
token = NULL;
if (!(tmp = switch_channel_get_variable(channel, "valet_hold_music"))) {
tmp = switch_channel_get_hold_music(channel);
}
@@ -249,7 +316,13 @@ SWITCH_STANDARD_APP(valet_parking_function)
music = "silence_stream://-1";
}
dest = switch_core_session_sprintf(session, "set:valet_hold_music=%s,sleep:1000,valet_park:%s %s", music, lot_name, ext);
switch_zmalloc(token, sizeof(*token));
token->timeout = switch_epoch_time_now(NULL) + 10;
switch_set_string(token->uuid, switch_core_session_get_uuid(session));
switch_core_hash_insert(lot->hash, ext, token);
dest = switch_core_session_sprintf(session, "set:valet_ticket=%s,set:valet_hold_music=%s,sleep:1000,valet_park:%s %s",
token->uuid, music, lot_name, ext);
switch_channel_set_variable(channel, "inline_destination", dest);
if (is_auto) {
@@ -263,6 +336,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
if (play_announce) {
switch_ivr_phrase_macro(session, "valet_announce_ext", tmp, NULL, NULL);
}
switch_ivr_session_transfer(b_session, dest, "inline", NULL);
switch_mutex_unlock(lot->mutex);
switch_core_session_rwunlock(b_session);
@@ -286,7 +360,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
}
switch_core_hash_insert(lot->hash, ext, switch_core_session_get_uuid(session));
args.input_callback = valet_on_dtmf;
args.buf = dbuf;
@@ -302,10 +376,6 @@ SWITCH_STANDARD_APP(valet_parking_function)
}
}
switch_mutex_lock(lot->mutex);
switch_core_hash_delete(lot->hash, ext);
switch_mutex_unlock(lot->mutex);
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VALET_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Lot-Name", lot_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Extension", ext);
@@ -4318,7 +4318,7 @@ static int api_list_callback(void *pArg, int argc, char **argv, char **columnNam
{
switch_stream_handle_t *stream = (switch_stream_handle_t *) pArg;
if (!strcasecmp(argv[9], "xml")) {
if (!strcasecmp(argv[10], "xml")) {
stream->write_function(stream, " <message>\n");
stream->write_function(stream, " <created_epoch>%s</created_epoch>\n", argv[0]);
stream->write_function(stream, " <read_epoch>%s</read_epoch>\n", argv[1]);
@@ -4329,9 +4329,10 @@ static int api_list_callback(void *pArg, int argc, char **argv, char **columnNam
stream->write_function(stream, " <uuid>%s</uuid>\n", argv[6]);
stream->write_function(stream, " <cid-name>%s</cid-name>\n", argv[7]);
stream->write_function(stream, " <cid-number>%s</cid-number>\n", argv[8]);
stream->write_function(stream, " <message-len>%s</message-len>\n", argv[9]);
stream->write_function(stream, " </message>\n");
} else {
stream->write_function(stream, "%s:%s:%s:%s:%s:%s:%s:%s:%s\n", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
stream->write_function(stream, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
}
return 0;
@@ -4375,11 +4376,11 @@ SWITCH_STANDARD_API(voicemail_list_api_function)
if (id && domain && profile_name && (profile = get_profile(profile_name))) {
if (uuid) {
sql = switch_mprintf("select created_epoch, read_epoch, username, domain, in_folder, file_path, uuid, cid_name, cid_number, "
sql = switch_mprintf("select created_epoch, read_epoch, username, domain, in_folder, file_path, uuid, cid_name, cid_number, message_len, "
"'%q' from voicemail_msgs where username='%q' and domain='%q' and uuid='%q'",
format, id, domain, uuid);
} else {
sql = switch_mprintf("select created_epoch, read_epoch, username, domain, in_folder, file_path, uuid, cid_name, cid_number, "
sql = switch_mprintf("select created_epoch, read_epoch, username, domain, in_folder, file_path, uuid, cid_name, cid_number, message_len, "
"'%q' from voicemail_msgs where username='%q' and domain='%q'",
format, id, domain);
}
@@ -4390,7 +4391,6 @@ SWITCH_STANDARD_API(voicemail_list_api_function)
vm_execute_sql_callback(profile, profile->mutex, sql, api_list_callback, stream);
switch_safe_free(sql);
update_mwi(profile, id, domain, "inbox");
if (!strcasecmp(format, "xml")) {
stream->write_function(stream, "</voicemail>\n");
+1 -1
View File
@@ -1096,7 +1096,7 @@ void sofia_glue_get_addr(msg_t *msg, char *buf, size_t buflen, int *port);
sofia_destination_t *sofia_glue_get_destination(char *data);
void sofia_glue_free_destination(sofia_destination_t *dst);
switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *user, const char *host, const char *event, const char *contenttype,
const char *body, const char *o_contact, const char *network_ip);
const char *body, const char *o_contact, const char *network_ip, const char *call_id);
char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix);
void sofia_glue_set_extra_headers(switch_channel_t *channel, sip_t const *sip, const char *prefix);
void sofia_info_send_sipfrag(switch_core_session_t *aleg, switch_core_session_t *bleg);
+12 -9
View File
@@ -85,7 +85,7 @@ void sofia_handle_sip_r_notify(switch_core_session_t *session, int status,
sofia_dispatch_event_t *de, tagi_t tags[])
{
if (status >= 300 && sip && sip->sip_call_id) {
if (status >= 300 && sip && sip->sip_call_id && (!sofia_private || !sofia_private->is_call)) {
char *sql;
sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", sip->sip_call_id->i_id);
switch_assert(sql != NULL);
@@ -952,9 +952,8 @@ static void our_sofia_event_callback(nua_event_t event,
}
}
case nua_r_ack:
if (channel) {
if (channel)
switch_channel_set_flag(channel, CF_MEDIA_ACK);
}
break;
case nua_r_shutdown:
if (status >= 200) {
@@ -4969,12 +4968,6 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
sofia_clear_flag(tech_pvt, TFLAG_RECOVERING);
}
if ((status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
const char *val;
if ((val = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(val)) {
nua_notify(nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR("talk"), TAG_END());
}
}
}
end:
@@ -5165,6 +5158,15 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
status = 183;
}
if (channel && (status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
const char *val;
if ((val = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(val)) {
nua_notify(nh, NUTAG_NEWSUB(1), NUTAG_WITH_THIS_MSG(de->data->e_msg),
NUTAG_SUBSTATE(nua_substate_terminated), SIPTAG_EVENT_STR("talk"), TAG_END());
}
}
state_process:
@@ -5840,6 +5842,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_snprintf(st, sizeof(st), "%d", cause);
switch_channel_set_variable(channel, "sip_term_cause", st);
switch_channel_hangup(channel, cause);
ss_state = nua_callstate_terminated;
}
+2 -1
View File
@@ -6319,7 +6319,7 @@ void sofia_glue_free_destination(sofia_destination_t *dst)
}
switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *user, const char *host, const char *event, const char *contenttype,
const char *body, const char *o_contact, const char *network_ip)
const char *body, const char *o_contact, const char *network_ip, const char *call_id)
{
char *id = NULL;
nua_handle_t *nh;
@@ -6376,6 +6376,7 @@ switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *use
TAG_IF(dst->route_uri, NUTAG_PROXY(route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
TAG_IF(event, SIPTAG_EVENT_STR(event)),
TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)),
TAG_IF(contenttype, SIPTAG_CONTENT_TYPE_STR(contenttype)), TAG_IF(body, SIPTAG_PAYLOAD_STR(body)), TAG_END());
switch_safe_free(contact);
+4 -3
View File
@@ -484,10 +484,10 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
}
if (for_everyone) {
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q' "
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q',call_id "
"from sip_registrations where mwi_user='%q' and mwi_host='%q'", stream.data, user, host);
} else if (call_id) {
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q' "
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q',call_id "
"from sip_registrations where mwi_user='%q' and mwi_host='%q' and call_id='%q'", stream.data, user, host, call_id);
}
@@ -1860,6 +1860,7 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char
const char *body = argv[5];
const char *o_contact = argv[2];
const char *network_ip = argv[4];
const char *call_id = argv[6];
char *profile_name = argv[3];
struct mwi_helper *h = (struct mwi_helper *) pArg;
@@ -1871,7 +1872,7 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char
}
}
sofia_glue_send_notify(profile, user, host, event, contenttype, body, o_contact, network_ip);
sofia_glue_send_notify(profile, user, host, event, contenttype, body, o_contact, network_ip, call_id);
if (ext_profile) {
sofia_glue_release_profile(ext_profile);
+1 -1
View File
@@ -519,7 +519,7 @@ void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const cha
event = "reboot";
}
sofia_glue_send_notify(profile, user, host, event, contenttype, body, contact, network_ip);
sofia_glue_send_notify(profile, user, host, event, contenttype, body, contact, network_ip, NULL);
}
int sofia_sla_dialog_del_callback(void *pArg, int argc, char **argv, char **columnNames)