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
switch_core_standard_on_init(switch_core_session_t * session)38 static void switch_core_standard_on_init(switch_core_session_t *session)
39 {
40 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(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);
44 } else {
45 if (switch_channel_test_flag(session->channel, CF_RECOVERING)) {
46 switch_channel_set_state(session->channel, CS_EXECUTE);
47 } else {
48 switch_channel_set_state(session->channel, CS_ROUTING);
49 }
50 }
51
52 switch_channel_clear_flag(session->channel, CF_RECOVERING);
53 }
54
switch_core_standard_on_hangup(switch_core_session_t * session)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_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 if (switch_true(switch_channel_get_variable(session->channel, "log_audio_stats_on_hangup"))) {
64 switch_rtp_stats_t *audio_stats = NULL;
65
66 switch_core_media_set_stats(session);
67 audio_stats = switch_core_media_get_stats(session, SWITCH_MEDIA_TYPE_AUDIO, switch_core_session_get_pool(session));
68 if (audio_stats) {
69 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
70 SWITCH_LOG_DEBUG,
71 "%s Call statistics:\n"
72 "in_raw_bytes: %d\n"
73 "in_media_bytes: %d\n"
74 "in_packet_count: %d\n"
75 "in_media_packet_count: %d\n"
76 "in_skip_packet_count: %d\n"
77 "in_jitter_packet_count: %d\n"
78 "in_dtmf_packet_count: %d\n"
79 "in_cng_packet_count: %d\n"
80 "in_flush_packet_count: %d\n"
81 "in_largest_jb_size: %d\n\n"
82 "in_jitter_min_variance: %lf\n"
83 "in_jitter_max_variance: %lf\n"
84 "in_jitter_loss_rate: %lf\n"
85 "in_jitter_burst_rate: %lf\n"
86 "in_mean_interval: %lf\n\n"
87 "in_flaw_total: %d\n"
88 "in_quality_percentage: %lf\n"
89 "in_mos: %lf\n\n"
90 "out_raw_bytes: %d\n"
91 "out_media_bytes: %d\n"
92 "out_packet_count: %d\n"
93 "out_media_packet_count: %d\n"
94 "out_skip_packet_count: %d\n"
95 "out_dtmf_packet_count: %d\n"
96 "out_cng_packet_count: %d\n\n"
97 "rtcp_packet_count: %d\n"
98 "rtcp_octet_count: %d\n",
99 switch_channel_get_name(session->channel),
100 (int)audio_stats->inbound.raw_bytes,
101 (int)audio_stats->inbound.media_bytes,
102 (int)audio_stats->inbound.packet_count,
103 (int)audio_stats->inbound.media_packet_count,
104 (int)audio_stats->inbound.skip_packet_count,
105 (int)audio_stats->inbound.jb_packet_count,
106 (int)audio_stats->inbound.dtmf_packet_count,
107 (int)audio_stats->inbound.cng_packet_count,
108 (int)audio_stats->inbound.flush_packet_count,
109 (int)audio_stats->inbound.largest_jb_size,
110 audio_stats->inbound.min_variance,
111 audio_stats->inbound.max_variance,
112 audio_stats->inbound.lossrate,
113 audio_stats->inbound.burstrate,
114 audio_stats->inbound.mean_interval,
115 (int)audio_stats->inbound.flaws,
116 audio_stats->inbound.R,
117 audio_stats->inbound.mos,
118 (int)audio_stats->outbound.raw_bytes,
119 (int)audio_stats->outbound.media_bytes,
120 (int)audio_stats->outbound.packet_count,
121 (int)audio_stats->outbound.media_packet_count,
122 (int)audio_stats->outbound.skip_packet_count,
123 (int)audio_stats->outbound.dtmf_packet_count,
124 (int)audio_stats->outbound.cng_packet_count,
125 (int)audio_stats->rtcp.packet_count,
126 (int)audio_stats->rtcp.octet_count
127 );
128 } else {
129 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Missing call statistics!\n",
130 switch_channel_get_name(session->channel));
131 }
132 }
133
134 rec = switch_channel_test_flag(session->channel, CF_RECOVERING);
135 switch_channel_clear_flag(session->channel, CF_RECOVERING);
136
137 if (!rec) {
138 switch_core_recovery_untrack(session, SWITCH_TRUE);
139 }
140
141
142 if (!switch_channel_test_flag(session->channel, CF_ZOMBIE_EXEC)) {
143 return;
144 }
145
146 if ((extension = switch_channel_get_caller_extension(session->channel)) == 0) {
147 return;
148 }
149
150 while(extension->current_application) {
151 switch_caller_application_t *current_application = extension->current_application;
152 switch_status_t status;
153
154 extension->current_application = extension->current_application->next;
155
156 status = switch_core_session_execute_application(session,
157 current_application->application_name, current_application->application_data);
158
159
160 if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_IGNORE) {
161 return;
162 }
163 }
164
165
166
167
168
169 }
170
switch_core_standard_on_reporting(switch_core_session_t * session)171 static void switch_core_standard_on_reporting(switch_core_session_t *session)
172 {
173
174 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard REPORTING, cause: %s\n",
175 switch_channel_get_name(session->channel), switch_channel_cause2str(switch_channel_get_cause(session->channel)));
176 }
177
switch_core_standard_on_destroy(switch_core_session_t * session)178 static void switch_core_standard_on_destroy(switch_core_session_t *session)
179 {
180
181 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard DESTROY\n", switch_channel_get_name(session->channel));
182 }
183
switch_core_standard_on_reset(switch_core_session_t * session)184 static void switch_core_standard_on_reset(switch_core_session_t *session)
185 {
186 switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session));
187
188 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard RESET\n", switch_channel_get_name(session->channel));
189
190 if (switch_channel_test_flag(session->channel, CF_RECOVERING_BRIDGE)) {
191 switch_core_session_t *other_session = NULL;
192 const char *uuid = switch_core_session_get_uuid(session);
193
194 if (switch_channel_test_flag(session->channel, CF_BRIDGE_ORIGINATOR)) {
195 const char *other_uuid = switch_channel_get_partner_uuid(session->channel);
196 int x = 0;
197
198 if (other_uuid) {
199 for (x = 0; other_session == NULL && x < 20; x++) {
200 if (!switch_channel_up(session->channel)) {
201 break;
202 }
203 other_session = switch_core_session_locate(other_uuid);
204 switch_yield(100000);
205 }
206 }
207
208 if (other_session) {
209 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
210 switch_channel_clear_flag(session->channel, CF_BRIDGE_ORIGINATOR);
211 switch_channel_wait_for_state_timeout(other_channel, CS_RESET, 5000);
212 switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 2000, NULL);
213
214 if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) && switch_channel_test_flag(other_channel, CF_PROXY_MODE)) {
215 switch_ivr_signal_bridge(session, other_session);
216 } else {
217 switch_ivr_uuid_bridge(uuid, other_uuid);
218 }
219 switch_core_session_rwunlock(other_session);
220 }
221 }
222
223 switch_channel_clear_flag(session->channel, CF_RECOVERING_BRIDGE);
224 }
225
226 }
227
switch_core_standard_on_routing(switch_core_session_t * session)228 static void switch_core_standard_on_routing(switch_core_session_t *session)
229 {
230 switch_dialplan_interface_t *dialplan_interface = NULL;
231 switch_caller_profile_t *caller_profile;
232 switch_caller_extension_t *extension = NULL;
233 char *expanded = NULL;
234 char *dpstr = NULL;
235
236 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard ROUTING\n", switch_channel_get_name(session->channel));
237
238 switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session));
239
240 if ((switch_channel_test_flag(session->channel, CF_ANSWERED) ||
241 switch_channel_test_flag(session->channel, CF_EARLY_MEDIA) ||
242 switch_channel_test_flag(session->channel, CF_SIGNAL_BRIDGE_TTL)) && switch_channel_test_flag(session->channel, CF_PROXY_MODE)) {
243 switch_ivr_media(session->uuid_str, SMF_NONE);
244 }
245
246 if ((caller_profile = switch_channel_get_caller_profile(session->channel)) == 0) {
247 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't get profile!\n");
248 switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
249 return;
250 } else {
251 char *dp[25];
252 int argc, x, count = 0;
253
254 if ((extension = switch_channel_get_queued_extension(session->channel))) {
255 switch_channel_set_caller_extension(session->channel, extension);
256 switch_channel_set_state(session->channel, CS_EXECUTE);
257 goto end;
258 }
259
260 if (!zstr(caller_profile->dialplan)) {
261 if ((dpstr = switch_core_session_strdup(session, caller_profile->dialplan))) {
262 expanded = switch_channel_expand_variables(session->channel, dpstr);
263 argc = switch_separate_string(expanded, ',', dp, (sizeof(dp) / sizeof(dp[0])));
264 for (x = 0; x < argc; x++) {
265 char *dpname = dp[x];
266 char *dparg = NULL;
267
268 if (dpname) {
269 if ((dparg = strchr(dpname, ':'))) {
270 *dparg++ = '\0';
271 }
272 } else {
273 continue;
274 }
275 if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) {
276 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Dialplan [%s] not found, skipping\n", dpname);
277 continue;
278 }
279
280 count++;
281
282 extension = dialplan_interface->hunt_function(session, dparg, NULL);
283 UNPROTECT_INTERFACE(dialplan_interface);
284
285 if (extension) {
286 switch_channel_set_caller_extension(session->channel, extension);
287 switch_channel_set_state(session->channel, CS_EXECUTE);
288 goto end;
289 }
290 }
291 }
292 }
293
294 if (!count) {
295 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
296 if (switch_channel_test_flag(session->channel, CF_ANSWERED)) {
297 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
298 "No Dialplan on answered channel, changing state to HANGUP\n");
299 switch_channel_hangup(session->channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION);
300 } else {
301 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No Dialplan, changing state to CONSUME_MEDIA\n");
302 switch_channel_set_state(session->channel, CS_CONSUME_MEDIA);
303 }
304 goto end;
305 }
306 }
307 }
308
309 if (!extension) {
310
311 if (switch_ivr_blind_transfer_ack(session, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
312 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No Route, Aborting\n");
313 switch_channel_hangup(session->channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION);
314 }
315 }
316
317 end:
318
319 if (expanded && dpstr && expanded != dpstr) {
320 free(expanded);
321 }
322 }
323
switch_core_standard_on_execute(switch_core_session_t * session)324 static void switch_core_standard_on_execute(switch_core_session_t *session)
325 {
326 switch_caller_extension_t *extension;
327 const char *uuid;
328
329 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard EXECUTE\n", switch_channel_get_name(session->channel));
330
331 switch_channel_clear_flag(session->channel, CF_RECOVERING);
332
333 switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session));
334
335 if (switch_channel_get_variable(session->channel, "recovered") && !switch_channel_test_flag(session->channel, CF_RECOVERED)) {
336 switch_channel_set_flag(session->channel, CF_RECOVERED);
337 }
338
339 top:
340 switch_channel_clear_flag(session->channel, CF_RESET);
341
342 switch_core_session_video_reset(session);
343
344 if ((extension = switch_channel_get_caller_extension(session->channel)) == 0) {
345 switch_channel_hangup(session->channel, SWITCH_CAUSE_NORMAL_CLEARING);
346 return;
347 }
348
349 while (switch_channel_get_state(session->channel) == CS_EXECUTE && extension->current_application) {
350 switch_caller_application_t *current_application = extension->current_application;
351
352 extension->current_application = extension->current_application->next;
353
354 if (switch_core_session_execute_application(session,
355 current_application->application_name,
356 current_application->application_data) != SWITCH_STATUS_SUCCESS) {
357 return;
358 }
359
360 if (switch_channel_test_flag(session->channel, CF_RESET)) {
361 goto top;
362 }
363
364 }
365
366 if (switch_channel_ready(session->channel) && switch_channel_get_state(session->channel) == CS_EXECUTE &&
367 switch_channel_test_flag(session->channel, CF_CONFIRM_BLIND_TRANSFER) &&
368 (uuid = switch_channel_get_variable(session->channel, "blind_transfer_uuid"))) {
369 switch_core_session_t *other_session;
370
371 if ((other_session = switch_core_session_locate(uuid))) {
372 switch_core_session_message_t msg = { 0 };
373 msg.message_id = SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE;
374 msg.from = __FILE__;
375 msg.numeric_arg = 0;
376 switch_core_session_receive_message(other_session, &msg);
377 switch_core_session_rwunlock(other_session);
378
379 switch_channel_set_variable(session->channel, "park_timeout", "10:blind_transfer");
380 switch_channel_set_state(session->channel, CS_PARK);
381 switch_channel_clear_flag(session->channel, CF_CONFIRM_BLIND_TRANSFER);
382 }
383 }
384
385 if (switch_channel_ready(session->channel) && switch_channel_get_state(session->channel) == CS_EXECUTE) {
386 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "%s has executed the last dialplan instruction, hanging up.\n",
387 switch_channel_get_name(session->channel));
388 switch_channel_hangup(session->channel, SWITCH_CAUSE_NORMAL_CLEARING);
389 }
390 }
391
switch_core_standard_on_exchange_media(switch_core_session_t * session)392 static void switch_core_standard_on_exchange_media(switch_core_session_t *session)
393 {
394
395 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard EXCHANGE_MEDIA\n", switch_channel_get_name(session->channel));
396 }
397
switch_core_standard_on_soft_execute(switch_core_session_t * session)398 static void switch_core_standard_on_soft_execute(switch_core_session_t *session)
399 {
400 switch_assert(session != NULL);
401 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard SOFT_EXECUTE\n", switch_channel_get_name(session->channel));
402 }
403
switch_core_standard_on_park(switch_core_session_t * session)404 static void switch_core_standard_on_park(switch_core_session_t *session)
405 {
406 switch_assert(session != NULL);
407 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard PARK\n", switch_channel_get_name(session->channel));
408 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
409 switch_ivr_park(session, NULL);
410 }
411
switch_core_standard_on_consume_media(switch_core_session_t * session)412 static void switch_core_standard_on_consume_media(switch_core_session_t *session)
413 {
414 switch_assert(session != NULL);
415 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard CONSUME_MEDIA\n", switch_channel_get_name(session->channel));
416 }
417
switch_core_standard_on_hibernate(switch_core_session_t * session)418 static void switch_core_standard_on_hibernate(switch_core_session_t *session)
419 {
420 switch_assert(session != NULL);
421 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard HIBERNATE\n", switch_channel_get_name(session->channel));
422 }
423
switch_core_state_machine_init(switch_memory_pool_t * pool)424 void switch_core_state_machine_init(switch_memory_pool_t *pool)
425 {
426 return;
427 }
428
429 #define STATE_MACRO(__STATE, __STATE_STR) do { \
430 midstate = state; \
431 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) State %s\n", switch_channel_get_name(session->channel), __STATE_STR); \
432 if (state < CS_HANGUP && switch_channel_get_callstate(session->channel) == CCS_UNHELD) { \
433 switch_channel_set_callstate(session->channel, CCS_ACTIVE); \
434 } \
435 switch_core_session_request_video_refresh(session); \
436 switch_core_media_gen_key_frame(session); \
437 proceed = 1; \
438 while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler(session->channel, index++)) != 0) { \
439 if (!switch_test_flag(application_state_handler, SSH_FLAG_PRE_EXEC)) {\
440 continue; \
441 } \
442 if (!application_state_handler->on_##__STATE \
443 || (application_state_handler->on_##__STATE \
444 && application_state_handler->on_##__STATE(session) == SWITCH_STATUS_SUCCESS \
445 )) { \
446 proceed++; \
447 continue; \
448 } else { \
449 proceed = 0; \
450 break; \
451 } \
452 } \
453 index = 0; \
454 if (!proceed) global_proceed = 0; \
455 proceed = 1; \
456 while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler(index++)) != 0) { \
457 if (!switch_test_flag(application_state_handler, SSH_FLAG_PRE_EXEC)) { \
458 continue; \
459 } \
460 if (!application_state_handler->on_##__STATE || \
461 (application_state_handler->on_##__STATE && \
462 application_state_handler->on_##__STATE(session) == SWITCH_STATUS_SUCCESS \
463 )) { \
464 proceed++; \
465 continue; \
466 } else { \
467 proceed = 0; \
468 break; \
469 } \
470 } \
471 index = 0; \
472 if (!proceed) global_proceed = 0; \
473 if (!driver_state_handler->on_##__STATE || (driver_state_handler->on_##__STATE(session) == SWITCH_STATUS_SUCCESS )) { \
474 while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler(session->channel, index++)) != 0) { \
475 if (switch_test_flag(application_state_handler, SSH_FLAG_PRE_EXEC)) { \
476 continue; \
477 } \
478 if (!application_state_handler->on_##__STATE \
479 || (application_state_handler->on_##__STATE \
480 && application_state_handler->on_##__STATE(session) == SWITCH_STATUS_SUCCESS \
481 )) { \
482 proceed++; \
483 continue; \
484 } else { \
485 proceed = 0; \
486 break; \
487 } \
488 } \
489 index = 0; \
490 if (!proceed) global_proceed = 0; \
491 proceed = 1; \
492 while (do_extra_handlers && proceed && (application_state_handler = switch_core_get_state_handler(index++)) != 0) { \
493 if (switch_test_flag(application_state_handler, SSH_FLAG_PRE_EXEC)) { \
494 continue; \
495 } \
496 if (!application_state_handler->on_##__STATE || \
497 (application_state_handler->on_##__STATE && \
498 application_state_handler->on_##__STATE(session) == SWITCH_STATUS_SUCCESS \
499 )) { \
500 proceed++; \
501 continue; \
502 } else { \
503 proceed = 0; \
504 break; \
505 } \
506 } \
507 if (!proceed || midstate != switch_channel_get_state(session->channel)) global_proceed = 0; \
508 if (global_proceed) { \
509 switch_core_standard_on_##__STATE(session); \
510 } \
511 } \
512 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) State %s going to sleep\n", switch_channel_get_name(session->channel), __STATE_STR); \
513 } while (silly)
514
515
check_presence(switch_core_session_t * session)516 static void check_presence(switch_core_session_t *session)
517 {
518 switch_channel_state_t state = switch_channel_get_running_state(session->channel);
519
520 if (state == CS_ROUTING || state == CS_HANGUP) {
521 if (switch_channel_get_cause(session->channel) == SWITCH_CAUSE_LOSE_RACE) {
522 switch_channel_presence(session->channel, "unknown", "cancelled", NULL);
523 switch_channel_set_variable(session->channel, "presence_call_info", NULL);
524 } else {
525 switch_channel_presence(session->channel, "unknown", switch_channel_state_name(state), NULL);
526 }
527 }
528 }
529
530
531
switch_core_session_run(switch_core_session_t * session)532 SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
533 {
534 switch_channel_state_t state = CS_NEW, midstate = CS_DESTROY, endstate;
535 const switch_endpoint_interface_t *endpoint_interface;
536 const switch_state_handler_table_t *driver_state_handler = NULL;
537 const switch_state_handler_table_t *application_state_handler = NULL;
538 int silly = 0;
539 uint32_t new_loops = 500;
540
541 /*
542 Life of the channel. you have channel and pool in your session
543 everywhere you go you use the session to malloc with
544 switch_core_session_alloc(session, <size>)
545
546 The endpoint module gets the first crack at implementing the state
547 if it wants to, it can cancel the default behavior by returning SWITCH_STATUS_FALSE
548
549 Next comes the channel's event handler table that can be set by an application
550 which also can veto the next behavior in line by returning SWITCH_STATUS_FALSE
551
552 Finally the default state behavior is called.
553
554
555 */
556 switch_assert(session != NULL);
557
558 switch_set_flag(session, SSF_THREAD_RUNNING);
559 endpoint_interface = session->endpoint_interface;
560 switch_assert(endpoint_interface != NULL);
561
562 driver_state_handler = endpoint_interface->state_handler;
563 switch_assert(driver_state_handler != NULL);
564
565 switch_mutex_lock(session->mutex);
566
567 while ((state = switch_channel_get_state(session->channel)) != CS_DESTROY) {
568
569 if (switch_channel_test_flag(session->channel, CF_BLOCK_STATE)) {
570 switch_channel_wait_for_flag(session->channel, CF_BLOCK_STATE, SWITCH_FALSE, 0, NULL);
571 if ((state = switch_channel_get_state(session->channel)) == CS_DESTROY) {
572 break;
573 }
574 }
575
576 midstate = state;
577 if (state != switch_channel_get_running_state(session->channel) || state >= CS_HANGUP) {
578 int index = 0;
579 int proceed = 1;
580 int global_proceed = 1;
581 int do_extra_handlers = 1;
582 switch_io_event_hook_state_run_t *ptr;
583 switch_status_t rstatus = SWITCH_STATUS_SUCCESS;
584
585 switch_channel_set_running_state(session->channel, state);
586 switch_channel_clear_flag(session->channel, CF_TRANSFER);
587 switch_channel_clear_flag(session->channel, CF_REDIRECT);
588 switch_ivr_parse_all_messages(session);
589
590 if (session->endpoint_interface->io_routines->state_run) {
591 rstatus = session->endpoint_interface->io_routines->state_run(session);
592 }
593
594 if (rstatus == SWITCH_STATUS_SUCCESS) {
595 for (ptr = session->event_hooks.state_run; ptr; ptr = ptr->next) {
596 if ((rstatus = ptr->state_run(session)) != SWITCH_STATUS_SUCCESS) {
597 break;
598 }
599 }
600 }
601
602 switch (state) {
603 case CS_NEW: /* Just created, Waiting for first instructions */
604 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) State NEW\n", switch_channel_get_name(session->channel));
605 break;
606 case CS_DESTROY:
607 goto done;
608 case CS_REPORTING: /* Call Detail */
609 {
610 switch_core_session_reporting_state(session);
611 switch_channel_set_state(session->channel, CS_DESTROY);
612 }
613 goto done;
614 case CS_HANGUP: /* Deactivate and end the thread */
615 {
616 switch_core_session_hangup_state(session, SWITCH_TRUE);
617 if (switch_channel_test_flag(session->channel, CF_VIDEO)) {
618 switch_core_session_wake_video_thread(session);
619 }
620 switch_channel_set_state(session->channel, CS_REPORTING);
621 }
622
623 break;
624 case CS_INIT: /* Basic setup tasks */
625 {
626 switch_event_t *event;
627
628 STATE_MACRO(init, "INIT");
629
630 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_CREATE) == SWITCH_STATUS_SUCCESS) {
631 switch_channel_event_set_data(session->channel, event);
632 switch_event_fire(&event);
633 }
634
635 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
636 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_ORIGINATE) == SWITCH_STATUS_SUCCESS) {
637 switch_channel_event_set_data(session->channel, event);
638 switch_event_fire(&event);
639 }
640 }
641 }
642 break;
643 case CS_ROUTING: /* Look for a dialplan and find something to do */
644 STATE_MACRO(routing, "ROUTING");
645 break;
646 case CS_RESET: /* Reset */
647 STATE_MACRO(reset, "RESET");
648 break;
649 /* These other states are intended for prolonged durations so we do not signal lock for them */
650 case CS_EXECUTE: /* Execute an Operation */
651 STATE_MACRO(execute, "EXECUTE");
652 break;
653 case CS_EXCHANGE_MEDIA: /* loop all data back to source */
654 STATE_MACRO(exchange_media, "EXCHANGE_MEDIA");
655 break;
656 case CS_SOFT_EXECUTE: /* send/recieve data to/from another channel */
657 STATE_MACRO(soft_execute, "SOFT_EXECUTE");
658 break;
659 case CS_PARK: /* wait in limbo */
660 STATE_MACRO(park, "PARK");
661 break;
662 case CS_CONSUME_MEDIA: /* wait in limbo */
663 STATE_MACRO(consume_media, "CONSUME_MEDIA");
664 break;
665 case CS_HIBERNATE: /* sleep */
666 STATE_MACRO(hibernate, "HIBERNATE");
667 break;
668 case CS_NONE:
669 abort();
670 break;
671 }
672
673 check_presence(session);
674
675 if (midstate == CS_DESTROY) {
676 break;
677 }
678
679 }
680
681 endstate = switch_channel_get_state(session->channel);
682
683 if (endstate == switch_channel_get_running_state(session->channel)) {
684 if (endstate == CS_NEW) {
685 switch_yield(20000);
686 switch_ivr_parse_all_events(session);
687 if (!--new_loops) {
688 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s %s Abandoned\n",
689 session->uuid_str, switch_core_session_get_name(session));
690 switch_channel_set_flag(session->channel, CF_NO_CDR);
691 switch_channel_hangup(session->channel, SWITCH_CAUSE_WRONG_CALL_STATE);
692 }
693 } else {
694 switch_channel_state_thread_lock(session->channel);
695
696 switch_ivr_parse_all_events(session);
697
698 if (switch_channel_test_flag(session->channel, CF_STATE_REPEAT)) {
699 switch_channel_clear_flag(session->channel, CF_STATE_REPEAT);
700 } else if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) {
701 switch_channel_set_flag(session->channel, CF_THREAD_SLEEPING);
702 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s session thread sleep state: %s!\n",
703 switch_channel_get_name(session->channel),
704 switch_channel_state_name(switch_channel_get_running_state(session->channel)));
705 switch_thread_cond_wait(session->cond, session->mutex);
706 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s session thread wake state: %s!\n",
707 switch_channel_get_name(session->channel),
708 switch_channel_state_name(switch_channel_get_running_state(session->channel)));
709 switch_channel_clear_flag(session->channel, CF_THREAD_SLEEPING);
710 }
711
712 switch_channel_state_thread_unlock(session->channel);
713
714 switch_ivr_parse_all_events(session);
715 }
716 }
717 }
718 done:
719 switch_mutex_unlock(session->mutex);
720
721 switch_clear_flag(session, SSF_THREAD_RUNNING);
722 }
723
switch_core_session_destroy_state(switch_core_session_t * session)724 SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *session)
725 {
726 switch_channel_state_t state = CS_DESTROY, midstate = CS_DESTROY;
727 const switch_endpoint_interface_t *endpoint_interface;
728 const switch_state_handler_table_t *driver_state_handler = NULL;
729 const switch_state_handler_table_t *application_state_handler = NULL;
730 int proceed = 1;
731 int global_proceed = 1;
732 int do_extra_handlers = 1;
733 int silly = 0;
734 int index = 0;
735
736 switch_channel_set_callstate(session->channel, CCS_DOWN);
737
738 switch_assert(session != NULL);
739 switch_channel_set_running_state(session->channel, CS_DESTROY);
740 switch_channel_clear_flag(session->channel, CF_TRANSFER);
741 switch_channel_clear_flag(session->channel, CF_REDIRECT);
742
743 endpoint_interface = session->endpoint_interface;
744 switch_assert(endpoint_interface != NULL);
745
746 driver_state_handler = endpoint_interface->state_handler;
747 switch_assert(driver_state_handler != NULL);
748
749 STATE_MACRO(destroy, "DESTROY");
750
751 switch_channel_clear_device_record(session->channel);
752
753 return;
754 }
755
api_hook(switch_core_session_t * session,const char * hook_var,int use_session)756 static void api_hook(switch_core_session_t *session, const char *hook_var, int use_session)
757 {
758 if (!zstr(hook_var)) {
759 switch_stream_handle_t stream = { 0 };
760 char *cmd = strdup(hook_var);
761 char *arg = NULL;
762 char *expanded = NULL;
763
764 if ((arg = strchr(cmd, ':')) && *(arg + 1) == ':') {
765 *arg++ = '\0';
766 *arg++ = '\0';
767 } else {
768 if ((arg = strchr(cmd, ' '))) {
769 *arg++ = '\0';
770 }
771 }
772
773 SWITCH_STANDARD_STREAM(stream);
774
775 switch_channel_get_variables(session->channel, &stream.param_event);
776 switch_channel_event_set_data(session->channel, stream.param_event);
777 expanded = switch_event_expand_headers(stream.param_event, arg);
778
779 switch_api_execute(cmd, expanded, use_session ? session : NULL, &stream);
780
781 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Hangup Command %s %s(%s):\n%s\n",
782 use_session ? "with Session" : "with no Session", cmd, switch_str_nil(expanded),
783 switch_str_nil((char *) stream.data) );
784
785 if (expanded != arg) {
786 switch_safe_free(expanded);
787 }
788
789 switch_safe_free(cmd);
790
791 switch_safe_free(stream.data);
792 }
793 }
794
795
796
switch_core_session_hangup_state(switch_core_session_t * session,switch_bool_t force)797 SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session, switch_bool_t force)
798 {
799 switch_call_cause_t cause = switch_channel_get_cause(session->channel);
800 switch_call_cause_t cause_q850 = switch_channel_get_cause_q850(session->channel);
801 int proceed = 1;
802 int global_proceed = 1;
803 int do_extra_handlers = 1;
804 int silly = 0;
805 int index = 0;
806 switch_channel_state_t state = switch_channel_get_state(session->channel), midstate;
807 const switch_endpoint_interface_t *endpoint_interface;
808 const switch_state_handler_table_t *driver_state_handler = NULL;
809 const switch_state_handler_table_t *application_state_handler = NULL;
810 const char *hook_var;
811 int use_session = 0;
812
813 if (!force) {
814 if (!switch_channel_test_flag(session->channel, CF_EARLY_HANGUP) && !switch_test_flag((&runtime), SCF_EARLY_HANGUP)) {
815 return;
816 }
817
818 if (switch_thread_self() != session->thread_id) {
819 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s thread mismatch skipping state handler.\n",
820 switch_channel_get_name(session->channel));
821 return;
822 }
823 }
824
825 if (switch_test_flag(session, SSF_HANGUP)) {
826 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s handler already called, skipping state handler.\n",
827 switch_channel_get_name(session->channel));
828 return;
829 }
830
831 endpoint_interface = session->endpoint_interface;
832 switch_assert(endpoint_interface != NULL);
833
834 driver_state_handler = endpoint_interface->state_handler;
835 switch_assert(driver_state_handler != NULL);
836
837 switch_channel_set_hangup_time(session->channel);
838
839 switch_core_media_bug_remove_all(session);
840
841 switch_channel_stop_broadcast(session->channel);
842
843 switch_channel_set_variable(session->channel, "hangup_cause", switch_channel_cause2str(cause));
844 switch_channel_set_variable_printf(session->channel, "hangup_cause_q850", "%d", cause_q850);
845 //switch_channel_presence(session->channel, "unknown", switch_channel_cause2str(cause), NULL);
846
847 switch_channel_set_timestamps(session->channel);
848 switch_channel_set_callstate(session->channel, CCS_HANGUP);
849
850 STATE_MACRO(hangup, "HANGUP");
851
852 switch_core_media_set_stats(session);
853
854 if ((hook_var = switch_channel_get_variable(session->channel, SWITCH_API_HANGUP_HOOK_VARIABLE))) {
855
856 if (switch_true(switch_channel_get_variable(session->channel, SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE))) {
857 use_session = 1;
858 }
859
860 api_hook(session, hook_var, use_session);
861 }
862
863 switch_channel_process_device_hangup(session->channel);
864
865 switch_set_flag(session, SSF_HANGUP);
866
867 }
868
switch_core_session_reporting_state(switch_core_session_t * session)869 SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t *session)
870 {
871 switch_channel_state_t state = switch_channel_get_state(session->channel), midstate;
872 const switch_endpoint_interface_t *endpoint_interface;
873 const switch_state_handler_table_t *driver_state_handler = NULL;
874 const switch_state_handler_table_t *application_state_handler = NULL;
875 int proceed = 1;
876 int global_proceed = 1;
877 int do_extra_handlers = 1;
878 int silly = 0;
879 int index = 0;
880 const char *var = switch_channel_get_variable(session->channel, SWITCH_PROCESS_CDR_VARIABLE);
881 const char *skip_var = switch_channel_get_variable(session->channel, SWITCH_SKIP_CDR_CAUSES_VARIABLE);
882 const char *hook_var;
883 int use_session = 0;
884 switch_event_t *event;
885 switch_call_cause_t cause = switch_channel_get_cause(session->channel);
886
887 if (switch_channel_test_flag(session->channel, CF_REPORTING)) {
888 return;
889 }
890
891 switch_channel_set_flag(session->channel, CF_REPORTING);
892
893 switch_assert(session != NULL);
894
895 endpoint_interface = session->endpoint_interface;
896 switch_assert(endpoint_interface != NULL);
897
898 driver_state_handler = endpoint_interface->state_handler;
899 switch_assert(driver_state_handler != NULL);
900
901 if (!zstr(var)) {
902 if (!strcasecmp(var, "a_only")) {
903 if (switch_channel_get_originator_caller_profile(session->channel)) {
904 do_extra_handlers = 0;
905 }
906 } else if (!strcasecmp(var, "b_only")) {
907 if (switch_channel_get_originatee_caller_profile(session->channel)) {
908 do_extra_handlers = 0;
909 }
910 } else if (!switch_true(var)) {
911 do_extra_handlers = 0;
912 }
913 }
914
915
916 if (!zstr(skip_var)) {
917 int x, ttl = 0;
918 char *list[128] = { 0 };
919 char *dup = switch_core_session_strdup(session, skip_var);
920
921 ttl = switch_split(dup, '|', list);
922
923 for(x = 0; x < ttl; x++) {
924 if (switch_channel_str2cause(list[x]) == cause) {
925 do_extra_handlers = 0;
926 break;
927 }
928 }
929 }
930
931 if (switch_channel_test_flag(session->channel, CF_NO_CDR)) {
932 do_extra_handlers = 0;
933 }
934
935
936 STATE_MACRO(reporting, "REPORTING");
937
938 if ((hook_var = switch_channel_get_variable(session->channel, SWITCH_API_REPORTING_HOOK_VARIABLE))) {
939
940 if (switch_true(switch_channel_get_variable(session->channel, SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE))) {
941 use_session = 1;
942 }
943
944 api_hook(session, hook_var, use_session);
945 }
946
947 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE) == SWITCH_STATUS_SUCCESS) {
948 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hangup-Cause", switch_channel_cause2str(cause));
949 switch_channel_event_set_data(session->channel, event);
950 if (switch_true(switch_channel_get_variable(session->channel, "hangup_complete_with_xml"))) {
951 switch_xml_t cdr = NULL;
952 char *xml_cdr_text;
953
954 if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) {
955 xml_cdr_text = switch_xml_toxml(cdr, SWITCH_FALSE);
956 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Attached", "xml");
957 switch_event_add_body(event, "%s", xml_cdr_text);
958 switch_xml_free(cdr);
959 switch_safe_free(xml_cdr_text);
960 }
961 }
962 switch_event_fire(&event);
963 }
964
965
966
967 return;
968 }
969
970 /* For Emacs:
971 * Local Variables:
972 * mode:c
973 * indent-tabs-mode:t
974 * tab-width:4
975 * c-basic-offset:4
976 * End:
977 * For VIM:
978 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
979 */
980