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

switch_channel.c File Reference


Data Structures

struct  switch_cause_table
struct  switch_channel

Defines

#define resize(l)

Functions

const char * switch_channel_cause2str (switch_call_cause_t cause)
switch_call_cause_t switch_channel_str2cause (const char *str)
switch_call_cause_t switch_channel_get_cause (switch_channel_t *channel)
switch_channel_timetable_tswitch_channel_get_timetable (switch_channel_t *channel)
switch_status_t switch_channel_alloc (switch_channel_t **channel, switch_memory_pool_t *pool)
switch_size_t switch_channel_has_dtmf (switch_channel_t *channel)
switch_status_t switch_channel_queue_dtmf (switch_channel_t *channel, const switch_dtmf_t *dtmf)
switch_status_t switch_channel_queue_dtmf_string (switch_channel_t *channel, const char *dtmf_string)
switch_status_t switch_channel_dequeue_dtmf (switch_channel_t *channel, switch_dtmf_t *dtmf)
switch_size_t switch_channel_dequeue_dtmf_string (switch_channel_t *channel, char *dtmf_str, switch_size_t len)
void switch_channel_flush_dtmf (switch_channel_t *channel)
void switch_channel_uninit (switch_channel_t *channel)
 Uninitalize a channel.
switch_status_t switch_channel_init (switch_channel_t *channel, switch_core_session_t *session, switch_channel_state_t state, uint32_t flags)
 Connect a newly allocated channel to a session object and setup it's initial state.
void switch_channel_presence (switch_channel_t *channel, const char *rpid, const char *status)
 Fire A presence event for the channel.
const char * switch_channel_get_variable (switch_channel_t *channel, const char *varname)
 Retrieve a variable from a given channel.
const char * switch_channel_get_variable_partner (switch_channel_t *channel, const char *varname)
void switch_channel_variable_last (switch_channel_t *channel)
switch_event_header_tswitch_channel_variable_first (switch_channel_t *channel)
switch_status_t switch_channel_set_private (switch_channel_t *channel, const char *key, const void *private_info)
 Set private data on channel.
void * switch_channel_get_private (switch_channel_t *channel, const char *key)
 Retrieve private from a given channel.
switch_status_t switch_channel_set_name (switch_channel_t *channel, const char *name)
 Assign a name to a given channel.
char * switch_channel_get_name (switch_channel_t *channel)
 Retrieve the name of a given channel.
switch_status_t switch_channel_set_variable (switch_channel_t *channel, const char *varname, const char *value)
 Set a variable on a given channel.
switch_status_t switch_channel_set_variable_partner (switch_channel_t *channel, const char *varname, const char *value)
uint32_t switch_channel_test_flag (switch_channel_t *channel, switch_channel_flag_t flags)
 Test for presence of given flag(s) on a given channel.
switch_bool_t switch_channel_set_flag_partner (switch_channel_t *channel, switch_channel_flag_t flags)
 Set given flag(s) on a given channel's bridge partner.
switch_bool_t switch_channel_clear_flag_partner (switch_channel_t *channel, switch_channel_flag_t flags)
 Clears given flag(s) on a given channel's bridge partner.
void switch_channel_wait_for_state (switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state)
switch_status_t switch_channel_wait_for_flag (switch_channel_t *channel, switch_channel_flag_t want_flag, switch_bool_t pres, uint32_t to)
void switch_channel_set_flag (switch_channel_t *channel, switch_channel_flag_t flags)
 Set given flag(s) on a given channel.
void switch_channel_set_state_flag (switch_channel_t *channel, switch_channel_flag_t flags)
 Set given flag(s) on a given channel to be applied on the next state change.
void switch_channel_clear_flag (switch_channel_t *channel, switch_channel_flag_t flags)
 Clear given flag(s) from a channel.
switch_channel_state_t switch_channel_get_state (switch_channel_t *channel)
 Get the current state of a channel in the state engine.
switch_channel_state_t switch_channel_get_running_state (switch_channel_t *channel)
uint8_t switch_channel_ready (switch_channel_t *channel)
 Determine if a channel is ready for io.
const char * switch_channel_state_name (switch_channel_state_t state)
switch_channel_state_t switch_channel_name_state (const char *name)
switch_channel_state_t switch_channel_perform_set_running_state (switch_channel_t *channel, switch_channel_state_t state, const char *file, const char *func, int line)
switch_channel_state_t switch_channel_perform_set_state (switch_channel_t *channel, const char *file, const char *func, int line, switch_channel_state_t state)
void switch_channel_event_set_data (switch_channel_t *channel, switch_event_t *event)
void switch_channel_set_caller_profile (switch_channel_t *channel, switch_caller_profile_t *caller_profile)
 Set the given channel's caller profile.
switch_caller_profile_tswitch_channel_get_caller_profile (switch_channel_t *channel)
 Retrive the given channel's caller profile.
void switch_channel_set_originator_caller_profile (switch_channel_t *channel, switch_caller_profile_t *caller_profile)
 Set the given channel's originator caller profile.
