| File: | src/switch_core_state_machine.c |
| Location: | line 758, column 77 |
| Description: | Value stored to 'midstate' during its initialization is never read |
| 1 | /* |
| 2 | * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application |
| 3 | * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org> |
| 4 | * |
| 5 | * Version: MPL 1.1 |
| 6 | * |
| 7 | * The contents of this file are subject to the Mozilla Public License Version |
| 8 | * 1.1 (the "License"); you may not use this file except in compliance with |
| 9 | * the License. You may obtain a copy of the License at |
| 10 | * http://www.mozilla.org/MPL/ |
| 11 | * |
| 12 | * Software distributed under the License is distributed on an "AS IS" basis, |
| 13 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| 14 | * for the specific language governing rights and limitations under the |
| 15 | * License. |
| 16 | * |
| 17 | * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application |
| 18 | * |
| 19 | * The Initial Developer of the Original Code is |
| 20 | * Anthony Minessale II <anthm@freeswitch.org> |
| 21 | * Portions created by the Initial Developer are Copyright (C) |
| 22 | * the Initial Developer. All Rights Reserved. |
| 23 | * |
| 24 | * Contributor(s): |
| 25 | * |
| 26 | * Anthony Minessale II <anthm@freeswitch.org> |
| 27 | * Michael Jerris <mike@jerris.com> |
| 28 | * Paul D. Tinsley <pdt at jackhammer.org> |
| 29 | * |
| 30 | * |
| 31 | * switch_core_state_machine.c -- Main Core Library (state machine) |
| 32 | * |
| 33 | */ |
| 34 | |
| 35 | #include <switch.h> |
| 36 | #include "private/switch_core_pvt.h" |
| 37 | |
| 38 | static void switch_core_standard_on_init(switch_core_session_t *session) |
| 39 | { |
| 40 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 40, (const char*)(session), SWITCH_LOG_DEBUG, "%s Standard INIT\n", switch_channel_get_name(session->channel)); |
| 41 | |
| 42 | if (switch_channel_test_flag(session->channel, CF_RECOVERING_BRIDGE)) { |
| 43 | switch_channel_set_state(session->channel, CS_RESET)switch_channel_perform_set_state(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 43, CS_RESET); |
| 44 | } else { |
| 45 | if (switch_channel_test_flag(session->channel, CF_RECOVERING)) { |
| 46 | switch_channel_set_state(session->channel, CS_EXECUTE)switch_channel_perform_set_state(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 46, CS_EXECUTE); |
| 47 | } else { |
| 48 | switch_channel_set_state(session->channel, CS_ROUTING)switch_channel_perform_set_state(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 48, CS_ROUTING); |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | switch_channel_clear_flag(session->channel, CF_RECOVERING); |
| 53 | } |
| 54 | |
| 55 | static void switch_core_standard_on_hangup(switch_core_session_t *session) |
| 56 | { |
| 57 | switch_caller_extension_t *extension; |
| 58 | int rec; |
| 59 | |
| 60 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 60, (const char*)(session), SWITCH_LOG_DEBUG, "%s Standard HANGUP, cause: %s\n", |
| 61 | switch_channel_get_name(session->channel), switch_channel_cause2str(switch_channel_get_cause(session->channel))); |
| 62 | |
| 63 | |
| 64 | rec = switch_channel_test_flag(session->channel, CF_RECOVERING); |
| 65 | switch_channel_clear_flag(session->channel, CF_RECOVERING); |
| 66 | |
| 67 | if (!rec) { |
| 68 | switch_core_recovery_untrack(session, SWITCH_TRUE); |
| 69 | } |
| 70 | |
| 71 | |
| 72 | if (!switch_channel_test_flag(session->channel, CF_ZOMBIE_EXEC)) { |
| 73 | return; |
| 74 | } |
| 75 | |
| 76 | if ((extension = switch_channel_get_caller_extension(session->channel)) == 0) { |
| 77 | return; |
| 78 | } |
| 79 | |
| 80 | while(extension->current_application) { |
| 81 | switch_caller_application_t *current_application = extension->current_application; |
| 82 | switch_status_t status; |
| 83 | |
| 84 | extension->current_application = extension->current_application->next; |
| 85 | |
| 86 | status = switch_core_session_execute_application(session,switch_core_session_execute_application_get_flags(session, current_application ->application_name, current_application->application_data , ((void*)0)) |
| 87 | current_application->application_name, current_application->application_data)switch_core_session_execute_application_get_flags(session, current_application ->application_name, current_application->application_data , ((void*)0)); |
| 88 | |
| 89 | |
| 90 | if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_IGNORE) { |
| 91 | return; |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | |
| 96 | |
| 97 | |
| 98 | |
| 99 | } |
| 100 | |
| 101 | static void switch_core_standard_on_reporting(switch_core_session_t *session) |
| 102 | { |
| 103 | |
| 104 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 104, (const char*)(session), SWITCH_LOG_DEBUG, "%s Standard REPORTING, cause: %s\n", |
| 105 | switch_channel_get_name(session->channel), switch_channel_cause2str(switch_channel_get_cause(session->channel))); |
| 106 | } |
| 107 | |
| 108 | static void switch_core_standard_on_destroy(switch_core_session_t *session) |
| 109 | { |
| 110 | |
| 111 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 111, (const char*)(session), SWITCH_LOG_DEBUG, "%s Standard DESTROY\n", switch_channel_get_name(session->channel)); |
| 112 | } |
| 113 | |
| 114 | static void switch_core_standard_on_reset(switch_core_session_t *session) |
| 115 | { |
| 116 | switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(session->channel, "call_uuid" , switch_core_session_get_uuid(session), SWITCH_TRUE); |
| 117 | |
| 118 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 118, (const char*)(session), SWITCH_LOG_DEBUG, "%s Standard RESET\n", switch_channel_get_name(session->channel)); |
| 119 | |
| 120 | if (switch_channel_test_flag(session->channel, CF_RECOVERING_BRIDGE)) { |
| 121 | switch_core_session_t *other_session = NULL((void*)0); |
| 122 | const char *uuid = switch_core_session_get_uuid(session); |
| 123 | |
| 124 | if (switch_channel_test_flag(session->channel, CF_BRIDGE_ORIGINATOR)) { |
| 125 | const char *other_uuid = switch_channel_get_partner_uuid(session->channel); |
| 126 | int x = 0; |
| 127 | |
| 128 | if (other_uuid) { |
| 129 | for (x = 0; other_session == NULL((void*)0) && x < 20; x++) { |
| 130 | if (!switch_channel_up(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE ) || switch_channel_get_state(session->channel) < CS_HANGUP )) { |
| 131 | break; |
| 132 | } |
| 133 | other_session = switch_core_session_locate(other_uuid)switch_core_session_perform_locate(other_uuid, "src/switch_core_state_machine.c" , (const char *)__func__, 133); |
| 134 | switch_yield(100000)switch_sleep(100000);; |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | if (other_session) { |
| 139 | switch_channel_t *other_channel = switch_core_session_get_channel(other_session); |
| 140 | switch_channel_clear_flag(session->channel, CF_BRIDGE_ORIGINATOR); |
| 141 | switch_channel_wait_for_state_timeout(other_channel, CS_RESET, 5000); |
| 142 | switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 2000, NULL((void*)0)); |
| 143 | |
| 144 | if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) && switch_channel_test_flag(other_channel, CF_PROXY_MODE)) { |
| 145 | switch_ivr_signal_bridge(session, other_session); |
| 146 | } else { |
| 147 | switch_ivr_uuid_bridge(uuid, other_uuid); |
| 148 | } |
| 149 | switch_core_session_rwunlock(other_session); |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | switch_channel_clear_flag(session->channel, CF_RECOVERING_BRIDGE); |
| 154 | } |
| 155 | |
| 156 | } |
| 157 | |
| 158 | static void switch_core_standard_on_routing(switch_core_session_t *session) |
| 159 | { |
| 160 | switch_dialplan_interface_t *dialplan_interface = NULL((void*)0); |
| 161 | switch_caller_profile_t *caller_profile; |
| 162 | switch_caller_extension_t *extension = NULL((void*)0); |
| 163 | char *expanded = NULL((void*)0); |
| 164 | char *dpstr = NULL((void*)0); |
| 165 | |
| 166 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 166, (const char*)(session), SWITCH_LOG_DEBUG, "%s Standard ROUTING\n", switch_channel_get_name(session->channel)); |
| 167 | |
| 168 | switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(session->channel, "call_uuid" , switch_core_session_get_uuid(session), SWITCH_TRUE); |
| 169 | |
| 170 | if ((switch_channel_test_flag(session->channel, CF_ANSWERED) || |
| 171 | switch_channel_test_flag(session->channel, CF_EARLY_MEDIA) || |
| 172 | switch_channel_test_flag(session->channel, CF_SIGNAL_BRIDGE_TTL)) && switch_channel_test_flag(session->channel, CF_PROXY_MODE)) { |
| 173 | switch_ivr_media(session->uuid_str, SMF_NONE); |
| 174 | } |
| 175 | |
| 176 | if ((caller_profile = switch_channel_get_caller_profile(session->channel)) == 0) { |
| 177 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 177, (const char*)(session), SWITCH_LOG_ERROR, "Can't get profile!\n"); |
| 178 | switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 178, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ); |
| 179 | return; |
| 180 | } else { |
| 181 | char *dp[25]; |
| 182 | int argc, x, count = 0; |
| 183 | |
| 184 | if ((extension = switch_channel_get_queued_extension(session->channel))) { |
| 185 | switch_channel_set_caller_extension(session->channel, extension); |
| 186 | switch_channel_set_state(session->channel, CS_EXECUTE)switch_channel_perform_set_state(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 186, CS_EXECUTE); |
| 187 | goto end; |
| 188 | } |
| 189 | |
| 190 | if (!zstr(caller_profile->dialplan)_zstr(caller_profile->dialplan)) { |
| 191 | if ((dpstr = switch_core_session_strdup(session, caller_profile->dialplan)switch_core_perform_session_strdup(session, caller_profile-> dialplan, "src/switch_core_state_machine.c", (const char *)__func__ , 191))) { |
| 192 | expanded = switch_channel_expand_variables(session->channel, dpstr)switch_channel_expand_variables_check(session->channel, dpstr , ((void*)0), ((void*)0), 0); |
| 193 | argc = switch_separate_string(expanded, ',', dp, (sizeof(dp) / sizeof(dp[0]))); |
| 194 | for (x = 0; x < argc; x++) { |
| 195 | char *dpname = dp[x]; |
| 196 | char *dparg = NULL((void*)0); |
| 197 | |
| 198 | if (dpname) { |
| 199 | if ((dparg = strchr(dpname, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p (dpname) && (':') == '\0' ? (char *) __rawmemchr (dpname , ':') : __builtin_strchr (dpname, ':'))))) { |
| 200 | *dparg++ = '\0'; |
| 201 | } |
| 202 | } else { |
| 203 | continue; |
| 204 | } |
| 205 | if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) { |
| 206 | continue; |
| 207 | } |
| 208 | |
| 209 | count++; |
| 210 | |
| 211 | extension = dialplan_interface->hunt_function(session, dparg, NULL((void*)0)); |
| 212 | UNPROTECT_INTERFACE(dialplan_interface)if (dialplan_interface) {switch_mutex_lock(dialplan_interface ->reflock); switch_thread_rwlock_unlock(dialplan_interface ->rwlock); switch_thread_rwlock_unlock(dialplan_interface-> parent->rwlock); dialplan_interface->refs--; dialplan_interface ->parent->refs--; switch_mutex_unlock(dialplan_interface ->reflock);}; |
| 213 | |
| 214 | if (extension) { |
| 215 | switch_channel_set_caller_extension(session->channel, extension); |
| 216 | switch_channel_set_state(session->channel, CS_EXECUTE)switch_channel_perform_set_state(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 216, CS_EXECUTE); |
| 217 | goto end; |
| 218 | } |
| 219 | } |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | if (!count) { |
| 224 | if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { |
| 225 | if (switch_channel_test_flag(session->channel, CF_ANSWERED)) { |
| 226 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 226, (const char*)(session), SWITCH_LOG_DEBUG, |
| 227 | "No Dialplan on answered channel, changing state to HANGUP\n"); |
| 228 | switch_channel_hangup(session->channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION)switch_channel_perform_hangup(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 228, SWITCH_CAUSE_NO_ROUTE_DESTINATION ); |
| 229 | } else { |
| 230 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 230, (const char*)(session), SWITCH_LOG_DEBUG, "No Dialplan, changing state to CONSUME_MEDIA\n"); |
| 231 | switch_channel_set_state(session->channel, CS_CONSUME_MEDIA)switch_channel_perform_set_state(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 231, CS_CONSUME_MEDIA); |
| 232 | } |
| 233 | goto end; |
| 234 | } |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | if (!extension) { |
| 239 | |
| 240 | if (switch_ivr_blind_transfer_ack(session, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { |
| 241 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 241, (const char*)(session), SWITCH_LOG_INFO, "No Route, Aborting\n"); |
| 242 | switch_channel_hangup(session->channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION)switch_channel_perform_hangup(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 242, SWITCH_CAUSE_NO_ROUTE_DESTINATION ); |
| 243 | } |
| 244 | } |
| 245 | |
| 246 | end: |
| 247 | |
| 248 | if (expanded && dpstr && expanded != dpstr) { |
| 249 | free(expanded); |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | static void switch_core_standard_on_execute(switch_core_session_t *session) |
| 254 | { |
| 255 | switch_caller_extension_t *extension; |
| 256 | const char *uuid; |
| 257 | |
| 258 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 258, (const char*)(session), SWITCH_LOG_DEBUG, "%s Standard EXECUTE\n", switch_channel_get_name(session->channel)); |
| 259 | |
| 260 | switch_channel_clear_flag(session->channel, CF_RECOVERING); |
| 261 | |
| 262 | switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(session->channel, "call_uuid" , switch_core_session_get_uuid(session), SWITCH_TRUE); |
| 263 | |
| 264 | if (switch_channel_get_variable(session->channel, "recovered")switch_channel_get_variable_dup(session->channel, "recovered" , SWITCH_TRUE, -1) && !switch_channel_test_flag(session->channel, CF_RECOVERED)) { |
| 265 | switch_channel_set_flag(session->channel, CF_RECOVERED)switch_channel_set_flag_value(session->channel, CF_RECOVERED , 1); |
| 266 | } |
| 267 | |
| 268 | top: |
| 269 | switch_channel_clear_flag(session->channel, CF_RESET); |
| 270 | |
| 271 | switch_core_session_video_reset(session); |
| 272 | |
| 273 | if ((extension = switch_channel_get_caller_extension(session->channel)) == 0) { |
| 274 | switch_channel_hangup(session->channel, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 274, SWITCH_CAUSE_NORMAL_CLEARING); |
| 275 | return; |
| 276 | } |
| 277 | |
| 278 | while (switch_channel_get_state(session->channel) == CS_EXECUTE && extension->current_application) { |
| 279 | switch_caller_application_t *current_application = extension->current_application; |
| 280 | |
| 281 | extension->current_application = extension->current_application->next; |
| 282 | |
| 283 | if (switch_core_session_execute_application(session,switch_core_session_execute_application_get_flags(session, current_application ->application_name, current_application->application_data , ((void*)0)) |
| 284 | current_application->application_name,switch_core_session_execute_application_get_flags(session, current_application ->application_name, current_application->application_data , ((void*)0)) |
| 285 | current_application->application_data)switch_core_session_execute_application_get_flags(session, current_application ->application_name, current_application->application_data , ((void*)0)) != SWITCH_STATUS_SUCCESS) { |
| 286 | return; |
| 287 | } |
| 288 | |
| 289 | if (switch_channel_test_flag(session->channel, CF_RESET)) { |
| 290 | goto top; |
| 291 | } |
| 292 | |
| 293 | } |
| 294 | |
| 295 | if (switch_channel_ready(session->channel)switch_channel_test_ready(session->channel, SWITCH_TRUE, SWITCH_FALSE ) && switch_channel_get_state(session->channel) == CS_EXECUTE && |
| 296 | switch_channel_test_flag(session->channel, CF_CONFIRM_BLIND_TRANSFER) && |
| 297 | (uuid = switch_channel_get_variable(session->channel, "blind_transfer_uuid")switch_channel_get_variable_dup(session->channel, "blind_transfer_uuid" , SWITCH_TRUE, -1))) { |
| 298 | switch_core_session_t *other_session; |
| 299 | |
| 300 | if ((other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_core_state_machine.c" , (const char *)__func__, 300))) { |
| 301 | switch_core_session_message_t msg = { 0 }; |
| 302 | msg.message_id = SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE; |
| 303 | msg.from = __FILE__"src/switch_core_state_machine.c"; |
| 304 | msg.numeric_arg = 0; |
| 305 | switch_core_session_receive_message(other_session, &msg)switch_core_session_perform_receive_message(other_session, & msg, "src/switch_core_state_machine.c", (const char *)__func__ , 305); |
| 306 | switch_core_session_rwunlock(other_session); |
| 307 | |
| 308 | switch_channel_set_variable(session->channel, "park_timeout", "10:blind_transfer")switch_channel_set_variable_var_check(session->channel, "park_timeout" , "10:blind_transfer", SWITCH_TRUE); |
| 309 | switch_channel_set_state(session->channel, CS_PARK)switch_channel_perform_set_state(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 309, CS_PARK); |
| 310 | switch_channel_clear_flag(session->channel, CF_CONFIRM_BLIND_TRANSFER); |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | if (switch_channel_ready(session->channel)switch_channel_test_ready(session->channel, SWITCH_TRUE, SWITCH_FALSE ) && switch_channel_get_state(session->channel) == CS_EXECUTE) { |
| 315 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 315, (const char*)(session), SWITCH_LOG_NOTICE, "%s has executed the last dialplan instruction, hanging up.\n", |
| 316 | switch_channel_get_name(session->channel)); |
| 317 | switch_channel_hangup(session->channel, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 317, SWITCH_CAUSE_NORMAL_CLEARING); |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | static void switch_core_standard_on_exchange_media(switch_core_session_t *session) |
| 322 | { |
| 323 | |
| 324 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 324, (const char*)(session), SWITCH_LOG_DEBUG, "%s Standard EXCHANGE_MEDIA\n", switch_channel_get_name(session->channel)); |
| 325 | } |
| 326 | |
| 327 | static void switch_core_standard_on_soft_execute(switch_core_session_t *session) |
| 328 | { |
| 329 | switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)" , "src/switch_core_state_machine.c", 329, __PRETTY_FUNCTION__ )); |
| 330 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 330, (const char*)(session), SWITCH_LOG_DEBUG, "%s Standard SOFT_EXECUTE\n", switch_channel_get_name(session->channel)); |
| 331 | } |
| 332 | |
| 333 | static void switch_core_standard_on_park(switch_core_session_t *session) |
| 334 | { |
| 335 | switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)" , "src/switch_core_state_machine.c", 335, __PRETTY_FUNCTION__ )); |
| 336 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 336, (const char*)(session), SWITCH_LOG_DEBUG, "%s Standard PARK\n", switch_channel_get_name(session->channel)); |
| 337 | switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); |
| 338 | switch_ivr_park(session, NULL((void*)0)); |
| 339 | } |
| 340 | |
| 341 | static void switch_core_standard_on_consume_media(switch_core_session_t *session) |
| 342 | { |
| 343 | switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)" , "src/switch_core_state_machine.c", 343, __PRETTY_FUNCTION__ )); |
| 344 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 344, (const char*)(session), SWITCH_LOG_DEBUG, "%s Standard CONSUME_MEDIA\n", switch_channel_get_name(session->channel)); |
| 345 | } |
| 346 | |
| 347 | static void switch_core_standard_on_hibernate(switch_core_session_t *session) |
| 348 | { |
| 349 | switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)" , "src/switch_core_state_machine.c", 349, __PRETTY_FUNCTION__ )); |
| 350 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 350, (const char*)(session), SWITCH_LOG_DEBUG, "%s Standard HIBERNATE\n", switch_channel_get_name(session->channel)); |
| 351 | } |
| 352 | |
| 353 | void switch_core_state_machine_init(switch_memory_pool_t *pool) |
| 354 | { |
| 355 | return; |
| 356 | } |
| 357 | |
| 358 | #define STATE_MACRO(__STATE, __STATE_STR)do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 358 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), __STATE_STR); if (state < CS_HANGUP && switch_channel_get_callstate (session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 358); } switch_core_session_refresh_video (session); if (!driver_state_handler->on___STATE || (driver_state_handler ->on___STATE(session) == SWITCH_STATUS_SUCCESS )) { while ( do_extra_handlers && (application_state_handler = switch_channel_get_state_handler (session->channel, index++)) != 0) { if (!application_state_handler || !application_state_handler->on___STATE || (application_state_handler ->on___STATE && application_state_handler->on___STATE (session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on___STATE || (application_state_handler->on___STATE && application_state_handler->on___STATE(session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state(session-> channel)) global_proceed = 0; if (global_proceed) { switch_core_standard_on___STATE (session); } } switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 358, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), __STATE_STR); } while (silly) do { \ |
| 359 | midstate = state; \ |
| 360 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 360, (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n", switch_channel_get_name(session->channel), __STATE_STR); \ |
| 361 | if (state < CS_HANGUP && switch_channel_get_callstate(session->channel) == CCS_UNHELD) { \ |
| 362 | switch_channel_set_callstate(session->channel, CCS_ACTIVE)switch_channel_perform_set_callstate(session->channel, CCS_ACTIVE , "src/switch_core_state_machine.c", (const char *)__func__, 362 ); \ |
| 363 | } \ |
| 364 | switch_core_session_refresh_video(session); \ |
| 365 | if (!driver_state_handler->on_##__STATE || (driver_state_handler->on_##__STATE(session) == SWITCH_STATUS_SUCCESS \ |
| 366 | )) { \ |
| 367 | while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler(session->channel, index++)) != 0) { \ |
| 368 | if (!application_state_handler || !application_state_handler->on_##__STATE \ |
| 369 | || (application_state_handler->on_##__STATE \ |
| 370 | && application_state_handler->on_##__STATE(session) == SWITCH_STATUS_SUCCESS \ |
| 371 | )) { \ |
| 372 | proceed++; \ |
| 373 | continue; \ |
| 374 | } else { \ |
| 375 | proceed = 0; \ |
| 376 | break; \ |
| 377 | } \ |
| 378 | } \ |
| 379 | index = 0; \ |
| 380 | if (!proceed) global_proceed = 0; \ |
| 381 | proceed = 1; \ |
| 382 | while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler(index++)) != 0) { \ |
| 383 | if (!application_state_handler || !application_state_handler->on_##__STATE || \ |
| 384 | (application_state_handler->on_##__STATE && \ |
| 385 | application_state_handler->on_##__STATE(session) == SWITCH_STATUS_SUCCESS \ |
| 386 | )) { \ |
| 387 | proceed++; \ |
| 388 | continue; \ |
| 389 | } else { \ |
| 390 | proceed = 0; \ |
| 391 | break; \ |
| 392 | } \ |
| 393 | } \ |
| 394 | if (!proceed || midstate != switch_channel_get_state(session->channel)) global_proceed = 0; \ |
| 395 | if (global_proceed) { \ |
| 396 | switch_core_standard_on_##__STATE(session); \ |
| 397 | } \ |
| 398 | } \ |
| 399 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 399, (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s going to sleep\n", switch_channel_get_name(session->channel), __STATE_STR); \ |
| 400 | } while (silly) |
| 401 | |
| 402 | |
| 403 | static void check_presence(switch_core_session_t *session) |
| 404 | { |
| 405 | switch_channel_state_t state = switch_channel_get_running_state(session->channel); |
| 406 | |
| 407 | if (state == CS_ROUTING || state == CS_HANGUP) { |
| 408 | if (switch_channel_get_cause(session->channel) == SWITCH_CAUSE_LOSE_RACE) { |
| 409 | switch_channel_presence(session->channel, "unknown", "cancelled", NULL)switch_channel_perform_presence(session->channel, "unknown" , "cancelled", ((void*)0), "src/switch_core_state_machine.c", (const char *)__func__, 409); |
| 410 | switch_channel_set_variable(session->channel, "presence_call_info", NULL)switch_channel_set_variable_var_check(session->channel, "presence_call_info" , ((void*)0), SWITCH_TRUE); |
| 411 | } else { |
| 412 | switch_channel_presence(session->channel, "unknown", switch_channel_state_name(state), NULL)switch_channel_perform_presence(session->channel, "unknown" , switch_channel_state_name(state), ((void*)0), "src/switch_core_state_machine.c" , (const char *)__func__, 412); |
| 413 | } |
| 414 | } |
| 415 | } |
| 416 | |
| 417 | |
| 418 | |
| 419 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_run(switch_core_session_t *session) |
| 420 | { |
| 421 | switch_channel_state_t state = CS_NEW, midstate = CS_DESTROY, endstate; |
| 422 | const switch_endpoint_interface_t *endpoint_interface; |
| 423 | const switch_state_handler_table_t *driver_state_handler = NULL((void*)0); |
| 424 | const switch_state_handler_table_t *application_state_handler = NULL((void*)0); |
| 425 | int silly = 0; |
| 426 | uint32_t new_loops = 500; |
| 427 | |
| 428 | /* |
| 429 | Life of the channel. you have channel and pool in your session |
| 430 | everywhere you go you use the session to malloc with |
| 431 | switch_core_session_alloc(session, <size>) |
| 432 | |
| 433 | The endpoint module gets the first crack at implementing the state |
| 434 | if it wants to, it can cancel the default behavior by returning SWITCH_STATUS_FALSE |
| 435 | |
| 436 | Next comes the channel's event handler table that can be set by an application |
| 437 | which also can veto the next behavior in line by returning SWITCH_STATUS_FALSE |
| 438 | |
| 439 | Finally the default state behavior is called. |
| 440 | |
| 441 | |
| 442 | */ |
| 443 | switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)" , "src/switch_core_state_machine.c", 443, __PRETTY_FUNCTION__ )); |
| 444 | |
| 445 | switch_set_flag(session, SSF_THREAD_RUNNING)(session)->flags |= (SSF_THREAD_RUNNING); |
| 446 | endpoint_interface = session->endpoint_interface; |
| 447 | switch_assert(endpoint_interface != NULL)((endpoint_interface != ((void*)0)) ? (void) (0) : __assert_fail ("endpoint_interface != ((void*)0)", "src/switch_core_state_machine.c" , 447, __PRETTY_FUNCTION__)); |
| 448 | |
| 449 | driver_state_handler = endpoint_interface->state_handler; |
| 450 | switch_assert(driver_state_handler != NULL)((driver_state_handler != ((void*)0)) ? (void) (0) : __assert_fail ("driver_state_handler != ((void*)0)", "src/switch_core_state_machine.c" , 450, __PRETTY_FUNCTION__)); |
| 451 | |
| 452 | switch_mutex_lock(session->mutex); |
| 453 | |
| 454 | while ((state = switch_channel_get_state(session->channel)) != CS_DESTROY) { |
| 455 | |
| 456 | if (switch_channel_test_flag(session->channel, CF_BLOCK_STATE)) { |
| 457 | switch_channel_wait_for_flag(session->channel, CF_BLOCK_STATE, SWITCH_FALSE, 0, NULL((void*)0)); |
| 458 | if ((state = switch_channel_get_state(session->channel)) == CS_DESTROY) { |
| 459 | break; |
| 460 | } |
| 461 | } |
| 462 | |
| 463 | midstate = state; |
| 464 | if (state != switch_channel_get_running_state(session->channel) || state >= CS_HANGUP) { |
| 465 | int index = 0; |
| 466 | int proceed = 1; |
| 467 | int global_proceed = 1; |
| 468 | int do_extra_handlers = 1; |
| 469 | switch_io_event_hook_state_run_t *ptr; |
| 470 | switch_status_t rstatus = SWITCH_STATUS_SUCCESS; |
| 471 | |
| 472 | switch_channel_set_running_state(session->channel, state)switch_channel_perform_set_running_state(session->channel, state, "src/switch_core_state_machine.c", (const char *)__func__ , 472); |
| 473 | switch_channel_clear_flag(session->channel, CF_TRANSFER); |
| 474 | switch_channel_clear_flag(session->channel, CF_REDIRECT); |
| 475 | switch_ivr_parse_all_messages(session); |
| 476 | |
| 477 | if (session->endpoint_interface->io_routines->state_run) { |
| 478 | rstatus = session->endpoint_interface->io_routines->state_run(session); |
| 479 | } |
| 480 | |
| 481 | if (rstatus == SWITCH_STATUS_SUCCESS) { |
| 482 | for (ptr = session->event_hooks.state_run; ptr; ptr = ptr->next) { |
| 483 | if ((rstatus = ptr->state_run(session)) != SWITCH_STATUS_SUCCESS) { |
| 484 | break; |
| 485 | } |
| 486 | } |
| 487 | } |
| 488 | |
| 489 | switch (state) { |
| 490 | case CS_NEW: /* Just created, Waiting for first instructions */ |
| 491 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 491, (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State NEW\n", switch_channel_get_name(session->channel)); |
| 492 | break; |
| 493 | case CS_DESTROY: |
| 494 | goto done; |
| 495 | case CS_REPORTING: /* Call Detail */ |
| 496 | { |
| 497 | switch_core_session_reporting_state(session); |
| 498 | switch_channel_set_state(session->channel, CS_DESTROY)switch_channel_perform_set_state(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 498, CS_DESTROY); |
| 499 | } |
| 500 | goto done; |
| 501 | case CS_HANGUP: /* Deactivate and end the thread */ |
| 502 | { |
| 503 | switch_core_session_hangup_state(session, SWITCH_TRUE); |
| 504 | switch_channel_set_state(session->channel, CS_REPORTING)switch_channel_perform_set_state(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 504, CS_REPORTING); |
| 505 | } |
| 506 | |
| 507 | break; |
| 508 | case CS_INIT: /* Basic setup tasks */ |
| 509 | { |
| 510 | switch_event_t *event; |
| 511 | |
| 512 | STATE_MACRO(init, "INIT")do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 512 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), "INIT"); if ( state < CS_HANGUP && switch_channel_get_callstate( session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 512); } switch_core_session_refresh_video (session); if (!driver_state_handler->on_init || (driver_state_handler ->on_init(session) == SWITCH_STATUS_SUCCESS )) { while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler (session->channel, index++)) != 0) { if (!application_state_handler || !application_state_handler->on_init || (application_state_handler ->on_init && application_state_handler->on_init (session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on_init || (application_state_handler->on_init && application_state_handler->on_init(session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state(session-> channel)) global_proceed = 0; if (global_proceed) { switch_core_standard_on_init (session); } } switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 512, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), "INIT"); } while (silly); |
| 513 | |
| 514 | if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_CREATE)switch_event_create_subclass_detailed("src/switch_core_state_machine.c" , (const char * )(const char *)__func__, 514, &event, SWITCH_EVENT_CHANNEL_CREATE , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
| 515 | switch_channel_event_set_data(session->channel, event); |
| 516 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_state_machine.c", (const char * )(const char *)__func__, 516, &event, ((void *)0)); |
| 517 | } |
| 518 | |
| 519 | if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { |
| 520 | if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_ORIGINATE)switch_event_create_subclass_detailed("src/switch_core_state_machine.c" , (const char * )(const char *)__func__, 520, &event, SWITCH_EVENT_CHANNEL_ORIGINATE , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
| 521 | switch_channel_event_set_data(session->channel, event); |
| 522 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_state_machine.c", (const char * )(const char *)__func__, 522, &event, ((void *)0)); |
| 523 | } |
| 524 | } |
| 525 | } |
| 526 | break; |
| 527 | case CS_ROUTING: /* Look for a dialplan and find something to do */ |
| 528 | STATE_MACRO(routing, "ROUTING")do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 528 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), "ROUTING"); if (state < CS_HANGUP && switch_channel_get_callstate (session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 528); } switch_core_session_refresh_video (session); if (!driver_state_handler->on_routing || (driver_state_handler ->on_routing(session) == SWITCH_STATUS_SUCCESS )) { while ( do_extra_handlers && (application_state_handler = switch_channel_get_state_handler (session->channel, index++)) != 0) { if (!application_state_handler || !application_state_handler->on_routing || (application_state_handler ->on_routing && application_state_handler->on_routing (session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on_routing || (application_state_handler->on_routing && application_state_handler->on_routing(session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state(session-> channel)) global_proceed = 0; if (global_proceed) { switch_core_standard_on_routing (session); } } switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 528, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), "ROUTING"); } while (silly); |
| 529 | break; |
| 530 | case CS_RESET: /* Reset */ |
| 531 | STATE_MACRO(reset, "RESET")do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 531 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), "RESET"); if ( state < CS_HANGUP && switch_channel_get_callstate( session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 531); } switch_core_session_refresh_video (session); if (!driver_state_handler->on_reset || (driver_state_handler ->on_reset(session) == SWITCH_STATUS_SUCCESS )) { while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler (session->channel, index++)) != 0) { if (!application_state_handler || !application_state_handler->on_reset || (application_state_handler ->on_reset && application_state_handler->on_reset (session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on_reset || (application_state_handler->on_reset && application_state_handler->on_reset(session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state(session-> channel)) global_proceed = 0; if (global_proceed) { switch_core_standard_on_reset (session); } } switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 531, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), "RESET"); } while (silly); |
| 532 | break; |
| 533 | /* These other states are intended for prolonged durations so we do not signal lock for them */ |
| 534 | case CS_EXECUTE: /* Execute an Operation */ |
| 535 | STATE_MACRO(execute, "EXECUTE")do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 535 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), "EXECUTE"); if (state < CS_HANGUP && switch_channel_get_callstate (session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 535); } switch_core_session_refresh_video (session); if (!driver_state_handler->on_execute || (driver_state_handler ->on_execute(session) == SWITCH_STATUS_SUCCESS )) { while ( do_extra_handlers && (application_state_handler = switch_channel_get_state_handler (session->channel, index++)) != 0) { if (!application_state_handler || !application_state_handler->on_execute || (application_state_handler ->on_execute && application_state_handler->on_execute (session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on_execute || (application_state_handler->on_execute && application_state_handler->on_execute(session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state(session-> channel)) global_proceed = 0; if (global_proceed) { switch_core_standard_on_execute (session); } } switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 535, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), "EXECUTE"); } while (silly); |
| 536 | break; |
| 537 | case CS_EXCHANGE_MEDIA: /* loop all data back to source */ |
| 538 | STATE_MACRO(exchange_media, "EXCHANGE_MEDIA")do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 538 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), "EXCHANGE_MEDIA" ); if (state < CS_HANGUP && switch_channel_get_callstate (session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 538); } switch_core_session_refresh_video (session); if (!driver_state_handler->on_exchange_media || (driver_state_handler->on_exchange_media(session) == SWITCH_STATUS_SUCCESS )) { while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler(session->channel, index ++)) != 0) { if (!application_state_handler || !application_state_handler ->on_exchange_media || (application_state_handler->on_exchange_media && application_state_handler->on_exchange_media(session ) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on_exchange_media || (application_state_handler->on_exchange_media && application_state_handler->on_exchange_media(session ) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state (session->channel)) global_proceed = 0; if (global_proceed ) { switch_core_standard_on_exchange_media(session); } } switch_log_printf (SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 538, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), "EXCHANGE_MEDIA"); } while (silly); |
| 539 | break; |
| 540 | case CS_SOFT_EXECUTE: /* send/recieve data to/from another channel */ |
| 541 | STATE_MACRO(soft_execute, "SOFT_EXECUTE")do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 541 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), "SOFT_EXECUTE" ); if (state < CS_HANGUP && switch_channel_get_callstate (session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 541); } switch_core_session_refresh_video (session); if (!driver_state_handler->on_soft_execute || ( driver_state_handler->on_soft_execute(session) == SWITCH_STATUS_SUCCESS )) { while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler(session->channel, index ++)) != 0) { if (!application_state_handler || !application_state_handler ->on_soft_execute || (application_state_handler->on_soft_execute && application_state_handler->on_soft_execute(session ) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on_soft_execute || (application_state_handler->on_soft_execute && application_state_handler->on_soft_execute(session ) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state (session->channel)) global_proceed = 0; if (global_proceed ) { switch_core_standard_on_soft_execute(session); } } switch_log_printf (SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 541, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), "SOFT_EXECUTE"); } while (silly); |
| 542 | break; |
| 543 | case CS_PARK: /* wait in limbo */ |
| 544 | STATE_MACRO(park, "PARK")do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 544 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), "PARK"); if ( state < CS_HANGUP && switch_channel_get_callstate( session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 544); } switch_core_session_refresh_video (session); if (!driver_state_handler->on_park || (driver_state_handler ->on_park(session) == SWITCH_STATUS_SUCCESS )) { while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler (session->channel, index++)) != 0) { if (!application_state_handler || !application_state_handler->on_park || (application_state_handler ->on_park && application_state_handler->on_park (session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on_park || (application_state_handler->on_park && application_state_handler->on_park(session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state(session-> channel)) global_proceed = 0; if (global_proceed) { switch_core_standard_on_park (session); } } switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 544, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), "PARK"); } while (silly); |
| 545 | break; |
| 546 | case CS_CONSUME_MEDIA: /* wait in limbo */ |
| 547 | STATE_MACRO(consume_media, "CONSUME_MEDIA")do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 547 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), "CONSUME_MEDIA" ); if (state < CS_HANGUP && switch_channel_get_callstate (session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 547); } switch_core_session_refresh_video (session); if (!driver_state_handler->on_consume_media || ( driver_state_handler->on_consume_media(session) == SWITCH_STATUS_SUCCESS )) { while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler(session->channel, index ++)) != 0) { if (!application_state_handler || !application_state_handler ->on_consume_media || (application_state_handler->on_consume_media && application_state_handler->on_consume_media(session ) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on_consume_media || (application_state_handler->on_consume_media && application_state_handler->on_consume_media(session ) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state (session->channel)) global_proceed = 0; if (global_proceed ) { switch_core_standard_on_consume_media(session); } } switch_log_printf (SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 547, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), "CONSUME_MEDIA"); } while (silly); |
| 548 | break; |
| 549 | case CS_HIBERNATE: /* sleep */ |
| 550 | STATE_MACRO(hibernate, "HIBERNATE")do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 550 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), "HIBERNATE"); if (state < CS_HANGUP && switch_channel_get_callstate (session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 550); } switch_core_session_refresh_video (session); if (!driver_state_handler->on_hibernate || (driver_state_handler ->on_hibernate(session) == SWITCH_STATUS_SUCCESS )) { while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler (session->channel, index++)) != 0) { if (!application_state_handler || !application_state_handler->on_hibernate || (application_state_handler ->on_hibernate && application_state_handler->on_hibernate (session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on_hibernate || (application_state_handler->on_hibernate && application_state_handler->on_hibernate(session ) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state (session->channel)) global_proceed = 0; if (global_proceed ) { switch_core_standard_on_hibernate(session); } } switch_log_printf (SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 550, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), "HIBERNATE"); } while (silly); |
| 551 | break; |
| 552 | case CS_NONE: |
| 553 | abort(); |
| 554 | break; |
| 555 | } |
| 556 | |
| 557 | check_presence(session); |
| 558 | |
| 559 | if (midstate == CS_DESTROY) { |
| 560 | break; |
| 561 | } |
| 562 | |
| 563 | } |
| 564 | |
| 565 | endstate = switch_channel_get_state(session->channel); |
| 566 | |
| 567 | if (endstate == switch_channel_get_running_state(session->channel)) { |
| 568 | if (endstate == CS_NEW) { |
| 569 | switch_yield(20000)switch_sleep(20000);; |
| 570 | switch_ivr_parse_all_events(session); |
| 571 | if (!--new_loops) { |
| 572 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 572, (const char*)(session), SWITCH_LOG_WARNING, "%s %s Abandoned\n", |
| 573 | session->uuid_str, switch_core_session_get_name(session)switch_channel_get_name(switch_core_session_get_channel(session ))); |
| 574 | switch_channel_set_flag(session->channel, CF_NO_CDR)switch_channel_set_flag_value(session->channel, CF_NO_CDR, 1); |
| 575 | switch_channel_hangup(session->channel, SWITCH_CAUSE_WRONG_CALL_STATE)switch_channel_perform_hangup(session->channel, "src/switch_core_state_machine.c" , (const char *)__func__, 575, SWITCH_CAUSE_WRONG_CALL_STATE); |
| 576 | } |
| 577 | } else { |
| 578 | switch_ivr_parse_all_events(session); |
| 579 | switch_ivr_parse_all_events(session); |
| 580 | |
| 581 | if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) { |
| 582 | switch_channel_state_thread_lock(session->channel); |
| 583 | switch_channel_set_flag(session->channel, CF_THREAD_SLEEPING)switch_channel_set_flag_value(session->channel, CF_THREAD_SLEEPING , 1); |
| 584 | if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) { |
| 585 | switch_ivr_parse_all_events(session); |
| 586 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 586, (const char*)(session), SWITCH_LOG_DEBUG1, "%s session thread sleep state: %s!\n", |
| 587 | switch_channel_get_name(session->channel), |
| 588 | switch_channel_state_name(switch_channel_get_running_state(session->channel))); |
| 589 | switch_thread_cond_wait(session->cond, session->mutex); |
| 590 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 590, (const char*)(session), SWITCH_LOG_DEBUG1, "%s session thread wake state: %s!\n", |
| 591 | switch_channel_get_name(session->channel), |
| 592 | switch_channel_state_name(switch_channel_get_running_state(session->channel))); |
| 593 | |
| 594 | |
| 595 | } |
| 596 | switch_channel_clear_flag(session->channel, CF_THREAD_SLEEPING); |
| 597 | switch_channel_state_thread_unlock(session->channel); |
| 598 | } |
| 599 | |
| 600 | switch_ivr_parse_all_events(session); |
| 601 | switch_ivr_parse_all_events(session); |
| 602 | } |
| 603 | } |
| 604 | } |
| 605 | done: |
| 606 | switch_mutex_unlock(session->mutex); |
| 607 | |
| 608 | switch_clear_flag(session, SSF_THREAD_RUNNING)(session)->flags &= ~(SSF_THREAD_RUNNING); |
| 609 | } |
| 610 | |
| 611 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_destroy_state(switch_core_session_t *session) |
| 612 | { |
| 613 | switch_channel_state_t state = CS_DESTROY, midstate = CS_DESTROY; |
| 614 | const switch_endpoint_interface_t *endpoint_interface; |
| 615 | const switch_state_handler_table_t *driver_state_handler = NULL((void*)0); |
| 616 | const switch_state_handler_table_t *application_state_handler = NULL((void*)0); |
| 617 | int proceed = 1; |
| 618 | int global_proceed = 1; |
| 619 | int do_extra_handlers = 1; |
| 620 | int silly = 0; |
| 621 | int index = 0; |
| 622 | |
| 623 | switch_channel_set_callstate(session->channel, CCS_DOWN)switch_channel_perform_set_callstate(session->channel, CCS_DOWN , "src/switch_core_state_machine.c", (const char *)__func__, 623 ); |
| 624 | |
| 625 | switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)" , "src/switch_core_state_machine.c", 625, __PRETTY_FUNCTION__ )); |
| 626 | switch_channel_set_running_state(session->channel, CS_DESTROY)switch_channel_perform_set_running_state(session->channel, CS_DESTROY, "src/switch_core_state_machine.c", (const char * )__func__, 626); |
| 627 | switch_channel_clear_flag(session->channel, CF_TRANSFER); |
| 628 | switch_channel_clear_flag(session->channel, CF_REDIRECT); |
| 629 | |
| 630 | endpoint_interface = session->endpoint_interface; |
| 631 | switch_assert(endpoint_interface != NULL)((endpoint_interface != ((void*)0)) ? (void) (0) : __assert_fail ("endpoint_interface != ((void*)0)", "src/switch_core_state_machine.c" , 631, __PRETTY_FUNCTION__)); |
| 632 | |
| 633 | driver_state_handler = endpoint_interface->state_handler; |
| 634 | switch_assert(driver_state_handler != NULL)((driver_state_handler != ((void*)0)) ? (void) (0) : __assert_fail ("driver_state_handler != ((void*)0)", "src/switch_core_state_machine.c" , 634, __PRETTY_FUNCTION__)); |
| 635 | |
| 636 | STATE_MACRO(destroy, "DESTROY")do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 636 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), "DESTROY"); if (state < CS_HANGUP && switch_channel_get_callstate (session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 636); } switch_core_session_refresh_video (session); if (!driver_state_handler->on_destroy || (driver_state_handler ->on_destroy(session) == SWITCH_STATUS_SUCCESS )) { while ( do_extra_handlers && (application_state_handler = switch_channel_get_state_handler (session->channel, index++)) != 0) { if (!application_state_handler || !application_state_handler->on_destroy || (application_state_handler ->on_destroy && application_state_handler->on_destroy (session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on_destroy || (application_state_handler->on_destroy && application_state_handler->on_destroy(session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state(session-> channel)) global_proceed = 0; if (global_proceed) { switch_core_standard_on_destroy (session); } } switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 636, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), "DESTROY"); } while (silly); |
| 637 | |
| 638 | switch_channel_clear_device_record(session->channel); |
| 639 | |
| 640 | return; |
| 641 | } |
| 642 | |
| 643 | static void api_hook(switch_core_session_t *session, const char *hook_var, int use_session) |
| 644 | { |
| 645 | if (!zstr(hook_var)_zstr(hook_var)) { |
| 646 | switch_stream_handle_t stream = { 0 }; |
| 647 | char *cmd = strdup(hook_var)(__extension__ (__builtin_constant_p (hook_var) && (( size_t)(const void *)((hook_var) + 1) - (size_t)(const void * )(hook_var) == 1) ? (((const char *) (hook_var))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (hook_var) + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , hook_var, __len); __retval; })) : __strdup (hook_var))); |
| 648 | char *arg = NULL((void*)0); |
| 649 | char *expanded = NULL((void*)0); |
| 650 | |
| 651 | if ((arg = strchr(cmd, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p (cmd) && (':') == '\0' ? (char *) __rawmemchr (cmd, ':' ) : __builtin_strchr (cmd, ':')))) && *(arg + 1) == ':') { |
| 652 | *arg++ = '\0'; |
| 653 | *arg++ = '\0'; |
| 654 | } else { |
| 655 | if ((arg = strchr(cmd, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p (cmd) && (' ') == '\0' ? (char *) __rawmemchr (cmd, ' ' ) : __builtin_strchr (cmd, ' '))))) { |
| 656 | *arg++ = '\0'; |
| 657 | } |
| 658 | } |
| 659 | |
| 660 | SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc( 1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data" , "src/switch_core_state_machine.c", 660, __PRETTY_FUNCTION__ )); memset(stream.data, 0, 1024); stream.end = stream.data; stream .data_size = 1024; stream.write_function = switch_console_stream_write ; stream.raw_write_function = switch_console_stream_raw_write ; stream.alloc_len = 1024; stream.alloc_chunk = 1024; |
| 661 | |
| 662 | switch_channel_get_variables(session->channel, &stream.param_event); |
| 663 | switch_channel_event_set_data(session->channel, stream.param_event); |
| 664 | expanded = switch_event_expand_headers(stream.param_event, arg)switch_event_expand_headers_check(stream.param_event, arg, (( void*)0), ((void*)0), 0); |
| 665 | |
| 666 | switch_api_execute(cmd, expanded, use_session ? session : NULL((void*)0), &stream); |
| 667 | |
| 668 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 668, (const char*)(session), SWITCH_LOG_DEBUG, "Hangup Command %s %s(%s):\n%s\n", |
| 669 | use_session ? "with Session" : "with no Session", cmd, switch_str_nil(expanded)(expanded ? expanded : ""), |
| 670 | switch_str_nil((char *) stream.data)((char *) stream.data ? (char *) stream.data : "") ); |
| 671 | |
| 672 | if (expanded != arg) { |
| 673 | switch_safe_free(expanded)if (expanded) {free(expanded);expanded=((void*)0);}; |
| 674 | } |
| 675 | |
| 676 | switch_safe_free(cmd)if (cmd) {free(cmd);cmd=((void*)0);}; |
| 677 | |
| 678 | switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);}; |
| 679 | } |
| 680 | } |
| 681 | |
| 682 | |
| 683 | |
| 684 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_hangup_state(switch_core_session_t *session, switch_bool_t force) |
| 685 | { |
| 686 | switch_call_cause_t cause = switch_channel_get_cause(session->channel); |
| 687 | switch_call_cause_t cause_q850 = switch_channel_get_cause_q850(session->channel); |
| 688 | int proceed = 1; |
| 689 | int global_proceed = 1; |
| 690 | int do_extra_handlers = 1; |
| 691 | int silly = 0; |
| 692 | int index = 0; |
| 693 | switch_channel_state_t state = switch_channel_get_state(session->channel), midstate = state; |
| 694 | const switch_endpoint_interface_t *endpoint_interface; |
| 695 | const switch_state_handler_table_t *driver_state_handler = NULL((void*)0); |
| 696 | const switch_state_handler_table_t *application_state_handler = NULL((void*)0); |
| 697 | const char *hook_var; |
| 698 | int use_session = 0; |
| 699 | |
| 700 | if (!force) { |
| 701 | if (!switch_channel_test_flag(session->channel, CF_EARLY_HANGUP) && !switch_test_flag((&runtime), SCF_EARLY_HANGUP)(((&runtime))->flags & SCF_EARLY_HANGUP)) { |
| 702 | return; |
| 703 | } |
| 704 | |
| 705 | if (switch_thread_self() != session->thread_id) { |
| 706 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 706, (const char*)(session), SWITCH_LOG_DEBUG10, "%s thread mismatch skipping state handler.\n", |
| 707 | switch_channel_get_name(session->channel)); |
| 708 | return; |
| 709 | } |
| 710 | } |
| 711 | |
| 712 | if (switch_test_flag(session, SSF_HANGUP)((session)->flags & SSF_HANGUP)) { |
| 713 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c", (const char *)__func__, 713, (const char*)(session), SWITCH_LOG_DEBUG10, "%s handler already called, skipping state handler.\n", |
| 714 | switch_channel_get_name(session->channel)); |
| 715 | return; |
| 716 | } |
| 717 | |
| 718 | endpoint_interface = session->endpoint_interface; |
| 719 | switch_assert(endpoint_interface != NULL)((endpoint_interface != ((void*)0)) ? (void) (0) : __assert_fail ("endpoint_interface != ((void*)0)", "src/switch_core_state_machine.c" , 719, __PRETTY_FUNCTION__)); |
| 720 | |
| 721 | driver_state_handler = endpoint_interface->state_handler; |
| 722 | switch_assert(driver_state_handler != NULL)((driver_state_handler != ((void*)0)) ? (void) (0) : __assert_fail ("driver_state_handler != ((void*)0)", "src/switch_core_state_machine.c" , 722, __PRETTY_FUNCTION__)); |
| 723 | |
| 724 | switch_channel_set_hangup_time(session->channel); |
| 725 | |
| 726 | switch_core_media_bug_remove_all(session)switch_core_media_bug_remove_all_function(session, ((void*)0) ); |
| 727 | |
| 728 | switch_channel_stop_broadcast(session->channel)for(;;) {if (switch_channel_test_flag(session->channel, CF_BROADCAST )) {switch_channel_set_flag_value(session->channel, CF_STOP_BROADCAST , 1); switch_channel_set_flag_value(session->channel, CF_BREAK , 1); } break;}; |
| 729 | |
| 730 | switch_channel_set_variable(session->channel, "hangup_cause", switch_channel_cause2str(cause))switch_channel_set_variable_var_check(session->channel, "hangup_cause" , switch_channel_cause2str(cause), SWITCH_TRUE); |
| 731 | switch_channel_set_variable_printf(session->channel, "hangup_cause_q850", "%d", cause_q850); |
| 732 | //switch_channel_presence(session->channel, "unknown", switch_channel_cause2str(cause), NULL); |
| 733 | |
| 734 | switch_channel_set_timestamps(session->channel); |
| 735 | switch_channel_set_callstate(session->channel, CCS_HANGUP)switch_channel_perform_set_callstate(session->channel, CCS_HANGUP , "src/switch_core_state_machine.c", (const char *)__func__, 735 ); |
| 736 | |
| 737 | STATE_MACRO(hangup, "HANGUP")do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 737 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), "HANGUP"); if (state < CS_HANGUP && switch_channel_get_callstate (session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 737); } switch_core_session_refresh_video (session); if (!driver_state_handler->on_hangup || (driver_state_handler ->on_hangup(session) == SWITCH_STATUS_SUCCESS )) { while ( do_extra_handlers && (application_state_handler = switch_channel_get_state_handler (session->channel, index++)) != 0) { if (!application_state_handler || !application_state_handler->on_hangup || (application_state_handler ->on_hangup && application_state_handler->on_hangup (session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on_hangup || (application_state_handler->on_hangup && application_state_handler->on_hangup(session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state(session-> channel)) global_proceed = 0; if (global_proceed) { switch_core_standard_on_hangup (session); } } switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 737, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), "HANGUP"); } while (silly); |
| 738 | |
| 739 | switch_core_media_set_stats(session); |
| 740 | |
| 741 | if ((hook_var = switch_channel_get_variable(session->channel, SWITCH_API_HANGUP_HOOK_VARIABLE)switch_channel_get_variable_dup(session->channel, "api_hangup_hook" , SWITCH_TRUE, -1))) { |
| 742 | |
| 743 | if (switch_true(switch_channel_get_variable(session->channel, SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE)switch_channel_get_variable_dup(session->channel, "session_in_hangup_hook" , SWITCH_TRUE, -1))) { |
| 744 | use_session = 1; |
| 745 | } |
| 746 | |
| 747 | api_hook(session, hook_var, use_session); |
| 748 | } |
| 749 | |
| 750 | switch_channel_process_device_hangup(session->channel); |
| 751 | |
| 752 | switch_set_flag(session, SSF_HANGUP)(session)->flags |= (SSF_HANGUP); |
| 753 | |
| 754 | } |
| 755 | |
| 756 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_reporting_state(switch_core_session_t *session) |
| 757 | { |
| 758 | switch_channel_state_t state = switch_channel_get_state(session->channel), midstate = state; |
Value stored to 'midstate' during its initialization is never read | |
| 759 | const switch_endpoint_interface_t *endpoint_interface; |
| 760 | const switch_state_handler_table_t *driver_state_handler = NULL((void*)0); |
| 761 | const switch_state_handler_table_t *application_state_handler = NULL((void*)0); |
| 762 | int proceed = 1; |
| 763 | int global_proceed = 1; |
| 764 | int do_extra_handlers = 1; |
| 765 | int silly = 0; |
| 766 | int index = 0; |
| 767 | const char *var = switch_channel_get_variable(session->channel, SWITCH_PROCESS_CDR_VARIABLE)switch_channel_get_variable_dup(session->channel, "process_cdr" , SWITCH_TRUE, -1); |
| 768 | const char *skip_var = switch_channel_get_variable(session->channel, SWITCH_SKIP_CDR_CAUSES_VARIABLE)switch_channel_get_variable_dup(session->channel, "skip_cdr_causes" , SWITCH_TRUE, -1); |
| 769 | const char *hook_var; |
| 770 | int use_session = 0; |
| 771 | switch_event_t *event; |
| 772 | switch_call_cause_t cause = switch_channel_get_cause(session->channel); |
| 773 | |
| 774 | if (switch_channel_test_flag(session->channel, CF_REPORTING)) { |
| 775 | return; |
| 776 | } |
| 777 | |
| 778 | switch_channel_set_flag(session->channel, CF_REPORTING)switch_channel_set_flag_value(session->channel, CF_REPORTING , 1); |
| 779 | |
| 780 | switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)" , "src/switch_core_state_machine.c", 780, __PRETTY_FUNCTION__ )); |
| 781 | |
| 782 | endpoint_interface = session->endpoint_interface; |
| 783 | switch_assert(endpoint_interface != NULL)((endpoint_interface != ((void*)0)) ? (void) (0) : __assert_fail ("endpoint_interface != ((void*)0)", "src/switch_core_state_machine.c" , 783, __PRETTY_FUNCTION__)); |
| 784 | |
| 785 | driver_state_handler = endpoint_interface->state_handler; |
| 786 | switch_assert(driver_state_handler != NULL)((driver_state_handler != ((void*)0)) ? (void) (0) : __assert_fail ("driver_state_handler != ((void*)0)", "src/switch_core_state_machine.c" , 786, __PRETTY_FUNCTION__)); |
| 787 | |
| 788 | if (!zstr(var)_zstr(var)) { |
| 789 | if (!strcasecmp(var, "a_only")) { |
| 790 | if (switch_channel_get_originator_caller_profile(session->channel)) { |
| 791 | do_extra_handlers = 0; |
| 792 | } |
| 793 | } else if (!strcasecmp(var, "b_only")) { |
| 794 | if (switch_channel_get_originatee_caller_profile(session->channel)) { |
| 795 | do_extra_handlers = 0; |
| 796 | } |
| 797 | } else if (!switch_true(var)) { |
| 798 | do_extra_handlers = 0; |
| 799 | } |
| 800 | } |
| 801 | |
| 802 | |
| 803 | if (!zstr(skip_var)_zstr(skip_var)) { |
| 804 | int x, ttl = 0; |
| 805 | char *list[128] = { 0 }; |
| 806 | char *dup = switch_core_session_strdup(session, skip_var)switch_core_perform_session_strdup(session, skip_var, "src/switch_core_state_machine.c" , (const char *)__func__, 806); |
| 807 | |
| 808 | ttl = switch_split(dup, '|', list)switch_separate_string(dup, '|', list, (sizeof(list) / sizeof (list[0]))); |
| 809 | |
| 810 | for(x = 0; x < ttl; x++) { |
| 811 | if (switch_channel_str2cause(list[x]) == cause) { |
| 812 | do_extra_handlers = 0; |
| 813 | break; |
| 814 | } |
| 815 | } |
| 816 | } |
| 817 | |
| 818 | if (switch_channel_test_flag(session->channel, CF_NO_CDR)) { |
| 819 | do_extra_handlers = 0; |
| 820 | } |
| 821 | |
| 822 | |
| 823 | STATE_MACRO(reporting, "REPORTING")do { midstate = state; switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "src/switch_core_state_machine.c", (const char *)__func__, 823 , (const char*)(session), SWITCH_LOG_DEBUG, "(%s) State %s\n" , switch_channel_get_name(session->channel), "REPORTING"); if (state < CS_HANGUP && switch_channel_get_callstate (session->channel) == CCS_UNHELD) { switch_channel_perform_set_callstate (session->channel, CCS_ACTIVE, "src/switch_core_state_machine.c" , (const char *)__func__, 823); } switch_core_session_refresh_video (session); if (!driver_state_handler->on_reporting || (driver_state_handler ->on_reporting(session) == SWITCH_STATUS_SUCCESS )) { while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler (session->channel, index++)) != 0) { if (!application_state_handler || !application_state_handler->on_reporting || (application_state_handler ->on_reporting && application_state_handler->on_reporting (session) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } index = 0; if (!proceed) global_proceed = 0; proceed = 1; while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler (index++)) != 0) { if (!application_state_handler || !application_state_handler ->on_reporting || (application_state_handler->on_reporting && application_state_handler->on_reporting(session ) == SWITCH_STATUS_SUCCESS )) { proceed++; continue; } else { proceed = 0; break; } } if (!proceed || midstate != switch_channel_get_state (session->channel)) global_proceed = 0; if (global_proceed ) { switch_core_standard_on_reporting(session); } } switch_log_printf (SWITCH_CHANNEL_ID_SESSION, "src/switch_core_state_machine.c" , (const char *)__func__, 823, (const char*)(session), SWITCH_LOG_DEBUG , "(%s) State %s going to sleep\n", switch_channel_get_name(session ->channel), "REPORTING"); } while (silly); |
| 824 | |
| 825 | if ((hook_var = switch_channel_get_variable(session->channel, SWITCH_API_REPORTING_HOOK_VARIABLE)switch_channel_get_variable_dup(session->channel, "api_reporting_hook" , SWITCH_TRUE, -1))) { |
| 826 | |
| 827 | if (switch_true(switch_channel_get_variable(session->channel, SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE)switch_channel_get_variable_dup(session->channel, "session_in_hangup_hook" , SWITCH_TRUE, -1))) { |
| 828 | use_session = 1; |
| 829 | } |
| 830 | |
| 831 | api_hook(session, hook_var, use_session); |
| 832 | } |
| 833 | |
| 834 | if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE)switch_event_create_subclass_detailed("src/switch_core_state_machine.c" , (const char * )(const char *)__func__, 834, &event, SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
| 835 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hangup-Cause", switch_channel_cause2str(cause)); |
| 836 | switch_channel_event_set_data(session->channel, event); |
| 837 | if (switch_true(switch_channel_get_variable(session->channel, "hangup_complete_with_xml")switch_channel_get_variable_dup(session->channel, "hangup_complete_with_xml" , SWITCH_TRUE, -1))) { |
| 838 | switch_xml_t cdr = NULL((void*)0); |
| 839 | char *xml_cdr_text; |
| 840 | |
| 841 | if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) { |
| 842 | xml_cdr_text = switch_xml_toxml(cdr, SWITCH_FALSE); |
| 843 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Attached", "xml"); |
| 844 | switch_event_add_body(event, "%s", xml_cdr_text); |
| 845 | switch_xml_free(cdr); |
| 846 | switch_safe_free(xml_cdr_text)if (xml_cdr_text) {free(xml_cdr_text);xml_cdr_text=((void*)0) ;}; |
| 847 | } |
| 848 | } |
| 849 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_state_machine.c", (const char * )(const char *)__func__, 849, &event, ((void *)0)); |
| 850 | } |
| 851 | |
| 852 | |
| 853 | |
| 854 | return; |
| 855 | } |
| 856 | |
| 857 | /* For Emacs: |
| 858 | * Local Variables: |
| 859 | * mode:c |
| 860 | * indent-tabs-mode:t |
| 861 | * tab-width:4 |
| 862 | * c-basic-offset:4 |
| 863 | * End: |
| 864 | * For VIM: |
| 865 | * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: |
| 866 | */ |