Main Page | Modules | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

switch_ivr.c File Reference


Data Structures

struct  switch_ivr_digit_stream_parser
struct  switch_ivr_digit_stream

Functions

switch_status_t switch_ivr_sleep (switch_core_session_t *session, uint32_t ms)
 Wait for time to pass for a specified number of milliseconds.
switch_status_t switch_ivr_deactivate_unicast (switch_core_session_t *session)
switch_status_t switch_ivr_activate_unicast (switch_core_session_t *session, char *local_ip, switch_port_t local_port, char *remote_ip, switch_port_t remote_port, char *transport, char *flags)
switch_status_t switch_ivr_parse_event (switch_core_session_t *session, switch_event_t *event)
switch_status_t switch_ivr_parse_next_event (switch_core_session_t *session)
switch_status_t switch_ivr_parse_all_events (switch_core_session_t *session)
 Parse all commands from an event.
switch_status_t switch_ivr_park (switch_core_session_t *session, switch_input_args_t *args)
switch_status_t switch_ivr_collect_digits_callback (switch_core_session_t *session, switch_input_args_t *args, uint32_t timeout)
 Wait for DTMF digits calling a pluggable callback function when digits are collected.
switch_status_t switch_ivr_collect_digits_count (switch_core_session_t *session, char *buf, switch_size_t buflen, switch_size_t maxdigits, const char *terminators, char *terminator, uint32_t first_timeout, uint32_t digit_timeout, uint32_t abs_timeout)
 Wait for specified number of DTMF digits, untile terminator is received or until the channel hangs up.
switch_status_t switch_ivr_hold (switch_core_session_t *session, const char *message, switch_bool_t moh)
 Signal the session with a protocol specific hold message.
switch_status_t switch_ivr_hold_uuid (const char *uuid, const char *message, switch_bool_t moh)
 Signal the session with a protocol specific hold message.
switch_status_t switch_ivr_unhold (switch_core_session_t *session)
 Signal the session with a protocol specific unhold message.
switch_status_t switch_ivr_unhold_uuid (const char *uuid)
 Signal the session with a protocol specific unhold message.
switch_status_t switch_ivr_media (const char *uuid, switch_media_flag_t flags)
 Signal a session to request direct media access to it's remote end.
switch_status_t switch_ivr_nomedia (const char *uuid, switch_media_flag_t flags)
 Signal a session to request indirect media allowing it to exchange media directly with another device.
switch_status_t switch_ivr_session_transfer (switch_core_session_t *session, const char *extension, const char *dialplan, const char *context)
switch_status_t switch_ivr_transfer_variable (switch_core_session_t *sessa, switch_core_session_t *sessb, char *var)
 Transfer variables from one session to another.
switch_status_t switch_ivr_digit_stream_parser_new (switch_memory_pool_t *pool, switch_ivr_digit_stream_parser_t **parser)
 Create a digit stream parser object.
switch_status_t switch_ivr_digit_stream_parser_destroy (switch_ivr_digit_stream_parser_t *parser)
 Destroy a digit stream parser object.
switch_status_t switch_ivr_digit_stream_new (switch_ivr_digit_stream_parser_t *parser, switch_ivr_digit_stream_t **stream)
 Create a new digit stream object.
switch_status_t switch_ivr_digit_stream_destroy (switch_ivr_digit_stream_t *stream)
 Destroys a digit stream object.
switch_status_t switch_ivr_digit_stream_parser_set_event (switch_ivr_digit_stream_parser_t *parser, char *digits, void *data)
 Set a digit string to action mapping.
switch_status_t switch_ivr_digit_stream_parser_del_event (switch_ivr_digit_stream_parser_t *parser, char *digits)
 Delete a string to action mapping.
void * switch_ivr_digit_stream_parser_feed (switch_ivr_digit_stream_parser_t *parser, switch_ivr_digit_stream_t *stream, char digit)
 Feed digits collected into the stream for event match testing.
switch_status_t switch_ivr_digit_stream_reset (switch_ivr_digit_stream_t *stream)
 Reset the collected digit stream to nothing.
switch_status_t switch_ivr_digit_stream_parser_set_terminator (switch_ivr_digit_stream_parser_t *parser, char digit)
 Set a digit string terminator.