void switch_channel_set_originatee_caller_profile (switch_channel_t *channel, switch_caller_profile_t *caller_profile)
 Set the given channel's originatee caller profile.
switch_caller_profile_tswitch_channel_get_originator_caller_profile (switch_channel_t *channel)
 Retrive the given channel's originator caller profile.
switch_caller_profile_tswitch_channel_get_originatee_caller_profile (switch_channel_t *channel)
 Retrive the given channel's originatee caller profile.
char * switch_channel_get_uuid (switch_channel_t *channel)
 Retrive the given channel's unique id.
int switch_channel_add_state_handler (switch_channel_t *channel, const switch_state_handler_table_t *state_handler)
 add a state handler table to a given channel
const switch_state_handler_table_tswitch_channel_get_state_handler (switch_channel_t *channel, int index)
 Retrieve an state handler tablefrom a given channel at given index level.
void switch_channel_clear_state_handler (switch_channel_t *channel, const switch_state_handler_table_t *state_handler)
 clear a state handler table from a given channel
void switch_channel_set_caller_extension (switch_channel_t *channel, switch_caller_extension_t *caller_extension)
 Assign a caller extension to a given channel.
switch_caller_extension_tswitch_channel_get_caller_extension (switch_channel_t *channel)
 Retrieve caller extension from a given channel.
switch_channel_state_t switch_channel_perform_hangup (switch_channel_t *channel, const char *file, const char *func, int line, switch_call_cause_t hangup_cause)
switch_status_t switch_channel_perform_mark_ring_ready (switch_channel_t *channel, const char *file, const char *func, int line)
switch_status_t switch_channel_perform_mark_pre_answered (switch_channel_t *channel, const char *file, const char *func, int line)
switch_status_t switch_channel_perform_pre_answer (switch_channel_t *channel, const char *file, const char *func, int line)
switch_status_t switch_channel_perform_ring_ready (switch_channel_t *channel, const char *file, const char *func, int line)
switch_status_t switch_channel_perform_mark_answered (switch_channel_t *channel, const char *file, const char *func, int line)
switch_status_t switch_channel_perform_answer (switch_channel_t *channel, const char *file, const char *func, int line)
char * switch_channel_expand_variables (switch_channel_t *channel, const char *in)
char * switch_channel_build_param_string (switch_channel_t *channel, switch_caller_profile_t *caller_profile, const char *prefix)
switch_status_t switch_channel_set_timestamps (switch_channel_t *channel)


Define Documentation

#define resize  ) 
 

Value:

{\
        char *dp;\
        olen += (len + l + block);\
        cpos = c - data;\
        if ((dp = realloc(data, olen))) {\
        data = dp;\
        c = data + cpos;\
        memset(c, 0, olen - cpos);\
        }}                           \


Function Documentation

switch_status_t switch_channel_alloc switch_channel_t **  channel,
switch_memory_pool_t pool
 

00180 {
00181         switch_assert(pool != NULL);
00182 
00183         if (((*channel) = switch_core_alloc(pool, sizeof(switch_channel_t))) == 0) {
00184                 return SWITCH_STATUS_MEMERR;
00185         }
00186 
00187         switch_event_create(&(*channel)->variables, SWITCH_EVENT_MESSAGE);
00188 
00189         switch_core_hash_init(&(*channel)->private_hash, pool);
00190         switch_queue_create(&(*channel)->dtmf_queue, 128, pool);
00191 
00192         switch_mutex_init(&(*channel)->dtmf_mutex, SWITCH_MUTEX_NESTED, pool);
00193         switch_mutex_init(&(*channel)->flag_mutex, SWITCH_MUTEX_NESTED, pool);
00194         switch_mutex_init(&(*channel)->profile_mutex, SWITCH_MUTEX_NESTED, pool);
00195         (*channel)->hangup_cause = SWITCH_CAUSE_UNALLOCATED;
00196         (*channel)->name = "";
00197 
00198         return SWITCH_STATUS_SUCCESS;
00199 }

Here is the call graph for this function:

char* switch_channel_build_param_string switch_channel_t channel,
switch_caller_profile_t caller_profile,
const char *  prefix
 

