File: | src/switch_core_state_machine.c |
Location: | line 693, 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; |
Value stored to 'midstate' during its initialization is never read | |
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; |
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 | */ |