int switch_ivr_set_xml_profile_data (switch_xml_t xml, switch_caller_profile_t *caller_profile, int off)
int switch_ivr_set_xml_chan_vars (switch_xml_t xml, switch_channel_t *channel, int off)
switch_status_t switch_ivr_generate_xml_cdr (switch_core_session_t *session, switch_xml_t *xml_cdr)
 Generate an XML CDR report.
void switch_ivr_park_session (switch_core_session_t *session)
void switch_ivr_delay_echo (switch_core_session_t *session, uint32_t delay_ms)
switch_status_t switch_ivr_say (switch_core_session_t *session, const char *tosay, const char *module_name, const char *say_type, const char *say_method, switch_input_args_t *args)


Function Documentation

switch_status_t switch_ivr_parse_event switch_core_session_t session,
switch_event_t event
 

00253 {
00254         switch_channel_t *channel = switch_core_session_get_channel(session);
00255         char *cmd = switch_event_get_header(event, "call-command");
00256         unsigned long cmd_hash;
00257         switch_ssize_t hlen = -1;
00258         unsigned long CMD_EXECUTE = switch_hashfunc_default("execute", &hlen);
00259         unsigned long CMD_HANGUP = switch_hashfunc_default("hangup", &hlen);
00260         unsigned long CMD_NOMEDIA = switch_hashfunc_default("nomedia", &hlen);
00261         unsigned long CMD_UNICAST = switch_hashfunc_default("unicast", &hlen);
00262         char *lead_frames = switch_event_get_header(event, "lead-frames");
00263         char *event_lock = switch_event_get_header(event, "event-lock");
00264         switch_status_t status = SWITCH_STATUS_FALSE;
00265 
00266         if (switch_strlen_zero(cmd)) {
00267                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Command!\n");
00268                 return SWITCH_STATUS_FALSE;
00269         }
00270 
00271         cmd_hash = switch_hashfunc_default(cmd, &hlen);
00272 
00273         switch_channel_set_flag(channel, CF_EVENT_PARSE);
00274 
00275         if (switch_true(event_lock)) {
00276                 switch_channel_set_flag(channel, CF_EVENT_LOCK);
00277         }
00278 
00279         if (lead_frames) {
00280                 switch_frame_t *read_frame;
00281                 int frame_count = atoi(lead_frames);
00282                 int max_frames = frame_count * 2;
00283                 
00284                 while(frame_count > 0 && --max_frames > 0) {
00285                         status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
00286                         if (!SWITCH_READ_ACCEPTABLE(status)) {
00287                                 goto done;
00288                         }
00289                         if (!switch_test_flag(read_frame, SFF_CNG)) {
00290                                 frame_count--;
00291                         }
00292                 }
00293         }
00294 
00295         if (cmd_hash == CMD_EXECUTE) {
00296                 const switch_application_interface_t *application_interface;
00297                 char *app_name = switch_event_get_header(event, "execute-app-name");
00298                 char *app_arg = switch_event_get_header(event, "execute-app-arg");
00299                 char *loop_h = switch_event_get_header(event, "loops");
00300                 char *hold_bleg = switch_event_get_header(event, "hold-bleg");
00301                 int loops = 1;
00302 
00303                 if (loop_h) {
00304                         loops = atoi(loop_h);
00305                 }
00306 
00307                 if (app_name) {
00308                         if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
00309                                 if (application_interface->application_function) {
00310                                         int x;
00311                                         const char *b_uuid = NULL;
00312                                         switch_core_session_t *b_session = NULL;
00313                                         
00314                                         switch_channel_clear_flag(channel, CF_STOP_BROADCAST);
00315                                         switch_channel_set_flag(channel, CF_BROADCAST);
00316                                         if (hold_bleg && switch_true(hold_bleg)) {
00317                                                 if ((b_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
00318                                                         const char *stream;
00319                                                         b_uuid = switch_core_session_strdup(session, b_uuid);
00320 
00321                                                         if (!(stream = switch_channel_get_variable_partner(channel, SWITCH_HOLD_MUSIC_VARIABLE))) {
00322                                                                 stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE);
00323                                                         }
00324 
00325                                                         if (stream && switch_is_moh(stream)) {
00326                                                                 if ((b_session = switch_core_session_locate(b_uuid))) {
00327                                                                         switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
00328                                                                         switch_ivr_broadcast(b_uuid, stream, SMF_ECHO_ALEG | SMF_LOOP);
00329                                                                         switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_TRUE, 5000);
00330                                                                         switch_core_session_rwunlock(b_session);
00331                                                                 }
00332                                                         } else {
00333                                                                 b_uuid = NULL;
00334                                                         }
00335                                                 }
00336                                         }
00337                                         for (x = 0; x < loops || loops < 0; x++) {
00338                                                 switch_time_t b4, aftr;
00339                                                 
00340                                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Command Execute %s(%s)\n", 
00341                                                                                   switch_channel_get_name(channel), app_name, app_arg);
00342                                                 b4 = switch_timestamp_now();
00343                                                 switch_core_session_exec(session, application_interface, app_arg);
00344                                                 aftr = switch_timestamp_now();
00345                                                 if (!switch_channel_ready(channel) || switch_channel_test_flag(channel, CF_STOP_BROADCAST) || aftr - b4 < 500000) {
00346                                                         break;
00347                                                 }
00348                                         }
00349 
00350                                         if (b_uuid) {
00351                                                 if ((b_session = switch_core_session_locate(b_uuid))) {
00352                                                         switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
00353                                                         switch_channel_stop_broadcast(b_channel);
00354                                                         switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000);
00355                                                         switch_core_session_rwunlock(b_session);
00356                                                 }
00357                                         }
00358 
00359                                         switch_channel_clear_flag(channel, CF_BROADCAST);                                       
00360                                 }
00361                         }
00362                 }
00363         } else if (cmd_hash == CMD_UNICAST) {
00364                 char *local_ip = switch_event_get_header(event, "local-ip");
00365                 char *local_port = switch_event_get_header(event, "local-port");
00366                 char *remote_ip = switch_event_get_header(event, "remote-ip");
00367                 char *remote_port = switch_event_get_header(event, "remote-port");
00368                 char *transport = switch_event_get_header(event, "transport");
00369                 char *flags = switch_event_get_header(event, "flags");
00370 
00371                 if (switch_strlen_zero(local_ip)) {
00372                         local_ip = "127.0.0.1";
00373                 }
00374                 if (switch_strlen_zero(remote_ip)) {
00375                         remote_ip = "127.0.0.1";
00376                 }
00377                 if (switch_strlen_zero(local_port)) {
00378                         local_port = "8025";
00379                 }
00380                 if (switch_strlen_zero(remote_port)) {
00381                         remote_port = "8026";
00382                 }
00383                 if (switch_strlen_zero(transport)) {
00384                         transport = "udp";
00385                 }
00386 
00387                 switch_ivr_activate_unicast(session, local_ip, (switch_port_t)atoi(local_port), remote_ip, (switch_port_t)atoi(remote_port), transport, flags);
00388 
00389         } else if (cmd_hash == CMD_HANGUP) {
00390                 char *cause_name = switch_event_get_header(event, "hangup-cause");
00391                 switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
00392 
00393                 if (cause_name) {
00394                         cause = switch_channel_str2cause(cause_name);
00395                 }
00396 
00397                 switch_channel_hangup(channel, cause);
00398         } else if (cmd_hash == CMD_NOMEDIA) {
00399                 char *uuid = switch_event_get_header(event, "nomedia-uuid");
00400                 switch_ivr_nomedia(uuid, SMF_REBRIDGE);
00401         }
00402 
00403         status = SWITCH_STATUS_SUCCESS;
00404 
00405  done:
00406         switch_channel_clear_flag(channel, CF_EVENT_PARSE);
00407         switch_channel_clear_flag(channel, CF_EVENT_LOCK);
00408 
00409         return status;
00410 }