01829 {
01830         switch_stream_handle_t stream = { 0 };
01831         switch_size_t encode_len = 1024, new_len = 0;
01832         char *encode_buf = NULL;
01833         const char *prof[12] = { 0 }, *prof_names[12] = {0};
01834         char *e = NULL;
01835         switch_event_header_t *hi;
01836         uint32_t x = 0;
01837 
01838         SWITCH_STANDARD_STREAM(stream);
01839 
01840         if (prefix) {
01841                 stream.write_function(&stream, "%s&", prefix);
01842         }
01843 
01844         encode_buf = malloc(encode_len);
01845         switch_assert(encode_buf);
01846 
01847         if (!caller_profile) {
01848                 caller_profile = switch_channel_get_caller_profile(channel);
01849         }
01850 
01851         switch_assert(caller_profile != NULL);
01852 
01853         prof[0] = caller_profile->context;
01854         prof[1] = caller_profile->destination_number;
01855         prof[2] = caller_profile->caller_id_name;
01856         prof[3] = caller_profile->caller_id_number;
01857         prof[4] = caller_profile->network_addr;
01858         prof[5] = caller_profile->ani;
01859         prof[6] = caller_profile->aniii;
01860         prof[7] = caller_profile->rdnis;
01861         prof[8] = caller_profile->source;
01862         prof[9] = caller_profile->chan_name;
01863         prof[10] = caller_profile->uuid;
01864 
01865         prof_names[0] = "context";
01866         prof_names[1] = "destination_number";
01867         prof_names[2] = "caller_id_name";
01868         prof_names[3] = "caller_id_number";
01869         prof_names[4] = "network_addr";
01870         prof_names[5] = "ani";
01871         prof_names[6] = "aniii";
01872         prof_names[7] = "rdnis";
01873         prof_names[8] = "source";
01874         prof_names[9] = "chan_name";
01875         prof_names[10] = "uuid";
01876 
01877         for (x = 0; prof[x]; x++) {
01878                 if (switch_strlen_zero(prof[x])) {
01879                         continue;
01880                 }
01881                 new_len = (strlen(prof[x]) * 3) + 1;
01882                 if (encode_len < new_len) {
01883                         char *tmp;
01884 
01885                         encode_len = new_len;
01886 
01887                         if (!(tmp = realloc(encode_buf, encode_len))) {
01888                                 abort();
01889                         }
01890 
01891                         encode_buf = tmp;
01892                 }
01893                 switch_url_encode(prof[x], encode_buf, encode_len);
01894                 stream.write_function(&stream, "%s=%s&", prof_names[x], encode_buf);
01895         }
01896 
01897         if ((hi = switch_channel_variable_first(channel))) {
01898                 for (; hi; hi = hi->next) {
01899                         char *var = hi->name;
01900                         char *val = hi->value;
01901 
01902                         new_len = (strlen((char *) var) * 3) + 1;
01903                         if (encode_len < new_len) {
01904                                 char *tmp;
01905 
01906                                 encode_len = new_len;
01907 
01908                                 tmp = realloc(encode_buf, encode_len);
01909                                 switch_assert(tmp);
01910                                 encode_buf = tmp;
01911                         }
01912 
01913                         switch_url_encode((char *) val, encode_buf, encode_len);
01914                         stream.write_function(&stream, "%s=%s&", (char *) var, encode_buf);
01915 
01916                 }
01917                 switch_channel_variable_last(channel);
01918         }
01919 
01920         e = (char *) stream.data + (strlen((char *) stream.data) - 1);
01921 
01922         if (e && *e == '&') {
01923                 *e = '\0';
01924         }
01925 
01926         switch_safe_free(encode_buf);
01927 
01928         return stream.data;
01929 }

Here is the call graph for this function:

const char* switch_channel_cause2str switch_call_cause_t  cause  ) 
 

00129 {
00130         uint8_t x;
00131         const char *str = "UNKNOWN";
00132 
00133         for (x = 0; x < (sizeof(CAUSE_CHART) / sizeof(struct switch_cause_table)) -1 ; x++) {
00134                 if (CAUSE_CHART[x].cause == cause) {
00135                         str = CAUSE_CHART[x].name;
00136                         break;
00137                 }
00138         }
00139 
00140         return str;
00141 }

switch_status_t switch_channel_dequeue_dtmf switch_channel_t channel,
switch_dtmf_t dtmf
 

00312 {
00313         switch_event_t *event;
00314         void *pop;
00315         switch_dtmf_t *dt;
00316         switch_status_t status = SWITCH_STATUS_FALSE;
00317 
00318         switch_mutex_lock(channel->dtmf_mutex);
00319 
00320         if (switch_queue_trypop(channel->dtmf_queue, &pop) == SWITCH_STATUS_SUCCESS) {
00321                 dt = (switch_dtmf_t *) pop;
00322                 *dtmf = *dt;
00323                 free(dt);
00324 
00325                 if (dtmf->duration > switch_core_max_dtmf_duration(0)) {
00326                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s EXECSSIVE DTMF DIGIT [%c] LEN [%d]\n", 
00327                                                           switch_channel_get_name(channel), dtmf->digit, dtmf->duration);
00328                         dtmf->duration = switch_core_max_dtmf_duration(0);
00329                 } else if (!dtmf->duration) {
00330                         dtmf->duration = switch_core_default_dtmf_duration(0);
00331                 }
00332 
00333                 status = SWITCH_STATUS_SUCCESS;
00334         }
00335         switch_mutex_unlock(channel->dtmf_mutex);
00336 
00337         if (status == SWITCH_STATUS_SUCCESS && switch_event_create(&event, SWITCH_EVENT_DTMF) == SWITCH_STATUS_SUCCESS) {
00338                 switch_channel_event_set_data(channel, event);
00339                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "DTMF-Digit", "%c", dtmf->digit);
00340                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "DTMF-Duration", "%u", dtmf->duration);
00341                 switch_event_fire(&event);
00342         }
00343 
00344         return status;
00345 }

