About

Channel variables are used to manipulate dialplan execution, to control call progress, and to provide options to applications. They play a pervasive role, as FreeSWITCH™ frequently consults channel variables as a way to customize processing prior to a channel’s creation, during call progress, and after the channel hangs up.  Click here to expand Table of Contents

Variable Expansion

We rely on variable expansion to create flexible, reusable dialplans:

  • $${variable} is expanded once when FreeSWITCH™ first parses the configuration on startup or after invoking reloadxml. It is suitable for variables that do not change, such as the domain of a single-tenant FreeSWITCH™ server. That is why $${domain} is referenced so frequently in the vanilla dialplan examples
  • ${variable} is expanded during each pass through the dialplan, so it is used for variables that are expected to change, such as the ${destination_number} or ${sip_to_user} fields.

Channel Variables in the XML Dialplan

Channel variables are set, appropriately enough, with the set application:

<action application=“set” data=“var_name=var value”/>

Reading channel variables requires the ${} syntax:

<action application=“log” data=“INFO The value in the var_name chan var is ${var_name}”/><condition field="${var_name}" expression=“some text”>

Scoped Variables

Channel variables used to be global to the session. As of b2c3199f, it is possible to set variables that only exist within a single application execution and any subsequent applications under it. For example, applications can use scoped variables for named input params:

<action application=“log” data=“INFO myvar is ‘${myvar}’”/><action application=“log” data="%[myvar=Hello]INFO myvar is ‘${myvar}’"/><action application=“log” data=“INFO myvar is ‘${myvar}’”/><action application=“myapp” data="%[var1=val1,var2=val2]mydata"/>

Channel Variables in Dial Strings

The variable assignment syntax for dial strings differs depending on which scope they should apply to:

  • {foo=bar} is only valid at the beginning of the dial string. It will set the same variables on every channel, but does not do so for enterprise bridging/originate.
  • <foo=bar> is only valid at the beginning of a dial string. It will set the same variables on every channel, including all thos in an enterprise bridging/originate.
  • [foo=bar] goes before each individual dial string and will set the variable values specified for only this channel.

ExamplesSet foo variable for all channels implemented and chan=1 will only be set for blah, while chan=2 will only be set for blah2:

{foo=bar}[chan=1]sofia/default/blah@baz.com,[chan=2]sofia/default/blah2@baz.com

Set multiple variables by delimiting with commas:

[var1=abc,var2=def,var3=ghi]sofia/default/blah@baz.com

To have variables in [] override variables in {}, set local_var_clobber=true inside {}. You must also set local_var_clobber=true when you want to override channel variables that have been exported to your b-legs in your dialplan. In this example, the legs for blah1@baz.com and johndoe@example.com would be set to offer SRTP (RTP/SAVP) while janedoe@acme.com would not receive an SRTP offer (she would see RTP/AVP instead):

{local_var_clobber=true,rtp_secure_media=true}sofia/default/blah1@baz.com|sofia/default/johndoe@example.com|rtp_secure_media=false]sofia/default/janedoe@acme.com 

Escaping/Redefining Delimiters

Commas are the default delimiter inside variable assignment tags. In some cases (like in absolute_codec_string), we may need to define variables whose values contain literal commas that should not be interpreted as delimiters. We can redefine the delimiter for a variable using ^^ followed by the desired delimiter:

^^;one,two,three;four,five,six;seven,eight,nine

To set absolute_codec_string=PCMA@8000h@20i@64000b,PCMU@8000h@20i@64000b,G729@8000h@20i@8000b in a dial string:

{absolute_codec_string=^^:PCMA@8000h@20i@64000b:PCMU@8000h@20i@64000b:G729@8000h@20i@8000b,leg_time_out=10,process_cdr=b_only}

This approach does not work when setting sip_h_, sip_rh_, and sip_ph headers. To pass a comma into the contents of a private header, escape the comma with a backslash:

{sip_h_X-My-Header=one\,two\,three,leg_time_out=10,process_cdr=b_only}

Exporting Channel Variables in Bridge Operations

Variables from one call leg (A) can be exported to the other call leg (B) by using the export_vars variable. Its value is a comma separated list of variables that should propagate across calls.

<action application=“set” data=“export_vars=myvar,myvar2,foo,bar”/>

To set a variable on the A-leg and add it to the export list, use the export application:

<action application=“export” data=“myvar=true”/>

Using Channel Variables in Dialplan Condition Statements

Channel variables can be used in conditions, refer to XML Dialplan Conditions for more information. Some channel variables may not be set during the dialplan parsing phrase. See Inline Actions.

Custom Channel Variables

We are not constrained to the channel variables that FreeSWITCH™, its modules, and applications define. It is possible to set any number of unique channel variables for any purpose. They can also be logged in CDR. The set application can be used to set any channel variable:

<action application=“set” data=“lead_id=2e4b5966-0aaf-11e8-ba89-0ed5f89f718b”/><action application=“set” data=“campaign_id=333814”/><action application=“set” data=“crm_tags=referral new loyal” />

In a command issued via mod_xml_rpc or mod_event_socket:

originate {lead_id=2e4b5966-0aaf-11e8-ba89-0ed5f89f718,campaign_id=333814}sofia/mydomain.com/18005551212@1.2.3.4 15555551212

Values with spaces must be enclosed by quotes:

originate {crm_tags=‘referral new loyal'}sofia/mydomain.com/18005551212@1.2.3.4 15555551212

Channel Variable Manipulation

Channel variables can be manipulated for varied results. For example, a channel variable could be trimmed to get the first three digits of a phone number. Manipulating Channel Variables discusses this in detail.

Channel Variable Scope Example

Consider this example:

<extension name=“test” continue=“false”>  <condition field=“destination_number” expression="^test([0-9]+)$">    <action application=“set” data=“fruit=tomato” />     <action application=“export” data=“veggie=tomato” />     <action application=“bridge” data="{meat=tomato}sofia/gateway/testaccount/1234" />  </condition></extension>

Leg A (the channel that called the dial plan) will have these variables set:

fruit: tomatoveggie: tomato

Leg B (the channel created with sofia/gateway/testaccount/1234) will have these variables set:

fruit: tomatomeat: tomato

Accessing Channel Variables in Other Environments

In addition to the dialplan, channel variables can be set in other environments as well.In a  FreeSWITCH™ module, written in C:

switch_channel_set_variable(channel,“name”,“value”);char* result = switch_channel_get_variable(channel,“name”); char* result = switch_channel_get_variable_partner(channel,“name”);

In the console (or fs_cli, implemented in mod_commands): 

uuid_getvar uuid_setvar []uuid_setvar_multi =[;=[;…]] 

Alternatively, call uuid_dump to get all the variables, or use the eval command, adding the prefix variable_ to the key:

uuid_dump eval uuid: ${variable_}

In an event socket, just extend the above with the api prefix:

api uuid_getvar

In Lua, there are several ways to interact with variables. In the freeswitch.Session() invocation that creates a new Session object, variables go in square brackets:

s = freeswitch.Session("[myname=myvars]sofia/localhost/1003")

With the new Session object s:

local result1 = s:getVariable(“myname”) – “myvars”s:setVariable(“name”, “value”)local result2 = s:getVariable(“name”) – “value”

Info Application Variable Names (variable_xxxx)

Some variables, as shown from the info app, may have variable_ in front of their names. For example, if you pass a header variable called type from the proxy server, it will get displayed as variable_sip_h_type in FreeSWITCH™. To access that variable, you should strip off the variable_, and just do ${sip_h_type}. Other variables shown in the info app are prepended with channel, which should be stripped as well. The example below show a list of info app variables and the corresponding channel variable names:

Info variable namechannel variable nameDescription
Channel-StatestateCurrent state of the call
Channel-State-Numberstate_numberInteger
Channel-Namechannel_nameChannel name
Unique-IDuuiduuid of this channel’s call leg
Call-DirectiondirectionInbound or Outbound
Answer-Statestate-
Channel-Read-Codec-Nameread_codecthe read codec variable mean the source codec
Channel-Read-Codec-Rateread_ratethe source rate
Channel-Write-Codec-Namewrite_codecthe destination codec same to write_codec if not transcoded
Channel-Write-Codec-Ratewrite_ratedestination rate same to read rate if not transcoded
Caller-Usernameusername.
Caller-Dialplandialplanuser dialplan like xml, lua, enum, lcr
Caller-Caller-ID-Namecaller_id_name.
Caller-Caller-ID-Numbercaller_id_number.
Caller-ANIaniANI of caller, frequently the same as caller ID number
Caller-ANI-IIaniiiANI II Digits (OLI - Originating Line Information), if available. Refer to: http://www.nanpa.com/number_resource_info/ani_ii_digits.html
Caller-Network-Addrnetwork_addrIP address of calling party
Caller-Destination-Numberdestination_numberDestination (dialed) number
Caller-Unique-IDuuidThis channel’s uuid
Caller-SourcesourceSource module, i.e. mod_sofia, mod_openzap, etc.
Caller-ContextcontextDialplan context
Caller-RDNISrdnisRedirected DNIS info. See mod_dptools: transfer application
Caller-Channel-Namechannel_name.
Caller-Profile-Indexprofile_index.
Caller-Channel-Created-Timecreated_time.
Caller-Channel-Answered-Timeanswered_time.
Caller-Channel-Hangup-Timehangup_time.
Caller-Channel-Transfer-Timetransfer_time.
Caller-Screen-Bitscreen_bit.
Caller-Privacy-Hide-Nameprivacy_hide_name.
Caller-Privacy-Hide-Numberprivacy_hide_numberThis variable tells you if the inbound call is asking for CLIR[Calling Line ID presentation Restriction] (either with anonymous method or Privacy:id method)
initial_callee_id_nameSets the callee id name during the 183. This allows the phone to see a name of who they are calling prior to the phone being answered. An example of setting this to the caller id name of the number being dialled:
variable_sip_received_ipsip_received_ip.
variable_sip_received_portsip_received_port.
variable_sip_authorizedsip_authorized.
variable_sip_mailboxsip_mailbox.
variable_sip_auth_usernamesip_auth_username.
variable_sip_auth_realmsip_auth_realm.
variable_mailboxmailbox.
variable_user_nameuser_name.
variable_domain_namedomain_name.
variable_record_stereorecord_stereo.
variable_accountcodeaccountcodeAccountcode for the call. This is an arbitrary value. It can be defined in the user variables in the directory, or it can be set/modified from dialplan. The accountcode may be used to force a specific CDR CSV template for the call.
variable_user_contextuser_context.
variable_effective_caller_id_nameeffective_caller_id_name.
variable_effective_caller_id_numbereffective_caller_id_number.
variable_caller_domaincaller_domain.
variable_sip_from_usersip_from_user.
variable_sip_from_urisip_from_uri.
variable_sip_from_hostsip_from_host.
variable_sip_from_user_strippedsip_from_user_stripped.
variable_sip_from_tagsip_from_tag.
variable_sofia_profile_namesofia_profile_name.
variable_sofia_profile_domain_namesofia_profile_domain_name.
variable_sip_full_routesip_full_routeThe complete contents of the Route: header.
variable_sip_full_viasip_full_viaThe complete contents of the Via: header.
variable_sip_full_fromsip_full_fromThe complete contents of the From: header.
variable_sip_full_tosip_full_toThe complete contents of the To: header.
variable_sip_req_paramssip_req_params.
variable_sip_req_usersip_req_user.
variable_sip_req_urisip_req_uri.
variable_sip_req_hostsip_req_host.
variable_sip_to_paramssip_to_params.
variable_sip_to_tagsip_to_tag.
variable_sip_to_usersip_to_user.
variable_sip_to_urisip_to_uri.
variable_sip_to_hostsip_to_host.
variable_sip_contact_paramssip_contact_params.
variable_sip_contact_usersip_contact_user.
variable_sip_contact_portsip_contact_port.
variable_sip_contact_urisip_contact_uri.
variable_sip_contact_hostsip_contact_host.
variable_sip_invite_domainsip_invite_domain.
variable_channel_namechannel_name.
variable_sip_call_idsip_call_idSIP header Call-ID
variable_sip_user_agentsip_user_agent.
variable_sip_via_hostsip_via_host.
variable_sip_via_portsip_via_port.
variable_sip_via_rportsip_via_rport.
variable_presence_idpresence_id.
variable_sip_h_P-Key-Flagssip_h_p-key-flagsThis will contain the optional P-Key-Flags header(s) that may be received from calling endpoint.
variable_switch_r_sdpswitch_r_sdpThe whole SDP received from calling endpoint.
variable_remote_media_ipremote_media_ip.
variable_remote_media_portremote_media_port.
variable_write_codecwrite_codec.
variable_write_ratewrite_rate.
variable_endpoint_dispositionendpoint_disposition.
variable_dialed_extdialed_ext.
variable_transfer_ringbacktransfer_ringback.
variable_call_timeoutcall_timeout.
variable_hangup_after_bridgehangup_after_bridge.
variable_continue_on_failcontinue_on_fail.
variable_dialed_userdialed_user.
variable_dialed_domaindialed_domain.
variable_sip_redirect_contact_user_0sip_redirect_contact_user_0.
variable_sip_redirect_contact_host_0sip_redirect_contact_host_0.
variable_sip_h_Referred-Bysip_h_referred-by.
variable_sip_refer_tosip_refer_toThe full SIP URI received from a SIP Refer-To: response
variable_max_forwardsmax_forwards.
variable_originate_dispositionoriginate_disposition.
variable_read_codecread_codec.
variable_read_rateread_rate.
variable_openopen.
variable_use_profileuse_profile.
variable_current_applicationcurrent_application.
variable_ep_codec_stringep_codec_stringThis variable is only available if late negotiation is enabled on the profile. It’s a readable string containing all the codecs proposed by the calling endpoint. This can be easily parsed in the dialplan.
variable_rtp_disable_holdrtp_disable_holdThis variable when set will disable the hold feature of the phone.
variable_sip_acl_authed_bysip_acl_authed_byThis variable holds what ACL rule allowed the call.
variable_curl_response_datacurl_response_dataThis variable stores the output from the last curl made.
variable_drop_dtmfdrop_dtmfSet on a channel to drop DTMF events on the way out.
variable_drop_dtmf_masking_filedrop_dtmf_masking_fileIf drop_dtmf is true play specified file for every tone received.
variable_drop_dtmf_masking_digitsdrop_dtmf_masking_digitsIf drop_dtmf is true play specified tone for every tone received.
sip_codec_negotiationsip_codec_negotiationsip_codec_negotiation is basically a channel variable equivalent of inbound-codec-negotiation.sip_codec_negotiation accepts “scrooge” & “greedy” as values.This means you can change codec negotiation on a per call basis.
Caller-Callee-ID-Name--
Caller-Callee-ID-Number--
Caller-Channel-Progress-Media-Time--
Caller-Channel-Progress-Time--
Caller-Direction--
Caller-Profile-Created-Timeprofile_created-
Caller-Transfer-Source--
Channel-Call-State--
Channel-Call-UUID--
Channel-HIT-Dialplan--
Channel-Read-Codec-Bit-Rate--
Channel-Write-Codec-Bit-Rate--
Core-UUID--
Event-Calling-File--
Event-Calling-Function--
Event-Calling-Line-Number--
Event-Date-GMT--
Event-Date-Local--
Event-Date-Timestamp--
Event-Name--
Event-Sequence--
FreeSWITCH-Hostname--
FreeSWITCH-IPv4--
FreeSWITCH-IPv6--
FreeSWITCH-Switchname--
Hunt-ANI--
Hunt-Callee-ID-Name--
Hunt-Callee-ID-Number--
Hunt-Caller-ID-Name--
Hunt-Caller-ID-Number--
Hunt-Channel-Answered-Time--
Hunt-Channel-Created-Time--
Hunt-Channel-Hangup-Time--
Hunt-Channel-Name--
Hunt-Channel-Progress-Media-Time--
Hunt-Channel-Progress-Time--
Hunt-Channel-Transfer-Time--
Hunt-Context--
Hunt-Destination-Number--
Hunt-Dialplan--
Hunt-Direction--
Hunt-Network-Addr--
Hunt-Privacy-Hide-Name--
Hunt-Privacy-Hide-Number--
Hunt-Profile-Created-Timeprofile_created-
Hunt-Profile-Index--
Hunt-RDNIS--
Hunt-Screen-Bit--
Hunt-Source--
Hunt-Transfer-Source--
Hunt-Unique-ID--
Hunt-Username--
Presence-Call-Direction--
variable_DIALSTATUS--
variable_absolute_codec_string--
variable_advertised_media_ip--
variable_answersec
variable_answermsec
variable_answerusec
variable_billsec
variable_billmsec
variable_billusec
variable_bridge_channel--
variable_bridge_hangup_cause--
variable_bridge_uuid--
variable_call_uuid--
variable_current_application_response--
variable_direction--
variable_duration
variable_mduration
variable_uduration
variable_inherit_codec--
variable_is_outbound--
variable_last_bridge_to--
variable_last_sent_callee_id_name--
variable_last_sent_callee_id_number--
variable_local_media_ip--
variable_local_media_port--
variable_number_alias--
variable_originate_early_media--
variable_originating_leg_uuid--
variable_originator--
variable_originator_codec--
variable_outbound_caller_id_number--
variable_progresssec
variable_progressmsec
variable_progressusec
variable_progress_mediasec
variable_progress_mediamsec
variable_progress_mediausec
variable_recovery_profile_name--
variable_rtp_use_ssrc--
variable_session_id--
variable_sip_2833_recv_payload--
variable_sip_2833_send_payload--
variable_sip_P-Asserted-Identity--
variable_sip_Privacy--
variable_sip_audio_recv_pt--
variable_sip_cid_type--
variable_sip_cseq--
variable_sip_destination_url--
variable_sip_from_displaysip_from_display‘User’ element of SIP From: line
variable_sip_from_port--
variable_sip_gateway--
variable_sip_gateway_name--
variable_sip_h_P-Charging-Vector--
variable_sip_local_network_addr--
variable_sip_local_sdp_str--
variable_sip_network_ip--
variable_sip_network_port--
variable_sip_number_alias--
variable_sip_outgoing_contact_uri--
variable_sip_ph_P-Charging-Vector--
variable_sip_profile_name--
variable_sip_recover_contact--
variable_sip_recover_via--
variable_sip_reply_host--
variable_sip_reply_port--
variable_sip_req_port--
variable_sip_to_port--
variable_sip_use_codec_name--
variable_sip_use_codec_ptime--
variable_sip_use_codec_rate--
variable_sip_use_pt--
variable_sip_via_protocol--
variable_switch_m_sdp--
variable_transfer_history--
variable_transfer_source--
variable_uuid--
variable_waitsec
variable_waitmsec
variable_waitusec