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 level
04411 if (switch_test_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN)) { // catch the fallback and recover
04412 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 }