Here is the call graph for this function:

switch_size_t switch_channel_dequeue_dtmf_string switch_channel_t channel,
char *  dtmf_str,
switch_size_t  len
 

00348 {
00349         switch_size_t x = 0;
00350         switch_dtmf_t dtmf = {0};
00351 
00352         memset(dtmf_str, 0, len);
00353 
00354         while(x < len - 1 && switch_channel_dequeue_dtmf(channel, &dtmf) == SWITCH_STATUS_SUCCESS) {
00355                 dtmf_str[x++] = dtmf.digit;
00356         }
00357 
00358         return x;
00359 
00360 }

Here is the call graph for this function:

void switch_channel_event_set_data switch_channel_t channel,
switch_event_t event
 

01031 {
01032         switch_caller_profile_t *caller_profile, *originator_caller_profile = NULL, *originatee_caller_profile = NULL;
01033         switch_event_header_t *hi;
01034         switch_codec_t *codec;
01035         char state_num[25];
01036         int x;
01037         switch_mutex_lock(channel->profile_mutex);
01038 
01039         if ((caller_profile = switch_channel_get_caller_profile(channel))) {
01040                 originator_caller_profile = caller_profile->originator_caller_profile;
01041                 originatee_caller_profile = caller_profile->originatee_caller_profile;
01042         }
01043 
01044         switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-State", "%s", switch_channel_state_name(channel->state));
01045         switch_snprintf(state_num, sizeof(state_num), "%d", channel->state);
01046         switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-State-Number", "%s", state_num);
01047         switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Name", "%s", switch_channel_get_name(channel));
01048         switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Unique-ID", "%s", switch_core_session_get_uuid(channel->session));
01049 
01050         switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Call-Direction", "%s", switch_channel_test_flag(channel, CF_OUTBOUND) ? "outbound" : "inbound");
01051         if (switch_channel_test_flag(channel, CF_ANSWERED)) {
01052                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Answer-State", "answered");
01053         } else if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
01054                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Answer-State", "early");
01055         } else {
01056                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Answer-State", "ringing");
01057         }
01058 
01059         if ((codec = switch_core_session_get_read_codec(channel->session)) && codec->implementation) {
01060                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Name", "%s", switch_str_nil(codec->implementation->iananame));
01061                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Rate", "%u", codec->implementation->actual_samples_per_second);
01062         }
01063 
01064         if ((codec = switch_core_session_get_write_codec(channel->session)) && codec->implementation) {
01065                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Name", "%s", switch_str_nil(codec->implementation->iananame));
01066                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Rate", "%u", codec->implementation->actual_samples_per_second);
01067         }
01068 
01069         /* Index Caller's Profile */
01070         if (caller_profile) {
01071                 switch_caller_profile_event_set_data(caller_profile, "Caller", event);
01072         }
01073 
01074         if (originator_caller_profile && originatee_caller_profile) {
01075                 /* Index Originator's Profile */
01076                 switch_caller_profile_event_set_data(originator_caller_profile, "Originator", event);
01077 
01078                 /* Index Originatee's Profile */
01079                 switch_caller_profile_event_set_data(originatee_caller_profile, "Originatee", event);
01080         } else {
01081                 /* Index Originator's Profile */
01082                 if (originator_caller_profile) {
01083                         switch_caller_profile_event_set_data(originator_caller_profile, "Other-Leg", event);
01084                 } else if (originatee_caller_profile) { /* Index Originatee's Profile */
01085                         switch_caller_profile_event_set_data(originatee_caller_profile, "Other-Leg", event);
01086                 }
01087         }
01088         x = 0;
01089         /* Index Variables */
01090         if (channel->variables) {
01091                 for (hi = channel->variables->headers; hi; hi = hi->next) {
01092                         char buf[1024];
01093                         char *vvar = NULL, *vval = NULL;
01094 
01095                         vvar = (char *) hi->name;
01096                         vval = (char *) hi->value;
01097                         x++;
01098 
01099                         switch_assert(vvar && vval);
01100                         switch_snprintf(buf, sizeof(buf), "variable_%s", vvar);
01101                         switch_event_add_header(event, SWITCH_STACK_BOTTOM, buf, "%s", vval);
01102                 }
01103         }
01104         switch_mutex_unlock(channel->profile_mutex);
01105 }

Here is the call graph for this function:

char* switch_channel_expand_variables switch_channel_t channel,
const char *  in
 

