rendered paste body04280 {04281 int reps = 0, errs = 0, match = 0, running = 1;04282 char *greeting_sound = NULL, *aptr = NULL;04283 char arg[512];04284 switch_ivr_action_t todo = SWITCH_IVR_ACTION_DIE;04285 switch_ivr_menu_action_t *ap;04286 switch_ivr_menu_t *menu;04287 switch_channel_t *channel;04288 switch_status_t status = SWITCH_STATUS_SUCCESS;04289 04290 if (session == NULL || stack == NULL || switch_strlen_zero(name)) {04291 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid menu context\n");04292 return SWITCH_STATUS_FALSE;04293 }04294 04295 channel = switch_core_session_get_channel(session);04296 assert(channel != NULL);04297 04298 if (!(menu = switch_ivr_menu_find(stack, name))) {04299 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Menu!\n");04300 return SWITCH_STATUS_FALSE;04301 }04302 04303 if (!(menu->buf = malloc(menu->inlen))) {04304 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Memory!\n");04305 return SWITCH_STATUS_FALSE;04306 }04307 04308 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Executing IVR menu %s\n", menu->name);04309 04310 for (reps = 0 ; (running && status == SWITCH_STATUS_SUCCESS && errs < menu->max_failures) ; reps++) {04311 if (!switch_channel_ready(channel)) {04312 break;04313 }04314 04315 if (reps > 0 && menu->short_greeting_sound) {04316 greeting_sound = menu->short_greeting_sound;04317 } else {04318 greeting_sound = menu->greeting_sound;04319 }04320 04321 match = 0;04322 aptr = NULL;04323 04324 memset(arg, 0, sizeof(arg));04325 04326 memset(menu->buf, 0, menu->inlen);04327 status = play_or_say(session, menu, greeting_sound, menu->inlen - 1);04328 04329 if (!switch_strlen_zero(menu->buf)) {04330 for(ap = menu->actions; ap ; ap = ap->next) {04331 if (!strcmp(menu->buf, ap->bind)) {04332 char *membuf;04333 04334 match++;04335 errs = 0;04336 if (ap->function) {04337 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IVR function on menu '%s' matched '%s' param '%s'\n", menu->name, menu->buf, ap->arg);04338 todo = ap->function(menu, ap->arg, arg, sizeof(arg), obj);04339 aptr = arg;04340 } else {04341 todo = ap->ivr_action;04342 aptr = ap->arg;04343 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IVR action on menu '%s' matched '%s' param '%s'\n", menu->name, menu->buf,aptr);04344 }04345 04346 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "switch_ivr_menu_execute todo=[%d]\n", todo);04347 04348 switch(todo) {04349 case SWITCH_IVR_ACTION_DIE:04350 status = SWITCH_STATUS_FALSE;04351 break;04352 case SWITCH_IVR_ACTION_PLAYSOUND:04353 status = switch_ivr_play_file(session, NULL, aptr, NULL);04354 break;04355 case SWITCH_IVR_ACTION_SAYTEXT:04356 status = switch_ivr_speak_text(session, menu->tts_engine, menu->tts_voice, 0, aptr, NULL);04357 break;04358 case SWITCH_IVR_ACTION_SAYPHRASE:04359 status = switch_ivr_phrase_macro(session, aptr, "", menu->phrase_lang, NULL);04360 break;04361 case SWITCH_IVR_ACTION_TRANSFER:04362 switch_ivr_session_transfer(session, aptr, NULL, NULL);04363 running = 0;04364 break;04365 case SWITCH_IVR_ACTION_EXECMENU:04366 reps = -1;04367 status = switch_ivr_menu_execute(session, stack, aptr, obj);04368 break;04369 case SWITCH_IVR_ACTION_EXECAPP: {04370 const switch_application_interface_t *application_interface;04371 04372 if ((membuf = strdup(aptr))) {04373 char *app_name = membuf;04374 char *app_arg = strchr(app_name, ' ');04375 04376 if (app_arg) {04377 *app_arg = '\0';04378 app_arg++;04379 }04380 04381 if (app_name && app_arg) {04382 if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {04383 if (application_interface->application_function) {04384 application_interface->application_function(session, app_arg);04385 }04386 }04387 }04388 }04389 }04390 break;04391 case SWITCH_IVR_ACTION_BACK:04392 running = 0;04393 status = SWITCH_STATUS_SUCCESS;04394 break;04395 case SWITCH_IVR_ACTION_TOMAIN:04396 switch_set_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN);04397 status = SWITCH_STATUS_BREAK;04398 break;04399 case SWITCH_IVR_ACTION_NOOP:04400 status = SWITCH_STATUS_SUCCESS;04401 break;04402 default:04403 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid TODO!\n");04404 break;04405 }04406 }04407 }04408 04409 04410 if (switch_test_flag(menu, SWITCH_IVR_MENU_FLAG_STACK)) { // top level04411 if (switch_test_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN)) { // catch the fallback and recover04412 switch_clear_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN);04413 status = SWITCH_STATUS_SUCCESS;04414 running = 1;04415 continue;04416 }04417 }04418 }04419 if (!match) {04420 if (*menu->buf) {04421 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IVR menu '%s' caught invalid input '%s'\n", menu->name, menu->buf);04422 if (menu->invalid_sound) {04423 play_or_say(session, menu, menu->invalid_sound, 0);04424 }04425 }04426 else {04427 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IVR menu '%s' no input detected\n", menu->name);04428 }04429 errs++;04430 if (status == SWITCH_STATUS_SUCCESS) {04431 status = switch_ivr_sleep(session, 1000);04432 }04433 /* breaks are ok too */04434 if (SWITCH_STATUS_IS_BREAK(status)) {04435 status = SWITCH_STATUS_SUCCESS;04436 }04437 }04438 }04439 04440 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "exit-sound '%s'\n",menu->exit_sound);04441 if (!switch_strlen_zero(menu->exit_sound)) {04442 play_or_say(session, menu, menu->exit_sound, 0);04443 }04444 04445 switch_safe_free(menu->buf);04446 04447 return status;04448 }