|
|
|
|
|
|
|
|
|
|
|
|
|
|
00638 {
00639 SWITCH_IVR_ACTION_DIE, /* Exit the menu. */
00640 SWITCH_IVR_ACTION_EXECMENU, /* Goto another menu in the stack. */
00641 SWITCH_IVR_ACTION_EXECAPP, /* Execute an application. */
00642 SWITCH_IVR_ACTION_PLAYSOUND, /* Play a sound. */
00643 SWITCH_IVR_ACTION_BACK, /* Go back 1 menu. */
00644 SWITCH_IVR_ACTION_TOMAIN, /* Go back to the top level menu. */
00645 SWITCH_IVR_ACTION_NOOP /* No operation */
00646 } switch_ivr_action_t;
|
|
|
00632 {
00633 SWITCH_IVR_MENU_FLAG_FALLTOMAIN = (1 << 0),
00634 SWITCH_IVR_MENU_FLAG_FREEPOOL = (1 << 1),
00635 SWITCH_IVR_MENU_FLAG_STACK = (1 << 2)
00636 } switch_ivr_menu_flags;
|
|
||||||||||||||||||||
|
01506 {
01507 switch_channel_t *channel = switch_core_session_get_channel(session);
01508 dtmf_meta_data_t *md = switch_channel_get_private(channel, SWITCH_META_VAR_KEY);
01509
01510 if (key > 9) {
01511 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid key %u\n", key);
01512 return SWITCH_STATUS_FALSE;
01513 }
01514
01515 if (!md) {
01516 md = switch_core_session_alloc(session, sizeof(*md));
01517 switch_channel_set_private(channel, SWITCH_META_VAR_KEY, md);
01518 switch_core_event_hook_add_send_dtmf(session, meta_on_dtmf);
01519 switch_core_event_hook_add_recv_dtmf(session, meta_on_dtmf);
01520 }
01521
01522 if (!switch_strlen_zero(app)) {
01523 if ((bind_flags & SBF_DIAL_ALEG)) {
01524 md->sr[SWITCH_DTMF_RECV].up = 1;
01525 md->sr[SWITCH_DTMF_RECV].map[key].app = switch_core_session_strdup(session, app);
01526 md->sr[SWITCH_DTMF_RECV].map[key].flags |= SMF_HOLD_BLEG;
01527 md->sr[SWITCH_DTMF_RECV].map[key].bind_flags = bind_flags;
01528
01529 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Bound A-Leg: %d %s\n", key, app);
01530 }
01531 if ((bind_flags & SBF_DIAL_BLEG)) {
01532 md->sr[SWITCH_DTMF_SEND].up = 1;
01533 md->sr[SWITCH_DTMF_SEND].map[key].app = switch_core_session_strdup(session, app);
01534 md->sr[SWITCH_DTMF_SEND].map[key].flags |= SMF_HOLD_BLEG;
01535 md->sr[SWITCH_DTMF_SEND].map[key].bind_flags = bind_flags;
01536 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Bound B-Leg: %d %s\n", key, app);
01537 }
01538
01539 } else {
01540 if ((bind_flags & SBF_DIAL_ALEG)) {
01541 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "UnBound A-Leg: %d\n", key);
01542 md->sr[SWITCH_DTMF_SEND].map[key].app = NULL;
01543 } else {
01544 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "UnBound: B-Leg %d\n", key);
01545 md->sr[SWITCH_DTMF_SEND].map[key].app = NULL;
01546 }
01547 }
01548
01549 return SWITCH_STATUS_SUCCESS;
01550 }
|
Here is the call graph for this function:

|
||||||||||||
|
01719 {
01720 stfu_instance_t *jb;
01721 int qlen = 0;
01722 switch_codec_t *read_codec;
01723 stfu_frame_t *jb_frame;
01724 switch_frame_t *read_frame, write_frame = { 0 };
01725 switch_status_t status;
01726 switch_channel_t *channel = switch_core_session_get_channel(session);
01727 uint32_t interval, samples;
01728 uint32_t ts = 0;
01729
01730 if (delay_ms < 1 || delay_ms > 10000) {
01731 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid delay [%d] must be between 1 and 10000\n", delay_ms);
01732 return;
01733 }
01734
01735 read_codec = switch_core_session_get_read_codec(session);
01736 interval = read_codec->implementation->microseconds_per_frame / 1000;
01737 samples = switch_samples_per_frame(read_codec->implementation->samples_per_second, interval);
01738
01739 qlen = delay_ms / (interval);
01740 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen);
01741 jb = stfu_n_init(qlen);
01742
01743 write_frame.codec = read_codec;
01744
01745 while (switch_channel_ready(channel)) {
01746 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
01747 if (!SWITCH_READ_ACCEPTABLE(status)) {
01748 break;
01749 }
01750
01751 stfu_n_eat(jb, ts, read_frame->data, read_frame->datalen);
01752 ts += interval;
01753
01754 if ((jb_frame = stfu_n_read_a_frame(jb))) {
01755 write_frame.data = jb_frame->data;
01756 write_frame.datalen = (uint32_t) jb_frame->dlen;
01757 status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
01758 if (!SWITCH_READ_ACCEPTABLE(status)) {
01759 break;
01760 }
01761 }
01762 }
01763
01764 stfu_n_destroy(&jb);
01765 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
01070 {
01071 switch_core_session_t *rsession;
01072 switch_status_t status = SWITCH_STATUS_FALSE;
01073
01074 switch_assert(uuid);
01075
01076 if ((rsession = switch_core_session_locate(uuid))) {
01077 switch_channel_t *rchannel = switch_core_session_get_channel(rsession);
01078 const char *brto;
01079
01080 if ((brto = switch_channel_get_variable(rchannel, SWITCH_SIGNAL_BOND_VARIABLE))) {
01081 switch_copy_string(b_uuid, brto, blen);
01082 status = SWITCH_STATUS_SUCCESS;
01083 }
01084 switch_core_session_rwunlock(rsession);
01085 }
01086
01087 return status;
01088
01089 }
|
Here is the call graph for this function:

|
|
00069 {
00070 int x = 0;
00071 for (x = 0; SAY_METHOD_NAMES[x]; x++) {
00072 if (!strcasecmp(SAY_METHOD_NAMES[x], name)) {
00073 break;
00074 }
00075 }
00076
00077 return (switch_say_method_t) x;
00078 }
|
|
|
00081 {
00082 int x = 0;
00083 for (x = 0; SAY_TYPE_NAMES[x]; x++) {
00084 if (!strcasecmp(SAY_TYPE_NAMES[x], name)) {
00085 break;
00086 }
00087 }
00088
00089 return (switch_say_type_t) x;
00090 }
|
|
||||||||||||||||
|
01092 {
01093 switch_core_session_t *rsession, *bsession = NULL;
01094 switch_channel_t *channel, *rchannel, *bchannel = NULL;
01095 const char *buuid;
01096 char brto[SWITCH_UUID_FORMATTED_LENGTH + 1] = "";
01097
01098 if (bleg) {
01099 if (switch_ivr_find_bridged_uuid(uuid, brto, sizeof(brto)) == SWITCH_STATUS_SUCCESS) {
01100 uuid = switch_core_session_strdup(session, brto);
01101 } else {
01102 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no uuid bridged to %s\n", uuid);
01103 return;
01104 }
01105 }
01106
01107 if (switch_strlen_zero(uuid) || !(rsession = switch_core_session_locate(uuid))) {
01108 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no uuid %s\n", uuid);
01109 return;
01110 }
01111
01112 channel = switch_core_session_get_channel(session);
01113 rchannel = switch_core_session_get_channel(rsession);
01114
01115 switch_channel_pre_answer(channel);
01116
01117 if ((buuid = switch_channel_get_variable(rchannel, SWITCH_SIGNAL_BOND_VARIABLE))) {
01118 bsession = switch_core_session_locate(buuid);
01119 bchannel = switch_core_session_get_channel(bsession);
01120 }
01121
01122 if (!switch_channel_test_flag(rchannel, CF_ANSWERED)) {
01123 switch_channel_answer(rchannel);
01124 }
01125
01126 switch_channel_set_state_flag(rchannel, CF_TRANSFER);
01127 switch_channel_set_state(rchannel, CS_PARK);
01128
01129 if (bchannel) {
01130 switch_channel_set_state_flag(bchannel, CF_TRANSFER);
01131 switch_channel_set_state(bchannel, CS_PARK);
01132 }
01133
01134 switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), uuid);
01135 switch_core_session_rwunlock(rsession);
01136
01137 if (bsession) {
01138 switch_channel_hangup(bchannel, SWITCH_CAUSE_PICKED_OFF);
01139 switch_core_session_rwunlock(bsession);
01140 }
01141
01142
01143
01144 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
switch_ivr_menu_bind_action: Bind a keystroke to an action.
00200 {
00201 switch_ivr_menu_action_t *action;
00202 uint32_t len;
00203
00204 if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) {
00205 action->bind = switch_core_strdup(menu->pool, bind);
00206 action->next = menu->actions;
00207 action->arg = switch_core_strdup(menu->pool, arg);
00208 if (*action->bind == '/') {
00209 action->re = 1;
00210 } else {
00211 len = (uint32_t) strlen(action->bind);
00212 if (len > menu->inlen) {
00213 menu->inlen = len;
00214 }
00215 }
00216 action->ivr_action = ivr_action;
00217 menu->actions = action;
00218 return SWITCH_STATUS_SUCCESS;
00219 }
00220
00221 return SWITCH_STATUS_MEMERR;
00222 }
|
|
||||||||||||||||||||
|
Bind a keystroke to a callback function.
00226 {
00227 switch_ivr_menu_action_t *action;
00228 uint32_t len;
00229
00230 if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) {
00231 action->bind = switch_core_strdup(menu->pool, bind);
00232 action->next = menu->actions;
00233 action->arg = switch_core_strdup(menu->pool, arg);
00234 if (*action->bind == '/') {
00235 action->re = 1;
00236 } else {
00237 len = (uint32_t) strlen(action->bind);
00238 if (len > menu->inlen) {
00239 menu->inlen = len;
00240 }
00241 }
00242 action->function = function;
00243 menu->actions = action;
00244 return SWITCH_STATUS_SUCCESS;
00245 }
00246
00247 return SWITCH_STATUS_MEMERR;
00248 }
|
|
||||||||||||||||||||
|
Execute a menu.
00351 {
00352 int reps = 0, errs = 0, timeouts = 0, match = 0, running = 1;
00353 char *greeting_sound = NULL, *aptr = NULL;
00354 char arg[512];
00355 switch_ivr_action_t todo = SWITCH_IVR_ACTION_DIE;
00356 switch_ivr_menu_action_t *ap;
00357 switch_ivr_menu_t *menu;
00358 switch_channel_t *channel;
00359 switch_status_t status = SWITCH_STATUS_SUCCESS;
00360
00361 if (!session || !stack || switch_strlen_zero(name)) {
00362 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid menu context\n");
00363 return SWITCH_STATUS_FALSE;
00364 }
00365
00366 channel = switch_core_session_get_channel(session);
00367
00368 if (!(menu = switch_ivr_menu_find(stack, name))) {
00369 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Menu!\n");
00370 return SWITCH_STATUS_FALSE;
00371 }
00372
00373 if (!(menu->buf = malloc(menu->inlen + 1))) {
00374 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Memory!\n");
00375 return SWITCH_STATUS_FALSE;
00376 }
00377
00378 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Executing IVR menu %s\n", menu->name);
00379 switch_channel_set_variable(channel, "ivr_menu_status", "success");
00380
00381 for (reps = 0; running && status == SWITCH_STATUS_SUCCESS; reps++) {
00382 if (!switch_channel_ready(channel)) {
00383 break;
00384 }
00385 if (errs == menu->max_failures) {
00386 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Maximum failures\n");
00387 switch_channel_set_variable(channel, "ivr_menu_status", "failure");
00388 break;
00389 }
00390 if (timeouts == menu->max_timeouts) {
00391 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Maximum timeouts\n");
00392 switch_channel_set_variable(channel, "ivr_menu_status", "timeout");
00393 break;
00394 }
00395
00396 if (reps > 0 && menu->short_greeting_sound) {
00397 greeting_sound = menu->short_greeting_sound;
00398 } else {
00399 greeting_sound = menu->greeting_sound;
00400 }
00401
00402 match = 0;
00403 aptr = NULL;
00404
00405 memset(arg, 0, sizeof(arg));
00406
00407 memset(menu->buf, 0, menu->inlen + 1);
00408
00409 if (play_and_collect(session, menu, greeting_sound, menu->inlen) == SWITCH_STATUS_TIMEOUT && *menu->buf == '\0') {
00410 timeouts++;
00411 continue;
00412 }
00413
00414 if (*menu->buf != '\0') {
00415
00416 for (ap = menu->actions; ap; ap = ap->next) {
00417 int ok = 0;
00418 char substituted[1024];
00419 char *use_arg = ap->arg;
00420
00421 if (ap->re) {
00422 switch_regex_t *re = NULL;
00423 int ovector[30];
00424
00425 if ((ok = switch_regex_perform(menu->buf, ap->bind, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
00426 switch_perform_substitution(re, ok, ap->arg, menu->buf, substituted, sizeof(substituted), ovector);
00427 use_arg = substituted;
00428 }
00429 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "action regex [%s] [%s] [%d]\n", menu->buf, ap->bind, ok);
00430
00431 switch_regex_safe_free(re);
00432 } else {
00433 ok = !strcmp(menu->buf, ap->bind);
00434 }
00435
00436 if (ok) {
00437 match++;
00438 errs = 0;
00439 if (ap->function) {
00440 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
00441 "IVR function on menu '%s' matched '%s' param '%s'\n", menu->name, menu->buf, use_arg);
00442 todo = ap->function(menu, use_arg, arg, sizeof(arg), obj);
00443 aptr = arg;
00444 } else {
00445 todo = ap->ivr_action;
00446 aptr = use_arg;
00447 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
00448 "IVR action on menu '%s' matched '%s' param '%s'\n", menu->name, menu->buf, aptr);
00449 }
00450
00451 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "switch_ivr_menu_execute todo=[%d]\n", todo);
00452
00453 switch (todo) {
00454 case SWITCH_IVR_ACTION_DIE:
00455 status = SWITCH_STATUS_FALSE;
00456 break;
00457 case SWITCH_IVR_ACTION_PLAYSOUND:
00458 status = switch_ivr_play_file(session, NULL, aptr, NULL);
00459 break;
00460 case SWITCH_IVR_ACTION_EXECMENU:
00461 reps = -1;
00462 status = switch_ivr_menu_execute(session, stack, aptr, obj);
00463 break;
00464 case SWITCH_IVR_ACTION_EXECAPP:
00465 {
00466 const switch_application_interface_t *application_interface;
00467 char *app_name;
00468 char *app_arg = NULL;
00469
00470 status = SWITCH_STATUS_FALSE;
00471
00472 if (!switch_strlen_zero(aptr)) {
00473 app_name = switch_core_session_strdup(session, aptr);
00474 if ((app_arg = strchr(app_name, ' '))) {
00475 *app_arg++ = '\0';
00476 }
00477
00478 if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
00479 switch_core_session_exec(session, application_interface, app_arg);
00480 status = SWITCH_STATUS_SUCCESS;
00481 }
00482 }
00483 }
00484 break;
00485 case SWITCH_IVR_ACTION_BACK:
00486 running = 0;
00487 status = SWITCH_STATUS_SUCCESS;
00488 break;
00489 case SWITCH_IVR_ACTION_TOMAIN:
00490 switch_set_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN);
00491 status = SWITCH_STATUS_BREAK;
00492 break;
00493 case SWITCH_IVR_ACTION_NOOP:
00494 status = SWITCH_STATUS_SUCCESS;
00495 break;
00496 default:
00497 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid TODO!\n");
00498 break;
00499 }
00500 }
00501 }
00502
00503 if (switch_test_flag(menu, SWITCH_IVR_MENU_FLAG_STACK)) { /* top level */
00504 if (switch_test_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN)) { /* catch the fallback and recover */
00505 switch_clear_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN);
00506 status = SWITCH_STATUS_SUCCESS;
00507 running = 1;
00508 continue;
00509 }
00510 }
00511 }
00512 if (!match) {
00513 if (*menu->buf) {
00514 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IVR menu '%s' caught invalid input '%s'\n", menu->name, menu->buf);
00515 if (menu->invalid_sound) {
00516 play_and_collect(session, menu, menu->invalid_sound, 0);
00517 }
00518 } else {
00519 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IVR menu '%s' no input detected\n", menu->name);
00520 }
00521 errs++;
00522 if (status == SWITCH_STATUS_SUCCESS) {
00523 status = switch_ivr_sleep(session, 1000, NULL);
00524 }
00525 /* breaks are ok too */
00526 if (SWITCH_STATUS_IS_BREAK(status)) {
00527 status = SWITCH_STATUS_SUCCESS;
00528 }
00529 }
00530 }
00531
00532 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "exit-sound '%s'\n", menu->exit_sound);
00533 if (!switch_strlen_zero(menu->exit_sound)) {
00534 status = play_and_collect(session, menu, menu->exit_sound, 0);
00535 }
00536
00537 switch_safe_free(menu->buf);
00538
00539 return status;
00540 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Create a new menu object.
00108 {
00109 switch_ivr_menu_t *menu;
00110 uint8_t newpool = 0;
00111
00112 if (!pool) {
00113 if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
00114 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
00115 return SWITCH_STATUS_MEMERR;
00116 }
00117 newpool = 1;
00118 }
00119
00120 if (!(menu = switch_core_alloc(pool, sizeof(*menu)))) {
00121 if (newpool) {
00122 switch_core_destroy_memory_pool(&pool);
00123 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
00124 return SWITCH_STATUS_MEMERR;
00125 }
00126 }
00127
00128 menu->pool = pool;
00129
00130 if (!confirm_attempts) {
00131 confirm_attempts = 3;
00132 }
00133
00134 if (!inter_timeout) {
00135 inter_timeout = timeout / 2;
00136 }
00137
00138 if (!switch_strlen_zero(name)) {
00139 menu->name = switch_core_strdup(menu->pool, name);
00140 }
00141
00142 if (!switch_strlen_zero(greeting_sound)) {
00143 menu->greeting_sound = switch_core_strdup(menu->pool, greeting_sound);
00144 }
00145
00146 if (!switch_strlen_zero(short_greeting_sound)) {
00147 menu->short_greeting_sound = switch_core_strdup(menu->pool, short_greeting_sound);
00148 }
00149
00150 if (!switch_strlen_zero(invalid_sound)) {
00151 menu->invalid_sound = switch_core_strdup(menu->pool, invalid_sound);
00152 }
00153
00154 if (!switch_strlen_zero(exit_sound)) {
00155 menu->exit_sound = switch_core_strdup(menu->pool, exit_sound);
00156 }
00157
00158 if (!switch_strlen_zero(confirm_macro)) {
00159 menu->confirm_macro = switch_core_strdup(menu->pool, confirm_macro);
00160 }
00161
00162 if (!switch_strlen_zero(confirm_key)) {
00163 menu->confirm_key = switch_core_strdup(menu->pool, confirm_key);
00164 }
00165
00166 menu->confirm_attempts = confirm_attempts;
00167
00168 menu->inlen = digit_len;
00169
00170 menu->max_failures = max_failures;
00171
00172 menu->max_timeouts = max_timeouts;
00173
00174 menu->timeout = timeout;
00175
00176 menu->inter_timeout = inter_timeout;
00177
00178 menu->actions = NULL;
00179
00180 if (newpool) {
00181 menu->flags |= SWITCH_IVR_MENU_FLAG_FREEPOOL;
00182 }
00183
00184 if (menu->timeout <= 0) {
00185 menu->timeout = 10000;
00186 }
00187
00188 if (main) {
00189 switch_ivr_menu_stack_add(&main, menu);
00190 } else {
00191 menu->flags |= SWITCH_IVR_MENU_FLAG_STACK;
00192 }
00193
00194 *new_menu = menu;
00195
00196 return SWITCH_STATUS_SUCCESS;
00197 }
|
Here is the call graph for this function:

|
|
free a stack of menu objects.
00251 {
00252 switch_status_t status = SWITCH_STATUS_FALSE;
00253
00254 if (stack != NULL && stack->pool != NULL) {
00255 if (switch_test_flag(stack, SWITCH_IVR_MENU_FLAG_STACK)
00256 && switch_test_flag(stack, SWITCH_IVR_MENU_FLAG_FREEPOOL)) {
00257 switch_memory_pool_t *pool = stack->pool;
00258 status = switch_core_destroy_memory_pool(&pool);
00259 } else {
00260 status = SWITCH_STATUS_SUCCESS;
00261 }
00262 }
00263
00264 return status;
00265 }
|
|
||||||||||||||||
|
00693 {
00694 return switch_ivr_menu_stack_xml_add(xml_menu_ctx, name, -1, function);
00695 }
|
|
||||||||||||||||||||
|
Build a menu stack from an xml source.
00699 {
00700 switch_status_t status = SWITCH_STATUS_FALSE;
00701
00702 if (xml_menu_ctx != NULL && menu_stack != NULL && xml_menu != NULL) {
00703 const char *menu_name = switch_xml_attr_soft(xml_menu, "name"); /* if the attr doesn't exist, return "" */
00704 const char *greet_long = switch_xml_attr(xml_menu, "greet-long"); /* if the attr doesn't exist, return NULL */
00705 const char *greet_short = switch_xml_attr(xml_menu, "greet-short"); /* if the attr doesn't exist, return NULL */
00706 const char *invalid_sound = switch_xml_attr(xml_menu, "invalid-sound"); /* if the attr doesn't exist, return NULL */
00707 const char *exit_sound = switch_xml_attr(xml_menu, "exit-sound"); /* if the attr doesn't exist, return NULL */
00708 const char *timeout = switch_xml_attr_soft(xml_menu, "timeout"); /* if the attr doesn't exist, return "" */
00709 const char *max_failures = switch_xml_attr_soft(xml_menu, "max-failures"); /* if the attr doesn't exist, return "" */
00710 const char *max_timeouts = switch_xml_attr_soft(xml_menu, "max-timeouts");
00711 const char *confirm_macro= switch_xml_attr(xml_menu, "confirm-macro");
00712 const char *confirm_key= switch_xml_attr(xml_menu, "confirm-key");
00713 const char *confirm_attempts = switch_xml_attr_soft(xml_menu, "confirm-attempts");
00714 const char *digit_len = switch_xml_attr_soft(xml_menu, "digit-len");
00715 const char *inter_timeout = switch_xml_attr_soft(xml_menu, "inter-digit-timeout");
00716
00717 switch_ivr_menu_t *menu = NULL;
00718
00719 if (switch_strlen_zero(max_timeouts)) {
00720 max_timeouts = max_failures;
00721 }
00722
00723 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "building menu '%s'\n", menu_name);
00724
00725 status = switch_ivr_menu_init(&menu,
00726 *menu_stack,
00727 menu_name,
00728 greet_long,
00729 greet_short,
00730 invalid_sound,
00731 exit_sound,
00732 confirm_macro,
00733 confirm_key,
00734 atoi(confirm_attempts),
00735 atoi(inter_timeout),
00736 atoi(digit_len),
00737 atoi(timeout),
00738 strlen(max_failures)? atoi(max_failures): 1,
00739 strlen(max_timeouts)? atoi(max_timeouts): 1,
00740 xml_menu_ctx->pool);
00741 /* set the menu_stack for the caller */
00742 if (status == SWITCH_STATUS_SUCCESS && *menu_stack == NULL) {
00743 *menu_stack = menu;
00744 }
00745
00746 if (status == SWITCH_STATUS_SUCCESS && menu != NULL) {
00747 switch_xml_t xml_kvp;
00748
00749 /* build menu entries */
00750 for (xml_kvp = switch_xml_child(xml_menu, "entry"); xml_kvp != NULL && status == SWITCH_STATUS_SUCCESS; xml_kvp = xml_kvp->next) {
00751 const char *action = switch_xml_attr(xml_kvp, "action");
00752 const char *digits = switch_xml_attr(xml_kvp, "digits");
00753 const char *param = switch_xml_attr_soft(xml_kvp, "param");
00754
00755 if (is_valid_action(action) && !switch_strlen_zero(digits)) {
00756 switch_ivr_menu_xml_map_t *xml_map = xml_menu_ctx->map;
00757 int found = 0;
00758
00759 /* find and appropriate xml handler */
00760 while (xml_map != NULL && !found) {
00761 if (!(found = (strcasecmp(xml_map->name, action) == 0))) {
00762 xml_map = xml_map->next;
00763 }
00764 }
00765
00766 if (found && xml_map != NULL) {
00767 /* do we need to build a new sub-menu ? */
00768 if (xml_map->action == SWITCH_IVR_ACTION_EXECMENU && switch_ivr_menu_find(*menu_stack, param) == NULL) {
00769 if ((xml_menu = switch_xml_find_child(xml_menus, "menu", "name", param)) != NULL) {
00770 status = switch_ivr_menu_stack_xml_build(xml_menu_ctx, menu_stack, xml_menus, xml_menu);
00771 }
00772 }
00773 /* finally bind the menu entry */
00774 if (status == SWITCH_STATUS_SUCCESS) {
00775 if (xml_map->function != NULL) {
00776 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
00777 "binding menu caller control '%s'/'%s' to '%s'\n", xml_map->name, param, digits);
00778 status = switch_ivr_menu_bind_function(menu, xml_map->function, param, digits);
00779 } else {
00780 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "binding menu action '%s' to '%s'\n", xml_map->name, digits);
00781 status = switch_ivr_menu_bind_action(menu, xml_map->action, param, digits);
00782 }
00783 }
00784 }
00785 } else {
00786 status = SWITCH_STATUS_FALSE;
00787 }
00788 }
00789 }
00790 }
00791
00792 if (status != SWITCH_STATUS_SUCCESS) {
00793 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to build xml menu\n");
00794 }
00795
00796 return status;
00797 }
|
Here is the call graph for this function:

|
||||||||||||
|
00657 {
00658 switch_status_t status = SWITCH_STATUS_FALSE;
00659 int autocreated = 0;
00660
00661 /* build a memory pool ? */
00662 if (pool == NULL) {
00663 status = switch_core_new_memory_pool(&pool);
00664 autocreated = 1;
00665 }
00666 /* allocate the xml context */
00667 if (xml_menu_ctx != NULL && pool != NULL) {
00668 *xml_menu_ctx = switch_core_alloc(pool, sizeof(switch_ivr_menu_xml_ctx_t));
00669 if (*xml_menu_ctx != NULL) {
00670 (*xml_menu_ctx)->pool = pool;
00671 (*xml_menu_ctx)->autocreated = autocreated;
00672 (*xml_menu_ctx)->map = NULL;
00673 status = SWITCH_STATUS_SUCCESS;
00674 } else {
00675 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to alloc xml_ctx\n");
00676 status = SWITCH_STATUS_FALSE;
00677 }
00678 }
00679 /* build the standard/default xml menu handler mappings */
00680 if (status == SWITCH_STATUS_SUCCESS && xml_menu_ctx != NULL && *xml_menu_ctx != NULL) {
00681 int i;
00682
00683 for (i = 0; iam[i].name && status == SWITCH_STATUS_SUCCESS; i++) {
00684 status = switch_ivr_menu_stack_xml_add(*xml_menu_ctx, iam[i].name, iam[i].action, NULL);
00685 }
00686 }
00687
00688 return status;
00689 }
|
Here is the call graph for this function:

|
||||||||||||
|
00617 {
00618 int i;
00619
00620 if (!switch_strlen_zero(action_name)) {
00621 for(i = 0;;i++) {
00622 if (!iam[i].name) {
00623 break;
00624 }
00625
00626 if (!strcasecmp(iam[i].name, action_name)) {
00627 *action = iam[i].action;
00628 return SWITCH_STATUS_SUCCESS;
00629 }
00630 }
00631 }
00632
00633 return SWITCH_STATUS_FALSE;
00634 }
|
|