01581 {
01582         char *p, *c = NULL;
01583         char *data, *indup;
01584         size_t sp = 0, len = 0, olen = 0, vtype = 0, br = 0, cpos, block = 128;
01585         const char *q, *sub_val = NULL;
01586         char *cloned_sub_val = NULL;
01587         char *func_val = NULL;
01588         int nv = 0;
01589 
01590         if (switch_strlen_zero(in)) {
01591                 return (char *)in;
01592         }
01593 
01594         q = in;
01595         while(q && *q) {
01596                 if (!(p = strchr(q, '$'))) {
01597                         break;
01598                 }
01599 
01600                 if (*(p+1) != '{') {
01601                         q = p + 1;
01602                         continue;
01603                 }
01604 
01605                 nv = 1;
01606                 break;
01607         }
01608 
01609         if (!nv) {
01610                 return (char *)in;
01611         }
01612 
01613         
01614         nv = 0;
01615         olen = strlen(in) + 1;
01616         indup = strdup(in);
01617 
01618         if ((data = malloc(olen))) {
01619                 memset(data, 0, olen);
01620                 c = data;
01621                 for (p = indup; p && *p; p++) {
01622                         vtype = 0;
01623 
01624                         if (*p == '\\') {
01625                                 if (*(p + 1) == '$') {
01626                                         nv = 1;
01627                                 } else if (*(p + 1) == '\\') {
01628                                         *c++ = *p++;
01629                                         len++;
01630                                         continue;
01631                                 }
01632                                 p++;
01633                         }
01634 
01635                         if (*p == '$' && !nv) {
01636                                 if (*(p+1)) {
01637                                         if (*(p+1) == '{') {
01638                                                 vtype = 1;
01639                                         } else {
01640                                                 nv = 1;
01641                                         }
01642                                 } else {
01643                                         nv = 1;
01644                                 }
01645                         }
01646 
01647                         if (nv) {
01648                                 *c++ = *p;
01649                                 len++;
01650                                 nv = 0;
01651                                 continue;
01652                         }
01653 
01654                         if (vtype) {
01655                                 char *s = p, *e, *vname, *vval = NULL;
01656                                 size_t nlen;
01657 
01658                                 s++;
01659 
01660                                 if (vtype == 1 && *s == '{') {
01661                                         br = 1;
01662                                         s++;
01663                                 }
01664 
01665                                 e = s;
01666                                 vname = s;
01667                                 while (*e) {
01668                                         if (br == 1 && *e == '}') {
01669                                                 br = 0;
01670                                                 *e++ = '\0';
01671                                                 break;
01672                                         }
01673 
01674                                         if (br > 0) {
01675                                                 if (e != s && *e == '{') {
01676                                                         br++;
01677                                                 } else if (br > 1 && *e == '}') {
01678                                                         br--;
01679                                                 }
01680                                         }
01681 
01682                                         e++;
01683                                 }
01684                                 p = e;
01685 
01686                                 if ((vval = strchr(vname, '('))) {
01687                                         e = vval - 1;
01688                                         *vval++ = '\0';
01689                                         while(*e == ' ') {
01690                                                 *e-- = '\0';
01691                                         }
01692                                         e = vval;
01693                                         br = 1;
01694                                         while(e && *e) {
01695                                                 if (*e == '(') {
01696                                                         br++;
01697                                                 } else if (br > 1 && *e == ')') {
01698                                                         br--;
01699                                                 } else if (br == 1 && *e == ')') {
01700                                                         *e = '\0';
01701                                                         break;
01702                                                 }
01703                                                 e++;
01704                                         }
01705 
01706                                         vtype = 2;
01707                                 }
01708 
01709                                 if (vtype == 1) {
01710                                         char *expanded = NULL;
01711                                         int offset = 0;
01712                                         int ooffset = 0;
01713                                         char *ptr;
01714 
01715                                         if ((expanded = switch_channel_expand_variables(channel, (char *)vname)) == vname) {
01716                                                 expanded = NULL;
01717                                         } else {
01718                                                 vname = expanded;
01719                                         }
01720                                         if ((ptr = strchr(vname, ':'))) {
01721                                                 *ptr++ = '\0';
01722                                                 offset = atoi(ptr);
01723                                                 if ((ptr = strchr(ptr, ':'))) {
01724                                                         ptr++;
01725                                                         ooffset = atoi(ptr);
01726                                                 }
01727                                         }
01728 
01729                                         if ((sub_val = switch_channel_get_variable(channel, vname))) {
01730                                                 if (offset || ooffset) {
01731                                                         cloned_sub_val = strdup(sub_val);
01732                                                         switch_assert(cloned_sub_val);
01733                                                         sub_val = cloned_sub_val;
01734                                                 }
01735 
01736                                                 if (offset >= 0) {
01737                                                         sub_val += offset;
01738                                                 } else if ((size_t)abs(offset) <= strlen(sub_val)) {
01739                                                         sub_val = cloned_sub_val + (strlen(cloned_sub_val) + offset);
01740                                                 }
01741 
01742                                                 if (ooffset > 0 && (size_t)ooffset < strlen(sub_val)) {
01743                                                         if ((ptr = (char *)sub_val + ooffset)) {
01744                                                                 *ptr = '\0';
01745                                                         }
01746                                                 }
01747                                         }
01748 
01749                                         switch_safe_free(expanded);
01750                                 } else {
01751                                         switch_stream_handle_t stream = { 0 };
01752                                         char *expanded = NULL;
01753 
01754                                         SWITCH_STANDARD_STREAM(stream);
01755 
01756                                         if (stream.data) {
01757                                                 char *expanded_vname = NULL;
01758 
01759                                                 if ((expanded_vname = switch_channel_expand_variables(channel, (char *)vname)) == vname) {
01760                                                         expanded_vname = NULL;
01761                                                 } else {
01762                                                         vname = expanded_vname;
01763                                                 }
01764 
01765                                                 if ((expanded = switch_channel_expand_variables(channel, vval)) == vval) {
01766                                                         expanded = NULL;
01767                                                 } else {
01768                                                         vval = expanded;
01769                                                 }
01770 
01771                                                 if (switch_api_execute(vname, vval, channel->session, &stream) == SWITCH_STATUS_SUCCESS) {
01772                                                         func_val = stream.data;
01773                                                         sub_val = func_val;
01774                                                 } else {
01775                                                         free(stream.data);
01776                                                 }
01777 
01778                                                 switch_safe_free(expanded);
01779                                                 switch_safe_free(expanded_vname);
01780 
01781                                         } else {
01782                                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
01783                                                 free(data);
01784                                                 free(indup);
01785                                                 return (char *)in;
01786                                         }
01787                                 }
01788                                 if ((nlen = sub_val ? strlen(sub_val) : 0)) {
01789                                         if (len + nlen >= olen) {
01790                                                 resize(nlen);
01791                                         }
01792 
01793                                         len += nlen;
01794                                         strcat(c, sub_val);
01795                                         c += nlen;
01796                                 }
01797 
01798                                 switch_safe_free(func_val);
01799                                 switch_safe_free(cloned_sub_val);
01800                                 sub_val = NULL;
01801                                 vname = NULL;
01802                                 vtype = 0;
01803                                 br = 0;
01804                         }
01805                         if (len + 1 >= olen) {
01806                                 resize(1);
01807                         }
01808 
01809                         if (sp) {
01810                                 *c++ = ' ';
01811                                 sp = 0;
01812                                 len++;
01813                         }
01814 
01815                         if (*p == '$') {
01816                                 p--;
01817                         } else {
01818                                 *c++ = *p;
01819                                 len++;
01820                         }
01821                 }
01822         }
01823         free(indup);
01824 
01825         return data;
01826 }