Here is the call graph for this function:

switch_status_t switch_ivr_session_transfer switch_core_session_t session,
const char *  extension,
const char *  dialplan,
const char *  context
 

00951 {
00952         switch_channel_t *channel = switch_core_session_get_channel(session);
00953         switch_caller_profile_t *profile, *new_profile;
00954         switch_core_session_message_t msg = { 0 };
00955         switch_core_session_t *other_session;
00956         switch_channel_t *other_channel = NULL;
00957         const char *uuid = NULL;
00958         const char *max_forwards;
00959         const char *forwardvar = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE);
00960         int forwardval = 70;
00961 
00962         if (!switch_strlen_zero(forwardvar)) {
00963                 forwardval =  atoi(forwardvar) - 1;
00964         }
00965         if (forwardval <= 0) {
00966                 switch_channel_hangup(channel, SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR);
00967                 return SWITCH_STATUS_FALSE;
00968         }
00969 
00970         max_forwards = switch_core_session_sprintf(session, "%d", forwardval);
00971         switch_channel_set_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards);
00972 
00973         switch_core_session_reset(session, SWITCH_TRUE);
00974         switch_channel_clear_flag(channel, CF_ORIGINATING);
00975 
00976         /* clear all state handlers */
00977         switch_channel_clear_state_handler(channel, NULL);
00978 
00979         if ((profile = switch_channel_get_caller_profile(channel))) {
00980 
00981                 if (switch_strlen_zero(dialplan)) {
00982                         dialplan = profile->dialplan;
00983                 }
00984         
00985                 if (switch_strlen_zero(context)) {
00986                         context = profile->context;
00987                 }
00988 
00989                 if (switch_strlen_zero(dialplan)) {
00990                         dialplan = "XML";
00991                 }
00992         
00993                 if (switch_strlen_zero(context)) {
00994                         context = "default";
00995                 }
00996 
00997                 if (switch_strlen_zero(extension)) {
00998                         extension = "service";
00999                 }
01000                 
01001                 new_profile = switch_caller_profile_clone(session, profile);
01002 
01003                 new_profile->dialplan = switch_core_strdup(new_profile->pool, dialplan);
01004                 new_profile->context = switch_core_strdup(new_profile->pool, context);
01005                 new_profile->destination_number = switch_core_strdup(new_profile->pool, extension);
01006                 new_profile->rdnis = switch_core_strdup(new_profile->pool, profile->destination_number);
01007 
01008                 switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL);
01009 
01010                 /* If HANGUP_AFTER_BRIDGE is set to 'true', SWITCH_SIGNAL_BRIDGE_VARIABLE 
01011                  * will not have a value, so we need to check SWITCH_BRIDGE_VARIABLE */
01012 
01013                 uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE);
01014 
01015                 if (!uuid) {
01016                         uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE);
01017                 }
01018                 
01019                 if (uuid && (other_session = switch_core_session_locate(uuid))) {
01020                         other_channel = switch_core_session_get_channel(other_session);
01021                         switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL);
01022                         switch_core_session_rwunlock(other_session);
01023                 }
01024 
01025                 if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE))
01026                         && (other_session = switch_core_session_locate(uuid))) {
01027                         other_channel = switch_core_session_get_channel(other_session);
01028 
01029                         switch_channel_set_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL);
01030                         switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL);
01031                         
01032                         switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, NULL);
01033                         switch_channel_set_variable(other_channel, SWITCH_BRIDGE_VARIABLE, NULL);
01034 
01035                         /* If we are transferring the CALLER out of the bridge, we do not want to hang up on them */
01036                         switch_channel_set_variable(channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "false");
01037 
01038                         switch_channel_hangup(other_channel, SWITCH_CAUSE_BLIND_TRANSFER);
01039                         switch_ivr_media(uuid, SMF_NONE);
01040 
01041                         switch_core_session_rwunlock(other_session);
01042                 }
01043 
01044                 switch_channel_set_caller_profile(channel, new_profile);
01045                 switch_channel_set_flag(channel, CF_TRANSFER);
01046 
01047                 switch_channel_set_state(channel, CS_ROUTING);
01048                 
01049                 msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSFER;
01050                 msg.from = __FILE__;
01051                 switch_core_session_receive_message(session, &msg);
01052 
01053                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Transfer %s to %s[%s@%s]\n", switch_channel_get_name(channel), dialplan, extension,
01054                                                   context);
01055                 return SWITCH_STATUS_SUCCESS;
01056         }
01057 
01058         return SWITCH_STATUS_FALSE;
01059 }

Here is the call graph for this function:


Generated on Mon May 26 22:06:52 2008 for FreeSWITCH by  doxygen 1.3.9.1