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; }; 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); diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index d896527d7d..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); } @@ -4390,7 +4391,6 @@ SWITCH_STANDARD_API(voicemail_list_api_function) vm_execute_sql_callback(profile, profile->mutex, sql, api_list_callback, stream); switch_safe_free(sql); - update_mwi(profile, id, domain, "inbox"); if (!strcasecmp(format, "xml")) { stream->write_function(stream, "\n"); 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.c b/src/mod/endpoints/mod_sofia/sofia.c index 316c23d369..318ca29b7b 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); @@ -952,9 +952,8 @@ static void our_sofia_event_callback(nua_event_t event, } } case nua_r_ack: - if (channel) { + if (channel) switch_channel_set_flag(channel, CF_MEDIA_ACK); - } break; case nua_r_shutdown: if (status >= 200) { @@ -4969,12 +4968,6 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status sofia_clear_flag(tech_pvt, TFLAG_RECOVERING); } - if ((status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - const char *val; - if ((val = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(val)) { - nua_notify(nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR("talk"), TAG_END()); - } - } } end: @@ -5165,6 +5158,15 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, status = 183; } + if (channel && (status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + const char *val; + if ((val = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(val)) { + nua_notify(nh, NUTAG_NEWSUB(1), NUTAG_WITH_THIS_MSG(de->data->e_msg), + NUTAG_SUBSTATE(nua_substate_terminated), SIPTAG_EVENT_STR("talk"), TAG_END()); + } + } + + state_process: @@ -5840,6 +5842,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_snprintf(st, sizeof(st), "%d", cause); switch_channel_set_variable(channel, "sip_term_cause", st); switch_channel_hangup(channel, cause); + ss_state = nua_callstate_terminated; } 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) diff --git a/src/switch_channel.c b/src/switch_channel.c index bd2f84b779..7dd43672a9 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; }; @@ -1840,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)) { @@ -2106,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); } @@ -2156,23 +2172,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 +2351,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 +2412,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_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_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])) { diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 9dbd4aecab..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; @@ -997,6 +999,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 +1314,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); } diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 6df4f40782..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; @@ -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)); }