Here is the call graph for this function:

void switch_channel_flush_dtmf switch_channel_t channel  ) 
 

00363 {
00364         void *pop;
00365         switch_mutex_lock(channel->dtmf_mutex);
00366         while(switch_queue_trypop(channel->dtmf_queue, &pop) == SWITCH_STATUS_SUCCESS) {
00367                 switch_safe_free(pop);
00368         }
00369         switch_mutex_unlock(channel->dtmf_mutex);
00370 }

Here is the call graph for this function:

switch_call_cause_t switch_channel_get_cause switch_channel_t channel  ) 
 

00162 {
00163         return channel->hangup_cause;
00164 }

switch_channel_timetable_t* switch_channel_get_timetable switch_channel_t channel  ) 
 

00167 {
00168         switch_channel_timetable_t *times = NULL;
00169 
00170         if (channel->caller_profile) {
00171                 switch_mutex_lock(channel->profile_mutex);
00172                 times = channel->caller_profile->times;
00173                 switch_mutex_unlock(channel->profile_mutex);
00174         }
00175 
00176         return times;
00177 }

Here is the call graph for this function:

switch_size_t switch_channel_has_dtmf switch_channel_t channel  ) 
 

00202 {
00203         switch_size_t has;
00204 
00205         switch_mutex_lock(channel->dtmf_mutex);
00206         has = switch_queue_size(channel->dtmf_queue);
00207         switch_mutex_unlock(channel->dtmf_mutex);
00208 
00209         return has;
00210 }

Here is the call graph for this function:

switch_channel_state_t switch_channel_name_state const char *  name  ) 
 

00757 {
00758         uint32_t x = 0;
00759         for (x = 0; state_names[x]; x++) {
00760                 if (!strcasecmp(state_names[x], name)) {
00761                         return (switch_channel_state_t) x;
00762                 }
00763         }
00764 
00765         return CS_DONE;
00766 }

switch_status_t switch_channel_queue_dtmf switch_channel_t channel,
const switch_dtmf_t dtmf
 

