From d364e9f2b81465d40415a67fe11aef3f4bb71a9c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 3 Aug 2011 23:43:41 -0500 Subject: [PATCH 001/354] display fixes and add 2 new cols to channels to store last sent display data --- .../mod_spandsp/mod_spandsp_fax.c | 2 + src/mod/endpoints/mod_sofia/mod_sofia.c | 14 +++++-- src/mod/endpoints/mod_sofia/sofia.c | 17 ++++----- src/switch_core_sqldb.c | 38 ++++++++++++++++--- src/switch_ivr_bridge.c | 16 ++++++++ 5 files changed, 70 insertions(+), 17 deletions(-) diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index 9b36d03cca..34562faadd 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -1570,6 +1570,8 @@ static switch_status_t t38_gateway_on_consume_media(switch_core_session_t *sessi switch_core_session_receive_message(session, &msg); if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session)); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", peer_uuid); switch_channel_event_set_data(channel, event); switch_event_fire(&event); } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 3165484b0e..b7db7985c6 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -2013,13 +2013,21 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi tech_pvt->last_sent_callee_id_name = switch_core_session_strdup(tech_pvt->session, name); tech_pvt->last_sent_callee_id_number = switch_core_session_strdup(tech_pvt->session, number); + switch_channel_set_variable(channel, "last_sent_callee_id_name", name); + switch_channel_set_variable(channel, "last_sent_callee_id_number", number); + + if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE) == SWITCH_STATUS_SUCCESS) { const char *uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Direction", "SEND"); - switch_channel_set_profile_var(channel, "callee_id_name", name); - switch_channel_set_profile_var(channel, "callee_id_number", number); - + + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Sent-Callee-ID-Name", name); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Sent-Callee-ID-Number", number); + + //switch_channel_set_profile_var(channel, "callee_id_name", name); + //switch_channel_set_profile_var(channel, "callee_id_number", number); + if (uuid) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridged-To", uuid); } diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 4ca0e91054..865feebbde 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -952,8 +952,9 @@ 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) { @@ -4968,6 +4969,12 @@ 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: @@ -5158,14 +5165,6 @@ 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_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR("talk"), TAG_END()); - } - } - - state_process: diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 3ef516a80b..ee37c612f9 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1291,10 +1291,12 @@ static void core_event_handler(switch_event_t *event) break; case SWITCH_EVENT_CALL_UPDATE: { - new_sql() = switch_mprintf("update channels set callee_name='%q',callee_num='%q',callee_direction='%q'," + new_sql() = switch_mprintf("update channels set callee_name='%q',callee_num='%q',sent_callee_name='%q',sent_callee_num='%q',callee_direction='%q'," "cid_name='%q',cid_num='%q' where uuid='%s'", switch_event_get_header_nil(event, "caller-callee-id-name"), switch_event_get_header_nil(event, "caller-callee-id-number"), + switch_event_get_header_nil(event, "sent-callee-id-name"), + switch_event_get_header_nil(event, "sent-callee-id-number"), switch_event_get_header_nil(event, "direction"), switch_event_get_header_nil(event, "caller-caller-id-name"), switch_event_get_header_nil(event, "caller-caller-id-number"), @@ -1337,6 +1339,7 @@ static void core_event_handler(switch_event_t *event) case CS_ROUTING: if ((extra_cols = parse_presence_data_cols(event))) { new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q'," + "sent_callee_name='%q',sent_callee_num='%q'," "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q',%s " "where uuid='%s'", switch_event_get_header_nil(event, "channel-state"), @@ -1344,6 +1347,8 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "caller-caller-id-number"), switch_event_get_header_nil(event, "caller-callee-id-name"), switch_event_get_header_nil(event, "caller-callee-id-number"), + switch_event_get_header_nil(event, "sent-callee-id-name"), + switch_event_get_header_nil(event, "sent-callee-id-number"), switch_event_get_header_nil(event, "caller-network-addr"), switch_event_get_header_nil(event, "caller-destination-number"), switch_event_get_header_nil(event, "caller-dialplan"), @@ -1354,7 +1359,8 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "unique-id")); free(extra_cols); } else { - new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q'," + new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q'," + "sent_callee_name='%q',sent_callee_num='%q', callee_num='%q'," "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q' " "where uuid='%s'", switch_event_get_header_nil(event, "channel-state"), @@ -1362,6 +1368,8 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "caller-caller-id-number"), switch_event_get_header_nil(event, "caller-callee-id-name"), switch_event_get_header_nil(event, "caller-callee-id-number"), + switch_event_get_header_nil(event, "sent-callee-id-name"), + switch_event_get_header_nil(event, "sent-callee-id-number"), switch_event_get_header_nil(event, "caller-network-addr"), switch_event_get_header_nil(event, "caller-destination-number"), switch_event_get_header_nil(event, "caller-dialplan"), @@ -1384,6 +1392,15 @@ static void core_event_handler(switch_event_t *event) } case SWITCH_EVENT_CHANNEL_BRIDGE: { + const char *a_uuid, *b_uuid; + + a_uuid = switch_event_get_header(event, "Bridge-A-Unique-ID"); + b_uuid = switch_event_get_header(event, "Bridge-B-Unique-ID"); + + if (zstr(a_uuid) || zstr(b_uuid)) { + a_uuid = switch_event_get_header_nil(event, "caller-unique-id"); + b_uuid = switch_event_get_header_nil(event, "other-leg-unique-id"); + } new_sql() = switch_mprintf("update channels set call_uuid='%q' where uuid='%s'", switch_event_get_header_nil(event, "channel-call-uuid"), @@ -1395,8 +1412,8 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-call-uuid"), switch_event_get_header_nil(event, "event-date-local"), (long) switch_epoch_time_now(NULL), - switch_event_get_header_nil(event, "caller-unique-id"), - switch_event_get_header_nil(event, "Other-Leg-unique-id"), + a_uuid, + b_uuid, switch_core_get_switchname() ); } @@ -1554,7 +1571,9 @@ static char create_channels_sql[] = " callee_name VARCHAR(1024),\n" " callee_num VARCHAR(256),\n" " callee_direction VARCHAR(5),\n" - " call_uuid VARCHAR(256)\n" + " call_uuid VARCHAR(256),\n" + " sent_callee_name VARCHAR(1024),\n" + " sent_callee_num VARCHAR(256)\n" ");\n" "create index chidx1 on channels (hostname);\n" "create index uuindex on channels (uuid);\n" @@ -1650,6 +1669,8 @@ static char detailed_calls_sql[] = "a.callee_num as callee_num," "a.callee_direction as callee_direction," "a.call_uuid as call_uuid," + "a.sent_callee_name as sent_callee_name," + "a.sent_callee_num as sent_callee_num," "b.uuid as b_uuid," "b.direction as b_direction," "b.created as b_created," @@ -1679,6 +1700,8 @@ static char detailed_calls_sql[] = "b.callee_num as b_callee_num," "b.callee_direction as b_callee_direction," "b.call_uuid as b_call_uuid," + "b.sent_callee_name as b_sent_callee_name," + "b.sent_callee_num as b_sent_callee_num," "c.call_created_epoch as call_created_epoch " "from channels a " "left join calls c on a.uuid = c.caller_uuid and a.hostname = c.hostname " @@ -1707,6 +1730,9 @@ static char basic_calls_sql[] = "a.callee_direction as callee_direction," "a.call_uuid as call_uuid," "a.hostname as hostname," + "a.sent_callee_name as sent_callee_name," + "a.sent_callee_num as sent_callee_num," + "b.uuid as b_uuid," "b.direction as b_direction," @@ -1725,6 +1751,8 @@ static char basic_calls_sql[] = "b.callee_name as b_callee_name," "b.callee_num as b_callee_num," "b.callee_direction as b_callee_direction," + "b.sent_callee_name as b_sent_callee_name," + "b.sent_callee_num as b_sent_callee_num," "c.call_created_epoch as call_created_epoch " "from channels a " diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 0fecc309f7..32d1451a6e 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -918,6 +918,8 @@ static switch_status_t signal_bridge_on_hibernate(switch_core_session_t *session if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session)); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", msg.string_arg); switch_channel_event_set_data(channel, event); switch_event_fire(&event); } @@ -1151,6 +1153,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_channel_set_state(peer_channel, CS_CONSUME_MEDIA); if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session)); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", switch_core_session_get_uuid(peer_session)); switch_channel_event_set_data(caller_channel, event); switch_event_fire(&event); br = 1; @@ -1398,6 +1402,18 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu originator_channel = switch_core_session_get_channel(originator_session); originatee_channel = switch_core_session_get_channel(originatee_session); + + if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(originatee_channel, CF_DIALPLAN)) { + switch_channel_flip_cid(originatee_channel); + switch_channel_set_flag(originatee_channel, CF_DIALPLAN); + } + + if (switch_channel_direction(originator_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(originator_channel, CF_DIALPLAN)) { + switch_channel_flip_cid(originator_channel); + switch_channel_set_flag(originator_channel, CF_DIALPLAN); + } + + if (switch_channel_down(originator_channel)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s is hungup refusing to bridge.\n", switch_channel_get_name(originatee_channel)); switch_core_session_rwunlock(originator_session); From bd64631b5c628f0ad5a14d27e1e3d81727e06cb6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 3 Aug 2011 23:47:47 -0500 Subject: [PATCH 002/354] skip looking up session again in hash table when we already are parsing the event from the session thread --- src/mod/endpoints/mod_sofia/mod_sofia.c | 3 +++ src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 6 +++--- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index b7db7985c6..39b71f1f88 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1388,6 +1388,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (msg->message_id == SWITCH_MESSAGE_INDICATE_SIGNAL_DATA) { sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) msg->pointer_arg; switch_mutex_lock(tech_pvt->sofia_mutex); + if (switch_core_session_in_thread(session)) { + de->session = session; + } sofia_process_dispatch_event(&de); switch_mutex_unlock(tech_pvt->sofia_mutex); goto end; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index c20a45e6e4..07c917cbca 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -143,6 +143,7 @@ typedef struct sofia_dispatch_event_s { nua_t *nua; sofia_profile_t *profile; int save; + switch_core_session_t *session; } sofia_dispatch_event_t; struct sofia_private { diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 865feebbde..464f5ff50d 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -818,14 +818,14 @@ static void our_sofia_event_callback(nua_event_t event, return; } } else if (!zstr(sofia_private->uuid)) { - if ((session = switch_core_session_locate(sofia_private->uuid))) { + if ((session = de->session) || (session = switch_core_session_locate(sofia_private->uuid))) { tech_pvt = switch_core_session_get_private(session); channel = switch_core_session_get_channel(session); if (tech_pvt) { switch_mutex_lock(tech_pvt->sofia_mutex); locked = 1; } else { - switch_core_session_rwunlock(session); + if (session != de->session) switch_core_session_rwunlock(session); return; } @@ -1111,7 +1111,7 @@ static void our_sofia_event_callback(nua_event_t event, switch_mutex_unlock(tech_pvt->sofia_mutex); } - if (session) { + if (session && session != de->session) { switch_core_session_rwunlock(session); } } From 61ee7fdc859f13da35a52f9d27d8489ef330153a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 3 Aug 2011 23:49:09 -0500 Subject: [PATCH 003/354] don't allow auto answer on an non-outbound call --- src/mod/endpoints/mod_sofia/mod_sofia.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 39b71f1f88..87817c3c7f 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1881,14 +1881,21 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi case SWITCH_MESSAGE_INDICATE_PHONE_EVENT: { const char *event = "talk"; + if (!zstr(msg->string_arg) && strcasecmp(msg->string_arg, event)) { if (!strcasecmp(msg->string_arg, "hold")) { event = "hold"; - } else { + } else if (strncasecmp(msg->string_arg, "talk", 4)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Invalid event.\n"); } } - nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR(event), TAG_END()); + + if (!switch_channel_test_flag(channel, CF_ANSWERED) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, + "Operation not permitted on an inbound non-answered call leg!\n"); + } else { + nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR(event), TAG_END()); + } } break; case SWITCH_MESSAGE_INDICATE_SIMPLIFY: From f83ec35ab4edeab285b547e8e3a01329e01e1f5d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 3 Aug 2011 23:52:15 -0500 Subject: [PATCH 004/354] FS-3444 revert --- src/mod/endpoints/mod_sofia/sofia.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 464f5ff50d..316c23d369 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -5840,7 +5840,6 @@ 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; } From 0a97462f3f9549f2e28163a43da888470a65d6a1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Aug 2011 00:01:26 -0500 Subject: [PATCH 005/354] FS-3340 revert --- src/mod/endpoints/mod_sofia/sofia_glue.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 062da61a98..54c946ad58 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2427,8 +2427,10 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) if (sofia_use_soa(tech_pvt)) { nua_invite(tech_pvt->nh, NUTAG_AUTOANSWER(0), - TAG_IF(zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(0)), - TAG_IF(!zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(1)), + //TAG_IF(zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(0)), + //TAG_IF(!zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(1)), + // The code above is breaking things...... grrr WE need this because we handle our own acks and there are 3pcc cases in there too + NUTAG_AUTOACK(0), NUTAG_SESSION_TIMER(session_timeout), NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher), TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)), From 8caef22b6c0daf0730de4f9486fccbe6e4dc0536 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Aug 2011 00:02:13 -0500 Subject: [PATCH 006/354] don't add the fs_nat stuff twice when its already there --- src/mod/endpoints/mod_sofia/sofia_reg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 520b4e6849..4b5422fab6 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1218,13 +1218,14 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand if (auto_connectile || (v_contact_str = switch_event_get_header(*v_event, "sip-force-contact"))) { if (auto_connectile || (!strcasecmp(v_contact_str, "NDLB-connectile-dysfunction-2.0"))) { - char *path_encoded; + char *path_encoded = NULL; size_t path_encoded_len; char my_contact_str[1024]; switch_snprintf(my_contact_str, sizeof(my_contact_str), "sip:%s@%s:%d", contact->m_url->url_user, url_ip, network_port); path_encoded_len = (strlen(my_contact_str) * 3) + 1; + if (!switch_stristr("fs_path=", contact_str)) { switch_zmalloc(path_encoded, path_encoded_len); switch_copy_string(path_encoded, ";fs_nat=yes;fs_path=", 21); switch_url_encode(my_contact_str, path_encoded + 20, path_encoded_len - 20); @@ -1237,7 +1238,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand } else { switch_snprintf(contact_str + strlen(contact_str), sizeof(contact_str) - strlen(contact_str), "%s", path_encoded); } - free(path_encoded); + switch_safe_free(path_encoded); + } } else { if (*received_data && sofia_test_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT)) { switch_snprintf(received_data, sizeof(received_data), ";received=%s:%d", url_ip, network_port); From b946ee94b2584aaf9b939507ea0489d770c7aea3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Aug 2011 01:04:21 -0500 Subject: [PATCH 007/354] update call_uuid stuff --- src/switch_channel.c | 2 ++ src/switch_core_session.c | 4 ++++ src/switch_core_sqldb.c | 14 +++++++++++--- src/switch_core_state_machine.c | 5 +++++ src/switch_ivr_bridge.c | 6 ++++++ src/switch_ivr_originate.c | 32 +++++--------------------------- 6 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index 3f96616794..bd2f84b779 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2121,6 +2121,8 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann if ((v = switch_channel_get_variable(channel, "call_uuid"))) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-UUID", v); + } else { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-UUID", switch_core_session_get_uuid(channel->session)); } if (switch_channel_down(channel)) { diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 168bec3695..23aa8bed52 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1427,6 +1427,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_uuid(switch_core_session profile->uuid = switch_core_strdup(profile->pool, use_uuid); } + switch_channel_set_variable(session->channel, "uuid", use_uuid); + switch_channel_set_variable(session->channel, "call_uuid", use_uuid); + switch_event_create(&event, SWITCH_EVENT_CHANNEL_UUID); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Old-Unique-ID", session->uuid_str); switch_core_hash_delete(session_manager.session_table, session->uuid_str); @@ -1729,6 +1732,7 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_ } switch_channel_set_variable(session->channel, "uuid", session->uuid_str); + switch_channel_set_variable(session->channel, "call_uuid", session->uuid_str); session->endpoint_interface = endpoint_interface; session->raw_write_frame.data = session->raw_write_buf; diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index ee37c612f9..897cbe9ebd 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1221,6 +1221,11 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "unique-id"), switch_event_get_header_nil(event, "old-unique-id") ); + + new_sql() = switch_mprintf("update channels set call_uuid='%q' where call_uuid='%q'", + switch_event_get_header_nil(event, "unique-id"), + switch_event_get_header_nil(event, "old-unique-id") + ); break; } case SWITCH_EVENT_CHANNEL_CREATE: @@ -1402,9 +1407,9 @@ static void core_event_handler(switch_event_t *event) b_uuid = switch_event_get_header_nil(event, "other-leg-unique-id"); } - new_sql() = switch_mprintf("update channels set call_uuid='%q' where uuid='%s'", - switch_event_get_header_nil(event, "channel-call-uuid"), - switch_event_get_header_nil(event, "unique-id")); + new_sql() = switch_mprintf("update channels set call_uuid='%q' where uuid='%s' or uuid='%s'", + switch_event_get_header_nil(event, "channel-call-uuid"), a_uuid, b_uuid); + new_sql() = switch_mprintf("insert into calls (call_uuid,call_created,call_created_epoch," "caller_uuid,callee_uuid,hostname) " @@ -1422,6 +1427,9 @@ static void core_event_handler(switch_event_t *event) { char *uuid = switch_event_get_header_nil(event, "caller-unique-id"); + new_sql() = switch_mprintf("update channels set call_uuid=uuid where call_uuid='%s'", + switch_event_get_header_nil(event, "channel-call-uuid")); + new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q')", uuid, uuid); break; diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 2e45dde559..1ab9af91a9 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -62,6 +62,7 @@ static void switch_core_standard_on_destroy(switch_core_session_t *session) static void switch_core_standard_on_reset(switch_core_session_t *session) { + switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session)); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard RESET\n", switch_channel_get_name(session->channel)); } @@ -76,6 +77,8 @@ static void switch_core_standard_on_routing(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard ROUTING\n", switch_channel_get_name(session->channel)); + switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session)); + if ((switch_channel_test_flag(session->channel, CF_ANSWERED) || switch_channel_test_flag(session->channel, CF_EARLY_MEDIA) || switch_channel_test_flag(session->channel, CF_SIGNAL_BRIDGE_TTL)) && switch_channel_test_flag(session->channel, CF_PROXY_MODE)) { @@ -156,6 +159,8 @@ static void switch_core_standard_on_execute(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard EXECUTE\n", switch_channel_get_name(session->channel)); + switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session)); + if (switch_channel_get_variable(session->channel, "recovered") && !switch_channel_test_flag(session->channel, CF_RECOVERED)) { switch_channel_set_flag(session->channel, CF_RECOVERED); } diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 32d1451a6e..9dbd4aecab 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -968,6 +968,7 @@ static switch_status_t signal_bridge_on_hangup(switch_core_session_t *session) switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL); switch_channel_set_variable(other_channel, SWITCH_BRIDGE_VARIABLE, NULL); + switch_channel_set_variable(other_channel, "call_uuid", switch_core_session_get_uuid(other_session)); if (switch_channel_up(other_channel)) { @@ -1044,6 +1045,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t * switch_channel_set_variable(caller_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, switch_core_session_get_uuid(peer_session)); switch_channel_set_variable(peer_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, switch_core_session_get_uuid(session)); + switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(session)); switch_channel_set_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR); switch_channel_clear_flag(peer_channel, CF_BRIDGE_ORIGINATOR); @@ -1152,6 +1154,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_channel_set_state(peer_channel, CS_CONSUME_MEDIA); + switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(session)); + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session)); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", switch_core_session_get_uuid(peer_session)); @@ -1303,6 +1307,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses done: + switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(peer_session)); + if (br && switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(caller_channel, event); switch_event_fire(&event); diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index cf0fca1d9d..6df4f40782 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1843,33 +1843,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } - if (var_event) { - switch_uuid_t uuid; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - char *use_uuid; - - if (caller_channel) { - use_uuid = switch_core_session_get_uuid(session); - } else { - switch_uuid_get(&uuid); - switch_uuid_format(uuid_str, &uuid); - use_uuid = uuid_str; - } - - switch_event_del_header(var_event, "call_uuid"); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "call_uuid", use_uuid); - - if (caller_channel) { - switch_channel_set_variable(caller_channel, "call_uuid", use_uuid); - } - } - - if (caller_channel) { - switch_channel_process_export(caller_channel, NULL, var_event, SWITCH_EXPORT_VARS_VARIABLE); - } - - - /* strip leading spaces */ while (data && *data && *data == ' ') { data++; @@ -2478,6 +2451,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess originate_status[i].peer_session = new_session; switch_channel_set_flag(originate_status[i].peer_channel, CF_ORIGINATING); + + if (caller_channel) { + switch_channel_set_variable(originate_status[i].peer_channel, "call_uuid", switch_channel_get_variable(caller_channel, "call_uuid")); + } + if ((lc = switch_event_get_header(var_event, "local_var_clobber"))) { local_clobber = switch_true(lc); From bfabc98f3daa190dfb4a9521151e7f8a6597ff24 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 4 Aug 2011 10:09:28 -0400 Subject: [PATCH 008/354] freetdm: more CLI improvements --- libs/freetdm/mod_freetdm/mod_freetdm.c | 144 ++++++++++++++----------- 1 file changed, 79 insertions(+), 65 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 5117c6dbe8..c3ca4786d5 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -3790,16 +3790,21 @@ void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t * switch_channel_cause2str(caller_data->hangup_cause)); } +typedef struct ftdm_cli_entry ftdm_cli_entry_t; +typedef switch_status_t (*ftdm_cli_function_t)(ftdm_cli_entry_t *cli, const char *cmd, switch_core_session_t *session, + switch_stream_handle_t *stream, int argc, char *argv[]); +#define FTDM_CLI_DECLARE(name) static switch_status_t name(ftdm_cli_entry_t *cli, const char *cmd, \ + switch_core_session_t *session, switch_stream_handle_t *stream, \ + int argc, char *argv[]) +static void print_usage(switch_stream_handle_t *stream, ftdm_cli_entry_t *cli); -static switch_status_t ftdm_cmd_voice_detect(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]) +FTDM_CLI_DECLARE(ftdm_cmd_voice_detect) { - stream->write_function(stream, "IMPLEMENT ME!\n"); + print_usage(stream, cli); return SWITCH_STATUS_SUCCESS; } -static switch_status_t ftdm_cmd_list(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]) +FTDM_CLI_DECLARE(ftdm_cmd_list) { int j; for (j = 0 ; j < FTDM_MAX_SPANS_INTERFACE; j++) { @@ -3876,19 +3881,20 @@ static switch_status_t ftdm_cmd_list(const char *cmd, switch_core_session_t *ses return SWITCH_STATUS_SUCCESS; } -static switch_status_t ftdm_cmd_start_stop(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]) +FTDM_CLI_DECLARE(ftdm_cmd_start_stop) { char *span_name = argv[1]; ftdm_span_t *span = NULL; ftdm_status_t status; - if (span_name) { - ftdm_span_find_by_name(span_name, &span); + if (argc < 2) { + print_usage(stream, cli); + goto end; } + ftdm_span_find_by_name(span_name, &span); if (!span) { - stream->write_function(stream, "-ERR no span\n"); + stream->write_function(stream, "-ERR span %s not found\n", span_name); goto end; } @@ -3903,34 +3909,36 @@ end: return SWITCH_STATUS_SUCCESS; } -static switch_status_t ftdm_cmd_reset(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]) +FTDM_CLI_DECLARE(ftdm_cmd_reset) { uint32_t chan_id = 0; uint32_t ccount = 0; ftdm_channel_t *chan; ftdm_span_t *span = NULL; + if (argc < 2) { - stream->write_function(stream, "-ERR Usage: ftdm reset []\n"); + print_usage(stream, cli); goto end; } + ftdm_span_find_by_name(argv[1], &span); if (!span) { - stream->write_function(stream, "-ERR invalid span\n"); + stream->write_function(stream, "-ERR span %s not found\n", argv[1]); goto end; } if (argc > 2) { chan_id = atoi(argv[2]); if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "-ERR invalid chan\n"); + stream->write_function(stream, "-ERR invalid channel %d\n", chan_id); goto end; } } + if (chan_id) { chan = ftdm_span_get_channel(span, chan_id); if (!chan) { - stream->write_function(stream, "-ERR Could not find chan\n"); + stream->write_function(stream, "-ERR Could not find channel %d\n", chan_id); goto end; } stream->write_function(stream, "Resetting channel %s:%s\n", argv[1], argv[2]); @@ -3950,8 +3958,7 @@ end: return SWITCH_STATUS_SUCCESS; } -static switch_status_t ftdm_cmd_dump(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]) +FTDM_CLI_DECLARE(ftdm_cmd_dump) { ftdm_iterator_t *chaniter = NULL; ftdm_iterator_t *curr = NULL; @@ -3960,12 +3967,11 @@ static switch_status_t ftdm_cmd_dump(const char *cmd, switch_core_session_t *ses char *as = NULL; if (argc < 2) { - stream->write_function(stream, "-ERR Usage: ftdm dump []\n"); + print_usage(stream, cli); goto end; } ftdm_span_find_by_name(argv[1], &span); - if (argc > 2) { if (argv[3] && !strcasecmp(argv[2], "as")) { as = argv[3]; @@ -4028,28 +4034,29 @@ end: return SWITCH_STATUS_SUCCESS; } -static switch_status_t ftdm_cmd_sigstatus(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]) +FTDM_CLI_DECLARE(ftdm_cmd_sigstatus) { ftdm_span_t *span = NULL; ftdm_signaling_status_t sigstatus; if (argc < 3) { - stream->write_function(stream, "-ERR Usage: ftdm sigstatus get|set [] [] []\n"); + print_usage(stream, cli); goto end; } + if (!strcasecmp(argv[1], "get") && argc < 3) { - stream->write_function(stream, "-ERR sigstatus get usage: get \n"); + print_usage(stream, cli); goto end; } + if (!strcasecmp(argv[1], "set") && argc != 5) { - stream->write_function(stream, "-ERR sigstatus set usage: set |all \n"); + print_usage(stream, cli); goto end; } ftdm_span_find_by_name(argv[2], &span); if (!span) { - stream->write_function(stream, "-ERR invalid span\n"); + stream->write_function(stream, "-ERR invalid span %s\n", argv[2]); goto end; } @@ -4058,21 +4065,21 @@ static switch_status_t ftdm_cmd_sigstatus(const char *cmd, switch_core_session_t uint32_t chan_id = atol(argv[3]); ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id); if (!fchan) { - stream->write_function(stream, "-ERR failed to get channel id '%d'\n", chan_id); + stream->write_function(stream, "-ERR invalid channel id '%d'\n", chan_id); goto end; } if ((FTDM_SUCCESS == ftdm_channel_get_sig_status(fchan, &sigstatus))) { - stream->write_function(stream, "channel %d signaling status: %s\n", chan_id, ftdm_signaling_status2str(sigstatus)); + stream->write_function(stream, "Channel %d signaling status: %s\n", chan_id, ftdm_signaling_status2str(sigstatus)); } else { - stream->write_function(stream, "-ERR failed to get channel sigstatus\n"); + stream->write_function(stream, "-ERR failed to get channel signaling status\n"); } goto end; } else { if ((FTDM_SUCCESS == ftdm_span_get_sig_status(span, &sigstatus))) { stream->write_function(stream, "signaling_status: %s\n", ftdm_signaling_status2str(sigstatus)); } else { - stream->write_function(stream, "-ERR failed to read span status: %s\n", ftdm_span_get_last_error(span)); + stream->write_function(stream, "-ERR failed to read span signaling status: %s\n", ftdm_span_get_last_error(span)); } } goto end; @@ -4110,8 +4117,7 @@ end: return SWITCH_STATUS_SUCCESS; } -static switch_status_t ftdm_cmd_trace(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]) +FTDM_CLI_DECLARE(ftdm_cmd_trace) { char tracepath[255]; unsigned i = 0; @@ -4121,19 +4127,19 @@ static switch_status_t ftdm_cmd_trace(const char *cmd, switch_core_session_t *se ftdm_span_t *span = NULL; ftdm_channel_t *chan = NULL; if (argc < 3) { - stream->write_function(stream, "-ERR Usage: ftdm trace []\n"); + print_usage(stream, cli); goto end; } ftdm_span_find_by_name(argv[2], &span); if (!span) { - stream->write_function(stream, "-ERR invalid span\n"); + stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]); goto end; } chan_count = ftdm_span_get_chan_count(span); if (argc > 3) { chan_id = atoi(argv[3]); if (chan_id > chan_count) { - stream->write_function(stream, "-ERR invalid chan\n"); + stream->write_function(stream, "-ERR invalid channel\n"); goto end; } } @@ -4158,31 +4164,33 @@ end: return SWITCH_STATUS_SUCCESS; } -static switch_status_t ftdm_cmd_notrace(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]) +FTDM_CLI_DECLARE(ftdm_cmd_notrace) { uint32_t i = 0; uint32_t chan_id = 0; uint32_t chan_count = 0; ftdm_channel_t *fchan = NULL; ftdm_span_t *span = NULL; + if (argc < 2) { - stream->write_function(stream, "-ERR Usage: ftdm notrace []\n"); + print_usage(stream, cli); goto end; } ftdm_span_find_by_name(argv[1], &span); if (!span) { - stream->write_function(stream, "-ERR invalid span\n"); + stream->write_function(stream, "-ERR failed to find span %s\n", argv[1]); goto end; } + chan_count = ftdm_span_get_chan_count(span); if (argc > 2) { chan_id = atoi(argv[2]); if (chan_id > chan_count) { - stream->write_function(stream, "-ERR invalid chan\n"); + stream->write_function(stream, "-ERR invalid channel\n"); goto end; } } + if (chan_id) { fchan = ftdm_span_get_channel(span, chan_id); ftdm_channel_command(fchan, FTDM_COMMAND_TRACE_END_ALL, NULL); @@ -4193,12 +4201,12 @@ static switch_status_t ftdm_cmd_notrace(const char *cmd, switch_core_session_t * } } stream->write_function(stream, "+OK trace disabled\n"); + end: return SWITCH_STATUS_SUCCESS; } -static switch_status_t ftdm_cmd_gains(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]) +FTDM_CLI_DECLARE(ftdm_cmd_gains) { unsigned int i = 0; float txgain = 0.0; @@ -4208,18 +4216,19 @@ static switch_status_t ftdm_cmd_gains(const char *cmd, switch_core_session_t *se ftdm_channel_t *chan; ftdm_span_t *span = NULL; if (argc < 4) { - stream->write_function(stream, "-ERR Usage: ftdm gains []\n"); + print_usage(stream, cli); goto end; } ftdm_span_find_by_name(argv[3], &span); if (!span) { - stream->write_function(stream, "-ERR invalid span\n"); + stream->write_function(stream, "-ERR failed to find span %s\n", argv[3]); goto end; } + if (argc > 4) { chan_id = atoi(argv[4]); if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "-ERR invalid chan\n"); + stream->write_function(stream, "-ERR invalid channel\n"); goto end; } } @@ -4247,8 +4256,7 @@ end: return SWITCH_STATUS_SUCCESS; } -static switch_status_t ftdm_cmd_dtmf(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]) +FTDM_CLI_DECLARE(ftdm_cmd_dtmf) { unsigned i = 0; uint32_t chan_id = 0; @@ -4256,8 +4264,9 @@ static switch_status_t ftdm_cmd_dtmf(const char *cmd, switch_core_session_t *ses ftdm_span_t *span = NULL; ftdm_command_t fcmd = FTDM_COMMAND_ENABLE_DTMF_DETECT; ftdm_channel_t *fchan; + if (argc < 3) { - stream->write_function(stream, "-ERR Usage: dtmf on|off []\n"); + print_usage(stream, cli); goto end; } @@ -4269,14 +4278,15 @@ static switch_status_t ftdm_cmd_dtmf(const char *cmd, switch_core_session_t *ses ftdm_span_find_by_name(argv[2], &span); if (!span) { - stream->write_function(stream, "-ERR invalid span\n"); + stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]); goto end; } + schan_count = ftdm_span_get_chan_count(span); if (argc > 3) { chan_id = atoi(argv[3]); if (chan_id > schan_count) { - stream->write_function(stream, "-ERR invalid chan\n"); + stream->write_function(stream, "-ERR invalid channel\n"); goto end; } } @@ -4296,8 +4306,7 @@ end: return SWITCH_STATUS_SUCCESS; } -static switch_status_t ftdm_cmd_queuesize(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]) +FTDM_CLI_DECLARE(ftdm_cmd_queuesize) { unsigned int i = 0; uint32_t rxsize = 10; @@ -4307,21 +4316,24 @@ static switch_status_t ftdm_cmd_queuesize(const char *cmd, switch_core_session_t ftdm_channel_t *chan; ftdm_span_t *span = NULL; if (argc < 4) { - stream->write_function(stream, "-ERR Usage: ftdm queuesize []\n"); + print_usage(stream, cli); goto end; } + ftdm_span_find_by_name(argv[3], &span); if (!span) { - stream->write_function(stream, "-ERR invalid span\n"); + stream->write_function(stream, "-ERR failed to find span %s\n", argv[3]); goto end; } + if (argc > 4) { chan_id = atoi(argv[4]); if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "-ERR invalid chan\n"); + stream->write_function(stream, "-ERR invalid channel\n"); goto end; } } + i = sscanf(argv[1], "%u", &rxsize); i += sscanf(argv[2], "%u", &txsize); if (i != 2) { @@ -4375,8 +4387,7 @@ static void exec_io_command(const char *cmd, switch_stream_handle_t *stream, ftd } } -static switch_status_t ftdm_cmd_iostats(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]) +FTDM_CLI_DECLARE(ftdm_cmd_iostats) { uint32_t chan_id = 0; ftdm_channel_t *chan; @@ -4385,20 +4396,20 @@ static switch_status_t ftdm_cmd_iostats(const char *cmd, switch_core_session_t * ftdm_span_t *span = NULL; if (argc < 3) { - stream->write_function(stream, "-ERR Usage: ftdm iostats enable|disable|flush|print []\n"); + print_usage(stream, cli); goto end; } ftdm_span_find_by_name(argv[2], &span); if (!span) { - stream->write_function(stream, "-ERR invalid span\n"); + stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]); goto end; } if (argc > 3) { chan_id = atoi(argv[3]); if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "-ERR invalid chan\n"); + stream->write_function(stream, "-ERR invalid channel\n"); goto end; } chan = ftdm_span_get_channel(span, chan_id); @@ -4416,14 +4427,12 @@ end: return SWITCH_STATUS_SUCCESS; } -typedef switch_status_t (*ftdm_cli_function_t)(const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]); -typedef struct ftdm_cli_entry { +struct ftdm_cli_entry { const char *name; const char *args; const char *complete; ftdm_cli_function_t execute; -} ftdm_cli_entry_t; +}; static ftdm_cli_entry_t ftdm_cli_options[] = { @@ -4448,6 +4457,11 @@ static ftdm_cli_entry_t ftdm_cli_options[] = { "core calls", "", "", NULL }, }; +static void print_usage(switch_stream_handle_t *stream, ftdm_cli_entry_t *cli) +{ + stream->write_function(stream, "-ERR Usage: ftdm %s %s\n", cli->name, cli->args); +} + static void print_full_usage(switch_stream_handle_t *stream) { int i = 0; @@ -4480,7 +4494,7 @@ SWITCH_STANDARD_API(ft_function) for (i = 0 ; i < ftdm_array_len(ftdm_cli_options); i++) { entry = &ftdm_cli_options[i]; if (!strcasecmp(argv[0], entry->name) && entry->execute) { - entry->execute(cmd, session, stream, argc, argv); + entry->execute(entry, cmd, session, stream, argc, argv); break; } } From 2eae19e63f04459187179d1529a5e367ff921b29 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Aug 2011 09:38:45 -0500 Subject: [PATCH 009/354] FS-3484 --resolve --- src/switch_core_session.c | 1 - src/switch_ivr_originate.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 23aa8bed52..fc03ab6f10 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -530,7 +530,6 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_ switch_channel_set_variable(peer_channel, SWITCH_ORIGINATOR_VARIABLE, switch_core_session_get_uuid(session)); switch_channel_set_variable(peer_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(session)); - switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(*new_session)); if ((val = switch_channel_get_variable(channel, SWITCH_PROCESS_CDR_VARIABLE))) { switch_channel_set_variable(peer_channel, SWITCH_PROCESS_CDR_VARIABLE, val); diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 6df4f40782..48b75090d7 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -3413,6 +3413,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_channel_set_originatee_caller_profile(caller_channel, cloned_profile); } } + + switch_channel_set_variable(caller_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(*bleg)); } From dee0f540269e07d00a4b6589fce94cf38eea4643 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Aug 2011 09:50:23 -0500 Subject: [PATCH 010/354] FS-3483 --resolve --- src/switch_ivr_originate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 48b75090d7..938be90db2 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -2346,7 +2346,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } new_profile->callee_id_name = switch_core_strdup(new_profile->pool, "Outbound Call"); - new_profile->callee_id_number = switch_core_strdup(new_profile->pool, new_profile->destination_number); + new_profile->callee_id_number = switch_sanitize_number(switch_core_strdup(new_profile->pool, new_profile->destination_number)); originate_status[i].caller_profile = NULL; originate_status[i].peer_channel = NULL; From b952b2b2d9111ae963067f20a667c472c4d77aea Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Thu, 4 Aug 2011 19:53:18 +0200 Subject: [PATCH 011/354] remove pointless update_mwi() in vm_list api command --- src/mod/applications/mod_voicemail/mod_voicemail.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index d896527d7d..1ce5ecccd1 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -4390,7 +4390,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, "\n"); From 77c5000dad6154231fa2b9eb59d77f3187670800 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Thu, 4 Aug 2011 20:17:15 +0200 Subject: [PATCH 012/354] add message_len to output of vm_list api command --- src/mod/applications/mod_voicemail/mod_voicemail.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 1ce5ecccd1..2eb89ebc43 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -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, " \n"); stream->write_function(stream, " %s\n", argv[0]); stream->write_function(stream, " %s\n", argv[1]); @@ -4329,9 +4329,10 @@ static int api_list_callback(void *pArg, int argc, char **argv, char **columnNam stream->write_function(stream, " %s\n", argv[6]); stream->write_function(stream, " %s\n", argv[7]); stream->write_function(stream, " %s\n", argv[8]); + stream->write_function(stream, " %s\n", argv[9]); stream->write_function(stream, " \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); } From 3e2c662a882aae0d447f489df7b4a6d9dbe4f71e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Aug 2011 17:20:02 -0500 Subject: [PATCH 013/354] clean up originator/ee profile so the right one is prevelant in events --- src/switch_channel.c | 32 +++++++++++++++++--------------- src/switch_ivr_bridge.c | 4 ++++ 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index bd2f84b779..72aa68ea7f 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -110,6 +110,12 @@ typedef enum { OCF_HANGUP = (1 << 0) } opaque_channel_flag_t; +typedef enum { + LP_NEITHER, + LP_ORIGINATOR, + LP_ORIGINATEE +} switch_originator_type_t; + struct switch_channel { char *name; switch_call_direction_t direction; @@ -139,6 +145,7 @@ struct switch_channel { int event_count; int profile_index; opaque_channel_flag_t opaque_flags; + switch_originator_type_t last_profile_type; }; @@ -2156,23 +2163,16 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann switch_caller_profile_event_set_data(caller_profile, "Caller", event); } - if (originator_caller_profile && originatee_caller_profile) { - /* Index Originator's Profile */ - switch_caller_profile_event_set_data(originator_caller_profile, "Originator", event); - - /* Index Originatee's Profile */ - switch_caller_profile_event_set_data(originatee_caller_profile, "Originatee", event); - } else { - /* Index Originator's Profile */ - if (originator_caller_profile) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Type", "originator"); - switch_caller_profile_event_set_data(originator_caller_profile, "Other-Leg", event); - } else if (originatee_caller_profile) { /* Index Originatee's Profile */ - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Type", "originatee"); - switch_caller_profile_event_set_data(originatee_caller_profile, "Other-Leg", event); - } + /* Index Originator/ee's Profile */ + if (originator_caller_profile && channel->last_profile_type == LP_ORIGINATOR) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Type", "originator"); + switch_caller_profile_event_set_data(originator_caller_profile, "Other-Leg", event); + } else if (originatee_caller_profile && channel->last_profile_type == LP_ORIGINATEE) { /* Index Originatee's Profile */ + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Type", "originatee"); + switch_caller_profile_event_set_data(originatee_caller_profile, "Other-Leg", event); } + switch_mutex_unlock(channel->profile_mutex); } @@ -2342,6 +2342,7 @@ SWITCH_DECLARE(void) switch_channel_set_originator_caller_profile(switch_channel if (channel->caller_profile) { caller_profile->next = channel->caller_profile->originator_caller_profile; channel->caller_profile->originator_caller_profile = caller_profile; + channel->last_profile_type = LP_ORIGINATOR; } switch_assert(channel->caller_profile->originator_caller_profile->next != channel->caller_profile->originator_caller_profile); switch_mutex_unlock(channel->profile_mutex); @@ -2402,6 +2403,7 @@ SWITCH_DECLARE(void) switch_channel_set_originatee_caller_profile(switch_channel if (channel->caller_profile) { caller_profile->next = channel->caller_profile->originatee_caller_profile; channel->caller_profile->originatee_caller_profile = caller_profile; + channel->last_profile_type = LP_ORIGINATEE; } switch_assert(channel->caller_profile->originatee_caller_profile->next != channel->caller_profile->originatee_caller_profile); switch_mutex_unlock(channel->profile_mutex); diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 9dbd4aecab..b1726e9119 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -997,6 +997,8 @@ static switch_status_t signal_bridge_on_hangup(switch_core_session_t *session) if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { switch_channel_clear_flag_recursive(channel, CF_BRIDGE_ORIGINATOR); if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session)); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", uuid); switch_channel_event_set_data(channel, event); switch_event_fire(&event); } @@ -1310,6 +1312,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(peer_session)); if (br && switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session)); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", switch_core_session_get_uuid(peer_session)); switch_channel_event_set_data(caller_channel, event); switch_event_fire(&event); } From 308f44af2e59623f9b9fd1bb6329953781307a42 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Aug 2011 16:12:17 -0500 Subject: [PATCH 014/354] make valet parking reserve a space for 10 seconds to allow time for an attended transfer switcharoo --- .../mod_valet_parking/mod_valet_parking.c | 102 +++++++++++++++--- 1 file changed, 86 insertions(+), 16 deletions(-) diff --git a/src/mod/applications/mod_valet_parking/mod_valet_parking.c b/src/mod/applications/mod_valet_parking/mod_valet_parking.c index 14412bc318..3e8337d857 100644 --- a/src/mod/applications/mod_valet_parking/mod_valet_parking.c +++ b/src/mod/applications/mod_valet_parking/mod_valet_parking.c @@ -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); From 714195b8f26ed325ac0100dfd02befb6cdbdcbb8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Aug 2011 16:34:01 -0500 Subject: [PATCH 015/354] FS-3487 gonna guess, try this... --- src/mod/endpoints/mod_sofia/sofia.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 316c23d369..7a5fe8fc74 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -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,14 @@ 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_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR("talk"), TAG_END()); + } + } + + state_process: From ef1accf70738d12749688a61b54064a0422c2982 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Aug 2011 20:26:23 -0500 Subject: [PATCH 016/354] FS-3487 --resolve --- src/mod/endpoints/mod_sofia/sofia.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 7a5fe8fc74..7932eeed8b 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -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); @@ -5161,7 +5161,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, 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_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR("talk"), TAG_END()); + 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()); } } From b3208f5cdc1c74a5975f33e7c81d91476379c8c6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Aug 2011 20:27:54 -0500 Subject: [PATCH 017/354] FS-3444 --resolve with previous commit this can come back --- src/mod/endpoints/mod_sofia/sofia.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 7932eeed8b..318ca29b7b 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -5842,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; } From 885203a461fe831247de6bd8bc5dfee04c9d5b3d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Aug 2011 22:32:06 -0500 Subject: [PATCH 018/354] add event header --- src/switch_channel.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/switch_channel.c b/src/switch_channel.c index 72aa68ea7f..7dd43672a9 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -1847,6 +1847,10 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state( switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Presence-Call-Direction", channel->direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-HIT-Dialplan", + switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND || + switch_channel_test_flag(channel, CF_DIALPLAN) ? "true" : "false"); + if (switch_channel_down(channel)) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "hangup"); } else if (switch_channel_test_flag(channel, CF_ANSWERED)) { @@ -2113,6 +2117,11 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Presence-Call-Direction", channel->direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-HIT-Dialplan", + switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND || + switch_channel_test_flag(channel, CF_DIALPLAN) ? "true" : "false"); + + if ((v = switch_channel_get_variable(channel, "presence_id"))) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Presence-ID", v); } From 88a681d47c5b2d46c2f11bb3ef276d1d70916e6e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Aug 2011 23:21:38 -0500 Subject: [PATCH 019/354] fix typo in sql stmt --- src/switch_core_sqldb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 897cbe9ebd..a55d3ee905 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1364,8 +1364,8 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "unique-id")); free(extra_cols); } else { - new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q'," - "sent_callee_name='%q',sent_callee_num='%q', callee_num='%q'," + new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q'," + "sent_callee_name='%q',sent_callee_num='%q'," "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q' " "where uuid='%s'", switch_event_get_header_nil(event, "channel-state"), @@ -1511,6 +1511,7 @@ static void core_event_handler(switch_event_t *event) if (sql_idx) { int i = 0; + for (i = 0; i < sql_idx; i++) { if (switch_stristr("update channels", sql[i]) || switch_stristr("delete from channels", sql[i])) { From 0f459d4b4545398f0def0bd70a1cf0c37c0705ac Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 5 Aug 2011 09:31:21 -0500 Subject: [PATCH 020/354] check for answer flag in bridge to do display update properly --- src/switch_core.c | 2 +- src/switch_ivr_bridge.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/switch_core.c b/src/switch_core.c index e7cd60d58f..37784193b0 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1449,7 +1449,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS; runtime.tipping_point = 0; - runtime.timer_affinity = -1; + runtime.timer_affinity = 0; runtime.microseconds_per_tick = 20000; switch_load_core_config("switch.conf"); diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index b1726e9119..fb8b89096d 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -457,6 +457,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) } } + if (originator && !ans_b) ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED); + if (originator && !sent_update && ans_a && ans_b && switch_channel_media_ack(chan_a) && switch_channel_media_ack(chan_b)) { switch_ivr_bridge_display(session_a, session_b); sent_update = 1; From 54feb3e245f0c8fa00afeef42507f338178c48ee Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 5 Aug 2011 09:32:23 -0500 Subject: [PATCH 021/354] revert, didn't mean to commit that one --- src/switch_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core.c b/src/switch_core.c index 37784193b0..e7cd60d58f 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1449,7 +1449,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS; runtime.tipping_point = 0; - runtime.timer_affinity = 0; + runtime.timer_affinity = -1; runtime.microseconds_per_tick = 20000; switch_load_core_config("switch.conf"); From 53b0ecce6009db3247fcfa3369e11887d2fe64b7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 5 Aug 2011 11:09:45 -0500 Subject: [PATCH 022/354] use the call_id of the original register in the unsolicited notify for MWI --- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 +- src/mod/endpoints/mod_sofia/sofia_glue.c | 3 ++- src/mod/endpoints/mod_sofia/sofia_presence.c | 7 ++++--- src/mod/endpoints/mod_sofia/sofia_reg.c | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 07c917cbca..a7bd1e6843 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -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); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 54c946ad58..006f002334 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -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); diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index a85138b8f6..f7b7a0aa84 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -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); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 4b5422fab6..1d014aff80 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -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) From 2ecf2d6e62ac37fea8facd0a824e3ddf59910916 Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Fri, 5 Aug 2011 22:50:58 -0400 Subject: [PATCH 023/354] freetdm/libpri: Add support to change status of an individual channel or multiple channel. This allow to put bchannel out of service on an active T1 without affecting active call. Allow graceful out of service of T1 trunk. NOTE: There is bugs in libpri, even latest 1.4.12 as of this writing if you use NI2. So rightnow it only work in DMS100/ATT mode. Email me to get the NI2 patch (really stupid error). NOTE2: The way libpri is build doesn't allow to do advance feature with the SERVICE feature, so if you put an channel out of service, and the far end send an restart, it will be bring back in service. Lot of changes in libpri is required to allow this. I need to figure out what would be the best steps to take since I don't have commit access to libpri release. NOTE3: You need to enable this feature by setting service_message_support to true on the span --- .../src/ftmod/ftmod_libpri/ftmod_libpri.c | 108 ++++++++++++++++++ .../src/ftmod/ftmod_libpri/ftmod_libpri.h | 6 + 2 files changed, 114 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 7a8e74fd7c..a379aeda9c 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -204,6 +204,32 @@ static int parse_debug(const char *in, uint32_t *flags) return res; } +/** + * \brief Parses a change status string to flags + * \param in change status string to parse for + * \return Flags + */ +static int parse_change_status(const char *in) +{ + int flags = 0; + if (!in) { + return 0; + } + + if (strstr(in, "in_service") || strstr(in, "in")) { + flags = SERVICE_CHANGE_STATUS_INSERVICE; + } + if (strstr(in, "maintenance") || strstr(in, "maint")) { + flags = SERVICE_CHANGE_STATUS_MAINTENANCE; + } + if (strstr(in, "out_of_service") || strstr(in, "out")) { + flags = SERVICE_CHANGE_STATUS_OUTOFSERVICE; + } + + + return flags; +} + static int print_debug(uint32_t flags, char *tmp, const int size) { int offset = 0; @@ -240,6 +266,9 @@ static ftdm_io_interface_t ftdm_libpri_interface; static const char *ftdm_libpri_usage = "Usage:\n" "libpri kill \n" + "libpri reset \n" + "libpri restart \n" + "libpri maintenance \n" "libpri debug [all|none|flag,...flagN]\n" "\n" "Possible debug flags:\n" @@ -339,8 +368,78 @@ static FIO_API_FUNCTION(ftdm_libpri_api) goto done; } } + if (!strcasecmp(argv[0], "reset")) { + ftdm_span_t *span = NULL; + if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) { + ftdm_libpri_data_t *isdn_data = span->signal_data; + if (span->start != ftdm_libpri_start) { + stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); + goto done; + } + + pri_restart(isdn_data->spri.pri); + stream->write_function(stream, "%s: +OK reset.\n", __FILE__); + goto done; + } else { + stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); + goto done; + } + } + if (!strcasecmp(argv[0], "restart") && argc == 3) { + ftdm_span_t *span = NULL; + if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) { + ftdm_libpri_data_t *isdn_data = span->signal_data; + if (span->start != ftdm_libpri_start) { + stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); + goto done; + } + if (!strcasecmp(argv[2], "all")) { + int j; + for(j = 1; j <= span->chan_count; j++) { + pri_reset(isdn_data->spri.pri, j); + ftdm_sleep(50); + } + } else { + pri_reset(isdn_data->spri.pri, atoi(argv[2])); + } + stream->write_function(stream, "%s: +OK restart set.\n", __FILE__); + goto done; + } else { + stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); + goto done; + } + } + if (!strcasecmp(argv[0], "maintenance") && argc > 3) { + ftdm_span_t *span = NULL; + if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) { + ftdm_libpri_data_t *isdn_data = span->signal_data; + if (span->start != ftdm_libpri_start) { + stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); + goto done; + } + if (!isdn_data->service_message_support) { + stream->write_function(stream, "%s: -ERR service message support is disabled\n", __FILE__); + goto done; + } + if (!strcasecmp(argv[2], "all")) { + int j; + for(j = 1; j <= span->chan_count; j++) { + pri_maintenance_service(isdn_data->spri.pri, atoi(argv[1]), j, parse_change_status(argv[3])); + ftdm_sleep(50); + } + } else { + pri_maintenance_service(isdn_data->spri.pri, atoi(argv[1]), atoi(argv[2]), parse_change_status(argv[3])); + } + stream->write_function(stream, "%s: +OK change status set.\n", __FILE__); + goto done; + } else { + stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); + goto done; + } + } } + stream->write_function(stream, "%s: -ERR invalid command.\n", __FILE__); done: @@ -1780,6 +1879,10 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj) pri_facility_enable(isdn_data->spri.pri); } #endif + /* Support the different switch of service status */ + if (isdn_data->service_message_support) { + pri_set_service_message_support(isdn_data->spri.pri, 1 /* True */); + } if (res == 0) { LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_ANY, on_anything); @@ -2159,6 +2262,11 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span) isdn_data->debug_mask = 0; } } + else if (!strcasecmp(var, "service_message_support")) { + if (ftdm_true(val)) { + isdn_data->service_message_support = 1; + } + } else { ftdm_log(FTDM_LOG_ERROR, "Unknown parameter '%s', aborting configuration\n", var); snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var); diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h index 4ec15c7b69..27b1763fec 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h @@ -31,6 +31,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +typedef enum { + SERVICE_CHANGE_STATUS_INSERVICE = 0, + SERVICE_CHANGE_STATUS_MAINTENANCE = 1, + SERVICE_CHANGE_STATUS_OUTOFSERVICE = 2 +} service_change_status_t; #ifndef FTMOD_LIBPRI_H #define FTMOD_LIBPRI_H @@ -69,6 +74,7 @@ struct ftdm_libpri_data { int overlap; /*!< Overlap dial flags */ unsigned int layer1; unsigned int ton; + unsigned int service_message_support; lpwrap_pri_t spri; }; From 1b4c78bf870e3579b93eb6f67bbbfc386dac7a08 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Sat, 6 Aug 2011 03:28:26 -0500 Subject: [PATCH 024/354] skypopen: avoid accumulating delay on VMs, better debug logging --- src/mod/endpoints/mod_skypopen/mod_skypopen.c | 11 +++++------ .../endpoints/mod_skypopen/skypopen_protocol.c | 16 ++++++++++------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c index 63f99c567a..4f095ff886 100644 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c +++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.c @@ -838,7 +838,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { //DEBUGA_SKYPE("CHANNEL READ FRAME in TFLAG_PROGRESS goto CNG\n", SKYPOPEN_P_LOG); - switch_sleep(MS_SKYPOPEN * 1000); + //switch_sleep(MS_SKYPOPEN * 1000); goto cng; } @@ -879,7 +879,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch DEBUGA_SKYPE("skypopen_audio_read going back to read\n", SKYPOPEN_P_LOG); goto read; } - DEBUGA_SKYPE("skypopen_audio_read Silence\n", SKYPOPEN_P_LOG); + DEBUGA_SKYPE("READ BUFFER EMPTY, skypopen_audio_read Silence\n", SKYPOPEN_P_LOG); memset(tech_pvt->read_frame.data, 255, BYTES_PER_FRAME); tech_pvt->read_frame.datalen = BYTES_PER_FRAME; @@ -1022,17 +1022,16 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc switch_mutex_lock(tech_pvt->mutex_audio_cli); if (switch_buffer_freespace(tech_pvt->write_buffer) < frame->datalen) { - DEBUGA_SKYPE("NO SPACE WRITE: %d\n", SKYPOPEN_P_LOG, frame->datalen); switch_buffer_zero(tech_pvt->write_buffer); no_space = 1; } switch_buffer_write(tech_pvt->write_buffer, frame->data, frame->datalen); switch_mutex_unlock(tech_pvt->mutex_audio_cli); if (no_space) { - switch_sleep(MS_SKYPOPEN * 1000); - } else { - tech_pvt->begin_to_write = 1; + //switch_sleep(MS_SKYPOPEN * 1000); + DEBUGA_SKYPE("NO SPACE in WRITE BUFFER: there was no space for %d\n", SKYPOPEN_P_LOG, frame->datalen); } + tech_pvt->begin_to_write = 1; return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c index 129e343ba6..a308e2e551 100644 --- a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c +++ b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c @@ -540,6 +540,7 @@ int skypopen_signaling_read(private_t *tech_pvt) DEBUGA_SKYPE("Skype FAILED on skype_call %s. Let's wait for the FAILED message.\n", SKYPOPEN_P_LOG, id); } #if 0 +#ifndef WIN32 if (!strcasecmp(prop, "DURATION")) { /* each 20 seconds, we zero the buffers and sync the timers */ if (!((atoi(value) % 20))) { if (tech_pvt->read_buffer) { @@ -565,6 +566,7 @@ int skypopen_signaling_read(private_t *tech_pvt) DEBUGA_SKYPE("Synching audio on skype_call: %s.\n", SKYPOPEN_P_LOG, id); } } +#endif //WIN32 #endif //0 if (!strcasecmp(prop, "DURATION") && (!strcasecmp(value, "1"))) { if (strcasecmp(id, tech_pvt->skype_call_id)) { @@ -882,19 +884,21 @@ void *skypopen_do_tcp_srv_thread_func(void *obj) || tech_pvt->skype_callflow == CALLFLOW_STATUS_EARLYMEDIA || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPOPEN_STATE_UP)) { - unsigned int fdselect; + //unsigned int fdselect; int rt=1; - fd_set fs; + //fd_set fs; //struct timeval to; int nospace; if (!(running && tech_pvt->running)) break; +#if 0 fdselect = fd; FD_ZERO(&fs); FD_SET(fdselect, &fs); - //to.tv_usec = MS_SKYPOPEN * 1000 * 3; - //to.tv_sec = 0; + to.tv_usec = MS_SKYPOPEN * 1000 * 3; + to.tv_sec = 0; +#endif //0 if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { switch_core_timer_next(&tech_pvt->timer_read_srv); @@ -935,7 +939,7 @@ void *skypopen_do_tcp_srv_thread_func(void *obj) } switch_mutex_unlock(tech_pvt->mutex_audio_srv); if (nospace) { - DEBUGA_SKYPE("NO SPACE READ: there was no space for: %d\n", SKYPOPEN_P_LOG, len); + DEBUGA_SKYPE("NO SPACE in READ BUFFER: there was no space for: %d\n", SKYPOPEN_P_LOG, len); } } else if (len == 0) { DEBUGA_SKYPE("CLOSED\n", SKYPOPEN_P_LOG); @@ -1080,7 +1084,7 @@ void *skypopen_do_tcp_cli_thread_func(void *obj) } switch_mutex_lock(tech_pvt->mutex_audio_cli); if (tech_pvt->write_buffer && switch_buffer_inuse(tech_pvt->write_buffer)) { - bytes_to_write = switch_buffer_read(tech_pvt->write_buffer, cli_out, BYTES_PER_FRAME * 2); + bytes_to_write = switch_buffer_read(tech_pvt->write_buffer, cli_out, BYTES_PER_FRAME); } switch_mutex_unlock(tech_pvt->mutex_audio_cli); From 8ea3cbd5b198fe15599c3b67f3cbfadc097f97cc Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Sat, 6 Aug 2011 11:09:41 -0500 Subject: [PATCH 025/354] FS-1231 -- resolve thanks please watch the code formatting in the future --- src/mod/formats/mod_shout/mod_shout.c | 44 ++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index 4ac6790933..bc72038db5 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -53,6 +53,9 @@ static struct { char decoder[256]; float vol; uint32_t outscale; + uint32_t brate; + uint32_t resample; + uint32_t quality; } globals; mpg123_handle *our_mpg123_new(const char *decoder, int *error) @@ -172,7 +175,7 @@ static inline void free_context(shout_context_t *context) } if (context->fp) { - unsigned char mp3buffer[8192]; + unsigned char mp3buffer[20480]; int len; int16_t blank[2048] = { 0 }, *r = NULL; @@ -494,7 +497,7 @@ static void *SWITCH_THREAD_FUNC write_stream_thread(switch_thread_t *thread, voi } while (!context->err && context->thread_running) { - unsigned char mp3buf[8192] = ""; + unsigned char mp3buf[20480] = ""; int16_t audio[9600] = { 0 }; switch_size_t audio_read = 0; int rlen = 0; @@ -667,17 +670,33 @@ static switch_status_t shout_file_open(switch_file_handle_t *handle, const char } context->channels = handle->channels; - lame_set_brate(context->gfp, 16 * (handle->samplerate / 8000) * handle->channels); + + if (globals.brate) { + lame_set_brate(context->gfp, globals.brate); + } else { + lame_set_brate(context->gfp, 16 * (handle->samplerate / 8000) * handle->channels); + } + lame_set_num_channels(context->gfp, handle->channels); lame_set_in_samplerate(context->gfp, handle->samplerate); - lame_set_out_samplerate(context->gfp, handle->samplerate); + + if (globals.resample) { + lame_set_out_samplerate(context->gfp, globals.resample); + } else { + lame_set_out_samplerate(context->gfp, handle->samplerate); + } if (handle->channels == 2) { lame_set_mode(context->gfp, STEREO); } else { lame_set_mode(context->gfp, MONO); } - lame_set_quality(context->gfp, 2); /* 2=high 5 = medium 7=low */ + + if (globals.quality) { + lame_set_quality(context->gfp, globals.quality); + } else { + lame_set_quality(context->gfp, 2); /* 2=high 5 = medium 7=low */ + } lame_set_errorf(context->gfp, log_error); lame_set_debugf(context->gfp, log_debug); @@ -1464,6 +1483,21 @@ static switch_status_t load_config(void) if (tmp > 0) { globals.outscale = tmp; } + } else if (!strcmp(var, "encode-brate")) { + int tmp = atoi(val); + if (tmp > 0) { + globals.brate = tmp; + } + } else if (!strcmp(var, "encode-resample")) { + int tmp = atoi(val); + if (tmp > 0) { + globals.resample = tmp; + } + } else if (!strcmp(var, "encode-quality")) { + int tmp = atoi(val); + if (tmp > 0) { + globals.quality = tmp; + } } } } From f57c33f1eee8ea5f818201fcd93ed11b579a9e3a Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Sat, 6 Aug 2011 21:29:46 -0400 Subject: [PATCH 026/354] OPENZAP-112 --resolve --- libs/freetdm/conf/freetdm.conf.xml | 5 ++++ libs/freetdm/mod_freetdm/mod_freetdm.c | 4 +++ .../src/ftmod/ftmod_analog/ftdm_analog.h | 3 ++- .../src/ftmod/ftmod_analog/ftmod_analog.c | 23 +++++++++++++++-- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 25 ++++++++++++++++++- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h | 7 ++++++ 6 files changed, 63 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/conf/freetdm.conf.xml b/libs/freetdm/conf/freetdm.conf.xml index dd426b089a..d8fa55c8cb 100644 --- a/libs/freetdm/conf/freetdm.conf.xml +++ b/libs/freetdm/conf/freetdm.conf.xml @@ -75,6 +75,11 @@ with the signaling protocols that you can run on top of your I/O interfaces. --> + + + diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index c3ca4786d5..9d6eac94f5 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -3021,6 +3021,7 @@ static switch_status_t load_config(void) const char *enable_callerid = "true"; const char *answer_polarity = "false"; const char *hangup_polarity = "false"; + const char *polarity_callerid = "false"; int polarity_delay = 600; int callwaiting = 1; int dialtone_timeout = 5000; @@ -3102,6 +3103,8 @@ static switch_status_t load_config(void) hangup_polarity = val; } else if (!strcasecmp(var, "polarity-delay")) { polarity_delay = atoi(val); + } else if (!strcasecmp(var, "polarity-callerid")) { + polarity_callerid = val; } else if (!strcasecmp(var, "fail-dial-regex")) { fail_dial_regex = val; } else if (!strcasecmp(var, "hold-music")) { @@ -3164,6 +3167,7 @@ static switch_status_t load_config(void) "enable_callerid", enable_callerid, "answer_polarity_reverse", answer_polarity, "hangup_polarity_reverse", hangup_polarity, + "polarity_callerid", polarity_callerid, "polarity_delay", &polarity_delay, "callwaiting", &callwaiting, "wait_dialtone_timeout", &dialtone_timeout, diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h b/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h index 39cbc5ff2b..a2339120c5 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h @@ -39,7 +39,8 @@ typedef enum { FTDM_ANALOG_RUNNING = (1 << 0), FTDM_ANALOG_CALLERID = (1 << 1), FTDM_ANALOG_ANSWER_POLARITY_REVERSE = (1 << 2), - FTDM_ANALOG_HANGUP_POLARITY_REVERSE = (1 << 3) + FTDM_ANALOG_HANGUP_POLARITY_REVERSE = (1 << 3), + FTDM_ANALOG_POLARITY_CALLERID = (1 << 4) } ftdm_analog_flag_t; #define FTDM_MAX_HOTLINE_STR 20 diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index 27eecb4f7f..cfbc4807f3 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -275,6 +275,15 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span) break; } hotline = val; + } else if (!strcasecmp(var, "polarity_callerid")) { + if (!(val = va_arg(ap, char *))) { + break; + } + if (ftdm_true(val)) { + flags |= FTDM_ANALOG_POLARITY_CALLERID; + } else { + flags &= ~FTDM_ANALOG_POLARITY_CALLERID; + } } else { ftdm_log(FTDM_LOG_ERROR, "Unknown parameter %s in span %s\n", var, span->name); } @@ -1130,8 +1139,18 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e break; } if (event->channel->state == FTDM_CHANNEL_STATE_DOWN) { - ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG, - "Ignoring polarity reversal because this channel is down\n"); + if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID) + && ftdm_test_flag(analog_data, FTDM_ANALOG_POLARITY_CALLERID)) { + ftdm_log_chan_msg(event->channel, "Polarity reversal detected while down, getting caller id now\n"); + ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID); + event->channel->ring_count = 1; + ftdm_mutex_unlock(event->channel->mutex); + locked = 0; + ftdm_thread_create_detached(ftdm_analog_channel_run); + } else { + ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG, + "Ignoring polarity reversal because this channel is down\n"); + } break; } /* we have a good channel, set the polarity flag and let the channel thread deal with it */ diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 982412d334..4e7914685b 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -29,6 +29,12 @@ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Contributors: + * + * Moises Silva + * W McRoberts + * */ #include "private/ftdm_core.h" @@ -94,6 +100,7 @@ struct ioctl_codes { ioctlcmd ECHOTRAIN; ioctlcmd SETTXBITS; ioctlcmd GETRXBITS; + ioctlcmd SETPOLARITY; }; /** @@ -169,7 +176,8 @@ static struct ioctl_codes dahdi_ioctl_codes = { .GETCONFMUTE = DAHDI_GETCONFMUTE, .ECHOTRAIN = DAHDI_ECHOTRAIN, .SETTXBITS = DAHDI_SETTXBITS, - .GETRXBITS = DAHDI_GETRXBITS + .GETRXBITS = DAHDI_GETRXBITS, + .SETPOLARITY = DAHDI_SETPOLARITY }; #define ZT_INVALID_SOCKET -1 @@ -826,6 +834,15 @@ static FIO_COMMAND_FUNCTION(zt_command) err = ioctl(ftdmchan->sockfd, codes.FLUSH, &flushmode); } break; + case FTDM_COMMAND_SET_POLARITY: + { + ftdm_polarity_t polarity = FTDM_COMMAND_OBJ_INT; + err = ioctl(ftdmchan->sockfd, codes.SETPOLARITY, polarity); + if (!err) { + ftdmchan->polarity = polarity; + } + } + break; case FTDM_COMMAND_FLUSH_RX_BUFFERS: { int flushmode = ZT_FLUSH_READ; @@ -1088,6 +1105,12 @@ static __inline__ ftdm_status_t zt_channel_process_event(ftdm_channel_t *fchan, *event_id = FTDM_OOB_NOOP; /* What else could we do? */ } break; + case ZT_EVENT_POLARITY: + { + ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "Got polarity reverse (ZT_EVENT_POLARITY)\n"); + *event_id = FTDM_OOB_POLARITY_REVERSE; + } + break; case ZT_EVENT_NONE: { ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "No event\n"); diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h index cf5479dba1..065d7e63e2 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h @@ -29,6 +29,12 @@ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Contributors: + * + * Moises Silva + * W McRoberts + * */ #ifndef FTDM_ZT_H @@ -349,6 +355,7 @@ ZT_ABIT = 8 #define DAHDI_SETTXBITS _IOW (DAHDI_CODE, 43, int) #define DAHDI_GETRXBITS _IOR (DAHDI_CODE, 43, int) +#define DAHDI_SETPOLARITY _IOW (DAHDI_CODE, 92, int) /* Polarity setting for FXO lines */ #endif From c6f5c96c6e520a3dd3dab1c92737bf8434ffee9c Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Sat, 6 Aug 2011 21:38:04 -0400 Subject: [PATCH 027/354] freetdm: *shrug* --- libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index cfbc4807f3..85da471739 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -1141,12 +1141,12 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e if (event->channel->state == FTDM_CHANNEL_STATE_DOWN) { if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID) && ftdm_test_flag(analog_data, FTDM_ANALOG_POLARITY_CALLERID)) { - ftdm_log_chan_msg(event->channel, "Polarity reversal detected while down, getting caller id now\n"); + ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG, "Polarity reversal detected while down, getting caller id now\n"); ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID); event->channel->ring_count = 1; ftdm_mutex_unlock(event->channel->mutex); locked = 0; - ftdm_thread_create_detached(ftdm_analog_channel_run); + ftdm_thread_create_detached(ftdm_analog_channel_run, event->channel); } else { ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG, "Ignoring polarity reversal because this channel is down\n"); From 46f097c1b94f43e5dad2c0b9592e921ae6933665 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Sun, 7 Aug 2011 01:33:26 -0400 Subject: [PATCH 028/354] freetdm: ftmod_wanpipe - tx idle frames needs to be bigger --- libs/freetdm/src/include/freetdm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 0948f16e29..238314c560 100755 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -926,20 +926,20 @@ typedef enum { /*! \brief IO statistics */ typedef struct { struct { + uint64_t packets; uint32_t errors; uint16_t flags; uint8_t queue_size; /*!< max queue size configured */ uint8_t queue_len; /*!< Current number of elements in queue */ - uint64_t packets; } rx; struct { + uint64_t idle_packets; + uint64_t packets; uint32_t errors; uint16_t flags; - uint8_t idle_packets; uint8_t queue_size; /*!< max queue size configured */ uint8_t queue_len; /*!< Current number of elements in queue */ - uint64_t packets; } tx; } ftdm_channel_iostats_t; From 38e3f5fe1655336f9fc807e62f877ed8f932b8a0 Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Tue, 9 Aug 2011 03:09:19 -0400 Subject: [PATCH 029/354] switch_ivr_originate: export variables were broken since b946ee94 4 aug 2011 --- src/switch_ivr_originate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 938be90db2..2bec189547 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1843,6 +1843,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } + if (caller_channel) { + switch_channel_process_export(caller_channel, NULL, var_event, SWITCH_EXPORT_VARS_VARIABLE); + } + /* strip leading spaces */ while (data && *data && *data == ' ') { data++; From 01b2bd0494ffd3cf9d92463d54ec41028832add5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 9 Aug 2011 08:33:03 -0500 Subject: [PATCH 030/354] fix seg on user_recurse_variables reported on the mailing list --- src/mod/applications/mod_dptools/mod_dptools.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index d62db97e13..39e6380399 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -3084,8 +3084,10 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, } } - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_user", user); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_domain", domain); + if (var_event) { + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_user", user); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_domain", domain); + } if (!dest) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No dial-string available, please check your user directory.\n"); From b2389dabe51887d1072efc44c72d2c9afa5c3452 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 9 Aug 2011 08:47:46 -0500 Subject: [PATCH 031/354] tweak --- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 +- src/mod/endpoints/mod_sofia/sofia.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index a7bd1e6843..190212a22b 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -321,7 +321,7 @@ typedef enum { TFLAG_MAX } TFLAGS; -#define SOFIA_MAX_MSG_QUEUE 51 +#define SOFIA_MAX_MSG_QUEUE 101 #define SOFIA_MSG_QUEUE_SIZE 5000 struct mod_sofia_globals { diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 318ca29b7b..c225b2bf35 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1145,6 +1145,7 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj while(switch_queue_pop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) { sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop; sofia_process_dispatch_event(&de); + switch_cond_next(); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MSG Thread Ended\n"); @@ -1175,7 +1176,7 @@ static void sofia_msg_thread_start(int idx) switch_threadattr_create(&thd_attr, mod_sofia_globals.pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); + //switch_threadattr_priority_increase(thd_attr); switch_thread_create(&mod_sofia_globals.msg_queue_thread[i], thd_attr, sofia_msg_thread_run, From 6d1d4a9c1838db9b1f527febfc34a57159bbcf3d Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Tue, 9 Aug 2011 16:48:58 -0500 Subject: [PATCH 032/354] initial addition of very basic LRN --- src/mod/applications/mod_lcr/mod_lcr.c | 134 +++++++++++++++++-------- 1 file changed, 94 insertions(+), 40 deletions(-) diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index c0d99dfc35..272745b6dc 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -127,6 +127,7 @@ struct callback_obj { int matches; switch_memory_pool_t *pool; char *lookup_number; + char *lrn_number; char *cid; switch_bool_t intrastate; switch_bool_t intralata; @@ -622,6 +623,8 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa additional->carrier_name = switch_core_strdup(pool, switch_str_nil(argv[i])); } else if (CF("lcr_rate_field")) { if (!argv[i] || zstr(argv[i])) { + /* maybe we want to consider saying which carriers have null rate fields... maybe they can run the query and find out */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "rate field is null, skipping\n"); goto end; } additional->rate = (float)atof(switch_str_nil(argv[i])); @@ -798,7 +801,7 @@ static switch_status_t is_intrastatelata(callback_t *cb_struct) cb_struct->lookup_number+1, cb_struct->lookup_number+4, cb_struct->cid+1, cb_struct->cid+4); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "SQL: %s\n", sql); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "SQL: %s\n", sql); return(lcr_execute_sql_callback(sql, intrastatelata_callback, cb_struct)); @@ -808,8 +811,9 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct) { switch_stream_handle_t sql_stream = { 0 }; char *digits = cb_struct->lookup_number; - char *digits_copy; - char *digits_expanded; + char *digits_copy = NULL; + char *digits_expanded = NULL; + char *lrn_digits_expanded = NULL; profile_t *profile = cb_struct->profile; switch_bool_t lookup_status; switch_channel_t *channel; @@ -832,6 +836,11 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct) } digits_expanded = expand_digits(cb_struct->pool, digits_copy, cb_struct->profile->quote_in_list); + if (cb_struct->lrn_number) { + lrn_digits_expanded = expand_digits(cb_struct->pool, cb_struct->lrn_number, cb_struct->profile->quote_in_list); + } else { + lrn_digits_expanded = switch_core_strdup(cb_struct->pool, digits_expanded); + } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "Has NPA NXX: [%u == %u]\n", profile->profile_has_npanxx, SWITCH_TRUE); if (profile->profile_has_npanxx == SWITCH_TRUE) { @@ -866,6 +875,10 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct) id_str = switch_core_sprintf(cb_struct->pool, "%d", cb_struct->profile->id); switch_channel_set_variable_var_check(channel, "lcr_query_profile", id_str, SWITCH_FALSE); switch_channel_set_variable_var_check(channel, "lcr_query_expanded_digits", digits_expanded, SWITCH_FALSE); + switch_channel_set_variable_var_check(channel, "lcr_query_expanded_lrn_digits", lrn_digits_expanded, SWITCH_FALSE); + if ( cb_struct->lrn_number ) { + switch_channel_set_variable_var_check(channel, "lcr_lrn", cb_struct->lrn_number, SWITCH_FALSE); + } } } if (cb_struct->event) { @@ -876,6 +889,10 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct) id_str = switch_core_sprintf(cb_struct->pool, "%d", cb_struct->profile->id); switch_event_add_header_string(cb_struct->event, SWITCH_STACK_BOTTOM, "lcr_query_profile", id_str); switch_event_add_header_string(cb_struct->event, SWITCH_STACK_BOTTOM, "lcr_query_expanded_digits", digits_expanded); + switch_event_add_header_string(cb_struct->event, SWITCH_STACK_BOTTOM, "lcr_query_expanded_lrn_digits", lrn_digits_expanded); + if ( cb_struct->lrn_number ) { + switch_event_add_header_string(cb_struct->event, SWITCH_STACK_BOTTOM, "lcr_lrn", cb_struct->lrn_number); + } } /* set up the query to be executed */ @@ -998,7 +1015,7 @@ static switch_status_t lcr_load_config() char *export_fields = NULL; char *limit_type = NULL; int argc, x = 0; - char *argv[4] = { 0 }; + char *argv[32] = { 0 }; SWITCH_STANDARD_STREAM(order_by); @@ -1078,29 +1095,48 @@ static switch_status_t lcr_load_config() SWITCH_STANDARD_STREAM(sql_stream); if (zstr(custom_sql)) { /* use default sql */ + + /* Checking for codec field, adding if needed */ + if (db_check("SELECT codec FROM carrier_gateway LIMIT 1") == SWITCH_TRUE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "codec field defined.\n"); + } else { + if (db_check("ALTER TABLE carrier_gateway add codec varchar(255);") == SWITCH_TRUE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "adding codec field your lcr carrier_gateway database schema.\n"); + } else { + return SWITCH_FALSE; + } + } + + /* Checking for cid field, adding if needed */ + if (db_check("SELECT cid FROM lcr LIMIT 1") == SWITCH_TRUE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "cid field defined.\n"); + } else { + if (db_check("ALTER TABLE lcr add cid varchar(32);") == SWITCH_TRUE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "adding cid field to your lcr database schema.\n"); + } else { + return SWITCH_FALSE; + } + } + + if (db_check("SELECT lrn FROM lcr LIMIT 1") != SWITCH_TRUE) { + if (db_check("ALTER TABLE lcr add lrn boolean")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "adding cid field to your lcr database schema.\n"); + } else { + return SWITCH_FALSE; + } + } + sql_stream.write_function(&sql_stream, "SELECT l.digits AS lcr_digits, c.carrier_name AS lcr_carrier_name, l.${lcr_rate_field} AS lcr_rate_field, \ cg.prefix AS lcr_gw_prefix, cg.suffix AS lcr_gw_suffix, l.lead_strip AS lcr_lead_strip, \ - l.trail_strip AS lcr_trail_strip, l.prefix AS lcr_prefix, l.suffix AS lcr_suffix " - ); - if (db_check("SELECT codec from carrier_gateway limit 1") == SWITCH_TRUE) { - sql_stream.write_function(&sql_stream, ", cg.codec AS lcr_codec "); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "codec field defined.\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "codec field not defined, please update your lcr carrier_gateway database schema.\n" - ); - } - if (db_check("SELECT cid from lcr limit 1") == SWITCH_TRUE) { - sql_stream.write_function(&sql_stream, ", l.cid AS lcr_cid "); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "cid field defined.\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "cid field not defined, please update your lcr database schema.\n"); - } + l.trail_strip AS lcr_trail_strip, l.prefix AS lcr_prefix, l.suffix AS lcr_suffix, \ + cg.codec AS lcr_codec, l.cid AS lcr_cid "); sql_stream.write_function(&sql_stream, "FROM lcr l JOIN carriers c ON l.carrier_id=c.id \ - JOIN carrier_gateway cg ON c.id=cg.carrier_id WHERE \ - c.enabled = '1' AND cg.enabled = '1' AND l.enabled = '1' AND digits IN ("); - sql_stream.write_function(&sql_stream, "${lcr_query_expanded_digits}"); + JOIN carrier_gateway cg ON c.id=cg.carrier_id \ + WHERE c.enabled = '1' AND cg.enabled = '1' AND l.enabled = '1' AND (\ + (digits IN (${lcr_query_expanded_digits}) AND lrn = false) OR \ + (digits IN (${lcr_query_expanded_lrn_digits}) AND lrn = true)"); + sql_stream.write_function(&sql_stream, ") AND CURRENT_TIMESTAMP BETWEEN date_start AND date_end "); if (profile->id > 0) { sql_stream.write_function(&sql_stream, "AND lcr_profile=%d ", profile->id); @@ -1430,6 +1466,7 @@ SWITCH_STANDARD_DIALPLAN(lcr_dialplan_hunt) switch_event_t *event = NULL; const char *intrastate = NULL; const char *intralata = NULL; + const char *lrn = NULL; if (session) { pool = switch_core_session_get_pool(session); @@ -1443,8 +1480,12 @@ SWITCH_STANDARD_DIALPLAN(lcr_dialplan_hunt) intrastate = switch_channel_get_variable(channel, "intrastate"); intralata = switch_channel_get_variable(channel, "intralata"); + lrn = switch_channel_get_variable(channel, "lrn"); + routes.lrn_number = (char *) lrn; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intrastate channel var is [%s]\n", intrastate); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intralata channel var is [%s]\n", intralata); + if (!zstr(intralata) && !strcasecmp((char *)intralata, "true")) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on intralata rates\n"); routes.intralata = SWITCH_FALSE; @@ -1531,7 +1572,7 @@ void str_repeat(size_t how_many, char *what, switch_stream_handle_t *str_stream) SWITCH_STANDARD_APP(lcr_app_function) { int argc = 0; - char *argv[4] = { 0 }; + char *argv[32] = { 0 }; char *mydata = NULL; char *dest = NULL; char vbuf[1024] = ""; @@ -1544,6 +1585,7 @@ SWITCH_STANDARD_APP(lcr_app_function) switch_memory_pool_t *pool; switch_event_t *event; const char *intra = NULL; + const char *lrn = NULL; if (!(mydata = switch_core_session_strdup(session, data))) { return; @@ -1557,11 +1599,15 @@ SWITCH_STANDARD_APP(lcr_app_function) switch_event_create(&event, SWITCH_EVENT_MESSAGE); routes.event = event; } + routes.pool = pool; + + lrn = switch_channel_get_variable(channel, "lrn"); + routes.lrn_number = (char *) lrn; + intra = switch_channel_get_variable(channel, "intrastate"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intrastate channel var is [%s]\n", - zstr(intra) ? "undef" : intra); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intrastate channel var is [%s]\n", zstr(intra) ? "undef" : intra); if (zstr(intra) || strcasecmp((char *)intra, "true")) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on interstate rates\n"); routes.intrastate = SWITCH_FALSE; @@ -1578,6 +1624,7 @@ SWITCH_STANDARD_APP(lcr_app_function) if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { dest = argv[0]; + if (argc > 1) { lcr_profile = argv[1]; } @@ -1664,21 +1711,20 @@ static void write_data(switch_stream_handle_t *stream, switch_bool_t as_xml, con SWITCH_STANDARD_API(dialplan_lcr_function) { - char *argv[9] = { 0 }; + char *argv[32] = { 0 }; int argc; - char *mydata = NULL; - //char *dialstring = NULL; - char *lcr_profile = NULL; - lcr_route current = NULL; - max_obj_t maximum_lengths = { 0 }; - callback_t cb_struct = { 0 }; - switch_memory_pool_t *pool = NULL; + char *mydata = NULL; + char *lcr_profile = NULL; + lcr_route current = NULL; + max_obj_t maximum_lengths = { 0 }; + callback_t cb_struct = { 0 }; + switch_memory_pool_t *pool = NULL; switch_event_t *event; switch_status_t lookup_status = SWITCH_STATUS_SUCCESS; - switch_bool_t as_xml = SWITCH_FALSE; - char *event_str = NULL; - switch_xml_t event_xml = NULL; - int rowcount=0; + switch_bool_t as_xml = SWITCH_FALSE; + char *event_str = NULL; + switch_xml_t event_xml = NULL; + int rowcount = 0; if (zstr(cmd)) { goto usage; @@ -1708,10 +1754,18 @@ SWITCH_STANDARD_API(dialplan_lcr_function) } if (argc > 2) { int i; - for (i=2; i Date: Wed, 10 Aug 2011 07:36:48 -0500 Subject: [PATCH 033/354] FS-3494 --- src/mod/endpoints/mod_loopback/mod_loopback.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 97684b6f10..17f0b91e7a 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -802,15 +802,20 @@ static switch_status_t loopback_bowout_on_execute_state_handler(switch_core_sess switch_core_session_read_lock(tech_pvt->other_session); b_channel = switch_core_session_get_channel(tech_pvt->other_session); + /* Wait for b_channel to be fully bridged */ + switch_channel_wait_for_flag(b_channel, CF_BRIDGED, SWITCH_TRUE, 5000, NULL); + uuid = switch_channel_get_variable(b_channel, SWITCH_SIGNAL_BOND_VARIABLE); if (uuid && (other_session = switch_core_session_locate(uuid))) { switch_channel_t *other_channel = switch_core_session_get_channel(other_session); switch_caller_profile_t *cp, *clone; - + + switch_channel_wait_for_state(other_channel, NULL, CS_EXCHANGE_MEDIA); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->other_session), SWITCH_LOG_INFO, "Replacing loopback channel: %s with real channel: %s\n", switch_channel_get_name(b_channel), switch_channel_get_name(other_channel)); - + if ((cp = switch_channel_get_caller_profile(channel))) { clone = switch_caller_profile_clone(other_session, cp); clone->originator_caller_profile = NULL; @@ -831,7 +836,7 @@ static switch_status_t loopback_bowout_on_execute_state_handler(switch_core_sess switch_core_session_rwunlock(tech_pvt->other_session); switch_core_event_hook_remove_state_change(session, loopback_bowout_on_execute_state_handler); - + } return SWITCH_STATUS_SUCCESS; } From 3696ced79220b1557204173705d0008e2e3919fa Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 10 Aug 2011 07:55:17 -0500 Subject: [PATCH 034/354] FS-3497 --resolve --- src/switch_event.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/switch_event.c b/src/switch_event.c index 629e67e9c3..b469b9f7b7 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -45,7 +45,7 @@ struct switch_event_node { /*! the event id enumeration to bind to */ switch_event_types_t event_id; /*! the event subclass to bind to for custom events */ - switch_event_subclass_t *subclass; + char *subclass_name; /*! a callback function to execute when the event is triggered */ switch_event_callback_t callback; /*! private data */ @@ -205,28 +205,28 @@ static int switch_events_match(switch_event_t *event, switch_event_node_t *node) if (node->event_id == SWITCH_EVENT_ALL) { match++; - if (!node->subclass) { + if (!node->subclass_name) { return match; } } if (match || event->event_id == node->event_id) { - if (event->subclass_name && node->subclass) { - if (!strncasecmp(node->subclass->name, "file:", 5)) { + if (event->subclass_name && node->subclass_name) { + if (!strncasecmp(node->subclass_name, "file:", 5)) { char *file_header; if ((file_header = switch_event_get_header(event, "file")) != 0) { - match = strstr(node->subclass->name + 5, file_header) ? 1 : 0; + match = strstr(node->subclass_name + 5, file_header) ? 1 : 0; } - } else if (!strncasecmp(node->subclass->name, "func:", 5)) { + } else if (!strncasecmp(node->subclass_name, "func:", 5)) { char *func_header; if ((func_header = switch_event_get_header(event, "function")) != 0) { - match = strstr(node->subclass->name + 5, func_header) ? 1 : 0; + match = strstr(node->subclass_name + 5, func_header) ? 1 : 0; } - } else if (event->subclass_name && node->subclass->name) { - match = strstr(event->subclass_name, node->subclass->name) ? 1 : 0; + } else if (event->subclass_name && node->subclass_name) { + match = strstr(event->subclass_name, node->subclass_name) ? 1 : 0; } - } else if ((event->subclass_name && !node->subclass) || (!event->subclass_name && !node->subclass)) { + } else if ((event->subclass_name && !node->subclass_name) || (!event->subclass_name && !node->subclass_name)) { match = 1; } else { match = 0; @@ -1732,7 +1732,9 @@ SWITCH_DECLARE(switch_status_t) switch_event_bind_removable(const char *id, swit /* ----------------------------------------------- */ event_node->id = DUP(id); event_node->event_id = event; - event_node->subclass = subclass; + if (subclass_name) { + event_node->subclass_name = DUP(subclass_name); + } event_node->callback = callback; event_node->user_data = user_data; @@ -1786,6 +1788,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_unbind_callback(switch_event_callba } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Event Binding deleted for %s:%s\n", n->id, switch_event_name(n->event_id)); + FREE(n->subclass_name); FREE(n->id); FREE(n); status = SWITCH_STATUS_SUCCESS; @@ -1825,7 +1828,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_unbind(switch_event_node_t **node) EVENT_NODES[n->event_id] = n->next; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Event Binding deleted for %s:%s\n", n->id, switch_event_name(n->event_id)); - n->subclass = NULL; + FREE(n->subclass_name); FREE(n->id); FREE(n); *node = NULL; From 97a7668cf2678645e8003651d594c8a74b059802 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 10 Aug 2011 07:57:20 -0500 Subject: [PATCH 035/354] FS-3416 --resolve --- .../mod_event_multicast/mod_event_multicast.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c index 2c0b927c0f..f0635275f6 100644 --- a/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c +++ b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c @@ -61,6 +61,7 @@ static struct { char *psk; switch_mutex_t *mutex; switch_hash_t *peer_hash; + int loopback; } globals; struct peer_status { @@ -88,6 +89,7 @@ static switch_status_t load_config(void) globals.ttl = 1; globals.key_count = 0; + globals.loopback = 0; if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); @@ -119,6 +121,8 @@ static switch_status_t load_config(void) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid ttl '%s' specified, using default of 1\n", val); } + } else if (!strcasecmp(var, "loopback")) { + globals.loopback = switch_true(val); } } @@ -408,8 +412,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_event_multicast_load) switch_goto_status(SWITCH_STATUS_TERM, fail); } - if (switch_mcast_loopback(globals.udp_socket, 0) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to disable loopback\n"); + if (switch_mcast_loopback(globals.udp_socket, globals.loopback) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set loopback to '%d'\n", globals.loopback); switch_goto_status(SWITCH_STATUS_TERM, fail); } From 9c8437a1da2607d52a7e65a9e002f6fc97c523c3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 10 Aug 2011 07:58:02 -0500 Subject: [PATCH 036/354] FS-3415 --resolve --- src/switch_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_core.c b/src/switch_core.c index e7cd60d58f..12850ce998 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -81,6 +81,7 @@ static void send_heartbeat(void) duration.ms, duration.ms == 1 ? "" : "s", duration.mms, duration.mms == 1 ? "" : "s"); 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-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()); From e2a4fb11aba9538f2379a5454dc3d6f45b3103f0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 10 Aug 2011 07:59:03 -0500 Subject: [PATCH 037/354] FS-3396 --resolve --- src/switch_channel.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index 7dd43672a9..4f272db7e2 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2842,10 +2842,6 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_ switch_channel_set_flag(channel, CF_EARLY_MEDIA); switch_channel_set_callstate(channel, CCS_EARLY); switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "EARLY MEDIA"); - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } if (channel->caller_profile && channel->caller_profile->times) { switch_mutex_lock(channel->profile_mutex); @@ -2865,6 +2861,11 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_ switch_mutex_unlock(channel->profile_mutex); } + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, event); + switch_event_fire(&event); + } + switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_PRE_ANSWER_VARIABLE); switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE); From 7c5b57971fea0455d199294428a1cfd46b2d1185 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 10 Aug 2011 08:00:02 -0500 Subject: [PATCH 038/354] FS-3357 --resolve --- src/mod/applications/mod_mongo/mod_mongo.cpp | 85 ++++++++++++++++++-- 1 file changed, 78 insertions(+), 7 deletions(-) diff --git a/src/mod/applications/mod_mongo/mod_mongo.cpp b/src/mod/applications/mod_mongo/mod_mongo.cpp index bb82c840e0..52e1eadf31 100644 --- a/src/mod/applications/mod_mongo/mod_mongo.cpp +++ b/src/mod/applications/mod_mongo/mod_mongo.cpp @@ -1,26 +1,87 @@ #include #include "mod_mongo.h" +#define DELIMITER ';' +#define FIND_ONE_SYNTAX "mongo_find_one ns; query; fields" +#define MAPREDUCE_SYNTAX "mongo_mapreduce ns; query" static struct { mongo_connection_pool_t *conn_pool; + char *map; + char *reduce; + char *finalize; } globals; +SWITCH_STANDARD_API(mongo_mapreduce_function) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + DBClientConnection *conn = NULL; + char *ns = NULL, *json_query = NULL; + + ns = strdup(cmd); + switch_assert(ns != NULL); + + if ((json_query = strchr(ns, DELIMITER))) { + *json_query++ = '\0'; + } + + if (!zstr(ns) && !zstr(json_query)) { + try { + BSONObj query = fromjson(json_query); + BSONObj out; + BSONObjBuilder cmd; + + cmd.append("mapreduce", conn->nsGetCollection(ns)); + if (!zstr(globals.map)) { + cmd.appendCode("map", globals.map); + } + if (!zstr(globals.reduce)) { + cmd.appendCode("reduce", globals.reduce); + } + if (!zstr(globals.finalize)) { + cmd.appendCode("finalize", globals.finalize); + } + if(!query.isEmpty()) { + cmd.append("query", query); + } + cmd.append("out", BSON("inline" << 1)); + + conn = mongo_connection_pool_get(globals.conn_pool); + if (conn) { + conn->runCommand(conn->nsGetDB(ns), cmd.done(), out); + mongo_connection_pool_put(globals.conn_pool, conn); + + stream->write_function(stream, "-OK\n%s\n", out.toString().c_str()); + } else { + stream->write_function(stream, "-ERR\nNo connection\n"); + } + } catch (DBException &e) { + if (conn) { + mongo_connection_destroy(&conn); + } + stream->write_function(stream, "-ERR\n%s\n", e.toString().c_str()); + } + } else { + stream->write_function(stream, "-ERR\n%s\n", MAPREDUCE_SYNTAX); + } + + switch_safe_free(ns); + + return status; +} -static const char *SYNTAX = "mongo_find_one ns; query; fields"; SWITCH_STANDARD_API(mongo_find_one_function) { switch_status_t status = SWITCH_STATUS_SUCCESS; char *ns = NULL, *json_query = NULL, *json_fields = NULL; - char delim = ';'; ns = strdup(cmd); switch_assert(ns != NULL); - if ((json_query = strchr(ns, delim))) { + if ((json_query = strchr(ns, DELIMITER))) { *json_query++ = '\0'; - if ((json_fields = strchr(json_query, delim))) { + if ((json_fields = strchr(json_query, DELIMITER))) { *json_fields++ = '\0'; } } @@ -49,9 +110,8 @@ SWITCH_STANDARD_API(mongo_find_one_function) stream->write_function(stream, "-ERR\n%s\n", e.toString().c_str()); } - } else { - stream->write_function(stream, "-ERR\n%s\n", SYNTAX); + stream->write_function(stream, "-ERR\n%s\n", FIND_ONE_SYNTAX); } switch_safe_free(ns); @@ -88,6 +148,12 @@ static switch_status_t config(void) if ((tmp = atoi(val)) > 0) { max_connections = tmp; } + } else if (!strcmp(var, "map")) { + globals.map = strdup(val); + } else if (!strcmp(var, "reduce")) { + globals.reduce = strdup(val); + } else if (!strcmp(var, "finalize")) { + globals.finalize = strdup(val); } } } @@ -125,7 +191,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_mongo_load) return SWITCH_STATUS_TERM; } - SWITCH_ADD_API(api_interface, "mongo_find_one", "mongo", mongo_find_one_function, SYNTAX); + SWITCH_ADD_API(api_interface, "mongo_find_one", "findOne", mongo_find_one_function, FIND_ONE_SYNTAX); + SWITCH_ADD_API(api_interface, "mongo_mapreduce", "Map/Reduce", mongo_mapreduce_function, MAPREDUCE_SYNTAX); return SWITCH_STATUS_SUCCESS; } @@ -133,6 +200,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_mongo_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mongo_shutdown) { mongo_connection_pool_destroy(&globals.conn_pool); + switch_safe_free(globals.map); + switch_safe_free(globals.reduce); + switch_safe_free(globals.finalize); + return SWITCH_STATUS_SUCCESS; } From cd62d37b6ebe9e5d2229207e98840b29be95f130 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 10 Aug 2011 08:18:42 -0500 Subject: [PATCH 039/354] add conf from earlier patch --- conf/autoload_configs/event_multicast.conf.xml | 1 + conf/autoload_configs/mongo.conf.xml | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/conf/autoload_configs/event_multicast.conf.xml b/conf/autoload_configs/event_multicast.conf.xml index b362ebc459..eac0392607 100644 --- a/conf/autoload_configs/event_multicast.conf.xml +++ b/conf/autoload_configs/event_multicast.conf.xml @@ -4,6 +4,7 @@ + diff --git a/conf/autoload_configs/mongo.conf.xml b/conf/autoload_configs/mongo.conf.xml index a7fdecae8d..ff8daed72a 100644 --- a/conf/autoload_configs/mongo.conf.xml +++ b/conf/autoload_configs/mongo.conf.xml @@ -3,5 +3,12 @@ + + + From 9d98d49f0556fb79656c8403f285ae0a615439d3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 10 Aug 2011 08:38:55 -0500 Subject: [PATCH 040/354] add emulation for asterisk DIALSTATUS magic var --- src/switch_ivr_originate.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 2bec189547..262d6d7a91 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -337,6 +337,7 @@ static switch_bool_t monitor_callback(switch_core_session_t *session, const char if (!bd) { bd = "monitor_early_media_fail"; } + switch_channel_set_variable(channel, "DIALSTATUS", "BUSY"); switch_channel_set_variable(channel, "originate_disposition", bd); switch_channel_hangup(channel, data ? switch_channel_str2cause(data) : SWITCH_CAUSE_USER_BUSY); } else if (!strcmp(app, "ring")) { @@ -346,6 +347,7 @@ static switch_bool_t monitor_callback(switch_core_session_t *session, const char bd = "monitor_early_media_ring"; } switch_channel_set_variable(channel, "originate_disposition", bd); + switch_channel_set_variable(channel, "DIALSTATUS", "EARLY"); if (oglobals) { if (oglobals->monitor_early_media_ring_total && ++oglobals->monitor_early_media_ring_count < oglobals->monitor_early_media_ring_total) { @@ -1967,6 +1969,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } switch_channel_set_variable(caller_channel, "originate_disposition", "failure"); + switch_channel_set_variable(caller_channel, "DIALSTATUS", "INVALIDARGS"); if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) { ringback_data = NULL; @@ -3201,6 +3204,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_channel_set_variable(caller_channel, "originate_disposition", "call accepted"); if (peer_channel) { switch_process_import(oglobals.session, peer_channel, "import", NULL); + + if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) { + switch_channel_set_variable(caller_channel, "DIALSTATUS", "EARLY"); + } else { + switch_channel_set_variable(caller_channel, "DIALSTATUS", "ANSWER"); + } + } } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG, "Originate Resulted in Success: [%s]\n", @@ -3304,6 +3314,27 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (caller_channel) { switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause)); + + switch (*cause) { + case SWITCH_CAUSE_ORIGINATOR_CANCEL: + switch_channel_set_variable(caller_channel, "DIALSTATUS", "CANCEL"); + break; + case SWITCH_CAUSE_USER_BUSY: + switch_channel_set_variable(caller_channel, "DIALSTATUS", "BUSY"); + break; + case SWITCH_CAUSE_NO_ANSWER: + switch_channel_set_variable(caller_channel, "DIALSTATUS", "NOANSWER"); + break; + case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER: + switch_channel_set_variable(caller_channel, "DIALSTATUS", "INVALIDARGS"); + break; + case SWITCH_CAUSE_CALL_REJECTED: + switch_channel_set_variable(caller_channel, "DIALSTATUS", "DONTCALL"); + break; + default: + switch_channel_set_variable(caller_channel, "DIALSTATUS", switch_channel_cause2str(*cause)); + break; + } } early_state.ready = 0; From f10566af914cc6e89cb0bbbdd8a8d63b5630638f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 11 Aug 2011 08:49:13 -0500 Subject: [PATCH 041/354] FS-3181 --resolve the new code requires accurate timestamps, we were incrementing it by the interval (20) instaead of the samples (160) --- src/switch_ivr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 84e077f27b..0989cbc4d4 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -2412,7 +2412,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3 } stfu_n_eat(jb, ts, read_frame->payload, read_frame->data, read_frame->datalen, 0); - ts += interval; + ts += read_impl.samples_per_packet; if ((jb_frame = stfu_n_read_a_frame(jb))) { write_frame.data = jb_frame->data; From 94c9cbf63bac2e356073881aa10314ea16e21b01 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 11 Aug 2011 14:02:08 -0500 Subject: [PATCH 042/354] FS-3498 --resolve --- src/mod/endpoints/mod_portaudio/mod_portaudio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index bc4c19b614..04a3011d72 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -1324,7 +1324,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load) globals.read_frame.buflen = sizeof(globals.databuf); globals.cng_frame.data = globals.cngbuf; globals.cng_frame.buflen = sizeof(globals.cngbuf); - globals.cng_frame.datalen = switch_samples_per_packet(globals.sample_rate, globals.codec_ms) * 2; switch_set_flag((&globals.cng_frame), SFF_CNG); globals.flags = GFLAG_EAR | GFLAG_MOUTH; /* dual streams makes portaudio on solaris choke */ @@ -1750,6 +1749,8 @@ static switch_status_t load_config(void) globals.codec_ms = 20; } + globals.cng_frame.datalen = switch_samples_per_packet(globals.sample_rate, globals.codec_ms) * 2; + if (!globals.ring_interval) { globals.ring_interval = 5; } From decfdbb0830609d9f969bb45c51488e00c60e38b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 11 Aug 2011 13:01:52 -0500 Subject: [PATCH 043/354] fix sql typo --- src/switch_core_sqldb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index a55d3ee905..b23d082bdf 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1936,8 +1936,8 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ { char *err; switch_cache_db_test_reactive(dbh, "select call_uuid, read_bit_rate from channels", "DROP TABLE channels", create_channels_sql); - switch_cache_db_test_reactive(dbh, "select * from detailed_calls", "DROP VIEW detailed_calls", detailed_calls_sql); - switch_cache_db_test_reactive(dbh, "select * from basic_calls", "DROP VIEW basic_call", basic_calls_sql); + switch_cache_db_test_reactive(dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql); + switch_cache_db_test_reactive(dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql); if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { switch_cache_db_test_reactive(dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql); } else { From baa1624e9d86c8cce3d0ee5c1f855947ace72c60 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Sun, 14 Aug 2011 15:38:41 -0400 Subject: [PATCH 044/354] typo --- src/mod/applications/mod_lcr/mod_lcr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index 272745b6dc..e23d432aab 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -1120,7 +1120,7 @@ static switch_status_t lcr_load_config() if (db_check("SELECT lrn FROM lcr LIMIT 1") != SWITCH_TRUE) { if (db_check("ALTER TABLE lcr add lrn boolean")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "adding cid field to your lcr database schema.\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "adding lrn field to your lcr database schema.\n"); } else { return SWITCH_FALSE; } From efb83b183cc2a3ef82bc837880cbbc978f6dae0b Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Sun, 14 Aug 2011 17:23:58 -0400 Subject: [PATCH 045/354] default to false instead of null --- src/mod/applications/mod_lcr/mod_lcr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index e23d432aab..a12f9a0ed6 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -1119,7 +1119,7 @@ static switch_status_t lcr_load_config() } if (db_check("SELECT lrn FROM lcr LIMIT 1") != SWITCH_TRUE) { - if (db_check("ALTER TABLE lcr add lrn boolean")) { + if (db_check("ALTER TABLE lcr ADD lrn BOOLEAN NOT NULL DEFAULT false")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "adding lrn field to your lcr database schema.\n"); } else { return SWITCH_FALSE; From ec02e275d1d9900a62e22f0f09c108630b256c30 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Sun, 14 Aug 2011 17:29:26 -0400 Subject: [PATCH 046/354] update schema --- src/mod/applications/mod_lcr/sql/mysql-5.0.sql | 1 + src/mod/applications/mod_lcr/sql/postgres-8.3.sql | 1 + 2 files changed, 2 insertions(+) diff --git a/src/mod/applications/mod_lcr/sql/mysql-5.0.sql b/src/mod/applications/mod_lcr/sql/mysql-5.0.sql index b9594abd61..2bdcf632f8 100644 --- a/src/mod/applications/mod_lcr/sql/mysql-5.0.sql +++ b/src/mod/applications/mod_lcr/sql/mysql-5.0.sql @@ -38,6 +38,7 @@ CREATE TABLE `lcr` ( `reliability` float(10,6) NOT NULL, `cid` varchar(32) NOT NULL DEFAULT '', `enabled` boolean NOT NULL DEFAULT '1', + `lrn` boolean NOT NULL DEFAULT false, PRIMARY KEY (`id`), KEY `carrier_id` (`carrier_id`), KEY `digits` (`digits`), diff --git a/src/mod/applications/mod_lcr/sql/postgres-8.3.sql b/src/mod/applications/mod_lcr/sql/postgres-8.3.sql index cf2add7c2e..b9e91bf346 100644 --- a/src/mod/applications/mod_lcr/sql/postgres-8.3.sql +++ b/src/mod/applications/mod_lcr/sql/postgres-8.3.sql @@ -57,6 +57,7 @@ CREATE TABLE lcr reliability numeric(10,6) NOT NULL DEFAULT 0, cid VARCHAR(32) NOT NULL DEFAULT '', enabled boolean NOT NULL DEFAULT 'true', + lrn boolean NOT NULL DEFAULT 'false', CONSTRAINT lcr_pkey PRIMARY KEY (id) ); From 4ffa20d1a41a58e23aa4d78cad5d67890869c809 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Mon, 15 Aug 2011 05:37:31 -0500 Subject: [PATCH 047/354] skypopen: OSS driver now compiles on newer kernels (no more .ioctl) --- src/mod/endpoints/mod_skypopen/oss/main.c | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index 72d82cb10c..10ebfc9899 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -283,6 +283,7 @@ static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t * The ioctl() implementation */ +#ifndef HAVE_UNLOCKED_IOCTL static int skypopen_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -302,13 +303,38 @@ static int skypopen_ioctl(struct inode *inode, struct file *filp, } } +#else// HAVE_UNLOCKED_IOCTL +static long skypopen_unlocked_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + int __user *p = argp; + + switch (cmd) { + case OSS_GETVERSION: + return put_user(SOUND_VERSION, p); + case SNDCTL_DSP_GETBLKSIZE: + return put_user(SKYPOPEN_BLK, p); + case SNDCTL_DSP_GETFMTS: + return put_user(28731, p); + + default: + return 0; + } + +} +#endif// HAVE_UNLOCKED_IOCTL struct file_operations skypopen_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = skypopen_read, .write = skypopen_write, +#ifndef HAVE_UNLOCKED_IOCTL .ioctl = skypopen_ioctl, +#else// HAVE_UNLOCKED_IOCTL + .unlocked_ioctl = skypopen_unlocked_ioctl, +#endif// HAVE_UNLOCKED_IOCTL .open = skypopen_c_open, .release = skypopen_c_release, }; From 5b36aea097ce2399fe81a086e398223bb0766bcb Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Sun, 14 Aug 2011 23:56:32 +0200 Subject: [PATCH 048/354] Missed one in e8ae13a8 --- src/mod/endpoints/mod_rtmp/rtmp_sig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_rtmp/rtmp_sig.c b/src/mod/endpoints/mod_rtmp/rtmp_sig.c index ece43bc050..7aaf79d6f6 100644 --- a/src/mod/endpoints/mod_rtmp/rtmp_sig.c +++ b/src/mod/endpoints/mod_rtmp/rtmp_sig.c @@ -301,7 +301,7 @@ RTMP_INVOKE_FUNCTION(rtmp_i_makeCall) amf_object_to_event(argv[3], &event); } - if (rtmp_session_create_call(rsession, &newsession, 0, RTMP_DEFAULT_STREAM_AUDIO, number, user, domain, event) != SWITCH_CAUSE_NONE) { + if (rtmp_session_create_call(rsession, &newsession, 0, RTMP_DEFAULT_STREAM_AUDIO, number, user, domain, event) != SWITCH_CAUSE_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_ERROR, "Couldn't create call.\n"); } From 8446b0f262f2d0659816f66f555e88cb58093315 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Mon, 15 Aug 2011 17:30:41 +0200 Subject: [PATCH 049/354] mod_sofia: don't compile with their built-in stun server as it is buggy --- libs/sofia-sip/configure.gnu | 2 +- src/mod/endpoints/mod_sofia/sofia.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/libs/sofia-sip/configure.gnu b/libs/sofia-sip/configure.gnu index e9cd89ac7c..4b64a47b7b 100644 --- a/libs/sofia-sip/configure.gnu +++ b/libs/sofia-sip/configure.gnu @@ -1,4 +1,4 @@ #! /bin/sh srcpath=$(dirname $0 2>/dev/null ) || srcpath="." -$srcpath/configure "$@" --with-pic --with-glib=no --disable-shared --without-doxygen +$srcpath/configure "$@" --with-pic --with-glib=no --disable-shared --without-doxygen --disable-stun diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index c225b2bf35..0f6486a361 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -48,7 +48,9 @@ extern su_log_t nth_server_log[]; extern su_log_t nua_log[]; extern su_log_t soa_log[]; extern su_log_t sresolv_log[]; +#ifdef HAVE_SOFIA_STUN extern su_log_t stun_log[]; +#endif extern su_log_t su_log_default[]; static void config_sofia_profile_urls(sofia_profile_t * profile); @@ -2077,8 +2079,10 @@ static su_log_t *sofia_get_logger(const char *name) return soa_log; } else if (!strcasecmp(name, "sresolv")) { return sresolv_log; +#ifdef HAVE_SOFIA_STUN } else if (!strcasecmp(name, "stun")) { return stun_log; +#endif } else if (!strcasecmp(name, "default")) { return su_log_default; } else { @@ -2105,7 +2109,9 @@ switch_status_t sofia_set_loglevel(const char *name, int level) su_log_set_level(nua_log, level); su_log_set_level(soa_log, level); su_log_set_level(sresolv_log, level); +#ifdef HAVE_SOFIA_STUN su_log_set_level(stun_log, level); +#endif return SWITCH_STATUS_SUCCESS; } @@ -3356,7 +3362,9 @@ switch_status_t config_sofia(int reload, char *profile_name) su_log_redirect(nua_log, logger, NULL); su_log_redirect(soa_log, logger, NULL); su_log_redirect(sresolv_log, logger, NULL); +#ifdef HAVE_SOFIA_STUN su_log_redirect(stun_log, logger, NULL); +#endif } if (!zstr(profile_name) && (profile = sofia_glue_find_profile(profile_name))) { From a6a970069618549c059e4326688a75078e817734 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 15 Aug 2011 11:21:31 -0500 Subject: [PATCH 050/354] fix regression from previous patch --- .../mod_valet_parking/mod_valet_parking.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/mod/applications/mod_valet_parking/mod_valet_parking.c b/src/mod/applications/mod_valet_parking/mod_valet_parking.c index 3e8337d857..291d6c86a5 100644 --- a/src/mod/applications/mod_valet_parking/mod_valet_parking.c +++ b/src/mod/applications/mod_valet_parking/mod_valet_parking.c @@ -276,17 +276,19 @@ SWITCH_STANDARD_APP(valet_parking_function) 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 (!zstr(var)) { + 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 (!zstr(token->uuid) && (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); From 9423216b64f577b208ed34a1a8c576f44022f7df Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 15 Aug 2011 14:48:05 -0500 Subject: [PATCH 051/354] update auto-drop test for channels table --- src/switch_core_sqldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index b23d082bdf..7495b06302 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1935,7 +1935,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ case SCDB_TYPE_ODBC: { char *err; - switch_cache_db_test_reactive(dbh, "select call_uuid, read_bit_rate from channels", "DROP TABLE channels", create_channels_sql); + switch_cache_db_test_reactive(dbh, "select call_uuid, read_bit_rate, sent_callee_name from channels", "DROP TABLE channels", create_channels_sql); switch_cache_db_test_reactive(dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql); switch_cache_db_test_reactive(dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql); if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { From 0bcfdbe6ca610ad19e271014927449513839fcd5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 16 Aug 2011 11:03:29 -0500 Subject: [PATCH 052/354] only do the 10 second pause, not the reduction in max_sessions when the event system overloads --- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 +- src/switch_event.c | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 190212a22b..ec3f9a7889 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -33,7 +33,7 @@ * mod_sofia.h -- SOFIA SIP Endpoint * */ - +#define HAVE_MEMLEAK_LOG 1 /*Defines etc..*/ /*************************************************************************************************************************************************************/ #define MANUAL_BYE 1 diff --git a/src/switch_event.c b/src/switch_event.c index b469b9f7b7..8265a18207 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -333,17 +333,11 @@ static void *SWITCH_THREAD_FUNC switch_event_thread(switch_thread_t *thread, voi if (++loops > 2) { - uint32_t last_sps = 0, sess_count = switch_core_session_count(); if (auto_pause) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Event system *still* overloading.\n"); } else { - switch_core_session_ctl(SCSC_LAST_SPS, &last_sps); - last_sps = (uint32_t) (float) (last_sps * 0.75f); - sess_count = (uint32_t) (float) (sess_count * 0.75f); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "Event system overloading. Taking a 10 second break, Reducing max_sessions to %d %dsps\n", sess_count, last_sps); - switch_core_session_limit(sess_count); - switch_core_session_ctl(SCSC_SPS, &last_sps); + "Event system overloading. Taking a 10 second break\n"); auto_pause = 10; switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause); } From ba6b5e603588f70bbc02951c0bd15bcde8a70c9c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 16 Aug 2011 11:52:34 -0500 Subject: [PATCH 053/354] revert --- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index ec3f9a7889..190212a22b 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -33,7 +33,7 @@ * mod_sofia.h -- SOFIA SIP Endpoint * */ -#define HAVE_MEMLEAK_LOG 1 + /*Defines etc..*/ /*************************************************************************************************************************************************************/ #define MANUAL_BYE 1 From 316414b9ec0446b7aa4d15de820cd0a9bd365786 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 16 Aug 2011 13:26:13 -0500 Subject: [PATCH 054/354] erase files before recording in VM to make append impossible and write to tmp copy when recording greetings/name so it's not installed until finalized --- .../mod_voicemail/mod_voicemail.c | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 2eb89ebc43..b662620682 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1160,6 +1160,8 @@ static switch_status_t create_file(switch_core_session_t *session, vm_profile_t args.buf = input; args.buflen = sizeof(input); + unlink(file_path); + switch_ivr_record_file(session, &fh, file_path, &args, profile->max_record_len); if (switch_file_exists(file_path, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { @@ -1819,7 +1821,7 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p uint32_t timeout, attempts = 0, retries = 0; int failed = 0; msg_type_t play_msg_type = MSG_NONE; - char *dir_path = NULL, *file_path = NULL; + char *dir_path = NULL, *file_path = NULL, *tmp_file_path = NULL; int total_new_messages = 0; int total_saved_messages = 0; int total_new_urgent_messages = 0; @@ -2099,13 +2101,19 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p } else { switch_event_t *params; file_path = switch_mprintf("%s%sgreeting_%d.%s", dir_path, SWITCH_PATH_SEPARATOR, num, profile->file_ext); + tmp_file_path = switch_mprintf("%s%sgreeting_%d_TMP.%s", dir_path, SWITCH_PATH_SEPARATOR, num, profile->file_ext); + unlink(tmp_file_path); + TRY_CODE(create_file(session, profile, VM_RECORD_GREETING_MACRO, file_path, &message_len, SWITCH_TRUE, NULL, NULL)); + switch_file_rename(tmp_file_path, file_path, switch_core_session_get_pool(session)); + sql = switch_mprintf("update voicemail_prefs set greeting_path='%s' where username='%s' and domain='%s'", file_path, myid, domain_name); vm_execute_sql(profile, sql, profile->mutex); switch_safe_free(sql); switch_safe_free(file_path); + switch_safe_free(tmp_file_path); switch_event_create_subclass(¶ms, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Action", "record-greeting"); @@ -2146,10 +2154,14 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p } else if (!strcmp(input, profile->record_name_key)) { switch_event_t *params; file_path = switch_mprintf("%s%srecorded_name.%s", dir_path, SWITCH_PATH_SEPARATOR, profile->file_ext); + tmp_file_path = switch_mprintf("%s%srecorded_name_TMP.%s", dir_path, SWITCH_PATH_SEPARATOR, profile->file_ext); + unlink(tmp_file_path); TRY_CODE(create_file(session, profile, VM_RECORD_NAME_MACRO, file_path, &message_len, SWITCH_FALSE, NULL, NULL)); + switch_file_rename(tmp_file_path, file_path, switch_core_session_get_pool(session)); sql = switch_mprintf("update voicemail_prefs set name_path='%s' where username='%s' and domain='%s'", file_path, myid, domain_name); vm_execute_sql(profile, sql, profile->mutex); switch_safe_free(file_path); + switch_safe_free(tmp_file_path); switch_safe_free(sql); switch_event_create_subclass(¶ms, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT); @@ -2431,6 +2443,14 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p end: + switch_safe_free(file_path); + + if (tmp_file_path) { + unlink(tmp_file_path); + free(tmp_file_path); + tmp_file_path = NULL; + } + if (switch_channel_ready(channel)) { if (failed) { status = switch_ivr_phrase_macro(session, VM_ABORT_MACRO, NULL, NULL, NULL); From 47f997a05030133c4a406d3ad4709121be8a9904 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 16 Aug 2011 13:26:43 -0500 Subject: [PATCH 055/354] back off locking contention so you can query for other interfaces while a module is loading that locks the interfaces hash --- src/switch_loadable_module.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 8fca52eb58..007309781e 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -994,8 +994,8 @@ static switch_status_t switch_loadable_module_load_module_ex(char *dir, char *fn switch_snprintf(path, len, "%s%s%s%s", dir, SWITCH_PATH_SEPARATOR, file, ext); } - switch_mutex_lock(loadable_modules.mutex); - if (switch_core_hash_find(loadable_modules.module_hash, file)) { + + if (switch_core_hash_find_locked(loadable_modules.module_hash, file, loadable_modules.mutex)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Module %s Already Loaded!\n", file); *err = "Module already loaded"; status = SWITCH_STATUS_FALSE; @@ -1010,7 +1010,7 @@ static switch_status_t switch_loadable_module_load_module_ex(char *dir, char *fn } else { *err = "module load file routine returned an error"; } - switch_mutex_unlock(loadable_modules.mutex); + return status; From d48edc53ed5440a20878d9fe1d0ff847d9594b8a Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Tue, 16 Aug 2011 22:38:13 +0200 Subject: [PATCH 056/354] mod_sofia: don't complain that an info dtmf was ignored if it actually wasn't a dtmf info message --- src/mod/endpoints/mod_sofia/sofia.c | 46 +++++++++++++++-------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 0f6486a361..f7fbacff1a 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6745,35 +6745,37 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t goto end; } - if (dtmf.digit && (tech_pvt->dtmf_type == DTMF_INFO || - sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || sofia_test_flag(tech_pvt, TFLAG_LIBERAL_DTMF))) { - /* queue it up */ - switch_channel_queue_dtmf(channel, &dtmf); + if (dtmf.digit) { + if (tech_pvt->dtmf_type == DTMF_INFO || + sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || sofia_test_flag(tech_pvt, TFLAG_LIBERAL_DTMF)) { + /* queue it up */ + switch_channel_queue_dtmf(channel, &dtmf); - /* print debug info */ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "INFO DTMF(%c)\n", dtmf.digit); + /* print debug info */ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "INFO DTMF(%c)\n", dtmf.digit); - if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { - const char *uuid; - switch_core_session_t *session_b; + if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { + const char *uuid; + switch_core_session_t *session_b; - if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (session_b = switch_core_session_locate(uuid))) { - while (switch_channel_has_dtmf(channel)) { - switch_dtmf_t idtmf = { 0, 0 }; - if (switch_channel_dequeue_dtmf(channel, &idtmf) == SWITCH_STATUS_SUCCESS) { - switch_core_session_send_dtmf(session_b, &idtmf); + if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (session_b = switch_core_session_locate(uuid))) { + while (switch_channel_has_dtmf(channel)) { + switch_dtmf_t idtmf = { 0, 0 }; + if (switch_channel_dequeue_dtmf(channel, &idtmf) == SWITCH_STATUS_SUCCESS) { + switch_core_session_send_dtmf(session_b, &idtmf); + } } + + switch_core_session_rwunlock(session_b); } - - switch_core_session_rwunlock(session_b); } - } - /* Send 200 OK response */ - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, - "IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit); + /* Send 200 OK response */ + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, + "IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit); + } } goto end; } From 1521869750b0522a83cf38081eaeb773ead64a02 Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Tue, 16 Aug 2011 17:19:07 -0400 Subject: [PATCH 057/354] mod_protovm: Removal of the proto vm. Might reinclude it under a different name in the future. --- src/mod/applications/mod_protovm/Makefile | 3 - src/mod/applications/mod_protovm/config.c | 135 ---- src/mod/applications/mod_protovm/config.h | 53 -- src/mod/applications/mod_protovm/ivr.c | 250 ------ src/mod/applications/mod_protovm/ivr.h | 30 - src/mod/applications/mod_protovm/menu.c | 743 ------------------ src/mod/applications/mod_protovm/menu.h | 32 - .../applications/mod_protovm/mod_protovm.c | 139 ---- .../applications/mod_protovm/protovm.conf.xml | 176 ----- src/mod/applications/mod_protovm/sounds.xml | 397 ---------- src/mod/applications/mod_protovm/util.c | 175 ----- src/mod/applications/mod_protovm/util.h | 16 - 12 files changed, 2149 deletions(-) delete mode 100644 src/mod/applications/mod_protovm/Makefile delete mode 100644 src/mod/applications/mod_protovm/config.c delete mode 100644 src/mod/applications/mod_protovm/config.h delete mode 100644 src/mod/applications/mod_protovm/ivr.c delete mode 100644 src/mod/applications/mod_protovm/ivr.h delete mode 100644 src/mod/applications/mod_protovm/menu.c delete mode 100644 src/mod/applications/mod_protovm/menu.h delete mode 100644 src/mod/applications/mod_protovm/mod_protovm.c delete mode 100644 src/mod/applications/mod_protovm/protovm.conf.xml delete mode 100644 src/mod/applications/mod_protovm/sounds.xml delete mode 100644 src/mod/applications/mod_protovm/util.c delete mode 100644 src/mod/applications/mod_protovm/util.h diff --git a/src/mod/applications/mod_protovm/Makefile b/src/mod/applications/mod_protovm/Makefile deleted file mode 100644 index 92f8441104..0000000000 --- a/src/mod/applications/mod_protovm/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -BASE=../../../.. -LOCAL_OBJS=ivr.o util.o config.o menu.o -include $(BASE)/build/modmake.rules diff --git a/src/mod/applications/mod_protovm/config.c b/src/mod/applications/mod_protovm/config.c deleted file mode 100644 index 6a2573b83a..0000000000 --- a/src/mod/applications/mod_protovm/config.c +++ /dev/null @@ -1,135 +0,0 @@ -/* Copy paste from FS mod_voicemail */ -#include - -#include "config.h" - -const char *global_cf = "protovm.conf"; - -void populate_profile_menu_event(vmivr_profile_t *profile, vmivr_menu_profile_t *menu) { - switch_xml_t cfg, xml, x_profiles, x_profile, x_keys, x_phrases, x_menus, x_menu; - - free_profile_menu_event(menu); - - if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); - goto end; - } - if (!(x_profiles = switch_xml_child(cfg, "profiles"))) { - goto end; - } - - if ((x_profile = switch_xml_find_child(x_profiles, "profile", "name", profile->name))) { - if ((x_menus = switch_xml_child(x_profile, "menus"))) { - if ((x_menu = switch_xml_find_child(x_menus, "menu", "name", menu->name))) { - if ((x_keys = switch_xml_child(x_menu, "keys"))) { - switch_event_import_xml(switch_xml_child(x_keys, "key"), "dtmf", "action", &menu->event_keys_dtmf); - switch_event_import_xml(switch_xml_child(x_keys, "key"), "action", "dtmf", &menu->event_keys_action); - switch_event_import_xml(switch_xml_child(x_keys, "key"), "action", "variable", &menu->event_keys_varname); - } - if ((x_phrases = switch_xml_child(x_menu, "phrases"))) { - switch_event_import_xml(switch_xml_child(x_phrases, "phrase"), "name", "value", &menu->event_phrases); - } - } - } - } -end: - if (xml) - switch_xml_free(xml); - return; - -} - -void free_profile_menu_event(vmivr_menu_profile_t *menu) { - if (menu->event_keys_dtmf) { - switch_event_destroy(&menu->event_keys_dtmf); - } - if (menu->event_keys_action) { - switch_event_destroy(&menu->event_keys_action); - } - if (menu->event_keys_varname) { - switch_event_destroy(&menu->event_keys_varname); - } - - if (menu->event_phrases) { - switch_event_destroy(&menu->event_phrases); - } -} - -vmivr_profile_t *get_profile(switch_core_session_t *session, const char *profile_name) -{ - vmivr_profile_t *profile = NULL; - switch_xml_t cfg, xml, x_profiles, x_profile, x_apis, param; - - if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); - return profile; - } - if (!(x_profiles = switch_xml_child(cfg, "profiles"))) { - goto end; - } - - if ((x_profile = switch_xml_find_child(x_profiles, "profile", "name", profile_name))) { - if (!(profile = switch_core_session_alloc(session, sizeof(vmivr_profile_t)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Alloc Failure\n"); - goto end; - } - - profile->name = profile_name; - - profile->current_msg = 0; - profile->current_msg_uuid = NULL; - - /* TODO Make the following configurable */ - profile->api_profile = profile->name; - profile->menu_check_auth = "std_authenticate"; - profile->menu_check_main = "std_navigator"; - profile->menu_check_terminate = "std_purge"; - - if ((x_apis = switch_xml_child(x_profile, "apis"))) { - int total_options = 0; - int total_invalid_options = 0; - for (param = switch_xml_child(x_apis, "api"); param; param = param->next) { - char *var, *val; - if ((var = (char *) switch_xml_attr_soft(param, "name")) && (val = (char *) switch_xml_attr_soft(param, "value"))) { - if (!strcasecmp(var, "msg_undelete") && !profile->api_msg_undelete) - profile->api_msg_undelete = switch_core_session_strdup(session, val); - else if (!strcasecmp(var, "msg_delete") && !profile->api_msg_delete) - profile->api_msg_delete = switch_core_session_strdup(session, val); - else if (!strcasecmp(var, "msg_list") && !profile->api_msg_list) - profile->api_msg_list = switch_core_session_strdup(session, val); - else if (!strcasecmp(var, "msg_count") && !profile->api_msg_count) - profile->api_msg_count = switch_core_session_strdup(session, val); - else if (!strcasecmp(var, "msg_save") && !profile->api_msg_save) - profile->api_msg_save = switch_core_session_strdup(session, val); - else if (!strcasecmp(var, "msg_purge") && !profile->api_msg_purge) - profile->api_msg_purge = switch_core_session_strdup(session, val); - else if (!strcasecmp(var, "msg_get") && !profile->api_msg_get) - profile->api_msg_get = switch_core_session_strdup(session, val); - else if (!strcasecmp(var, "msg_forward") && !profile->api_msg_forward) - profile->api_msg_forward = switch_core_session_strdup(session, val); - else if (!strcasecmp(var, "pref_greeting_set") && !profile->api_pref_greeting_set) - profile->api_pref_greeting_set = switch_core_session_strdup(session, val); - else if (!strcasecmp(var, "pref_recname_set") && !profile->api_pref_recname_set) - profile->api_pref_recname_set = switch_core_session_strdup(session, val); - else if (!strcasecmp(var, "pref_password_set") && !profile->api_pref_password_set) - profile->api_pref_password_set = switch_core_session_strdup(session, val); - else if (!strcasecmp(var, "auth_login") && !profile->api_auth_login) - profile->api_auth_login = switch_core_session_strdup(session, val); - else - total_invalid_options++; - total_options++; - } - } - if (total_options - total_invalid_options != 12) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing api definition for profile '%s'\n", profile_name); - profile = NULL; - } - } - - } - -end: - switch_xml_free(xml); - return profile; -} - diff --git a/src/mod/applications/mod_protovm/config.h b/src/mod/applications/mod_protovm/config.h deleted file mode 100644 index 2429f2cb36..0000000000 --- a/src/mod/applications/mod_protovm/config.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _CONFIG_H_ -#define _CONFIG_H_ - -extern const char *global_cf; - -struct vmivr_profile { - const char *name; - - const char *domain; - const char *id; - - int current_msg; - const char *current_msg_uuid; - - const char *menu_check_auth; - const char *menu_check_main; - const char *menu_check_terminate; - - switch_bool_t authorized; - - const char *api_profile; - const char *api_auth_login; - const char *api_msg_delete; - const char *api_msg_undelete; - const char *api_msg_list; - const char *api_msg_count; - const char *api_msg_save; - const char *api_msg_purge; - const char *api_msg_get; - const char *api_msg_forward; - const char *api_pref_greeting_set; - const char *api_pref_recname_set; - const char *api_pref_password_set; - -}; -typedef struct vmivr_profile vmivr_profile_t; - -struct vmivr_menu_profile { - const char *name; - - switch_event_t *event_keys_action; - switch_event_t *event_keys_dtmf; - switch_event_t *event_keys_varname; - switch_event_t *event_phrases; -}; -typedef struct vmivr_menu_profile vmivr_menu_profile_t; - -vmivr_profile_t *get_profile(switch_core_session_t *session, const char *profile_name); - -void free_profile_menu_event(vmivr_menu_profile_t *menu); -void populate_profile_menu_event(vmivr_profile_t *profile, vmivr_menu_profile_t *menu); - -#endif /* _CONFIG_H_ */ diff --git a/src/mod/applications/mod_protovm/ivr.c b/src/mod/applications/mod_protovm/ivr.c deleted file mode 100644 index a48132b1a2..0000000000 --- a/src/mod/applications/mod_protovm/ivr.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Marc Olivier Chouinard - * - * - * ivr.c -- MT IVR System Interface - * - */ - -#include - -#include "ivr.h" - -int match_dtmf(switch_core_session_t *session, dtmf_ss_t *loc) { - switch_bool_t is_invalid[128] = { SWITCH_FALSE }; - int i; - loc->potentialMatch = NULL; - loc->completeMatch = NULL; - loc->potentialMatchCount = 0; - - for (i = 0; i < loc->dtmf_received; i++) { - int j; - loc->potentialMatchCount = 0; - for (j = 0; !zstr(loc->dtmf_accepted[j]) && j < 128; j++) { - switch_bool_t cMatch = SWITCH_FALSE; - char test[2] = { 0 }; - - if (is_invalid[j]) - continue; - - test[0] = loc->dtmf_stored[i]; - if (loc->dtmf_accepted[j][i] == 'N' && atoi(test) >= 2 && atoi(test) <= 9) - cMatch = SWITCH_TRUE; - if (loc->dtmf_accepted[j][i] == 'X' && atoi(test) >= 0 && atoi(test) <= 9) { - cMatch = SWITCH_TRUE; - } - if (i >= strlen(loc->dtmf_accepted[j]) - 1 && loc->dtmf_accepted[j][strlen(loc->dtmf_accepted[j])-1] == '.') - cMatch = SWITCH_TRUE; - if (loc->dtmf_accepted[j][i] == loc->dtmf_stored[i]) - cMatch = SWITCH_TRUE; - - if (cMatch == SWITCH_FALSE) { - is_invalid[j] = SWITCH_TRUE; - continue; - } - - if (i == strlen(loc->dtmf_accepted[j]) - 1 && loc->dtmf_accepted[j][strlen(loc->dtmf_accepted[j])-1] == '.') { - loc->completeMatch = loc->dtmf_accepted[j]; - } - if (i == loc->dtmf_received - 1 && loc->dtmf_received == strlen(loc->dtmf_accepted[j]) && loc->dtmf_accepted[j][strlen(loc->dtmf_accepted[j])-1] != '.') { - loc->completeMatch = loc->dtmf_accepted[j]; - continue; - } - loc->potentialMatchCount++; - } - } - - return 1; -} - -static switch_status_t cb_on_dtmf_ignore(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) -{ - switch (itype) { - case SWITCH_INPUT_TYPE_DTMF: - { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_dtmf_t *dtmf = (switch_dtmf_t *) input; - switch_channel_queue_dtmf(channel, dtmf); - return SWITCH_STATUS_BREAK; - } - default: - break; - } - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t cb_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) -{ - dtmf_ss_t *loc = (dtmf_ss_t*) buf; - - switch (itype) { - case SWITCH_INPUT_TYPE_DTMF: - { - switch_dtmf_t *dtmf = (switch_dtmf_t *) input; - switch_bool_t audio_was_stopped = loc->audio_stopped; - loc->audio_stopped = SWITCH_TRUE; - - if (loc->dtmf_received >= sizeof(loc->dtmf_stored)) { - loc->result = RES_BUFFER_OVERFLOW; - break; - } - if (!loc->terminate_key || dtmf->digit != loc->terminate_key) - loc->dtmf_stored[loc->dtmf_received++] = dtmf->digit; - - match_dtmf(session, loc); - - if (loc->terminate_key && dtmf->digit == loc->terminate_key && loc->result == RES_WAITFORMORE) { - if (loc->potentialMatchCount == 1 && loc->completeMatch != NULL) { - loc->result = RES_FOUND; - } else { - loc->result = RES_INVALID; - } - return SWITCH_STATUS_BREAK; - } else { - if (loc->potentialMatchCount == 0 && loc->completeMatch != NULL) { - loc->result = RES_FOUND; - return SWITCH_STATUS_BREAK; - } else if (loc->potentialMatchCount > 0) { - loc->result = RES_WAITFORMORE; - if (!audio_was_stopped) - return SWITCH_STATUS_BREAK; - } else { - loc->result = RES_INVALID; - return SWITCH_STATUS_BREAK; - } - } - } - break; - default: - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t captureMenuInitialize(dtmf_ss_t *loc, char **dtmf_accepted) { - int i; - - memset(loc, 0, sizeof(*loc)); - - for (i = 0; dtmf_accepted[i] && i < 16; i++) { - strncpy(loc->dtmf_accepted[i], dtmf_accepted[i], 128); - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t playbackBufferDTMF(switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout) { - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_channel_t *channel = switch_core_session_get_channel(session); - - if (switch_channel_ready(channel)) { - switch_input_args_t args = { 0 }; - - args.input_callback = cb_on_dtmf_ignore; - - if (macro_name) { - status = switch_ivr_phrase_macro_event(session, macro_name, data, event, lang, &args); - } - } else { - status = SWITCH_STATUS_BREAK; - } - - return status; -} - - -switch_status_t captureMenu(switch_core_session_t *session, dtmf_ss_t *loc, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout) { - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_channel_t *channel = switch_core_session_get_channel(session); - - if (switch_channel_ready(channel)) { - switch_input_args_t args = { 0 }; - - args.input_callback = cb_on_dtmf; - args.buf = loc; - - if (macro_name && loc->audio_stopped == SWITCH_FALSE && loc->result == RES_WAITFORMORE) { - status = switch_ivr_phrase_macro_event(session, macro_name, data, event, lang, &args); - } - - if (switch_channel_ready(channel) && (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) && timeout && loc->result == RES_WAITFORMORE) { - loc->audio_stopped = SWITCH_TRUE; - switch_ivr_collect_digits_callback(session, &args, timeout, 0); - if (loc->result == RES_WAITFORMORE) { - if (loc->potentialMatchCount == 1 && loc->completeMatch != NULL) { - loc->result = RES_FOUND; - } else { - loc->result = RES_TIMEOUT; - } - } - } - } else { - status = SWITCH_STATUS_BREAK; - } - - return status; -} - -switch_status_t captureMenuRecord(switch_core_session_t *session, dtmf_ss_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len) { - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_channel_t *channel = switch_core_session_get_channel(session); - - if (switch_channel_ready(channel)) { - switch_input_args_t args = { 0 }; - - args.input_callback = cb_on_dtmf; - args.buf = loc; - - if (loc->audio_stopped == SWITCH_FALSE && loc->result == RES_WAITFORMORE) { - loc->recorded_audio = SWITCH_TRUE; - switch_ivr_gentones(session, "%(1000, 0, 640)", 0, NULL); /* TODO Make this optional and configurable */ - status = switch_ivr_record_file(session, fh, file_path, &args, max_record_len); - - } - if (loc->result == RES_WAITFORMORE) { - loc->result = RES_TIMEOUT; - } - - } else { - status = SWITCH_STATUS_BREAK; - } - - return status; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 - */ diff --git a/src/mod/applications/mod_protovm/ivr.h b/src/mod/applications/mod_protovm/ivr.h deleted file mode 100644 index 99136475fd..0000000000 --- a/src/mod/applications/mod_protovm/ivr.h +++ /dev/null @@ -1,30 +0,0 @@ -struct dtmf_ss { - char dtmf_stored[128]; - int dtmf_received; - char dtmf_accepted[16][128]; - int result; - switch_bool_t audio_stopped; - switch_bool_t recorded_audio; - const char *potentialMatch; - int potentialMatchCount; - const char *completeMatch; - char terminate_key; -}; -typedef struct dtmf_ss dtmf_ss_t; - -#define RES_WAITFORMORE 0 -#define RES_FOUND 1 -#define RES_INVALID 3 -#define RES_TIMEOUT 4 -#define RES_BREAK 5 -#define RES_RECORD 6 -#define RES_BUFFER_OVERFLOW 99 - -#define MAX_DTMF_SIZE_OPTION 32 - -switch_status_t captureMenu(switch_core_session_t *session, dtmf_ss_t *loc, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout); -switch_status_t captureMenuRecord(switch_core_session_t *session, dtmf_ss_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len); -switch_status_t captureMenuInitialize(dtmf_ss_t *loc, char **dtmf_accepted); - -switch_status_t playbackBufferDTMF(switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout); - diff --git a/src/mod/applications/mod_protovm/menu.c b/src/mod/applications/mod_protovm/menu.c deleted file mode 100644 index ba4229d43d..0000000000 --- a/src/mod/applications/mod_protovm/menu.c +++ /dev/null @@ -1,743 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Marc Olivier Chouinard - * - * - * menu.c -- VoiceMail Menu - * - */ -#include - -#include "ivr.h" -#include "menu.h" -#include "util.h" -#include "config.h" - -/* List of available menu */ -vmivr_menu_function_t menu_list[] = { - {"std_authenticate", mtvm_menu_authenticate}, - {"std_navigator", mtvm_menu_main}, - {"std_record_name", mtvm_menu_record_name}, - {"std_set_password", mtvm_menu_set_password}, - {"std_select_greeting_slot", mtvm_menu_select_greeting_slot}, - {"std_record_greeting_with_slot", mtvm_menu_record_greeting_with_slot}, - {"std_preference", mtvm_menu_preference}, - {"std_purge", mtvm_menu_purge}, - {"std_forward", mtvm_menu_forward}, - { NULL, NULL } -}; - -#define MAX_ATTEMPT 3 /* TODO Make these fields configurable */ -#define DEFAULT_IVR_TIMEOUT 3000 - -void mtvm_menu_purge(switch_core_session_t *session, vmivr_profile_t *profile) { - if (profile->id && profile->authorized) { - if (1==1 /* TODO make Purge email on exit optional ??? */) { - const char *cmd = switch_core_session_sprintf(session, "%s %s %s", profile->api_profile, profile->domain, profile->id); - mt_api_execute(session, profile->api_msg_purge, cmd); - } - } -} -void mtvm_menu_main(switch_core_session_t *session, vmivr_profile_t *profile) { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_event_t *msg_list_params = NULL; - size_t msg_count = 0; - size_t current_msg = 1; - size_t next_msg = current_msg; - size_t previous_msg = current_msg; - char *cmd = NULL; - int retry; - - /* Different switch to control playback of phrases */ - switch_bool_t initial_count_played = SWITCH_FALSE; - switch_bool_t skip_header = SWITCH_FALSE; - switch_bool_t msg_deleted = SWITCH_FALSE; - switch_bool_t msg_undeleted = SWITCH_FALSE; - switch_bool_t msg_saved = SWITCH_FALSE; - - vmivr_menu_profile_t menu = { "std_navigator" }; - - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &menu); - - if (!menu.event_keys_dtmf || !menu.event_phrases) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases or Keys\n"); - return; - } - - /* Get VoiceMail List And update msg count */ - cmd = switch_core_session_sprintf(session, "json %s %s %s", profile->api_profile, profile->domain, profile->id); - msg_list_params = jsonapi2event(session, NULL, profile->api_msg_list, cmd); - msg_count = atol(switch_event_get_header(msg_list_params,"VM-List-Count")); - - /* TODO Add Detection of new message and notify the user */ - - for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { - switch_core_session_message_t msg = { 0 }; - char cid_buf[1024] = ""; - dtmf_ss_t loc; - char *dtmfa[16] = { 0 }; - switch_event_t *phrase_params = NULL; - - switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); - - append_event_profile(phrase_params, profile, menu); - - populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa); - - previous_msg = current_msg; - - /* Simple Protection to not go out of msg list scope */ - /* TODO: Add Prompt to notify they reached the begining or the end */ - if (next_msg == 0) { - next_msg = 1; - } else if (next_msg > msg_count) { - next_msg = msg_count; - } - - current_msg = next_msg; - - captureMenuInitialize(&loc, dtmfa); - - /* Prompt related to previous Message here */ - append_event_message(session, profile, phrase_params, msg_list_params, previous_msg); - if (msg_deleted) { - msg_deleted = SWITCH_FALSE; - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "deleted", phrase_params, NULL, 0); - } - if (msg_undeleted) { - msg_undeleted = SWITCH_FALSE; - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "undeleted", phrase_params, NULL, 0); - } - if (msg_saved) { - msg_saved = SWITCH_FALSE; - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "saved", phrase_params, NULL, 0); - } - - /* Prompt related the current message */ - append_event_message(session, profile, phrase_params, msg_list_params, current_msg); - - /* Save in profile the current msg info for other menu processing AND restoration of our current position */ - switch_snprintf(cid_buf, sizeof(cid_buf), "%s|%s", switch_str_nil(switch_event_get_header(phrase_params, "VM-Message-Caller-Number")), switch_str_nil(switch_event_get_header(phrase_params, "VM-Message-Caller-Name"))); - - /* Display MSG CID/Name to caller */ - msg.from = __FILE__; - msg.string_arg = cid_buf; - msg.message_id = SWITCH_MESSAGE_INDICATE_DISPLAY; - switch_core_session_receive_message(session, &msg); - - profile->current_msg = current_msg; - profile->current_msg_uuid = switch_core_session_strdup(session, switch_event_get_header(phrase_params, "VM-Message-UUID")); - - /* TODO check if msg is gone (purged by another session, notify user and auto jump to next message or something) */ - if (!skip_header) { - if (!initial_count_played) { - cmd = switch_core_session_sprintf(session, "json %s %s %s", profile->api_profile, profile->domain, profile->id); - jsonapi2event(session, phrase_params, profile->api_msg_count, cmd); - initial_count_played = SWITCH_TRUE; - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "msg_count"), NULL, phrase_params, NULL, 0); - } - if (msg_count > 0) { - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "say_msg_number"), NULL, phrase_params, NULL, 0); - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "say_date"), NULL, phrase_params, NULL, 0); - } - } - if (msg_count > 0) { - /* TODO Update the Read date of a message (When msg start, or when it listen compleatly ??? To be determined */ - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "play_message"), NULL, phrase_params, NULL, 0); - } - skip_header = SWITCH_FALSE; - - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); - - if (loc.result == RES_TIMEOUT) { - /* TODO Ask for the prompt Again IF retry != 0 */ - } else if (loc.result == RES_INVALID) { - /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ - } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ - const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored); - - /* Reset the try count */ - retry = MAX_ATTEMPT; - - if (action) { - if (!strcasecmp(action, "skip_intro")) { /* Skip Header / Play the recording again */ - skip_header = SWITCH_TRUE; - } else if (!strcasecmp(action, "next_msg")) { /* Next Message */ - next_msg++; - } else if (!strcasecmp(action, "prev_msg")) { /* Previous Message */ - next_msg--; - } else if (!strcasecmp(action, "delete_msg")) { /* Delete / Undelete Message */ - const char *msg_flags = switch_event_get_header(phrase_params, "VM-Message-Flags"); - if (!msg_flags || strncasecmp(msg_flags, "delete", 6)) { - cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID")); - mt_api_execute(session, profile->api_msg_delete, cmd); - - msg_deleted = SWITCH_TRUE; - /* TODO Option for auto going to next message or just return to the menu (So user used to do 76 to delete and next message wont be confused) */ - next_msg++; - } else { - cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID")); - mt_api_execute(session, profile->api_msg_undelete, cmd); - - msg_undeleted = SWITCH_TRUE; - } - } else if (!strcasecmp(action, "save_msg")) { /* Save Message */ - cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID")); - mt_api_execute(session, profile->api_msg_save, cmd); - - msg_saved = SWITCH_TRUE; - } else if (!strcasecmp(action, "callback")) { /* CallBack caller */ - const char *cid_num = switch_event_get_header(phrase_params, "VM-Message-Caller-Number"); - if (cid_num) { - /* TODO add detection for private number */ - switch_core_session_execute_exten(session, cid_num, "XML", profile->domain); - } else { - /* TODO Some error msg that the msg doesn't contain a caller number */ - } - } else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */ - void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5); - if (fPtr) { - fPtr(session, profile); - } - } else if (!strcasecmp(action, "return")) { /* Return */ - retry = -1; - } - } - } - - /* IF the API to get the message returned us a COPY of the file locally (temp file create from a DB or from a web server), delete it */ - if (switch_true(switch_event_get_header(phrase_params, "VM-Message-Private-Local-Copy"))) { - const char *file_path = switch_event_get_header(phrase_params, "VM-Message-File-Path"); - if (file_path && unlink(file_path) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete temp file [%s]\n", file_path); - } - } - switch_event_destroy(&phrase_params); - } - - switch_event_destroy(&msg_list_params); - - free_profile_menu_event(&menu); - - return; -} - -void mtvm_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile) { - - vmivr_menu_profile_t menu = { "std_forward_ask_prepend" }; - switch_channel_t *channel = switch_core_session_get_channel(session); - const char *prepend_filepath = NULL; - int retry; - switch_bool_t forward_msg = SWITCH_FALSE; - - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &menu); - - if (!menu.event_keys_dtmf || !menu.event_phrases) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n"); - return; - } - - for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { - dtmf_ss_t loc; - char *dtmfa[16] = { 0 }; - switch_event_t *phrase_params = NULL; - - switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); - append_event_profile(phrase_params, profile, menu); - - populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa); - - captureMenuInitialize(&loc, dtmfa); - - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); - - if (loc.result == RES_TIMEOUT) { - /* TODO Ask for the prompt Again IF retry != 0 */ - } else if (loc.result == RES_INVALID) { - /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ - } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ - const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored); - - /* Reset the try count */ - retry = MAX_ATTEMPT; - - if (action) { - if (!strcasecmp(action, "return")) { /* Return to the previous menu */ - retry = -1; - forward_msg = SWITCH_FALSE; - } else if (!strcasecmp(action, "prepend")) { /* Prepend record msg */ - vmivr_menu_profile_t sub_menu = { "std_record_message" }; - char *tmp_filepath = generate_random_file_name(session, "protovm", "wav" /* TODO make it configurable */); - switch_status_t status; - - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &sub_menu); - - status = mtvm_menu_record(session, profile, sub_menu, tmp_filepath); - - if (status == SWITCH_STATUS_SUCCESS) { - //char *cmd = switch_core_session_sprintf(session, "%s %s %s %d %s", profile->api_profile, profile->domain, profile->id, gnum, tmp_filepath); - //char *str_num = switch_core_session_sprintf(session, "%d", gnum); - //mt_api_execute(session, profile->api_pref_greeting_set, cmd); - //playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0); - prepend_filepath = tmp_filepath; - retry = -1; - forward_msg = SWITCH_TRUE; - } else { - /* TODO Error Recording msg */ - } - free_profile_menu_event(&sub_menu); - - } else if (!strcasecmp(action, "forward")) { /* Forward without prepend msg */ - retry = -1; - forward_msg = SWITCH_TRUE; - } else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */ - void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5); - if (fPtr) { - fPtr(session, profile); - } - } - } - } - switch_event_destroy(&phrase_params); - - - } - /* Ask Extension to Forward */ - if (forward_msg) { - for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { - const char *id = NULL; - vmivr_menu_profile_t sub_menu = { "std_forward_ask_extension" }; - - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &sub_menu); - - id = mtvm_menu_get_input_set(session, profile, sub_menu, "X."); - if (id) { - const char *cmd = switch_core_session_sprintf(session, "%s %s %s %s %s %s %s%s%s", profile->api_profile, profile->domain, profile->id, profile->current_msg_uuid, profile->domain, id, prepend_filepath?" ":"", prepend_filepath?prepend_filepath:"" ); - if (mt_api_execute(session, profile->api_msg_forward, cmd) == SWITCH_STATUS_SUCCESS) { - playbackBufferDTMF(session, switch_event_get_header(sub_menu.event_phrases, "ack"), "saved", NULL, NULL, 0); - retry = -1; - } else { - playbackBufferDTMF(session, switch_event_get_header(sub_menu.event_phrases, "invalid_extension"), NULL, NULL, NULL, 0); - } - } else { - /* TODO Prompt about input not valid */ - } - free_profile_menu_event(&sub_menu); - /* TODO add Confirmation of the transfered number */ - } - /* TODO Ask if we want to transfer the msg to more person */ - - } - - free_profile_menu_event(&menu); -} - - -void mtvm_menu_record_name(switch_core_session_t *session, vmivr_profile_t *profile) { - switch_status_t status; - vmivr_menu_profile_t menu = { "std_record_name" }; - - char *tmp_filepath = generate_random_file_name(session, "protovm", "wav" /* TODO make it configurable */); - - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &menu); - - status = mtvm_menu_record(session, profile, menu, tmp_filepath); - - if (status == SWITCH_STATUS_SUCCESS) { - char *cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, tmp_filepath); - mt_api_execute(session, profile->api_pref_recname_set, cmd); - } -} - -void mtvm_menu_set_password(switch_core_session_t *session, vmivr_profile_t *profile) { - char *password; - vmivr_menu_profile_t menu = { "std_set_password" }; - - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &menu); - - password = mtvm_menu_get_input_set(session, profile, menu, "XXX." /* TODO Conf Min 3 Digit */); - - /* TODO Add Prompts to tell if password was set and if it was not */ - if (password) { - char *cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, password); - mt_api_execute(session, profile->api_pref_password_set, cmd); - - } - - free_profile_menu_event(&menu); -} - -void mtvm_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *profile) { - switch_channel_t *channel = switch_core_session_get_channel(session); - vmivr_menu_profile_t menu = { "std_authenticate" }; - int retry; - const char *auth_var = NULL; - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &menu); - - if (profile->id && (auth_var = switch_channel_get_variable(channel, "voicemail_authorized")) && switch_true(auth_var)) { - profile->authorized = SWITCH_TRUE; - } - - for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0 && profile->authorized == SWITCH_FALSE; retry--) { - const char *id = profile->id, *password = NULL; - char *cmd = NULL; - - if (!id) { - vmivr_menu_profile_t sub_menu = { "std_authenticate_ask_user" }; - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &sub_menu); - - id = mtvm_menu_get_input_set(session, profile, sub_menu, "X." /* TODO Conf Min 3 Digit */); - free_profile_menu_event(&sub_menu); - } - if (!password) { - vmivr_menu_profile_t sub_menu = { "std_authenticate_ask_password" }; - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &sub_menu); - - password = mtvm_menu_get_input_set(session, profile, sub_menu, "X." /* TODO Conf Min 3 Digit */); - free_profile_menu_event(&sub_menu); - } - cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, id, password); - - if (mt_api_execute(session, profile->api_auth_login, cmd) == SWITCH_STATUS_SUCCESS) { - profile->id = id; - profile->authorized = SWITCH_TRUE; - } else { - playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "fail_auth"), NULL, NULL, NULL, 0); - } - } - free_profile_menu_event(&menu); -} - -void mtvm_menu_select_greeting_slot(switch_core_session_t *session, vmivr_profile_t *profile) { - vmivr_menu_profile_t menu = { "std_select_greeting_slot" }; - - const char *result; - int gnum = -1; - - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &menu); - - result = mtvm_menu_get_input_set(session, profile, menu, "X"); - - if (result) - gnum = atoi(result); - if (gnum != -1) { - char * cmd = switch_core_session_sprintf(session, "%s %s %s %d", profile->api_profile, profile->domain, profile->id, gnum); - if (mt_api_execute(session, profile->api_pref_greeting_set, cmd) == SWITCH_STATUS_SUCCESS) { - char *str_num = switch_core_session_sprintf(session, "%d", gnum); - playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0); - } else { - playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "invalid_slot"), NULL, NULL, NULL, 0); - } - } - free_profile_menu_event(&menu); -} - -void mtvm_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_profile_t *profile) { - - vmivr_menu_profile_t menu = { "std_record_greeting_with_slot" }; - - const char *result; - int gnum = -1; - - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &menu); - - result = mtvm_menu_get_input_set(session, profile, menu, "X"); - - if (result) - gnum = atoi(result); - - /* If user entered 0, we don't accept it */ - if (gnum > 0) { - vmivr_menu_profile_t sub_menu = { "std_record_greeting" }; - char *tmp_filepath = generate_random_file_name(session, "protovm", "wav" /* TODO make it configurable */); - switch_status_t status; - - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &sub_menu); - - status = mtvm_menu_record(session, profile, sub_menu, tmp_filepath); - - if (status == SWITCH_STATUS_SUCCESS) { - char *cmd = switch_core_session_sprintf(session, "%s %s %s %d %s", profile->api_profile, profile->domain, profile->id, gnum, tmp_filepath); - char *str_num = switch_core_session_sprintf(session, "%d", gnum); - mt_api_execute(session, profile->api_pref_greeting_set, cmd); - playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0); - } - free_profile_menu_event(&sub_menu); - - } - - free_profile_menu_event(&menu); - -} - -void mtvm_menu_preference(switch_core_session_t *session, vmivr_profile_t *profile) { - switch_channel_t *channel = switch_core_session_get_channel(session); - - int retry; - - vmivr_menu_profile_t menu = { "std_preference" }; - - /* Initialize Menu Configs */ - populate_profile_menu_event(profile, &menu); - - if (!menu.event_keys_dtmf || !menu.event_phrases) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n"); - return; - } - - for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { - dtmf_ss_t loc; - char *dtmfa[16] = { 0 }; - switch_event_t *phrase_params = NULL; - - switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); - append_event_profile(phrase_params, profile, menu); - - populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa); - - captureMenuInitialize(&loc, dtmfa); - - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); - - if (loc.result == RES_TIMEOUT) { - /* TODO Ask for the prompt Again IF retry != 0 */ - } else if (loc.result == RES_INVALID) { - /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ - } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ - const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored); - - /* Reset the try count */ - retry = MAX_ATTEMPT; - - if (action) { - if (!strcasecmp(action, "return")) { /* Return to the previous menu */ - retry = -1; - } else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */ - void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5); - if (fPtr) { - fPtr(session, profile); - } - } - } - } - switch_event_destroy(&phrase_params); - } - - free_profile_menu_event(&menu); -} - -char *mtvm_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *input_mask) { - char *result = NULL; - int retry; - const char *terminate_key = NULL; - switch_channel_t *channel = switch_core_session_get_channel(session); - - if (!menu.event_keys_dtmf || !menu.event_phrases) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys : %s\n", menu.name); - return result; - } - - terminate_key = switch_event_get_header(menu.event_keys_action, "ivrengine:terminate_entry"); - - for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { - dtmf_ss_t loc; - char *dtmfa[16] = { 0 }; - int i; - switch_event_t *phrase_params = NULL; - - switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); - append_event_profile(phrase_params, profile, menu); - - populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa); - - /* Find the last entry and append this one to it */ - for (i=0; dtmfa[i] && i < 16; i++){ - } - dtmfa[i] = (char *) input_mask; - - captureMenuInitialize(&loc, dtmfa); - if (terminate_key) { - loc.terminate_key = terminate_key[0]; - } - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "instructions"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); - - if (loc.result == RES_TIMEOUT) { - /* TODO Ask for the prompt Again IF retry != 0 */ - } else if (loc.result == RES_INVALID) { - /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ - } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ - - /* Reset the try count */ - retry = MAX_ATTEMPT; - - if (!strncasecmp(loc.completeMatch, input_mask, 1)) { - result = switch_core_session_strdup(session, loc.dtmf_stored); - retry = -1; - - } - } - switch_event_destroy(&phrase_params); - } - - return result; -} - -switch_status_t mtvm_menu_record(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *file_name) { - switch_status_t status = SWITCH_STATUS_FALSE; - switch_channel_t *channel = switch_core_session_get_channel(session); - int retry; - - switch_bool_t record_prompt = SWITCH_TRUE; - switch_bool_t listen_recording = SWITCH_FALSE; - switch_bool_t play_instruction = SWITCH_TRUE; - - if (!menu.event_keys_dtmf || !menu.event_phrases) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n"); - return status; - } - - for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { - dtmf_ss_t loc; - - char *dtmfa[16] = { 0 }; - switch_event_t *phrase_params = NULL; - switch_file_handle_t fh = { 0 }; - - /* TODO Make the following configurable */ - fh.thresh = 200; - fh.silence_hits = 4; - //fh.samplerate = 8000; - - - switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); - append_event_profile(phrase_params, profile, menu); - - populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa); - - captureMenuInitialize(&loc, dtmfa); - if (record_prompt) { - if (play_instruction) { - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "instructions"), NULL, phrase_params, NULL, 0); - } - play_instruction = SWITCH_TRUE; - - captureMenuRecord(session, &loc, phrase_params, file_name, &fh, 30 /* TODO Make max recording configurable */); - } else { - if (listen_recording) { - switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Record-File-Path", "%s", file_name); - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "play_recording"), NULL, phrase_params, NULL, 0); - listen_recording = SWITCH_FALSE; - - } - captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); - } - - if (loc.recorded_audio) { - /* Reset the try count */ - retry = MAX_ATTEMPT; - - /* TODO Check if message is too short */ - - record_prompt = SWITCH_FALSE; - - } else if (loc.result == RES_TIMEOUT) { - /* TODO Ask for the prompt Again IF retry != 0 */ - } else if (loc.result == RES_INVALID) { - /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ - } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ - const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored); - - /* Reset the try count */ - retry = MAX_ATTEMPT; - - if (action) { - if (!strcasecmp(action, "listen")) { /* Listen */ - listen_recording = SWITCH_TRUE; - - } else if (!strcasecmp(action, "save")) { - retry = -1; - /* TODO ALLOW SAVE ONLY IF FILE IS RECORDED AND HIGHER THAN MIN SIZE */ - status = SWITCH_STATUS_SUCCESS; - - } else if (!strcasecmp(action, "rerecord")) { - record_prompt = SWITCH_TRUE; - - } else if (!strcasecmp(action, "skip_instruction")) { /* Skip Recording Greeting */ - play_instruction = SWITCH_FALSE; - - } else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */ - void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5); - if (fPtr) { - fPtr(session, profile); - } - } else if (!strcasecmp(action, "return")) { /* Return */ - retry = -1; - } - } - } - switch_event_destroy(&phrase_params); - } - return status; -} - - -void (*mtvm_get_menu_function(const char *menu_name))(switch_core_session_t *session, vmivr_profile_t *profile) { - int i = 0; - - if (menu_name) { - for (i=0; menu_list[i].name ; i++) { - if (!strcasecmp(menu_list[i].name, menu_name)) { - return menu_list[i].pt2Func; - } - } - } - return NULL; -} - - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 - */ diff --git a/src/mod/applications/mod_protovm/menu.h b/src/mod/applications/mod_protovm/menu.h deleted file mode 100644 index 82fd993a8f..0000000000 --- a/src/mod/applications/mod_protovm/menu.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _MENU_H_ -#define _MENU_H_ - -#include "config.h" - -void mtvm_menu_purge(switch_core_session_t *session, vmivr_profile_t *profile); -void mtvm_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *profile); -void mtvm_menu_main(switch_core_session_t *session, vmivr_profile_t *profile); -void mtvm_menu_record_name(switch_core_session_t *session, vmivr_profile_t *profile); -void mtvm_menu_set_password(switch_core_session_t *session, vmivr_profile_t *profile); -void mtvm_menu_select_greeting_slot(switch_core_session_t *session, vmivr_profile_t *profile); -void mtvm_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_profile_t *profile); -void mtvm_menu_preference(switch_core_session_t *session, vmivr_profile_t *profile); -void mtvm_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile); - -switch_status_t mtvm_menu_record(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *file_name); -char *mtvm_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *input_mask); - - -struct vmivr_menu_function { - const char *name; - void (*pt2Func)(switch_core_session_t *session, vmivr_profile_t *profile); - -}; -typedef struct vmivr_menu_function vmivr_menu_function_t; - -extern vmivr_menu_function_t menu_list[]; - -void (*mtvm_get_menu_function(const char *menu_name))(switch_core_session_t *session, vmivr_profile_t *profile); - -#endif /* _MENU_H_ */ - diff --git a/src/mod/applications/mod_protovm/mod_protovm.c b/src/mod/applications/mod_protovm/mod_protovm.c deleted file mode 100644 index 7d826e03c2..0000000000 --- a/src/mod/applications/mod_protovm/mod_protovm.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Marc Olivier Chouinard - * - * - * mod_protovm.c -- MT VoiceMail System - * - */ -#include - -#include "config.h" -#include "menu.h" - -/* Prototypes */ -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_protovm_shutdown); -SWITCH_MODULE_RUNTIME_FUNCTION(mod_protovm_runtime); -SWITCH_MODULE_LOAD_FUNCTION(mod_protovm_load); - -/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime) - * Defines a switch_loadable_module_function_table_t and a static const char[] modname - */ -SWITCH_MODULE_DEFINITION(mod_protovm, mod_protovm_load, mod_protovm_shutdown, NULL); - - -#define MTVM_DESC "protovm" -#define MTVM_USAGE " profile domain [id]" - -SWITCH_STANDARD_APP(protovm_function) -{ - const char *id = NULL; - const char *domain = NULL; - const char *profile_name = NULL; - vmivr_profile_t *profile = NULL; - int argc = 0; - char *argv[6] = { 0 }; - char *mydata = NULL; - - if (!zstr(data)) { - mydata = switch_core_session_strdup(session, data); - argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (argv[1]) - profile_name = argv[1]; - - if (argv[2]) - domain = argv[2]; - - if (!strcasecmp(argv[0], "check")) { - if (argv[3]) - id = argv[3]; - - if (domain && profile_name) { - profile = get_profile(session, profile_name); - - if (profile) { - void (*fPtrAuth)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(profile->menu_check_auth); - void (*fPtrMain)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(profile->menu_check_main); - void (*fPtrTerminate)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(profile->menu_check_terminate); - - profile->domain = domain; - profile->id = id; - - if (fPtrAuth && !profile->authorized) { - fPtrAuth(session, profile); - } - - if (fPtrMain && profile->authorized) { - fPtrMain(session, profile); - } - if (fPtrTerminate) { - fPtrTerminate(session, profile); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile '%s' not found\n", profile_name); - } - } - } - return; -} - -/* Macro expands to: switch_status_t mod_protovm_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */ -SWITCH_MODULE_LOAD_FUNCTION(mod_protovm_load) -{ - switch_application_interface_t *app_interface; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - SWITCH_ADD_APP(app_interface, "protovm", "protovm", MTVM_DESC, protovm_function, MTVM_USAGE, SAF_NONE); - - /* indicate that the module should continue to be loaded */ - return status; -} - -/* - Called when the system shuts down - Macro expands to: switch_status_t mod_protovm_shutdown() */ -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_protovm_shutdown) -{ - - return SWITCH_STATUS_SUCCESS; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 - */ diff --git a/src/mod/applications/mod_protovm/protovm.conf.xml b/src/mod/applications/mod_protovm/protovm.conf.xml deleted file mode 100644 index c57e8f72b6..0000000000 --- a/src/mod/applications/mod_protovm/protovm.conf.xml +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/applications/mod_protovm/sounds.xml b/src/mod/applications/mod_protovm/sounds.xml deleted file mode 100644 index 35dcef169a..0000000000 --- a/src/mod/applications/mod_protovm/sounds.xml +++ /dev/null @@ -1,397 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/applications/mod_protovm/util.c b/src/mod/applications/mod_protovm/util.c deleted file mode 100644 index 476e99bd26..0000000000 --- a/src/mod/applications/mod_protovm/util.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Marc Olivier Chouinard - * - * - * utils.c -- MT VoiceMail / Different utility that might need to go into the core (after cleanup) - * - */ -#include - -#include "util.h" - -switch_status_t mt_merge_media_files(const char** inputs, const char *output) { - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_file_handle_t fh_output = { 0 }; - int channels = 1; - int rate = 8000; /* TODO Make this configurable */ - int j = 0; - - if (switch_core_file_open(&fh_output, output, channels, rate, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open %s\n", output); - goto end; - } - - for (j = 0; inputs[j] != NULL && j < 128 && status == SWITCH_STATUS_SUCCESS; j++) { - switch_file_handle_t fh_input = { 0 }; - char buf[2048]; - switch_size_t len = sizeof(buf) / 2; - - if (switch_core_file_open(&fh_input, inputs[j], channels, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open %s\n", inputs[j]); - status = SWITCH_STATUS_GENERR; - break; - } - - while (switch_core_file_read(&fh_input, buf, &len) == SWITCH_STATUS_SUCCESS) { - if (switch_core_file_write(&fh_output, buf, &len) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write error\n"); - status = SWITCH_STATUS_GENERR; - break; - } - } - - if (fh_input.file_interface) { - switch_core_file_close(&fh_input); - } - } - - if (fh_output.file_interface) { - switch_core_file_close(&fh_output); - } -end: - return status; -} - -switch_event_t *jsonapi2event(switch_core_session_t *session, switch_event_t *apply_event, const char *api, const char *data) { - switch_event_t *phrases_event = NULL; - switch_stream_handle_t stream = { 0 }; - SWITCH_STANDARD_STREAM(stream); - switch_api_execute(api, data, session, &stream); - switch_event_create_json(&phrases_event, (char *) stream.data); - switch_safe_free(stream.data); - - if (apply_event) { - switch_event_header_t *hp; - for (hp = phrases_event->headers; hp; hp = hp->next) { - if (!strncasecmp(hp->name, "VM-", 3)) { - switch_event_add_header(apply_event, SWITCH_STACK_BOTTOM, hp->name, "%s", hp->value); - } - } - switch_event_destroy(&phrases_event); - phrases_event = apply_event; - - } - - return phrases_event; -} - -char *generate_random_file_name(switch_core_session_t *session, const char *mod_name, char *file_extension) { - char rand_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = ""; - switch_uuid_t srand_uuid; - - switch_uuid_get(&srand_uuid); - switch_uuid_format(rand_uuid, &srand_uuid); - - return switch_core_session_sprintf(session, "%s%s%s_%s.%s", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, mod_name, rand_uuid, file_extension); - -} - -switch_status_t mt_api_execute(switch_core_session_t *session, const char *apiname, const char *arguments) { - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch_stream_handle_t stream = { 0 }; - - SWITCH_STANDARD_STREAM(stream); - switch_api_execute(apiname, arguments, session, &stream); - if (!strncasecmp(stream.data, "-ERR", 4)) { - status = SWITCH_STATUS_GENERR; - } - switch_safe_free(stream.data); - return status; -} - -void append_event_profile(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu) { - /* Used for some appending function */ - if (profile->name && profile->id && profile->domain) { - switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Profile", "%s", profile->name); - switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Account-ID", "%s", profile->id); - switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Account-Domain", "%s", profile->domain); - } -} - -void populate_dtmfa_from_event(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu, char **dtmfa) { - int i = 0; - if (menu.event_keys_dtmf) { - switch_event_header_t *hp; - - for (hp = menu.event_keys_dtmf->headers; hp; hp = hp->next) { - if (strlen(hp->name) < 3 && hp->value) { /* TODO This is a hack to discard default FS Events ! */ - const char *varphrasename = switch_event_get_header(menu.event_keys_varname, hp->value); - dtmfa[i++] = hp->name; - - if (varphrasename && !zstr(varphrasename)) { - switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, varphrasename, "%s", hp->name); - } - } - } - } - -} - -void append_event_message(switch_core_session_t *session, vmivr_profile_t *profile, switch_event_t *phrase_params, switch_event_t *msg_list_event, size_t current_msg) { - - char *varname; - char *apicmd; - - varname = switch_mprintf("VM-List-Message-%" SWITCH_SIZE_T_FMT "-UUID", current_msg); - apicmd = switch_mprintf("json %s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(msg_list_event, varname)); - - switch_safe_free(varname); - - jsonapi2event(session, phrase_params, profile->api_msg_get, apicmd); - - /* TODO Set these 2 header correctly */ - switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Message-Type", "%s", "new"); - switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Message-Number", "%"SWITCH_SIZE_T_FMT, current_msg); - - switch_event_add_header_string(phrase_params, SWITCH_STACK_BOTTOM, "VM-Message-Private-Local-Copy", "False"); - - switch_safe_free(apicmd); -} - diff --git a/src/mod/applications/mod_protovm/util.h b/src/mod/applications/mod_protovm/util.h deleted file mode 100644 index 1c46329e18..0000000000 --- a/src/mod/applications/mod_protovm/util.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _UTIL_H_ -#define _UTIL_H_ - -#include "config.h" - -switch_status_t mt_merge_files(const char** inputs, const char *output); - -void append_event_message(switch_core_session_t *session, vmivr_profile_t *profile, switch_event_t *phrase_params, switch_event_t *msg_list_event, size_t current_msg); -void append_event_profile(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu); -char *generate_random_file_name(switch_core_session_t *session, const char *mod_name, char *file_extension); -switch_event_t *jsonapi2event(switch_core_session_t *session, switch_event_t *apply_event, const char *api, const char *data); -switch_status_t mt_merge_media_files(const char** inputs, const char *output); -switch_status_t mt_api_execute(switch_core_session_t *session, const char *apiname, const char *arguments); -void populate_dtmfa_from_event(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu, char **dtmfa); -#endif /* _UTIL_H_ */ - From 93e3462c853917262bc0915e2440b08db49033eb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 16 Aug 2011 15:50:21 -0500 Subject: [PATCH 058/354] reset handler field on filehandles so it gets cleared on reuse reported by bevenky on irc --- src/switch_core_file.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_core_file.c b/src/switch_core_file.c index 58b63bdc4b..28f1172ff8 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -135,10 +135,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, switch_uuid_format(uuid_str, &uuid); fh->spool_path = switch_core_sprintf(fh->memory_pool, "%s%s%s.%s", spool_path, SWITCH_PATH_SEPARATOR, uuid_str, ext); + } else { + fh->spool_path = NULL; } if (rhs) { fh->handler = switch_core_strdup(fh->memory_pool, rhs); + } else { + fh->handler = NULL; } if (channels) { From 9d2b4da88176396870d15b4e720bf6914a7b07aa Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Tue, 16 Aug 2011 16:06:23 -0700 Subject: [PATCH 059/354] Add remote CF set/cancel phrase macros --- conf/lang/en/ivr/sounds.xml | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/conf/lang/en/ivr/sounds.xml b/conf/lang/en/ivr/sounds.xml index 58db0a6c15..e436e294a3 100644 --- a/conf/lang/en/ivr/sounds.xml +++ b/conf/lang/en/ivr/sounds.xml @@ -8,4 +8,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 5cf6dc3115840a8ca089461ca9eba3ea69d3fb83 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 16 Aug 2011 16:11:18 -0500 Subject: [PATCH 060/354] FS-3505 --resolve copied same code from the other place the original intention was to behave as described in the bug report but it seemed like a reasonable enough request --- src/switch_ivr_play_say.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index bc6ba62120..c5200d0e0e 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -377,7 +377,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se int divisor = 0; int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT; int restart_limit_on_dtmf = 0; - const char *prefix; + const char *prefix, *var; prefix = switch_channel_get_variable(channel, "sound_prefix"); @@ -756,6 +756,29 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se switch_core_file_close(fh); + + if ((var = switch_channel_get_variable(channel, "record_post_process_exec_api"))) { + char *cmd = switch_core_session_strdup(session, var); + char *data, *expanded = NULL; + switch_stream_handle_t stream = { 0 }; + + SWITCH_STANDARD_STREAM(stream); + + if ((data = strchr(cmd, ':'))) { + *data++ = '\0'; + expanded = switch_channel_expand_variables(channel, data); + } + + switch_api_execute(cmd, expanded, session, &stream); + + if (expanded && expanded != data) { + free(expanded); + } + + switch_safe_free(stream.data); + + } + if (read_impl.samples_per_second) { switch_channel_set_variable_printf(channel, "record_seconds", "%d", fh->samples_out / read_impl.samples_per_second); switch_channel_set_variable_printf(channel, "record_ms", "%d", fh->samples_out / (read_impl.samples_per_second / 1000)); From 4192195b80ff5a58d3b0c7b3734c5c8ebd0383be Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Tue, 16 Aug 2011 19:39:06 -0400 Subject: [PATCH 061/354] FS-3503 --resolve mod_callcenter: add DNIS in some event, and add a few API like get uuid and get state for agent --- .../mod_callcenter/mod_callcenter.c | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index 2a5a2aa2d1..aa95b1e28c 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -850,7 +850,7 @@ cc_status_t cc_agent_get(const char *key, const char *agent, char *ret_result, s switch_event_t *event; char res[256]; - /* Check to see if agent already exist */ + /* Check to see if agent already exists */ sql = switch_mprintf("SELECT count(*) FROM agents WHERE name = '%q'", agent); cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res)); switch_safe_free(sql); @@ -860,8 +860,8 @@ cc_status_t cc_agent_get(const char *key, const char *agent, char *ret_result, s goto done; } - if (!strcasecmp(key, "status") ) { - /* Check to see if agent already exist */ + if (!strcasecmp(key, "status") || !strcasecmp(key, "state") || !strcasecmp(key, "uuid") ) { + /* Check to see if agent already exists */ sql = switch_mprintf("SELECT %q FROM agents WHERE name = '%q'", key, agent); cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res)); switch_safe_free(sql); @@ -869,9 +869,15 @@ cc_status_t cc_agent_get(const char *key, const char *agent, char *ret_result, s result = CC_STATUS_SUCCESS; if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) { + char tmpname[256]; + if (!strcasecmp(key, "uuid")) { + switch_snprintf(tmpname, sizeof(tmpname), "CC-Agent-UUID"); + } else { + switch_snprintf(tmpname, sizeof(tmpname), "CC-Agent-%c%s", (char) switch_toupper(key[0]), key+1); + } switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", agent); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "agent-status-get"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-Status", res); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Action", "agent-%s-get", key); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, tmpname, res); switch_event_fire(&event); } @@ -1400,6 +1406,10 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa /* Proceed contact the agent to offer the member */ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) { + switch_channel_t *member_channel = switch_core_session_get_channel(member_session); + switch_caller_profile_t *member_profile = switch_channel_get_caller_profile(member_channel); + const char *member_dnis = member_profile->rdnis; + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Queue", h->queue_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "agent-offering"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name); @@ -1409,6 +1419,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Number", h->member_cid_number); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-DNIS", member_dnis); switch_event_fire(&event); } @@ -1548,6 +1559,9 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa t_agent_answered = local_epoch_time_now(NULL); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) { + switch_caller_profile_t *member_profile = switch_channel_get_caller_profile(member_channel); + const char *member_dnis = member_profile->rdnis; + switch_channel_event_set_data(agent_channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Queue", h->queue_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "bridge-agent-start"); @@ -1561,6 +1575,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Number", h->member_cid_number); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-DNIS", member_dnis); switch_event_fire(&event); } /* for xml_cdr needs */ @@ -2676,7 +2691,9 @@ static int list_result_callback(void *pArg, int argc, char **argv, char **column "\tcallcenter_config agent set busy_delay_time [agent_name] [wait second] | \n"\ "\tcallcenter_config agent set no_answer_delay_time [agent_name] [wait second] | \n"\ "\tcallcenter_config agent get status [agent_name] | \n" \ -"\tcallcenter_config agent list | \n" \ +"\tcallcenter_config agent get state [agent_name] | \n" \ +"\tcallcenter_config agent get uuid [agent_name] | \n" \ +"\tcallcenter_config agent list [[agent_name]] | \n" \ "\tcallcenter_config tier add [queue_name] [agent_name] [level] [position] | \n" \ "\tcallcenter_config tier set state [queue_name] [agent_name] [state] | \n" \ "\tcallcenter_config tier set level [queue_name] [agent_name] [level] | \n" \ @@ -2832,7 +2849,14 @@ SWITCH_STANDARD_API(cc_config_api_function) struct list_result cbt; cbt.row_process = 0; cbt.stream = stream; - sql = switch_mprintf("SELECT * FROM agents"); + if ( argc-initial_argc > 1 ) { + stream->write_function(stream, "%s", "-ERR Invalid!\n"); + goto done; + } else if ( argc-initial_argc == 1 ) { + sql = switch_mprintf("SELECT * FROM agents WHERE name='%q'", argv[0 + initial_argc]); + } else { + sql = switch_mprintf("SELECT * FROM agents"); + } cc_execute_sql_callback(NULL /* queue */, NULL /* mutex */, sql, list_result_callback, &cbt /* Call back variables */); switch_safe_free(sql); stream->write_function(stream, "%s", "+OK\n"); From b7e651a5e84f269b6015631032febbaa9a6ff905 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Aug 2011 09:34:56 -0500 Subject: [PATCH 062/354] FS-3509 --resolve --- src/switch_core_sqldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 7495b06302..798e7c288f 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -996,7 +996,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, trans = 1; } - if (len + newlen > sql_len) { + if (len + newlen + 1 > sql_len) { int new_mlen = len + newlen + 10240; if (new_mlen < runtime.max_sql_buffer_len) { From 25032153fbee1034f0d5031145c21602fb62c301 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Aug 2011 11:14:17 -0500 Subject: [PATCH 063/354] FS-3508 --resolve --- src/mod/endpoints/mod_sofia/mod_sofia.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 87817c3c7f..2774e7135a 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -792,6 +792,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")), SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), SOATAG_REUSE_REJECTED(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1), + TAG_IF(is_proxy, SOATAG_RTP_SELECT(1)), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote), SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END()); From 7531fed8d8add901853836256b80eacc6054e7dd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Aug 2011 11:27:20 -0500 Subject: [PATCH 064/354] break event parsing for mod_voicemail into its own internal queue (by Moc) --- .../mod_voicemail/mod_voicemail.c | 125 +++++++++++++++++- 1 file changed, 122 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index b662620682..3d0e48981e 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -45,6 +45,7 @@ SWITCH_MODULE_DEFINITION(mod_voicemail, mod_voicemail_load, mod_voicemail_shutdo #define VM_EVENT_MAINT "vm::maintenance" #define VM_MAX_GREETINGS 9 +#define VM_EVENT_QUEUE_SIZE 50000 static switch_status_t voicemail_inject(const char *data, switch_core_session_t *session); @@ -53,6 +54,9 @@ static struct { switch_hash_t *profile_hash; int debug; int message_query_exact_match; + int32_t threads; + int32_t running; + switch_queue_t *event_queue; switch_mutex_t *mutex; switch_memory_pool_t *pool; } globals; @@ -3655,7 +3659,7 @@ SWITCH_STANDARD_API(prefs_api_function) } -static void message_query_handler(switch_event_t *event) +static void actual_message_query_handler(switch_event_t *event) { char *account = switch_event_get_header(event, "message-account"); int created = 0; @@ -3727,6 +3731,101 @@ static void message_query_handler(switch_event_t *event) } +static int EVENT_THREAD_RUNNING = 0; +static int EVENT_THREAD_STARTED = 0; + +void *SWITCH_THREAD_FUNC vm_event_thread_run(switch_thread_t *thread, void *obj) +{ + void *pop; + int done = 0; + + switch_mutex_lock(globals.mutex); + if (!EVENT_THREAD_RUNNING) { + EVENT_THREAD_RUNNING++; + globals.threads++; + } else { + done = 1; + } + switch_mutex_unlock(globals.mutex); + + if (done) { + return NULL; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Event Thread Started\n"); + + while (globals.running == 1) { + int count = 0; + + if (switch_queue_trypop(globals.event_queue, &pop) == SWITCH_STATUS_SUCCESS) { + switch_event_t *event = (switch_event_t *) pop; + + if (!pop) { + break; + } + actual_message_query_handler(event); + switch_event_destroy(&event); + count++; + } + + if (!count) { + switch_yield(100000); + } + } + + while (switch_queue_trypop(globals.event_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { + switch_event_t *event = (switch_event_t *) pop; + switch_event_destroy(&event); + } + + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Event Thread Ended\n"); + + switch_mutex_lock(globals.mutex); + globals.threads--; + EVENT_THREAD_RUNNING = EVENT_THREAD_STARTED = 0; + switch_mutex_unlock(globals.mutex); + + return NULL; +} + +void vm_event_thread_start(void) +{ + switch_thread_t *thread; + switch_threadattr_t *thd_attr = NULL; + int done = 0; + + switch_mutex_lock(globals.mutex); + if (!EVENT_THREAD_STARTED) { + EVENT_THREAD_STARTED++; + } else { + done = 1; + } + switch_mutex_unlock(globals.mutex); + + if (done) { + return; + } + + switch_threadattr_create(&thd_attr, globals.pool); + switch_threadattr_detach_set(thd_attr, 1); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_priority_increase(thd_attr); + switch_thread_create(&thread, thd_attr, vm_event_thread_run, NULL, globals.pool); +} + +void vm_event_handler(switch_event_t *event) +{ + switch_event_t *cloned_event; + + switch_event_dup(&cloned_event, event); + switch_assert(cloned_event); + switch_queue_push(globals.event_queue, cloned_event); + + if (!EVENT_THREAD_STARTED) { + vm_event_thread_start(); + } +} struct holder { vm_profile_t *profile; @@ -5502,14 +5601,20 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voicemail_load) switch_core_hash_init(&globals.profile_hash, globals.pool); switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool); + switch_mutex_lock(globals.mutex); + globals.running = 1; + switch_mutex_unlock(globals.mutex); + + switch_queue_create(&globals.event_queue, VM_EVENT_QUEUE_SIZE, globals.pool); if ((status = load_config()) != SWITCH_STATUS_SUCCESS) { + globals.running = 0; return status; } /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); - if (switch_event_bind(modname, SWITCH_EVENT_MESSAGE_QUERY, SWITCH_EVENT_SUBCLASS_ANY, message_query_handler, NULL) + if (switch_event_bind(modname, SWITCH_EVENT_MESSAGE_QUERY, SWITCH_EVENT_SUBCLASS_ANY, vm_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); return SWITCH_STATUS_GENERR; @@ -5554,9 +5659,23 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_voicemail_shutdown) void *val = NULL; const void *key; switch_ssize_t keylen; + int sanity = 0; + + switch_mutex_lock(globals.mutex); + if (globals.running == 1) { + globals.running = 0; + } + switch_mutex_unlock(globals.mutex); switch_event_free_subclass(VM_EVENT_MAINT); - switch_event_unbind_callback(message_query_handler); + switch_event_unbind_callback(vm_event_handler); + + while (globals.threads) { + switch_cond_next(); + if (++sanity >= 60000) { + break; + } + } switch_mutex_lock(globals.mutex); while ((hi = switch_hash_first(NULL, globals.profile_hash))) { From f2b66d3d8520b43a94b5cf5ffc278cf5c14c1281 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Aug 2011 17:25:56 -0500 Subject: [PATCH 065/354] update log --- src/switch_channel.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index 4f272db7e2..8fb1d27c59 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -362,7 +362,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *chan { switch_status_t status; void *pop; - switch_dtmf_t new_dtmf; + switch_dtmf_t new_dtmf = { 0 }; switch_assert(dtmf); @@ -376,14 +376,17 @@ SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *chan if (is_dtmf(new_dtmf.digit)) { switch_dtmf_t *dt; int x = 0; + char str[2] = ""; + str[0] = new_dtmf.digit; + if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n", - switch_channel_get_name(channel), new_dtmf.digit, new_dtmf.duration); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "%s EXCESSIVE DTMF DIGIT [%s] LEN [%d]\n", + switch_channel_get_name(channel), str, new_dtmf.duration); new_dtmf.duration = switch_core_max_dtmf_duration(0); } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n", - switch_channel_get_name(channel), new_dtmf.digit, new_dtmf.duration); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "%s SHORT DTMF DIGIT [%s] LEN [%d]\n", + switch_channel_get_name(channel), str, new_dtmf.duration); new_dtmf.duration = switch_core_min_dtmf_duration(0); } else if (!new_dtmf.duration) { new_dtmf.duration = switch_core_default_dtmf_duration(0); From 30d7ad878c10975ced8f9eb7024599cd6bc017d6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Aug 2011 18:10:44 -0500 Subject: [PATCH 066/354] only close inner file handle if it was initilized --- src/mod/applications/mod_dptools/mod_dptools.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 39e6380399..8c260ddf7f 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -3669,7 +3669,9 @@ static switch_status_t file_string_file_close(switch_file_handle_t *handle) { file_string_context_t *context = handle->private_info; - switch_core_file_close(&context->fh); + if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) { + switch_core_file_close(&context->fh); + } return SWITCH_STATUS_SUCCESS; } From bab3289ff3d05260521ac36bd956cded693fe80f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Aug 2011 18:42:48 -0500 Subject: [PATCH 067/354] do not queue messages to the session when they are in bypass mode --- src/mod/endpoints/mod_sofia/sofia.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index f7fbacff1a..6891562e11 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1257,8 +1257,9 @@ void sofia_event_callback(nua_event_t event, if (!zstr(sofia_private->uuid)) { if ((session = switch_core_session_locate(sofia_private->uuid))) { - - if (switch_core_session_running(session)) { + switch_channel_t *channel = switch_core_session_get_channel(session); + + if (switch_core_session_running(session) && !switch_channel_test_flag(channel, CF_PROXY_MODE)) { switch_core_session_queue_signal_data(session, de); } else { switch_core_session_message_t msg = { 0 }; From fab82936512b6aa8e578c633d04200de292146dd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Aug 2011 19:21:36 -0500 Subject: [PATCH 068/354] stop at first profile if can't find one --- src/mod/applications/mod_voicemail/mod_voicemail.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 3d0e48981e..6fc16465d7 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -3653,7 +3653,6 @@ SWITCH_STANDARD_API(prefs_api_function) switch_event_add_header_string(new_event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", account); \ switch_event_add_header(new_event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", \ +total_new_messages, total_saved_messages, total_new_urgent_messages, total_saved_urgent_messages); \ - created++; \ } \ } \ } @@ -3662,7 +3661,6 @@ SWITCH_STANDARD_API(prefs_api_function) static void actual_message_query_handler(switch_event_t *event) { char *account = switch_event_get_header(event, "message-account"); - int created = 0; switch_event_t *new_event = NULL; char *dup = NULL; int total_new_messages = 0; @@ -3701,6 +3699,10 @@ static void actual_message_query_handler(switch_event_t *event) switch_hash_this(hi, NULL, NULL, &val); profile = (vm_profile_t *) val; parse_profile(); + + if (new_event) { + break; + } } } } @@ -3709,7 +3711,7 @@ static void actual_message_query_handler(switch_event_t *event) } - if (!created) { + if (!new_event) { if (switch_event_create(&new_event, SWITCH_EVENT_MESSAGE_WAITING) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(new_event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", "no"); switch_event_add_header_string(new_event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", account); From c269a58ac54a381ae68c1d6e6e7616d356584f88 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Aug 2011 19:30:15 -0500 Subject: [PATCH 069/354] FS-3045 --resolve --- src/switch_channel.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index 8fb1d27c59..308d29f858 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -1017,8 +1017,10 @@ SWITCH_DECLARE(void) switch_channel_process_export(switch_channel_t *channel, sw const char *vval; if ((vval = switch_channel_get_variable(channel, argv[x]))) { char *vvar = argv[x]; - if (!strncasecmp(vvar, "nolocal:", 8)) { + if (!strncasecmp(vvar, "nolocal:", 8)) { /* remove this later ? */ vvar += 8; + } else if (!strncasecmp(vvar, "_nolocal_", 9)) { + vvar += 9; } if (var_event) { switch_event_del_header(var_event, vvar); @@ -1058,9 +1060,12 @@ SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_var_check(switch_ var = switch_core_session_strdup(channel->session, varname); if (var) { - if (!strncasecmp(var, "nolocal:", 8)) { + if (!strncasecmp(var, "nolocal:", 8)) { /* remove this later ? */ var_name = var + 8; local = 0; + } else if (!strncasecmp(var, "_nolocal_", 9)) { + var_name = var + 9; + local = 0; } else { var_name = var; } From cd316330c6a987ee37d95baa3adaeb302e561ba6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Aug 2011 19:34:22 -0500 Subject: [PATCH 070/354] FS-3511 FS-2875 --resolve we will go with this as-is and just make it a default --- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 + src/mod/endpoints/mod_sofia/sofia.c | 13 ++ src/mod/endpoints/mod_sofia/sofia_reg.c | 222 +++++++++++++++++------- 3 files changed, 178 insertions(+), 59 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 190212a22b..5566854208 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -354,6 +354,7 @@ struct mod_sofia_globals { int debug_presence; int debug_sla; int auto_restart; + int reg_deny_binding_fetch_and_no_lookup; /* backwards compatibility */ int auto_nat; int tracelevel; char *capture_server; @@ -1116,6 +1117,7 @@ switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *sess char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type); void sofia_glue_tech_simplify(private_object_t *tech_pvt); switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host); +switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host); switch_bool_t sofia_glue_profile_exists(const char *key); void sofia_glue_global_siptrace(switch_bool_t on); void sofia_glue_global_capture(switch_bool_t on); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 6891562e11..2e2aacf9d0 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2709,6 +2709,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) mod_sofia_globals.debug_sla = atoi(val); } else if (!strcasecmp(var, "auto-restart")) { mod_sofia_globals.auto_restart = switch_true(val); + } else if (!strcasecmp(var, "reg-deny-binding-fetch-and-no-lookup")) { /* backwards compatibility */ + mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */ + if (switch_true(val)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Enabling reg-deny-binding-fetch-and-no-lookup - this functionality is " + "deprecated and will be removed - let FS devs know if you think it should stay\n"); + } } else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) { if( (!strcasecmp(val, "to_host")) || (!strcasecmp(val, "1")) ) { /* old behaviour */ @@ -3386,6 +3392,7 @@ switch_status_t config_sofia(int reload, char *profile_name) } mod_sofia_globals.auto_restart = SWITCH_TRUE; + mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = SWITCH_FALSE; /* handle backwards compatilibity - by default use new behavior */ mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE; if ((settings = switch_xml_child(cfg, "global_settings"))) { @@ -3402,6 +3409,12 @@ switch_status_t config_sofia(int reload, char *profile_name) mod_sofia_globals.debug_sla = atoi(val); } else if (!strcasecmp(var, "auto-restart")) { mod_sofia_globals.auto_restart = switch_true(val); + } else if (!strcasecmp(var, "reg-deny-binding-fetch-and-no-lookup")) { /* backwards compatibility */ + mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */ + if (switch_true(val)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Enabling reg-deny-binding-fetch-and-no-lookup - this functionality is " + "deprecated and will be removed - let FS devs know if you think it should stay\n"); + } } else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) { if( (!strcasecmp(val, "to_host")) || (!strcasecmp(val, "1")) ) { /* old behaviour */ diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 1d014aff80..e281903dd6 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -30,9 +30,10 @@ * Marcel Barbulescu * David Knell <> * Eliot Gable + * Leon de Rooij * * - * sofia_ref.c -- SOFIA SIP Endpoint (registration code) + * sofia_reg.c -- SOFIA SIP Endpoint (registration code) * */ #include "mod_sofia.h" @@ -466,6 +467,39 @@ int sofia_reg_find_callback(void *pArg, int argc, char **argv, char **columnName return cbt->matches == 1 ? 0 : 1; } + +int sofia_reg_find_reg_with_positive_expires_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + struct callback_t *cbt = (struct callback_t *) pArg; + sofia_destination_t *dst = NULL; + long int expires; + char *contact = NULL; + + expires = atol(argv[1]) - 60 - (long) switch_epoch_time_now(NULL); + + if (expires > 0) { + dst = sofia_glue_get_destination(argv[0]); + contact = switch_mprintf("<%s>;expires=%ld", dst->contact, expires); + + if (!cbt->len) { + switch_console_push_match(&cbt->list, contact); + switch_safe_free(contact); + sofia_glue_free_destination(dst); + cbt->matches++; + return 0; + } + + switch_copy_string(cbt->val, contact, cbt->len); + switch_safe_free(contact); + sofia_glue_free_destination(dst); + cbt->matches++; + return cbt->matches == 1 ? 0 : 1; + } + + return 0; +} + + int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames) { sofia_profile_t *profile = (sofia_profile_t *) pArg; @@ -875,6 +909,29 @@ switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *p } +switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host) +{ + struct callback_t cbt = { 0 }; + char sql[512] = ""; + + if (!user) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Called with null user!\n"); + return NULL; + } + + if (host) { + switch_snprintf(sql, sizeof(sql), "select contact,expires from sip_registrations where sip_user='%s' and (sip_host='%s' or presence_hosts like '%%%s%%')", + user, host, host); + } else { + switch_snprintf(sql, sizeof(sql), "select contact,expires from sip_registrations where sip_user='%s'", user); + } + + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_find_reg_with_positive_expires_callback, &cbt); + + return cbt.list; +} + + void sofia_reg_auth_challenge(sofia_profile_t *profile, nua_handle_t *nh, sofia_dispatch_event_t *de, sofia_regtype_t regtype, const char *realm, int stale) { @@ -983,8 +1040,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand } } - /* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */ - switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL); + /* all callers must confirm that sip and sip->sip_request are not NULL */ + switch_assert(sip != NULL && sip->sip_request != NULL); sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port); @@ -1032,7 +1089,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand sub_host = to_host; } - if (contact->m_url) { + if (contact && contact->m_url) { const char *port = contact->m_url->url_port; char new_port[25] = ""; const char *contact_host = contact->m_url->url_host; @@ -1130,7 +1187,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand if (expires) { exptime = expires->ex_delta; - } else if (contact->m_expires) { + } else if (contact && contact->m_expires) { exptime = atol(contact->m_expires); } @@ -1163,11 +1220,13 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str); + if (contact) + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", reg_desc); - switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime); + if (contact) + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-user", from_user); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-host", from_host); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-ip", network_ip); @@ -1178,7 +1237,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_event_fire(&s_event); } - if (exptime && v_event && *v_event) { + if (contact && exptime && v_event && *v_event) { char *exp_var; char *allow_multireg = NULL; int auto_connectile = 0; @@ -1310,11 +1369,13 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str); + if (contact) + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", reg_desc); - switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime); + if (contact) + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-user", from_user); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-host", from_host); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-ip", network_ip); @@ -1343,6 +1404,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_goto_int(r, 1, end); } + + if (!contact) + goto respond_200_ok; + reg: @@ -1589,69 +1654,107 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand } } + respond_200_ok: if (regtype == REG_REGISTER) { char exp_param[128] = ""; char date[80] = ""; switch_event_t *s_mwi_event = NULL; + switch_console_callback_match_t *contact_list = NULL; + tagi_t *contact_tags; + switch_console_callback_match_node_t *m; + int i; + s_event = NULL; - if (exptime) { - switch_snprintf(exp_param, sizeof(exp_param), "expires=%ld", exptime); - sip_contact_add_param(nua_handle_home(nh), sip->sip_contact, exp_param); + if (contact) { + if (exptime) { + switch_snprintf(exp_param, sizeof(exp_param), "expires=%ld", exptime); + sip_contact_add_param(nua_handle_home(nh), sip->sip_contact, exp_param); - if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) || - (reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) { - if (switch_event_create(&s_mwi_event, SWITCH_EVENT_MESSAGE_QUERY) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(s_mwi_event, SWITCH_STACK_BOTTOM, "Message-Account", "sip:%s@%s", mwi_user, mwi_host); - switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Sofia-Profile", profile->name); - switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Call-ID", call_id); - } - } - - if (sofia_test_pflag(profile, PFLAG_PRESENCE_ON_REGISTER) || - (reg_count == 1 && sofia_test_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER)) - || send_pres == 1 || (reg_count == 1 && send_pres == 2)) { - - if (sofia_test_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)) { - if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name); - switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host); - switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, sub_host); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence"); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog"); - switch_event_fire(&s_event); + if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) || + (reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) { + if (switch_event_create(&s_mwi_event, SWITCH_EVENT_MESSAGE_QUERY) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(s_mwi_event, SWITCH_STACK_BOTTOM, "Message-Account", "sip:%s@%s", mwi_user, mwi_host); + switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Sofia-Profile", profile->name); + switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Call-ID", call_id); } - } else { - if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name); - switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "unknown"); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Registered"); - switch_event_fire(&s_event); - } } - } - } else { - switch_core_del_registration(to_user, reg_host, call_id); - if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid); - switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime); + if (sofia_test_pflag(profile, PFLAG_PRESENCE_ON_REGISTER) || + (reg_count == 1 && sofia_test_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER)) + || send_pres == 1 || (reg_count == 1 && send_pres == 2)) { + + if (sofia_test_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)) { + if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, sub_host); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence"); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog"); + switch_event_fire(&s_event); + } + } else { + if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "unknown"); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Registered"); + switch_event_fire(&s_event); + } + } + } + } else { + switch_core_del_registration(to_user, reg_host, call_id); + + if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime); + } } } switch_rfc822_date(date, switch_micro_time_now()); - nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact), - TAG_IF(path_val, SIPTAG_PATH_STR(path_val)), NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END()); + + /* generate and respond a 200 OK */ + + if (mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup) { + /* handle backwards compatibility - contacts will not be looked up but only copied from the request into the response + remove this condition later if nobody complains about the extra select of the below new behavior + also remove the parts in mod_sofia.h, sofia.c and sofia_reg.c that refer to reg_deny_binding_fetch_and_no_lookup */ + nua_respond(nh, SIP_200_OK, TAG_IF(contact, SIPTAG_CONTACT(sip->sip_contact)), TAG_IF(path_val, SIPTAG_PATH_STR(path_val)), + NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END()); + + } else if ((contact_list = sofia_reg_find_reg_url_with_positive_expires_multi(profile, from_user, reg_host))) { + /* all + 1 tag_i elements initialized as NULL - last one implies TAG_END() */ + switch_zmalloc(contact_tags, sizeof(*contact_tags) * (contact_list->count + 1)); + i = 0; + for (m = contact_list->head; m; m = m->next) { + contact_tags[i].t_tag = siptag_contact_str; + contact_tags[i].t_value = (tag_value_t) m->val; + ++i; + } + + nua_respond(nh, SIP_200_OK, TAG_IF(path_val, SIPTAG_PATH_STR(path_val)), + NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_NEXT(contact_tags)); + + switch_safe_free(contact_tags); + switch_console_free_matches(&contact_list); + + } else { + /* respond without any contacts */ + nua_respond(nh, SIP_200_OK, TAG_IF(path_val, SIPTAG_PATH_STR(path_val)), + NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END()); + } + if (s_event) { switch_event_fire(&s_event); @@ -1661,7 +1764,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_event_fire(&s_mwi_event); } - if (*contact_str && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE_SYLANTRO)) { + if (contact && *contact_str && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE_SYLANTRO)) { sofia_sla_handle_register(nua, profile, sip, de, exptime, contact_str); } @@ -1707,7 +1810,8 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port); - if (!(sip->sip_contact && sip->sip_contact->m_url)) { + /* backwards compatibility */ + if (mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup && !(sip->sip_contact && sip->sip_contact->m_url)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO CONTACT! ip: %s, port: %i\n", network_ip, network_port); nua_respond(nh, 400, "Missing Contact Header", TAG_END()); goto end; From 850f2e3cffda1f6df53e109599749f82da06c357 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 18 Aug 2011 09:11:45 -0500 Subject: [PATCH 071/354] FS-3510 --resolve make all instances of execute_on_X uniform with api_on_X and support both prefix vars as before and usage of arrays to push several exexute_on or api_on records into one variable --- src/include/switch_channel.h | 2 +- src/include/switch_types.h | 11 +- src/mod/endpoints/mod_sofia/sofia_glue.c | 17 +-- src/switch_channel.c | 142 ++++++++++++++++------- src/switch_ivr_async.c | 2 + src/switch_ivr_originate.c | 3 +- 6 files changed, 114 insertions(+), 63 deletions(-) diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index 176b841147..8fa0439b47 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -625,7 +625,7 @@ SWITCH_DECLARE(void) switch_channel_mark_hold(switch_channel_t *channel, switch_ /** @} */ SWITCH_DECLARE(switch_status_t) switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix); - +SWITCH_DECLARE(switch_status_t) switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix); SWITCH_END_EXTERN_C #endif diff --git a/src/include/switch_types.h b/src/include/switch_types.h index f6183e6018..dd36b7f680 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -131,12 +131,21 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_COPY_XML_CDR_VARIABLE "copy_xml_cdr" #define SWITCH_CURRENT_APPLICATION_VARIABLE "current_application" #define SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE "proto_specific_hangup_cause" + #define SWITCH_CHANNEL_EXECUTE_ON_ANSWER_VARIABLE "execute_on_answer" #define SWITCH_CHANNEL_EXECUTE_ON_PRE_ANSWER_VARIABLE "execute_on_pre_answer" #define SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE "execute_on_media" -#define SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE "api_on_answer" #define SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE "execute_on_ring" #define SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE "execute_on_tone_detect" +#define SWITCH_CHANNEL_EXECUTE_ON_ORIGINATE_VARIABLE "execute_on_originate" + +#define SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE "api_on_answer" +#define SWITCH_CHANNEL_API_ON_PRE_ANSWER_VARIABLE "api_on_pre_answer" +#define SWITCH_CHANNEL_API_ON_MEDIA_VARIABLE "api_on_media" +#define SWITCH_CHANNEL_API_ON_RING_VARIABLE "api_on_ring" +#define SWITCH_CHANNEL_API_ON_TONE_DETECT_VARIABLE "api_on_tone_detect" +#define SWITCH_CHANNEL_API_ON_ORIGINATE_VARIABLE "api_on_originate" + #define SWITCH_CALL_TIMEOUT_VARIABLE "call_timeout" #define SWITCH_HOLDING_UUID_VARIABLE "holding_uuid" #define SWITCH_SOFT_HOLDING_UUID_VARIABLE "soft_holding_uuid" diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 006f002334..b7b139e52d 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3989,7 +3989,6 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_ { switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options"); sdp_attribute_t *attr; - const char *var; if (!t38_options) { t38_options = switch_core_session_alloc(tech_pvt->session, sizeof(switch_t38_options_t)); @@ -4069,20 +4068,8 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_ switch_channel_set_private(tech_pvt->channel, "t38_options", t38_options); switch_channel_set_app_flag_key("T38", tech_pvt->channel, CF_APP_T38); - if ((var = switch_channel_get_variable(tech_pvt->channel, "sip_execute_on_image"))) { - char *app, *arg = NULL; - app = switch_core_session_strdup(tech_pvt->session, var); - - if (strstr(app, "::")) { - switch_core_session_execute_application_async(tech_pvt->session, app, arg); - } else { - if ((arg = strchr(app, ' '))) { - *arg++ = '\0'; - } - - switch_core_session_execute_application(tech_pvt->session, app, arg); - } - } + switch_channel_execute_on(tech_pvt->channel, "sip_execute_on_image"); + switch_channel_api_on(tech_pvt->channel, "sip_api_on_image"); return t38_options; } diff --git a/src/switch_channel.c b/src/switch_channel.c index 308d29f858..0a6071105f 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2830,6 +2830,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_ring_ready_value(swi } switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE); + switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_RING_VARIABLE); return SWITCH_STATUS_SUCCESS; } @@ -2877,7 +2878,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_ switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_PRE_ANSWER_VARIABLE); switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE); - + switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_PRE_ANSWER_VARIABLE); + switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_MEDIA_VARIABLE); if ((var = switch_channel_get_variable(channel, SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE))) { switch_channel_set_flag(channel, CF_PASSTHRU_PTIME_MISMATCH); @@ -2969,43 +2971,108 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_ring_ready_value(switch_c return status; } +static void do_api_on(switch_channel_t *channel, const char *variable) +{ + char *app; + char *arg = NULL; + switch_stream_handle_t stream = { 0 }; + + app = switch_core_session_strdup(channel->session, variable); + + if ((arg = strchr(app, ' '))) { + *arg++ = '\0'; + } + + SWITCH_STANDARD_STREAM(stream); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s process %s: %s(%s)\n%s\n", + channel->name, variable, app, switch_str_nil(arg), (char *) stream.data); + switch_api_execute(app, arg, NULL, &stream); + free(stream.data); +} + + +SWITCH_DECLARE(switch_status_t) switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix) +{ + switch_event_header_t *hp; + switch_event_t *event; + int x = 0; + + + switch_channel_get_variables(channel, &event); + + for (hp = event->headers; hp; hp = hp->next) { + char *var = hp->name; + char *val = hp->value; + + if (!strncasecmp(var, variable_prefix, strlen(variable_prefix))) { + if (hp->idx) { + int i; + for (i = 0; i < hp->idx; i++) { + x++; + do_api_on(channel, hp->array[i]); + } + } else { + x++; + do_api_on(channel, val); + } + } + } + + switch_event_destroy(&event); + + return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; +} + +static void do_execute_on(switch_channel_t *channel, const char *variable) +{ + char *arg = NULL; + char *p; + int bg = 0; + char *app; + + app = switch_core_session_strdup(channel->session, variable); + + for(p = app; p && *p; p++) { + if (*p == ' ') { + *p++ = '\0'; + arg = p; + break; + } else if (*p == ':' && (*(p+1) == ':')) { + bg++; + break; + } + } + + + if (bg) { + switch_core_session_execute_application_async(channel->session, app, arg); + } else { + switch_core_session_execute_application(channel->session, app, arg); + } +} + SWITCH_DECLARE(switch_status_t) switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix) { - switch_event_header_t *hi; + switch_event_header_t *hp; switch_event_t *event; int x = 0; switch_channel_get_variables(channel, &event); - for (hi = event->headers; hi; hi = hi->next) { - char *var = hi->name; - char *val = hi->value; - char *app; - + for (hp = event->headers; hp; hp = hp->next) { + char *var = hp->name; + char *val = hp->value; + if (!strncasecmp(var, variable_prefix, strlen(variable_prefix))) { - char *arg = NULL; - char *p; - int bg = 0; - x++; - - app = switch_core_session_strdup(channel->session, val); - - for(p = app; p && *p; p++) { - if (*p == ' ') { - *p++ = '\0'; - arg = p; - break; - } else if (*p == ':' && (*(p+1) == ':')) { - bg++; - break; + if (hp->idx) { + int i; + for (i = 0; i < hp->idx; i++) { + x++; + do_execute_on(channel, hp->array[i]); } - } - - - if (bg) { - switch_core_session_execute_application_async(channel->session, app, arg); } else { - switch_core_session_execute_application(channel->session, app, arg); + x++; + do_execute_on(channel, val); } } } @@ -3021,7 +3088,6 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan const char *uuid; switch_core_session_t *other_session; const char *var; - char *app; switch_assert(channel != NULL); @@ -3087,24 +3153,10 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan if (!switch_channel_test_flag(channel, CF_EARLY_MEDIA)) { switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE); + switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_MEDIA_VARIABLE); } - if ((var = switch_channel_get_variable(channel, SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE)) && !zstr(var)) { - switch_stream_handle_t stream = { 0 }; - char *arg = NULL; - - app = switch_core_session_strdup(channel->session, var); - if ((arg = strchr(app, ' '))) { - *arg++ = '\0'; - } - - SWITCH_STANDARD_STREAM(stream); - switch_api_execute(app, arg, NULL, &stream); - - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s api on answer: %s(%s)\n%s\n", - channel->name, app, switch_str_nil(arg), (char *) stream.data); - free(stream.data); - } + switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE); switch_channel_presence(channel, "unknown", "answered", NULL); diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index a47cfbd0c0..b55413f007 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -2458,6 +2458,8 @@ static switch_status_t tone_on_dtmf(switch_core_session_t *session, const switch cont->list[i].callback(cont->session, cont->list[i].app, cont->list[i].data); } else { switch_channel_execute_on(switch_core_session_get_channel(cont->session), SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE); + switch_channel_api_on(switch_core_session_get_channel(cont->session), SWITCH_CHANNEL_API_ON_TONE_DETECT_VARIABLE); + if (cont->list[i].app) { switch_core_session_execute_application_async(cont->session, cont->list[i].app, cont->list[i].data); } diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 262d6d7a91..9ab1c1b1da 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -2561,7 +2561,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_channel_set_variable(originate_status[i].peer_channel, "originating_leg_uuid", switch_core_session_get_uuid(session)); } - switch_channel_execute_on(originate_status[i].peer_channel, "execute_on_originate"); + switch_channel_execute_on(originate_status[i].peer_channel, SWITCH_CHANNEL_EXECUTE_ON_ORIGINATE_VARIABLE); + switch_channel_api_on(originate_status[i].peer_channel, SWITCH_CHANNEL_API_ON_ORIGINATE_VARIABLE); } if (table) { From 94961e4ff6d39c0181ec41efdad0d09eea987be9 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Thu, 18 Aug 2011 13:23:04 -0400 Subject: [PATCH 072/354] can never be == 3 if it's == 2 :-) ... thanks Deeewayne --- src/mod/applications/mod_easyroute/mod_easyroute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_easyroute/mod_easyroute.c b/src/mod/applications/mod_easyroute/mod_easyroute.c index 75b4712f2d..ad1d75c303 100644 --- a/src/mod/applications/mod_easyroute/mod_easyroute.c +++ b/src/mod/applications/mod_easyroute/mod_easyroute.c @@ -303,7 +303,7 @@ SWITCH_STANDARD_APP(easyroute_app_function) if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { destnum = argv[0]; - if (argc == 2) { + if (argc >= 2) { if (!strcasecmp(argv[1], "noat")) { noat = 1; } else if (!strcasecmp(argv[1], "separator")) { From f846a42e60347b084f23d0ec13f9bdfb50c49219 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Thu, 18 Aug 2011 14:47:06 -0400 Subject: [PATCH 073/354] the rest of that last patch --- src/mod/applications/mod_easyroute/mod_easyroute.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_easyroute/mod_easyroute.c b/src/mod/applications/mod_easyroute/mod_easyroute.c index ad1d75c303..cc6d6121f8 100644 --- a/src/mod/applications/mod_easyroute/mod_easyroute.c +++ b/src/mod/applications/mod_easyroute/mod_easyroute.c @@ -308,7 +308,7 @@ SWITCH_STANDARD_APP(easyroute_app_function) noat = 1; } else if (!strcasecmp(argv[1], "separator")) { if (argc == 3) { - switch_set_string(separator, argv[2]); + separator = argv[2]; } } } @@ -358,13 +358,13 @@ SWITCH_STANDARD_API(easyroute_function) status = SWITCH_STATUS_SUCCESS; goto done; } - if (argc == 2) { + if (argc >= 2) { if (!strcasecmp(argv[1], "noat")) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Entering noat.\n"); noat = 1; } else if (!strcasecmp(argv[1], "separator")) { if (argc == 3) { - switch_set_string(separator, argv[2]); + separator = argv[2]; } } } From dadd3fe5471fe96c3dea1ce41c725ab6974619c7 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Thu, 18 Aug 2011 14:55:33 -0400 Subject: [PATCH 074/354] update schema --- src/mod/applications/mod_lcr/sql/mysql-5.0.sql | 6 +++--- src/mod/applications/mod_lcr/sql/postgres-8.3.sql | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mod/applications/mod_lcr/sql/mysql-5.0.sql b/src/mod/applications/mod_lcr/sql/mysql-5.0.sql index 2bdcf632f8..a8756b3c21 100644 --- a/src/mod/applications/mod_lcr/sql/mysql-5.0.sql +++ b/src/mod/applications/mod_lcr/sql/mysql-5.0.sql @@ -23,9 +23,9 @@ DROP TABLE IF EXISTS `lcr`; CREATE TABLE `lcr` ( `id` int(11) NOT NULL auto_increment, `digits` varchar(15) default NULL, - `rate` float(11,5) unsigned NOT NULL, - `intrastate_rate` float(11, 5) unsigned NOT NULL, - `intralata_rate` float(11, 5) unsigned NOT NULL, + `rate` float(11,5) unsigned, + `intrastate_rate` float(11, 5) unsigned, + `intralata_rate` float(11, 5) unsigned, `carrier_id` int(11) NOT NULL, `lead_strip` int(11) NOT NULL, `trail_strip` int(11) NOT NULL, diff --git a/src/mod/applications/mod_lcr/sql/postgres-8.3.sql b/src/mod/applications/mod_lcr/sql/postgres-8.3.sql index b9e91bf346..693b36fb29 100644 --- a/src/mod/applications/mod_lcr/sql/postgres-8.3.sql +++ b/src/mod/applications/mod_lcr/sql/postgres-8.3.sql @@ -42,9 +42,9 @@ CREATE TABLE lcr ( id serial NOT NULL, digits NUMERIC(20, 0), - rate numeric(11,5) NOT NULL, - intrastate_rate numeric(11,5) NOT NULL, - intralata_rate numeric(11,5) NOT NULL, + rate numeric(11,5), + intrastate_rate numeric(11,5), + intralata_rate numeric(11,5), carrier_id integer NOT NULL REFERENCES carriers(id), lead_strip integer NOT NULL DEFAULT 0, trail_strip integer NOT NULL DEFAULT 0, From 92d2999273019785532f4519c6fdda6b73ae72f1 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Thu, 18 Aug 2011 16:00:19 -0400 Subject: [PATCH 075/354] use your own hostname --- clients/flex/freeswitch.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/flex/freeswitch.html b/clients/flex/freeswitch.html index 0c2aeebefc..481b2fb5f4 100644 --- a/clients/flex/freeswitch.html +++ b/clients/flex/freeswitch.html @@ -14,7 +14,7 @@