00213 {
00214         switch_status_t status;
00215         void *pop;
00216         switch_dtmf_t new_dtmf;
00217         
00218         switch_assert(dtmf);
00219 
00220         switch_mutex_lock(channel->dtmf_mutex); 
00221         new_dtmf = *dtmf;
00222         
00223         if ((status = switch_core_session_recv_dtmf(channel->session, dtmf) != SWITCH_STATUS_SUCCESS)) {
00224                 goto done;
00225         }
00226 
00227         if (is_dtmf(new_dtmf.digit)) {
00228                 switch_dtmf_t *dt;
00229                 int x = 0;
00230 
00231                 if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) {
00232                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s EXECSSIVE DTMF DIGIT [%c] LEN [%d]\n", 
00233                                                           switch_channel_get_name(channel), new_dtmf.digit, new_dtmf.duration);
00234                         new_dtmf.duration = switch_core_max_dtmf_duration(0);
00235                 } else if (!new_dtmf.duration) {
00236                         new_dtmf.duration = switch_core_default_dtmf_duration(0);
00237                 }
00238                 
00239                 switch_zmalloc(dt, sizeof(*dt));
00240                 *dt = new_dtmf;
00241 
00242                 while (switch_queue_trypush(channel->dtmf_queue, dt) != SWITCH_STATUS_SUCCESS) {
00243                         switch_queue_trypop(channel->dtmf_queue, &pop);
00244                         if (++x > 100) {
00245                                 status = SWITCH_STATUS_FALSE;
00246                                 free(dt);
00247                                 goto done;
00248                         }
00249                 }
00250         }
00251 
00252         status = SWITCH_STATUS_SUCCESS;
00253 
00254 done:
00255 
00256         switch_mutex_unlock(channel->dtmf_mutex);
00257 
00258         return status;
00259 }

Here is the call graph for this function:

switch_status_t switch_channel_queue_dtmf_string switch_channel_t channel,
const char *  dtmf_string
 

00262 {
00263         char *p;
00264         switch_dtmf_t dtmf = {0, switch_core_default_dtmf_duration(0)};
00265         int sent = 0, dur;
00266         char *string;
00267         int i, argc;
00268         char *argv[256];
00269 
00270         if (switch_strlen_zero(dtmf_string)) {
00271                 return SWITCH_STATUS_FALSE;
00272         }
00273 
00274         string = switch_core_session_strdup(channel->session, dtmf_string);
00275         argc = switch_separate_string(string, '+', argv, (sizeof(argv) / sizeof(argv[0])));
00276 
00277         for(i = 0; i < argc; i++) {
00278                 dtmf.duration = switch_core_default_dtmf_duration(0);
00279                 dur = switch_core_default_dtmf_duration(0) / 8;
00280                 if ((p = strchr(argv[i], '@'))) {
00281                         *p++ = '\0';
00282                         if ((dur = atoi(p)) > 50) {
00283                                 dtmf.duration = dur * 8;
00284                         }
00285                 }
00286 
00287                 if (dtmf.duration > switch_core_max_dtmf_duration(0)) {
00288                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "EXECSSIVE DTMF DIGIT LEN %c %d\n", dtmf.digit, dtmf.duration);
00289                         dtmf.duration = switch_core_max_dtmf_duration(0);
00290                 } else if (!dtmf.duration) {
00291                         dtmf.duration = switch_core_default_dtmf_duration(0);
00292                 }
00293 
00294 
00295                 for (p = argv[i]; p && *p; p++) {
00296                         if (is_dtmf(*p)) {
00297                                 dtmf.digit = *p;
00298                                 if (switch_channel_queue_dtmf(channel, &dtmf) == SWITCH_STATUS_SUCCESS) {
00299                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Queue dtmf\ndigit=%c ms=%u samples=%u\n",
00300                                                 switch_channel_get_name(channel), dtmf.digit, dur, dtmf.duration);
00301                                         sent++;
00302                                 }
00303                         }
00304                 }
00305 
00306         }
00307 
00308         return sent ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
00309 }

Here is the call graph for this function:

switch_status_t switch_channel_set_timestamps switch_channel_t channel  ) 
 

01932 {
01933         switch_status_t status = SWITCH_STATUS_SUCCESS;
01934         const char *cid_buf = NULL;
01935         switch_caller_profile_t *caller_profile, *ocp;
01936         switch_app_log_t *app_log, *ap;
01937         char *last_app = NULL, *last_arg = NULL;
01938         char start[80] = "", answer[80] = "", progress[80] = "", progress_media[80] = "", end[80] = "", tmp[80] = "", profile_start[80] = "";
01939         int32_t duration = 0, legbillsec = 0, billsec = 0, mduration = 0, billmsec = 0, legbillmsec = 0, progressmsec = 0, progress_mediamsec = 0;
01940         switch_time_t uduration = 0, legbillusec = 0, billusec = 0, progresssec = 0, progressusec = 0, progress_mediasec = 0, progress_mediausec = 0;
01941         time_t tt_created = 0, tt_answered = 0, tt_progress = 0, tt_progress_media = 0, tt_hungup = 0, mtt_created = 0, mtt_answered = 0, mtt_hungup = 0, tt_prof_created, mtt_prof_created, mtt_progress = 0 , mtt_progress_media = 0;
01942 
01943         if (!(caller_profile = switch_channel_get_caller_profile(channel)) || !channel->variables) {
01944                 return SWITCH_STATUS_FALSE;
01945         }
01946 
01947         if ((app_log = switch_core_session_get_app_log(channel->session))) {
01948                 for (ap = app_log; ap && ap->next; ap = ap->next);
01949                 last_app = ap->app;
01950                 last_arg = ap->arg;
01951         }
01952         
01953         if (!(ocp = switch_channel_get_originatee_caller_profile(channel))) {
01954                 ocp = switch_channel_get_originator_caller_profile(channel);
01955         }
01956 
01957         if (!switch_strlen_zero(caller_profile->caller_id_name)) {
01958                 cid_buf = switch_core_session_sprintf(channel->session, "\"%s\" <%s>", caller_profile->caller_id_name, 
01959                                                                                           switch_str_nil(caller_profile->caller_id_number));
01960         } else {
01961                 cid_buf = caller_profile->caller_id_number;
01962         }
01963 
01964 
01965         if (caller_profile->times) {
01966                 switch_time_exp_t tm;
01967                 switch_size_t retsize;
01968                 const char *fmt = "%Y-%m-%d %T";
01969 
01970                 switch_time_exp_lt(&tm, caller_profile->times->created);
01971                 switch_strftime(start, &retsize, sizeof(start), fmt, &tm);
01972                 switch_channel_set_variable(channel, "start_stamp", start);
01973 
01974                 switch_time_exp_lt(&tm, caller_profile->times->profile_created);
01975                 switch_strftime(profile_start, &retsize, sizeof(profile_start), fmt, &tm);
01976                 switch_channel_set_variable(channel, "profile_start_stamp", profile_start);
01977 
01978                 if (caller_profile->times->answered) {
01979                         switch_time_exp_lt(&tm, caller_profile->times->answered);
01980                         switch_strftime(answer, &retsize, sizeof(answer), fmt, &tm);
01981                         switch_channel_set_variable(channel, "answer_stamp", answer);
01982                 }
01983 
01984                 if (caller_profile->times->progress) {
01985                         switch_time_exp_lt(&tm, caller_profile->times->progress);
01986                         switch_strftime(progress, &retsize, sizeof(progress), fmt, &tm);
01987                         switch_channel_set_variable(channel, "progress_stamp", progress);
01988                 }
01989 
01990                 if (caller_profile->times->progress_media) {
01991                         switch_time_exp_lt(&tm, caller_profile->times->progress_media);
01992                         switch_strftime(progress_media, &retsize, sizeof(progress_media), fmt, &tm);
01993                         switch_channel_set_variable(channel, "progress_media_stamp", progress_media);
01994                 }
01995 
01996                 switch_time_exp_lt(&tm, caller_profile->times->hungup);
01997                 switch_strftime(end, &retsize, sizeof(end), fmt, &tm);
01998                 switch_channel_set_variable(channel, "end_stamp", end);
01999 
02000                 tt_created = (time_t) (caller_profile->times->created / 1000000);
02001                 mtt_created = (time_t) (caller_profile->times->created / 1000);
02002                 tt_prof_created = (time_t) (caller_profile->times->profile_created / 1000000);
02003                 mtt_prof_created = (time_t) (caller_profile->times->profile_created / 1000);
02004                 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_created);
02005                 switch_channel_set_variable(channel, "start_epoch", tmp);
02006                 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->created);
02007                 switch_channel_set_variable(channel, "start_uepoch", tmp);
02008 
02009                 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_prof_created);
02010                 switch_channel_set_variable(channel, "profile_start_epoch", tmp);
02011                 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->profile_created);
02012                 switch_channel_set_variable(channel, "profile_start_uepoch", tmp);
02013 
02014                 tt_answered = (time_t) (caller_profile->times->answered / 1000000);
02015                 mtt_answered = (time_t) (caller_profile->times->answered / 1000);
02016                 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_answered);
02017                 switch_channel_set_variable(channel, "answer_epoch", tmp);
02018                 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->answered);
02019                 switch_channel_set_variable(channel, "answer_uepoch", tmp);             
02020 
02021                 tt_progress = (time_t) (caller_profile->times->progress / 1000000);
02022                 mtt_progress = (time_t) (caller_profile->times->progress / 1000);
02023                 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_progress);
02024                 switch_channel_set_variable(channel, "answer_epoch", tmp);
02025                 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress);
02026                 switch_channel_set_variable(channel, "answer_uepoch", tmp);             
02027 
02028                 tt_progress_media = (time_t) (caller_profile->times->progress_media / 1000000);
02029                 mtt_progress_media = (time_t) (caller_profile->times->progress_media / 1000);
02030                 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_progress_media);
02031                 switch_channel_set_variable(channel, "answer_epoch", tmp);
02032                 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress_media);
02033                 switch_channel_set_variable(channel, "answer_uepoch", tmp);             
02034 
02035 
02036                 tt_hungup = (time_t) (caller_profile->times->hungup / 1000000);
02037                 mtt_hungup = (time_t) (caller_profile->times->hungup / 1000);
02038                 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_hungup);
02039                 switch_channel_set_variable(channel, "end_epoch", tmp);
02040                 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hungup);
02041                 switch_channel_set_variable(channel, "end_uepoch", tmp);
02042 
02043                 uduration = caller_profile->times->hungup - caller_profile->times->created;
02044                 duration = (int32_t)(tt_hungup - tt_created);
02045                 mduration = (int32_t)(mtt_hungup - mtt_created);
02046 
02047                 if (caller_profile->times->answered) {
02048